FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > Verilog

Verilog comp.lang.verilog newsgroup / usenet

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 11-04-2009, 07:46 PM
Riad KACED
Guest
 
Posts: n/a
Default generate/genvar, for loop and procdural (always/initial) block

Dear Community,

I'm fairly new to Verilog and I'm already hitting some hurdles using
the 'genvar' statement.
I have written 2 verilog modules, both of them are using for loops.
though the for loop index is required to be genvar when used out of
always/initial block.
This is my example:

1. The loop index is genvar, the compile fails otherwise:

module rkXor (xout, xin1, xin2);
parameter width = 4;
output [1:width] xout;
input [1:width] xin1, xin2;
genvar i;
for ( i = 1; i <= width; i=i+1 )
assign xout[i] = xin1[i] ^ xin2[i];
endmodule

2. The loop index is integer, the compile would complain otherwise:

module clock1(clock);
parameter period = 20;
parameter nbBits = 4;
output [0:nbBits-1] clock;
reg [0:nbBits-1] clock;
integer i,j;
initial begin
for (i = 0; i < nbBits; i=i+1) begin: loop1
clock[i] = 0;
end
end
always
begin
for (j = 0; j < nbBits; j=j+1) begin: loop2
#(period/2) clock[j] = 1;
#(period/2) clock[j] = 0;
end
end
endmodule

Can someone shed some light on this please ? i.e. why the loop is
behaving differently when used in the always/initial bloc ?

Thank you very much in advance,
Regards,
Riad.
Reply With Quote
  #2 (permalink)  
Old 11-04-2009, 08:42 PM
pallav
Guest
 
Posts: n/a
Default Re: generate/genvar, for loop and procdural (always/initial) block

On Nov 4, 2:46*pm, Riad KACED <[email protected]> wrote:
> Dear Community,
>
> I'm fairly new to Verilog and I'm already hitting some hurdles using
> the 'genvar' statement.
> I have written 2 verilog modules, both of them are using for loops.
> though the for loop index is required to be genvar when used out of
> always/initial block.
> This is my example:
>
> 1. The loop index is genvar, the compile fails otherwise:
>
> module rkXor (xout, xin1, xin2);
> * parameter width = 4;
> * output [1:width] xout;
> * input [1:width] xin1, xin2;
> * genvar i;
> * for ( i = 1; i <= width; i=i+1 )
> * * * assign *xout[i] = xin1[i] ^ xin2[i];
> endmodule
>
> 2. The loop index is integer, the compile would complain otherwise:
>
> module clock1(clock);
> * parameter period = 20;
> * parameter nbBits = 4;
> * output [0:nbBits-1] clock;
> * reg [0:nbBits-1] clock;
> * integer i,j;
> * initial begin
> * * for (i = 0; i < nbBits; i=i+1) begin: loop1
> * * * clock[i] = 0;
> * * end
> * end
> * always
> * begin
> * * for (j = 0; j < nbBits; j=j+1) begin: loop2
> * * * #(period/2) clock[j] = 1;
> * * * #(period/2) clock[j] = 0;
> * * end
> * end
> endmodule
>
> Can someone shed some light on this please ? i.e. why the loop is
> behaving differently when used in the always/initial bloc ?
>
> Thank you very much in advance,
> Regards,
> Riad.


Welcome to verilog. Your life will be much easier if you get into the
habit of thinking like how the hardware works as opposed to writing
"code" in software. Your first module is better written as:

module rkXor #(parameter WIDTH = 4) (xout, xin1, xin2);
output [WIDTH-1:0] xout;
input [WIDTH-1:0] xin1, xin2;

assign xout[WIDTH-1:0] = xin1[WIDTH-1:0] ^ xin2[WIDTH-1:0];
endmodule

The conventional notation for signals, register is MSB:LSB. And we
start from 0.

Others can correct me, but I think I've only ever used genvar in
generate/endgenerate blocks where I want to instantiate the same
modules with different bit-selects of a signals. Because you didn't
use generate/endgenerate block the compile failed. In this case, there
isn't a need to use it. Verilog is very good in understanding "bits"
provided you specify them.

