写在前面:笔者不是大佬,P4二战方过,这里记载了二战题目的comprehensive版本。
- 为什么是comprehensive版本?因为做完挺早,等助教问答的时候顺手把题抄了。
- 为什么没有一战题目?因为一战没心情回忆痛苦的过去。
- 为什么二战如此神速?我也不知道,可能是题简单吧。
SSZE
opcode = 6’b000000
func = 6’b001111
当GPR[rs]和GPR[rt]后缀 0 的个数相同时,将GPR[rd]置 1 ,否则置 0 ; |
Answer:重点在数0的个数,还有就是改指令的时候记得把通路改完整(这个以大家对自己verilog代码的理解都不成问题)。
CABC
opcode = 6’b111100
cross1 = GPR[rs][23:16] || GPR[rs][7:0] || GPR[rt][31:24] || GPR[rt][15:8] |
Answer:这和第一题几乎一样,唯一需要注意的是if判断条件成立与否,寄存器堆设计的是是否操作,因此在CTRL模块中的WE(寄存器写使能信号)是(caba && isequal == 0)。isequal是ALU输出的count_zeros(xor_result[31:16]) == count_zeros(xor_result[15:0])判断结果。
LHBOC
opcode = 101101
vaddr <-- GPR[base] + sign_extend(offset) |
Answer:这个题也挺简单的,注意一下不要被RTL语言骗了,我们看到这行memword <-- Memory[paddr],paddr是32位,而DM的范围是0-3072,只需要12位即可,我们在verilog实现的过程中要像这样
memword = DM[addr[13:2]];
addr是ALU的输出结果。
一些Tips
- 课下最好实现这个函数——-sign_extend
- 一定要记得有符号数怎么比大小,要不然就上去
if手搓吧:$signed(A) > $singned(B) - 循环移位别写
for循环,会TLE,用这个(A >> n) + (A << (32 - n)) - 写函数的时候记得在
function后面有begin,end把函数体包起来。 - 祝大家P4一战顺利😉😊
Lyrics Sharing
倘若那天 |
后记
谨以此篇,纪念我的第一篇github博客。