3
\$\begingroup\$

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:

  1. Am I doing it wrong?
  2. Is there a better way? (e.g. something like c = {a,b};)
\$\endgroup\$
  • \$\begingroup\$ assign x = y is creating a "wire" between x and y. Pretty efficient. \$\endgroup\$ – Eugene Sh. Aug 26 '15 at 19:25
  • \$\begingroup\$ Meaning assign c[0] = b; and assign c[1] = a; ? \$\endgroup\$ – Daniel B. Aug 26 '15 at 19:30
  • \$\begingroup\$ Or even assign c = {a, b} \$\endgroup\$ – Eugene Sh. Aug 26 '15 at 19:32
  • \$\begingroup\$ I still need to create the register though right? And what is the difference between 'assign' and 'wire'? \$\endgroup\$ – Daniel B. Aug 26 '15 at 19:32
  • \$\begingroup\$ Depends on what you are trying to do. think of assign as a connection point, while wire is ..well.. wire :) \$\endgroup\$ – Eugene Sh. Aug 26 '15 at 19:35
8
\$\begingroup\$

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.

\$\endgroup\$

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.