Dumb Verilog Questions - Mostly about assignments

B

benn

Guest
I'm very new to Verilog, and I'm trying to learn by reading verilog
code from openCores.org... unfortunately, I see syntax thats not
entirely consistent.. I'm sure its makes total sense to everyone
else, but pretty confusing for me. For example...

Most "assign" assignments, use "=", as opposed to "<=" (perhaps it
doesn't matter), while most begin/end blocks have statements inside
that use "<=" as opposed to "="... confusing because I've also seen
code that uses "=" inside begin/end, so it must be acceptable!!).

Wire assignments ( wire a = b;) never seem to use "<=", but perhaps I
just haven't read enough examples. I think I'm starting to sound like
Andy Rooney, so I'll just cut to the questions:

1) When do you use "<=" over "="? Is there any rule where its
prohibited to use one or the other?

2) Is there a difference between "wire a = b;" and "assign a = b;"?
(i.e. when can you omit "assign")?

3) When a module has outputs, a "wire" of the same name is often (but
not always) declared as well. Why?

4) When would you use "reg" over "wire", for example, to me, "wire
[15:0]a;" and "reg [15:0]a" both create a 16 bit bus that can be used
for internal assignments (i.e. like variables in c).

5) The "?" operator always seems to come up in wire assignments only,
but not in begin/end blocks. Is this a coincidence? In other words,
is this legal:

input inWire;
output outWire;
begin
outWire = inWire ? 1'b0 : 1'b1;
end

Thanks!
 
On Thu, 10 Apr 2008 22:49:43 -0700 (PDT), benn wrote:

I'm very new to Verilog, and I'm trying to learn by reading verilog
code from openCores.org...
I suspect you need a good textbook or tutorial. opencores is
(in my personal opinion) often of patchy quality, and the
coding styles you see there are very varied.

The questions you're asking are important but rather basic.
Let me try to summarise, and then you must go away and do
some more reading.

1) When do you use "<=" over "="? Is there any rule where its
prohibited to use one or the other?

2) Is there a difference between "wire a = b;" and "assign a = b;"?
(i.e. when can you omit "assign")?

3) When a module has outputs, a "wire" of the same name is often (but
not always) declared as well. Why?

4) When would you use "reg" over "wire", for example, to me, "wire
[15:0]a;" and "reg [15:0]a" both create a 16 bit bus that can be used
for internal assignments (i.e. like variables in c).

5) The "?" operator always seems to come up in wire assignments only,
but not in begin/end blocks. Is this a coincidence? In other words,
is this legal:
Assignment
~~~~~~~~~~
appears in two different contexts in Verilog:

CONTINUOUS ASSIGNMENT in which the value of an expression
is computed whenever it changes, and the value is driven
continuously on to a net as if by a hardware buffer:

wire some_net;
assign some_net = some_expression;

or the shorthand, but exact equivalent , "wire assignment":

wire some_net = some_expression;

Continuous assignment invariably uses "=" - that's a syntax rule.
The expression is quite likely to include the ?: operator,
because that's a neat way to describe multiplexer or choice
behaviour and - obviously - you can't use if...else in an
expression.

PROCEDURAL ASSIGNMENT in which the value of an expression
is computed at the moment procedural execution flow reaches
the relevant statement, and is then copied (possibly with
a time delay) on to a variable.

reg some_variable, some_other;
always @(posedge clock)
some_variable <= some_expression;
always @(some_variable)
some_other = some_variable;

Because you've got procedural code, you can use if..else
(within a begin...end, because "always" controls only
one procedural statement) and therefore there is less
temptation to use ?:, althoug ?: is perfectly legal in
any expression and is often a better way to describe a
hardware multiplexer (that one will have to wait for
another day!). The choice of = or <= assignment has
been discussed ad nauseam here, but if you're writing
design (synthesisable) code the rule is simple:

- in any combinational logic, use = ;
- in a clocked block, use <= to avoid read/write races
at the moment of the clock edge UNLESS you are writing
to a variable declared locally within that block.
The nonblocking assignment <= evaluates the expression
immediately, but postpones the variable update until
all other activity has completed at the moment of the
clock edge, so - as a trivial example - in this piece of
code...

always @(posedge clock) begin
B <= A;
C <= B;
end

the second assignment will see the value of B as it was
JUST BEFORE the clock edge; the update B<=A will not yet
have taken effect. Such assignment invariably creates a
flipflop on the target variable.

NOTE that continuous assignment MUST drive a wire (more
generally, a net - but wire is by far the commonest sort
of net). Procedural assignment MUST drive a variable.
That's it, except to note that wires (but NOT variables)
can get their values by other means that are, in effect,
a kind of continuous assignment:
- connect a wire to the output port of a module
- on the inside of a module, an input port is a wire
that is effectively driven from the outside of the
module by continuous assign

Finally, the port declaration thing. The underlying
reasons for this are subtle, but the practical impact
is simple: When you declare an output port, you must
- name the port
- specify that it's an output
- if you plan to use procedural assignment
to it, specify that it's a variable (reg)
- if you plan to drive it by continuous assignment,
*optionally* specify it to be a wire (it is so,
by default).
Verilog-2001 (now supported by all realistic tools)
allows you to do all that in one hit:

