帮我看下这个二级流水线加法器有什么问题?
我仿照王金明的那本书的例子做了一个二级流水线的十六进制加法器,
可是为什么会有这样的问题:就是最后的输出时,进位始终为0,请各位高手帮我看下,
多谢各位了 ,下面是代码
module adder16(a,b,cin,clk,sum,cout);
input[15:0] a,b;
input cin;
input clk;
output[15:0] sum;
output cout;
reg[15:0] sum;
reg cout;
reg[15:0] temp_a,temp_b;
reg temp_cin;
reg[7:0] first_sum;
reg first_cout;
reg[7:0] first_a,first_b;
always @(posedge clk)
begin
temp_a<=a;temp_b<=b;temp_cin<=cin;
end
always @(posedge clk)
begin
{first_cout,first_sum}<=temp_a[7:0]+temp_b[7:0]+temp_cin;
first_a<=temp_a[15:8];
first_b<=temp_b[15:8];
end
always @(posedge clk)
begin
{cout,sum}<={first_a+first_b+first_cout,first_sum};
end
endmodule
左端赋值,使用{A,B}。
很明显,你最后一个赋值的右边有错。 你在整个等式右边加一个大括号有什么用?这不就相当于4=(2 + 2 )吗?
{cout,sum}<={first_a+first_b+first_cout,first_sum};
这个地方位宽不对,左边17bit,右边16bit,等于没有对高位“cout”赋值;同样的问题存在于first_cout。
{first_cout,first_sum}<=temp_a[7:0]+temp_b[7:0]+temp_cin;
我理解的是,temp_a[7:0]和temp_b[7:0]都是8位的,加起来不就9位了吗
请指教
从电路角度思考,verilog课程上应该都会强调这一点。
右边的寄存器位宽不够,进位位是无法保存并赋值到左边的。
这几个地方改一下应该就可以了(仅供参考)。
reg[8:0] first_a,first_b;
{first_cout,first_sum}<={1'b0,temp_a[7:0]}+{1'b0,temp_b[7:0]}+temp_cin;
first_a<={1'b0,temp_a[15:8]};
first_b<={1'b0,temp_b[15:8]};
always @(posedge clk)
begin
{cout,sum}<={first_a+first_b+first_cout,first_sum};
end
右边是不能用大括号的 ,这个相当于把16位的数据给到17位,所以最高位始终是0.
右边用了大括号 就相当于右边只有16bit了。
十分感谢,对于我这种初学者来说,从电路的角度思考,听起来很容易,但是写起程序不经意间就忘了。
会了以后看这个模块可能十分简单,但是这个蕴含的思想,我还得好好消化。
多谢了,以后不会犯同样的错误了,
总结一句话,王金明的书害人呀,他书里流水线加法器就是这么用大括号的。
多谢,我知道错在哪里了。
