1
\$\begingroup\$

I am describing a behavioral model of an adder and subtractor with this simple code:

module TOP(
   input SEL,
   input A,
   input B,
   output O
);

always @(SEL)
   case(SEL)
      0:    O = A + B;
      1:    O = A - B;
   endcase

endmodule

However, I get the following error:

Procedural assignment to a non-register O is not permitted, left-hand side should be reg/integer/time/genvar

What is wrong with my behavioral model? Why do I need a register if this functionality can be implemented using combinational logic with primitives? Shouldn't those be just wires on the inputs and the output and a mux that selects the result? None of that needs register.

\$\endgroup\$
3
\$\begingroup\$

In Verilog a wire cannot store a value, it can only be used to connect two parts of a circuit together.

In order to be used in a procedural block (such as an always block, or initial block, etc.) a variable must be able to store a value, even if it is only during the processing of the block. As such you cannot assign a value to a wire within a procedural block because it cannot store a value.

In your case you are using your output in an always block, so your output cannot be a wire. If not specified to be otherwise an output is assumed to be a wire type. This is where your error occurs. In order to make the assignment in an always block you must therefore explicitly declare the output as a reg (i.e. output reg).


To expand on the point "Why do I need a register if this functionality can be implemented using combinational logic with primitives?":

Remember that Verilog is just a description language. You can declare things in many different ways, and not necessarily description just for FPGAs but also for simulation and other devices. As such what is inferred from the code is situation dependent.

An always block as far as Verilog is concerned is executed line by line, which means anything that is assigned within the always block must be able to store a value temporarily during the execution of the block, and depending on the code after execution as well.

Whether or not this storage represents registers, latches, or just plain combinational logic depends on how it synthesises which is for the most part up to the synthesis tool and not something defined in the Verilog spec. This is why regardless of what happens in the block the Verilog spec simply mandates that any variable used in a procedural block must be able to store a value.


In response to your comment, there are non-procedural ways of doing things which do not require registers - any combinational circuit can be defined without the need for procedural blocks.

An example in your case would be to use the ternary operator with a continuous assignment statement:

assign O = SEL ? (A - B) : (A + B);

When SEL is 1, O is assigned (A-B), otherwise O is (A+B).

\$\endgroup\$
  • \$\begingroup\$ Then, what's an alternative to not use procedural block? My point is that since the circuit does not have registers, could I create a behavioral model without using a register and still have the same function? \$\endgroup\$ – Nazar Jul 28 '17 at 23:57
  • \$\begingroup\$ @Naz see my edit. In your case you can use a ternary statement. \$\endgroup\$ – Tom Carpenter Jul 29 '17 at 0:01
  • \$\begingroup\$ I see, I was considering this approach, but how do you expand it to [1:0] sel? \$\endgroup\$ – Nazar Jul 29 '17 at 0:03
  • \$\begingroup\$ @Naz either nest ternaries: (SEL == 0) ? ... : (SEL == 1) ? ... : (SEL == 2) ... : ... and so forth, or as you are doing just use a procedural block with a reg. Both will result in the same hardware anyway. Which you go for is really down to whether you you care to put output reg O. \$\endgroup\$ – Tom Carpenter Jul 29 '17 at 0:08
  • \$\begingroup\$ You could also use a 2D array of wires as a mux. wire mux[1:0]; assign mux[0] = (A+B); assign mux[1] = (A-B); assign O = mux[SEL]; \$\endgroup\$ – Tom Carpenter Jul 29 '17 at 0:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.