You should spend some time understanding how the "assign" statement
works. I like to think of it as continuous evaluation. An event is
scheduled to update the output when the inputs change.

In your second case, you can declare clock as reg [3:0] clock. Then,
to initialize it to 0 at t=0 of simulation,

initial begin
clock[3:0] = 4'b0000;


Initial blocks execute only once at the beginning of simulation.
Always blocks execute each time the specified condition is true. I
prefer to specify the sensitivity list or use always @(*). A better
way might be to use the verilog mode for Emacs and use always @(/
*AUTOSENSE*/) and let the mode generate the sensitivity list for you.
You should look into that.

One way to generate a clock is as follows:

// generate clock
reg clk;
parameter CLOCK_PERIOD = 10;
initial
clk <= 1'b0;
always #(CLOCK_PERIOD/2) clk = ~clk;

Hope this helps.
Reply With Quote
  #3 (permalink)  
Old 11-04-2009, 08:55 PM
gabor
Guest
 
Posts: n/a
Default Re: generate/genvar, for loop and procdural (always/initial) block

On Nov 4, 2:46*pm, Riad KACED <[email protected]> wrote:
> Dear Community,
>
> I'm fairly new to Verilog and I'm already hitting some hurdles using
> the 'genvar' statement.
> I have written 2 verilog modules, both of them are using for loops.
> though the for loop index is required to be genvar when used out of
> always/initial block.
> This is my example:
>
> 1. The loop index is genvar, the compile fails otherwise:
>
> module rkXor (xout, xin1, xin2);
> * parameter width = 4;
> * output [1:width] xout;
> * input [1:width] xin1, xin2;
> * genvar i;
> * for ( i = 1; i <= width; i=i+1 )
> * * * assign *xout[i] = xin1[i] ^ xin2[i];
> endmodule
>


I'm surprised that this compiles as shown. What compiler are
you running? I would assume you needed a generate statement
like:
generate
genvar i;
for ( i = 1; i <= width; i=i+1 ) begin : BLOCK_NAME
assign xout[i] = xin1[i] ^ xin2[i];
end
endgenerate

That is unless you take the other suggestion of coding it
without a loop.

> 2. The loop index is integer, the compile would complain otherwise:
>
> module clock1(clock);
> * parameter period = 20;
> * parameter nbBits = 4;
> * output [0:nbBits-1] clock;
> * reg [0:nbBits-1] clock;
> * integer i,j;
> * initial begin
> * * for (i = 0; i < nbBits; i=i+1) begin: loop1
> * * * clock[i] = 0;
> * * end
> * end
> * always
> * begin
> * * for (j = 0; j < nbBits; j=j+1) begin: loop2
> * * * #(period/2) clock[j] = 1;
> * * * #(period/2) clock[j] = 0;
> * * end
> * end
> endmodule
>
> Can someone shed some light on this please ? i.e. why the loop is
> behaving differently when used in the always/initial bloc ?
>
> Thank you very much in advance,
> Regards,
> Riad.


There's a very good reference book from Doulos called the
Verilog Golden Reference Guide. It describes how the
generate works and how loops inside a generate statement
are different from loops in a procedural block.

Regards,
Gabor
Reply With Quote
  #4 (permalink)  
Old 11-04-2009, 09:10 PM
Riad KACED
Guest
 
Posts: n/a
Default Re: generate/genvar, for loop and procdural (always/initial) block

Hi Pallv,

Thank you very much indeed for your prompt answer.
Well, your comments are very interesting. They don't help me that much
with understanding my problem though.

Both modules I have provided did not use any generate/endgenerate.
Though, one module has worked not the other. the generate/endgenerate
is not required as far as I understand. In fact, I have just read the
following from the Verilog-D IEEE Std 1364-2005 doc (Page 181):

"The keywords generate and endgenerate may be used in a module to
define a generate region. A generate region is a textual span in the
module description where generate constructs may appear. Use of
generate regions is optional. There is no semantic difference in the
module when a generate region is used. A parser may choose to
recognize the generate region to produce different error messages for
misused generate construct keywords ..."
Besides, I'm rather a user of Verilog-AMS where the generate is an
obsolete statement that is left for legacy reasons. This is another
story, I'm just interested in Verilog-D right here.

