I'm pretty new to verilog, and I'm trying to learn the difference between
wire and reg. I've looked through an altera tutorial that I have, but it
hasn't been much of a help in explaining these two.
I realize that a wire represents a node, and that a reg can hold a
variable of any bit size. But, that doesn't help me with I am looking a
making a simple adder, as follows:
module adder(a, b, sum);
input [15:0] a, b;
output [15:0] sum;
// reg [15:0] sum; // Why do I have to use wire here? I get
errors when I use
wire [15:0] sum; // reg. I don't understand why reg doesn't
work.
assign sum = a + b;
endmodule
Can someone please explain why I have to use wire, and why reg doesn't work?
Now with this code for a 4 or 8 bit shifter, I use reg, and it works fine.
module shifter (in, cnt, result);
input [7:0] in;
input [1:0] cnt;
output [15:0] result;
reg [15:0] result;
always @(cnt)
begin
if (cnt[1:0] == 2'b00)
assign result = in;
else if (cnt[1:0] == 2'b01)
assign result = in<<4;
else if (cnt[1:0] == 2'b10)
assign result = in<<8;
else if (cnt[1:0] == 2'b11)
assign result = in;
end
endmodule
so, I obviously don't understand what I'm doing...
any explanation would be great
thanks,
--Matt
This is one of the most common stumbling blocks for newcomers to Verilog. A
good way to remember this is *Use a reg when you are assigning a value to a
variable in an always or an initial block and use a wire when you are
doing a continuos assignment (namely the assign statement).*
> module shifter (in, cnt, result);
>
> input [7:0] in;
> input [1:0] cnt;
> output [15:0] result;
>
> reg [15:0] result;
>
> always @(cnt)
> begin
> if (cnt[1:0] == 2'b00)
> assign result = in;
> else if (cnt[1:0] == 2'b01)
> assign result = in<<4;
> else if (cnt[1:0] == 2'b10)
> assign result = in<<8;
> else if (cnt[1:0] == 2'b11)
> assign result = in;
> end
In the first example you have a continuous assignment and so it has to
be defined as a wire while in the second example you have an always block
"always @(cnt)" and so the variable has to be defined as a reg.
All a reg means in a variable is that it is a data type which can store a
variable, it *does not* imply the inference of a flip-flop. If you want to
infer a flip flop, you need to make a clocked always block eg.
always @(posedge clock)
variable = variable +1;
HTH,
vikas
so you can write an combinatorial adder as:
wire [3:0] ans = a + b;
or: reg [3:0] ans;
always @(a or b) begin
ans = a + b;
end
But this gets to be WAY too burdonsome if you have a large combinatorial
block (say a microport).
It took me a while to wrap my head around wires/regs, but after you work
with it for a while it makes a lot of sense.
One thing to be careful with (that I noticed once): If you use assign
statements then the wires get directional. i.e.,
[code fragment]
output my_answer;
wire temp_wire;
assign temp_wire = my_answer;
SOMEMODULE a( .output(temp_wire));
endmodule
The wire temp_wire won't drive the output in this example (assume that
SOMEMODULE.output is some output driver), due to the assignment
statement.
But if you write it as "assign my_answer = temp_wire" it will work.
Moral of the story: You can't just treat wires as connections, they can
have directionality.
--
Jason Rosinski
Mitel Semiconductor
Jason_R...@mitel.com
Jason Rosinski - mrd wrote:
> Moral of the story: You can't just treat wires as connections, they can
> have directionality.
Its stronger than that. At RTL/behavioural level wire *always* has directionality
from the driver(s) to the receivers. If you connect 2 "drivers" to the same wire
and they are driving opposite values the wire goes to `X'. This makes it hard, for
example, to model a QuickSwitch part without resorting to Verilog's gate level
primitives.
For a reg variable the definition is that it retains the last value assigned to it
from which ever always block did the assignment. The language allows a reg to be
assigned from multiple always blocks but synthesis tools will reject this [There's
one case where they shouldn't - inferring dual port RAMs - but, with no offense
intended, that's not really for newbies].
One final thing. I would strongly advise you, before you go any further, to start
coming to grips with the differences between blocking and non-blocking assignments.
Read everything you can starting with the LRM and think very hard about it. Its the
standard killer for Verilog newbies, incl. yours truely when I started 2.5 years
ago.
Here's some more rules of thumb (most already covered, the last two in
regards to the blocking and non-blocking assignments:
1. If it's assigned in an initial block or an always block, then it must be
reg.
2. If it's an assign statement or if it's connecting ports of instantiated
modules, then it's a wire.
3. If it's a reg (i.e. it's being assigned in an always block or an initial
block) and you are trying to design synchronous sequential logic
(flip-flops), then use the non-blocking procedural assignment (<=).
4. If it's a reg (i.e. it's being assigned in an always block or an initial
block) and you are trying to design combinatorial logic, then use the
blocking signal assignment.
There may be exceptions to the last two, but as far as I know, they are not
typical. And I do not claim to know much, so use these rules at your own
risk. ;-)
Good luck with your learning Verilog. It's really quite simple once you get
the reg, wire, blocking, and non-blocking rules set in your mind.
--
Marty
Marty Pietruszka wrote:
> "Good luck with your learning Verilog. It's really quite simple once you get
> the reg, wire, blocking, and non-blocking rules set in your mind.
> --
> Marty
He's right and once you have got to grips with it you'll wonder why you waited
so long.
If I may offer one further piece of advice culled from what I didn't do when I
was learning. If you've come from the VHDL world you probably don't need telling
but if you are an HDL newbie then ...
Start running your designs through the synthesis tools as early as possible so
the habits needed to write synthesiable code get embedded early on and you get
to know your synth tool's capabilities & weaknesses.
Vikas Mishra wrote:
>
> "Matt Plante" <mapl...@iol.unh.edu> writes:
> > Hello,
<SNIP>
> All a reg means in a variable is that it is a data type which can store a
> variable, it *does not* imply the inference of a flip-flop. If you want to
> infer a flip flop, you need to make a clocked always block eg.
>
> always @(posedge clock)
> variable = variable +1;
>
Just a small (but significant to a newcomer) note: Use non blocking
assignments within sequential (clocked) blocks:
i.e.
always @(posedge clock)
begin
variable <= variable + 1;
end
HTH,
Srini
> HTH,
> vikas
--
Srinivasan Venkataramanan (Srini)
ASIC Design Engineer,
Chennai (Madras), India