Hello All
OK Im a bit confused.
the verilog code
always @(posedge CLK or posedge CLR) begin if (CLR) Q
Hello All
OK Im a bit confused.
the verilog code
always @(posedge CLK or posedge CLR) begin if (CLR) Q
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
You wrote it.
-a
I am confused by your terminology.
Correct me if I am wrong.
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
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
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.
-t
I once wrote a program to explore gray code sequences (more than ten years ago). You can download it from:
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 0The 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?
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.
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:
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
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.