module M2001 (
input A, // all inputs are wires
input [7:0] B, // 8-bit wire
output reg [3:0] C, // 4-bit variable
output wire [7:0] D, // 8-bit wire
output E, // 1-bit (wire by default)
output [1:0] F // 2-bit (wire by default)
);

but legacy code will use Verilog-95 style:

module M95 (A, B, C, D, E, F); // just a list of names
input A;
input [7:0] B;
output [3:0] C;
reg [3:0] C; // this must be separate
output [7:0] D;
wire [7:0] D; // legal but redundant
output E; // wire by default
output [1:0] F; // wire [1:0] by default

Now go away and trawl through the back-catalog of
comp.lang.verilog, read some books (good books on
Verilog are thin on the ground, though), buy a
Golden Reference Guide off our website (sorry for
the advert!), and keep asking.

Hope this helps - good luck!
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Fri, 11 Apr 2008 01:45:25 -0700 (PDT),
bvkrock <bvkrock@gmail.com> wrote:


"?" is a combinatorial form of if else statement for single
assignment, cannot be assigned to reg works only with wire and output
ports tht are not declared as "output reg sampleport"
What leads you to that conclusion? This works for me:

reg y;
always @(posedge clock)
y <= sel ? a : b;
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Apr 11, 5:49 am, benn <benn...@hotmail.com> wrote:
I'm very new to Verilog, and I'm trying to learn by reading verilog
code from openCores.org... unfortunately, I see syntax thats not
entirely consistent.. I'm sure its makes total sense to everyone
else, but pretty confusing for me. For example...

Most "assign" assignments, use "=", as opposed to "<=" (perhaps it
doesn't matter), while most begin/end blocks have statements inside
that use "<=" as opposed to "="... confusing because I've also seen
code that uses "=" inside begin/end, so it must be acceptable!!).

Wire assignments ( wire a = b;) never seem to use "<=", but perhaps I
just haven't read enough examples. I think I'm starting to sound like
Andy Rooney, so I'll just cut to the questions:

1) When do you use "<=" over "="? Is there any rule where its
prohibited to use one or the other?

2) Is there a difference between "wire a = b;" and "assign a = b;"?
(i.e. when can you omit "assign")?

3) When a module has outputs, a "wire" of the same name is often (but
not always) declared as well. Why?

4) When would you use "reg" over "wire", for example, to me, "wire
[15:0]a;" and "reg [15:0]a" both create a 16 bit bus that can be used
for internal assignments (i.e. like variables in c).

5) The "?" operator always seems to come up in wire assignments only,
but not in begin/end blocks. Is this a coincidence? In other words,
is this legal:

input inWire;
output outWire;
begin
outWire = inWire ? 1'b0 : 1'b1;
end

Thanks!
hi benn
in simple words
"=" assignment is for async (combinatorial) logic, values dont get
updated inside always(sequential)block, often used for wire
assignments "outside always"
"<=" assignment for sync logic, values get updated immd inside always
block.

"?" is a combinatorial form of if else statement for single
assignment, cannot be assigned to reg works only with wire and output
ports tht are not declared as "output reg sampleport"
 
On Apr 11, 5:49 am, benn <benn...@hotmail.com> wrote:
I'm very new to Verilog, and I'm trying to learn by reading verilog
code from openCores.org... unfortunately, I see syntax thats not
entirely consistent.. I'm sure its makes total sense to everyone
else, but pretty confusing for me. For example...

Most "assign" assignments, use "=", as opposed to "<=" (perhaps it
doesn't matter), while most begin/end blocks have statements inside
that use "<=" as opposed to "="... confusing because I've also seen
code that uses "=" inside begin/end, so it must be acceptable!!).

Wire assignments ( wire a = b;) never seem to use "<=", but perhaps I
just haven't read enough examples. I think I'm starting to sound like
Andy Rooney, so I'll just cut to the questions:

1) When do you use "<=" over "="? Is there any rule where its
prohibited to use one or the other?

2) Is there a difference between "wire a = b;" and "assign a = b;"?
(i.e. when can you omit "assign")?

3) When a module has outputs, a "wire" of the same name is often (but
not always) declared as well. Why?

4) When would you use "reg" over "wire", for example, to me, "wire
[15:0]a;" and "reg [15:0]a" both create a 16 bit bus that can be used
for internal assignments (i.e. like variables in c).

5) The "?" operator always seems to come up in wire assignments only,
but not in begin/end blocks. Is this a coincidence? In other words,
is this legal:

input inWire;
output outWire;
begin
outWire = inWire ? 1'b0 : 1'b1;
end

Thanks!
reg is used for assigning values inside always block
wire is used only for assigning values outside always block
a port with reg [15:0] port1, cannot be used for assign port1 = port2;
 
