You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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主模块里有两个关键错误:

  1. 错误的wire初始化
    你写了:
wire s = 0;
wire cin = 0;

这种写法会强制把s和cin固定为0,直接覆盖了全加器和D触发器的输出驱动!正确的做法是只声明wire,不要给初始值:

wire s;
wire cin;

D触发器的initial已经把输出初始化为0了,所以cin的初始值会是0,刚好符合加法的初始进位要求。

  1. 时钟周期不足
    你的测试平台里只生成了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 08:48:10