I'm just learning verilog and have a question regarding setting bits in a 2 bit register (assuming I'm even making the register correctly).
Suppose I have a hypothetical module, foo(), which has two inputs, and I want to combine these inputs into a 2 bit register. My thinking is that I would do something like ...
module foo(a,b)
input a,b;
reg [1:0] c;
c[0] = b;
c[1] = a;
I have two questions:
- Am I doing it wrong?
- Is there a better way? (e.g. something like c = {a,b};)
1 Answer 1
It really depends if you want c
as a reg
or a wire
. Both aproaches work, but reg
needs to be assigned in procedural block, while wire
needs an assign
statement (or assigned at declaration).
As a reg
, it needs to be defined inside a procedural block. Such as:
reg [1:0] c;
always @* begin
c = {a,b};
end
or:
reg [1:0] c;
always @* begin
c[1] = a;
c[0] = b;
end
There is no functional or behavior difference with the two always blocks, it is just a matter of preference for readability.
As a wire
it can be declared and assigned in one line:
wire [1:0] c = {a,b};
Or declared and assigned on separate lines:
wire [1:0] c;
assign c = {a,b};
Or declared with each bit assigned on separate lines:
wire [1:0] c;
assign c[0] = b;
assign c[1] = a;
All of the above examples will simulate and synthesize the same.
With wire
if there are two conflicting drivers on the same net, there will be an X in simulation. With reg
it is last assignment wins in simulation and not synthesis. The assign
per bit method has more simulation overhead, but normally only noticeable with very large designs.
Simulators are not required to evaluate always blocks at time-0, so there could be a short mismatch. Results will be identical after the stimulus changes after time-0. (Note: SystemVerilog's always_comb
always does time-0 evaluation and throws errors there is another possible driver on one of its bits it assigns.)
For a small module that only have simple combinational logic; it really doesn't matter using wire
with assign
vs reg
with always
. With an FSM, I like to put just about all my combination logic in one big always @*
. I find this typically gives the best simulation performance and synthesis result with my tool set. Occupationally I split the one always @*
into separate always @*
chunks when dealing with particularly noise asynchronous input signals.
assign x = y
is creating a "wire" betweenx
andy
. Pretty efficient. \$\endgroup\$assign c = {a, b}
\$\endgroup\$assign
as a connection point, whilewire
is ..well.. wire :) \$\endgroup\$