Generate synchronous signals

K

Konx

Guest
Hi everyone.

I'm trying to write a piece of code that generates a signal, according
to a specific value in a clk_counter signal. the logic would be:

- if "reset" is high: set the clk_counter to zero
- if "reset" is low: at every positive edge of the clk, increment the
clk_counter
- when clk_counter = 7, set the "trigger" signal to 1 (or high)
- when clk_counter = 50, set the "trigger" to 0 (or low)
- when clk_counter = 100, set the clk_counter to zero and
automatically start again another cycle

(so, basically, if the reset is low I should see a "periodic" trigger
coming out). I want my code synthesizeable (it is not a testbench).
This is what I wrote:

module logic_gen(
clk_40,
reset,
trigger);

input clk_40;
input reset;
output trigger;

reg [31:0] clk_counter;
reg trigger;

always@(posedge clk_40)
if(reset)
begin
clk_counter <= 32'b00000000000000000000000000000000;
end else
begin
clk_counter <= clk_counter+1;
if(clk_counter == 7)
trigger <= 1'b1;
if(clk_counter == 50)
trigger <= 1'b0;
if(clk_counter == 100)
clk_counter <= 32'b00000000000000000000000000000000;
end

endmodule




I know that the coding style is awful (I'm learning-by-doing by
myself) but is this logic suppose to work? do you see big mistakes?

For reference: I'm using this code as one module inside a big design
that target a Xilinx FPGA; I can synthesize the code using the Xilinx
ISE and I can produce the bitstream, so I guess that I'm not seeing
the signal coming out because the code is logically wrong.

I hope I've explained well enough the problem, if you need other
informations just ask :)

Thank you very much in advance for any help

Francesco.
 
An "else if" is handy to make sure things don't get confused. I
believe your code *should* still work but by not including the if/else
if/else structure, you have the possibility that the synthesizer and
future readers get confused.

Minor points:
Don't use tabs, they're different from editor to editor.
Consider using C-type in-line declarations valid since Verilog2001.
If you have a single statement in a begin/end block consider using
it alone.
If you only need 7 bits in a counter, don't declare 32 bits.
Keep numbers dimensioned in compares and arithmetic for consistency.
Consider initializing with hex or decimal rather than binary.
You don't *have to* show all leading zeros in an init though
sometimes it's nice to see.

It's usually a good idea to keep assignments for one register entirely
within one statement (also if/else or case statement, even if case
else) rather than allowing the order of assignments to dictate what
occurs on a cycle; specifically, the 100 count wants to reset the
counter but you already counted by one; the if/else shows clearly your
intent.

