cruelfox 发表于 2021-6-12 19:45

【Perf-V评测】蜂鸟E203开源SOC的学习及RTL仿真实验

<p>  Perf-V&nbsp;FPGA板的资源可以实现RISC-V CPU核,即用FPGA中的硬逻辑搭出来一个CPU. 这个&ldquo;搭积木&rdquo;的过程就是FPGA综合工具干的活了&mdash;&mdash;是将CPU逻辑的描述(源代码)翻译成硬件(逻辑门、寄存器等)的过程。用硬件描述语言(HDL)实现的CPU并且其源代码是开放的,就可称作开源CPU. 开源的RISC-V CPU已经有不少了,可以作为学习和实验RISC-V的基础。</p>

<p>  E203是蜂鸟E200系列RISC-V IP核中的一款开源软核,用Verilog语言编写。E203作者写了两本关于RISC-V的书对E203的设计和应用进行了较为详细的介绍,一本偏重硬件,一本侧重软件。想深入了解RISC-V的朋友可以找来读。</p>

<p></p>

<p>  Perf-V官方提供的技术资料里面包含了蜂鸟E203开源SOC的FPGA demo工程,是把Xilinx Vivado的工程目录整个打包了。</p>

<p>  不过几十MB的压缩包中,几乎都是Vivado生成的文件,源代码只占一点点。要学习E203源代码,可以从里面找,也可以从github单独下载。</p>

<p><br />
  E203 SOC不仅仅是一个CPU,它包含了E203 RISC-V核之外的总线、内存块、外设功能模块等,相当于一个完整的MCU.&nbsp;</p>

<p>  在正式到板子上玩 RISC-V 之前,有必要对 E203 SOC 的结构进行了解。</p>

<p>&nbsp;</p>

<p>  下面是我从 github 上抓下来的 E203 RTL代码树,一共有几个子目录,源码总共不到3MB.</p>

