【LiteX】【仿真】使用litex_sim在Python环境中实现FPGA SoC仿真测试-LiteX社区-FPGA CPLD-ChipDebug

【LiteX】【仿真】使用litex_sim在Python环境中实现FPGA SoC仿真测试

 

 

介绍

环境依赖

sudo apt-get install libevent-dev libjson-c-dev libsdl2-dev sudo apt-get install verilator sudo apt-get install gtkwave 

litex_sim

在conda虚拟环境中安装LiteX环境时,会自动安litex_sim可执行程序
它能够在PC上对LiteX构建的SoC进行仿真验证,使用的验证工具是verilator

# 进入工作目录 which litex_sim /home/vacajk/anaconda3/bin/litex_sim 

litex_sim的工作流程:

  • 调用LiteX的标准流程:
    • 构建SoC
    • 生成verilog
    • 生成BIOS程序bios.bin(运行在SoC中,RISCV GCC交叉编译)
  • 跳过LiteX的流程:
    • 综合、布局、布线
    • 下载Bitstream
  • litex_sim还会基于verilator仿真工具生成一个可执行程序Vsim(Linux GCC编译),用于仿真调度
  • litex_sim能够将BIOS的串口桥接到可执行程序,这样就能在Linux命令行直接调试控制SoC

入门仿真

# 进入工作目录 cd ~/Study/litex/env/litex  # --cputype <cpu name>:指定SoC中集成的CPU名称,我们一般使用vexriscv(一个非常小的RiscV处理器) litex_sim --cpu-type=vexriscv 

仿真开始运行后,即可在Linux命令行中对BIOS的命令行进行操作

        __   _ __      _  __        / /  (_) /____ | |/_/       / /__/ / __/ -_)>  <      /____/_/__/__/_/|_|    Build your hardware, easily!   (c) Copyright 2012-2024 Enjoy-Digital  (c) Copyright 2007-2015 M-Labs   BIOS built on Aug 17 2024 16:26:13  BIOS CRC passed (3b300ea2)   LiteX git sha1: 35498b468  --=============== SoC ==================-- CPU:            VexRiscv @ 1MHz BUS:            wishbone 32-bit @ 4GiB CSR:            32-bit data ROM:            128.0KiB SRAM:           8.0KiB   --============== Boot ==================-- Booting from serial... Press Q or ESC to abort boot completely. sL5DdSMmkekro Timeout No boot medium found  --============= Console ================--  litex> litex> ident Ident: LiteX Simulation 2024-08-17 16:26:04 litex> help  LiteX BIOS, available commands:  flush_cpu_dcache         - Flush CPU data cache crc                      - Compute CRC32 of a part of the address space ident                    - Identifier of the system help                     - Print this help  serialboot               - Boot from Serial (SFL) reboot                   - Reboot boot                     - Boot from Memory  mem_cmp                  - Compare memory content mem_speed                - Test memory speed mem_test                 - Test memory access mem_copy                 - Copy address space mem_write                - Write address space mem_read                 - Read address space mem_list                 - List available memory regions   litex>  

 

litex_server、litex_cli、litescope_cli仿真调试

对于litex_sim的仿真,我们也可以使用litex_server工具进行远程连接,litex_server介绍:TODO:跳转litex_server工具

运行litex_sim并:

  • 使能etherbone模块(注意:使能etherbone时,会在Linux创建一个网口TAP,需要输入管理员密码)
  • 使能scope模块

若使用到litex_server进行调试,需要打开多个命令行

litex_sim仿真窗口

# BASH A,用于运行litex_sim cd ~/Study/litex/env/litex  # --with-etherbone:集成etherbone # --soc-csv csr.csv:生成寄存器表,litex_cli、litescope_cli会用到 litex_sim --cpu-type=vexriscv --with-etherbone --with-analyzer --soc-csv csr.csv  # CTRL+C退出,重新运行一次 litex_sim --cpu-type=vexriscv --with-etherbone --with-analyzer --soc-csv csr.csv 

注意

  • litescope_cli使用前需要确保当前目录包含文件:analyzer.csv
  • litex_sim使用litescope_cli时,需要先运行一次用来生成analyzer.csv,然后第二次开始持续运行

litex_server窗口

# BASH B,用于运行litex_server  # 查看网口TAP (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ ifconfig tap0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.1.100  netmask 255.255.255.0  broadcast 192.168.1.255         inet6 fe80::a8b6:24ff:fe69:7721  prefixlen 64  scopeid 0x20<link>         ether aa:b6:24:69:77:21  txqueuelen 1000  (Ethernet)         RX packets 0  bytes 0 (0.0 B)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 37  bytes 5223 (5.2 KB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ litex_server --udp --udp-ip 192.168.1.51 [CommUDP] ip: 192.168.1.51	 / port: 1234 / tcp port: 1234 

