初版,Logisim转换Verilog

This commit is contained in:
2026-09-12 13:18:24 +08:00
commit 03ac91bf65
12 changed files with 3406 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
pipelined-cpu/*
File diff suppressed because it is too large Load Diff
+60
View File
@@ -0,0 +1,60 @@
# `cpu21-riscv-4.circ` 的 Verilog 实现
文件:`cpu21_riscv_redirect_int_bpb.v`
该文件对应原电路中的“重定向流水线+中断+分支预测”部分,顶层模块为
`cpu21_riscv_redirect_int_bpb`,并包含独立的 `cpu21_riscv_alu``cpu21_bpb_8` 模块。
## 已转换的功能
- 五级流水:IF、ID、EX、MEM、WB。
- EX/MEM 与 MEM/WB 前递,以及 load-use 一拍停顿。
- 条件分支 `beq``bne``bltu` 在 EX 段判定,错误预测时清空 IF/ID、ID/EX 并重定向 PC。
- `jal``jalr` 在 EX 段重定向,返回地址写回 `rd`
- 8 项全相联 BPB:标签 `PC[11:2]`,每项包含 valid、目标 PC、2 位饱和计数器和 3 位年龄字段。BPB 只由条件分支更新,避免 `jal``jalr` 占用不会被查询的表项;未命中时优先使用无效项,否则替换年龄最大的项。
- 三路中断输入 `irq_i[2:0]`:两级同步、上升沿挂起、IRQ3 > IRQ2 > IRQ1 优先级,仅在 `ustatus[0]`MIE)允许时响应。
- 支持嵌套中断:保存 EPC、`ustatus` 和当前优先级;`URET` 使用当前 `uepc` 返回,并从硬件栈恢复外层上下文。三个入口按照原电路的 `INTpc` 选择:IRQ1=`0x30ac`、IRQ2=`0x31e4`、IRQ3=`0x3310``0x22``ecall` 的服务号 34,不是中断向量。
- CSRRSI、CSRRCI,以及 CSRRW:支持 CSR 地址 `0x004``ustatus`)和 `0x041``uepc`)。立即数为 `IR[19:15]` 的零扩展值,并按 RISC-V 规则把旧 CSR 值写回 `rd`;这覆盖任务书中的 `csrrsi s6,0x41,0``csrrw zero,0x41,s6` 用法。
- `ecall``a7 == 34` 时把 `a0` 锁存到 `led_data_o`;否则置 `halted_o`,直到 `go_i` 为高。
- `sw``sb`:输出 `data_wstrb_o`,支持按字节写入。
## 指令编码
表中的 `opcode` 是控制器使用的五位字段 `IR[6:2]`,不是包含最低两位的 7 位原始 opcode。
因此它与标准 RISC-V 指令的低 7 位 opcode 相差右移两位。
| 指令类别 | opcode | 说明 |
| ---------------------- | -----: | --------------------------------------- |
| R 型 | `0x0c` | add/sub/and/or/xor/slt/sltu/sll/srl/sra |
| I 型 ALU | `0x04` | addi/andi/ori/xori/slti/slli/srli/srai |
| `lw` | `0x00` | `funct3=010` |
| `sw` / `sb` | `0x08` | `funct3=010` / `000` |
| `beq` / `bne` / `bltu` | `0x18` | `funct3=000` / `001` / `110` |
| `jal` | `0x1b` | J 型立即数 |
| `jalr` | `0x19` | `funct3=000` |
| 系统类 | `0x1c` | `ecall``URET`、CSRRSI、CSRRCI |
`ecall``URET` 都是 `opcode=0x1c、funct3=0`,由 `IR[21]` 区分:
`IR[21]=0``ecall``IR[21]=1``URET`。这一点来自原控制器中的 `IR21` 分支逻辑。
## 顶层端口约定
- `instr_i`:当前 `instr_addr_o` 对应的 32 位指令。原 Logisim 中由 ROM 提供。
- `data_rdata_i`:当前 `data_addr_o` 的读数据。原 Logisim 中由 MIPS RAM 提供。
- `data_addr_o``data_wdata_o``data_wstrb_o``data_we_o`:数据存储器接口。地址按字节地址输出;若使用原 32 位 RAM,可用 `data_addr_o[11:2]` 作为字地址。
- `irq_i[0]``irq_i[1]``irq_i[2]`:1、2、3 号中断源;输入应为脉冲或边沿信号,模块内部会同步并锁存挂起状态。
- `go_i`:对应原电路的“继续运行”按键。
- `if_pc_o``id_pc_o``ex_pc_o``mem_pc_o``wb_pc_o`:五级流水当前保存的 PC,气泡时输出 0,便于替代原电路的调试探针。
- `rdin_o``mdin_o``reg_write_o``mem_write_o`:对应原电路的寄存器写回和存储器写调试输出。
- `cycle_count_o``stall_count_o``bubble_count_o``conditional_taken_count_o``unconditional_branch_count_o``prediction_success_count_o``prediction_failure_count_o`:对应原电路和课程要求的周期、停顿/气泡、分支和动态预测统计量。
## 时序和使用说明
1. `reset` 为高时异步清空流水线、寄存器文件、BPB、挂起中断和中断栈,PC 置为 `RESET_PC``ustatus` 复位为参数 `USTATUS_INIT`,默认 `0x0000_0001`(MIE 上电即使能)。这样做的原因是课程的中断测试程序只在中断处理程序的“保护现场”之后写 MIE,主流程不会开中断;若不默认使能,第一次中断只会挂在 `irq_pending_o` 上而永不响应。参数可覆盖,例如把 `USTATUS_INIT` 设为 `32'h0` 即可恢复“上电关中断”的行为。
2. 指令存储器按组合读处理;数据存储器读数据在一个 MEM 周期内返回。若 RAM 为同步读,需要在外部增加一级数据寄存或相应调整 MEM/WB。
3. 响应中断时允许当前 EX 指令完成,并保存下一条尚未执行指令的 PC;若 EX 是已正确预测的跳转分支,则保存实际目标地址。EX 为空时优先保存 IF/ID 中尚未执行的 PC。这样 `URET` 不会重复执行已经提交的存储或寄存器写操作。
4. 默认 BPB 新表项采用弱不跳转/弱跳转状态:首次更新为不跳转时计数器为 `01`,首次更新为跳转时为 `10`;命中后按 2 位饱和规则增减。
5. `bpb_predict_hit_o``bpb_predict_taken_o``bpb_mispredict_o``irq_*_o` 是观测端口,不参与外部控制,可以直接接逻辑分析仪或测试平台。
6. `cycle_count_o``halted_o` 为高时暂停;load-use 每次计入一个气泡,重定向或中断清空 IF/ID 与当前 IF 时计入两个气泡。
`.circ` 文件中的 ROM、MIPS RAM、按钮、LED 和调试显示器属于 Logisim 外围,不直接搬入 RTL;其功能分别由指令接口、数据接口、`go_i``led_*_o` 和调试端口替代。
@@ -0,0 +1,267 @@
7d000113
00100413
01f41993
41f9d993
00000433
00c00913
00800b13
00140413
00f47413
00800293
00100313
00499993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
00140413
00f00f93
01f47433
01c41413
00800293
00100313
0049d993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
01c45413
406b0b33
000b0463
f95ff06f
000002b3
fff2c293
01029293
fff2e293
00500533
02200893
00000073
f5dff06f
00512023
00410113
01c12023
00410113
00912023
00410113
01112023
00410113
00a12023
00410113
00812023
00410113
01312023
00410113
01412023
00410113
01512023
00410113
01612023
00410113
04106b73
01612023
00410113
0040e073
00200293
01100493
00849493
01148493
01049493
00900533
02200893
00000073
01c00e13
0254d4b3
00900533
02200893
00000073
fffe0e13
fe0e16e3
00a00893
00100b13
00300a13
00100a93
01600433
00441413
014469b3
01300533
02200893
00000073
fe0416e3
415a0a33
fe0a10e3
0040f073
ffc10113
00012b03
041b1073
ffc10113
00012b03
ffc10113
00012a83
ffc10113
00012a03
ffc10113
00012983
ffc10113
00012403
ffc10113
00012503
ffc10113
00012883
ffc10113
00012483
ffc10113
00012e03
ffc10113
00012283
00200073
00612023
00410113
01c12023
00410113
00912023
00410113
01212023
00410113
01112023
00410113
00a12023
00410113
00812023
00410113
01312023
00410113
01412023
00410113
01512023
00410113
01612023
00410113
04106b73
01612023
00410113
0040e073
ff100493
00900533
02200893
00000073
00148493
fe04c8e3
00a00893
00200b13
00300a13
00100a93
01600433
00441413
014469b3
01300533
02200893
00000073
fe0416e3
415a0a33
fe0a10e3
0040f073
ffc10113
00012b03
041b1073
ffc10113
00012b03
ffc10113
00012a83
ffc10113
00012a03
ffc10113
00012983
ffc10113
00012403
ffc10113
00012503
ffc10113
00012883
ffc10113
00012903
ffc10113
00012483
ffc10113
00012e03
ffc10113
00012303
00200073
00912023
00410113
01112023
00410113
00a12023
00410113
00812023
00410113
01312023
00410113
01412023
00410113
01512023
00410113
01612023
00410113
04106b73
01612023
00410113
0040e073
00000313
02000e13
00000493
00100913
00930023
00900533
02200893
00000073
012484b3
00130313
fffe0e13
fe0e12e3
00800e13
00000313
00032483
00900533
02200893
00000073
00430313
fffe0e13
fe0e14e3
00a00893
00300b13
00300a13
00100a93
01600433
00441413
014469b3
01300533
02200893
00000073
fe0416e3
415a0a33
fe0a10e3
0040f073
ffc10113
00012b03
041b1073
ffc10113
00012b03
ffc10113
00012a83
ffc10113
00012a03
ffc10113
00012983
ffc10113
00012403
ffc10113
00012503
ffc10113
00012883
ffc10113
00012483
00200073
Binary file not shown.
@@ -0,0 +1,428 @@
#############################################################
#jal,jalr指令
#############################################################
.text
addi s1,zero, 1 #jal,jalrr指令
j jmp_next1 #jal x0,8
addi s1,zero, 1
addi s2,zero, 2
addi s3,zero, 3
jmp_next1:
j jmp_next2
addi s1,zero, 1
addi s2,zero, 2
addi s3,zero, 3
jmp_next2:
j jmp_next3
addi s1,zero, 1
addi s2,zero, 2
addi s3,zero, 3
jmp_next3:
j jmp_next4
addi s1,zero, 1
addi s2,zero, 2
addi s3,zero, 3
jmp_next4:jal jmp_count
# addi,sll,add,ecall,srl,sll,sra,beq,j,ecall revise date:2015/12/16 tiger
.text
addi s0,zero,1 #011151
addi s1,zero,1
slli s1, s1, 31 #31 s1=0x80000000
###################################################################
#
# 0x80000000 0x20000000 0x08000000 0x02000000 0x00800000 0x00200000 0x00080000 0x00020000 0x00008000 0x00002000 0x00000800 0x00000200 0x00000080 0x00000020 0x00000008 0x00000002 0x00000000
###################################################################
LogicalRightShift: #1
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srli s1, s1, 2
beq s1, zero, shift_next1
j LogicalRightShift
shift_next1:
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
###################################################################
#
# 0x00000004 0x00000010 0x00000040 0x00000100 0x00000400 0x00001000 0x00004000 0x00010000 0x00040000 0x00100000 0x00400000 0x01000000 0x04000000 0x10000000 0x40000000 0x00000000
###################################################################
addi s1,zero, 1
LogicalLeftShift: #1
slli s1, s1, 2
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
beq s1, zero, ArithRightShift
j LogicalLeftShift
###################################################################
#
# 0x80000000 0xf0000000 0xff000000 0xfff00000 0xffff0000 0xfffff000 0xffffff00 0xfffffff0 0xffffffff
###################################################################
ArithRightShift: ##80000000F0000000,FF000000,FFF00000,FFFF0000直至FFFFFFFF
addi s1,zero,1
slli s1, s1, 31 #31 s1=0x80000000
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 3 #s1=0X80000000-->0XF0000000
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4 #0XF0000000-->0XFF000000
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4 #0XFF000000-->0XFFF00000
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
#############################################################
#,addi,andi,sll,srl,sra,or,ori,nor,ecall LED按走马灯方式来回显示数据
#############################################################
.text
addi s0,zero,1
slli s3, s0, 31 # s3=0x80000000
srai s3, s3, 31 # s3=0xFFFFFFFF
add s0,zero,zero # s0=0
addi s2,zero,12
addi s6,zero,3 #
zmd_loop:
addi s0, s0, 1 #
andi s0, s0, 15
#######################################
addi t0,zero,8
addi t1,zero,1
left:
slli s3, s3, 4 #
or s3, s3, s0
add a0,zero,s3 # display s3
addi a7,zero,34 # system call for LED display
ecall # display
sub t0,t0,t1
bne t0,zero,left
#######################################
addi s0, s0, 1 #
addi t6,zero,15
and s0, s0, t6
slli s0, s0, 28
addi t0,zero,8
addi t1,zero,1
zmd_right:
srli s3, s3, 4 #
or s3, s3, s0
add a0,zero,s3 # display s3
addi a7,zero,34 # system call for LED display
ecall # display
sub t0,t0,t1
bne t0,zero,zmd_right
srli s0, s0, 28
#######################################
sub s6,s6,t1
beq s6,zero, exit
j zmd_loop
exit:
add t0,zero,zero
xori t0,t0,-1 #test r xori
slli t0,t0,8
ori t0,t0,255
add a0,zero,t0 # display t0
addi a7,zero,34 # system call for LED display
ecall # display
#################################################################################
#0-15,rars 仿
#rars Setting中的Memory Configuration设置为Compactdata at address 0
#################################################################################
.text
sort_init:
addi s0,zero,-1
addi s1,zero,0
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
addi s0,s0,1
add s0,zero,zero
addi s1,zero,60 #
sort_loop:
lw s3,0(s0)
lw s4,0(s1)
slt t0,s3,s4
beq t0,zero,sort_next #
sw s3, 0(s1)
sw s4, 0(s0)
sort_next:
addi s1, s1, -4
bne s0, s1, sort_loop
add a0,zero,s0 #display s0
addi a7,zero,34 # display hex
ecall # we are out of here. DISP: disp r0, 0
addi s0,s0,4
addi s1,zero,60
bne s0, s1, sort_loop
addi a7,zero,10 # benchmark ecall # CCAB
#############################################
# insert your ccmb benchmark program here!!!
#############################################
#===== [1] CDIVU divu/mflo=====
#0x11110000 0x08888000 0x04444000 0x02222000 0x01111000 0x00888800 0x00444400 0x00222200 0x00111100 0x00088880 0x00044440 0x00022220 0x00011110 0x00008888 0x00004444 0x00002222 0x00001111 0x00000888 0x00000444 0x00000222 0x00000111 0x00000088 0x00000044 0x00000022 0x00000011 0x00000008 0x00000004 0x00000002 0x00000001
addi t0,zero,2 # /2
addi s1,zero, 0x11
slli s1,s1,8
addi s1,s1,0x11
slli s1,s1,16
add a0,zero,s1
addi a7,zero,34
ecall
addi t3,zero,28 #
divu_branch:
divu s1,s1,t0 #
add a0,zero,s1
addi a7,zero,34
ecall #
addi t3,t3, -1
bne t3,zero,divu_branch #
addi a7,zero,10 # 退
#===== [2] CREMU =====
# 0x87540110
addi s1,x0,0x88
slli s1,s1,8
addi s1,s1,0x48
addi s2,x0,0x87
slli s2,s2,8
addi s2,s2,0x54
remu s2,s2,s1
slli s2,s2,16
ori s2,s2,0x110
add a0,zero,s2
addi a7,zero,34 # system call for print
ecall
addi a7,zero,10 # system call for exit
#===== [3] ASB =====
# 0x00000000 0x00000001 0x00000002 0x00000003 0x00000004 0x00000005 0x00000006 0x00000007 0x00000008 0x00000009 0x0000000a 0x0000000b 0x0000000c 0x0000000d 0x0000000e 0x0000000f 0x00000010 0x00000011 0x00000012 0x00000013 0x00000014 0x00000015 0x00000016 0x00000017 0x00000018 0x00000019 0x0000001a 0x0000001b 0x0000001c 0x0000001d 0x0000001e 0x0000001f 0x03020100 0x07060504 0x0b0a0908 0x0f0e0d0c 0x13121110 0x17161514 0x1b1a1918 0x1f1e1d1c
addi t1,zero,0 #init_addr
addi t3,zero,32 #counter
#sb写入 01,02,03,04
addi s1,zero, 0x00 #
addi s2,zero, 0x01 #
sb_store:
sb s1,(t1)
add a0,zero,s1
addi a7,zero,34 # system call for print
ecall # print
add s1,s1,s2 #data +1
addi t1,t1,1 # addr ++
addi t3,t3,-1 #counter
bne t3,zero,sb_store
addi t3,zero,8
addi t1,zero,0 # addr
sb_branch:
lw s1,(t1) #
add a0,zero,s1
addi a7,zero,34 # system call for print
ecall # print
addi t1,t1,4
addi t3,t3, -1
bne t3,zero,sb_branch
addi a7,zero,10 # system call for exit
#===== [4] BBLT =====
#0xfffffff1 0xfffffff2 0xfffffff3 0xfffffff4 0xfffffff5 0xfffffff6 0xfffffff7 0xfffffff8 0xfffffff9 0xfffffffa 0xfffffffb 0xfffffffc 0xfffffffd 0xfffffffe 0xffffffff
addi s1,zero,-15 #
blt_branch:
add a0,zero,s1
addi a7,zero,34
ecall #
addi s1,s1,1
blt s1,zero,blt_branch #
ccab_end:
addi a7,zero,10
#ecall
jmp_count: addi s0,zero, 0
addi s0,s0, 1
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 2
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 3
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 4
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 5
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 6
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 7
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 8
add a0,zero,s0
addi a7,zero,34 # display hex
addi a7,zero,34 # display hex
ecall # we are out of here.
ret #persudo instruction jalr x0,x1,0
@@ -0,0 +1,282 @@
v2.0 raw
00100493
0100006f
00100493
00200913
00300993
0100006f
00100493
00200913
00300993
0100006f
00100493
00200913
00300993
0100006f
00100493
00200913
00300993
394000ef
00100413
00100493
01f49493
00900533
02200893
00000073
0024d493
00048463
fedff06f
00900533
02200893
00000073
00100493
00249493
00900533
02200893
00000073
00048463
fedff06f
00100493
01f49493
00900533
02200893
00000073
4034d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
00100413
01f41993
41f9d993
00000433
00c00913
00300b13
00140413
00f47413
00800293
00100313
00499993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
00140413
00f00f93
01f47433
01c41413
00800293
00100313
0049d993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
01c45413
406b0b33
000b0463
f95ff06f
000002b3
fff2c293
00829293
0ff2e293
00500533
02200893
00000073
fff00413
00000493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
00140413
00000433
03c00493
00042983
0004aa03
0149a2b3
00028663
0134a023
01442023
ffc48493
fe9412e3
00800533
02200893
00000073
00440413
03c00493
fc9416e3
00a00893
00000073
00200293
01100493
00849493
01148493
01049493
00900533
02200893
00000073
01c00e13
0254d4b3
00900533
02200893
00000073
fffe0e13
fe0e16e3
00a00893
00000073
08800493
00849493
04848493
08700913
00891913
05490913
02997933
01091913
11096913
01200533
02200893
00000073
00a00893
00000073
00000313
02000e13
00000493
00100913
00930023
00900533
02200893
00000073
012484b3
00130313
fffe0e13
fe0e12e3
00800e13
00000313
00032483
00900533
02200893
00000073
00430313
fffe0e13
fe0e14e3
00a00893
00000073
ff100493
00900533
02200893
00000073
00148493
fe04c8e3
00a00893
00000073
00000413
00140413
00800533
02200893
00000073
00240413
00800533
02200893
00000073
00340413
00800533
02200893
00000073
00440413
00800533
02200893
00000073
00540413
00800533
02200893
00000073
00640413
00800533
02200893
00000073
00740413
00800533
02200893
00000073
00840413
00800533
02200893
02200893
00000073
00008067
@@ -0,0 +1,421 @@
.text
addi sp, zero, 2000 #
#############################################################
#?,addi,andi,slli,srli,srai,or,ori,nor,ecall LED按走马灯方式来回显示数据
#############################################################
.text
START:
addi s0,zero,1
slli s3, s0, 31 # s3=0x80000000
srai s3, s3, 31 # s3=0xFFFFFFFF
add s0,zero,zero # s0=0
addi s2,zero,12
addi s6,zero,8 #
zmd_loop:
addi s0, s0, 1 #
andi s0, s0, 15
#######################################
addi t0,zero,8
addi t1,zero,1
left:
slli s3, s3, 4 #
or s3, s3, s0
add a0,zero,s3 # display s3
addi a7,zero,34 # system call for LED display
ecall # display
sub t0,t0,t1
bne t0,zero,left
#######################################
addi s0, s0, 1 #
addi t6,zero,15
and s0, s0, t6
slli s0, s0, 28
addi t0,zero,8
addi t1,zero,1
zmd_right:
srli s3, s3, 4 #
or s3, s3, s0
add a0,zero,s3 # display s3
addi a7,zero,34 # system call for LED display
ecall # display
sub t0,t0,t1
bne t0,zero,zmd_right
srli s0, s0, 28
#######################################
sub s6,s6,t1
beq s6,zero, exit
j zmd_loop
exit:
add t0,zero,zero
xori t0,t0,-1 #test nor ori
slli t0,t0,16
ori t0,t0,-1
add a0,zero,t0 # display t0
addi a7,zero,34 # system call for LED display
ecall # display
j START # loop forever
#InteruptProgram1:
#############################################################################################
# exceptoin 1
# 使?s6? s5?s4?s3?s0?a0?a7
#############################################################################################
#################
InteruptProgram1:
sw t0, 0(sp) #t0现场
addi sp, sp, 4
sw t3, 0(sp) #t3现场
addi sp, sp, 4
sw s1, 0(sp) #s1现场
addi sp, sp, 4
sw a7, 0(sp)
addi sp, sp, 4
sw a0, 0(sp)
addi sp, sp, 4
sw s0, 0(sp)
addi sp, sp, 4
sw s3, 0(sp)
addi sp, sp, 4
sw s4, 0(sp)
addi sp, sp, 4
sw s5, 0(sp)
addi sp, sp, 4
sw s6, 0(sp)
addi sp, sp, 4
csrrsi s6,0x41,0 #s6=uepc
sw s6, 0(sp) #uepc压栈保护
addi sp, sp, 4
#################
csrrsi zero,0x4,1 #ustatus.MIE=1
################# DIVU测试
addi t0,zero,2 # /2
addi s1,zero, 0x11
slli s1,s1,8
addi s1,s1,0x11
slli s1,s1,16
add a0,zero,s1
addi a7,zero,34
ecall
addi t3,zero,28 #ѭ
divu_branch:
divu s1,s1,t0 #ָ
add a0,zero,s1
addi a7,zero,34
ecall #ǰֵ
addi t3,t3, -1
bne t3,zero,divu_branch #ѭ
addi a7,zero,10
#################
addi s6,zero,1 #?1,2,3
addi s4,zero,3 #
addi s5,zero,1 #
IntLoop1:
add s0,zero,s6
IntLeftShift1:
slli s0, s0, 4
or s3,s0,s4
add a0,zero,s3 #display s0
addi a7,zero,34 # display hex
ecall
bne s0, zero, IntLeftShift1
sub s4,s4,s5 #
bne s4, zero, IntLoop1
#################
csrrci zero,0x4,1 #ustatus.MIE=0
#################
addi sp, sp, -4
lw s6, 0(sp)
csrrw zero,0x41,s6 #uepc=s6
addi sp, sp, -4
lw s6, 0(sp)
addi sp, sp, -4
lw s5, 0(sp)
addi sp, sp, -4
lw s4, 0(sp)
addi sp, sp, -4
lw s3, 0(sp)
addi sp, sp, -4
lw s0, 0(sp)
addi sp, sp, -4
lw a0, 0(sp)
addi sp, sp, -4
lw a7, 0(sp)
addi sp, sp, -4
lw s1, 0(sp) #s1现场
addi sp, sp, -4
lw t3, 0(sp) #t3现场
addi sp, sp, -4
lw t0, 0(sp) #t0现场
################
uret #uepc-->pc
#InteruptProgram2:
#############################################################################################
# exceptoin 2
# 使?s6? s5?s4?s3?s0?a0?a7
#############################################################################################
#################
InteruptProgram2:
sw t1, 0(sp) #t1现场
addi sp, sp, 4
sw t3, 0(sp) #t3现场
addi sp, sp, 4
sw s1, 0(sp) #s1现场
addi sp, sp, 4
sw s2, 0(sp) #s2现场
addi sp, sp, 4
sw a7, 0(sp)
addi sp, sp, 4
sw a0, 0(sp)
addi sp, sp, 4
sw s0, 0(sp)
addi sp, sp, 4
sw s3, 0(sp)
addi sp, sp, 4
sw s4, 0(sp)
addi sp, sp, 4
sw s5, 0(sp)
addi sp, sp, 4
sw s6, 0(sp)
addi sp, sp, 4
csrrsi s6,0x41,0 #s6=uepc
sw s6, 0(sp) #uepc压栈保护
addi sp, sp, 4
#################
csrrsi zero,0x4,1 #ustatus.MIE=1
################# BLT测试
addi s1,zero,-15 #
blt_branch:
add a0,zero,s1
addi a7,zero,34
ecall #
addi s1,s1,1
blt s1,zero,blt_branch #
addi a7,zero,10
#################
addi s6,zero,2 #?1,2,3
addi s4,zero,3 #
addi s5,zero,1 #
IntLoop2:
add s0,zero,s6
IntLeftShift2:
slli s0, s0, 4
or s3,s0,s4
add a0,zero,s3 #display s0
addi a7,zero,34 # display hex
ecall
bne s0, zero, IntLeftShift2
sub s4,s4,s5 #
bne s4, zero, IntLoop2
#################
csrrci zero,0x4,1 #ustatus.MIE=0
#################
addi sp, sp, -4
lw s6, 0(sp)
csrrw zero,0x41,s6 #uepc=s6
addi sp, sp, -4
lw s6, 0(sp)
addi sp, sp, -4
lw s5, 0(sp)
addi sp, sp, -4
lw s4, 0(sp)
addi sp, sp, -4
lw s3, 0(sp)
addi sp, sp, -4
lw s0, 0(sp) #s0现场
addi sp, sp, -4
lw a0, 0(sp)
addi sp, sp, -4
lw a7, 0(sp)
addi sp, sp, -4
lw s2, 0(sp) #s2现场
addi sp, sp, -4
lw s1, 0(sp) #s1现场
addi sp, sp, -4
lw t3, 0(sp) #t3现场
addi sp, sp, -4
lw t1, 0(sp) #t1现场
################
uret #uepc-->pc
#InteruptProgram3:
#############################################################################################
# exceptoin 3
# 使?s6? s5?s4?s3?s0?a0?a7
#############################################################################################
#################
InteruptProgram3:
sw s1, 0(sp) #s1现场
addi sp, sp, 4
sw a7, 0(sp)
addi sp, sp, 4
sw a0, 0(sp)
addi sp, sp, 4
sw s0, 0(sp)
addi sp, sp, 4
sw s3, 0(sp)
addi sp, sp, 4
sw s4, 0(sp)
addi sp, sp, 4
sw s5, 0(sp)
addi sp, sp, 4
sw s6, 0(sp)
addi sp, sp, 4
csrrsi s6,0x41,0 #s6=uepc
sw s6, 0(sp) #uepc压栈保护
addi sp, sp, 4
#################
csrrsi zero,0x4,1 #ustatus.MIE=1
################# SB测试
addi t1,zero,0 #init_addr
addi t3,zero,32 #counter
#sb写入 01,02,03,04
addi s1,zero, 0x00 #
addi s2,zero, 0x01 #
sb_store:
sb s1,(t1)
add a0,zero,s1
addi a7,zero,34 # system call for print
ecall # print
add s1,s1,s2 #data +1
addi t1,t1,1 # addr ++
addi t3,t3,-1 #counter
bne t3,zero,sb_store
addi t3,zero,8
addi t1,zero,0 # addr
sb_branch:
lw s1,(t1) #
add a0,zero,s1
addi a7,zero,34 # system call for print
ecall # print
addi t1,t1,4
addi t3,t3, -1
bne t3,zero,sb_branch
addi a7,zero,10 # system call for exit
#################
addi s6,zero,3 #?1,2,3
addi s4,zero,3 #
addi s5,zero,1 #
IntLoop3:
add s0,zero,s6
IntLeftShift3:
slli s0, s0, 4
or s3,s0,s4
add a0,zero,s3 #display s0
addi a7,zero,34 # display hex
ecall
bne s0, zero, IntLeftShift3
sub s4,s4,s5 #
bne s4, zero, IntLoop3
#################
csrrci zero,0x4,1 #ustatus.MIE=0
#################
addi sp, sp, -4
lw s6, 0(sp)
csrrw zero,0x41,s6 #uepc=s6
addi sp, sp, -4
lw s6, 0(sp)
addi sp, sp, -4
lw s5, 0(sp)
addi sp, sp, -4
lw s4, 0(sp)
addi sp, sp, -4
lw s3, 0(sp)
addi sp, sp, -4
lw s0, 0(sp)
addi sp, sp, -4
lw a0, 0(sp)
addi sp, sp, -4
lw a7, 0(sp)
addi sp, sp, -4
lw s1, 0(sp) #s1现场
################
uret #uepc-->pc
@@ -0,0 +1,270 @@
7d000113
00100413
01f41993
41f9d993
00000433
00c00913
00800b13
00140413
00f47413
00800293
00100313
00499993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
00140413
00f00f93
01f47433
01c41413
00800293
00100313
0049d993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
01c45413
406b0b33
000b0463
f95ff06f
000002b3
fff2c293
01029293
fff2e293
00500533
02200893
00000073
f5dff06f
00512023
00410113
01c12023
00410113
00912023
00410113
01112023
00410113
00a12023
00410113
00812023
00410113
01312023
00410113
01412023
00410113
01512023
00410113
01612023
00410113
04106b73
01612023
00410113
0040e073
00200293
01100493
00849493
01148493
01049493
00900533
02200893
00000073
01c00e13
0254d4b3
00900533
02200893
00000073
fffe0e13
fe0e16e3
00a00893
00000073
00100b13
00300a13
00100a93
01600433
00441413
014469b3
01300533
02200893
00000073
fe0416e3
415a0a33
fe0a10e3
0040f073
ffc10113
00012b03
041b1073
ffc10113
00012b03
ffc10113
00012a83
ffc10113
00012a03
ffc10113
00012983
ffc10113
00012403
ffc10113
00012503
ffc10113
00012883
ffc10113
00012483
ffc10113
00012e03
ffc10113
00012283
00200073
00612023
00410113
01c12023
00410113
00912023
00410113
01212023
00410113
01112023
00410113
00a12023
00410113
00812023
00410113
01312023
00410113
01412023
00410113
01512023
00410113
01612023
00410113
04106b73
01612023
00410113
0040e073
ff100493
00900533
02200893
00000073
00148493
fe04c8e3
00a00893
00000073
00200b13
00300a13
00100a93
01600433
00441413
014469b3
01300533
02200893
00000073
fe0416e3
415a0a33
fe0a10e3
0040f073
ffc10113
00012b03
041b1073
ffc10113
00012b03
ffc10113
00012a83
ffc10113
00012a03
ffc10113
00012983
ffc10113
00012903
ffc10113
00012483
ffc10113
00012e03
ffc10113
00012303
ffc10113
00012403
ffc10113
00012503
ffc10113
00012883
00200073
00912023
00410113
01112023
00410113
00a12023
00410113
00812023
00410113
01312023
00410113
01412023
00410113
01512023
00410113
01612023
00410113
04106b73
01612023
00410113
0040e073
00000313
02000e13
00000493
00100913
00930023
00900533
02200893
00000073
012484b3
00130313
fffe0e13
fe0e12e3
00800e13
00000313
00032483
00900533
02200893
00000073
00430313
fffe0e13
fe0e14e3
00a00893
00000073
00300b13
00300a13
00100a93
01600433
00441413
014469b3
01300533
02200893
00000073
fe0416e3
415a0a33
fe0a10e3
0040f073
ffc10113
00012b03
041b1073
ffc10113
00012b03
ffc10113
00012a83
ffc10113
00012a03
ffc10113
00012483
ffc10113
00012983
ffc10113
00012403
ffc10113
00012503
ffc10113
00012883
00200073
+276
View File
@@ -0,0 +1,276 @@
00100493
0100006f
00100493
00200913
00300993
0100006f
00100493
00200913
00300993
0100006f
00100493
00200913
00300993
0100006f
00100493
00200913
00300993
380000ef
00100413
00100493
01f49493
00900533
02200893
00000073
0024d493
00048463
fedff06f
00900533
02200893
00000073
00100493
00249493
00900533
02200893
00000073
00048463
fedff06f
00100493
01f49493
00900533
02200893
00000073
4034d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
00100413
01f41993
41f9d993
00000433
00c00913
00300b13
00140413
00f47413
00800293
00100313
00499993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
00140413
00f00f93
01f47433
01c41413
00800293
00100313
0049d993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
01c45413
406b0b33
000b0463
f95ff06f
000002b3
fff2c293
00829293
0ff2e293
00500533
02200893
00000073
fff00413
00000493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
00140413
00000433
03c00493
00042983
0004aa03
0149a2b3
00028663
0134a023
01442023
ffc48493
fe9412e3
00800533
02200893
00000073
00440413
03c00493
fc9416e3
00a00893
00200293
01100493
00849493
01148493
01049493
00900533
02200893
00000073
01c00e13
0254d4b3
00900533
02200893
00000073
fffe0e13
fe0e16e3
00a00893
08800493
00849493
04848493
08700913
00891913
05490913
02997933
01091913
11096913
01200533
02200893
00000073
00a00893
00000313
02000e13
00000493
00100913
00930023
00900533
02200893
00000073
012484b3
00130313
fffe0e13
fe0e12e3
00800e13
00000313
00032483
00900533
02200893
00000073
00430313
fffe0e13
fe0e14e3
00a00893
ff100493
00900533
02200893
00000073
00148493
fe04c8e3
00a00893
00000413
00140413
00800533
02200893
00000073
00240413
00800533
02200893
00000073
00340413
00800533
02200893
00000073
00440413
00800533
02200893
00000073
00540413
00800533
02200893
00000073
00640413
00800533
02200893
00000073
00740413
00800533
02200893
00000073
00840413
00800533
02200893
02200893
00000073
00008067
+273
View File
@@ -0,0 +1,273 @@
// Compile together with cpu21_riscv_redirect_int_bpb.v.
// Example:
// iverilog -g2012 -o cpu21_sim cpu21_riscv_redirect_int_bpb.v tb_cpu21_riscv_redirect_int_bpb.v
// vvp cpu21_sim
// The simulation writes cpu21_riscv_redirect_int_bpb.vcd for GTKWave.
//
// The program image is loaded into the ROM model with $readmemh from
// ROM_FILE. A failed $readmemh only prints a warning and leaves the memory
// untouched, so a wrong path used to make the ROM look like all-NOP
// (0x00000013). The simulator working directory is not fixed (Vivado xsim
// runs in <proj>.sim/sim_1/behav/xsim), so this testbench probes a list of
// candidate paths and reports which one worked. An explicit path always
// wins:
// vvp cpu21_sim +ROM_FILE=<path> (iverilog/vvp)
// xelab ... -generic_top "ROM_FILE=<path>" (Vivado xsim)
module tb_cpu21_riscv_redirect_int_bpb #(
parameter ROM_FILE = "risc-v-benchmark_ccab.hex"
// risc-v-benchmark_ccab.hex
// cpu21_riscv_redirect_int_bpb_rom.hex
);
localparam integer ROM_WORDS = 1024;
localparam integer RAM_WORDS = 1024;
localparam integer PATH_LEN = 512;
// Sentinel that cannot appear as the first ROM word of a RISC-V image.
localparam [31:0] EMPTY_ROM_WORD = 32'hFFFF_FFFF;
// Interrupt entry addresses, shared by the DUT instance and the trace
// condition below. The DUT addresses the ROM with PC[11:2], so these three
// entries live at words 43 / 120 / 192 of the program image (the first
// "sw ..., 0(sp)" of each handler prologue).
localparam [31:0] IRQ1_VECTOR = 32'h0000_30ac;
localparam [31:0] IRQ2_VECTOR = 32'h0000_31e0;
localparam [31:0] IRQ3_VECTOR = 32'h0000_3300;
reg clk;
reg reset;
reg [ 31:0] instr_i;
reg [ 31:0] data_rdata_i;
reg [ 2:0] irq_i;
reg go_i;
reg [ 31:0] rom [0:ROM_WORDS-1];
reg [ 31:0] ram [0:RAM_WORDS-1];
wire [ 31:0] instr_addr_o;
wire [ 31:0] data_addr_o;
wire [ 31:0] data_wdata_o;
wire [ 3:0] data_wstrb_o;
wire data_we_o;
wire [ 31:0] led_data_o;
wire led_valid_o;
wire [ 31:0] if_pc_o;
wire [ 31:0] id_pc_o;
wire [ 31:0] ex_pc_o;
wire [ 31:0] mem_pc_o;
wire [ 31:0] wb_pc_o;
wire [ 31:0] if_ir_o;
wire [ 31:0] id_ir_o;
wire [ 31:0] ex_ir_o;
wire [ 31:0] mem_ir_o;
wire [ 31:0] wb_ir_o;
wire [ 31:0] rdin_o;
wire [ 31:0] mdin_o;
wire reg_write_o;
wire mem_write_o;
wire halted_o;
wire [ 2:0] irq_pending_o;
wire [ 1:0] irq_current_level_o;
wire [ 31:0] uepc_o;
wire [ 31:0] ustatus_o;
wire bpb_predict_hit_o;
wire bpb_predict_taken_o;
wire bpb_mispredict_o;
wire [ 15:0] cycle_count_o;
wire [ 15:0] stall_count_o;
wire [ 15:0] bubble_count_o;
wire [ 15:0] conditional_taken_count_o;
wire [ 15:0] unconditional_branch_count_o;
wire [ 15:0] prediction_success_count_o;
wire [ 15:0] prediction_failure_count_o;
integer i;
integer tb_cycle;
reg rom_loaded;
reg [8*PATH_LEN-1:0] rom_file_path;
cpu21_riscv_redirect_int_bpb #(
.RESET_PC (32'h0000_0000),
.IRQ1_VECTOR(IRQ1_VECTOR),
.IRQ2_VECTOR(IRQ2_VECTOR),
.IRQ3_VECTOR(IRQ3_VECTOR),
// The interrupt test program writes MIE only inside its handlers, so
// the testbench starts with MIE already set (ustatus[0] = 1).
.USTATUS_INIT(32'h0000_0001)
) dut (
.clk (clk),
.reset (reset),
.instr_i (instr_i),
.data_rdata_i (data_rdata_i),
.irq_i (irq_i),
.go_i (go_i),
.instr_addr_o (instr_addr_o),
.data_addr_o (data_addr_o),
.data_wdata_o (data_wdata_o),
.data_wstrb_o (data_wstrb_o),
.data_we_o (data_we_o),
.led_data_o (led_data_o),
.led_valid_o (led_valid_o),
.if_pc_o (if_pc_o),
.id_pc_o (id_pc_o),
.ex_pc_o (ex_pc_o),
.mem_pc_o (mem_pc_o),
.wb_pc_o (wb_pc_o),
.if_ir_o (if_ir_o),
.id_ir_o (id_ir_o),
.ex_ir_o (ex_ir_o),
.mem_ir_o (mem_ir_o),
.wb_ir_o (wb_ir_o),
.rdin_o (rdin_o),
.mdin_o (mdin_o),
.reg_write_o (reg_write_o),
.mem_write_o (mem_write_o),
.halted_o (halted_o),
.irq_pending_o (irq_pending_o),
.irq_current_level_o (irq_current_level_o),
.uepc_o (uepc_o),
.ustatus_o (ustatus_o),
.bpb_predict_hit_o (bpb_predict_hit_o),
.bpb_predict_taken_o (bpb_predict_taken_o),
.bpb_mispredict_o (bpb_mispredict_o),
.cycle_count_o (cycle_count_o),
.stall_count_o (stall_count_o),
.bubble_count_o (bubble_count_o),
.conditional_taken_count_o (conditional_taken_count_o),
.unconditional_branch_count_o(unconditional_branch_count_o),
.prediction_success_count_o (prediction_success_count_o),
.prediction_failure_count_o (prediction_failure_count_o)
);
always #5 clk = ~clk;
// The Logisim ROM uses PC[11:2] as its word address. This also maps
// the three original interrupt vectors to the same ROM entries.
always @* begin
instr_i = 32'h00000013;
if (instr_addr_o[11:2] < ROM_WORDS) instr_i = rom[instr_addr_o[11:2]];
end
// Asynchronous read model for data memory.
always @* begin
data_rdata_i = 32'b0;
if (data_addr_o[11:2] < RAM_WORDS) data_rdata_i = ram[data_addr_o[11:2]];
end
// Synchronous write model with byte enables.
always @(posedge clk) begin
if (!reset && data_we_o && (data_addr_o[11:2] < RAM_WORDS)) begin
if (data_wstrb_o[0]) ram[data_addr_o[11:2]][7:0] <= data_wdata_o[7:0];
if (data_wstrb_o[1]) ram[data_addr_o[11:2]][15:8] <= data_wdata_o[15:8];
if (data_wstrb_o[2]) ram[data_addr_o[11:2]][23:16] <= data_wdata_o[23:16];
if (data_wstrb_o[3]) ram[data_addr_o[11:2]][31:24] <= data_wdata_o[31:24];
end
end
always @(posedge clk) begin
if (reset) begin
tb_cycle = 0;
end else begin
tb_cycle = tb_cycle + 1;
if ((tb_cycle <= 20) || data_we_o || led_valid_o ||
(irq_pending_o != 3'b000) ||
(instr_addr_o == IRQ1_VECTOR) ||
(instr_addr_o == IRQ2_VECTOR) ||
(instr_addr_o == IRQ3_VECTOR)) begin
$display(
"t=%0t cyc=%0d PC=%08h ID=%08h EX=%08h MEM=%08h WB=%08h irq=%b pend=%b uepc=%08h LEDv=%b LED=%08h memwe=%b addr=%08h wdata=%08h wstrb=%b",
$time, tb_cycle, if_pc_o, id_ir_o, ex_ir_o, mem_ir_o, wb_ir_o, irq_i, irq_pending_o,
uepc_o, led_valid_o, led_data_o, data_we_o, data_addr_o, data_wdata_o, data_wstrb_o);
end
end
end
// Try to load the ROM image from "fname". "loaded" is 1 when the file
// existed and contained at least one word. A sentinel in rom[0] makes a
// silent load failure impossible to miss.
task load_rom_image;
input [8*PATH_LEN-1:0] fname;
output loaded;
integer fh;
begin
loaded = 1'b0;
fh = $fopen(fname, "r");
if (fh != 0) begin
$fclose(fh);
rom[0] = EMPTY_ROM_WORD;
$readmemh(fname, rom);
if (rom[0] === EMPTY_ROM_WORD) begin
// Opened but empty: restore the default NOP fill.
rom[0] = 32'h0000_0013;
end else begin
rom_file_path = fname;
loaded = 1'b1;
$display("NOTE: ROM image loaded from \"%0s\".", fname);
end
end
end
endtask
initial begin
clk = 1'b0;
reset = 1'b1;
irq_i = 3'b000;
go_i = 1'b0;
tb_cycle = 0;
for (i = 0; i < ROM_WORDS; i = i + 1) rom[i] = 32'h00000013;
for (i = 0; i < RAM_WORDS; i = i + 1) ram[i] = 32'b0;
// Seed a few words so memory activity is visible in the waveform.
ram[1] = 32'h1234_5678;
ram[2] = 32'h89ab_cdef;
// Probe the usual locations for the ROM image. The first readable
// candidate wins; failed probes below are harmless (the ROM keeps its
// 0x00000013 fill until a real image is found).
$display("NOTE: searching for ROM image \"%0s\" ...", ROM_FILE);
rom_loaded = 1'b0;
if ($value$plusargs("ROM_FILE=%s", rom_file_path)) load_rom_image(rom_file_path, rom_loaded);
if (!rom_loaded) load_rom_image(ROM_FILE, rom_loaded);
if (!rom_loaded) load_rom_image({"testbench/", ROM_FILE}, rom_loaded);
if (!rom_loaded) load_rom_image({"../testbench/", ROM_FILE}, rom_loaded);
if (!rom_loaded) load_rom_image({"../../../testbench/", ROM_FILE}, rom_loaded);
if (!rom_loaded) load_rom_image({"../../../../../testbench/", ROM_FILE}, rom_loaded);
if (!rom_loaded)
$display(
"WARNING: no ROM image found for \"%0s\" - the ROM stays filled with NOPs (0x00000013).",
ROM_FILE
);
$dumpfile("cpu21_riscv_redirect_int_bpb.vcd");
$dumpvars(0, tb_cpu21_riscv_redirect_int_bpb);
#22 reset = 1'b0;
// Button-like interrupt pulses. The DUT synchronizes and latches them.
repeat (80) @(negedge clk);
irq_i[0] = 1'b1;
@(negedge clk);
irq_i[0] = 1'b0;
repeat (180) @(negedge clk);
irq_i[1] = 1'b1;
@(negedge clk);
irq_i[1] = 1'b0;
repeat (180) @(negedge clk);
irq_i[2] = 1'b1;
@(negedge clk);
irq_i[2] = 1'b0;
repeat (5560) @(negedge clk);
$display(
"FINAL: tb_cycles=%0d dut_cycles=%0d stalls=%0d bubbles=%0d cond_taken=%0d uncond=%0d pred_ok=%0d pred_fail=%0d halted=%b",
tb_cycle, cycle_count_o, stall_count_o, bubble_count_o, conditional_taken_count_o,
unconditional_branch_count_o, prediction_success_count_o, prediction_failure_count_o,
halted_o);
$finish;
end
endmodule
+33
View File
@@ -0,0 +1,33 @@
# 指令 "Funct7
(十进制)" "Funct3
(十进制)" "OpCode
(十六进制)" ALU_OP MemtoReg MemWrite ALU_Src RegWrite ecall S_Type BEQ BNE Jal jalr REMU sel BLT r1u r2u CSR CSRW CSRRCI
1 add 0 0 C 5 1 1 1
2 sub 32 0 C 6 1 1 1
3 and 0 7 C 7 1 1 1
4 or 0 6 C 8 1 1 1
5 slt 0 2 C 11 1 1 1
6 sltu 0 3 C 12 1 1 1
7 addi 0 4 5 1 1 1
8 andi 7 4 7 1 1 1
9 ori 6 4 8 1 1 1
10 xori 4 4 9 1 1 1
11 slti 2 4 11 1 1 1
12 slli 0 1 4 0 1 1 1
13 srli 0 5 4 2 1 1 1
14 srai 32 5 4 1 1 1 1
15 lw 2 0 5 1 1 1 1
16 sw 2 8 5 1 1 1 1 1
17 ecall 0 0 1C 1 1 1
18 beq 0 18 6 1 1 1
19 bne 1 18 6 1 1 1
20 jal 1B 1 1
21 jalr 0 19 6 1 1 1 1
22 CSRRSI 6 1C 8 1 1 1
23 CSRRCI 7 1C 7 1 1 1 1
24 URET 2 0 1C 1
25 DIVU 1 5 C 4 1 1 1
26 REMU 1 7 C 4 1 1 1 1
27 SB 0 8 5 1 1 1 1 1 1
28 BLT 4 18 11 1 1 1
29 CSRRW 1 1C 1 1 1