<pre>
<code>rtl
├─core
│      config.v
│      e203_biu.v
│      e203_clkgate.v
│      e203_clk_ctrl.v
│      e203_core.v
│      e203_cpu.v
│      e203_cpu_top.v
│      e203_defines.v
│      e203_dtcm_ctrl.v
│      e203_dtcm_ram.v
│      e203_extend_csr.v
│      e203_exu.v
│      e203_exu_alu.v
│      e203_exu_alu_bjp.v
│      e203_exu_alu_csrctrl.v
│      e203_exu_alu_dpath.v
│      e203_exu_alu_lsuagu.v
│      e203_exu_alu_muldiv.v
│      e203_exu_alu_rglr.v
│      e203_exu_branchslv.v
│      e203_exu_commit.v
│      e203_exu_csr.v
│      e203_exu_decode.v
│      e203_exu_disp.v
│      e203_exu_excp.v
│      e203_exu_longpwbck.v
│      e203_exu_oitf.v
│      e203_exu_regfile.v
│      e203_exu_wbck.v
│      e203_ifu.v
│      e203_ifu_ifetch.v
│      e203_ifu_ift2icb.v
│      e203_ifu_litebpu.v
│      e203_ifu_minidec.v
│      e203_irq_sync.v
│      e203_itcm_ctrl.v
│      e203_itcm_ram.v
│      e203_lsu.v
│      e203_lsu_ctrl.v
│      e203_reset_ctrl.v
│      e203_srams.v
│      
├─debug
│      sirv_debug_csr.v
│      sirv_debug_module.v
│      sirv_debug_ram.v
│      sirv_debug_rom.v
│      sirv_jtag_dtm.v
│      
├─fab
│      sirv_icb1to16_bus.v
│      sirv_icb1to2_bus.v
│      sirv_icb1to8_bus.v
│      
├─general
│      sirv_1cyc_sram_ctrl.v
│      sirv_gnrl_bufs.v
│      sirv_gnrl_dffs.v
│      sirv_gnrl_icbs.v
│      sirv_gnrl_ram.v
│      sirv_gnrl_xchecker.v
│      sirv_sim_ram.v
│      sirv_sram_icb_ctrl.v
│      
├─mems
│      sirv_mrom.v
│      sirv_mrom_top.v
│      
├─perips
│      i2c_master_bit_ctrl.v
│      i2c_master_byte_ctrl.v
│      i2c_master_defines.v
│      i2c_master_top.v
│      sirv_aon.v
│      sirv_aon_lclkgen_regs.v
│      sirv_aon_porrst.v
│      sirv_aon_top.v
│      sirv_aon_wrapper.v
│      sirv_AsyncResetReg.v
│      sirv_AsyncResetRegVec.v
│      sirv_AsyncResetRegVec_1.v
│      sirv_AsyncResetRegVec_129.v
│      sirv_AsyncResetRegVec_36.v
│      sirv_AsyncResetRegVec_67.v
│      sirv_clint.v
│      sirv_clint_top.v
│      sirv_DeglitchShiftRegister.v
│      sirv_expl_apb_slv.v
│      sirv_expl_axi_slv.v
│      sirv_flash_qspi.v
│      sirv_flash_qspi_top.v
│      sirv_gpio.v
│      sirv_gpio_top.v
│      sirv_hclkgen_regs.v
│      sirv_jtaggpioport.v
│      sirv_LevelGateway.v
│      sirv_otp_top.v
│      sirv_plic_man.v
│      sirv_plic_top.v
│      sirv_pmu.v
│      sirv_pmu_core.v
│      sirv_pwm16.v
│      sirv_pwm16_core.v
│      sirv_pwm16_top.v
│      sirv_pwm8.v
│      sirv_pwm8_core.v
│      sirv_pwm8_top.v
│      sirv_pwmgpioport.v
│      sirv_qspi_1cs.v
│      sirv_qspi_1cs_top.v
│      sirv_qspi_4cs.v
│      sirv_qspi_4cs_top.v
│      sirv_qspi_arbiter.v
│      sirv_qspi_fifo.v
│      sirv_qspi_media.v
│      sirv_qspi_media_1.v
│      sirv_qspi_media_2.v
│      sirv_qspi_physical.v
│      sirv_qspi_physical_1.v
│      sirv_qspi_physical_2.v
│      sirv_queue.v
│      sirv_queue_1.v
│      sirv_repeater_6.v
│      sirv_ResetCatchAndSync.v
│      sirv_ResetCatchAndSync_2.v
│      sirv_rtc.v
│      sirv_spigpioport.v
│      sirv_spigpioport_1.v
│      sirv_spigpioport_2.v
│      sirv_spi_flashmap.v
│      sirv_tlfragmenter_qspi_1.v
│      sirv_tlwidthwidget_qspi.v
│      sirv_tl_repeater_5.v
│      sirv_uart.v
│      sirv_uartgpioport.v
│      sirv_uartrx.v
│      sirv_uarttx.v
│      sirv_uart_top.v
│      sirv_wdog.v
│      
├─soc
│      e203_soc_top.v
│      
└─subsys
      e203_subsys_clint.v
      e203_subsys_gfcm.v
      e203_subsys_hclkgen.v
      e203_subsys_hclkgen_rstsync.v
      e203_subsys_main.v
      e203_subsys_mems.v
      e203_subsys_perips.v
      e203_subsys_plic.v
      e203_subsys_pll.v
      e203_subsys_pllclkdiv.v
      e203_subsys_top.v</code></pre>

<p>  文档中给出的层次结构描述是这样的:</p>

<p></p>

<p>  和这套RTL代码一起提供的还有很多测试例,可以对E203 CPU进行仿真测试。</p>

<p>  在tb目录下有一个 tb_top.v 的文件,就是测试用的顶层模块。在PC机上,用Verilog语言的仿真工具,差不多就可以做仿真实验了。在文档中,作者提到使用的是iverilog这个免费的仿真软件(全称 Icarus Verilog)&nbsp;,正好我也用这个,就直接调用 iverilog 处理源代码。</p>