litex_cli窗口

# BASH C,用于运行litex_cli工具,确保运行目录下存在文件:csv.csr cd ~/Study/litex/env/litex  # 使用litex_cli查看板子名称 (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ litex_cli --ident LiteX Simulation 2024-08-17 17:52:41  # 使用litex_cli查看所有寄存器当前值 (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ litex_cli --regs 0xf0000000 : 0x00000000 analyzer_mux_value 0xf0000004 : 0x00000000 analyzer_trigger_enable 0xf0000008 : 0x00000001 analyzer_trigger_done 0xf000000c : 0x00000000 analyzer_trigger_mem_write 0xf0000010 : 0x00000000 analyzer_trigger_mem_mask 0xf000002c : 0x00000000 analyzer_trigger_mem_value 0xf0000048 : 0x00000000 analyzer_trigger_mem_full 0xf000004c : 0x00000000 analyzer_subsampler_value 0xf0000050 : 0x00000000 analyzer_storage_enable 0xf0000054 : 0x00000001 analyzer_storage_done 0xf0000058 : 0x00000000 analyzer_storage_length 0xf000005c : 0x00000000 analyzer_storage_offset 0xf0000060 : 0x00000000 analyzer_storage_mem_level 0xf0000064 : 0x00000000 analyzer_storage_mem_data 0xf0000800 : 0x00000000 ctrl_reset 0xf0000804 : 0x12345678 ctrl_scratch 0xf0000808 : 0x00000000 ctrl_bus_errors 0xf0001000 : 0x00000000 ethphy_crg_reset 0xf0002000 : 0x0003d090 timer0_load 0xf0002004 : 0x00000000 timer0_reload 0xf0002008 : 0x00000001 timer0_en 0xf000200c : 0x00000001 timer0_update_value 0xf0002010 : 0x00000000 timer0_value 0xf0002014 : 0x00000001 timer0_ev_status 0xf0002018 : 0x00000001 timer0_ev_pending 0xf000201c : 0x00000000 timer0_ev_enable 0xf0002800 : 0x0000000a uart_rxtx 0xf0002804 : 0x00000000 uart_txfull 0xf0002808 : 0x00000001 uart_rxempty 0xf000280c : 0x00000001 uart_ev_status 0xf0002810 : 0x00000000 uart_ev_pending 0xf0002814 : 0x00000003 uart_ev_enable 0xf0002818 : 0x00000001 uart_txempty 0xf000281c : 0x00000000 uart_rxfull 

litescope_cli窗口

# BASH C,用于运行litescope_cli工具,确保运行目录下存在文件:analyzer.csr  # 使用litescope_cli直接DUMP波形 (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ litescope_cli No trigger, immediate capture. [running]... [uploading]... [====================>] 100% [writing to dump.vcd]...  # 使用litescope_cli根据触发条件DUMP波形 # 如simsoc_ibus_cyc的上升沿触发 # 因为我们使用的是ibus_cyc信号,我们可以在litex_sim运行中的命令行中随便输入一个命令,即可实现IBUS总线触发 (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ litescope_cli -r simsoc_ibus_cyc Exact: simsoc_ibus_cyc Rising edge: simsoc_ibus_cyc [running]... [uploading]... [====================>] 100% [writing to dump.vcd]... 

波形DUMP

虽然litex_sim的可执行程序是verilator生成的,但默认参数时无法导出波形,若需要导出波形有如下几种方法

方法一:导出指定时间段的波形

若仿真前就已经知道需要导出波形的具体时间段,可以使用如下配置参数:

# --trace:使能DUMP # --trace:DUMP格式fst(fst文件较小) # --trace_start <start time (ps)> # --trace_end <end time (ps)> # 需要注意litex_sim对应的SoC运行在1MHz,我们将start和end设置的时间比较大 litex_sim --cpu-type=vexriscv --trace --trace-fst --trace-start 0 --trace-end 100e9 

使用gtkwave打开波形

gtkwave build/sim/gateware/sim.gtkw 

在这里插入图片描述

方法二:在命令行中配置寄存器控制波形导出

在前面的入门仿真中我们已经看到,Linux命令行已经桥接到了BIOS的命令行,我们可以使用寄存器写命令手动触发开始和停止仿真

# --trace:使能DUMP # --trace:DUMP格式fst(fst文件较小) # --sim-debug:是能sim-debug模块 litex_sim --cpu-type=vexriscv --trace --trace-fst --sim-debug 

