Synchronous Binary counter question.

Hello All

OK Im a bit confused.

the verilog code

always @(posedge CLK or posedge CLR) begin if (CLR) Q

Reply to
Denis Gleeson
Loading thread data ...

Reply to
Peter Alfke

because

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

Reply to
Glen Herrmannsfeldt

You wrote it.

-a

Reply to
Andy Peters

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.

Reply to
Bob Feng

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

Reply to
Denis Gleeson

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 i); bnext = bin + 1; gray_plus_1 = (bnext>>1) ^ bnext; end

endmodule

Reply to
Bob Perlman

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.

formatting link
formatting link

-t

Reply to
Anthony J Bybell

I once wrote a program to explore gray code sequences (more than ten years ago). You can download it from:

formatting link

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?
Reply to
Petter Gustad

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.

Reply to
Andy Peters

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:

Reply to
Peter Alfke

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) ^ next_binary_ctr_val;

always @(posedge clk or posedge global_async_reset) gray_ctr

Reply to
Bob Perlman

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.