<p>  不过一开始就遇到错误了:包含文件 e200_defines.v 找不到。原来 rtl/core 里面文件名是 e203_defines.v 不一样。改了下,然后居然宏定义缺失。仔细一看,是 tb_top.v 里面到处使用的是 e200 和 E200 字样,而 rtl 代码树中都没有出现,遂都分别改为 e203 和 E203 才可以。</p>

<p>  因为我不想逐个添加&nbsp;verilog 文件,就用了 iverilog 的&nbsp;+libdir 命令指定子目录。这样还有一些模块找不到的错误,是因为引用的 verilog 模块名没有对应到 verilog 文件名(一个文件可以包含多个模块定义),故还需要单独指定一些文件。调整好以后,写成的文件如下:</p>

<pre>
<code>+incdir+rtl/core
+incdir+rtl/perips
+define+DISABLE_SV_ASSERTION=1
rtl/general/sirv_1cyc_sram_ctrl.v
rtl/general/sirv_gnrl_icbs.v
rtl/general/sirv_sim_ram.v
rtl/general/sirv_gnrl_bufs.v
rtl/general/sirv_gnrl_ram.v
rtl/general/sirv_sram_icb_ctrl.v
rtl/general/sirv_gnrl_dffs.v
rtl/general/sirv_gnrl_xchecker.v
rtl/perips/sirv_spi_flashmap.v
+libdir+rtl/core
+libdir+rtl/mems
+libdir+rtl/debug
+libdir+rtl/fab
+libdir+rtl/perips
+libdir+rtl/soc
+libdir+rtl/subsys
tb/tb_top.v
</code></pre>

<p>将这个文件命名为 sim_e203.f 再用 iverilog -f sim_e203.f 即可编译。</p>

<p>  如果成功了,执行 vvp a.out 进行仿真。</p>

<p>  这时候 vvp 报错了,是 tb_top.v 中这里有问题</p>

<pre>
<code>initial begin
    $value$plusargs("DUMPWAVE=%d",dumpwave);
    if(dumpwave != 0)begin
         // To add your waveform generation function
    end
end</code></pre>

<p>  我暂时也不用 dump ,先给把这段注释屏蔽掉不管。然后再来一次,出现仿真运行的信息了:</p>

<p><span style="color:#2980b9;"><span style="font-family:Courier;"><strong>E:\Perf-V\e203&gt;vvp a.out</strong><br />
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!<br />
ERROR: tb/tb_top.v:257: $readmemh: Unable to open .verilog for reading.<br />
ITCM 0x00: xxxxxxxxxxxxxxxx<br />
ITCM 0x01: xxxxxxxxxxxxxxxx<br />
ITCM 0x02: xxxxxxxxxxxxxxxx<br />
ITCM 0x03: xxxxxxxxxxxxxxxx<br />
ITCM 0x04: xxxxxxxxxxxxxxxx<br />
ITCM 0x05: xxxxxxxxxxxxxxxx<br />
ITCM 0x06: xxxxxxxxxxxxxxxx<br />
ITCM 0x07: xxxxxxxxxxxxxxxx<br />
ITCM 0x16: xxxxxxxxxxxxxxxx<br />
ITCM 0x20: xxxxxxxxxxxxxxxx</span></span></p>

<p>  看来是需要加载的内存数据文件缺少了,不能正确初始化。根据提示找到代码中读取文件的位置,便知道了需要提供 TESTCASE 宏指定一个数据文件。</p>

<p>  在 github 上 e200_opensource/riscv-tools/riscv-tests/isa/generated/ 下有许多编译过的文件,以 .verilog 结尾,可以直接拿来测试。这个目录下的测试例是测试指令集的。比如我使用&nbsp;rv32ui-p-add.verilog 这个文件,就执行:</p>

