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