Synchronous Binary counter question.

D

Denis Gleeson

Guest
Hello All

OK Im a bit confused.

the verilog code

always @(posedge CLK or posedge CLR)
begin
if (CLR)
Q <= 20'b0;
else
if (CE) // Is counter Enabled.
begin
Q<=Q+1;
end
end

produces a ripple counter? Yes, No?

When I look at my simulation results I see glitches in the count output
leading me to assume that I have implemented a ripple counter.

IS it possible to remove the glitches with a synchronous Binary counter?
If yes what is the verilog code?

Ive read about Gray counters but as Im using the counter to step through
SRAM addresses I dont want to loose storage locations in my SRAM just because
my counter doesnt count through all possible binary counts.


Thanks in advance for all suggestions.


Denis
 
A properly designed Gray counter steps through all binary addresses.
It's just the sequence that differes from a binary counter.
A normal Linear Shift register counter (LFSR) skips one code, but
additional logic can remedy that also.
Just for the record...
Peter Alfke, Xilinx Applications

Denis Gleeson wrote:
Ive read about Gray counters but as Im using the counter to step through
SRAM addresses I dont want to loose storage locations in my SRAM just because
my counter doesnt count through all possible binary counts.
 
"Denis Gleeson" <dgleeson-2@utvinternet.com> wrote in message
news:184c35f9.0309250354.763cf662@posting.google.com...
Hello All

OK Im a bit confused.

the verilog code

always @(posedge CLK or posedge CLR)
begin
if (CLR)
Q <= 20'b0;
else
if (CE) // Is counter Enabled.
begin
Q<=Q+1;
end
end

produces a ripple counter? Yes, No?
I prefer structural verilog, but I would have thought it would be a
synchronous counter.

When I look at my simulation results I see glitches in the count output
leading me to assume that I have implemented a ripple counter.

IS it possible to remove the glitches with a synchronous Binary counter?
If yes what is the verilog code?
Even a synchronous counter will glitch, but they should be shorter. The
outputs might have different rise and fall times, for example. I don't know
if the simulation would show that, though.

Ive read about Gray counters but as Im using the counter to step through
SRAM addresses I dont want to loose storage locations in my SRAM just
because
my counter doesnt count through all possible binary counts.
Gray counters should count through all possible counts. I do hope you are
not changing the address on the SRAM with write enable active.

-- glen
 
dgleeson-2@utvinternet.com (Denis Gleeson) wrote in message news:<184c35f9.0309250354.763cf662@posting.google.com>...
Hello All

OK Im a bit confused.

the verilog code

always @(posedge CLK or posedge CLR)
begin
if (CLR)
Q <= 20'b0;
else
if (CE) // Is counter Enabled.
begin
Q<=Q+1;
end
end

produces a ripple counter? Yes, No?
Looks like a synchronous counter to me.

When I look at my simulation results I see glitches in the count output
leading me to assume that I have implemented a ripple counter.
What simulator are you using? What's in your test bench?

IS it possible to remove the glitches with a synchronous Binary counter?
If yes what is the verilog code?
You wrote it.

-a
 
I am confused by your terminology.

Correct me if I am wrong.
1. You are looking for a "synchrounous binary counter". Isn't it the one you
just wrote?
2. What is the matter with ripple counter? And what is the difference from a
"synchrounous binary counter"?
3. Gray code should be able to walk through all the addresses.

---Bob
"Denis Gleeson" <dgleeson-2@utvinternet.com> wrote in message
news:184c35f9.0309250354.763cf662@posting.google.com...
Hello All

OK Im a bit confused.

the verilog code

always @(posedge CLK or posedge CLR)
begin
if (CLR)
Q <= 20'b0;
else
if (CE) // Is counter Enabled.
begin
Q<=Q+1;
end
end

produces a ripple counter? Yes, No?

When I look at my simulation results I see glitches in the count output
leading me to assume that I have implemented a ripple counter.

IS it possible to remove the glitches with a synchronous Binary counter?
If yes what is the verilog code?

Ive read about Gray counters but as Im using the counter to step through
SRAM addresses I dont want to loose storage locations in my SRAM just
because
my counter doesnt count through all possible binary counts.


Thanks in advance for all suggestions.


Denis
 
Ok I was confused.

I did implement a synchronous counter as everybody points out.
The glitches are due to routing delays in the FPGA.

Now Im not confused any more.

All I need now is to find verilog for a 16 bit gray code counter.

Many thanks

Denis



"Bob Feng" <yi.feng@sbcglobal.net> wrote in message news:<XLPcb.3437$6b6.3086@newssvr29.news.prodigy.com>...
I am confused by your terminology.

Correct me if I am wrong.
1. You are looking for a "synchrounous binary counter". Isn't it the one you
just wrote?
2. What is the matter with ripple counter? And what is the difference from a
"synchrounous binary counter"?
3. Gray code should be able to walk through all the addresses.

---Bob
"Denis Gleeson" <dgleeson-2@utvinternet.com> wrote in message
news:184c35f9.0309250354.763cf662@posting.google.com...
Hello All

OK Im a bit confused.

the verilog code

always @(posedge CLK or posedge CLR)
begin
if (CLR)
Q <= 20'b0;
else
if (CE) // Is counter Enabled.
begin
Q<=Q+1;
end
end

produces a ripple counter? Yes, No?

When I look at my simulation results I see glitches in the count output
leading me to assume that I have implemented a ripple counter.

IS it possible to remove the glitches with a synchronous Binary counter?
If yes what is the verilog code?

Ive read about Gray counters but as Im using the counter to step through
SRAM addresses I dont want to loose storage locations in my SRAM just
because
my counter doesnt count through all possible binary counts.


Thanks in advance for all suggestions.


Denis
 
On 26 Sep 2003 06:08:08 -0700, dgleeson-2@utvinternet.com (Denis
Gleeson) wrote:

Ok I was confused.

I did implement a synchronous counter as everybody points out.
The glitches are due to routing delays in the FPGA.

Now Im not confused any more.

All I need now is to find verilog for a 16 bit gray code counter.
Try this. Credit where credit is due: as noted in the comments, the
gray code calculation comes from a paper by Cliff Cummings.

Bob Perlman
Cambrian Design Works

//===============================================================
// Module
//===============================================================
//
// Module: gray_ctr_module.v
//
// Author: Bob Perlman
//
// Description: The Verilog code for a gray-code counter
// incorporates a gray-to-binary converter, a binary-
// to-gray converter and increments the binary value
// between conversions.
//
// This code was based on Cliff Cummings' 2001 SNUG paper,
// "Synthesis and Scripting Techniques for Designing
// Multi-Asynchronous Clock Designs."
//
// Revision history:
// Rev. Date Modification
// ---- --------
----------------------------------------------
// - 12/29/01 Baseline version

