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

相关推荐
I'm a winner5 小时前
FPGA 在情绪识别领域的护理应用(三)
fpga开发·前沿研究
小眼睛FPGA9 小时前
【盘古100Pro+开发板实验例程】FPGA学习 | gamma 变化 | 图像实验指导手册
科技·学习·ai·fpga开发·fpga
屁股割了还要学10 小时前
【数据结构入门】排序算法:插入排序
c语言·开发语言·数据结构·算法·青少年编程·排序算法
I'm a winner15 小时前
FPGA 在情绪识别领域的护理应用(二)
fpga开发·学习方法·前沿研究
yuyanjingtao1 天前
CCF-GESP 等级考试 2025年6月认证C++二级真题解析
c++·青少年编程·gesp·csp-j/s
9527华安2 天前
FPGA实现Aurora 64B66B图像视频点对点传输,基于GTH高速收发器,提供2套工程源码和技术支持
fpga开发·音视频·aurora·gth·高速收发器·64b66b
XINVRY-FPGA2 天前
EPM240T100I5N Altera FPGA MAX II CPLD
人工智能·嵌入式硬件·fpga开发·硬件工程·dsp开发·射频工程·fpga
第二层皮-合肥2 天前
FPGA实现ETH接口
单片机·嵌入式硬件·fpga开发
更深兼春远2 天前
spark+scala安装部署
大数据·spark·scala
璞致电子2 天前
【PZ-ZU47DR-KFB】璞致FPGA ZYNQ UltraScalePlus RFSOC QSPI Flash 固化常见问题说明
嵌入式硬件·fpga开发·fpga·软件无线电·sdr