USTC-RVSoC/README.md

116 lines
7.3 KiB
Markdown
Raw Normal View History

2019-02-05 16:19:46 +08:00
# USTCRVSoC
2019-02-05 17:00:24 +08:00
2019-03-03 15:58:27 +08:00
一个用SystemVerilog编写的基于RISC-V的普林斯顿结构的SoC
2019-02-05 17:00:24 +08:00
2019-02-07 19:36:33 +08:00
# 特点
2019-02-11 21:40:34 +08:00
> * 5段流水线RISC-V能运行RV32I指令集
> * 简单直观的32bit握手总线 (naive_bus.sv)
> * 总线仲裁器(naive_bus_router.sv)可修改以方便拓展外设、多核、DMA等
> * 具有交互式UART调试器(isp_uart.sv)用户可以使用PC上的串口助手、minicom等软件实现系统复位、上传程序、查看内存等功能
2019-03-03 02:42:38 +08:00
> * 全部使用 SystemVerilog 实现不调用IP核方便在 Altera、Xilinx、Lattice 等不同FPGA平台上移植也方便在各种工具中进行仿真
2019-03-03 15:58:27 +08:00
> * RAM 和 ROM 符合一定的Verilog写法自动综合成 Block RAM
2019-02-07 19:36:33 +08:00
2019-02-05 17:00:24 +08:00
# SoC 结构
2019-02-08 00:38:18 +08:00
![Image text](https://github.com/WangXuan95/USTCRVSoC/blob/master/images/SoC.png)
2019-02-05 17:00:24 +08:00
2019-02-11 21:40:34 +08:00
上图展示了SoC的结构总线仲裁器bus_router为SoC的中心上面挂载了2个“主设备”和5个“从设备”。实际上CPU具有两个“主接口”因此bus_router共有3个“主接口”和5个“从接口”。
2019-02-05 21:22:07 +08:00
2019-02-11 21:40:34 +08:00
这个SoC使用的总线并不来自于任何标准例如AXI或APB总线而是笔者自编的因为简单所以命名为“naive_bus”。
2019-02-05 21:22:07 +08:00
2019-02-11 21:40:34 +08:00
每个“从接口”都占有一段地址空间。当“主接口”访问总线时bus_router判断该地址属于哪个地址空间然后将它“路由”到相应的“从接口”。下表展示了5个“从接口”的地址空间。
2019-02-05 17:00:24 +08:00
2019-02-11 21:40:34 +08:00
| 外设类型 | 起始地址 | 结束地址 |
| :-----: | :-----: | :----: |
| 指令ROM | 0x00000000 | 0x00007fff |
| 指令RAM | 0x00008000 | 0x00008fff |
| 数据RAM | 0x00010000 | 0x00010fff |
| 显存RAM | 0x00020000 | 0x00020fff |
| 用户UART | 0x00030000 | 0x00030003 |
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
### 主要部件
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
> * **多主多从总线仲裁器(naive_bus_router.sv)**:为每个从设备划分地址空间,将主设备的总线读写请求路由到从设备。当多个主设备同时访问一个从设备时,还能进行访问冲突控制。
> * **RV32I Core(core_top.sv)**:包括两个主接口。一个用于取指令,一个用于读写数据
> * **UART调试器(isp_uart.sv)**包括一个主接口和一个从接口。它接收用户从UART发来的命令对总线进行读写。它可以用于在线烧写、在线调试。也可以接收CPU的命令去发送数据。
2019-02-11 21:40:34 +08:00
> * **指令ROM(instr_rom.sv)**CPU默认从这里开始取指令多用于仿真
2019-02-11 21:50:31 +08:00
> * **指令RAM(ram_bus_wrapper.sv)**:用户在线烧写程序到这里。
2019-02-11 21:40:34 +08:00
> * **数据RAM(ram_bus_wrapper.sv)**:存放运行时的数据。
> * **显存RAM(vedio_ram.sv)**在屏幕上显示98列*36行=3528个字符显存RAM的前3528B对应的ASCII码值就决定了每个字符是什么
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
# RV32I CPU 结构
2019-02-08 00:38:18 +08:00
![Image text](https://github.com/WangXuan95/USTCRVSoC/blob/master/images/Core-RTL.png)
TODO
# 在开发板上运行SoC
2019-02-08 00:38:18 +08:00
我们提供了两种方式运行代码:
2019-02-11 21:40:34 +08:00
1、**使用指令ROM**修改instr_rom.sv中的代码然后重新编译综合重新烧写FPGA逻辑。虽然麻烦但这便于进行RTL仿真你可以将想要运行的程序放入指令ROM然后仅需在testbench中给予SoC一个时钟就可以观察整个SoC在运行这段代码时的波形。
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
2、**使用指令RAM**使用UART调试器在线上传程序到指令RAM。
2019-02-08 00:38:18 +08:00
### 部署电路到FPGA
目前我们提供了Xilinx的Nexys4板子和Altera的DE0-Nano板子的工程。
1、**Nexys4硬件连接**Nexys4开发板上有一个USB口既可以用于FPGA烧录也可以用于UART通信我们需要连接该USB口到电脑。另外VGA的连接是可选的你可以把它连接到屏幕上。
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
![Image text](https://github.com/WangXuan95/USTCRVSoC/blob/master/images/DE0-Nano.png)
2019-02-08 00:38:18 +08:00
2、**DE0-Nano硬件连接**DE0-Nano开发板上既没有串口转USB也没有VGA接口。因此都需要以来外部模块。我们使用DE0-Nano上的两排GPIO作为外接模块的引脚接口意义如上图。你至少需要一个USB转UART的模块将ISP-UART的TX和RX引脚连接上去使之能与电脑通信如下图
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
![Image text](https://github.com/WangXuan95/USTCRVSoC/blob/master/images/connection.png)
2019-02-08 00:38:18 +08:00
2019-02-11 21:50:31 +08:00
![Image text](https://github.com/WangXuan95/USTCRVSoC/blob/master/images/usb_uart.png)
2019-02-08 00:38:18 +08:00
3、**综合、烧写FPGA**如果你用的是Nexys4板子请用Vivado打开./hardware/Vivado/nexys4/USTCRVSoC-nexys4/USTCRVSoC-nexys4.xpr。如果你用的是DE0-Nano板子请用Quartus打开./hardware/Quartus/DE0_Nano/DE0_Nano.qpf。综合并烧写到开发板。
2019-02-11 21:50:31 +08:00
4、**HelloWorld**烧录FPGA后在电脑上的串口终端软件超级终端、串口助手、minicom使用格式(115200,n,8,1)打开串口,如果看到不断收到"hello\n"那么恭喜你SoC部署成功因为SoC的instr_rom里的程序就是循环打印hello的程序。
2019-02-08 00:38:18 +08:00
5、**尝试读取总线**下面让我们尝试UART的调试功能首先发送"s\n"进入调试模式,可以看到对方发来"debug\n",说明进入调试模式成功。然后,发送"00000000\n"会看到对方发来一个8位16进制数。该数代表SoC数据总线的地址0x00000000处的读取数据。
2019-02-08 00:38:18 +08:00
6、上一步我们尝试了UART调试器的读总线命令下表显示了它的所有3种命令。
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
![Image text](https://github.com/WangXuan95/USTCRVSoC/blob/master/images/commands.png)
2019-02-08 00:38:18 +08:00
> * 注意:无论是发送还是接受,所有命令都以\n或\r或\r\n结尾
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
根据这些命令,不难猜出,在线上传程序的流程是:
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
> 1、使用写命令将指令流写入指令RAM指令RAM的地址是00008000~00008fff
2019-02-11 21:50:31 +08:00
2019-02-28 13:47:08 +08:00
> 2、使用复位命令r00008000将CPU复位并从指令RAM中BOOT
2019-02-08 00:38:18 +08:00
### 使用工具USTCRVSoC-tool (该软件有所改动,文档稍后补充)
2019-02-08 00:38:18 +08:00
./USTCRVSoC-tool/USTCRVSoC-tool.exe 是一个能汇编和烧写的小工具相当于一个汇编语言的IDE。
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
我们提供了几个汇编小程序如下表。
2019-02-08 00:38:18 +08:00
2019-02-11 21:40:34 +08:00
| 文件名 | 说明 |
| :----- | :----- |
| uart_print.S | 用户UART循环打印hello! |
| vga_hello.S | 屏幕上显示hello |
| fibonacci_recursive.S | 递归法计算斐波那契数列第7个数并用用户UART打印结果 |
| load_store.S | 完成一些内存读写没有具体表现为了观察现象可以使用UART调试器查看内存 |
2019-02-08 00:38:18 +08:00
2019-03-03 15:58:27 +08:00
现在我们尝试让SoC运行一个计算斐波那契数列并UART打印的程序。点击“打开...”按钮,浏览到目录./software/asm-code打开汇编文件 fibonacci_recursive.S。点击右侧的“汇编”按钮可以看到右方框里出现了一串16进制数这就是汇编得到的机器码。然后选择正确的COM口点击“烧写”如果下方状态栏里显示“烧写成功”则CPU就已经开始运行该机器码了。这时在右侧的“串口查看”框里选中“16进制显示”可以看到不断显示出22这说明CPU正确的计算出斐波那契数列的第七个数是0x22即十进制的34。
2019-02-08 00:38:18 +08:00
2019-02-05 21:22:07 +08:00
2019-02-11 21:40:34 +08:00
# RTL仿真
2019-02-05 21:22:07 +08:00
2019-02-11 21:40:34 +08:00
### 生成Verilog ROM
2019-02-11 21:50:31 +08:00
USTCRVSoC-tool.exe 除了进行烧写也可以生成指令ROM的Verilog代码。当你使用“汇编”按钮产生指令流后可以点击右侧的“保存指令流(Verilog)”按钮用生成的ROM代码替换 ./RTL/instr_rom.sv
2019-02-05 17:00:24 +08:00
2019-02-08 00:38:18 +08:00
### 进行仿真
2019-02-05 17:00:24 +08:00
2019-02-11 21:40:34 +08:00
生成ROM后请直接使用soc_top_tb.sv文件进行仿真这个仿真是针对整个SoC的因此你可以修改ROM程序后进行仿真观察SoC运行该程序的行为。