`timescale 1 ns / 1 ps
module gray_ctr_module
(// Outputs
gray_ctr,
// Inputs
inc_en, preload_en, preload_val, clk, global_async_reset
);

//==================
// Parameters
//==================

parameter SIZE = 4;


//==================
// Port declarations
//==================

output [SIZE-1:0] gray_ctr;

input inc_en;
input preload_en;
input [SIZE-1:0] preload_val;
input clk;
input global_async_reset; // Global asynchronous reset

//====================================================
// Reg, wire, integer, task, and function declarations
//====================================================

reg [SIZE-1:0] gray_plus_1, gray_ctr, bnext, bin;
integer i;

//=================
// Logic
//=================

always @(posedge clk or posedge global_async_reset)
gray_ctr <= #1 global_async_reset ? 0 :
preload_en ? preload_val :
inc_en ? gray_plus_1 :
gray_ctr;

// Calculate next gray code by:
// 1) Converting current gray counter value to binary
// 2) Incrementing the binary value
// 3) Converting the incremented binary value to gray code

always @(gray_ctr or inc_en) begin
for (i=0; i<SIZE; i=i+1)
bin = ^(gray_ctr >> i);
bnext = bin + 1;
gray_plus_1 = (bnext>>1) ^ bnext;
end

endmodule
 
produces a ripple counter? Yes, No?

Looks like a synchronous counter to me.
If he's using Icarus, older versions (a couple of months back) prior
to the RoSync fix for the VCD writer would dump a value change entry
per bitchange. As such, you could observe the value updating from the
LSB->MSB if you'd look at the VCD file in a text editor.

http://archives.seul.org/geda/dev/Apr-2003/msg00060.html
http://archives.seul.org/geda/dev/Apr-2003/msg00061.html
<etc>

-t
 
dgleeson-2@utvinternet.com (Denis Gleeson) writes:

Ok I was confused.

I did implement a synchronous counter as everybody points out.
The glitches are due to routing delays in the FPGA.

Now Im not confused any more.

All I need now is to find verilog for a 16 bit gray code counter.
I once wrote a program to explore gray code sequences (more than ten
years ago). You can download it from:

http://gustad.com/pub/eda/jc.tgz

It will generate Verilog for part of a case statement. For three bits
you could do:

../jct 3
../jct is starting up
case 10'b000: ns = 10'b001;
case 10'b001: ns = 10'b011;
case 10'b011: ns = 10'b010;
case 10'b010: ns = 10'b110;
case 10'b110: ns = 10'b111;
case 10'b111: ns = 10'b101;
case 10'b101: ns = 10'b100;
case 10'b100: ns = 10'b000;
../jct is finishing up

There's also another program called jc which will generate all
possible sequences, but you have to build the set of numbers in the
source. Here's the output for three bits

Set permute
0 1 3 2 6 4 5 7
0 1 3 2 6 7 5 4 circular
0 1 3 7 5 4 6 2 circular
0 1 5 4 6 2 3 7
0 1 5 4 6 7 3 2 circular
0 1 5 7 3 2 6 4 circular
0 2 3 1 5 4 6 7
0 2 3 1 5 7 6 4 circular
....
7 6 4 0 2 3 1 5 circular
7 6 4 5 1 0 2 3 circular
7 6 4 5 1 3 2 0


The program will give some errors/warning if compiled on a recent g++,
but this should be easy to fix by moving the "unsigned int i" out of
the for loop. C++ wasn't even a standard when I started programming in
C++ in the late 80's. The reference was the "cfront" implementation by
AT&T.

Petter

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
dgleeson-2@utvinternet.com (Denis Gleeson) wrote in message news:<184c35f9.0309260508.672fc895@posting.google.com>...
Ok I was confused.

I did implement a synchronous counter as everybody points out.
The glitches are due to routing delays in the FPGA.
You needn't be concerned with the glitches if the counter outputs will
be used synchronously, assuming, of course, that the counter outputs
are stable by the next clock edge. Your static timing analyzer will
tell you if you win or not.

--a
 
I think I have a significantly simpler implementation of a Gray counter:

Start with a plain-vanilla binary counter.
Add to it a register of equal length, where the Gray count value will appear.
Drive each Di input of the Gray register with the XOR
of the binary counter's Di and Di+1 inputs, since any Gray bit is the
XOR of the two (equivalent and equivalent+1) binary bits.
The subtle trick is to not use the binary Q outputs, but rather their D
inputs to drive the Gray register, which avoids having the Gray counter
trail the binary counter. (Good when the counter has a CE input).

Peter Alfke, Xilinx Applications
=========================


Bob Perlman wrote:
On 26 Sep 2003 06:08:08 -0700, dgleeson-2@utvinternet.com (Denis
Gleeson) wrote:

Ok I was confused.

I did implement a synchronous counter as everybody points out.
The glitches are due to routing delays in the FPGA.

Now Im not confused any more.

All I need now is to find verilog for a 16 bit gray code counter.

Try this. Credit where credit is due: as noted in the comments, the
gray code calculation comes from a paper by Cliff Cummings.

Bob Perlman
Cambrian Design Works

//===============================================================
// Module
//===============================================================
//
// Module: gray_ctr_module.v
//
// Author: Bob Perlman
//
// Description: The Verilog code for a gray-code counter
// incorporates a gray-to-binary converter, a binary-
// to-gray converter and increments the binary value
// between conversions.
//
// This code was based on Cliff Cummings' 2001 SNUG paper,
// "Synthesis and Scripting Techniques for Designing
// Multi-Asynchronous Clock Designs."
//
// Revision history:
// Rev. Date Modification
// ---- --------
----------------------------------------------
// - 12/29/01 Baseline version

`timescale 1 ns / 1 ps
module gray_ctr_module
(// Outputs
gray_ctr,
// Inputs
inc_en, preload_en, preload_val, clk, global_async_reset
);

