Chisel芯片开发入门系列 -- 14. CPU芯片开发和解释4(Load/Store指令再探)

接本系列的上一篇,本文继续介绍CPU的指令译码后的执行并特定针对Load/Store执行,也就是代码位于ChipCamp/riscv-chisel-book项目的src/main/scala/目录下的04_sw子目录(03_lw是昨天介绍的内容)!

04_sw和03_lw看似是并列的实际上是包含的,04的代码是在03的代码基础上增加的!比较一下这两个子目录,左侧03右侧04,右侧的文件均比左侧大。

Top.scala文件内容一样,只是package lw改成了package sw。

Memory.scala部分除了package lw改为sw以外,增加了两处代码,一个是在DmemPortIo的定义中增加了wen和wdata两个IO信号线,其中的w表示write(也就是Store的内存写),en表示enable(表示使能),和w一起则表示写使能信号,只有在写使能信号置位使能的情况下才将数据从DmemPortIo读取下来写到内存中,这正是第二块增量代码所表示的意思。当然这个Memory.scala还将代码文件(指令文件)从lw.hex变为了sw.hex。

Core.scala的部分除了package lw改为sw以外,有多处代码增加。其中指令译码(Instruction Decode, ID)部分,增加了imm_s_sext(指令中包含的有符号立即数,带符号扩展至32bit)。指令为sw的时候(也就是inst ===SW的时候)对alu_out赋值和(inst===LW)的时候有所区分,io.dmem.wen写使能标记位则只在(inst===SW)的时候置位。rs2_data赋值给io.dmem.wdata则不区分LW/SW,但实际上的逻辑则是靠io.dmem.wen控制的。

剩下的增加的部分就是debug的部分增加了打印dmem.wen和dmem.wdata了,如下所示。其中的exit信号置位条件是0x00602823的指令,这就要求我们在src/hex/sw.hex中有0x00602823作为结束程序运行的指令。

src/hex/sw.hex文件的构造,我们使用如下思路进行构造,构造出的SW指令是0x33802323:

把这个LW指令、SW指令、以及结束程序的指令0x00602823都写到src/hex/sw.hex中,如下所示,蓝色红色绿色深红色分别是LW指令、SW指令、一个任意构造的指令、结束指令:

$ cat src/hex/sw.hex
03
23
80
00
23
23
80
33
22
22
22
22
23
28
60
00

运行结果如下,其中蓝色的是LW指令,红色的是SW指令,从中可以看出rs1_addr等各个字段均和上面预期的是一致的,包括那个0x326(十进制806)。有一个特殊的地方是rs2_data的值是0x20250730!这是在Core.scala中通过对regfile(24)赋值实现的,这个对regfile(24)进行赋值的测试在此前的系列文章中有"预告"的,可翻看。

$ sbt "testOnly sw.HexTest"