benn wrote:
I'm very new to Verilog, and I'm trying to learn by reading verilog
code from openCores.org... unfortunately, I see syntax thats not
entirely consistent.. I'm sure its makes total sense to everyone
else, but pretty confusing for me. For example...

Most "assign" assignments, use "=", as opposed to "<="
Here are two pages that have various papers about Verilog:

http://www.sunburst-design.com/papers/
http://www.sutherland-hdl.com/papers-by-sutherland.php

For the '=' vs. '<=' you should look for the terms 'blocking' vs.
'nonblocking' assignments.

The sunburst page has a good paper that explains the internal of a
Verilog simulator model and what happens with blocking vs. nonblocking
assignments during the simulation cycles.

Cheers,

Guenter
 
benn wrote:
(snip)

2) Is there a difference between "wire a = b;" and "assign a = b;"?
(i.e. when can you omit "assign")?
I don't usually use "wire a=b;" but note its similarity to the
C statement

int a=b;
(hopefully when b already has a value.)

I believe it is a combination of the wire declaration and assign.

3) When a module has outputs, a "wire" of the same name is often (but
not always) declared as well. Why?
You mean in an output statement and wire statement? I believe
that isn't needed but some might do it for consistency.

4) When would you use "reg" over "wire", for example, to me, "wire
[15:0]a;" and "reg [15:0]a" both create a 16 bit bus that can be used
for internal assignments (i.e. like variables in c).
The two have different uses. The way I remember it is that a wire is
just a wire, used to connect different logic blocks together.
A reg is like a wire, but keeps its value even when nothing is
currently connected to it. It is a little strange, but when you get
used to it, it works.

The continuous assignment statement is similar to the output of
a logic gate, it always has a value and uses wire.

With always blocks, any assignments (without the assign keyword)
are done only under the condition specified in the block.
That may generate a real register, but it might also generate
a multiplexer or maybe nothing at all.

always @(posedge clk) a=b;

changes the value of a only on the rising edge of clk.
It must be a reg to keep that value in between.

5) The "?" operator always seems to come up in wire assignments only,
but not in begin/end blocks. Is this a coincidence? In other words,
is this legal:

input inWire;
output outWire;
begin
outWire = inWire ? 1'b0 : 1'b1;
end
Yes, but those are wires. Wire is like int in C; it is
implied in many declarations unless something else is stated.

An output may also be a reg, but is a wire unless also declared
in a reg statement. An input should not be a reg.

-- glen
 
Thanks, that does clear things up quite a bit! I started reading a
book by Palnikar, but it was VERY short on real/full examples
(especially for how much it costs!) Thats when I turned to the net
in search of real-world verilog examples!

Just two follow-up questions to the statements you made,

Because you've got procedural code, you can use if..else
(within a begin...end, because "always" controls only
one procedural statement) and therefore ...
Does this mean you can have n-number of nonblocking assignment
statements ("<=") inside a "always" block, but only 1 procedural
assignment ("="), or it cannot be mixed-and-matched? For example, is
this allowed:

always @(posedge CLOCK)
begin
nb1 <= 1;
nb2 <= 1;
pa = 1;
nb3 <= 1;
end

And #2, it seems that you would always want to postpone the update to
a variable until all the assignments inside the block are made. When
would you ever WANT to use a procedural assignment and possibly
introduce a race condition?

Also, your signature shows the url http://www.mycompany.com , is this
right?

Thanks!
 
On Apr 11, 9:14 pm, benn <benn...@hotmail.com> wrote:
Thanks, that does clear things up quite a bit! I started reading a
book by Palnikar, but it was VERY short on real/full examples
(especially for how much it costs!) Thats when I turned to the net
in search of real-world verilog examples!

Just two follow-up questions to the statements you made,

Because you've got procedural code, you can use if..else
(within a begin...end, because "always" controls only
one procedural statement) and therefore ...

Does this mean you can have n-number of nonblocking assignment
statements ("<=") inside a "always" block, but only 1 procedural
assignment ("="), or it cannot be mixed-and-matched? For example, is
this allowed:

always @(posedge CLOCK)
begin
nb1 <= 1;
nb2 <= 1;
pa = 1;
nb3 <= 1;
end
This should work for simulation, but most synthesizers will not
permit any blocking assignments in the always block.

And #2, it seems that you would always want to postpone the update to
a variable until all the assignments inside the block are made. When
would you ever WANT to use a procedural assignment and possibly
introduce a race condition?
If the output of the blocking assignment is only used in the same
always
block there is no race condition.

for example:

always @(posedge CLOCK)
begin
nb1 <= 1;
nb2 <= 1;
pa = 1;
nb3 <= pa;
end

Here nb3 will be assigned 1 because pa is already 1 when the
non-blocking statement is reached.

Also, your signature shows the urlhttp://www.mycompany.com, is this
right?
When you realize how much spam you get from posting on UseNet
newsgroups, you'll probably try to hide your address, too. This
is standard practice, i.e. don;t make it machine readable for
spam-bots, but give hints so any human can figure it out.

Cheers,
Gabor

> Thanks!
 

Welcome to EDABoard.com

Sponsor

Back
Top