+------------------+| Clock (50MHz) |+--------+---------+|+------------------+------------------+|||+-------v--------+ +---------v---------+| PC Reg || Inst ROM (BRAM) |+-------+--------+ +---------+---------+||+-------v-----------------------------------+| IF Stage || (fetch instruction &update PC) |+-------------------+-----------------------+|+-------------------v-----------------------+| ID || Control Unit ← Opcode Decoder || RegFile Read ← rs1, rs2 |+-------------------+-----------------------+|+-------------------v-----------------------+| EX || ALU Control ← funct3/funct7 || ALU Operation (add/sub/and/or/slt/etc.) |+-------------------+-----------------------+|+-------------------v-----------------------+| MEM || Data Memory (Block RAM) || Handle lw/sw |+-------------------+-----------------------+|+-------------------v-----------------------+| WB || Write Mux ← ALU out/ MEM data || RegFile Write Enable |+---------------------------------------------+
# 伪代码:asm → machine code → coewithopen("program.s") as f:
binary = riscv_assembler(f.read())
withopen("inst.coe", "w") as f:
f.write("memory_initialization_radix=16;\n")
for word in binary:
f.write(f"{word:08x}\n")
调试利器:ILA 集成逻辑分析仪
千万别等到板级测试才发现问题。提前插入 ILA 核,抓取以下关键信号:
pc, instruction
regfile[32](建议只抓部分常用寄存器)
alu_result, mem_data_out
forward_a, forward_b, stall
你可以亲眼看到一条 beq 指令如何触发流水线刷新,或者一次 lw 如何引发一拍停顿。
它真的能跑吗?实测案例
编写了一段简单的 RISC-V 汇编程序,功能是计算数组求和:
.global _start
_start:
li x5, 10 # counter
li x6, 0 # sum
la x7, arr # base address
loop:
lw x8, 0(x7) # load element
add x6, x6, x8 # accumulate
addi x7, x7, 4 # next address
addi x5, x5, -1 # decrement counter
bne x5, zero, loop
trap:
j trap # infinite loop