1 module syn_fifo
2 (
3 //input ports
4 sys_clk ,
5 sys_rst_n ,
6
7 wr_en ,
8 wr_data ,
9
10 rd_en ,
11 //output ports
12 rd_data ,
13 rd_dv ,
14
15 empty ,
16 full
17 );
18
19 // declare input ports
20 input sys_clk ; //system clock;
21 input sys_rst_n ; //system reset, low is active;
22
23 input wr_en ;
24 input [DWIDTH-1:0] wr_data ;
25
26 input rd_en ;
27
28
29 // declare output ports
30 output [DWIDTH-1:0] rd_data ;
31
32 output rd_dv ;
33
34 output empty ;
35
36 output full ;
37
38 //register define
39 reg [DWIDTH-1:0] rd_data ;
40 reg rd_dv ;
41 reg empty ;
42
43 reg [DWIDTH-1:0] fifo_0 ;
44 reg [DWIDTH-1:0] fifo_1 ;
45 reg [DWIDTH-1:0] fifo_2 ;
46 reg [DWIDTH-1:0] fifo_3 ;
47 reg [SIZE -1:0] current_fifo ;
48
49 reg [SIZE -1:0] wr_addr ;
50 reg [SIZE -1:0] rd_addr ;
51
52 //wire define
53 wire [SIZE -1:0] next_fifo ;
54 wire wr_fifo_0 ;
55 wire wr_fifo_1 ;
56 wire wr_fifo_2 ;
57 wire wr_fifo_3 ;
58
59 //parameter define
60 parameter DWIDTH = 8 ;
61 parameter SIZE = 3 ;
62
63 /**********************************************************************************
64 ** Main Program
65 **
66 **********************************************************************************/
67
68 assign wr_fifo_0 = wr_en && (wr_addr == 0) ;
69 assign wr_fifo_1 = wr_en && (wr_addr == 1) ;
70 assign wr_fifo_2 = wr_en && (wr_addr == 2) ;
71 assign wr_fifo_3 = wr_en && (wr_addr == 3) ;
72
73 assign next_fifo = current_fifo + 1'b1 ; //the space is increased
74
75 always@(posedge sys_clk or negedge sys_rst_n) begin
76 if (!sys_rst_n) begin
77 current_fifo <= 'b0;
78 end
79 else if (rd_en && wr_en) begin //read and write fifo the same time,the space of fifo is not change;
80 current_fifo <= current_fifo;
81 end
82 else if (rd_en && (current_fifo != 'b0)) //read fifo ,the space of fifo is decrease;
83 current_fifo <= current_fifo - 1'b1;
84 else if (wr_en && (current_fifo[SIZE-1] != 1))begin //wirte fifo ,the space of fifo is increase;
85 current_fifo <= next_fifo;
86 end
87 end
88
89 //generate the write address
90 always@(posedge sys_clk or negedge sys_rst_n) begin
91 if (!sys_rst_n) begin
92 wr_addr <= 'b0;
93 end
94 else if ((wr_en == 1'b1) && (full != 1'b1) ) begin
95 wr_addr <= wr_addr + 1'b1;
96 end
97 end
98
99 //wirte and read fifo
100 always@(posedge sys_clk or negedge sys_rst_n) begin
101 if (!sys_rst_n) begin
102 fifo_0 <= 'b0;
103 end
104 else if (wr_fifo_0) begin
105 fifo_0 <= wr_data;
106 end
107 end
108
109 //wirte and read fifo
110 always@(posedge sys_clk or negedge sys_rst_n) begin
111 if (!sys_rst_n) begin
112 fifo_1 <= 'b0;
113 end
114 else if (wr_fifo_1 ) begin
115 fifo_1 <= wr_data;
116 end
117 end
118
119 //wirte and read fifo
120 always@(posedge sys_clk or negedge sys_rst_n) begin
121 if (!sys_rst_n) begin
122 fifo_2 <= 'b0;
123 end
124 else if (wr_fifo_2) begin
125 fifo_2 <= wr_data;
126 end
127 end
128
129 //wirte and read fifo
130 always@(posedge sys_clk or negedge sys_rst_n) begin
131 if (!sys_rst_n) begin
132 fifo_3 <= 'b0;
133 end
134 else if (wr_fifo_3 ) begin
135 fifo_3 <= wr_data;
136 end
137 end
138
139 //generate the read address
140 always@(posedge sys_clk or negedge sys_rst_n) begin
141 if (!sys_rst_n) begin
142 rd_addr <= 'b0;
143 end
144 else if ((rd_en == 1'b1) && (empty != 1'b1) ) begin
145 rd_addr <= rd_addr + 1'b1;
146 end
147 end
148
149 //read fifo
150 always@(posedge sys_clk or negedge sys_rst_n) begin
151 if (!sys_rst_n) begin
152 rd_data <= 'b0;
153 end
154 else if (rd_en ==1'b1) begin
155 case (rd_addr)
156 0 : rd_data <= fifo_0 ;
157 1 : rd_data <= fifo_1 ;
158 2 : rd_data <= fifo_2 ;
159 3 : rd_data <= fifo_3 ;
160 default: rd_data <= rd_data ;
161 endcase
162 end
163 end
164
165
166 //generate read data and read valid signal
167 always@(posedge sys_clk or negedge sys_rst_n) begin
168 if (!sys_rst_n) begin
169 rd_dv <= 'b0;
170 end
171 else if (rd_en && (current_fifo != 0))begin
172 rd_dv <= 'b1;
173 end
174 else begin
175 rd_dv <= 'b0;
176 end
177 end
178
179 //generate fifo empty signal
180 always@(posedge sys_clk or negedge sys_rst_n) begin
181 if (!sys_rst_n) begin
182 empty <= 1'b0;
183 end
184 else if (rd_en && (current_fifo == 0)) begin //when the space of the fifo is 0,and read the fifo is comning,then the fifo is empty;
185 empty <= 1'b1;
186 end
187 else if (wr_en) begin
188 empty <= 1'b0;
189 end
190 end
191
192 assign full = current_fifo[SIZE-1] ; //when the space of the fifo is 4, then the fifo is full;
193
194 endmodule