BUAA-CO-p6-课上

BUAA-CO-p6-课上

jmv

op rs rt offset

I:d[(GPR[rs]+GPR[rt])&0xfffffffe]>>1new_addrsign_ext(offset02)+(d29...002)addrPC+4+new_addrI+1:PCaddr\begin{aligned} & \operatorname{I:} \\ & \qquad d \leftarrow [(GPR[rs] + GPR[rt]) \& \operatorname{0xfffffffe}] >> 1 \\ & \qquad new\_addr \leftarrow \operatorname{sign\_ext}(offset || 0^2) + (d_{29...0} || 0^2) \\ & \qquad addr \leftarrow \operatorname{PC} + 4 + new\_addr \\ & \operatorname{I+1:} \\ & \qquad \operatorname{PC} \leftarrow addr \end{aligned}

非常简单的j型指令,仅改变了跳转方式,因此仅需更改NPC即可

crt

op rs rt rd func

defrotate(x):rstxforiin1..31rstrst+(xi1..0x31..i)end_forend_deflhsrotate(GPR[rs])rhsrotate(GPR[rt])iflhs<rhsthenGPR[rd]1elseiflhs>rhsthenGPR[rd]1elseGPR[rd]0\begin{aligned} & \operatorname{def} \operatorname{rotate(x):} \\ & \qquad rst \leftarrow x\\ & \qquad \operatorname{for} i \operatorname{in} 1..31\\ & \qquad \qquad rst \leftarrow rst + (x_{i-1..0} || x_{31..i}) \\ & \qquad \operatorname{end\_for}\\ & \operatorname{end\_def}\\ & \\ & lhs \leftarrow \operatorname{rotate}(GPR[rs]) \\ & rhs \leftarrow \operatorname{rotate}(GPR[rt]) \\ & \operatorname{if} lhs \lt rhs \operatorname{then} \\ & \qquad GPR[rd] \leftarrow -1 \\ & \operatorname{else} \operatorname{if} lhs \gt rhs \operatorname{then} \\ & \qquad GPR[rd] \leftarrow 1 \\ & \operatorname{else} \\ & \qquad GPR[rd] \leftarrow 0 \end{aligned}

一个单纯的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
// rt同理
end

另外注意比大小时用$signed()

Load Prime Xor

op rs rt offset

vaddrGPR[base]+sign_ext(offset)paddrvaddr&0xfffffffcwordMem[paddr]xword4..0xs_prime(x)GPR[x]word\begin{aligned} & vaddr \leftarrow GPR[base] + \operatorname{sign\_ext}(offset)\\ & paddr \leftarrow vaddr \& \operatorname{0xfffffffc}\\ & word \leftarrow Mem[paddr] \\ & x \leftarrow word_{4..0} \\ & x \leftarrow \operatorname{s\_prime}(x) \\ & GPR[x] \leftarrow word \end{aligned}

其中s_prime表示“小于等于x的最大质数”

这题卡了我好久,虽然倒数第四分钟的时候交了一发过了,但是出来之后依然不明白怎么过的

几个点需要注意:

  1. s_prime的实现其实就是打表(反正我是打表,这样最稳妥可靠)

  2. paddr其实不需要特殊处理,因为这一步其实在课程组的tb里已经帮你处理过了。只需要确保自己读的是word即可

  3. 阻塞与转发。条件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

作者

OWPETER

发布于

2024-12-02

更新于

2024-12-02

许可协议

评论