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

相关推荐
No0d1es28 分钟前
第13届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2021年11月27日真题
python·青少年编程·蓝桥杯·选拔赛
@珍惜一生@2 小时前
xerces-c-src_2_8_0 arm_linux编译
linux·c语言·arm开发
嵌入式郑工2 小时前
Linux内核构建系统中的auto.conf与autoconf.h:原理与作用解析
arm开发
No0d1es4 小时前
第13届蓝桥杯Python青少组_省赛_中/高级组_2022年4月17日真题
算法·青少年编程·蓝桥杯·中高组
明月看潮生6 小时前
编程与数学 03-002 计算机网络 17_云计算与网络
计算机网络·青少年编程·云计算·编程与数学
霖006 小时前
深入讲讲异步FIFO
笔记·vscode·单片机·嵌入式硬件·学习·fpga开发
水果里面有苹果8 小时前
3-verilog的使用-1
fpga开发
is08158 小时前
LVGL 使用自定义字体
arm开发
嵌入式-老费9 小时前
再谈fpga开发(总结篇)
fpga开发