–sim-debug参数能够在SoC中例化sim_debug模块,并在Verilog Top Module中引出用于仿真控制的信号
如下图中的sim_trace信号

  • 在verilator仿真时程序会读取该信号状态
  • 为1表示dump波形,为0表示不dump波形
  • 该信号在SoC中有一个具体的寄存器可以控制
    在这里插入图片描述
    在命令行中输入help可以看到用于波形dump的控制命令
litex> help  LiteX BIOS, available commands:  mark                     - Set a debug simulation marker finish                   - Finish simulation trace                    - Toggle simulation tracing 

我们一般用到finish和trace即可

# 开始dump litex> trace <DUMP ON>  # 停止dump litex> trace <DUMP OFF>  # 结束仿真 litex> finish - /home/vacajk/Study/litex/env/litex/build/sim/gateware/sim.v:1414: Verilog $finish 

使用gtkwave打开波形

gtkwave build/sim/gateware/sim.gtkw 

方法三:litex_cli配置寄存器控制波形导出

在前面litex_server调试中已经介绍过,可以使用litex_server和litex_cli实现寄存器操作
我们再配合方法二的配置,即可实现litex_cli配置寄存器控制波形导出

litex_sim仿真窗口

# BASH A,用于运行litex_sim cd ~/Study/litex/env/litex  # --with-etherbone:集成etherbone # --soc-csv csr.csv:生成寄存器表,litex_cli会用到 litex_sim --cpu-type=vexriscv --with-etherbone --soc-csv csr.csv --trace --trace-fst --sim-debug 

litex_server窗口

# BASH B,用于运行litex_server (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ litex_server --udp --udp-ip 192.168.1.51 [CommUDP] ip: 192.168.1.51	 / port: 1234 / tcp port: 1234 

litex_cli窗口

bash # BASH C,用于运行litex_cli工具,确保运行目录下存在文件:csv.csr cd ~/Study/litex/env/litex  # 使用litex_cli所有寄存器当前值 (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ litex_cli --regs 0xf0000000 : 0x00000000 ctrl_reset 0xf0000004 : 0x12345678 ctrl_scratch 0xf0000008 : 0x00000000 ctrl_bus_errors 0xf0000800 : 0x00000000 ethphy_crg_reset 0xf0001800 : 0x00000000 sim_finish_finish 0xf0002000 : 0x00000000 sim_marker_marker 0xf0002800 : 0x00000000 sim_trace_enable 0xf0003000 : 0x0003d090 timer0_load 0xf0003004 : 0x00000000 timer0_reload 0xf0003008 : 0x00000001 timer0_en 0xf000300c : 0x00000001 timer0_update_value 0xf0003010 : 0x00000000 timer0_value 0xf0003014 : 0x00000001 timer0_ev_status 0xf0003018 : 0x00000001 timer0_ev_pending 0xf000301c : 0x00000000 timer0_ev_enable 0xf0003800 : 0x00000000 uart_rxtx 0xf0003804 : 0x00000000 uart_txfull 0xf0003808 : 0x00000001 uart_rxempty 0xf000380c : 0x00000001 uart_ev_status 0xf0003810 : 0x00000000 uart_ev_pending 0xf0003814 : 0x00000003 uart_ev_enable 0xf0003818 : 0x00000001 uart_txempty 0xf000381c : 0x00000000 uart_rxfull 

可以看到,在litex_cli中已经能看到sim_trace_enable、sim_finish_finish寄存器了
我们接着就可以使用方法二的顺序通过寄存器控制波形导出

# BASH C,用于运行litex_cli工具 # 开始dump (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ litex_cli --write sim_trace_enable 1 # 停止dump (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ litex_cli --write sim_trace_enable 0 # 结束仿真 (base) vacajk@vacajk-rog:~/Study/litex/env/litex$ litex_cli --write sim_finish_finish 1 
# BASH A,用于运行litex_sim # 我们可以看到命令行中打印了log <DUMP ON> <DUMP OFF> - /home/vacajk/Study/litex/env/litex/build/sim/gateware/sim.v:1414: Verilog $finish 

使用gtkwave打开波形

gtkwave build/sim/gateware/sim.gtkw 

Video

仿真video相关功能时需要安装SDL库,仿真程序会调用该库将SoC Video接口输出的图像显示到一个独立的窗口上

Color Bars

# 进入工作目录 cd ~/Study/litex/env/litex  # --with-video-colorbars:使能video模块,并输出Color Bars到显示窗口 litex_sim --cpu-type=vexriscv --with-video-colorbars 

在这里插入图片描述

Terminal Console

# 进入工作目录 cd ~/Study/litex/env/litex  # --with-video-terminal:使能video模块,并将控制台字符输出到显示窗口 litex_sim --cpu-type=vexriscv --with-video-terminal 

