source: XOpenSparcT1/trunk/T1-common/srams/bw_rf_16x81.v @ 6

Revision 6, 12.3 KB checked in by pntsvt00, 14 years ago (diff)

versione iniziale opensparc

Line 
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T1 Processor File: bw_rf_16x81.v
4// Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21module bw_rf_16x81(
22   rd_clk,    // read clock
23   wr_clk,    // read clock
24   csn_rd,    // read enable -- active low
25   csn_wr,    // write enable -- active low
26   hold,      // hold signal -- unflopped -- hold =1 holds input data
27   testmux_sel, // bypass  signal -- unflopped -- testmux_sel = 1 bypasses di to do
28   scan_en,   // Scan enable unflopped 
29   margin,    // Delay for the circuits--- set to 01010101
30   rd_a,      // read address 
31   wr_a,      // Write address
32   di,        // Data input
33   si,        // scan in 
34   so,        // scan out 
35   listen_out, // Listening flop--
36   do          // Data out
37
38);
39
40   input rd_clk;
41   input wr_clk;
42   input csn_rd;
43   input csn_wr;
44   input hold;
45   input testmux_sel;
46   input scan_en;
47   input [4:0] margin;
48   input [3:0] rd_a;
49   input [3:0] wr_a;
50   input [80:0] di;
51   input si;
52   output so;
53   output [80:0] do;
54   output [80:0] listen_out;
55
56parameter  SYNC_CLOCK_CHK1 = 1;
57parameter  SYNC_CLOCK_CHK2 = 1;
58parameter  SYNC_CLOCK_CHK3 = 1;
59parameter  MARGIN_WARNING = 1; // margin warning is on by default
60
61
62
63
64// Start code
65reg [80:0] memarray[15:0] ;
66reg [80:0] array_out  ;
67
68reg [80:0] array_out_latch    ;
69
70
71
72reg  [3:0] rd_a_ff   ;
73wire [3:0] rd_a_ff_so;
74wire [3:0] rd_a_ff_si ;
75
76reg  [3:0] wr_a_ff   ;
77wire [3:0] wr_a_ff_so;
78wire [3:0] wr_a_ff_si ;
79
80reg  [80:0] di_ff   ;
81wire [80:0] di_ff_so;
82wire [80:0] di_ff_si;
83
84wire [80:0] listen_out_so;
85wire [80:0] listen_out_si ;
86reg  [80:0] listen_out     ;
87
88
89reg        csn_rd_ff ;
90wire       csn_rd_ff_si ;
91wire       csn_rd_ff_so ;
92
93reg        csn_wr_ff ;
94wire       csn_wr_ff_si ;
95wire       csn_wr_ff_so ;
96
97reg        di_ff_latch_so ;
98///////////////////////////////////////
99// Scan chain connections            //
100///////////////////////////////////////
101assign wr_a_ff_si[3:0] = {si      , wr_a_ff_so[3:1]} ;
102assign csn_wr_ff_si    = wr_a_ff_so[0] ;
103assign di_ff_si        = {csn_wr_ff_so, di_ff_so[80:1]};
104assign listen_out_si   = {listen_out_so[79:0], di_ff_latch_so} ;
105assign csn_rd_ff_si    = listen_out_so[80] ;
106assign rd_a_ff_si[3:0] = {rd_a_ff_so[2:0], csn_rd_ff_so} ;
107assign so              = rd_a_ff_so[3] ;
108///////////////////////////////////////
109// Instantiate a clock headers        //
110///////////////////////////////////////
111
112wire   rd_ssclk       = rd_clk ; // clk_en & rd_clk ;
113wire   rd_local_clk   = rd_ssclk | scan_en | hold ; 
114wire   rd_smclk       = rd_ssclk |  ~(scan_en | hold) ;
115
116wire   wr_ssclk       = wr_clk ; // clk_en & wr_clk ;
117wire   wr_local_clk   = wr_ssclk | scan_en | hold ; 
118wire   wr_smclk       = wr_ssclk |  ~(scan_en | hold) ;
119
120
121/////////////////////////////////////////////////////
122// csn_rd Flop                                     //
123/////////////////////////////////////////////////////
124
125reg                     csn_rd_ff_inst_mdata ;
126wire                    csn_rd_ff_inst_smin ;
127reg                     csn_rd_ff_scan_out ;
128
129assign csn_rd_ff_inst_smin  = hold ?  csn_rd_ff_scan_out :  csn_rd_ff_si ; 
130always @(rd_smclk or rd_local_clk or csn_rd or csn_rd_ff_inst_smin ) begin
131       if (!rd_local_clk) begin
132          csn_rd_ff_inst_mdata = csn_rd ;
133       end
134       if (!rd_smclk) begin
135          csn_rd_ff_inst_mdata = csn_rd_ff_inst_smin;
136       end
137end
138always @(posedge rd_ssclk) begin
139    csn_rd_ff_scan_out    <=  csn_rd_ff_inst_mdata ; 
140end
141always @(rd_local_clk or csn_rd_ff_inst_mdata) begin
142   if (rd_local_clk ) begin
143    csn_rd_ff    <=  csn_rd_ff_inst_mdata ; 
144   end
145end
146assign csn_rd_ff_so =  csn_rd_ff_scan_out;
147       
148/////////////////////////////////////////////////////
149
150/////////////////////////////////////////////////////
151// rd_a Flop                                       //
152/////////////////////////////////////////////////////
153reg     [3:0]   rd_a_ff_inst_mdata ;
154wire    [3:0]   rd_a_ff_inst_smin ;
155reg     [3:0]   rd_a_ff_scan_out ;
156
157assign rd_a_ff_inst_smin[3:0]  = hold ?  rd_a_ff_scan_out[3:0] :  rd_a_ff_si[3:0] ; 
158always @(rd_smclk or rd_local_clk or rd_a or rd_a_ff_inst_smin ) begin
159       if (!rd_local_clk) begin
160          rd_a_ff_inst_mdata = rd_a[3:0] ;
161       end
162       if (!rd_smclk) begin
163          rd_a_ff_inst_mdata = rd_a_ff_inst_smin;
164       end
165end
166always @(posedge rd_ssclk) begin
167    rd_a_ff_scan_out[3:0]   <=  rd_a_ff_inst_mdata ; 
168end
169always @(rd_local_clk or rd_a_ff_inst_mdata) begin
170   if (rd_local_clk) begin
171    rd_a_ff[3:0]   <=  rd_a_ff_inst_mdata ; 
172   end
173end
174assign rd_a_ff_so[3:0] = rd_a_ff_scan_out[3:0] ;
175/////////////////////////////////////////////////////
176       
177/////////////////////////////////////////////////////
178// csn_wr Flop                                     //
179/////////////////////////////////////////////////////
180reg                     csn_wr_ff_inst_mdata ;
181wire                    csn_wr_ff_inst_smin ;
182
183assign csn_wr_ff_inst_smin  = hold ?  csn_wr_ff :  csn_wr_ff_si ; 
184always @(wr_smclk or wr_local_clk or csn_wr or csn_wr_ff_inst_smin ) begin
185       if (!wr_local_clk) begin
186          csn_wr_ff_inst_mdata = csn_wr ;
187       end
188       if (!wr_smclk) begin
189          csn_wr_ff_inst_mdata = csn_wr_ff_inst_smin;
190       end
191end
192always @(posedge wr_ssclk) begin
193    csn_wr_ff    <=  csn_wr_ff_inst_mdata ; 
194end
195assign csn_wr_ff_so =  csn_wr_ff;
196/////////////////////////////////////////////////////
197       
198/////////////////////////////////////////////////////
199// wr_a Flop                                       //
200/////////////////////////////////////////////////////
201reg     [3:0]   wr_a_ff_inst_mdata ;
202wire    [3:0]   wr_a_ff_inst_smin ;
203
204assign wr_a_ff_inst_smin[3:0]  = hold ?  wr_a_ff[3:0] :  wr_a_ff_si[3:0] ; 
205always @(wr_smclk or wr_local_clk or wr_a or wr_a_ff_inst_smin ) begin
206       if (!wr_local_clk) begin
207          wr_a_ff_inst_mdata = wr_a[3:0] ;
208       end
209       if (!wr_smclk) begin
210          wr_a_ff_inst_mdata = wr_a_ff_inst_smin;
211       end
212end
213always @(posedge wr_ssclk) begin
214    wr_a_ff[3:0]   <=  wr_a_ff_inst_mdata ; 
215end
216assign wr_a_ff_so[3:0] = wr_a_ff[3:0] ;
217/////////////////////////////////////////////////////
218
219/////////////////////////////////////////////////////
220// di Flop                                         //
221/////////////////////////////////////////////////////
222reg     [80:0]  di_ff_inst_mdata ;
223wire    [80:0]  di_ff_inst_smin ;
224
225assign di_ff_inst_smin[80:0]  = hold ?  di_ff[80:0] :  di_ff_si[80:0] ; 
226always @(wr_smclk or wr_local_clk or di or di_ff_inst_smin ) begin
227       if (!wr_local_clk) begin
228          di_ff_inst_mdata = di[80:0] ;
229       end
230       if (!wr_smclk) begin
231          di_ff_inst_mdata = di_ff_inst_smin;
232       end
233end
234always @(posedge wr_ssclk) begin
235    di_ff[80:0]   <=  di_ff_inst_mdata ; 
236end
237assign di_ff_so[80:0] = di_ff[80:0] ;
238/////////////////////////////////////////////////////
239
240wire wr_enable_l = csn_wr_ff | scan_en ;
241wire rd_enable_l = csn_rd_ff | scan_en ;
242
243// wire wr_clk_qual = wr_ssclk & ~scan_en ;
244always @(wr_ssclk or wr_a_ff or wr_enable_l or di_ff ) begin
245     if (!wr_ssclk) begin
246        if (!wr_enable_l) begin
247               memarray[wr_a_ff] <= di_ff[80:0] ; 
248        end
249     end 
250end
251       
252// wire  rd_clk_qual =  (rd_ssclk & ~scan_en) ;
253always @(rd_ssclk or rd_a_ff or rd_enable_l) begin
254     if (rd_ssclk) begin
255        if (rd_enable_l == 1'b0) begin
256             array_out[80:0] <= memarray[rd_a_ff] ;
257        end else if (rd_enable_l == 1'b1) begin
258             array_out[80:0] <= 81'h1FFFFFFFFFFFFFFFFFFFF;
259        end else begin 
260             array_out[80:0] <= 81'hXXXXXXXXXXXXXXXXXXXXX;
261        end
262     end
263end
264
265
266// synopsys translate_off
267
268`ifdef  INNO_MUXEX
269`else
270  always @(csn_rd_ff or csn_wr_ff or rd_a_ff or wr_a_ff)   begin
271   if ((SYNC_CLOCK_CHK1 == 0) & !csn_rd_ff & !csn_wr_ff & (rd_a_ff == wr_a_ff)) begin
272      array_out   <= 81'hxxxxxxxxxxxxxxxxxxxxx;
273        `ifdef MODELSIM 
274      $display ("sram_conflict", "conflict between read: %h and write: %h pointers", rd_a_ff, wr_a_ff);
275        `else
276      $error ("sram_conflict", "conflict between read: %h and write: %h pointers", rd_a_ff, wr_a_ff);
277        `endif
278   end
279  end
280`endif
281
282///////////////////////////////////////////////////////////////
283// Purely ERROR checking code.                               //
284///////////////////////////////////////////////////////////////
285reg  [3:0] rd_a_ff_del ;
286reg        csn_rd_ff_del ; 
287reg        rd_clk_del ; 
288always @(rd_local_clk) begin
289     if (rd_local_clk)  rd_clk_del = #300 rd_local_clk;
290     else              rd_clk_del = #300 rd_local_clk;
291end
292always @(posedge rd_clk_del) begin
293       rd_a_ff_del <= rd_a_ff ;
294       csn_rd_ff_del <= csn_rd_ff ;
295end 
296
297`ifdef  INNO_MUXEX
298`else
299  always @(csn_rd_ff_del or csn_wr_ff or rd_a_ff_del or wr_a_ff or rd_clk_del or wr_ssclk)   begin
300   if (SYNC_CLOCK_CHK2 == 0) begin
301       if (rd_clk_del & !wr_ssclk & !csn_rd_ff_del & !csn_wr_ff & (rd_a_ff_del == wr_a_ff)) begin
302        `ifdef MODELSIM   
303              $display ("sram_conflict", "conflict between read: %h and write: %h pointers ", rd_a_ff_del, wr_a_ff);
304        `else
305              $error ("sram_conflict", "conflict between read: %h and write: %h pointers ", rd_a_ff_del, wr_a_ff);
306        `endif
307       end 
308   end
309  end
310`endif
311
312reg  [3:0] wr_a_ff_del ;
313reg        csn_wr_ff_del ; 
314reg        wr_clk_del ; 
315always @(wr_ssclk) begin
316     if (wr_ssclk)  wr_clk_del = #300 wr_ssclk;
317     else              wr_clk_del = #300 wr_ssclk;
318end
319always @(posedge wr_clk_del) begin
320       wr_a_ff_del <= wr_a_ff ;
321       csn_wr_ff_del <= csn_wr_ff ;
322end 
323
324`ifdef  INNO_MUXEX
325`else
326  always @(csn_rd_ff or csn_wr_ff_del or rd_a_ff or wr_a_ff_del or rd_local_clk or wr_clk_del)   begin
327   if (SYNC_CLOCK_CHK3 == 0) begin
328       if (rd_local_clk & !wr_clk_del & !csn_rd_ff & !csn_wr_ff_del & (rd_a_ff == wr_a_ff_del)) begin
329      $display ("sram_conflict", "conflict between read: %h and write: %h pointers ", rd_a_ff, wr_a_ff_del);
330       end
331   end
332  end
333`endif
334
335///////////////////////////////////////////////////////////////
336// end the ERROR checking code.                              //
337///////////////////////////////////////////////////////////////
338///////////////////////////////////////
339
340
341// synopsys translate_on
342
343///////////////////////////////////
344// Transparent latch with reset
345///////////////////////////////////
346
347always @(array_out or rd_ssclk) begin
348     if (rd_ssclk) begin
349        array_out_latch <= array_out ;
350     end
351end
352
353always @(di_ff_so[0] or wr_ssclk) begin
354     if (!wr_ssclk) begin
355        di_ff_latch_so <= di_ff_so[0] ;
356     end
357end
358
359
360assign do  = testmux_sel ? di_ff : array_out_latch ;
361
362/////////////////////////////////////////////////////
363// listen_out Flop                                 //
364/////////////////////////////////////////////////////
365reg     [80:0]  listen_out_ff_inst_mdata ;
366wire    [80:0]  listen_out_ff_inst_smin ;
367
368assign listen_out_ff_inst_smin[80:0]  = hold ?  do[80:0] :  listen_out_si[80:0] ; 
369always @(rd_smclk or rd_local_clk or do or listen_out_ff_inst_smin ) begin
370       if (!rd_local_clk) begin
371          listen_out_ff_inst_mdata = do[80:0] ;
372       end
373       if (!rd_smclk) begin
374          listen_out_ff_inst_mdata = listen_out_ff_inst_smin;
375       end
376end
377always @(posedge rd_ssclk) begin
378    listen_out[80:0]   <=  listen_out_ff_inst_mdata ; 
379end
380assign listen_out_so[80:0] = listen_out[80:0] ;
381
382// synopsys translate_off
383
384`ifdef  INNO_MUXEX
385`else
386   always @(posedge rd_clk) begin
387     if ((MARGIN_WARNING == 0) & margin != 5'b10101) begin
388        `ifdef MODELSIM 
389          $display ("sram_margin", "margin is not set to the default value") ;
390        `else
391          $error ("sram_margin", "margin is not set to the default value") ;
392        `endif
393     end
394   end
395`endif
396
397// synopsys translate_on
398
399endmodule
Note: See TracBrowser for help on using the repository browser.