| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: dmu_common_simple_fifo.v |
| 4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved |
| 5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. |
| 6 | // |
| 7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 8 | // |
| 9 | // This program is free software; you can redistribute it and/or modify |
| 10 | // it under the terms of the GNU General Public License as published by |
| 11 | // the Free Software Foundation; version 2 of the License. |
| 12 | // |
| 13 | // This program is distributed in the hope that it will be useful, |
| 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | // GNU General Public License for more details. |
| 17 | // |
| 18 | // You should have received a copy of the GNU General Public License |
| 19 | // along with this program; if not, write to the Free Software |
| 20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | // |
| 22 | // For the avoidance of doubt, and except that if any non-GPL license |
| 23 | // choice is available it will apply instead, Sun elects to use only |
| 24 | // the General Public License version 2 (GPLv2) at this time for any |
| 25 | // software where a choice of GPL license versions is made |
| 26 | // available with the language indicating that GPLv2 or any later version |
| 27 | // may be used, or where a choice of which version of the GPL is applied is |
| 28 | // otherwise unspecified. |
| 29 | // |
| 30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 31 | // CA 95054 USA or visit www.sun.com if you need additional information or |
| 32 | // have any questions. |
| 33 | // |
| 34 | // ========== Copyright Header End ============================================ |
| 35 | module dmu_common_simple_fifo ( |
| 36 | clk, |
| 37 | rst_l, |
| 38 | |
| 39 | data_in, |
| 40 | write, |
| 41 | |
| 42 | data_out, |
| 43 | read, |
| 44 | |
| 45 | fifo_full, |
| 46 | fifo_almost_full, |
| 47 | fifo_empty |
| 48 | |
| 49 | ); |
| 50 | |
| 51 | |
| 52 | //############################################################################ |
| 53 | // PARAMETERS |
| 54 | //############################################################################ |
| 55 | parameter FIFO_WIDTH = 131; |
| 56 | parameter FIFO_DEPTH = 4'd8; |
| 57 | parameter FIFO_PTR_WDTH = 3; |
| 58 | parameter FIFO_DEPTH_MINUS_ONE = 3'd7; |
| 59 | |
| 60 | |
| 61 | //############################################################################ |
| 62 | // PORT DECLARATIONS |
| 63 | //############################################################################ |
| 64 | |
| 65 | input clk; // The input clock |
| 66 | input rst_l; // The fifo rst_l |
| 67 | |
| 68 | input [FIFO_WIDTH - 1:0] data_in; // The input data |
| 69 | input write; // The syncronous write strobe |
| 70 | |
| 71 | output [FIFO_WIDTH - 1:0] data_out; // The output data |
| 72 | input read; // The syncronous read strobe |
| 73 | |
| 74 | output fifo_full; // The fifo full flag |
| 75 | output fifo_almost_full; // The fifo almost full flag (full -1) |
| 76 | output fifo_empty; // The fifo empty flag |
| 77 | |
| 78 | |
| 79 | //############################################################################ |
| 80 | // SIGNAL DECLARATIONS |
| 81 | //############################################################################ |
| 82 | |
| 83 | //************************************************** |
| 84 | // Registers that Are Flops |
| 85 | //************************************************** |
| 86 | reg [FIFO_WIDTH - 1:0] fifo_ram[0:FIFO_DEPTH -1]; // The fifo storge arrary |
| 87 | reg [FIFO_PTR_WDTH - 1:0] wr_ptr, rd_ptr; // Read and write pointers |
| 88 | reg [FIFO_PTR_WDTH:0] fifo_count; // Number of entries in fifo |
| 89 | reg over_flow_err, under_flow_err; // Under flow and over flow errors |
| 90 | |
| 91 | |
| 92 | //************************************************** |
| 93 | // Registers that Are NOT Flops |
| 94 | //************************************************** |
| 95 | reg [FIFO_PTR_WDTH:0] n_fifo_count; // Next Number of entries in fifo |
| 96 | reg n_over_flow_err, n_under_flow_err; // Next Under flow and over flow errors |
| 97 | |
| 98 | //************************************************** |
| 99 | // Wires |
| 100 | //************************************************** |
| 101 | wire [FIFO_PTR_WDTH - 1:0] n_wr_ptr, n_rd_ptr; // Next Read and write pointers |
| 102 | wire fifo_full, fifo_empty; // Full and empty signals |
| 103 | |
| 104 | wire [FIFO_WIDTH - 1:0] data_out; |
| 105 | |
| 106 | //############################################################################ |
| 107 | // ZERO IN CHECKERS |
| 108 | //############################################################################ |
| 109 | |
| 110 | // A fifo checker for this fifo |
| 111 | |
| 112 | //0in fifo -enq write -deq read -depth FIFO_DEPTH -enq_data data_in -deq_data data_out |
| 113 | |
| 114 | // *********************************************** |
| 115 | // If this is a write access, put the data on the |
| 116 | // input bus into the location pointed to by the |
| 117 | // fifo write pointer |
| 118 | //************************************************ |
| 119 | always @ (posedge clk) |
| 120 | if(~rst_l) begin : fifo_rst |
| 121 | integer j; |
| 122 | for (j = 0; j < FIFO_DEPTH; j = j + 1) begin |
| 123 | fifo_ram[j] <= {FIFO_WIDTH{1'b0}}; |
| 124 | end |
| 125 | end |
| 126 | else begin |
| 127 | if (write) begin |
| 128 | fifo_ram[wr_ptr] <= data_in; |
| 129 | end |
| 130 | end |
| 131 | |
| 132 | //*********************************************** |
| 133 | // If this is a read get the data that is in |
| 134 | // the location pointed to by the read pointer |
| 135 | // and put it onto the output bus |
| 136 | //************************************************ |
| 137 | |
| 138 | assign data_out = fifo_ram[rd_ptr]; |
| 139 | |
| 140 | |
| 141 | //************************************************ |
| 142 | // Increment the write pointer on every write and |
| 143 | // the read pointer on every read |
| 144 | //************************************************/ |
| 145 | always @ (posedge clk) |
| 146 | if (!rst_l) |
| 147 | begin |
| 148 | wr_ptr <= 0; |
| 149 | rd_ptr <= 0; |
| 150 | end |
| 151 | else |
| 152 | begin |
| 153 | wr_ptr <= n_wr_ptr; |
| 154 | rd_ptr <= n_rd_ptr; |
| 155 | end |
| 156 | |
| 157 | assign n_wr_ptr = write ? ((wr_ptr == FIFO_DEPTH_MINUS_ONE) ? 0 : (wr_ptr + 1)) : wr_ptr; |
| 158 | assign n_rd_ptr = read ? ((rd_ptr == FIFO_DEPTH_MINUS_ONE) ? 0 : (rd_ptr + 1)) : rd_ptr; |
| 159 | |
| 160 | |
| 161 | |
| 162 | //********************************************* |
| 163 | // The fifo counter increment on every write and |
| 164 | // decrement on every read |
| 165 | //**********************************************/ |
| 166 | |
| 167 | always @ (posedge clk) |
| 168 | if (!rst_l) |
| 169 | begin |
| 170 | fifo_count <= 0; |
| 171 | over_flow_err <= 1'b0; |
| 172 | under_flow_err <= 1'b0; |
| 173 | end |
| 174 | else |
| 175 | begin |
| 176 | fifo_count <= n_fifo_count; |
| 177 | over_flow_err <= n_over_flow_err; |
| 178 | under_flow_err <= n_under_flow_err; |
| 179 | end |
| 180 | |
| 181 | |
| 182 | assign fifo_empty = (fifo_count == 0); |
| 183 | |
| 184 | assign fifo_full = (fifo_count == FIFO_DEPTH); |
| 185 | |
| 186 | assign fifo_almost_full = (fifo_count == FIFO_DEPTH - 1) | |
| 187 | (fifo_count == FIFO_DEPTH); |
| 188 | |
| 189 | |
| 190 | always @ (write or read or over_flow_err or under_flow_err or fifo_count) |
| 191 | begin |
| 192 | case ({write, read}) |
| 193 | 2'b00: |
| 194 | begin |
| 195 | n_fifo_count = fifo_count; // No transaction |
| 196 | n_over_flow_err = over_flow_err; |
| 197 | n_under_flow_err = under_flow_err; |
| 198 | end |
| 199 | |
| 200 | 2'b01: |
| 201 | begin |
| 202 | n_fifo_count = (fifo_count == 0) ? 0 : fifo_count - 1; |
| 203 | n_over_flow_err = 1'b0; |
| 204 | n_under_flow_err = (fifo_count == 0) ? 1'b1 : 1'b0; // Under flow case should not happen |
| 205 | end |
| 206 | |
| 207 | 2'b10: |
| 208 | begin |
| 209 | n_fifo_count = (fifo_count == FIFO_DEPTH) ? FIFO_DEPTH : fifo_count + 1; |
| 210 | n_over_flow_err = (fifo_count == FIFO_DEPTH) ? 1'b1 : 1'b0; // Over flow case shuld not happen |
| 211 | n_under_flow_err = 1'b0; |
| 212 | end |
| 213 | |
| 214 | 2'b11: |
| 215 | begin |
| 216 | n_fifo_count = fifo_count; // both transaction |
| 217 | n_over_flow_err = 1'b0; // Over flow case shuld not happen |
| 218 | n_under_flow_err = 1'b0; |
| 219 | end |
| 220 | |
| 221 | endcase |
| 222 | end |
| 223 | |
| 224 | endmodule |