My guess is that a the for loop behaves differently when in a
procedural bloc like initial/always. That's what I'm trying to
understand.
Anyway, thanks for your advice on the other bits of my code.

Cheers,
Riad.
Reply With Quote
  #5 (permalink)  
Old 11-04-2009, 09:21 PM
Riad KACED
Guest
 
Posts: n/a
Default Re: generate/genvar, for loop and procdural (always/initial) block

Hi Gabor,

My code compiles, yes it does. One of the compilers I have run was
Cadence's ncvlog
Thanks for the reference, I'll try to get hold of it ...

Thanks for your help too !
Cheers,
Riad.
Reply With Quote
  #6 (permalink)  
Old 11-04-2009, 10:51 PM
pallav
Guest
 
Posts: n/a
Default Re: generate/genvar, for loop and procdural (always/initial) block

On Nov 4, 4:10*pm, Riad KACED <[email protected]> wrote:
> Well, your comments are very interesting. They don't help me that much
> with understanding my problem though.
>


Hi Riad,

Looks like I did not understand your question. Sorry.

Kind regards.
Reply With Quote
  #7 (permalink)  
Old 11-05-2009, 07:12 PM
Riad KACED
Guest
 
Posts: n/a
Default Re: generate/genvar, for loop and procdural (always/initial) block

Hi Palav,

Although it didn't really answer my question, your comments are still
very valuable and I'm very grateful for it !
Looking forward for some more people to comment this item !

Cheers,
Riad.
Reply With Quote
  #8 (permalink)  
Old 11-06-2009, 04:01 PM
Chris Briggs
Guest
 
Posts: n/a
Default Re: generate/genvar, for loop and procdural (always/initial) block

On Nov 5, 2:12*pm, Riad KACED <[email protected]> wrote:
> Although it didn't really answer my question, your comments are still
> very valuable and I'm very grateful for it !
> Looking forward for some more people to comment this item !


I think what you're missing is the distinction between code that's
"executed" at compile/elaboration time and code that runs at
simulation time (or run time). Obviously, I'm just talking about
simulation here; synthesis also has compile/elaboration time, but
doesn't support initial blocks, so I assume you're interested in
simulation at this point.

Side note: I apologize for lumping compilation and elaboration
together. They're technically different stages, one following the
other, but I don't have the differences at the tip of my brain right
now. They might be discussed in your simulator manual and should be in
the LRM. Reading up on them will help you here.

Generate statements are handled at compile/elaboration time. Your
first example is a generate-for and, being handled at comp/elab time,
it's a useful shorthand for putting down multiple module
instantiations, continuous assigns, or even whole sequential blocks (I
think), with some reference (bit, bit range, array location) varying
with the genvar. Essentially, generate-for statements are to save you
potentially lots of typing, but in theory you could unroll the loop
yourself because the loop count must be known in advance. You're using
it to create more code or structures that will go through compile/
elaboration and then simulation.

