Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / pcie_common / rtl / fire_dmc_common_srfifo.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: fire_dmc_common_srfifo.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 ============================================
35module fire_dmc_common_srfifo (
36 clk,
37 rst_l,
38 enq,
39 data_in,
40 deq,
41 data_out,
42 full,
43 empty,
44 overflow,
45 underflow
46 );
47
48//************************************************
49// PARAMETERS
50//************************************************
51 parameter WIDTH = 8;
52 parameter DEPTH = 8;
53
54 integer i;
55
56//************************************************
57// PORTS
58//************************************************
59
60 input clk; // The input clock
61 input rst_l; // synopsys sync_set_reset "rst_l"
62
63 input enq; // enqueue into fifo
64 input [WIDTH - 1:0] data_in; // data to put in
65
66 input deq; // dequeue outof fifo
67 output [WIDTH - 1:0] data_out; // data taken out
68
69 output full; // full flag
70 output empty; // empty flag
71 output overflow; // overflow indicater
72 output underflow; // underflow indicater
73
74//************************************************
75// SIGNALS
76//************************************************
77
78 reg [WIDTH - 1:0] sr [0 :DEPTH -1]; // fifo flops
79 reg [DEPTH + 2:0] ld; // current load location
80 reg [DEPTH + 2:0] next_ld; // next load location
81 reg [DEPTH - 1:0] vld; // current location has valid data
82 reg [DEPTH - 1:0] next_vld; // next location to have valid data
83
84 reg empty; // fifo is empty
85 reg overflow; // enqueue when fifo was full
86 reg underflow; // dequeue when fifo was empty
87
88
89// uncoment these line for srfifo debug
90// wire [WIDTH -1:0] sr_out_7, sr_out_6, sr_out_5, sr_out_4,
91// sr_out_3, sr_out_2, sr_out_1, sr_out_0;
92
93 wire [DEPTH +2 :0] ld_init; // to make vlint happy
94 wire [DEPTH -1 :0] vld_init; // to make vlint happy
95
96
97// ----------------------------------------------------------------------------
98// Zero In Checkers
99// ----------------------------------------------------------------------------
100
101 //0in fifo -enq enq -deq deq -depth DEPTH -enq_data data_in -deq_data data_out
102
103
104//************************************************
105// mux function just to make the code easier for
106// synthesis (like we really want a 2:1 mux)
107//************************************************
108
109function [WIDTH -1:0] reg_mux;
110 input sel;
111 input [WIDTH -1:0] nxdata;
112 input [WIDTH -1:0] nxsrdata;
113
114 begin
115 reg_mux = sel ? nxdata : nxsrdata;
116 end
117endfunction
118
119
120//************************************************
121// the sr fifo location always gets the value on
122// next_ld. mux logic to make the code parameterized
123// and easier for synthesis
124//************************************************
125
126always @ (posedge clk)
127 if(~rst_l) begin : fifo_rst
128 integer j;
129 for (j = 0; j < DEPTH; j = j + 1) begin
130 sr[j] <= {WIDTH{1'b0}};
131 end
132 end
133else begin
134 for (i = 0; i < DEPTH -1 ; i = i+1)
135 case ({enq, deq}) // synopsys full_case parallel_case
136 2'b00: sr[i] <= sr[i];
137 2'b01: sr[i] <= sr[i+1];
138 2'b10: sr[i] <= reg_mux(next_ld[i+1], data_in, sr[i]);
139 2'b11: sr[i] <= reg_mux(next_ld[i+1], data_in, sr[i+1]);
140 endcase
141 for (i = DEPTH -1; i < DEPTH ; i = i+1)
142 case ({enq, deq}) // synopsys full_case parallel_case
143 2'b00: sr[i] <= sr[i];
144 2'b01: sr[i] <= data_in;
145 2'b10: sr[i] <= reg_mux(next_ld[i+1], data_in, sr[i]);
146 2'b11: sr[i] <= reg_mux(next_ld[i+1], data_in, sr[i]);
147 endcase
148end
149
150
151//*********************************************
152// sr_fifo load control updates when enq or deq
153// valid
154//*********************************************
155
156always @ (rst_l or ld or enq or deq or ld_init)
157begin
158 if (!rst_l) begin
159 next_ld = {ld_init[DEPTH +2 : 1], 1'b1}; // to make vlint happy
160 end
161 else begin
162 case ({enq, deq}) // synopsys full_case parallel_case
163 2'b00: next_ld = ld;
164 2'b01: next_ld = ld >> 1;
165 2'b10: next_ld = ld << 1;
166 2'b11: next_ld = ld;
167 endcase // case({enq, deq})
168 end // else: !if(!rst_l)
169end // always @ (posedge clk)
170
171//*********************************************
172// sr_fifo valid contents marker updates when enq
173// or deq valid
174//*********************************************
175
176always @ (rst_l or vld or enq or deq or vld_init)
177begin
178 if (!rst_l) begin
179 next_vld = 0;
180 end
181 else begin
182 case ({enq, deq}) // synopsys full_case parallel_case
183 2'b00: next_vld = vld;
184 2'b01: next_vld = vld >> 1;
185 2'b10: next_vld = {vld_init[DEPTH -1 :1] , 1'b1}; // to make vlint happy
186 2'b11: next_vld = vld;
187 endcase // case({enq, deq})
188 end // else: !if(!rst_l)
189end // always @ (vld or enq or deq or vld_init)
190
191//************************************************
192// srfifo registered internal ld, vld
193//************************************************
194
195always @ (posedge clk)
196begin
197 if (!rst_l) begin
198 ld <= {(ld_init[DEPTH +2 : 1] & 0), 1'b1}; // to make vlint happy
199 vld <= 0;
200 end
201 else begin
202 ld <= next_ld;
203 vld <= next_vld;
204 end // else: !if(!rst_l)
205end // always @ (posedge clk)
206
207
208//************************************************
209// Outputs
210//************************************************
211
212always @ (posedge clk)
213begin
214 if (!rst_l) begin
215 empty <= 1'b1;
216 underflow <= 1'b0;
217 overflow <= 1'b0;
218 end
219 else begin
220 empty <= enq ? 1'b0 : ((deq == 1'b1)
221 && (vld[1] == 1'b0)
222 && (ld_init[0] == 1'b1)) ? 1'b1 : empty;
223 underflow <= (((vld[0] == 1'b0)
224 && (vld_init[0] == 1'b0)
225 && (deq == 1'b1)) ? 1'b1 : underflow);
226 overflow <= (((vld[DEPTH -1] == 1'b1) & enq) ? 1'b1 : overflow);
227 end
228end
229
230//********************** Assignments *************
231
232 assign ld_init[DEPTH +2 :0] = {ld[DEPTH +2 : 1], 1'b1}; // make vlint happy
233 assign vld_init[DEPTH -1 :0] = vld[DEPTH -1 :0] << 1; // make vlint happy
234
235 assign full = vld[DEPTH -2];
236 assign data_out = sr[0];
237
238
239// uncoment these line for srfifo debug
240// assign sr_out_0 = sr[DEPTH - 8];
241// assign sr_out_1 = sr[DEPTH - 7];
242// assign sr_out_2 = sr[DEPTH - 6];
243// assign sr_out_3 = sr[DEPTH - 5];
244// assign sr_out_4 = sr[DEPTH - 4];
245// assign sr_out_5 = sr[DEPTH - 3];
246// assign sr_out_6 = sr[DEPTH - 2];
247// assign sr_out_7 = sr[DEPTH - 1];
248
249endmodule
250
251