Skip to content

Commit 0ed9670

Browse files
authored
Merge pull request #3 from Undefined01/soc
Support ysyx SoC and add an example for soc
2 parents 378f55b + ffd819e commit 0ed9670

File tree

7 files changed

+341
-8
lines changed

7 files changed

+341
-8
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@
77
[submodule "libraries/difftest"]
88
path = libraries/difftest
99
url = https://gitee.com/oscpu/difftest.git
10+
[submodule "libraries/ysyxSoC"]
11+
path = libraries/ysyxSoC
12+
url = https://github.com/oscpu/ysyxSoC

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,28 @@ Enter the test cycle:
137137
./build.sh -e chisel_cpu_diff -d -s -a "-i inst_diff.bin" -m "EMU_TRACE=1" -b
138138
```
139139

140+
### soc
141+
142+
`projects/soc`目录下存放了接入`ysyxSoC`的示例程序。源码中只有一个占位符,能够通过编译但不能正常运行。
143+
144+
要使用该框架,需要先按照 [ysyx SoC 的 readme](https://github.com/osCPU/ysyxsoc) 完成 `命名规范``CPU 内部修改` 两个步骤,得到 `ysyx_21xxxx.v`,随后放入 `projects/soc/vsrc/` 中。此后,执行下面的命令将会根据 `myinfo.txt` 中的 ID 自动 对代码进行规范检查、集成到 `soc` 并运行指定的程序。`ysyxSoC` 中附带的例程会被自动软连接至 `build` 目录下,仿真时可以快速使用。
145+
146+
```bash
147+
./build.sh -e soc -b -s -y -v '--timescale "1ns/1ns" -Wno-fatal --trace' -a "-i ysyxSoC/flash/hello-flash.bin --dump-wave"
148+
```
149+
150+
由于无法直接使用 `difftest` 框架,暂时只支持少量参数。
151+
```bash
152+
$ ./emu -h
153+
Usage: ./emu [OPTION...]
154+
155+
-i, --image=FILE run with this image file
156+
--dump-wave dump waveform when log is enabled
157+
-b, --log-begin=NUM display log from NUM th cycle
158+
-e, --log-end=NUM stop display log at NUM th cycle
159+
-h, --help print program help info
160+
```
161+
140162
## 查看波形
141163

142164
`oscpu`目录下使用命令可以通过`gtkwave`查看输出的波形,其中`xxx`表示例程名。

build.sh

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#!/bin/bash
22

3-
VERSION="1.19"
3+
VERSION="1.20"
44

55
help() {
66
echo "Version v"$VERSION
77
echo "Usage:"
8-
echo "build.sh [-e project_name] [-b] [-t top_file] [-s] [-a parameters_list] [-f] [-l] [-g] [-w] [-c] [-d] [-m] [-r test_cases]"
8+
echo "build.sh [-e project_name] [-b] [-t top_file] [-s] [-a parameters_list] [-f] [-l] [-g] [-w] [-c] [-d] [-m] [-r test_cases] [-v parameters_list] [-y]"
99
echo "Description:"
1010
echo "-e: Specify a example project. For example: -e counter. If not specified, the default directory \"cpu\" will be used."
1111
echo "-b: Build project using verilator and make tools automatically. It will generate the \"build\"(difftest) or \"build_test\" subfolder under the project directory."
@@ -20,6 +20,8 @@ help() {
2020
echo "-d: Connect to XiangShan difftest framework."
2121
echo "-m: Parameters passed to the difftest makefile. For example: -m \"EMU_TRACE=1 EMU_THREADS=4\". Multiple parameters require double quotes."
2222
echo "-r: Run all test cases of the specified directory in the \"bin\" directory. For example: -r \"case1 case2\". This option requires the project to be able to connect to difftest."
23+
echo "-v: Parameters passed to verilator. For example: -v '--timescale \"1ns/1ns\"'"
24+
echo "-y: Connect to ysyx SoC."
2325
exit 0
2426
}
2527

@@ -115,31 +117,61 @@ build_diff_proj() {
115117
compile_difftest
116118
}
117119

120+
build_soc_proj() {
121+
mkdir -p $BUILD_PATH/vsrc $BUILD_PATH/csrc
122+
123+
if [[ ! -f "$PROJECT_PATH/$VSRC_FOLDER/ysyx_${ID:0-6}.v" ]]; then
124+
echo "$VSRC_FOLDER/ysyx_${ID:0-6}.v not detected. Please follow the README of ysyxSoC to get this file."
125+
exit 1
126+
fi
127+
128+
[[ -f $BUILD_PATH/vsrc/cpu-check.py ]] || cp $YSYXSOC_HOME/ysyx/soc/cpu-check.py $BUILD_PATH/
129+
sed -i -e "s/input(.*)/\"${ID:0-4}\"/g" $BUILD_PATH/cpu-check.py
130+
eval "cd $PROJECT_PATH/$VSRC_FOLDER && python3 $BUILD_PATH/cpu-check.py 1> /dev/null && mv -f cpu-check.log $BUILD_PATH"
131+
grep 'fine' $BUILD_PATH/cpu-check.log 1> /dev/null 2>&1
132+
if [[ $? -ne 0 ]]; then
133+
echo "Interface check failed. Check $BUILD_FOLDER/cpu-check.log for more details."
134+
exit 1
135+
fi
136+
137+
if [[ ! -f $BUILD_PATH/vsrc/ysyxSoCFull.v ]]; then
138+
cp $YSYXSOC_HOME/ysyx/soc/ysyxSoCFull.v $BUILD_PATH/vsrc/
139+
sed -i -e "s/ysyx_000000/ysyx_${ID:0-6}/g" $BUILD_PATH/vsrc/ysyxSoCFull.v
140+
fi
141+
142+
ln -s $YSYXSOC_HOME/ysyx/peripheral $BUILD_PATH/vsrc/
143+
ln -s $YSYXSOC_HOME/ysyx/peripheral/spiFlash $BUILD_PATH/csrc/
144+
VSRC_FOLDER+=" $BUILD_PATH/vsrc"
145+
CSRC_FOLDER+=" $BUILD_PATH/csrc"
146+
147+
ln -s $YSYXSOC_HOME/ysyx/program/bin $BUILD_PATH/ysyxSoC
148+
}
149+
118150
build_proj() {
119151
cd $PROJECT_PATH
120152

121153
# get all .cpp files
122-
CSRC_LIST=`find $PROJECT_PATH/$CSRC_FOLDER -name "*.cpp"`
154+
CSRC_LIST=`find -L $PROJECT_PATH/$CSRC_FOLDER -name "*.cpp"`
123155
for CSRC_FILE in ${CSRC_LIST[@]}
124156
do
125157
CSRC_FILES="$CSRC_FILES $CSRC_FILE"
126158
done
127159
# get all vsrc subfolders
128-
VSRC_SUB_FOLDER=`find $VSRC_FOLDER -type d`
160+
VSRC_SUB_FOLDER=`find -L $VSRC_FOLDER -type d`
129161
for SUBFOLDER in ${VSRC_SUB_FOLDER[@]}
130162
do
131163
INCLUDE_VSRC_FOLDERS="$INCLUDE_VSRC_FOLDERS -I$SUBFOLDER"
132164
done
133165
# get all csrc subfolders
134-
CSRC_SUB_FOLDER=`find $PROJECT_PATH/$CSRC_FOLDER -type d`
166+
CSRC_SUB_FOLDER=`find -L $PROJECT_PATH/$CSRC_FOLDER -type d`
135167
for SUBFOLDER in ${CSRC_SUB_FOLDER[@]}
136168
do
137169
INCLUDE_CSRC_FOLDERS="$INCLUDE_CSRC_FOLDERS -I$SUBFOLDER"
138170
done
139171

140172
# compile
141173
mkdir $BUILD_FOLDER 1>/dev/null 2>&1
142-
eval "verilator --x-assign unique --cc --exe --trace --assert -O3 -CFLAGS \"-std=c++11 -Wall $INCLUDE_CSRC_FOLDERS $CFLAGS\" $LDFLAGS -o $PROJECT_PATH/$BUILD_FOLDER/$EMU_FILE \
174+
eval "verilator --x-assign unique --cc --exe --trace --assert -O3 $VERILATORFLAGS -CFLAGS \"-std=c++11 -Wall $INCLUDE_CSRC_FOLDERS $CFLAGS\" $LDFLAGS -o $PROJECT_PATH/$BUILD_FOLDER/$EMU_FILE \
143175
-Mdir $PROJECT_PATH/$BUILD_FOLDER/emu-compile $INCLUDE_VSRC_FOLDERS --build $V_TOP_FILE $CSRC_FILES"
144176
if [ $? -ne 0 ]; then
145177
echo "Failed to run verilator!!!"
@@ -176,12 +208,14 @@ DIFFTEST_TOP_FILE="SimTop.v"
176208
NEMU_PATH=$LIBRARIES_FOLDER"/NEMU"
177209
DIFFTEST_HELPER_PATH="src/test/vsrc/common"
178210
DIFFTEST_PARAM=
179-
TEST_CASES="false"
180211
DRAMSIM3_FOLDER="libraries/DRAMsim3"
181212
TEST_CASES=
213+
YSYXSOC="false"
214+
YSYXSOC_FOLDER="libraries/ysyxSoC"
215+
VERILATORFLAGS=
182216

183217
# Check parameters
184-
while getopts 'he:bt:sa:f:l:gwcdm:r:' OPT; do
218+
while getopts 'he:bt:sa:f:l:gwcdm:r:yv:' OPT; do
185219
case $OPT in
186220
h) help;;
187221
e) PROJECT_FOLDER="$OPTARG";;
@@ -197,6 +231,8 @@ while getopts 'he:bt:sa:f:l:gwcdm:r:' OPT; do
197231
d) DIFFTEST="true";;
198232
m) DIFFTEST_PARAM="$OPTARG";;
199233
r) TEST_CASES="$OPTARG"; DIFFTEST="true";;
234+
y) YSYXSOC="true"; V_TOP_FILE="ysyxSoCFull.v";;
235+
v) VERILATORFLAGS="$OPTARG";;
200236
?) help;;
201237
esac
202238
done
@@ -210,6 +246,7 @@ NEMU_HOME=$OSCPU_PATH/$NEMU_PATH
210246
DIFFTEST_HOME=$OSCPU_PATH/$DIFFTEST_PATH
211247
DRAMSIM3_HOME=$OSCPU_PATH/$DRAMSIM3_FOLDER
212248
LIBRARIES_HOME=$OSCPU_PATH/$LIBRARIES_FOLDER
249+
YSYXSOC_HOME=$OSCPU_PATH/$YSYXSOC_FOLDER
213250
export NEMU_HOME=$NEMU_HOME
214251
export NOOP_HOME=$PROJECT_PATH
215252
export DRAMSIM3_HOME=$DRAMSIM3_HOME
@@ -233,6 +270,8 @@ fi
233270

234271
# Build project
235272
if [[ "$BUILD" == "true" ]]; then
273+
[[ -d $BUILD_PATH ]] && find $BUILD_PATH -type l -delete
274+
[[ "$YSYXSOC" == "true" ]] && build_soc_proj
236275
[[ "$DIFFTEST" == "true" ]] && build_diff_proj || build_proj
237276

238277
#git commit

libraries/ysyxSoC

Submodule ysyxSoC added at b23f10d

projects/soc/csrc/emu.h

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#include <unistd.h>
2+
#include <getopt.h>
3+
4+
#include <verilated_vcd_c.h>
5+
#include <verilated.h>
6+
#include <VysyxSoCFull.h>
7+
8+
extern "C"
9+
{
10+
void flash_init(const char *img);
11+
}
12+
13+
class Emulator
14+
{
15+
public:
16+
Emulator(int argc, char *argv[])
17+
{
18+
parseArgs(argc, argv);
19+
20+
if (args.image == nullptr)
21+
{
22+
printf("Image file unspecified. Use -i to provide the image of flash");
23+
exit(1);
24+
}
25+
printf("Initializing flash with \"%s\" ...\n", args.image);
26+
flash_init(args.image);
27+
28+
printf("Initializing and resetting DUT ...\n");
29+
dut_ptr = new VysyxSoCFull;
30+
dut_ptr->reset = 1;
31+
for (int i = 0; i < 10; i++)
32+
{
33+
dut_ptr->clock = 0;
34+
dut_ptr->eval();
35+
dut_ptr->clock = 1;
36+
dut_ptr->eval();
37+
}
38+
dut_ptr->clock = 0;
39+
dut_ptr->reset = 0;
40+
dut_ptr->eval();
41+
42+
if (args.dump_wave)
43+
{
44+
Verilated::traceEverOn(true);
45+
printf("`dump-wave` enabled, waves will be written to \"vlt_dump.vcd\".\n");
46+
fp = new VerilatedVcdC;
47+
dut_ptr->trace(fp, 1);
48+
fp->open("vlt_dump.vcd");
49+
fp->dump(0);
50+
}
51+
}
52+
~Emulator()
53+
{
54+
if (args.dump_wave)
55+
{
56+
fp->close();
57+
delete fp;
58+
}
59+
}
60+
61+
void step()
62+
{
63+
dut_ptr->clock = 1;
64+
dut_ptr->eval();
65+
cycle++;
66+
if (args.dump_wave && args.dump_begin <= cycle && cycle <= args.dump_end)
67+
fp->dump((vluint64_t)cycle);
68+
dut_ptr->clock = 0;
69+
dut_ptr->eval();
70+
}
71+
72+
unsigned long long get_cycle()
73+
{
74+
return cycle;
75+
}
76+
77+
private:
78+
void parseArgs(int argc, char *argv[])
79+
{
80+
81+
int long_index;
82+
const struct option long_options[] = {
83+
{"dump-wave", 0, NULL, 0},
84+
{"log-begin", 1, NULL, 'b'},
85+
{"log-end", 1, NULL, 'e'},
86+
{"image", 1, NULL, 'i'},
87+
{"help", 0, NULL, 'h'},
88+
{0, 0, NULL, 0}};
89+
90+
int o;
91+
while ((o = getopt_long(argc, const_cast<char *const *>(argv),
92+
"-hi:b:e:", long_options, &long_index)) != -1)
93+
{
94+
switch (o)
95+
{
96+
case 0:
97+
switch (long_index)
98+
{
99+
case 0:
100+
args.dump_wave = true;
101+
continue;
102+
}
103+
// fall through
104+
default:
105+
print_help(argv[0]);
106+
exit(0);
107+
case 'i':
108+
args.image = optarg;
109+
break;
110+
case 'b':
111+
args.dump_begin = atoll(optarg);
112+
break;
113+
case 'e':
114+
args.dump_end = atoll(optarg);
115+
break;
116+
}
117+
}
118+
119+
Verilated::commandArgs(argc, argv);
120+
}
121+
122+
static inline void print_help(const char *file)
123+
{
124+
printf("Usage: %s [OPTION...]\n", file);
125+
printf("\n");
126+
printf(" -i, --image=FILE run with this image file\n");
127+
printf(" --dump-wave dump waveform when log is enabled\n");
128+
printf(" -b, --log-begin=NUM display log from NUM th cycle\n");
129+
printf(" -e, --log-end=NUM stop display log at NUM th cycle\n");
130+
printf(" -h, --help print program help info\n");
131+
printf("\n");
132+
}
133+
134+
unsigned long long cycle = 0;
135+
136+
struct Args
137+
{
138+
bool dump_wave = false;
139+
unsigned long dump_begin = 0;
140+
unsigned long dump_end = -1;
141+
const char *image = nullptr;
142+
} args;
143+
144+
VysyxSoCFull *dut_ptr = nullptr;
145+
VerilatedVcdC *fp = nullptr;
146+
};

projects/soc/csrc/main.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include <cstdio>
2+
#include <csignal>
3+
#include <chrono>
4+
namespace chrono = std::chrono;
5+
6+
#include "verilated.h" //Defines common routines
7+
#include "VysyxSoCFull.h"
8+
9+
#include <emu.h>
10+
11+
static int signal_received = 0;
12+
13+
void sig_handler(int signo)
14+
{
15+
if (signal_received != 0)
16+
{
17+
puts("SIGINT received, forcely shutting down.\n");
18+
exit(0);
19+
}
20+
puts("SIGINT received, gracefully shutting down... Type Ctrl+C again to stop forcely.\n");
21+
signal_received = signo;
22+
}
23+
24+
static Emulator *emu = nullptr;
25+
chrono::system_clock::time_point sim_start_time;
26+
void release()
27+
{
28+
if (emu != nullptr)
29+
{
30+
auto elapsed = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now() - sim_start_time);
31+
printf("Simulated %llu cycles in %lds\n",
32+
emu->get_cycle(),
33+
elapsed.count());
34+
delete emu;
35+
}
36+
}
37+
38+
int main(int argc, char *argv[])
39+
{
40+
printf("Emu compiled at %s, %s\n", __DATE__, __TIME__);
41+
42+
if (signal(SIGINT, sig_handler) == SIG_ERR)
43+
{
44+
printf("can't catch SIGINT\n");
45+
}
46+
atexit(release);
47+
48+
emu = new Emulator(argc, argv);
49+
printf("Start simulating ...\n");
50+
sim_start_time = chrono::system_clock::now();
51+
while (!Verilated::gotFinish() && signal_received == 0)
52+
{
53+
emu->step();
54+
}
55+
56+
return 0;
57+
}

0 commit comments

Comments
 (0)