Your second example has two sequential blocks containing for loops.
These are not generate-for statements, they're sequential for
statements (I guess you'd call them that). As such, these are handled
at simulation time, and while I hate to put it this way, you can think
of them like a for loop in C -- that is, they can have a variable loop
count, the loop can be interrupted, etc., but most important, you're
not creating new structures, you're running a block of code multiple
times.

As others have mentioned, your generate-for to create multiple 1-bit
assignments is better (and more efficiently) replaced by a single
multi-bit assign, and there are better styles for clock generators.
Personally, I still like this one from Janick Bergeron's _Writing
Testbenches_, 1st ed.:

reg clk;
initial
forever begin
#(period/2) clk = 1'b0;
#(period/2) clk = 1'b1;
end

Clock events at time 0 used to cause problems though the simulation
vendors have cleaned those up. I still like delaying the first posedge
clk though. Makes it easier to see what happens on the first clock in
waves.

-cb
Reply With Quote
  #9 (permalink)  
Old 11-06-2009, 07:33 PM
gabor
Guest
 
Posts: n/a
Default Re: generate/genvar, for loop and procdural (always/initial) block

On Nov 6, 11:01*am, Chris Briggs <[email protected]> wrote:

[snip]

> . . . there are better styles for clock generators.
> Personally, I still like this one from Janick Bergeron's _Writing
> Testbenches_, 1st ed.:
>
> reg clk;
> initial
> * *forever begin
> * * * #(period/2) clk = 1'b0;
> * * * #(period/2) clk = 1'b1;
> * *end
>
> Clock events at time 0 used to cause problems though the simulation
> vendors have cleaned those up. I still like delaying the first posedge
> clk though. Makes it easier to see what happens on the first clock in
> waves.
>
> -cb


That's pretty useful, thanks. No edge at time zero but X-0
edge at period/2 is still a "negedge" event consistent with
the clock's operation. I've been using the Xilinx GUI to
generate a quick starter for testbenches, but they always
fill in all the module inputs in an initial block starting
at time zero. Not a problem for rising edge only clocks
when setting the initial to 0. Of course the Xilinx stuff
has other start-up issues like their semi-hidden GSR net
that resets all their structural models (but not your
behavioral code) for the first 100 ns of the simulation.

Most of my behavioral code is written with asynchronous
reset, so what happens on the first clock isn't so important.
However I do remember having some headaches with the falling
edge event at time zero due to the initial statement. I always
thought that "initial" was for initial conditions - i.e.
everything is assumed to start from there, but of course
the LRM says otherwise, i.e. everything is X until initialized
and that X to whatever transition is an event.

Regards,
Gabor
Reply With Quote
  #10 (permalink)  
Old 11-07-2009, 10:07 AM
Jonathan Bromley
Guest
 
Posts: n/a
Default Re: generate/genvar, for loop and procdural (always/initial) block

Gabor wrote:
> everything is X until initialized
> and that X to whatever transition is an event.


Yes, but be very afraid.... Since 2001 you have been
able to initialize module-level variables:

module foo;
reg clock = 0;
always #5 clock = ~clock;
...

But that reg-initialization is, by definition, exactly
equivalent to

reg clock;
initial clock = 0;

with the semantics that Gabor indicated - clock is
initially X but is changed to 0 as one of the many
things that happens at time 0. This is, of course,
a fine way to get lots of unpleasant races.

In SystemVerilog-2005, the meaning of that initialization
was redefined to be like a VHDL signal initialization:
the reg had that value since before the Big Bang, and
has no value-change event at time 0. With the soon-to-
happen merging of Verilog and SystemVerilog, this will
be the generally mandated behaviour.

It happens that most simulator vendors, trying to give
customers roughly what they expect, have implemented
register-initializers in such a way that there will be
no noticeable difference when the new rules kick in.
The de-facto behaviour is one of the legal orderings
of the Verilog code anyway, so the change will not be
disruptive. But it's as well to be very, very cautious
about what happens around time 0 and, as far as possible,
make your design and testbench completely immune to
time-0 races. Easier said than done :-(
--
Jonathan Bromley


Reply With Quote
  #11 (permalink)  
Old 11-17-2009, 05:41 PM
Riad KACED
Guest
 
Posts: n/a
Default Re: generate/genvar, for loop and procdural (always/initial) block

Hi Guys,

Thank you all for your time and very valuable comments on my query !
Very much appreciated,

Riad.
Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
actel block RAM initial value Antti FPGA 1 05-15-2009 01:18 PM
initial block processing in XST 8.1, part 2 Jeff Brower FPGA 0 05-26-2006 07:41 PM
initial block processing in XST 8.1 Jeff Brower FPGA 2 05-22-2006 03:35 PM
How to generate variable labels for same component within a generate loop Weng Tianxiang VHDL 5 02-16-2006 01:45 PM
declaration and initialization inside initial block Nikhil Verilog 0 11-01-2004 03:32 PM


All times are GMT +1. The time now is 11:29 AM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved