当前位置: 首页 > news >正文

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

目录

  • 介绍
    • 环境依赖
    • litex_sim
  • 入门仿真
  • litex_server、litex_cli、litescope_cli仿真调试
    • litex_sim仿真窗口
    • litex_server窗口
    • litex_cli窗口
    • litescope_cli窗口
  • 波形DUMP
    • 方法一:导出指定时间段的波形
    • 方法二:在命令行中配置寄存器控制波形导出
    • 方法三:litex_cli配置寄存器控制波形导出
      • litex_sim仿真窗口
      • litex_server窗口
      • litex_cli窗口
  • Video
    • Color Bars
    • Terminal Console
    • Frame Buffer
    • Frame Buffer(通过litex_cli传输图像)
    • 注意
  • 替换BIOS
  • Bootloader
  • 模块仿真

介绍

环境依赖

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-LabsBIOS built on Aug 17 2024 16:26:13BIOS 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> helpLiteX 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 helpserialboot               - Boot from Serial (SFL)
reboot                   - Reboot
boot                     - Boot from Memorymem_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 regionslitex> 

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 1500inet 192.168.1.100  netmask 255.255.255.0  broadcast 192.168.1.255inet6 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 0TX 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> helpLiteX 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/litexlitex_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 NameSimulation Script PathDescription
litethliteeth/bench/sim.py网络仿真
litesdcardlitesdcard/bench/sim.pySD Card仿真
liteiclinkliteiclink/bench/serwb/sim.py片间互联总线仿真
litedramlitedram/litedram/phy/lpddr4/sim.py
litedram/litedram/phy/lpddr5/sim.py
SDRAM仿真
linux-on-litex-vexriscvlinux-on-litex-vexriscv/sim.pyLinux on VexRiscv仿真

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 谷歌的高级指令有哪些
  • 测试流程自动化实践!
  • Qcadoo MES(生产制造管理系统)编译、运行的相关配置
  • 【Python】函数入门(上)
  • Mac安装完maven,报zsh: command not found: mvn解决
  • ArcGIS简单介绍
  • 【屏驱MCU】系列文章合集
  • xssnote
  • 【微信小程序】网络数据请求
  • Spring由哪些模块组成?
  • 【已解决】tokenizer.chat_template is not set and no template argument was passed
  • dockers 阿里云镜像失效后如何配置,可视化操作
  • Linux如何查看服务启动状态是否开机自动启动
  • STM32(二):GPIO
  • 数据结构:线性结构之顺序表、链表篇
  • [译] 怎样写一个基础的编译器
  • 11111111
  • ECMAScript入门(七)--Module语法
  • KMP算法及优化
  • miaov-React 最佳入门
  • ng6--错误信息小结(持续更新)
  • Python学习笔记 字符串拼接
  • vue中实现单选
  • 程序员最讨厌的9句话,你可有补充?
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 高性能JavaScript阅读简记(三)
  • 给Prometheus造假数据的方法
  • 后端_MYSQL
  • 理清楚Vue的结构
  • 人脸识别最新开发经验demo
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 实习面试笔记
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 原生JS动态加载JS、CSS文件及代码脚本
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​​​​​​​开发面试“八股文”:助力还是阻力?
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • # Redis 入门到精通(一)数据类型(4)
  • #07【面试问题整理】嵌入式软件工程师
  • #数据结构 笔记三
  • #数学建模# 线性规划问题的Matlab求解
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (09)Hive——CTE 公共表达式
  • (13)Hive调优——动态分区导致的小文件问题
  • (4)(4.6) Triducer
  • (PySpark)RDD实验实战——求商品销量排行
  • (翻译)terry crowley: 写给程序员
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (一)基于IDEA的JAVA基础10
  • (原创)可支持最大高度的NestedScrollView
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...