<p><span style="color:#2980b9;"><span style="font-family:Courier;"><strong>E:\Perf-V\e203&gt;vvp a.out +TESTCASE=rv32ui-p-add</strong><br />
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!<br />
TESTCASE= &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rv32ui-p-add<br />
ITCM 0x00: 340510730001aa0d<br />
ITCM 0x01: ff85051300002517<br />
ITCM 0x02: 01f5222301e52023<br />
ITCM 0x03: 040f416334202f73<br />
ITCM 0x04: 4fa507ff02634fa1<br />
ITCM 0x05: 0c634fad05ff0f63<br />
ITCM 0x06: 0bff05634f8505ff<br />
ITCM 0x07: 4f9d0dff00634f95<br />
ITCM 0x16: 2f03f52505130000<br />
ITCM 0x20: 2f8300052f03f065</span></span></p>

<p>然后等待仿真结果。</p>

<p>&nbsp;</p>

<p>  但是等了很久都没有出来结果。电脑的CPU也一直占用着&hellip;&hellip; Ctrl-C中止了它,仿真时间还是在0,有奇怪的问题了。</p>

<p>  不解,我就到网上搜搜看有没有人遇到同样问题的。还真有人提到E203仿真的坑,就点开看看。据说是 iverilog 版本10不行,需要版本12. 而我用的 win32 port 版本正好是v10.0 ,而且更高版本的已经没有现成的win32 port了。</p>

<p>  那么远程登陆到单位的Linux工作站上去试试吧。iverilog 肯定是要自己编译的,好在源代码并不大,从 github 上很快拖下来了。准备编译,需要 gperf 但该机上没有,现装,可以用。make 过程中, g++ 报错了,估计是GCC版本不够高的原因。我看了下,出错的代码是</p>

<pre>
<code class="language-cpp">      buf &lt;&lt; (file_? file_ : "") &lt;&lt; ":" &lt;&lt; lineno_;</code></pre>

<p>  那么就修改成 if-else 语句来用吧。net_scope.cc 文件改了两处,编译通过。最后 iverilog 编译完成了。</p>

<p>  再执行&nbsp;iverilog 和 vvp ,不到一分钟,仿真运行结果出来了:</p>

<p>看来自家机器仿真不了是iverilog软件的问题。</p>

cruelfox 发表于 2021-6-12 21:50

本帖最后由 cruelfox 于 2021-6-12 22:36 编辑

<p>  用仿真耗时和&quot;Total cycle_count&quot;表达的仿真过程主时钟周期数进行折算,相当于 E203 SOC 的仿真运行频率只有 800Hz 左右.<img height="50" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/funk1.gif" width="53" /></p>

<p>  这样的仿真虽然耗时,但因为可以查看每个信号的状态,适合查错用。上面我试的仿真内容是验证 add 指令,其测试代码(RISC-V指令)是用汇编语言写的,而且用了宏定义,故不熟悉指令架构就难以明白其意图。例如,这是汇编文件片段:</p>

<pre>
<code>#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------

TEST_RR_OP( 2,add, 0x00000000, 0x00000000, 0x00000000 );
TEST_RR_OP( 3,add, 0x00000002, 0x00000001, 0x00000001 );
TEST_RR_OP( 4,add, 0x0000000a, 0x00000003, 0x00000007 );

TEST_RR_OP( 5,add, 0xffffffffffff8000, 0x0000000000000000, 0xffffffffffff8000 );
TEST_RR_OP( 6,add, 0xffffffff80000000, 0xffffffff80000000, 0x00000000 );
TEST_RR_OP( 7,add, 0xffffffff7fff8000, 0xffffffff80000000, 0xffffffffffff8000 );

TEST_RR_OP( 8,add, 0x0000000000007fff, 0x0000000000000000, 0x0000000000007fff );
TEST_RR_OP( 9,add, 0x000000007fffffff, 0x000000007fffffff, 0x0000000000000000 );
TEST_RR_OP( 10, add, 0x0000000080007ffe, 0x000000007fffffff, 0x0000000000007fff );

TEST_RR_OP( 11, add, 0xffffffff80007fff, 0xffffffff80000000, 0x0000000000007fff );
TEST_RR_OP( 12, add, 0x000000007fff7fff, 0x000000007fffffff, 0xffffffffffff8000 );

