Skip to content

Commit 6be0a48

Browse files
committed
DEM-UART: Initial implementation for FIFOs
1 parent 8d9016d commit 6be0a48

File tree

3 files changed

+546
-1
lines changed

3 files changed

+546
-1
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/* Copyright (c) 2017 by the author(s)
2+
*
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
* THE SOFTWARE.
20+
*
21+
* =============================================================================
22+
*
23+
* Synchronous First-Word Fall-Through (FWFT) FIFO
24+
*
25+
* This FIFO implementation wraps the FIFO with standard read characteristics
26+
* to have first-word fall-through read characteristics.
27+
*
28+
* Author(s):
29+
* Philipp Wagner <[email protected]>
30+
*/
31+
32+
module fifo_singleclock_fwft #(
33+
parameter WIDTH = 8,
34+
parameter DEPTH = 32,
35+
parameter PROG_FULL = (DEPTH / 2)
36+
)(
37+
input clk,
38+
input rst,
39+
40+
input [(WIDTH-1):0] din,
41+
input wr_en,
42+
output full,
43+
output prog_full,
44+
45+
output reg [(WIDTH-1):0] dout,
46+
input rd_en,
47+
output empty,
48+
49+
output [$clog2(DEPTH)-1:0] count
50+
);
51+
52+
reg fifo_valid, middle_valid, dout_valid;
53+
reg [(WIDTH-1):0] middle_dout;
54+
55+
wire [(WIDTH-1):0] fifo_dout;
56+
wire fifo_empty, fifo_rd_en;
57+
wire will_update_middle, will_update_dout;
58+
59+
// synchronous FIFO with standard (non-FWFT) read characteristics
60+
fifo_singleclock_standard
61+
#(.WIDTH(WIDTH),
62+
.DEPTH(DEPTH),
63+
.PROG_FULL(PROG_FULL))
64+
u_fifo (
65+
.rst(rst),
66+
.clk(clk),
67+
.rd_en(fifo_rd_en),
68+
.dout(fifo_dout),
69+
.empty(fifo_empty),
70+
.wr_en(wr_en),
71+
.din(din),
72+
.full(full),
73+
.prog_full(prog_full),
74+
.count(count)
75+
);
76+
77+
// create FWFT FIFO out of non-FWFT FIFO
78+
// public domain code from Eli Billauer
79+
// see http://www.billauer.co.il/reg_fifo.html
80+
assign will_update_middle = fifo_valid && (middle_valid == will_update_dout);
81+
assign will_update_dout = (middle_valid || fifo_valid) && (rd_en || !dout_valid);
82+
assign fifo_rd_en = (!fifo_empty) && !(middle_valid && dout_valid && fifo_valid);
83+
assign empty = !dout_valid;
84+
85+
always_ff @(posedge clk) begin
86+
if (rst) begin
87+
fifo_valid <= 0;
88+
middle_valid <= 0;
89+
dout_valid <= 0;
90+
dout <= 0;
91+
middle_dout <= 0;
92+
end else begin
93+
if (will_update_middle)
94+
middle_dout <= fifo_dout;
95+
96+
if (will_update_dout)
97+
dout <= middle_valid ? middle_dout : fifo_dout;
98+
99+
if (fifo_rd_en)
100+
fifo_valid <= 1;
101+
else if (will_update_middle || will_update_dout)
102+
fifo_valid <= 0;
103+
104+
if (will_update_middle)
105+
middle_valid <= 1;
106+
else if (will_update_dout)
107+
middle_valid <= 0;
108+
109+
if (will_update_dout)
110+
dout_valid <= 1;
111+
else if (rd_en)
112+
dout_valid <= 0;
113+
end
114+
end
115+
116+
endmodule
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/* Copyright (c) 2017 by the author(s)
2+
*
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
* THE SOFTWARE.
20+
*
21+
* =============================================================================
22+
*
23+
* Synchronous Standard FIFO (one clock)
24+
*
25+
* The memory block in this FIFO is following the "RAM HDL Coding Guidelines"
26+
* of Xilinx (UG901) to enable placing the FIFO memory into block ram during
27+
* synthesis.
28+
*
29+
* Author(s):
30+
* Philipp Wagner <[email protected]>
31+
*/
32+
33+
module fifo_singleclock_standard #(
34+
parameter WIDTH = 8,
35+
parameter DEPTH = 32,
36+
parameter PROG_FULL = DEPTH / 2
37+
)(
38+
input clk,
39+
input rst,
40+
41+
input [(WIDTH-1):0] din,
42+
input wr_en,
43+
output full,
44+
output prog_full,
45+
46+
output reg [(WIDTH-1):0] dout,
47+
input rd_en,
48+
output empty,
49+
50+
output [$clog2(DEPTH) - 1:0] count
51+
);
52+
localparam AW = $clog2(DEPTH);
53+
54+
// ensure that parameters are set to allowed values
55+
initial begin
56+
if ((1 << $clog2(DEPTH)) != DEPTH) begin
57+
$fatal("fifo_singleclock_standard: the DEPTH must be a power of two.");
58+
end
59+
end
60+
61+
reg [AW-1:0] wr_addr;
62+
reg [AW-1:0] rd_addr;
63+
wire fifo_read;
64+
wire fifo_write;
65+
reg [AW-1:0] rd_count;
66+
67+
// generate control signals
68+
assign empty = (rd_count[AW-1:0] == 0);
69+
assign prog_full = (rd_count[AW-1:0] >= PROG_FULL);
70+
assign full = (rd_count[AW-1:0] == (DEPTH-1));
71+
assign fifo_read = rd_en & ~empty;
72+
assign fifo_write = wr_en & ~full;
73+
assign count = rd_count;
74+
75+
// address logic
76+
always_ff @(posedge clk) begin
77+
if (rst) begin
78+
wr_addr[AW-1:0] <= 'd0;
79+
rd_addr[AW-1:0] <= 'b0;
80+
rd_count[AW-1:0] <= 'b0;
81+
end else begin
82+
if (fifo_write & fifo_read) begin
83+
wr_addr[AW-1:0] <= wr_addr[AW-1:0] + 'd1;
84+
rd_addr[AW-1:0] <= rd_addr[AW-1:0] + 'd1;
85+
end else if (fifo_write) begin
86+
wr_addr[AW-1:0] <= wr_addr[AW-1:0] + 'd1;
87+
rd_count[AW-1:0]<= rd_count[AW-1:0] + 'd1;
88+
end else if (fifo_read) begin
89+
rd_addr[AW-1:0] <= rd_addr[AW-1:0] + 'd1;
90+
rd_count[AW-1:0]<= rd_count[AW-1:0] - 'd1;
91+
end
92+
end
93+
end
94+
95+
// generic dual-port, single clock memory
96+
reg [WIDTH-1:0] ram [DEPTH-1:0];
97+
98+
// write
99+
always_ff @(posedge clk) begin
100+
if (fifo_write) begin
101+
ram[wr_addr] <= din;
102+
end
103+
end
104+
105+
// read
106+
always_ff @(posedge clk) begin
107+
if (fifo_read) begin
108+
dout <= ram[rd_addr];
109+
end
110+
end
111+
endmodule

0 commit comments

Comments
 (0)