Verilog 4位移位加法器实现报错及输出全X问题求助
Verilog 4位移位加法器实现报错及输出全X问题求助
嗨,刚学Verilog遇到这种问题太正常了,别慌!我帮你一步步拆解问题、解决问题:
先搞定「procedural continuous assignments」报错
你碰到的这个错误,核心原因是在initial/always这类过程块里用了assign连续赋值——Verilog规定assign只能放在模块级(过程块外面),过程块里必须用过程赋值(阻塞=或非阻塞<=,时序逻辑优先用非阻塞)。
看你的shift模块,这两处assign都是违规的:
initial begin assign y=d; end always @(posedge clk) assign y= {1'b0, d[3:1]};
而且你的移位逻辑本身也有问题:原来的代码每次时钟沿都从输入d取高位,根本不是真正的移位寄存器。正确的逻辑应该是先把输入d加载到y,然后每次时钟沿让y自己右移一位,修正后的shift模块如下:
//shift register to store the two inputs a and b to be added module shift(y, d, clk); input [3:0] d; input clk; output [3:0] y; reg [3:0] y; initial begin y = d; // 初始化加载输入d end always @(posedge clk) begin y <= {1'b0, y[3:1]}; // 右移一位,高位补0 end endmodule
再解决输出全「x」的问题
输出全X一般是因为信号没有被正确驱动,你的serial主模块里有两个关键错误:
- 错误的wire初始化
你写了:
wire s = 0; wire cin = 0;
这种写法会强制把s和cin固定为0,直接覆盖了全加器和D触发器的输出驱动!正确的做法是只声明wire,不要给初始值:
wire s; wire cin;
D触发器的initial已经把输出初始化为0了,所以cin的初始值会是0,刚好符合加法的初始进位要求。
- 时钟周期不足
你的测试平台里只生成了3个时钟上升沿(repeat(6)),但4位加法需要4个时钟周期才能完成4次移位相加,所以要把时钟次数改多一点:
initial begin #5 clock = 1'b0; repeat(8) // 生成4个完整时钟周期,对应4个上升沿 # 5 clock = ~clock; end
最后给你整合好的完整修正代码
其他模块(sipo、fa、dff)是没问题的,不用修改,下面是修正后的核心模块和测试平台:
修正后的serial主模块
//main module serial adder// module serial(sum, cout, a, b, clk); input [3:0] a, b; input clk; wire [3:0] x, z; output [3:0] sum; output cout; wire s; wire cin; fa k(s, cout, x[0], z[0], cin); //1 bit full adder dff q(cin, cout, clk); //d flipflop to store the cout value after each 1 bit full adder operation sipo m(sum, s, clk); //serial sum(s) converted to parallel output(4 bit sum)/// shift g(x, a, clk); //shifts the input a shift h(z, b, clk); //shifts the input b endmodule
修正后的测试平台
module SATestBench; reg [3:0] a, b; reg clock; wire cout; wire [3:0] sum; serial sa(sum, cout, a, b, clock); initial begin #5 clock = 1'b0; repeat(8) # 5 clock = ~clock; end initial begin #0 a = 4'b1000; b=4'b0110; $monitor($time, " A = %b, B = %b, CarryOut = %b, Sum = %b.", sa.x, sa.z, cout, sum); #40 $finish; // 主动结束仿真 end endmodule
现在运行仿真的话,应该能看到正确的结果:1000 + 0110 = 1110,最终sum会是1110,cout为0(无进位)。
备注:内容来源于stack exchange,提问作者Anish Kasegaonkar
相关产品推荐
相关产品推荐

