Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / niu_smx_ff_ctrl.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_smx_ff_ctrl.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
36module niu_smx_ff_ctrl(/*AUTOARG*/
37 // Outputs
38 full, empty, mwr, mwaddr, mrd, mraddr,
39 // Inputs
40 clk, reset_l, wr, rd
41 );
42 //
43 // auto read ahead at mem (ram/regfl);
44 // data available at rdata bus when
45 // empty flag is 0;
46 // tailor for mem file with rd control
47 // and data available one cycle after rd;
48 //
49 // empty flag adjust to match data out
50 //
51 // whenever not empty, reader sees valid data
52 // at rdata bus;
53 //
54 // note for ram, rdata reflects output
55 // at ram (no registered out)
56 //
57 // for regfl, rdata is registered
58 //
59parameter ADDR_WIDTH= 4;
60
61// fifo if
62input clk;
63input reset_l;
64
65input wr;
66input rd;
67
68output full;
69output empty;
70
71
72// mem if (ram/regfl)
73output mwr;
74output [ADDR_WIDTH-1:0] mwaddr;
75output mrd;
76output [ADDR_WIDTH-1:0] mraddr;
77
78
79/*
80output [DATA_WIDTH-1:0]rdata;
81wire [DATA_WIDTH-1:0]rdata_n; // reflects at ram/regfl out immediate
82
83wire [DATA_WIDTH-1:0]rdata= rdata_n; // reflects fifo out
84*/
85
86
87reg pre_empty, pre_empty_n; // reflects at ram/regfl out immediate
88reg pre_empty1;
89wire empty= (pre_empty)? pre_empty : pre_empty1;
90 // if empty, reflects immediate;
91 // if transition to not empty (ie. empty= 0),
92 // delay 1 cycle with pre_empty1;
93 // in a corner case when both pre_empty, pre_empty1=0,
94 // and rd, wr at same time (rd going into a just written entry),
95 // force delay 1 cycle by making pre_empty1= 1
96reg [ADDR_WIDTH-1:0] wptr;
97reg [ADDR_WIDTH-1:0] rptr; // reflects ptr to ram/regfl
98wire [ADDR_WIDTH-1:0] wptr_n= wptr + 1'b1;
99wire [ADDR_WIDTH-1:0] rptr_n= rptr + 1'b1;
100
101always @ (posedge clk) begin
102 if(!reset_l)
103 pre_empty1<= `SMX_PD 1'b1;
104 else
105 if(({rd,wr} == 2'b11) && (rptr_n==wptr))
106 // rptr going to just written entry;
107 // data not available until nxt cycle at wr
108 // make empty first
109 pre_empty1<= `SMX_PD 1'b1;
110 else
111 pre_empty1<= `SMX_PD pre_empty; // add one cycle to empty to match
112 // data availablility at wr (from empty to not-empty)
113end
114
115
116reg full, full_n;
117
118 always @ (posedge clk) begin
119 if(!reset_l) begin
120 wptr<= `SMX_PD {ADDR_WIDTH{1'b0}};
121 rptr<= `SMX_PD {ADDR_WIDTH{1'b0}};
122 full<= `SMX_PD 1'b0;
123 pre_empty<= `SMX_PD 1'b1;
124 end
125 else begin
126 full<= `SMX_PD full_n;
127 pre_empty<= `SMX_PD pre_empty_n;
128 if(wr) wptr<= `SMX_PD wptr_n;
129
130 if(rd) rptr<= `SMX_PD rptr_n;
131 end // not reset
132 end // always
133
134wire [ADDR_WIDTH-1:0] wptr_cmp_n= wptr + 1'b1; // use wptr_cmp_n in case needs
135 // to make full ahead;
136 // driver must NOT register wr if
137 // inc by 1'b1 !!!!
138 // if driver register wr;
139 // make full ahead (inc by 2;
140 // one more word on line
141 // before it sees the full
142 // status)
143
144
145 always @ (/*AUTOSENSE*/full or pre_empty or rd or rptr or rptr_n
146 or wptr or wptr_cmp_n or wr) begin
147 full_n= full;
148 pre_empty_n= pre_empty;
149 case({rd,wr})
150 2'b00: begin
151 full_n= full;
152 pre_empty_n= pre_empty;
153 end
154 2'b01: begin
155 if(full) // auto ignore wr if already full
156 full_n= full;
157 else
158 full_n= (wptr_cmp_n==rptr)? 1'b1 : 1'b0;
159 pre_empty_n= 1'b0;
160 end
161 2'b10: begin
162 if(full) // make sure read enough before taking away full
163 full_n= (wptr_cmp_n==rptr_n)? 1'b0 : 1'b1;
164 else
165 full_n= 1'b0;
166 if(pre_empty) // auto ignore rd if already empty
167 pre_empty_n= pre_empty;
168 else
169 pre_empty_n= (rptr_n==wptr)? 1'b1 : 1'b0;
170 end
171 2'b11: begin
172 full_n= full;
173 pre_empty_n= pre_empty;
174 end
175 endcase
176 end // always
177
178
179wire [ADDR_WIDTH-1:0] mem_rptr_n= (rd)? rptr_n : rptr;
180 // read ahead next entry when reading current
181// mem if
182wire [ADDR_WIDTH-1:0] mraddr= mem_rptr_n;
183wire [ADDR_WIDTH-1:0] mwaddr= wptr;
184wire mrd= !(mem_rptr_n==wptr); // read whenever fifo not empty
185wire mwr= wr;
186
187endmodule
188