//==================
// Parameters
//==================

parameter SIZE = 4;

//==================
// Port declarations
//==================

output [SIZE-1:0] gray_ctr;

input inc_en;
input preload_en;
input [SIZE-1:0] preload_val;
input clk;
input global_async_reset; // Global asynchronous reset

//====================================================
// Reg, wire, integer, task, and function declarations
//====================================================

reg [SIZE-1:0] gray_plus_1, gray_ctr, bnext, bin;
integer i;

//=================
// Logic
//=================

always @(posedge clk or posedge global_async_reset)
gray_ctr <= #1 global_async_reset ? 0 :
preload_en ? preload_val :
inc_en ? gray_plus_1 :
gray_ctr;

// Calculate next gray code by:
// 1) Converting current gray counter value to binary
// 2) Incrementing the binary value
// 3) Converting the incremented binary value to gray code

always @(gray_ctr or inc_en) begin
for (i=0; i<SIZE; i=i+1)
bin = ^(gray_ctr >> i);
bnext = bin + 1;
gray_plus_1 = (bnext>>1) ^ bnext;
end

endmodule
 
the verilog code

always @(posedge CLK or posedge CLR)
begin
if (CLR)
Q <= 20'b0;
else
if (CE) // Is counter Enabled.
begin
Q<=Q+1;
end
end

produces a ripple counter? Yes, No?

When I look at my simulation results I see glitches in the count output
leading me to assume that I have implemented a ripple counter.

IS it possible to remove the glitches with a synchronous Binary counter?
This is a synchronous counter. If you're simulating with delays, then
then each bit f the vector may toggle at different delays, but that's OK.
Thus after clock time Q may do something like:
Q 1 0 1 1 // prior to clock
Q 1 0 1 0 // small delay
Q 1 1 1 0 // small delay
Q 1 1 0 0 // final settled value
Maybe this is what you're seeing.
----------------------------------------------------------------------------
Ben Cohen Publisher, Trainer, Consultant (310) 721-4830
http://www.vhdlcohen.com/ vhdlcohen@aol.com
Author of following textbooks:
* Using PSL/SUGAR with Verilog and VHDL
Guide to Property Specification Language for ABV, 2003 isbn 0-9705394-4-4
* Real Chip Design and Verification Using Verilog and VHDL, 2002 isbn
0-9705394-2-8
* Component Design by Example ", 2001 isbn 0-9705394-0-1
* VHDL Coding Styles and Methodologies, 2nd Edition, 1999 isbn 0-7923-8474-1
* VHDL Answers to Frequently Asked Questions, 2nd Edition, isbn 0-7923-8115
------------------------------------------------------------------------------
 
Hi -

On Fri, 26 Sep 2003 14:26:12 -0700, Peter Alfke <peter@xilinx.com>
wrote:

I think I have a significantly simpler implementation of a Gray counter:

Start with a plain-vanilla binary counter.
Add to it a register of equal length, where the Gray count value will appear.
Drive each Di input of the Gray register with the XOR
of the binary counter's Di and Di+1 inputs, since any Gray bit is the
XOR of the two (equivalent and equivalent+1) binary bits.
The subtle trick is to not use the binary Q outputs, but rather their D
inputs to drive the Gray register, which avoids having the Gray counter
trail the binary counter. (Good when the counter has a CE input).

