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 1193

Go to most recent revision | 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 1193 dries
//
81
// Disable SRAM_GENERIC when using FPGAs
82
//
83
//`define SRAM_GENERIC
84 946 lampret
 
85
`ifdef SRAM_GENERIC
86
 
87 746 lampret
module sram_top (
88
  wb_clk_i, wb_rst_i,
89
 
90
  wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
91
  wb_stb_i, wb_ack_o, wb_err_o,
92
 
93
  r_cen, r0_wen, r1_wen, r_oen, r_a, r_d_i, r_d_o, d_oe,
94
  l_cen, l0_wen, l1_wen, l_oen, l_a, l_d_i, l_d_o
95
);
96
 
97
//
98
// Paraneters
99
//
100
parameter               aw = 19;
101
 
102
//
103
// I/O Ports
104
//
105
input                   wb_clk_i;
106
input                   wb_rst_i;
107
 
108
//
109
// WB slave i/f
110
//
111
input   [31:0]           wb_dat_i;
112
output  [31:0]           wb_dat_o;
113
input   [31:0]           wb_adr_i;
114
input   [3:0]            wb_sel_i;
115
input                   wb_we_i;
116
input                   wb_cyc_i;
117
input                   wb_stb_i;
118
output                  wb_ack_o;
119
output                  wb_err_o;
120
 
121
//
122
// Right SRAM bank
123
//
124
output                  r_oen;
125
output                  r0_wen;
126
output                  r1_wen;
127
output                  r_cen;
128
input   [15:0]           r_d_i;
129
output  [15:0]           r_d_o;
130
output  [aw-1:0] r_a;
131
 
132
//
133
// Left SRAM bank
134
//
135
output                  l_oen;
136
output                  l0_wen;
137
output                  l1_wen;
138
output                  l_cen;
139
input   [15:0]           l_d_i;
140
output  [15:0]           l_d_o;
141
output  [aw-1:0] l_a;
142
 
143
//
144
// Common SRAM signals
145
//
146
output                  d_oe;
147
 
148
//
149 946 lampret
// Internal wires and regs
150
//
151 959 lampret
reg     [7:0]           mem [2097151:0];
152 946 lampret
wire    [31:0]          adr;
153
`ifdef SRAM_GENERIC_REGISTERED
154
reg                     wb_err_o;
155 978 lampret
reg     [31:0]           prev_adr;
156
reg     [1:0]            delay;
157
`else
158
wire    [1:0]            delay;
159 946 lampret
`endif
160
wire                    wb_err;
161
 
162
//
163
// Aliases and simple assignments
164
//
165 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)
166 946 lampret
assign adr = {8'h00, wb_adr_i[23:2], 2'b00};
167
 
168
//
169
// Reading from SRAM model
170
//
171
assign wb_dat_o[7:0] = mem[adr+3];
172
assign wb_dat_o[15:8] = mem[adr+2];
173
assign wb_dat_o[23:16] = mem[adr+1];
174
assign wb_dat_o[31:24] = mem[adr+0];
175
 
176
//
177
// Writing to SRAM model
178
//
179
always @(posedge wb_rst_i or posedge wb_clk_i)
180
        if (wb_cyc_i & wb_stb_i & wb_we_i) begin
181
                if (wb_sel_i[0])
182
                        mem[adr+3] <= #1 wb_dat_i[7:0];
183
                if (wb_sel_i[1])
184
                        mem[adr+2] <= #1 wb_dat_i[15:8];
185
                if (wb_sel_i[2])
186
                        mem[adr+1] <= #1 wb_dat_i[23:16];
187
                if (wb_sel_i[3])
188
                        mem[adr+0] <= #1 wb_dat_i[31:24];
189
        end
190
 
