OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [orp/] [orp_soc/] [rtl/] [verilog/] [mem_if/] [sram_top.v] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 746 lampret
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  XESS SRAM interface                                         ////
4
////                                                              ////
5
////  This file is part of the OR1K test application              ////
6
////  http://www.opencores.org/cores/or1k/                        ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Connects the SoC to SRAM. It does RMW for byte accesses     ////
10
////  because XSV board has WEs on a 16-bit basis.                ////
11
////                                                              ////
12
////  To Do:                                                      ////
13
////   - nothing really                                           ////
14
////                                                              ////
15
////  Author(s):                                                  ////
16
////      - Simon Srot, simons@opencores.org                      ////
17
////      - Igor Mohor, igorm@opencores.org                       ////
18
////                                                              ////
19
//////////////////////////////////////////////////////////////////////
20
////                                                              ////
21
//// Copyright (C) 2001 Authors                                   ////
22
////                                                              ////
23
//// This source file may be used and distributed without         ////
24
//// restriction provided that this copyright statement is not    ////
25
//// removed from the file and that any derivative work contains  ////
26
//// the original copyright notice and the associated disclaimer. ////
27
////                                                              ////
28
//// This source file is free software; you can redistribute it   ////
29
//// and/or modify it under the terms of the GNU Lesser General   ////
30
//// Public License as published by the Free Software Foundation; ////
31
//// either version 2.1 of the License, or (at your option) any   ////
32
//// later version.                                               ////
33
////                                                              ////
34
//// This source is distributed in the hope that it will be       ////
35
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
36
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
37
//// PURPOSE.  See the GNU Lesser General Public License for more ////
38
//// details.                                                     ////
39
////                                                              ////
40
//// You should have received a copy of the GNU Lesser General    ////
41
//// Public License along with this source; if not, download it   ////
42
//// from http://www.opencores.org/lgpl.shtml                     ////
43
////                                                              ////
44
//////////////////////////////////////////////////////////////////////
45
//
46
// CVS Revision History
47
//
48
// $Log: not supported by cvs2svn $
49 1193 dries
// Revision 1.5  2002/09/16 02:51:23  lampret
50
// Delayed wb_err_o. Disabled wb_ack_o when wb_err_o is asserted.
51
//
52 1052 lampret
// Revision 1.4  2002/08/18 19:55:30  lampret
53
// Added variable delay for SRAM.
54
//
55 978 lampret
// Revision 1.3  2002/08/14 06:24:43  lampret
56
// Fixed size of generic flash/sram to exactly 2MB
57
//
58 959 lampret
// Revision 1.2  2002/08/12 05:34:06  lampret
59
// Added SRAM_GENERIC
60
//
61 946 lampret
// Revision 1.1.1.1  2002/03/21 16:55:44  lampret
62
// First import of the "new" XESS XSV environment.
63
//
64
//
65 746 lampret
// Revision 1.3  2002/01/23 07:50:44  lampret
66
// Added wb_err_o to flash and sram i/f for testing the buserr exception.
67
//
68
// Revision 1.2  2002/01/14 06:18:22  lampret
69
// Fixed mem2reg bug in FAST implementation. Updated debug unit to work with new genpc/if.
70
//
71
// Revision 1.1.1.1  2001/11/04 19:00:09  lampret
72
// First import.
73
//
74
//
75
 
76
// synopsys translate_off
77
`include "timescale.v"
78
// synopsys translate_on
79
 
80 1268 lampret
`define SRAM_GENERIC
81 946 lampret
 
