# Verilog: cannot be driven by primitives or continuous assignment

Could someone help me figure out why I am getting such an error. The code below implements a 4 bit shift register adder which takes one bit at a time from each register computes the sum of the 2 bits using a full adder stores the carry (previous) and then pushes the result of the full adder back to first shift register.thus at the end of 4 clock cycles the result (sum) is in the first register

Error i am getting Reg cannot be driven by primitives or continuous assignment.

CODE:

module FADDER(s,c,x,y,z);
input x,y,z;
output s,c;
reg s,c;

always @(x or y or z)
begin
s = (x^y)^z;
c = (x & y) | (y & z) | (z & x);
end
endmodule

output [3:0] a,b;
reg [3:0] a,b;
input clr, clk;

reg carr = 1'b0;
wire w1, newcarr;
wire w2,w3;

assign w2 = a[0];
assign w3 = b[0];
FADDER f(w1, newcarr, w2, w3, carr);

always @(posedge clk) begin
a <= {1'b0, a[3:1]};
a[3] <= w1;
b <= {1'b0, b[3:1]};
carr <= newcarr;
end
endmodule

module testbench;
reg [3:0] a,b;
reg clr, clk;

initial begin
clk = 0;
clr = 1;
end

always begin
#2 clk = ~clk;
end

initial $monitor($time, " clr %b a = %b b = %b prev_carr = %b", clr, a, b, s1.carr);

initial begin
a = 4'b0101;
b = 4'b1100;
clr = 1'b1;
end
endmodule

• Can you tell us what your error is and what you're expecting your output to be? (Please include this with your question by editing it) – KingDuken Oct 10 '19 at 15:42
• You still need to let us know what error you're seeing. What has the compiler told you? What is the functionality of this code? It kind of looks like a binary adder and then you're bit shifting your product but I don't know exactly what you're trying to do afterwards. Failing to provide this information could lead me to suspect that you're just copying and pasting someone else's code and then expecting it to work... Then that would make me refuse to answer this question since I wouldn't support plagiarism and/or academic dishonesty. – KingDuken Oct 10 '19 at 16:31
• Your usage of blocking and non-blocking assignments is correct, but you don't know why. That is suspicious! – Oldfart Oct 10 '19 at 16:33
• shift_reg_add s1(a,b,clr,clk); <<---- You declare a and b as reg in your test-bench, but then try to drive them from outputs of your shift_reg_add module. As such you will get an error saying a reg cannot be driven via continous assignment. Change a and b to wire in your testbench. This would be an answer, but the question is on hold. – Tom Carpenter Oct 10 '19 at 19:11
• go.mentor.com/wire-vs-reg – dave_59 Oct 10 '19 at 21:37

Your problem comes down to not correctly using wire vs reg in your test bench code.

Specifically:

reg [3:0] a,b;


You declare a and b as reg in your test-bench, but then try to drive them from outputs of your shift_reg_add module.

A reg (register) type variable can only be driven using a procedural block, that is primarily always, and initial. You cannot assign a value to a reg through continuous assignment.

A wire (net) type variable can be used to connect signals together using continuous assignment. This is either the assign statement or by being driven from the output of a module as in your case.

As such in your test bench, you will get an error saying a reg cannot be driven via continous assignment.

Change a and b to wire in your testbench.

Think of it this way, you declared your outputs as reg inside the module, this is fine because they are being driven from procedural blocks in the module. You now need to take what is essentially the output of your register, and connect it up in your test bench. This simply requires a net connection or $$`$$wire1.