191
`ifdef SRAM_GENERIC_REGISTERED
192
//
193
// WB Acknowledge
194
//
195
always @(posedge wb_clk_i or posedge wb_rst_i)
196 978 lampret
        if (wb_rst_i) begin
197
                delay <= #1 2'd3;
198
                prev_adr <= #1 32'h0000_0000;
199
        end
200
        else if (delay && (wb_adr_i == prev_adr) && wb_cyc_i && wb_stb_i)
201
                delay <= #1 delay - 2'd1;
202 1052 lampret
        else if (wb_ack_o || wb_err_o || (wb_adr_i != prev_adr) || ~wb_stb_i) begin
203
                delay <= #1 2'd2;       // delay ... can range from 3 to 0
204 978 lampret
                prev_adr <= #1 wb_adr_i;
205
        end
206 946 lampret
`else
207 978 lampret
assign delay = 2'd0;
208 946 lampret
`endif
209
 
210 1052 lampret
assign wb_ack_o = wb_cyc_i & wb_stb_i & ~wb_err & (delay == 2'd0)
211 946 lampret
`ifdef SRAM_GENERIC_REGISTERED
212 978 lampret
        & (wb_adr_i == prev_adr)
213
`endif
214
        ;
215
 
216
`ifdef SRAM_GENERIC_REGISTERED
217 946 lampret
//
218
// WB Error
219
//
220
always @(posedge wb_clk_i or posedge wb_rst_i)
221
        if (wb_rst_i)
222
                wb_err_o <= #1 1'b0;
223
        else
224
                wb_err_o <= #1 wb_err & !wb_err_o;
225
`else
226
assign wb_err_o = wb_err;
227
`endif
228
 
229
//
230 978 lampret
// SRAM i/f monitor
231 946 lampret
//
232
// synopsys translate_off
233
integer fsram;
234
initial fsram = $fopen("sram.log");
235
always @(posedge wb_clk_i)
236
        if (wb_cyc_i)
237
                if (wb_stb_i & wb_we_i) begin
238
                        if (wb_sel_i[3])
239
                                mem[{wb_adr_i[23:2], 2'b00}+0] = wb_dat_i[31:24];
240
                        if (wb_sel_i[2])
241
                                mem[{wb_adr_i[23:2], 2'b00}+1] = wb_dat_i[23:16];
242
                        if (wb_sel_i[1])
243
                                mem[{wb_adr_i[23:2], 2'b00}+2] = wb_dat_i[15:8];
244
                        if (wb_sel_i[0])
245
                                mem[{wb_adr_i[23:2], 2'b00}+3] = wb_dat_i[7:0];
246
                        $fdisplay(fsram, "%t [%h] <- write %h, byte sel %b", $time, wb_adr_i, wb_dat_i, wb_sel_i);
247
                end else if (wb_ack_o)
248
                        $fdisplay(fsram, "%t [%h] -> read %h", $time, wb_adr_i, wb_dat_o);
249
// synopsys translate_on
250
 
251
endmodule
252
 
253
`else
254
 
255
module sram_top (
256
  wb_clk_i, wb_rst_i,
257
 
258
  wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
259
  wb_stb_i, wb_ack_o, wb_err_o,
260
 
261
  r_cen, r0_wen, r1_wen, r_oen, r_a, r_d_i, r_d_o, d_oe,
262
  l_cen, l0_wen, l1_wen, l_oen, l_a, l_d_i, l_d_o
263
);
264
 
265
//
266
// Paraneters
267
//
268
parameter               aw = 19;
269
 
270
//
271
// I/O Ports
272
//
273
input                   wb_clk_i;
274
input                   wb_rst_i;
275
 
276
//
277
// WB slave i/f
278
//
279
input   [31:0]           wb_dat_i;
280
output  [31:0]           wb_dat_o;
281
input   [31:0]           wb_adr_i;
282
input   [3:0]            wb_sel_i;
283
input                   wb_we_i;
284
input                   wb_cyc_i;
285
input                   wb_stb_i;
286
output                  wb_ack_o;
287
output                  wb_err_o;
288
 
289
//
290
// Right SRAM bank
291
//
292
output                  r_oen;
293
output                  r0_wen;
294
output                  r1_wen;
295
output                  r_cen;
296
input   [15:0]           r_d_i;
297
output  [15:0]           r_d_o;
298
output  [aw-1:0] r_a;
299
 
300
//
301
// Left SRAM bank
302
//
303
output                  l_oen;
304
output                  l0_wen;
305
output                  l1_wen;
306
output                  l_cen;
307
input   [15:0]           l_d_i;
308
output  [15:0]           l_d_o;
309
output  [aw-1:0] l_a;
310
 
311
//
312
// Common SRAM signals
313
//
314
output                  d_oe;
315
 
316
//
317 746 lampret
// Internal regs and wires
318
//
319
reg     [15:0]           r_data;
320
reg     [15:0]           l_data;
321
reg                     l0_wen;
322
wire                    l1_wen = l0_wen;
323
reg                     r0_wen;
324
wire                    r1_wen = r0_wen;
325
reg     [31:0]           latch_data;
326
reg                     ack_we;
327
wire                    l_oe;
328
wire                    r_oe;
329
wire                    r_ack;
330
reg                     Mux;
331
reg     [aw-1:0] LatchedAddr;
332
reg     [15:0]           l_read;
333
reg     [15:0]           r_read;
334
reg                     d_oe;
335
reg     [15:0]           l_mux;
336
reg     [15:0]           r_mux;
337
 
338
//
339
// Aliases and simple assignments
340
//
341
assign wb_dat_o = {r_d_i, l_d_i};
342
assign l_oen = ~l_oe;
343
assign r_oen = ~r_oe;
344
assign l_a = Mux ? LatchedAddr : wb_adr_i[aw+1:2];
345
assign r_a = l_a;
346
assign l_d_o = l_mux;
347
assign r_d_o = r_mux;
348
assign l_oe = wb_cyc_i & wb_stb_i & l0_wen;
349
assign r_oe = wb_cyc_i & wb_stb_i & r0_wen;
350
assign l_cen = ~(wb_cyc_i & wb_stb_i);
351
assign r_cen = l_cen;
352 1193 dries
assign wb_ack_o = (wb_cyc_i & wb_stb_i & ~wb_err_o & ~wb_we_i) | ack_we;
353 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)
354
 
355
//
356
// RMW mux control
357
//
358
always @ (negedge wb_clk_i or posedge wb_rst_i)
359
begin
360
  if (wb_rst_i)
361
    Mux <= 1'b0;
362
  else
363
  if (ack_we)
364
    Mux <= #1 1'b1;
365
  else
366
    Mux <= #1 1'b0;
367
end
368
 
369
//
370
// Latch address
371
//
372
always @ (negedge wb_clk_i or posedge wb_rst_i)
373
begin
374
  if (wb_rst_i)
375
    LatchedAddr <= 'h0;
376
  else
377
  if (wb_cyc_i & wb_stb_i)
378
    LatchedAddr <= #1 wb_adr_i[aw+1:2];
379
end
380
 
381
//
382
// Latch data from RAM (read data)
383
//
384
always @ (posedge wb_clk_i or posedge wb_rst_i)
385
begin
386
  if (wb_rst_i)
387
    begin
388
      l_read <= 16'h0;
389
      r_read <= 16'h0;
390
    end
391
  else
392
  if (wb_cyc_i & wb_stb_i)
393
    begin
394
      l_read <= #1 l_d_i[15:0];
395
      r_read <= #1 r_d_i[15:0];
396
    end
397
end
398
 
399
//
400
// Mux and latch data for writing left SRAM bank (bytes 0 and 1)
401
//
402
always @ (negedge wb_clk_i or posedge wb_rst_i)
403
begin
404
  if (wb_rst_i)
405
    l_mux <= 16'h0;
406
  else
407
  if (~l0_wen)
408
    begin
409
      if (wb_sel_i[0])
410
        l_mux[7:0]  <= #1 wb_dat_i[7:0];
411
      else
412
        l_mux[7:0]  <= #1 l_read[7:0];
413
      if (wb_sel_i[1])
414
        l_mux[15:8] <= #1 wb_dat_i[15:8];
415
      else
416
        l_mux[15:8] <= #1 l_read[15:8];
417
    end
418
  else
419
    l_mux[15:0]  <= #1 16'hz;
420
end
421
 
422
//
423
// Mux and latch data for writing right SRAM bank (bytes 2 and 3)
424
//
425
always @ (negedge wb_clk_i or posedge wb_rst_i)
426
begin
427
  if (wb_rst_i)
428
    r_mux <= 16'h0;
429
  else
430
  if (~r0_wen)
431
    begin
432
      if (wb_sel_i[2])
433
        r_mux[7:0]  <= #1 wb_dat_i[23:16];
434
      else
435
        r_mux[7:0]  <= #1 r_read[7:0];
436
      if (wb_sel_i[3])
437
        r_mux[15:8]  <= #1 wb_dat_i[31:24];
438
      else
439
        r_mux[15:8]  <= #1 r_read[15:8];
440
    end
441
  else
442
    r_mux <= #1 16'hz;
443
end
444
 
445
//
446
// Left WE
447
//
448
always @ (posedge wb_clk_i or posedge wb_rst_i)
449
begin
450
  if (wb_rst_i)
451
    l0_wen <= 1'b1;
452
  else
453
  if (wb_cyc_i & wb_stb_i & wb_we_i & (|wb_sel_i[1:0]) & ~wb_ack_o)
454
    l0_wen <= #1 1'b0;
455
  else
456
    l0_wen <= #1 1'b1;
457
end
458
 
459
//
460
// Right WE
461
//
462
always @ (posedge wb_clk_i or posedge wb_rst_i)
463
begin
464
  if (wb_rst_i)
465
    r0_wen <= 1'b1;
466
  else
467
  if (wb_cyc_i & wb_stb_i & wb_we_i & (|wb_sel_i[3:2]) & ~wb_ack_o)
468
    r0_wen <= #1 1'b0;
469
  else
470
    r0_wen <= #1 1'b1;
471
end
472
 
473
//
474
// Write acknowledge
475
//
476
always @ (posedge wb_clk_i or posedge wb_rst_i)
477
begin
478
  if (wb_rst_i)
479
    ack_we <= 1'b0;
480
  else
481
  if (wb_cyc_i & wb_stb_i & wb_we_i & ~ack_we)
482
    ack_we <= #1 1'b1;
483
  else
484
    ack_we <= #1 1'b0;
485
end
486
 
487
//
488
// Generate d_oe signal (tristate control)
489
//
490
always @ (negedge wb_clk_i or posedge wb_rst_i)
491
begin
492
  if (wb_rst_i)
493
    d_oe <= 1'b0;
494
  else
495
  if (~l0_wen | ~r0_wen)
496
    d_oe <= 1'b1;
497
  else
498
    d_oe <= 1'b0;
499
end
500
 
501
//
502
// SRAM i/f monitor
503
//
504
// synopsys translate_off
505
integer fsram;
506
initial fsram = $fopen("sram.log");
507
always @(posedge wb_clk_i)
508
begin
509
  if (~l0_wen | ~r0_wen)
510
    $fdisplay(fsram, "%t [%h] <- write %h", $time, wb_adr_i, {r_d_o, l_d_o});
511
  else
512
  if ((l_oe | r_oe) & ~wb_we_i)
513
    $fdisplay(fsram, "%t [%h] -> read %h", $time, wb_adr_i, {r_d_i, l_d_i});
514
end
515
// synopsys translate_on
516
 
517
endmodule
518 946 lampret
 
519
`endif

powered by: WebSVN 2.1.0

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