在这里插入图片描述

Frame Buffer

该模式会在SDRAM中申请一片区域作为图像的Frame Buffer
Video模块会自动从Frame Buffer中读取图像数据然后输出

# 进入工作目录 cd ~/Study/litex/env/litex  # --with-video-framebuffer:使能video模块,并将控制台字符输出到显示窗口 # --with-sdram:用于存储Frame Buffer litex_sim --cpu-type=vexriscv --with-video-framebuffer --with-sdram 

程序运行后会弹出一个窗口,是黑色的,表示Frame Buffer中所有的数据都为0
我们可以使用litex_sim的命令行给Buffer中写一些数据,然后查看窗口变化

# 查看Frame Buffer基地址:0x40c00000 litex> mem_list Available memory regions: ROM                0x00000000 0x20000  SRAM               0x10000000 0x2000  MAIN_RAM           0x40000000 0x4000000  VIDEO_FRAMEBUFFER  0x40c00000 0x800000  CSR                0xf0000000 0x10000   # 对Frame Buffer写白色像素数据 litex> mem_write 0x40D00000 0xffffffff 1000 

可以看到,其中一些像素变成了白色
在这里插入图片描述

Frame Buffer(通过litex_cli传输图像)

为了能够显示一个真实图片,我门需要想办法将图像在线传输到仿真的SoC中
因此需要在仿真时打开以下功能:

  • etherbone:用来支持litex_server
  • sdram:用来作Frame Buffer
    TODO

注意

当完成video相关模块的仿真后若想继续仿真其他模块,需要删除build/sim文件夹,否则会有代码编译冲突

替换BIOS

提前运行一次litex_sim生成build/sim相关环境

# 进入工作目录 cd ~/Study/litex/env/litex  litex_sim --cpu-type=vexriscv 

运行liitex_bare_metal_demo,并配合build/sim生成demo固件(demo.bin会生成到当前目录下)

# --build-path=build/sim:指向编译目录,该文件夹中包含了gateware和software子目录 # --mem=rom:告诉编译工具demo.bin运行在rom中(启动地址会和bios.bin相同) liitex_bare_metal_demo --build-path=build/sim --mem=rom 

运行litex_sim,将demo.bin替换bios.bin,并开始仿真

# --integrated-rom-init=demo.bin:使用自行编译的demo.bin替换调bios.bin litex_sim --cpu-type=vexriscv --integrated-rom-init=demo.bin  # SoC启动后,会直接运行demo.bin程序,控制台打印 Available commands: help               - Show this command reboot             - Reboot CPU donut              - Spinning Donut demo helloc             - Hello C 

程序测试

# hello world litex-demo-app> helloc Hello C demo... C: Hello, world!  # donut litex-demo-app> donut Donut demo...                                                                                   $@@$$$$$$@@@                                                                $$$$$##########$$$$$                                                         #####**!!!!!!!!!!!**###$$$                                                    *###**!!=!=======!==!!!**#####                                                 *#***!!!!=;;:::::::;====!!**####                                               ****!!!=;;~~--,,.,,-~:;;==!!******                                             !***!!==;;:-,,........,~:;;==!!*****                                            !**!!!==;:~,...........-~:;=!!!!****=                                          =!!*!!!=;;:~,..       ..,~:;==!!!***!=                                          =!!*!!!==;:~-.         ~:;==!!!!*!!!!=                                          ;=!!*****!***!=       ;=!!!**!***!!!=;                                           ;=!!****########*!**###********!!!==:                                           :;!!***####$$$$@@$$$$$####****!!!==:                                             ~;=!!*####$$$$@@@@$$$###****!!!=;:                                               -;=!!***####$$$$$$$####***!!==:~                                                 ,~:=!!!***#######*#***!!!=;:~-                                                    ,~:;==!!!*******!!!==;;:~-                                                         .-::;;=======;;;:~~,                                                                .,,-------,..         

Bootloader

TODO

模块仿真

除了litex_sim能够对LiteX SoC仿真外,部分其他模块也拥有自己的仿真脚本

Module Name Simulation Script Path Description
liteth liteeth/bench/sim.py 网络仿真
litesdcard litesdcard/bench/sim.py SD Card仿真
liteiclink liteiclink/bench/serwb/sim.py 片间互联总线仿真
litedram litedram/litedram/phy/lpddr4/sim.py
litedram/litedram/phy/lpddr5/sim.py
SDRAM仿真
linux-on-litex-vexriscv linux-on-litex-vexriscv/sim.py Linux on VexRiscv仿真

 

请登录后发表评论

    没有回复内容