TEST_RR_OP( 13, add, 0xffffffffffffffff, 0x0000000000000000, 0xffffffffffffffff );
TEST_RR_OP( 14, add, 0x0000000000000000, 0xffffffffffffffff, 0x0000000000000001 );
TEST_RR_OP( 15, add, 0xfffffffffffffffe, 0xffffffffffffffff, 0xffffffffffffffff );</code></pre>

<p>  generated 目录下生成的机器码包括仿真用的 verilog 文件(相当于单片机烧写用的 .hex 文件的作用),编译得到的 .elf 文件,以及反汇编 ELF 文件的结果 *.dump.</p>

<p>&nbsp;</p>

<p>  看一下 .dump 文件的内容:很长,不能贴全在这里了</p>

<pre>
<code>Disassembly of section .text.init:

80000000 &lt;_start&gt;:
80000000:        aa0d                        j        80000132 &lt;reset_vector&gt;
80000002:        0001                        nop

80000004 &lt;trap_vector&gt;:
80000004:        34051073                  csrw        mscratch,a0
80000008:        00002517                  auipc        a0,0x2
8000000c:        ff850513                  addi        a0,a0,-8 # 80002000 &lt;test_trap_data&gt;
80000010:        01e52023                  sw        t5,0(a0)
80000014:        01f52223                  sw        t6,4(a0)
80000018:        34202f73                  csrr        t5,mcause
8000001c:        040f4163                  bltz        t5,8000005e &lt;other_interrupts&gt;
80000020:        4fa1                        li        t6,8
80000022:        07ff0263                  beq        t5,t6,80000086 &lt;write_tohost&gt;
80000026:        4fa5                        li        t6,9
80000028:        05ff0f63                  beq        t5,t6,80000086 &lt;write_tohost&gt;
8000002c:        4fad                        li        t6,11
8000002e:        05ff0c63                  beq        t5,t6,80000086 &lt;write_tohost&gt;
80000032:        4f85                        li        t6,1
80000034:        0bff0563                  beq        t5,t6,800000de &lt;ifetch_error_handler&gt;
80000038:        4f95                        li        t6,5
8000003a:        0dff0063                  beq        t5,t6,800000fa &lt;load_error_handler&gt;
8000003e:        4f9d                        li        t6,7
80000040:        0dff0b63                  beq        t5,t6,80000116 &lt;store_error_handler&gt;
80000044:        80000f17                  auipc        t5,0x80000
80000048:        fbcf0f13                  addi        t5,t5,-68 # 0 &lt;_start-0x80000000&gt;
8000004c:        000f0363                  beqz        t5,80000052 &lt;trap_vector+0x4e&gt;
80000050:        8f02                        jr        t5
80000052:        34202f73                  csrr        t5,mcause
80000056:        000f5363                  bgez        t5,8000005c &lt;handle_exception&gt;
8000005a:        a009                        j        8000005c &lt;handle_exception&gt;

8000005c &lt;handle_exception&gt;:
8000005c:        a01d                        j        80000082 &lt;other_interrupts+0x24&gt;

8000005e &lt;other_interrupts&gt;:
8000005e:        80000fb7                  lui        t6,0x80000
80000062:        003f8f93                  addi        t6,t6,3 # 80000003 &lt;_end+0xffffdff3&gt;
80000066:        05ff0463                  beq        t5,t6,800000ae &lt;sft_irq_handler&gt;
8000006a:        80000fb7                  lui        t6,0x80000
8000006e:        007f8f93                  addi        t6,t6,7 # 80000007 &lt;_end+0xffffdff7&gt;
80000072:        05ff0a63                  beq        t5,t6,800000c6 &lt;tmr_irq_handler&gt;
80000076:        80000fb7                  lui        t6,0x80000
8000007a:        00bf8f93                  addi        t6,t6,11 # 8000000b &lt;_end+0xffffdffb&gt;
8000007e:        01ff0c63                  beq        t5,t6,80000096 &lt;ext_irq_handler&gt;
80000082:        5391e193                  ori        gp,gp,1337