info\] welcome to sbt 1.10.11 (Oracle Corporation Java 24.0.2) \[info\] loading settings for project chisel-template-build from plugins.sbt... \[info\] loading project definition from D:\\src\\chipcamp\\riscv-chisel-book\\chisel-template\\project \[info\] loading settings for project chisel-template from build.sbt... \[info\] set current project to chisel-template (in build file:/D:/src/chipcamp/riscv-chisel-book/chisel-template/) \[info\] compiling 1 Scala source to D:\\src\\chipcamp\\riscv-chisel-book\\chisel-template\\target\\scala-2.13\\classes ... \[warn\] \\src\\main\\scala\\04_sw\\Core.scala 37:39: \[W002\] Dynamic index with width 6 is too large for extractee of width 1 \[warn\] val rs1_data = Mux((rs1_addr =/= 0.U(WORD_LEN.U)), regfile(rs1_addr), 0.U(WORD_LEN.W)) \[warn\] \^ \[warn\] \\src\\main\\scala\\04_sw\\Core.scala 38:39: \[W002\] Dynamic index with width 6 is too large for extractee of width 1 \[warn\] val rs2_data = Mux((rs2_addr =/= 0.U(WORD_LEN.U)), regfile(rs2_addr), 0.U(WORD_LEN.W)) \[warn\] \^ \[warn\] There were 2 warning(s) during hardware elaboration. io.imem.addr=0x00000000, io.imem.inst=0x00802303, io.dmem.addr=0x00000008, io.dmem.rdata=0x22222222. pc_reg : 0x00000000 inst : 0x00802303 rs1_addr : 0 rs2_addr : 8 wb_addr : 6 rs1_data : 0x00000000 rs2_data : 0x00000000 wb_data : 0x22222222 dmem.addr : 8 dmem.wen : 0 dmem.wdata : 0x00000000 --------- io.imem.addr=0x00000004, io.imem.inst=0x33802323, io.dmem.addr=0x00000326, io.dmem.rdata=0x00000000. io.imem.dmem=0x00000326, io.imem.wdata=0x20250730. pc_reg : 0x00000004 inst : 0x33802323 rs1_addr : 0 rs2_addr : 24 wb_addr : 6 rs1_data : 0x00000000 rs2_data : 0x20250730 wb_data : 0x00000000 dmem.addr : 806 dmem.wen : 1 dmem.wdata : 0x20250730 --------- io.imem.addr=0x00000008, io.imem.inst=0x22222222, io.dmem.addr=0x00000000, io.dmem.rdata=0x00802303. pc_reg : 0x00000008 inst : 0x22222222 rs1_addr : 4 rs2_addr : 2 wb_addr : 4 rs1_data : 0x00000000 rs2_data : 0x02ffff00 wb_data : 0x00802303 dmem.addr : 0 dmem.wen : 0 dmem.wdata : 0x02ffff00 --------- \[info\] HexTest: \[info\] mycpu \[info\] - should work through hex \[info\] Run completed in 1 second, 311 milliseconds. \[info\] Total number of tests run: 1 \[info\] Suites: completed 1, aborted 0 \[info\] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0 \[info\] All tests passed. \[success\] Total time: 5 s, completed 2025骞?鏈?0鏃?09:51:57 \[0J 附上本次测试的代码提交记录: [Commits详情 - riscv-chisel-book:fork riscv-chisel-book by ChipCamp for Tutorial 20250703 - GitCode](https://gitcode.com/ChipCamp/riscv-chisel-book/commit/4ca111599dc3836fef77c872774e8f787fd701f7?ref=master "Commits详情 - riscv-chisel-book:fork riscv-chisel-book by ChipCamp for Tutorial 20250703 - GitCode") 附本次提交代码的操作流水备忘(git操作备忘): xxx@DESKTOP-ZZ4F56 MINGW64 /d/src/chipcamp/riscv-chisel-book/chisel-template (master) $ git status On branch master Your branch is up to date with 'origin/master'. Changes not staged for commit: (use "git add \..." to update what will be committed) (use "git restore \..." to discard changes in working directory) modified: src/hex/sw.hex modified: src/main/scala/04_sw/Core.scala no changes added to commit (use "git add" and/or "git commit -a") xxx@DESKTOP-ZZ4F56 MINGW64 /d/src/chipcamp/riscv-chisel-book/chisel-template (master) $ git diff diff --git a/chisel-template/src/hex/sw.hex b/chisel-template/src/hex/sw.hex index 5ee368a..a0de553 100644 --- a/chisel-template/src/hex/sw.hex +++ b/chisel-template/src/hex/sw.hex @@ -3,10 +3,14 @@ 80 00 23 -28 -60 -00 +23 +80 +33 22 22 22 22 +23 +28 +60 +00 diff --git a/chisel-template/src/main/scala/04_sw/Core.scala b/chisel-template/src/main/scala/04_sw/Core.scala index 53d2c76..cb63e9f 100644 --- a/chisel-template/src/main/scala/04_sw/Core.scala +++ b/chisel-template/src/main/scala/04_sw/Core.scala @@ -13,6 +13,10 @@ class Core extends Module { }) val regfile = Mem(32, UInt(WORD_LEN.W)) + regfile(1) := 0x01ffff00.U(WORD_LEN.W) + regfile(2) := 0x02ffff00.U(WORD_LEN.W) + regfile(3) := 0x030f0f00.U(WORD_LEN.W) + regfile(24) := 0x20250730.U(WORD_LEN.W) //\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* xxx@DESKTOP-ZZ4F56 MINGW64 /d/src/chipcamp/riscv-chisel-book/chisel-template (master) $ git add . xxx@DESKTOP-ZZ4F56 MINGW64 /d/src/chipcamp/riscv-chisel-book/chisel-template (master) $ git commit -m "20250730 update src/hex/sw.hex and src/main/scala/04_sw/Core.scala for Store instruction demo" \[master 4ca1115\] 20250730 update src/hex/sw.hex and src/main/scala/04_sw/Core.scala for Store instruction demo 2 files changed, 11 insertions(+), 3 deletions(-) xxx@DESKTOP-ZZ4F56 MINGW64 /d/src/chipcamp/riscv-chisel-book/chisel-template (master) $ git push Enumerating objects: 19, done. Counting objects: 100% (19/19), done. Delta compression using up to 12 threads Compressing objects: 100% (9/9), done. Writing objects: 100% (10/10), 994 bytes \| 994.00 KiB/s, done. Total 10 (delta 5), reused 0 (delta 0), pack-reused 0 (from 0) remote: Start Git Hooks Checking \[PASSED

To https://gitcode.com/ChipCamp/riscv-chisel-book.git

f580d29..4ca1115 master -> master

相关推荐
s09071362 小时前
Xilinx FPGA 中ADC 数据下变频+ CIC 滤波
算法·fpga开发·fpga·zynq
范纹杉想快点毕业3 小时前
FPGA面试百问:从基础到实战全解析
fpga开发
我送炭你添花4 小时前
可编程逻辑器件(PLD)的发展历程、原理、开发与应用详解
嵌入式硬件·fpga开发
步达硬件5 小时前
【FPGA】电子学习资料(持续更新)
fpga开发
Aaron15886 小时前
电子战侦察干扰技术在反无人机领域的技术浅析
算法·fpga开发·硬件架构·硬件工程·无人机·基带工程
window20197 小时前
青少年编程竞赛怎么准备?刷题、复盘与社区交流的重要性
青少年编程
window20197 小时前
青少年编程等级考试怎么选?看认证、内容与便利性
青少年编程
windfantasy19907 小时前
如何有效准备青少年编程竞赛?5步系统规划法
青少年编程
切糕师学AI7 小时前
ARM 架构中的 PRIMASK、FAULTMAST、BASEPRI 寄存器
arm开发·架构·嵌入式·寄存器
tang_shou7 小时前
STM32CubeMx使用STM32F4系列芯片实现串口DMA接收
c语言·arm开发·stm32·单片机·嵌入式硬件·mcu·stm32cubemx