-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsyn_fifo.v
More file actions
113 lines (103 loc) · 2.53 KB
/
syn_fifo.v
File metadata and controls
113 lines (103 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// ---------------------------------------
// Design Name : syn_fifo
// File Name : syn_fifo.v
// Function : Synchronous (single clock) FIFO
// Coder : Mayank Parasar
// ---------------------------------------
module syn_fifo (
clk , // Clock input
rst , // Active high reset
wr_cs , // Write Chip select
rd_cs , // Read chip select
data_in , // data input
rd_en , // Read enable
wr_en , // Write enable
data_out , // Data output
empty , // FIFO empty
full // FIFO full
);
// FIFO constants...
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
parameter RAM_DEPTH = (1 << ADDR_WIDTH); // what is this for..?
// Port Declarations
input clk;
input rst;
input wr_cs;
input rd_cs;
input rd_en;
input wr_en;
input [DATA_WIDTH-1:0] data_in;
output full;
output empty;
output [DATA_WIDTH-1:0] data_out;
//-----------Internal variables-------------
reg [ADDR_WIDTH-1 : 0] wr_pointer;
reg [ADDR_WIDTH-1 : 0] rd_pointer;
reg [ADDR_WIDTH : 0] status_cnt;
reg [DATA_WIDTH-1 : 0] data_out;
wire [DATA_WIDTH-1 : 0] data_ram;
// ---------Variable assignments------------
assign full = (status_cnt == (RAM_DEPTH-1));
assign empty = (status_cnt == 0);
// ---------Code start----------------------
always @(posedge clk or posedge rst)
begin : WRITE_POINTER
if (rst) begin
// reset
wr_pointer <= 0;
end
else if (wr_cs && wr_en) begin
wr_pointer <= wr_pointer + 1;
end
end
always @(posedge clk or posedge rst)
begin : READ_POINTER
if (rst) begin
// reset
rd_pointer <= 0;
end
else if (rd_cs && rd_en) begin
rd_pointer <= rd_pointer + 1;
end
end
always @(posedge clk or posedge rst)
begin : READ_DATA
if (rst) begin
// reset
data_out = 0;
end
else if (rd_cs && rd_en) begin
data_out <= data_ram;
end
end
always @(posedge clk or posedge rst)
begin : STATUS_COUNTER
if (rst) begin
// reset
status_cnt <= 0;
end
// Read but no write.
else if ((rd_cs && rd_en) && !(wr_cs && wr_en)
&& (status_cnt != 0)) begin
status_cnt <= status_cnt - 1;
end
// Write but no read
else if ((wr_cs && wr_en) && !(rd_cs && rd_en)
&& (status_cnt != RAM_DEPTH)) begin
status_cnt <= status_cnt + 1;
end
end
ram_dp_ar_aw #(DATA_WIDTH, ADDR_WIDTH)DP_RAM (
.address_0 (wr_pointer), // address_0 input
.data_0 (data_in), // data_0 bi-directional
.cs_0 (wr_cs), // chip select
.we_0 (wr_en), // write enable
.oe_0 (1'b0), // output enable
.address_1 (rd_pointer), // address_q input
.data_1 (data_ram), // data_1 bi-directional
.cs_1 (rd_cs), // chip select
.we_1 (1'b0), // Read enable
.oe_1 (rd_en) // output enable
);
endmodule