80000086 &lt;write_tohost&gt;:
80000086:        4521                        li        a0,8
80000088:        30052073                  csrs        mstatus,a0
8000008c:        00001f17                  auipc        t5,0x1
80000090:        f63f2a23                  sw        gp,-140(t5) # 80001000 &lt;tohost&gt;
80000094:        bfcd                        j        80000086 &lt;write_tohost&gt;

80000096 &lt;ext_irq_handler&gt;:
80000096:        00002517                  auipc        a0,0x2
8000009a:        f6a50513                  addi        a0,a0,-150 # 80002000 &lt;test_trap_data&gt;
8000009e:        00052f03                  lw        t5,0(a0)
800000a2:        00452f83                  lw        t6,4(a0)
800000a6:        34002573                  csrr        a0,mscratch
800000aa:        30200073                  mret

800000ae &lt;sft_irq_handler&gt;:
800000ae:        00002517                  auipc        a0,0x2
800000b2:        f5250513                  addi        a0,a0,-174 # 80002000 &lt;test_trap_data&gt;
800000b6:        00052f03                  lw        t5,0(a0)
800000ba:        00452f83                  lw        t6,4(a0)
800000be:        34002573                  csrr        a0,mscratch
800000c2:        30200073                  mret

......

80000132 &lt;reset_vector&gt;:
80000132:        00000f13                  li        t5,0
80000136:        00000f93                  li        t6,0
8000013a:        f1402573                  csrr        a0,mhartid
8000013e:        e101                        bnez        a0,8000013e &lt;reset_vector+0xc&gt;
80000140:        4181                        li        gp,0
80000142:        00000297                  auipc        t0,0x0
80000146:        ec228293                  addi        t0,t0,-318 # 80000004 &lt;trap_vector&gt;
8000014a:        4521                        li        a0,8
8000014c:        30052073                  csrs        mstatus,a0
80000150:        fff00513                  li        a0,-1
80000154:        30452073                  csrs        mie,a0
80000158:        30529073                  csrw        mtvec,t0

8000015c &lt;post_mtvec&gt;:
8000015c:        80000297                  auipc        t0,0x80000
80000160:        ea428293                  addi        t0,t0,-348 # 0 &lt;_start-0x80000000&gt;
80000164:        00028e63                  beqz        t0,80000180 &lt;post_mtvec+0x24&gt;
80000168:        10529073                  csrw        stvec,t0
8000016c:        0000b2b7                  lui        t0,0xb
80000170:        10928293                  addi        t0,t0,265 # b109 &lt;_start-0x7fff4ef7&gt;
80000174:        30229073                  csrw        medeleg,t0
80000178:        30202373                  csrr        t1,medeleg
8000017c:        ee6290e3                  bne        t0,t1,8000005c &lt;handle_exception&gt;
80000180:        30005073                  csrwi        mstatus,0
80000184:        08000513                  li        a0,128
80000188:        30052073                  csrs        mstatus,a0
8000018c:        4501                        li        a0,0
8000018e:        bfc51073                  csrw        0xbfc,a0
80000192:        0000100f                  fence.i
80000196:        000012b7                  lui        t0,0x1
8000019a:        a0028293                  addi        t0,t0,-1536 # a00 &lt;_start-0x7ffff600&gt;

8000019e &lt;waitloop1&gt;:
8000019e:        12fd                        addi        t0,t0,-1
800001a0:        fe029fe3                  bnez        t0,8000019e &lt;waitloop1&gt;
800001a4:        100083b7                  lui        t2,0x10008
800001a8:        00838393                  addi        t2,t2,8 # 10008008 &lt;_start-0x6fff7ff8&gt;
800001ac:        0003a283                  lw        t0,0(t2)
800001b0:        00040337                  lui        t1,0x40
800001b4:        fff34313                  not        t1,t1
800001b8:        0062f2b3                  and        t0,t0,t1
800001bc:        0053a023                  sw        t0,0(t2)
800001c0:        40000293                  li        t0,1024