82
`ifdef SRAM_GENERIC
83
 
84 746 lampret
module sram_top (
85
  wb_clk_i, wb_rst_i,
86
 
87
  wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
88
  wb_stb_i, wb_ack_o, wb_err_o,
89
 
90
  r_cen, r0_wen, r1_wen, r_oen, r_a, r_d_i, r_d_o, d_oe,
91
  l_cen, l0_wen, l1_wen, l_oen, l_a, l_d_i, l_d_o
92
);
93
 
94
//
95
// Paraneters
96
//
97
parameter               aw = 19;
98
 
99
//
100
// I/O Ports
101
//
102
input                   wb_clk_i;
103
input                   wb_rst_i;
104
 
105
//
106
// WB slave i/f
107
//
108
input   [31:0]           wb_dat_i;
109
output  [31:0]           wb_dat_o;
110
input   [31:0]           wb_adr_i;
111
input   [3:0]            wb_sel_i;
112
input                   wb_we_i;
113
input                   wb_cyc_i;
114
input                   wb_stb_i;
115
output                  wb_ack_o;
116
output                  wb_err_o;
117
 
118
//
119
// Right SRAM bank
120
//
121
output                  r_oen;
122
output                  r0_wen;
123
output                  r1_wen;
124
output                  r_cen;
125
input   [15:0]           r_d_i;
126
output  [15:0]           r_d_o;
127
output  [aw-1:0] r_a;
128
 
129
//
130
// Left SRAM bank
131
//
132
output                  l_oen;
133
output                  l0_wen;
134
output                  l1_wen;
135
output                  l_cen;
136
input   [15:0]           l_d_i;
137
output  [15:0]           l_d_o;
138
output  [aw-1:0] l_a;
139
 
140
//
141
// Common SRAM signals
142
//
143
output                  d_oe;
144
 
145
//
146 946 lampret
// Internal wires and regs
147
//
148 959 lampret
reg     [7:0]           mem [2097151:0];
149 1268 lampret
integer                 i;
150 946 lampret
wire    [31:0]          adr;
151
`ifdef SRAM_GENERIC_REGISTERED
152
reg                     wb_err_o;
153 978 lampret
reg     [31:0]           prev_adr;
154
reg     [1:0]            delay;
155
`else
156
wire    [1:0]            delay;
157 946 lampret
`endif
158
wire                    wb_err;
159
 
160
//
161
// Aliases and simple assignments
162
//
163 1052 lampret
assign wb_err = wb_cyc_i & wb_stb_i & (delay == 2'd0) & (|wb_adr_i[23:21]);     // If Access to > 2MB (8-bit leading prefix ignored)
164 946 lampret
assign adr = {8'h00, wb_adr_i[23:2], 2'b00};
165
 
166
//
167
// Reading from SRAM model
168
//
169
assign wb_dat_o[7:0] = mem[adr+3];
170
assign wb_dat_o[15:8] = mem[adr+2];
171
assign wb_dat_o[23:16] = mem[adr+1];
172
assign wb_dat_o[31:24] = mem[adr+0];
173
 
174
//
175
// Writing to SRAM model
176
//
177
always @(posedge wb_rst_i or posedge wb_clk_i)
178
        if (wb_cyc_i & wb_stb_i & wb_we_i) begin
179
                if (wb_sel_i[0])
180
                        mem[adr+3] <= #1 wb_dat_i[7:0];
181
                if (wb_sel_i[1])
182
                        mem[adr+2] <= #1 wb_dat_i[15:8];
183
                if (wb_sel_i[2])
184
                        mem[adr+1] <= #1 wb_dat_i[23:16];
185
                if (wb_sel_i[3])
186
                        mem[adr+0] <= #1 wb_dat_i[31:24];
187
        end
188
 
189
`ifdef SRAM_GENERIC_REGISTERED
190
//
191
// WB Acknowledge
192
//
193
always @(posedge wb_clk_i or posedge wb_rst_i)
194 978 lampret
        if (wb_rst_i) begin
195
                delay <= #1 2'd3;
196
                prev_adr <= #1 32'h0000_0000;
197
        end
198
        else if (delay && (wb_adr_i == prev_adr) && wb_cyc_i && wb_stb_i)
199
                delay <= #1 delay - 2'd1;
200 1052 lampret
        else if (wb_ack_o || wb_err_o || (wb_adr_i != prev_adr) || ~wb_stb_i) begin
201
                delay <= #1 2'd2;       // delay ... can range from 3 to 0
202 978 lampret
                prev_adr <= #1 wb_adr_i;
203
        end
204 946 lampret
`else
205 978 lampret
assign delay = 2'd0;
206 946 lampret
`endif
207
 
208 1052 lampret
assign wb_ack_o = wb_cyc_i & wb_stb_i & ~wb_err & (delay == 2'd0)
209 946 lampret
`ifdef SRAM_GENERIC_REGISTERED
210 978 lampret
        & (wb_adr_i == prev_adr)
211
`endif
212
        ;
213
 
214
`ifdef SRAM_GENERIC_REGISTERED
215 946 lampret
//
216
// WB Error
217
//
218
always @(posedge wb_clk_i or posedge wb_rst_i)
219
        if (wb_rst_i)
220
                wb_err_o <= #1 1'b0;
221
        else
222
                wb_err_o <= #1 wb_err & !wb_err_o;
223
`else
224
assign wb_err_o = wb_err;
225
`endif
226
 
227
//
228 978 lampret
// SRAM i/f monitor
229 946 lampret
//
230
// synopsys translate_off
231
integer fsram;
232 1268 lampret
initial begin
233
        fsram = $fopen("sram.log");
234
        for (i = 0; i < 2097152; i = i + 1)
235
                mem[i] = 0;
236
end
237 946 lampret
always @(posedge wb_clk_i)
238
        if (wb_cyc_i)
239
                if (wb_stb_i & wb_we_i) begin
240
                        if (wb_sel_i[3])
241
                                mem[{wb_adr_i[23:2], 2'b00}+0] = wb_dat_i[31:24];
242
                        if (wb_sel_i[2])
243
                                mem[{wb_adr_i[23:2], 2'b00}+1] = wb_dat_i[23:16];
244
                        if (wb_sel_i[1])
245
                                mem[{wb_adr_i[23:2], 2'b00}+2] = wb_dat_i[15:8];
246
                        if (wb_sel_i[0])
247
                                mem[{wb_adr_i[23:2], 2'b00}+3] = wb_dat_i[7:0];
248
                        $fdisplay(fsram, "%t [%h] <- write %h, byte sel %b", $time, wb_adr_i, wb_dat_i, wb_sel_i);
249
                end else if (wb_ack_o)
250
                        $fdisplay(fsram, "%t [%h] -> read %h", $time, wb_adr_i, wb_dat_o);
251
// synopsys translate_on
252
 
253
endmodule
254
 
255
`else
256
 
257
module sram_top (
258
  wb_clk_i, wb_rst_i,
259
 
260
  wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
261
  wb_stb_i, wb_ack_o, wb_err_o,
262
 
263
  r_cen, r0_wen, r1_wen, r_oen, r_a, r_d_i, r_d_o, d_oe,
264
  l_cen, l0_wen, l1_wen, l_oen, l_a, l_d_i, l_d_o
265
);
266
 
267
//
268
// Paraneters
269
//
270
parameter               aw = 19;
271
 
272
//
273
// I/O Ports
274
//
275
input                   wb_clk_i;
276
input                   wb_rst_i;
277
 
278
//
279
// WB slave i/f
280
//
281
input   [31:0]           wb_dat_i;
282
output  [31:0]           wb_dat_o;
283
input   [31:0]           wb_adr_i;
284
input   [3:0]            wb_sel_i;
285
input                   wb_we_i;
286
input                   wb_cyc_i;
287
input                   wb_stb_i;
288
output                  wb_ack_o;
289
output                  wb_err_o;
290
 
291
//
292
// Right SRAM bank
293
//
294
output                  r_oen;
295
output                  r0_wen;
296
output                  r1_wen;
297
output                  r_cen;
298
input   [15:0]           r_d_i;
299
output  [15:0]           r_d_o;
300
output  [aw-1:0] r_a;
301
 
302
//
303
// Left SRAM bank
304
//
305
output                  l_oen;
306
output                  l0_wen;
307
output                  l1_wen;
308
output                  l_cen;
309
input   [15:0]           l_d_i;
310
output  [15:0]           l_d_o;
311
output  [aw-1:0] l_a;
312
 
313
//
314
// Common SRAM signals
315
//
316
output                  d_oe;
317
 
318
//
319 746 lampret
// Internal regs and wires
320
//
321
reg     [15:0]           r_data;
322
reg     [15:0]           l_data;
323
reg                     l0_wen;
324
wire                    l1_wen = l0_wen;
325
reg                     r0_wen;
326
wire                    r1_wen = r0_wen;
327
reg     [31:0]           latch_data;
328
reg                     ack_we;
329
wire                    l_oe;
330
wire                    r_oe;
331
wire                    r_ack;
332
reg                     Mux;
333
reg     [aw-1:0] LatchedAddr;
334
reg     [15:0]           l_read;
335
reg     [15:0]           r_read;
336
reg                     d_oe;
337
reg     [15:0]           l_mux;
338
reg     [15:0]           r_mux;
339
 
340
//
341
// Aliases and simple assignments
342
//
343
assign wb_dat_o = {r_d_i, l_d_i};
344
assign l_oen = ~l_oe;
345
assign r_oen = ~r_oe;
346
assign l_a = Mux ? LatchedAddr : wb_adr_i[aw+1:2];
347
assign r_a = l_a;
348
assign l_d_o = l_mux;
349
assign r_d_o = r_mux;
350
assign l_oe = wb_cyc_i & wb_stb_i & l0_wen;
351
assign r_oe = wb_cyc_i & wb_stb_i & r0_wen;
352
assign l_cen = ~(wb_cyc_i & wb_stb_i);
353
assign r_cen = l_cen;
354 1268 lampret
assign wb_ack_o = (wb_cyc_i & wb_stb_i & ~wb_err & ~wb_we_i) | ack_we;
355 746 lampret
assign wb_err_o = wb_cyc_i & wb_stb_i & (|wb_adr_i[27:21]);     // If Access to > 2MB (4-bit leading prefix ignored)
356
 
357
//
358
// RMW mux control
359
//
360
always @ (negedge wb_clk_i or posedge wb_rst_i)
361
begin
362
  if (wb_rst_i)
363
    Mux <= 1'b0;
364
  else
365
  if (ack_we)
366
    Mux <= #1 1'b1;
367
  else
368
    Mux <= #1 1'b0;
369
end
370
 
371
//
372
// Latch address
373
//
374
always @ (negedge wb_clk_i or posedge wb_rst_i)
375
begin
376
  if (wb_rst_i)
377
    LatchedAddr <= 'h0;
378
  else
379
  if (wb_cyc_i & wb_stb_i)
380
    LatchedAddr <= #1 wb_adr_i[aw+1:2];
381
end
382
 
383
//
384
// Latch data from RAM (read data)
385
//
386
always @ (posedge wb_clk_i or posedge wb_rst_i)
387
begin
388
  if (wb_rst_i)
389
    begin
390
      l_read <= 16'h0;
391
      r_read <= 16'h0;
392
    end
393
  else
394
  if (wb_cyc_i & wb_stb_i)
395
    begin
396
      l_read <= #1 l_d_i[15:0];
397
      r_read <= #1 r_d_i[15:0];
398
    end
399
end
400
 
401
//
402
// Mux and latch data for writing left SRAM bank (bytes 0 and 1)
403
//
404
always @ (negedge wb_clk_i or posedge wb_rst_i)
405
begin
406
  if (wb_rst_i)
407
    l_mux <= 16'h0;
408
  else
409
  if (~l0_wen)
410
    begin
411
      if (wb_sel_i[0])
412
        l_mux[7:0]  <= #1 wb_dat_i[7:0];
413
      else
414
        l_mux[7:0]  <= #1 l_read[7:0];
415
      if (wb_sel_i[1])
416
        l_mux[15:8] <= #1 wb_dat_i[15:8];
417
      else
418
        l_mux[15:8] <= #1 l_read[15:8];
419
    end
420
  else
421
    l_mux[15:0]  <= #1 16'hz;
422
end
423
 
424
//
425
// Mux and latch data for writing right SRAM bank (bytes 2 and 3)
426
//
427
always @ (negedge wb_clk_i or posedge wb_rst_i)
428
begin
429
  if (wb_rst_i)
430
    r_mux <= 16'h0;
431
  else
432
  if (~r0_wen)
433
    begin
434
      if (wb_sel_i[2])
435
        r_mux[7:0]  <= #1 wb_dat_i[23:16];
436
      else
437
        r_mux[7:0]  <= #1 r_read[7:0];
438
      if (wb_sel_i[3])
439
        r_mux[15:8]  <= #1 wb_dat_i[31:24];
440
      else
441
        r_mux[15:8]  <= #1 r_read[15:8];
442
    end
443
  else
444
    r_mux <= #1 16'hz;
445
end
446
 
447
//
448
// Left WE
449
//
450
always @ (posedge wb_clk_i or posedge wb_rst_i)
451
begin
452
  if (wb_rst_i)
453
    l0_wen <= 1'b1;
454
  else
455
  if (wb_cyc_i & wb_stb_i & wb_we_i & (|wb_sel_i[1:0]) & ~wb_ack_o)
456
    l0_wen <= #1 1'b0;
457
  else
458
    l0_wen <= #1 1'b1;
459
end
460
 
461
//
462
// Right WE
463
//
464
always @ (posedge wb_clk_i or posedge wb_rst_i)
465
begin
466
  if (wb_rst_i)
467
    r0_wen <= 1'b1;
468
  else
469
  if (wb_cyc_i & wb_stb_i & wb_we_i & (|wb_sel_i[3:2]) & ~wb_ack_o)
470
    r0_wen <= #1 1'b0;
471
  else
472
    r0_wen <= #1 1'b1;
473
end
474
 
475
//
476
// Write acknowledge
477
//
478
always @ (posedge wb_clk_i or posedge wb_rst_i)
479
begin
480
  if (wb_rst_i)
481
    ack_we <= 1'b0;
482
  else
483
  if (wb_cyc_i & wb_stb_i & wb_we_i & ~ack_we)
484
    ack_we <= #1 1'b1;
485
  else
486
    ack_we <= #1 1'b0;
487
end
488
 
489
//
490
// Generate d_oe signal (tristate control)
491
//
492
always @ (negedge wb_clk_i or posedge wb_rst_i)
493
begin
494
  if (wb_rst_i)
495
    d_oe <= 1'b0;
496
  else
497
  if (~l0_wen | ~r0_wen)
498
    d_oe <= 1'b1;
499
  else
500
    d_oe <= 1'b0;
501
end
502
 
503
//
504
// SRAM i/f monitor
505
//
506
// synopsys translate_off
507
integer fsram;
508
initial fsram = $fopen("sram.log");
509
always @(posedge wb_clk_i)
510
begin
511
  if (~l0_wen | ~r0_wen)
512
    $fdisplay(fsram, "%t [%h] <- write %h", $time, wb_adr_i, {r_d_o, l_d_o});
513
  else
514
  if ((l_oe | r_oe) & ~wb_we_i)
515
    $fdisplay(fsram, "%t [%h] -> read %h", $time, wb_adr_i, {r_d_i, l_d_i});
516
end
517
// synopsys translate_on
518
 
519
endmodule
520 946 lampret
 
521
`endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.