Peter Alfke, Xilinx Applications
=========================
If you want the best speed and have the extra (~2X) FFs to spare,
Peter's is the better solution, at least for longer counters. Here's
the Verilog code for the implementation. I've synthesized but not
simulated it, so I can't promise that it works.

Hoping that this wasn't a homework problem,
Bob Perlman
Cambrian Design Works

//===============================================================
// Module
//===============================================================
//
// Module: gray_ctr_module.v
//

`timescale 1 ns / 1 ps
module gray_ctr_module
(// Outputs
gray_ctr,
// Inputs
inc_en, clk, global_async_reset
);

//==================
// Parameters
//==================

parameter SIZE = 16;

//==================
// Port declarations
//==================

output [SIZE-1:0] gray_ctr;

input inc_en;
input clk;
input global_async_reset; // Global asynchronous reset

//====================================================
// Reg, wire, integer, task, and function declarations
//====================================================

reg [SIZE-1:0] gray_ctr, binary_ctr;

wire [SIZE-1:0] next_binary_ctr_val,
next_gray_ctr_val;

//=================
// Logic
//=================

assign next_binary_ctr_val = binary_ctr + 1;

always @(posedge clk or posedge global_async_reset)
binary_ctr <= #1 global_async_reset ? 0 :
inc_en ? next_binary_ctr_val :
binary_ctr;

assign next_gray_ctr_val = ( next_binary_ctr_val >>1) ^
next_binary_ctr_val;

always @(posedge clk or posedge global_async_reset)
gray_ctr <= #1 global_async_reset ? 0 :
inc_en ? next_gray_ctr_val :
gray_ctr;

endmodule


Bob Perlman wrote:

On 26 Sep 2003 06:08:08 -0700, dgleeson-2@utvinternet.com (Denis
Gleeson) wrote:

Ok I was confused.

I did implement a synchronous counter as everybody points out.
The glitches are due to routing delays in the FPGA.

Now Im not confused any more.

All I need now is to find verilog for a 16 bit gray code counter.

Try this. Credit where credit is due: as noted in the comments, the
gray code calculation comes from a paper by Cliff Cummings.

Bob Perlman
Cambrian Design Works

//===============================================================
// Module
//===============================================================
//
// Module: gray_ctr_module.v
//
// Author: Bob Perlman
//
// Description: The Verilog code for a gray-code counter
// incorporates a gray-to-binary converter, a binary-
// to-gray converter and increments the binary value
// between conversions.
//
// This code was based on Cliff Cummings' 2001 SNUG paper,
// "Synthesis and Scripting Techniques for Designing
// Multi-Asynchronous Clock Designs."
//
// Revision history:
// Rev. Date Modification
// ---- --------
----------------------------------------------
// - 12/29/01 Baseline version

`timescale 1 ns / 1 ps
module gray_ctr_module
(// Outputs
gray_ctr,
// Inputs
inc_en, preload_en, preload_val, clk, global_async_reset
);

//==================
// Parameters
//==================

parameter SIZE = 4;

//==================
// Port declarations
//==================

output [SIZE-1:0] gray_ctr;

input inc_en;
input preload_en;
input [SIZE-1:0] preload_val;
input clk;
input global_async_reset; // Global asynchronous reset

//====================================================
// Reg, wire, integer, task, and function declarations
//====================================================

reg [SIZE-1:0] gray_plus_1, gray_ctr, bnext, bin;
integer i;

//=================
// Logic
//=================

always @(posedge clk or posedge global_async_reset)
gray_ctr <= #1 global_async_reset ? 0 :
preload_en ? preload_val :
inc_en ? gray_plus_1 :
gray_ctr;

// Calculate next gray code by:
// 1) Converting current gray counter value to binary
// 2) Incrementing the binary value
// 3) Converting the incremented binary value to gray code

always @(gray_ctr or inc_en) begin
for (i=0; i<SIZE; i=i+1)
bin = ^(gray_ctr >> i);
bnext = bin + 1;
gray_plus_1 = (bnext>>1) ^ bnext;
end

endmodule
 

Welcome to EDABoard.com

Sponsor

Back
Top