Last active
July 8, 2017 07:01
-
-
Save C47D/847c5f4f66a59f74999fd199a25595d3 to your computer and use it in GitHub Desktop.
generic gray code generator written in verilog.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// file: gray.pcf | |
set_io clk_out 95 | |
set_io gray_leds[3] 96 | |
set_io gray_leds[2] 97 | |
set_io gray_leds[1] 98 | |
set_io gray_leds[0] 99 | |
set_io clk 21 | |
set_io rst 112 | |
// synthesis with yosys for ice40hx1k device (iceStick) | |
// $ yosys -p "synth_ice40 -blif gray.blif" gray.v gray_code_generator.v binary_counter.v clk_divider.v | |
// $ arachne-pnr -d 1k -p gray.pcf gray.blif -o gray.asc | |
// $ icepack gray.asc gray.bin | |
// program the icestick | |
// $ iceprog gray.bin | |
// time analysis | |
// $ icetime -p gray.pcf -d hx1k gray.asc | |
// file: gray.v | |
`timescale 1ns / 1ps | |
`default_nettype none | |
module top | |
( | |
input clk, | |
input rst, | |
output [3:0] gray_leds, | |
output clk_out | |
); | |
wire clk_1hz; | |
assign clk_out = clk_1hz; | |
localparam CLK_DIVISOR = 6_000_000; | |
localparam GRAY_CODE_BITS = 4; | |
clk_divider #(.DIVIDER(CLK_DIVISOR)) | |
div( | |
.clk(clk), | |
.rst(rst), | |
.clk_o(clk_1hz) | |
); | |
gray_code_counter #(.BITS(GRAY_CODE_BITS)) | |
g_counter ( | |
.clk(clk_1hz), | |
.rst(rst), | |
.gray_code(gray_leds) | |
); | |
endmodule | |
// 4bits Gray count: | |
// 0000 | |
// 0001 | |
// 0011 | |
// 0010 | |
// 0110 | |
// 0111 | |
// 0101 | |
// 0100 | |
// 1100 | |
// 1101 | |
// 1111 | |
// 1110 | |
// 1010 | |
// 1011 | |
// 1001 | |
// 1000 | |
// and back to 0000 | |
// file: gray_code_generator.v | |
module gray_code_counter #( | |
parameter BITS = 2 | |
)( | |
input clk, | |
input rst, | |
output [BITS-1:0] gray_code | |
); | |
wire [BITS-1:0] bin_cnt_output; | |
binary_counter #(.BITS(BITS)) | |
b_counter ( | |
.clk(clk), | |
.rst(rst), | |
.cnt(bin_cnt_output) | |
); | |
assign gray_code = bin_cnt_output ^ bin_cnt_output[BITS-1:1]; | |
endmodule | |
// file: binary_counter.v | |
module binary_counter #( | |
parameter BITS = 2 | |
)( | |
input clk, | |
input rst, | |
output reg [BITS-1:0] cnt | |
); | |
always @ (posedge clk) begin | |
if ( rst ) cnt <= 0; | |
else cnt <= cnt + 1; | |
end | |
endmodule | |
// file: clk_divider.v | |
module clk_divider #( | |
parameter DIVIDER = 6_000_000 | |
)( | |
input clk, | |
input rst, | |
output reg clk_o | |
); | |
reg [$clog2(DIVIDER)-1:0] cnt = 0; | |
always @(posedge clk) begin | |
if ( rst ) begin | |
cnt <= 0; | |
clk_o <= 0; | |
end else begin | |
if (cnt == DIVIDER) begin | |
clk_o <= ~clk_o; | |
cnt <= 0; | |
end | |
else cnt <= cnt + 1; | |
end | |
end | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
rev 3: Remove a reg named rst on the clk_divider module, use the rst_n input instead.
rev 4: Fix the rst_n signal on the clk_divider, make sure it's active low.
rev 5: Remove redundant comments.
rev 6: Fix indentation and code style.
rev 7: Change the polarity of the rst signal, changed from active low to active high, the FFs reset signal on the iCE40 devices are active high.
rev 8: Fixed typo on always block of the clk_divider module (from rst_n to rst).