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

Revision 6, 12.8 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_16x65.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_16x65(
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 [64:0] di;
51   input si;
52   output so;
53   output [64:0] do;
54   output [64:0] listen_out;
55
56parameter  SYNC_CLOCK_CHK1 = 0;
57parameter  SYNC_CLOCK_CHK2 = 0;
58parameter  SYNC_CLOCK_CHK3 = 0;
59parameter  MARGIN_WARNING = 0; // margin warning is on by default
60
61
62// Start code
63`ifdef DEFINE_0IN
64wire [64:0] array_out  ;
65`else
66reg [64:0] memarray[15:0] ;
67reg [64:0] array_out  ;
68`endif
69
70reg [64:0] array_out_latch    ;
71
72
73reg  [3:0] rd_a_ff   ;
74wire [3:0] rd_a_ff_so;
75wire [3:0] rd_a_ff_si ;
76
77reg  [3:0] wr_a_ff   ;
78wire [3:0] wr_a_ff_so;
79wire [3:0] wr_a_ff_si ;
80
81reg  [64:0] di_ff   ;
82wire [64:0] di_ff_so;
83wire [64:0] di_ff_si;
84
85wire [64:0] listen_out_so;
86wire [64:0] listen_out_si ;
87reg  [64:0] listen_out     ;
88
89
90reg        csn_rd_ff ;
91wire       csn_rd_ff_si ;
92wire       csn_rd_ff_so ;
93
94reg        csn_wr_ff ;
95wire       csn_wr_ff_si ;
96wire       csn_wr_ff_so ;
97
98reg        di_ff_latch_so ;
99///////////////////////////////////////
100// Scan chain connections            //
101///////////////////////////////////////
102assign wr_a_ff_si[3:0] = {si      , wr_a_ff_so[3:1]} ;
103assign csn_wr_ff_si    = wr_a_ff_so[0] ;
104assign di_ff_si        = {csn_wr_ff_so, di_ff_so[64:1]};
105assign listen_out_si   = {listen_out_so[63:0], di_ff_latch_so} ;
106assign csn_rd_ff_si    = listen_out_so[64] ;
107assign rd_a_ff_si[3:0] = {rd_a_ff_so[2:0], csn_rd_ff_so} ;
108assign so              = rd_a_ff_so[3] ;
109///////////////////////////////////////
110// Instantiate a clock headers        //
111///////////////////////////////////////
112
113wire   rd_ssclk       = rd_clk ; // clk_en & rd_clk ;
114wire   rd_local_clk   = rd_ssclk | scan_en | hold ; 
115wire   rd_smclk       = rd_ssclk |  ~(scan_en | hold) ;
116
117wire   wr_ssclk       = wr_clk ; // clk_en & wr_clk ;
118wire   wr_local_clk   = wr_ssclk | scan_en | hold ; 
119wire   wr_smclk       = wr_ssclk |  ~(scan_en | hold) ;
120
121
122/////////////////////////////////////////////////////
123// csn_rd Flop                                     //
124/////////////////////////////////////////////////////
125
126reg                     csn_rd_ff_inst_mdata ;
127wire                    csn_rd_ff_inst_smin ;
128reg                     csn_rd_ff_scan_out ;
129
130assign csn_rd_ff_inst_smin  = hold ?  csn_rd_ff_scan_out :  csn_rd_ff_si ; 
131always @(rd_smclk or rd_local_clk or csn_rd or csn_rd_ff_inst_smin ) begin
132       if (!rd_local_clk) begin
133          csn_rd_ff_inst_mdata = csn_rd ;
134       end
135       if (!rd_smclk) begin
136          csn_rd_ff_inst_mdata = csn_rd_ff_inst_smin;
137       end
138end
139always @(posedge rd_ssclk) begin
140    csn_rd_ff_scan_out    <=  csn_rd_ff_inst_mdata ; 
141end
142always @(rd_local_clk or csn_rd_ff_inst_mdata) begin
143   if (rd_local_clk ) begin
144    csn_rd_ff    <=  csn_rd_ff_inst_mdata ; 
145   end
146end
147assign csn_rd_ff_so =  csn_rd_ff_scan_out;
148       
149/////////////////////////////////////////////////////
150
151/////////////////////////////////////////////////////
152// rd_a Flop                                       //
153/////////////////////////////////////////////////////
154reg     [3:0]   rd_a_ff_inst_mdata ;
155wire    [3:0]   rd_a_ff_inst_smin ;
156reg     [3:0]   rd_a_ff_scan_out ;
157
158assign rd_a_ff_inst_smin[3:0]  = hold ?  rd_a_ff_scan_out[3:0] :  rd_a_ff_si[3:0] ; 
159always @(rd_smclk or rd_local_clk or rd_a or rd_a_ff_inst_smin ) begin
160       if (!rd_local_clk) begin
161          rd_a_ff_inst_mdata = rd_a[3:0] ;
162       end
163       if (!rd_smclk) begin
164          rd_a_ff_inst_mdata = rd_a_ff_inst_smin;
165       end
166end
167always @(posedge rd_ssclk) begin
168    rd_a_ff_scan_out[3:0]   <=  rd_a_ff_inst_mdata ; 
169end
170always @(rd_local_clk or rd_a_ff_inst_mdata) begin
171   if (rd_local_clk) begin
172    rd_a_ff[3:0]   <=  rd_a_ff_inst_mdata ; 
173   end
174end
175assign rd_a_ff_so[3:0] = rd_a_ff_scan_out[3:0] ;
176/////////////////////////////////////////////////////
177       
178/////////////////////////////////////////////////////
179// csn_wr Flop                                     //
180/////////////////////////////////////////////////////
181reg                     csn_wr_ff_inst_mdata ;
182wire                    csn_wr_ff_inst_smin ;
183
184assign csn_wr_ff_inst_smin  = hold ?  csn_wr_ff :  csn_wr_ff_si ; 
185always @(wr_smclk or wr_local_clk or csn_wr or csn_wr_ff_inst_smin ) begin
186       if (!wr_local_clk) begin
187          csn_wr_ff_inst_mdata = csn_wr ;
188       end
189       if (!wr_smclk) begin
190          csn_wr_ff_inst_mdata = csn_wr_ff_inst_smin;
191       end
192end
193always @(posedge wr_ssclk) begin
194    csn_wr_ff    <=  csn_wr_ff_inst_mdata ; 
195end
196assign csn_wr_ff_so =  csn_wr_ff;
197/////////////////////////////////////////////////////
198       
199/////////////////////////////////////////////////////
200// wr_a Flop                                       //
201/////////////////////////////////////////////////////
202reg     [3:0]   wr_a_ff_inst_mdata ;
203wire    [3:0]   wr_a_ff_inst_smin ;
204
205assign wr_a_ff_inst_smin[3:0]  = hold ?  wr_a_ff[3:0] :  wr_a_ff_si[3:0] ; 
206always @(wr_smclk or wr_local_clk or wr_a or wr_a_ff_inst_smin ) begin
207       if (!wr_local_clk) begin
208          wr_a_ff_inst_mdata = wr_a[3:0] ;
209       end
210       if (!wr_smclk) begin
211          wr_a_ff_inst_mdata = wr_a_ff_inst_smin;
212       end
213end
214always @(posedge wr_ssclk) begin
215    wr_a_ff[3:0]   <=  wr_a_ff_inst_mdata ; 
216end
217assign wr_a_ff_so[3:0] = wr_a_ff[3:0] ;
218/////////////////////////////////////////////////////
219
220/////////////////////////////////////////////////////
221// di Flop                                         //
222/////////////////////////////////////////////////////
223reg     [64:0]  di_ff_inst_mdata ;
224wire    [64:0]  di_ff_inst_smin ;
225
226assign di_ff_inst_smin[64:0]  = hold ?  di_ff[64:0] :  di_ff_si[64:0] ; 
227always @(wr_smclk or wr_local_clk or di or di_ff_inst_smin ) begin
228       if (!wr_local_clk) begin
229          di_ff_inst_mdata = di[64:0] ;
230       end
231       if (!wr_smclk) begin
232          di_ff_inst_mdata = di_ff_inst_smin;
233       end
234end
235always @(posedge wr_ssclk) begin
236    di_ff[64:0]   <=  di_ff_inst_mdata ; 
237end
238assign di_ff_so[64:0] = di_ff[64:0] ;
239/////////////////////////////////////////////////////
240
241wire wr_enable_l = csn_wr_ff | scan_en ;
242wire rd_enable_l = csn_rd_ff | scan_en ;
243
244// wire wr_clk_qual = wr_ssclk & ~scan_en ;
245`ifdef DEFINE_0IN
246rf16x65  rf16x65 ( .rdclk(rd_ssclk), .wrclk(wr_ssclk), .radr(rd_a_ff), .wadr(wr_a_ff), .ren(!rd_enable_l),
247                        .we(!wr_enable_l), .wm(65'h1FFFFFFFFFFFFFFFF), .din(di_ff), .dout(array_out) );
248`else
249always @(wr_ssclk or wr_a_ff or wr_enable_l or di_ff ) begin
250     if (!wr_ssclk) begin
251        if (!wr_enable_l) begin
252               memarray[wr_a_ff] <= di_ff[64:0] ; 
253        end
254     end 
255end
256       
257// wire  rd_clk_qual =  (rd_ssclk & ~scan_en) ;
258always @(rd_ssclk or rd_a_ff or rd_enable_l) begin
259     if (rd_ssclk) begin
260        if (rd_enable_l == 1'b0) begin
261             array_out[64:0] <= memarray[rd_a_ff] ;
262        end else if (rd_enable_l == 1'b1) begin
263             array_out[64:0] <= 65'h1FFFFFFFFFFFFFFFF;
264        end else begin 
265             array_out[64:0] <= 65'hXXXXXXXXXXXXXXXXX;
266        end
267     end
268end
269`endif
270
271// synopsys translate_off
272
273`ifdef DEFINE_0IN
274`else
275`ifdef INNO_MUXEX
276`else
277always @(csn_rd_ff or csn_wr_ff or rd_a_ff or wr_a_ff)   begin
278   if ((SYNC_CLOCK_CHK1 == 0) & !csn_rd_ff & !csn_wr_ff & (rd_a_ff == wr_a_ff)) begin
279      array_out   <= 65'hxxxxxxxxxxxxxxxxx;
280        `ifdef MODELSIM 
281      $display ("sram_conflict", "conflict between read: %h and write: %h pointers", rd_a_ff, wr_a_ff);
282        `else
283      $error ("sram_conflict", "conflict between read: %h and write: %h pointers", rd_a_ff, wr_a_ff);
284        `endif
285   end
286end
287`endif
288
289///////////////////////////////////////////////////////////////
290// Purely ERROR checking code.                               //
291///////////////////////////////////////////////////////////////
292reg  [3:0] rd_a_ff_del ;
293reg        csn_rd_ff_del ; 
294reg        rd_clk_del ; 
295always @(rd_local_clk) begin
296     if (rd_local_clk)  rd_clk_del = #300 rd_local_clk;
297     else              rd_clk_del = #300 rd_local_clk;
298end
299always @(posedge rd_clk_del) begin
300       rd_a_ff_del <= rd_a_ff ;
301       csn_rd_ff_del <= csn_rd_ff ;
302end 
303`ifdef INNO_MUXEX
304`else
305always @(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
306   if (SYNC_CLOCK_CHK2 == 0) begin
307       if (rd_clk_del & !wr_ssclk & !csn_rd_ff_del & !csn_wr_ff & (rd_a_ff_del == wr_a_ff)) begin
308        `ifdef MODELSIM   
309              $display ("sram_conflict", "conflict between read: %h and write: %h pointers ", rd_a_ff_del, wr_a_ff);
310        `else
311              $error ("sram_conflict", "conflict between read: %h and write: %h pointers ", rd_a_ff_del, wr_a_ff);
312        `endif   
313      end 
314   end
315end
316`endif
317reg  [3:0] wr_a_ff_del ;
318reg        csn_wr_ff_del ; 
319reg        wr_clk_del ; 
320always @(wr_ssclk) begin
321     if (wr_ssclk)  wr_clk_del = #300 wr_ssclk;
322     else              wr_clk_del = #300 wr_ssclk;
323end
324always @(posedge wr_clk_del) begin
325       wr_a_ff_del <= wr_a_ff ;
326       csn_wr_ff_del <= csn_wr_ff ;
327end 
328`ifdef INNO_MUXEX
329`else
330always @(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
331   if (SYNC_CLOCK_CHK3 == 0) begin
332       if (rd_local_clk & !wr_clk_del & !csn_rd_ff & !csn_wr_ff_del & (rd_a_ff == wr_a_ff_del)) begin
333        `ifdef MODELSIM   
334              $display ("sram_conflict", "conflict between read: %h and write: %h pointers ", rd_a_ff, wr_a_ff_del);
335        `else     
336              $error ("sram_conflict", "conflict between read: %h and write: %h pointers ", rd_a_ff, wr_a_ff_del);
337        `endif   
338       end
339   end
340end
341`endif
342`endif
343///////////////////////////////////////////////////////////////
344// end the ERROR checking code.                              //
345///////////////////////////////////////////////////////////////
346///////////////////////////////////////
347
348// synopsys translate_on
349
350
351///////////////////////////////////
352// Transparent latch with reset
353///////////////////////////////////
354
355always @(array_out or rd_ssclk) begin
356     if (rd_ssclk) begin
357        array_out_latch <= array_out ;
358     end
359end
360
361always @(di_ff_so[0] or wr_ssclk) begin
362     if (!wr_ssclk) begin
363        di_ff_latch_so <= di_ff_so[0] ;
364     end
365end
366
367
368assign do  = testmux_sel ? di_ff : array_out_latch ;
369
370/////////////////////////////////////////////////////
371// listen_out Flop                                 //
372/////////////////////////////////////////////////////
373reg     [64:0]  listen_out_ff_inst_mdata ;
374wire    [64:0]  listen_out_ff_inst_smin ;
375
376assign listen_out_ff_inst_smin[64:0]  = hold ?  do[64:0] :  listen_out_si[64:0] ; 
377always @(rd_smclk or rd_local_clk or do or listen_out_ff_inst_smin ) begin
378       if (!rd_local_clk) begin
379          listen_out_ff_inst_mdata = do[64:0] ;
380       end
381       if (!rd_smclk) begin
382          listen_out_ff_inst_mdata = listen_out_ff_inst_smin;
383       end
384end
385always @(posedge rd_ssclk) begin
386    listen_out[64:0]   <=  listen_out_ff_inst_mdata ; 
387end
388assign listen_out_so[64:0] = listen_out[64:0] ;
389
390// synopsys translate_off
391 
392`ifdef DEFINE_0IN
393`else
394`ifdef INNO_MUXEX
395`else
396always @(posedge rd_clk) begin
397     if ((MARGIN_WARNING == 0) & margin != 5'b10101) begin
398        `ifdef MODELSIM 
399          $display ("sram_margin", "margin is not set to the default value") ;
400        `else     
401          $error ("sram_margin", "margin is not set to the default value") ;
402        `endif
403     end
404end
405`endif
406`endif
407
408// synopsys translate_on
409
410endmodule
Note: See TracBrowser for help on using the repository browser.