jmv
I:d←[(GPR[rs]+GPR[rt])&0xfffffffe]>>1new_addr←sign_ext(offset∣∣02)+(d29...0∣∣02)addr←PC+4+new_addrI+1:PC←addr
非常简单的j型指令,仅改变了跳转方式,因此仅需更改NPC即可
crt
defrotate(x):rst←xforiin1..31rst←rst+(xi−1..0∣∣x31..i)end_forend_deflhs←rotate(GPR[rs])rhs←rotate(GPR[rt])iflhs<rhsthenGPR[rd]←−1elseiflhs>rhsthenGPR[rd]←1elseGPR[rd]←0
一个单纯的R型指令,所以只需要改ALU即可。不过需要注意verilog的切片不支持不定长度,所以按RTL语言这样写rotate
函数是不行的。
正解应该这样:
1 2 3 4 5 6 7 8 9
| integer i; reg [31:0] rst_rs; always @ (*) begin rst_rs = A; for(i=1; i<=31; i=i+1) begin rst_rs = rst_rs + {A[0], A[31:1]}; end end
|
另外注意比大小时用$signed()
Load Prime Xor
vaddr←GPR[base]+sign_ext(offset)paddr←vaddr&0xfffffffcword←Mem[paddr]x←word4..0x←s_prime(x)GPR[x]←word
其中s_prime
表示“小于等于x的最大质数”
这题卡了我好久,虽然倒数第四分钟的时候交了一发过了,但是出来之后依然不明白怎么过的
几个点需要注意:
-
s_prime
的实现其实就是打表(反正我是打表,这样最稳妥可靠)
-
paddr
其实不需要特殊处理,因为这一步其实在课程组的tb里已经帮你处理过了。只需要确保自己读的是word即可
-
阻塞与转发。条件Load类型最难搞的就是这玩意。
阻塞不能采用无脑阻塞,必须仅阻塞质数,否则会TLE
。另外,由于写地址在M级就已经出来了,因此我在M级并没有阻塞。经检验,这样不会run less cycle
。
那么我卡哪了呢?似乎是转发。
之前我的转发一直是这样的:
1 2 3 4 5 6
| assign D_FW_rs_Op = (D_rs != 0 && D_rs == E_GPRWaddr && E_GPRWaddr != 0) ? `DFWeback : (D_rs != 0 && D_rs == M_GPRWaddr && M_GPRWaddr != 0) ? `DFWmback : `DFWdefault; assign D_FW_rt_Op = (D_rt != 0 && D_rt == E_GPRWaddr && E_GPRWaddr != 0) ? `DFWeback : (D_rt != 0 && D_rt == M_GPRWaddr && M_GPRWaddr != 0) ? `DFWmback : `DFWdefault;
|
但是课上会出现类似@00003048: $13 <= xxxxxxxx
的报错。把所有==
改成===
就不会出现此问题了。按理来说即使用==
也不应该出现任何问题,因为所有指令应该都被阻挡在了D级。、
于是在疑惑中结束了P6