800001c4 &lt;waitloop2&gt;:
800001c4:        12fd                        addi        t0,t0,-1
800001c6:        0003ae03                  lw        t3,0(t2)
800001ca:        fe029de3                  bnez        t0,800001c4 &lt;waitloop2&gt;
800001ce:        0003a283                  lw        t0,0(t2)
800001d2:        00040337                  lui        t1,0x40
800001d6:        0062e2b3                  or        t0,t0,t1
800001da:        0053a023                  sw        t0,0(t2)
......

80000262 &lt;test_2&gt;:
80000262:        4081                        li        ra,0
80000264:        4101                        li        sp,0
80000266:        00208f33                  add        t5,ra,sp
8000026a:        4e81                        li        t4,0
8000026c:        4189                        li        gp,2
8000026e:        37df1d63                  bne        t5,t4,800005e8 &lt;fail&gt;

80000272 &lt;test_3&gt;:
80000272:        4085                        li        ra,1
80000274:        4105                        li        sp,1
80000276:        00208f33                  add        t5,ra,sp
8000027a:        4e89                        li        t4,2
8000027c:        418d                        li        gp,3
8000027e:        37df1563                  bne        t5,t4,800005e8 &lt;fail&gt;

80000282 &lt;test_4&gt;:
80000282:        408d                        li        ra,3
80000284:        411d                        li        sp,7
80000286:        00208f33                  add        t5,ra,sp
8000028a:        4ea9                        li        t4,10
8000028c:        4191                        li        gp,4
8000028e:        35df1d63                  bne        t5,t4,800005e8 &lt;fail&gt;

......</code></pre>

<p>  我尚不熟悉RISC-V的指令集,因此大部分都看不懂。<img height="48" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/loveliness.gif" width="48" /></p>

<p>  这段代码是直接放到 E203 SOC 的 ITCM 中的,因此一启动就执行了。它包含了中断向量的处理,是一个完整的程序,只是并不像我们做MCU程序要操作片上设备以实现功能。</p>

<p>&nbsp;</p>

<p>  想查看仿真的细节,用verilog系统的dump功能就可以。在 tb_top.v 中加这两行,将 e_203_cpu 这个模块以及其下级的信号导出成vcd文件:</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; $dumpfile(&quot;e203test.vcd&quot;);<br />
&nbsp; &nbsp; &nbsp; &nbsp; $dumpvars(0, u_e203_soc_top.u_e203_subsys_top.u_e203_subsys_main.u_e203_cpu_top.u_e203_cpu);<br />
  再重新做仿真,就会每次都生成 e203test.vcd 这个文件(几百MB,是纯文本文件)。然后可以用 gtkwave 这个软件来看波形了:</p>

<p>  这样可以观看 CPU 是如何取指令,如何执行指令等等的每一步状态变化,可以结合源代码阅读,帮助理解E203&nbsp;RISC-V CPU的设计。</p>

<p>&nbsp;</p>

<p>  既然 E203 SOC 整体都被仿真了,要写程序控制 GPIO、UART 也是可以做到,并且从仿真可以观察到的。只是,那样就适合用 FPGA 在电路中验证。</p>

Jacktang 发表于 2021-6-13 10:55

<p><img height="63" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/victory.gif" width="61" /></p>

<p>测试代码(RISC-V指令)是用汇编语言写</p>

<p>楼主很强大</p>

jcwangzi 发表于 2021-6-16 10:38

<p>用汇编语言写楼主很强大</p>

ayay33 发表于 2021-12-22 10:36

<p>看不懂,但感觉很厉害,希望能早入达到楼主的水平。</p>

老默外卖送鱼 发表于 2024-4-26 15:57

<p>请问楼主有没有试过从flash启动的仿真</p>
页: [1]
查看完整版本: 【Perf-V评测】蜂鸟E203开源SOC的学习及RTL仿真实验