Created
June 16, 2015 13:04
-
-
Save ikwzm/9906cc59b186e681f075 to your computer and use it in GitHub Desktop.
cdc_fifo
This file contains 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
module cdc_fifo | |
#( | |
parameter DATA_WIDTH = 8, | |
parameter ADDR_WIDTH = 8 | |
) | |
( | |
// -------- clock domain: read -------- | |
input clk_cr, | |
output [DATA_WIDTH-1:0] data_cr, | |
input req_cr, | |
output empty_cr, | |
// -------- clock domain: write -------- | |
input clk_cw, | |
input [DATA_WIDTH-1:0] data_cw, | |
input req_cw, | |
output full_cw | |
); | |
// binary to gray-code conversion | |
function [DATA_WIDTH-1:0] bin2gray | |
( | |
input [DATA_WIDTH-1:0] data_in | |
); | |
begin | |
bin2gray = {1'b0, data_in[DATA_WIDTH-1:1]} ^ data_in[DATA_WIDTH-1:0]; | |
end | |
endfunction | |
// -------- clock domain: read -------- | |
reg [ADDR_WIDTH-1:0] addr_r_cr = 1'd0; | |
reg [ADDR_WIDTH-1:0] addr_r_gray_cr; | |
wire [ADDR_WIDTH-1:0] addr_r_next_cr; | |
wire [ADDR_WIDTH-1:0] addr_w_sync_cr; | |
assign addr_r_next_cr = addr_r_cr + 1'd1; | |
assign empty_cr = (addr_r_gray_cr == addr_w_sync_cr) ? 1'b1 : 1'b0; | |
always @(posedge clk_cr) | |
begin | |
if ((req_cr == 1'b1) && (empty_cr == 1'b0)) | |
begin | |
addr_r_cr <= addr_r_next_cr; | |
addr_r_gray_cr <= bin2gray(addr_r_next_cr); | |
end | |
end | |
// -------- clock domain: write -------- | |
reg [ADDR_WIDTH-1:0] addr_w_cw = 1'd0; | |
wire [ADDR_WIDTH-1:0] addr_w_next_gray_cw; | |
wire [ADDR_WIDTH-1:0] addr_r_gray_cw; | |
wire we_cw; | |
wire [ADDR_WIDTH-1:0] addr_w_next_cw; | |
wire [ADDR_WIDTH-1:0] addr_r_sync_cw; | |
reg [ADDR_WIDTH-1:0] addr_w_gray_cw; | |
assign addr_w_next_cw = addr_w_cw + 1'd1; | |
assign full_cw = (addr_w_next_gray_cw == addr_r_sync_cw) ? 1'b1 : 1'b0; | |
assign we_cw = ((req_cw == 1'b1) && (full_cw == 1'b0)) ? 1'b1 : 1'b0; | |
assign addr_w_next_gray_cw = bin2gray(addr_w_next_cw); | |
always @(posedge clk_cw) | |
begin | |
if (we_cw == 1'b1) | |
begin | |
addr_w_cw <= addr_w_next_cw; | |
addr_w_gray_cw <= addr_w_next_gray_cw; | |
end | |
end | |
synchronizer | |
#( | |
.DATA_WIDTH (ADDR_WIDTH) | |
) | |
synchronizer_0 | |
( | |
.clk_out (clk_cw), | |
.data_in (addr_r_gray_cr), | |
.data_out(addr_r_sync_cw) | |
); | |
synchronizer | |
#( | |
.DATA_WIDTH (ADDR_WIDTH) | |
) | |
synchronizer_1 | |
( | |
.clk_out (clk_cr), | |
.data_in (addr_w_gray_cw), | |
.data_out(addr_w_sync_cr) | |
); | |
dual_port_ram | |
#( | |
.DATA_WIDTH (DATA_WIDTH), | |
.ADDR_WIDTH (ADDR_WIDTH) | |
) | |
dual_port_ram_0 | |
( | |
.data_in (data_cw), | |
.read_addr (addr_r_cr), | |
.write_addr (addr_w_cw), | |
.we (we_cw), | |
.read_clock (clk_cr), | |
.write_clock (clk_cw), | |
.data_out (data_cr) | |
); | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment