I was implementing a 4-bit shift adder using Verilog, and I was facing an issue with the following code:
//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
assign y=d;
end
always @(posedge clk)
assign y= {1'b0, d[3:1]};
endmodule
//serial in parallel out register to store the 4 bit sum
module sipo(y, s, clk);
input s, clk;
output [3:0] y;
reg [3:0] y;
always @(posedge clk)
begin
y={s,y[3:1]};
end
endmodule
//1 bit full adder
module fa(s, cout, a, b, cin);
input a, b, cin;
output s, cout;
assign {cout, s} = a + b + cin;
endmodule
//d flipflop to store the cout of each stage
module dff(q, d, clk);
input d, clk;
output q;
reg q;
initial begin
q = 1'b0;
end
always @(posedge clk)
begin
q = d;
end
endmodule
//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 = 0;
wire cin = 0;
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(6)
# 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);
end
endmodule
The error I was receiving was "vvp.tgt sorry: procedural continuous assignments are not yet fully supported. The RHS of this assignment will only be evaluated once, at the time the assignment statement is executed." I searched a bit online, and I found from here that assign isn't allowed in always blocks.
Then I tried removing the assign block, and then the output for Sum/CarryOut was only "x"s. I'm not able to fix this, I've tried for many hours now. I've just started learning Verilog, so I apologise if this is a novice mistake.
In the following snapshot of your exampe assign
used inside procedural blocks is the procedural continuous assignments which your message complains about.
initial begin
assign y=d;
end
always @(posedge clk)
assign y= {1'b0, d[3:1]};
This is a very special non-synthesizable statement seldom used if at all. You should avoid it.
Get rid of this keyword if it is used inside such a statemetn.
initial begin
y=d;
end
always @(posedge clk)
y <= {1'b0, d[3:1]};
Now you have a multiple-driver problem. Variable y is driven from two different procedural blocks. You should change that and use a reset instead:
always @(posedge clk) begin
if (reset)
y <= d;
else
y <= {1'b0, d[3:1]};
So, for that you should provide a reset.