One thing you didn't include which should probably be in your code
(and I didn't add below) is an initialization of trigger to 1'b0
during the reset block. Right now if you reset while trigger is high,
the "if( reset )" branch will simply hold the last trigger value,
whether 1 or 0.

Upon inspection, it looks like your code *should* have worked.
Perhaps you're leaving the reset on? Rather than *just* looking at
the trigger, consider looking at the count bits (or one bit) to make
sure there's activity.

The following huge paragraph is a comment on "style" which may be
helpful for visually clean code down the road. I've had much of this
summarized in bullet points for green engineers before, but I'm just
talking to what I did in the code rearrangement:

This is your code where the only functional difference should be the
if/else statements (and associated order) though I would have expected
the "function" to be the same. The rest of the formatting is my own
personal preferences which help to make code more readable. Use two
spaces per indent. Split the port definitions out so everything is
well ordered to include the port names starting in one column and the
commas continuing from start bracket to end bracket with the module
name above with the port definitions. When declarations are local to
an always block rather than at the head of the file, I like to
"attach" them visually with a comment blank line so the code doesn't
cluttering up too badly - attached, yet separate. The "if" statements
tend to read easier (on my eyes at least) when the open/close
parentheses are a space away from the conditions; no need for a space
between the if and the open parenthesis. Two spaces *after* the close
parenthesis helps split the statement visually off the condition. I
prefer to always include an else on a new line after a block end -
it's easy to lose the else visually otherwise. In an if/else if/else
construct, it's simpler to follow the flow when the conditions are
visually aligned. A one-line if-plus-statement is often helpful when
the statements are physically short to help tighten the code
vertically; if the statement is long, separate lines are almost always
preferred and even split up onto multiple lines when exceedingly
long. Lining up the non-blocking operators helps to keep the
assignments visually clean. Keeping the begin and end statements
indented the same as the if/else statements they follow keeps the
indentation for the statements within a block the same as indentation
of statements without a block. Keeping always blocks "solid" by not
having blank lines and using blank lines between always blocks keeps
functionality together; comment lines between chunks within a block
adds clarity without breaking up the block - attached, yet separate.

module
logic_gen
( input clk_40
, input reset
, output reg trigger
);

reg [6:0] clk_counter;
//
always@(posedge clk_40)
if( reset )
clk_counter <= 7'h0;
else
begin
if( clk_counter == 7'd100 ) clk_counter <= 7'h0;
else clk_counter <= clk_counter + 7'd1;
//
if( clk_counter == 7'd7 ) trigger <= 1'b1;
else if( clk_counter == 7'd50 ) trigger <= 1'b0;
end

endmodule

So, with a trigger reset included in the reset block (bring the begin/
end back in) and the if/else constructs, the code should be clean and
(still) work. Since Verilog has no sense of a "newline" outside of
line comments (//) there's flexibility in splitting and combining
items to/from different lines for visual clarity.
 
On 1 Apr, 14:00, John_H <newsgr...@johnhandwork.com> wrote:
An "else if" is handy to make sure things don't get confused.  I
believe your code *should* still work but by not including the if/else
if/else structure, you have the possibility that the synthesizer and
future readers get confused.
[cut]

Hi John_H!

Thank you for your detailed answer and your suggestions about code-
formatting :)

I'll try to follow this guidelines and see if they fit for me too!

Thanks again,

bye

Francesco.
 
On 1 Nisan, 15:00, John_H <newsgr...@johnhandwork.com> wrote:
An "else if" is handy to make sure things don't get confused.  I
believe your code *should* still work but by not including the if/else
if/else structure, you have the possibility that the synthesizer and
future readers get confused.

Minor points:
  Don't use tabs, they're different from editor to editor.
  Consider using C-type in-line declarations valid since Verilog2001.
  If you have a single statement in a begin/end block consider using
it alone.
  If you only need 7 bits in a counter, don't declare 32 bits.
  Keep numbers dimensioned in compares and arithmetic for consistency.
  Consider initializing with hex or decimal rather than binary.
  You don't *have to* show all leading zeros in an init though
sometimes it's nice to see.

It's usually a good idea to keep assignments for one register entirely
within one statement (also if/else or case statement, even if case
else) rather than allowing the order of assignments to dictate what
occurs on a cycle; specifically, the 100 count wants to reset the
counter but you already counted by one; the if/else shows clearly your
intent.

One thing you didn't include which should probably be in your code
(and I didn't add below) is an initialization of trigger to 1'b0
during the reset block.  Right now if you reset while trigger is high,
the "if( reset )" branch will simply hold the last trigger value,
whether 1 or 0.

Upon inspection, it looks like your code *should* have worked.
Perhaps you're leaving the reset on?  Rather than *just* looking at
the trigger, consider looking at the count bits (or one bit) to make
sure there's activity.

The following huge paragraph is a comment on "style" which may be
helpful for visually clean code down the road.  I've had much of this
summarized in bullet points for green engineers before, but I'm just
talking to what I did in the code rearrangement:

This is your code where the only functional difference should be the
if/else statements (and associated order) though I would have expected
the "function" to be the same.  The rest of the formatting is my own
personal preferences which help to make code more readable.  Use two
spaces per indent.  Split the port definitions out so everything is
well ordered to include the port names starting in one column and the
commas continuing from start bracket to end bracket with the module
name above with the port definitions.  When declarations are local to
an always block rather than at the head of the file, I like to
"attach" them visually with a comment blank line so the code doesn't
cluttering up too badly - attached, yet separate.  The "if" statements
tend to read easier (on my eyes at least) when the open/close
parentheses are a space away from the conditions; no need for a space
between the if and the open parenthesis.  Two spaces *after* the close
parenthesis helps split the statement visually off the condition.  I
prefer to always include an else on a new line after a block end -
it's easy to lose the else visually otherwise.  In an if/else if/else
construct, it's simpler to follow the flow when the conditions are
visually aligned.  A one-line if-plus-statement is often helpful when
the statements are physically short to help tighten the code
vertically; if the statement is long, separate lines are almost always
preferred and even split up onto multiple lines when exceedingly
long.  Lining up the non-blocking operators helps to keep the
assignments visually clean. Keeping the begin and end statements
indented the same as the if/else statements they follow keeps the
indentation for the statements within a block the same as indentation
of statements without a block.  Keeping always blocks "solid" by not
having blank lines and using blank lines between always blocks keeps
functionality together; comment lines between chunks within a block
adds clarity without breaking up the block - attached, yet separate.

module
  logic_gen
  ( input      clk_40
  , input      reset
  , output reg trigger
  );

reg [6:0] clk_counter;
//
always@(posedge clk_40)
  if( reset )
    clk_counter <= 7'h0;
  else
  begin
    if( clk_counter == 7'd100 )  clk_counter <= 7'h0;
    else                         clk_counter <= clk_counter + 7'd1;
    //
    if(      clk_counter == 7'd7  )  trigger <= 1'b1;
    else if( clk_counter == 7'd50 )  trigger <= 1'b0;
  end

endmodule

So, with a trigger reset included in the reset block (bring the begin/
end back in) and the if/else constructs, the code should be clean and
(still) work.  Since Verilog has no sense of a "newline" outside of
line comments (//) there's flexibility in splitting and combining
items to/from different lines for visual clarity.
Considering the your experience. Which book do you suggest for the
newbies?
One who wants to learn verilog, should begin where and how?

Ali
 
On 1 Nisan, 15:00, John_H <newsgr...@johnhandwork.com> wrote:
An "else if" is handy to make sure things don't get confused.  I
believe your code *should* still work but by not including the if/else
if/else structure, you have the possibility that the synthesizer and
future readers get confused.

Minor points:
  Don't use tabs, they're different from editor to editor.
  Consider using C-type in-line declarations valid since Verilog2001.
  If you have a single statement in a begin/end block consider using
it alone.
  If you only need 7 bits in a counter, don't declare 32 bits.
  Keep numbers dimensioned in compares and arithmetic for consistency.
  Consider initializing with hex or decimal rather than binary.
  You don't *have to* show all leading zeros in an init though
sometimes it's nice to see.

It's usually a good idea to keep assignments for one register entirely
within one statement (also if/else or case statement, even if case
else) rather than allowing the order of assignments to dictate what
occurs on a cycle; specifically, the 100 count wants to reset the
counter but you already counted by one; the if/else shows clearly your
intent.

One thing you didn't include which should probably be in your code
(and I didn't add below) is an initialization of trigger to 1'b0
during the reset block.  Right now if you reset while trigger is high,
the "if( reset )" branch will simply hold the last trigger value,
whether 1 or 0.

Upon inspection, it looks like your code *should* have worked.
Perhaps you're leaving the reset on?  Rather than *just* looking at
the trigger, consider looking at the count bits (or one bit) to make
sure there's activity.

The following huge paragraph is a comment on "style" which may be
helpful for visually clean code down the road.  I've had much of this
summarized in bullet points for green engineers before, but I'm just
talking to what I did in the code rearrangement:

This is your code where the only functional difference should be the
if/else statements (and associated order) though I would have expected
the "function" to be the same.  The rest of the formatting is my own
personal preferences which help to make code more readable.  Use two
spaces per indent.  Split the port definitions out so everything is
well ordered to include the port names starting in one column and the
commas continuing from start bracket to end bracket with the module
name above with the port definitions.  When declarations are local to
an always block rather than at the head of the file, I like to
"attach" them visually with a comment blank line so the code doesn't
cluttering up too badly - attached, yet separate.  The "if" statements
tend to read easier (on my eyes at least) when the open/close
parentheses are a space away from the conditions; no need for a space
between the if and the open parenthesis.  Two spaces *after* the close
parenthesis helps split the statement visually off the condition.  I
prefer to always include an else on a new line after a block end -
it's easy to lose the else visually otherwise.  In an if/else if/else
construct, it's simpler to follow the flow when the conditions are
visually aligned.  A one-line if-plus-statement is often helpful when
the statements are physically short to help tighten the code
vertically; if the statement is long, separate lines are almost always
preferred and even split up onto multiple lines when exceedingly
long.  Lining up the non-blocking operators helps to keep the
assignments visually clean. Keeping the begin and end statements
indented the same as the if/else statements they follow keeps the
indentation for the statements within a block the same as indentation
of statements without a block.  Keeping always blocks "solid" by not
having blank lines and using blank lines between always blocks keeps
functionality together; comment lines between chunks within a block
adds clarity without breaking up the block - attached, yet separate.

module
  logic_gen
  ( input      clk_40
  , input      reset
  , output reg trigger
  );

reg [6:0] clk_counter;
//
always@(posedge clk_40)
  if( reset )
    clk_counter <= 7'h0;
  else
  begin
    if( clk_counter == 7'd100 )  clk_counter <= 7'h0;
    else                         clk_counter <= clk_counter + 7'd1;
    //
    if(      clk_counter == 7'd7  )  trigger <= 1'b1;
    else if( clk_counter == 7'd50 )  trigger <= 1'b0;
  end

endmodule

So, with a trigger reset included in the reset block (bring the begin/
end back in) and the if/else constructs, the code should be clean and
(still) work.  Since Verilog has no sense of a "newline" outside of
line comments (//) there's flexibility in splitting and combining
items to/from different lines for visual clarity.
Considering to your experience, one who wants to learn verilog, should
begin where and how?
Do you suggest a book what you know for newbies?

Sto.
 
On Sat, 3 Apr 2010 08:50:39 -0700 (PDT), John_H wrote:

I'm sorry to say I have no suggestions for texts or similar
resources.
I'm inclined to agree; the general usefulness of Verilog
texts I've seen is disappointing (the situation for VHDL
is much better).

When I did take one Verilog class early on in
my experience, I was sincerely saddened to discover (two days into the
4 day course) that they *weren't* teaching Verilog for synthesis but
were teaching how to use the simulator product also named Verilog.
Anyone who's listening: please bear in mind that there *are* some
excellent training classes out there. I'm sure John_H is right that
there are some lemons too. But there's no doubt that a good course
from a reputable independent vendor (such as my former employer
Doulos, or Sunburst, or Sutherland-HDL, just to start your search)
will more than pay for itself if you are writing Verilog for
serious professional purposes. Sure, the total cost of the
course (fees, travel, lost time at work) will be some thousands
of dollars - but that is way, way less than the cost to a project
of wasted time because of some simple error that you likely
wouldn't have made after proper, focused training. And the
courses I'm thinking about most definitely *are* practical,
and will teach you how to write good synthesisable code as
well as how to use Verilog for simulation. The trainers I'm
thinking of are all talented, experienced engineers too, and
a training class is often a place for picking up priceless
practical design and verification tips that aren't on the
syllabus.

Naturally, the economic arguments are very different if you
are in academia, or a hobbyist. In those environments, self-
teaching, with all its frustration, slowness and inefficiency,
nevertheless brings other rewards; and the penalties for late
project completion are generally less severe too.

Disclaimer:
I am no longer working as a trainer and have no vested
interest, but I retain personal contacts with many folk
in the training business.
--
Jonathan Bromley
 
On Apr 3, 9:49 am, Stonerain <ali...@gmail.com> wrote:
Considering to your experience, one who wants to learn verilog, should
begin where and how?
Do you suggest a book what you know for newbies?

Sto.
I'm sorry to say I have no suggestions for texts or similar
resources. The discussion has occurred on this newsgroup several
times before; a search may provide some nice references.

My own experience came from looking through other peoples' code, lots
of trial and error, and the natural evolution that comes from coding
over many, many years. When I did take one Verilog class early on in
my experience, I was sincerely saddened to discover (two days into the
4 day course) that they *weren't* teaching Verilog for synthesis but
were teaching how to use the simulator product also named Verilog.
 

Welcome to EDABoard.com

Sponsor

Back
Top