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 978

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

powered by: WebSVN 2.1.0

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