计组实验笔记
记录一些踩到了的坑
ALU
考虑如下的两组代码:
1 | wire is_sub = ALUop[1] & (ALUop[0] | ALUop[2]); // SUB, SLT, SLTU |
1 | wire is_sub = ALUop[1] & (ALUop[0] | ALUop[2]); // SUB, SLT, SLTU |
是不是几乎一模一样?但执行结果是不一样的
1 | 第一个输出 |
原因:操作数位数不匹配,考虑上面的两个assign
语句,左边的是 位的,而右边的是 位的。
Verilog会自动将 位的数扩展成 位的数,然而这样的扩展不是“惰性求值”(先尽可能不改动位数,遇到不匹配的地方再扩展)的,在运算一开始就会将所有的运算数扩展成 位。
ref: Verilog 中表达式位宽和类型的确定规则
因此~B
在经过扩展再取反后的最高位是 ,但b_convert
的取反在assign
运算前就被执行了,在assign
语句中会直接在最高位补 ,因此造成错误。
解决方案:wire [N:0] b_convert = is_sub ? ~B : B;
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Cauphenuny's Blog!
评论