-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sebastien Bourdeauducq
committed
Jul 1, 2012
1 parent
acdd34e
commit 16c6e4f
Showing
3 changed files
with
163 additions
and
4 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
* This file is based on "Asynchronous FIFO" by Alex Claros F., | ||
* itself based on the article "Asynchronous FIFO in Virtex-II FPGAs" | ||
* by Peter Alfke. | ||
*/ | ||
|
||
module asfifo #( | ||
parameter data_width = 8, | ||
parameter address_width = 4, | ||
parameter fifo_depth = (1 << address_width) | ||
) ( | ||
/* Read port */ | ||
output [data_width-1:0] data_out, | ||
output reg empty, | ||
input read_en, | ||
input clk_read, | ||
|
||
/* Write port */ | ||
input [data_width-1:0] data_in, | ||
output reg full, | ||
input write_en, | ||
input clk_write, | ||
|
||
/* Asynchronous reset */ | ||
input rst | ||
); | ||
|
||
reg [data_width-1:0] mem[fifo_depth-1:0]; | ||
wire [address_width-1:0] write_index, read_index; | ||
wire equal_addresses; | ||
wire write_en_safe, read_en_safe; | ||
wire set_status, clear_status; | ||
reg status; | ||
wire preset_full, preset_empty; | ||
|
||
assign data_out = mem[read_index]; | ||
|
||
always @(posedge clk_write) begin | ||
if(write_en & !full) | ||
mem[write_index] <= data_in; | ||
end | ||
|
||
assign write_en_safe = write_en & ~full; | ||
assign read_en_safe = read_en & ~empty; | ||
|
||
asfifo_graycounter #( | ||
.width(address_width) | ||
) counter_write ( | ||
.gray_count(write_index), | ||
.ce(write_en_safe), | ||
.rst(rst), | ||
.clk(clk_write) | ||
); | ||
|
||
asfifo_graycounter #( | ||
.width(address_width) | ||
) counter_read ( | ||
.gray_count(read_index), | ||
.ce(read_en_safe), | ||
.rst(rst), | ||
.clk(clk_read) | ||
); | ||
|
||
assign equal_addresses = (write_index == read_index); | ||
|
||
assign set_status = (write_index[address_width-2] ~^ read_index[address_width-1]) & | ||
(write_index[address_width-1] ^ read_index[address_width-2]); | ||
|
||
assign clear_status = ((write_index[address_width-2] ^ read_index[address_width-1]) & | ||
(write_index[address_width-1] ~^ read_index[address_width-2])) | ||
| rst; | ||
|
||
always @(posedge clear_status, posedge set_status) begin | ||
if(clear_status) | ||
status <= 1'b0; | ||
else | ||
status <= 1'b1; | ||
end | ||
|
||
assign preset_full = status & equal_addresses; | ||
|
||
always @(posedge clk_write, posedge preset_full) begin | ||
if(preset_full) | ||
full <= 1'b1; | ||
else | ||
full <= 1'b0; | ||
end | ||
|
||
assign preset_empty = ~status & equal_addresses; | ||
|
||
always @(posedge clk_read, posedge preset_empty) begin | ||
if(preset_empty) | ||
empty <= 1'b1; | ||
else | ||
empty <= 1'b0; | ||
end | ||
|
||
endmodule |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* This file is based on "Asynchronous FIFO" by Alex Claros F., | ||
* itself based on the article "Asynchronous FIFO in Virtex-II FPGAs" | ||
* by Peter Alfke. | ||
*/ | ||
|
||
module asfifo_graycounter #( | ||
parameter width = 2 | ||
) ( | ||
output reg [width-1:0] gray_count, | ||
input ce, | ||
input rst, | ||
input clk | ||
); | ||
|
||
reg [width-1:0] binary_count; | ||
|
||
always @(posedge clk, posedge rst) begin | ||
if(rst) begin | ||
binary_count <= {width{1'b0}} + 1; | ||
gray_count <= {width{1'b0}}; | ||
end else if(ce) begin | ||
binary_count <= binary_count + 1; | ||
gray_count <= {binary_count[width-1], | ||
binary_count[width-2:0] ^ binary_count[width-1:1]}; | ||
end | ||
end | ||
|
||
endmodule |