北航计组-P5课上

通过阅读本文,你可以大致了解BUAA 2024秋季 P5课上测试的相关内容
题目每年都会发生变化,题面仅靠回忆,题意描述可能与原题有一定差异

写在前面

容我先BB几句,极限极限极限极限极限极限极限极限极限极限

十分侥幸通过了P5课上测试,没能做完T2,留下些许遗憾吧,不过,就像jzy哥哥说的那样“过了就好😁”,课上出了几处状况,曾一度以为要寄,最好侥幸通过了……课上状况留到最后再说吧,先来看看题目

必看

不要盲目顺序做题 !

不要盲目顺序做题 !

不要盲目顺序做题 !

一般来说,优先级,计算 > 跳转 > 访存

T1 bmoal

题面

bmoal rs, offset

若 GRF(rs) 中 1 的 个数大于 0 的个数,就和beq一样跳转,并且 链接,也就是 GRF(31) <- PC + 8;否则,啥也不干

思路

这是一道跳转类的题,需要修改CmpOp以及CMP内部比较逻辑,Control模块,以及流水线寄存器

至于NPC可以复用beq的接口,因为跳转方式一样

对于Tuse,Tuse_rs设为0,Tuse_rt设为3(默认就为3)就好了,Tnew的话1或者0都没影响,具体见P5课下

因为是否写31号寄存器需要根据比较结果来判断而无法直接由Control解码得到,因此需要将比较结果往后传递,也就是加入后面各级的流水线寄存器

所以需要在E M W级将比较结果condition加入到Control模块中,再输出RegWrite信号

具体一点就是

1
2
3
4
5
6
7
8
9
10
11
12
13
case(opcode)
newOp:
begin
newSign = 1'b1;
CmpOp = 2'b11;
AluOp = 4'b0101;//和课下jal一样
A3 = 5'd31;
Tuse_rs = 2'd0;
Tnew = 2'd1;
if(condition) begin
RegWrite = 1'b1;
end
end

所以,建议提前准备好相应的接口,课上临时加会非常麻烦,而且紧张的条件下很可能会出一些小bug,提前准备将CmpResult流水至后面的寄存器

T2 basel

题面

lc base1, offset(base)

GRF(base)和GRF(base1)分别作为基地址,offset为偏移量,从内存中取出来两个数据,分别为data1和data,将两者的低五位作为寄存器编号

if(data1 > data) GRF[data1[4:0]] <- data1

else GRF[data[4:0]] <- data

需要魔改DM,然后在W级才知道要写哪个寄存器,比较抽象,暴力阻塞可能会TLE,需要优化一下,不多说了,毕竟考场上没时间啃了,也无法确定自己的想法是否正确,就不误导大家了。

T3 ae

题面

ae rt, Imm_16

temp[15] = Imm[15] ^ Imm[14]

……

temp[1] = Imm[1] ^ Imm[0]

temp[0] = Imm[0] ^ 0

GRF[rt] = temp[15] || temp[14] || …… || temp[0] || Imm_16

思路

没啥特别的,直接运算就行,跟add唯一的区别就是AluOp以及具体的运算

课上出状况

ISE无法仿真

  • 某一次仿真后关闭,修改后再次仿真时就显示仿真已经在运行,,无语了,直接新建工程再重新导入了
  • 室友说可以直接在Project栏下Clearup project files

T3

首先不得不承认,本人课下确实有一些问题,但是测试却测不出来,具体一点就是ALU模块里全用的非阻塞赋值,非阻塞赋值是在块结束时并发进行的,对于结果,似乎也没啥问题,但这也埋下了隐患

具体一点

1
2
3
4
5
always @(*) begin
case (AluOp)
4'b0000: begin
result <= inA + inB;
end

对于新指令,我却采用的是阻塞赋值,具体如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
always @(*) begin
case (AluOp)
4'b0000: begin
result <= inA + inB;
end

newOp : begin
tmp1 = inB[15:0];
tmp2 = 16'b0;
for(i = 1;i < 16;i = i + 1) begin
tmp2[i] = tmp1[i] ^ tmp1[i-1];
end
tmp2[0] = tmp1[0] ^ 0;
result = {tmp2, tmp1};
end

但是这样,我每次执行新指令,result会输出前一条指令的result,无论我后来怎么改,都是这样,期间进行了无数改造,无数测试,包括但不限于把tmp1, tmp2整成32位的,再或一下,赋给result,但还是不对,但是tmp1. tmp2各自分别是对的,这我就恼火了,又傻看了半天,最后又整了一个tmp3,先tmp3 = tmp1 | tmp2,再result = tmp3;可惜,tmp3在波形图里对了,但是result还是之前那条指令的值。

这时候已经快到八点了,可我还在做最简单的计算题,几乎快要崩溃时,我注意到了 =<=,这里应该阻塞赋值啊,但我前面都用的非阻塞赋值,也没错啊,半信半疑中,我把最后一句改为

result <= tmp3;

一仿真,对了,艹,至于你问我为什么最后一句改成非阻塞赋值就对了,我只能说:经典verilog抽象日常,不过正确写法应该是全部用阻塞赋值,但课上也没时间细想了🤔

到头来还是课下留下的隐患😇唉唉,而且是测不出来的那种,至于为什么这里会写非阻塞赋值呢?我直接copy的P4的ALU,当时为什么非阻塞呢,我也不知道,可能就一时敲错了。。(话说我P4课上咋没有这个问题🤔抽象bug,抽象verilog,抽象ISE😇

T1

刚整完T3,已经八点多了,回头来解T1,是条件跳转,且条件链接,我提前准备了相关接口,直接连上,调了一会儿之后,本地测试没问题了,此时是20:33,我交上去了,正当我喝了口水准备交卷时,出现了一个红色的Wrong Answer,我一点开,发现10 个点过了8个,还有两个在该跳转的地方并没有跳转,这下麻烦了,因为10个点过了8个,说明你的代码在大部分情况下没问题,这就说明你很难自己构造数据卡出bug,只能瞪眼看代码debug了,我是这样的😭

于是回头检查我的代码,我的Cmp代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module D_CMP(
input [31:0] data1,
input [31:0] data2,
input [1:0] CmpOp,
output reg out
);
reg [4:0] num1;
integer i;
always @(*) begin
if (CmpOp == 2'b00) begin
out = (data1 == data2);
end
else if (CmpOp == 2'b01) begin
out = (data1 != data2);
end
else if (CmpOp == 2'b10) begin
num1 = 5'd0;
for(i=0;i<32;i=i+1) begin
if(data1[i]) num1 = num1 + 5'd1;
end
out = (num1 > 5'd16) ? 1'b1 : 1'b0;
end
else begin
out = 1'b0;
end
end

endmodule

看了一会儿,发现num1可能为32啊,5位只能表示0~31啊,艹,于是把所有的5位都改成6位了,这下窃喜了,以为可以走了,结果交上去,还是WA,此时已经快20:45了,说实话,心里真急了😭但这题也不难啊💔于是我反复对照RTTL语言,做了如下修改,交上去A了

1
2
3
4
5
6
7
8
9
10
11
12
13
reg [4:0] num1, num0;
integer i;

else if (CmpOp == 2'b10) begin
num1 = 6'd0;
num0 = 6'd0;
for(i=0;i<32;i=i+1) begin
if(data1[i]) num1 = num1 + 6'd1;
end
//out = (num1 > 6'd16) ? 1'b1 : 1'b0;
num0 = 6'd32 - num1;
out = (num1 > num0) ? 1'b1 : 1'b0;
end

注释掉的是之前的写法,改之后交上去A了,我趣,天不亡我啊 😁

回来和两个室友讨论,测试了半天,也不知道哪有问题,室友说我可能写的是num1 > 5’d16,16这里忘记改了,但是我们测试发现,写5‘d16问题也不大,verilog比较时会把6’ > 5’这样的比较式右边扩展

chatgpt作如下回答:

标准如下:

最后也没搞懂哪出问题了,,哎,verilog就这样,经常会有一些奇奇怪怪的问题,让人摸不着头脑,再比如极其抽象的符号法则等等,搭配上使用舒适度几乎为0的ISE,一个字,绝!

不多说了,说到底还是自身能力有欠缺,接下来就是P6了,加油吧😄


北航计组-P5课上
http://pzhwuhu.github.io/2024/11/18/P5课上/
本文作者
pzhwuhu
发布于
2024年11月18日
更新于
2025年4月18日
许可协议