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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1200/] [rtl/] [verilog/] [or1200_qmem_top.v] - Blame information for rev 249

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 unneback
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OR1200's Embedded Memory                                    ////
4
////                                                              ////
5
////  This file is part of the OpenRISC 1200 project              ////
6
////  http://www.opencores.org/cores/or1k/                        ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Embedded Memory               .                             ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////   - QMEM and IC/DC muxes can be removed except for cycstb    ////
13
////     (now are is there for easier debugging)                  ////
14
////   - currently arbitration is slow and stores take 2 clocks   ////
15
////     (final debugged version will be faster)                  ////
16
////                                                              ////
17
////  Author(s):                                                  ////
18
////      - Damjan Lampret, lampret@opencores.org                 ////
19
////                                                              ////
20
//////////////////////////////////////////////////////////////////////
21
////                                                              ////
22
//// Copyright (C) 2003 Authors and OPENCORES.ORG                 ////
23
////                                                              ////
24
//// This source file may be used and distributed without         ////
25
//// restriction provided that this copyright statement is not    ////
26
//// removed from the file and that any derivative work contains  ////
27
//// the original copyright notice and the associated disclaimer. ////
28
////                                                              ////
29
//// This source file is free software; you can redistribute it   ////
30
//// and/or modify it under the terms of the GNU Lesser General   ////
31
//// Public License as published by the Free Software Foundation; ////
32
//// either version 2.1 of the License, or (at your option) any   ////
33
//// later version.                                               ////
34
////                                                              ////
35
//// This source is distributed in the hope that it will be       ////
36
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
37
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
38
//// PURPOSE.  See the GNU Lesser General Public License for more ////
39
//// details.                                                     ////
40
////                                                              ////
41
//// You should have received a copy of the GNU Lesser General    ////
42
//// Public License along with this source; if not, download it   ////
43
//// from http://www.opencores.org/lgpl.shtml                     ////
44
////                                                              ////
45
//////////////////////////////////////////////////////////////////////
46
//
47
// CVS Revision History
48
//
49 141 marcus.erl
// $Log: or1200_qmem_top.v,v $
50
// Revision 2.0  2010/06/30 11:00:00  ORSoC
51
// Minor update: 
52
// Coding style changed.
53
//
54
// Revision 1.3  2004/06/08 18:17:36  lampret
55
// Non-functional changes. Coding style fixes.
56
//
57 10 unneback
// Revision 1.2  2004/04/05 08:40:26  lampret
58
// Merged branch_qmem into main tree.
59
//
60
// Revision 1.1.2.4  2004/01/11 22:45:46  andreje
61
// Separate instruction and data QMEM decoders, QMEM acknowledge and byte-select added
62
//
63
// Revision 1.1.2.3  2003/12/17 13:36:58  simons
64
// Qmem mbist signals fixed.
65
//
66
// Revision 1.1.2.2  2003/12/09 11:46:48  simons
67
// Mbist nameing changed, Artisan ram instance signal names fixed, some synthesis waning fixed.
68
//
69
// Revision 1.1.2.1  2003/07/08 15:45:26  lampret
70
// Added embedded memory QMEM.
71
//
72
//
73
 
74
// synopsys translate_off
75
`include "timescale.v"
76
// synopsys translate_on
77
`include "or1200_defines.v"
78
 
79
`define OR1200_QMEMFSM_IDLE     3'd0
80
`define OR1200_QMEMFSM_STORE    3'd1
81
`define OR1200_QMEMFSM_LOAD     3'd2
82
`define OR1200_QMEMFSM_FETCH    3'd3
83
 
84
//
85
// Embedded memory
86
//
87
module or1200_qmem_top(
88
        // Rst, clk and clock control
89
        clk, rst,
90
 
91
`ifdef OR1200_BIST
92
        // RAM BIST
93
        mbist_si_i, mbist_so_o, mbist_ctrl_i,
94
`endif
95
 
96
        // QMEM and CPU/IMMU
97
        qmemimmu_adr_i,
98
        qmemimmu_cycstb_i,
99
        qmemimmu_ci_i,
100 141 marcus.erl
        qmemicpu_sel_i,
101
        qmemicpu_tag_i,
102 10 unneback
        qmemicpu_dat_o,
103
        qmemicpu_ack_o,
104
        qmemimmu_rty_o,
105
        qmemimmu_err_o,
106
        qmemimmu_tag_o,
107
 
108
        // QMEM and IC
109
        icqmem_adr_o,
110
        icqmem_cycstb_o,
111 141 marcus.erl
        icqmem_ci_o,
112 10 unneback
        icqmem_sel_o,
113
        icqmem_tag_o,
114
        icqmem_dat_i,
115
        icqmem_ack_i,
116
        icqmem_rty_i,
117
        icqmem_err_i,
118
        icqmem_tag_i,
119
 
120
        // QMEM and CPU/DMMU
121
        qmemdmmu_adr_i,
122
        qmemdmmu_cycstb_i,
123
        qmemdmmu_ci_i,
124 141 marcus.erl
        qmemdcpu_we_i,
125
        qmemdcpu_sel_i,
126
        qmemdcpu_tag_i,
127
        qmemdcpu_dat_i,
128 10 unneback
        qmemdcpu_dat_o,
129
        qmemdcpu_ack_o,
130
        qmemdcpu_rty_o,
131
        qmemdmmu_err_o,
132
        qmemdmmu_tag_o,
133
 
134
        // QMEM and DC
135 141 marcus.erl
        dcqmem_adr_o,
136
        dcqmem_cycstb_o,
137
        dcqmem_ci_o,
138
        dcqmem_we_o,
139
        dcqmem_sel_o,
140
        dcqmem_tag_o,
141
        dcqmem_dat_o,
142
        dcqmem_dat_i,
143
        dcqmem_ack_i,
144
        dcqmem_rty_i,
145
        dcqmem_err_i,
146
        dcqmem_tag_i
147 10 unneback
 
148
);
149
 
150
parameter dw = `OR1200_OPERAND_WIDTH;
151
 
152
//
153
// I/O
154
//
155
 
156
//
157
// Clock and reset
158
//
159
input                           clk;
160
input                           rst;
161
 
162
`ifdef OR1200_BIST
163
//
164
// RAM BIST
165
//
166
input mbist_si_i;
167
input [`OR1200_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i;
168
output mbist_so_o;
169
`endif
170
 
171
//
172
// QMEM and CPU/IMMU
173
//
174
input   [31:0]                   qmemimmu_adr_i;
175
input                           qmemimmu_cycstb_i;
176
input                           qmemimmu_ci_i;
177 141 marcus.erl
input   [3:0]                    qmemicpu_sel_i;
178
input   [3:0]                    qmemicpu_tag_i;
179 10 unneback
output  [31:0]                   qmemicpu_dat_o;
180
output                          qmemicpu_ack_o;
181
output                          qmemimmu_rty_o;
182
output                          qmemimmu_err_o;
183
output  [3:0]                    qmemimmu_tag_o;
184
 
185
//
186
// QMEM and IC
187
//
188
output  [31:0]                   icqmem_adr_o;
189
output                          icqmem_cycstb_o;
190
output                          icqmem_ci_o;
191
output  [3:0]                    icqmem_sel_o;
192
output  [3:0]                    icqmem_tag_o;
193
input   [31:0]                   icqmem_dat_i;
194
input                           icqmem_ack_i;
195
input                           icqmem_rty_i;
196
input                           icqmem_err_i;
197
input   [3:0]                    icqmem_tag_i;
198
 
199
//
200
// QMEM and CPU/DMMU
201
//
202
input   [31:0]                   qmemdmmu_adr_i;
203
input                           qmemdmmu_cycstb_i;
204
input                           qmemdmmu_ci_i;
205
input                           qmemdcpu_we_i;
206 141 marcus.erl
input   [3:0]                    qmemdcpu_sel_i;
207
input   [3:0]                    qmemdcpu_tag_i;
208
input   [31:0]                   qmemdcpu_dat_i;
209 10 unneback
output  [31:0]                   qmemdcpu_dat_o;
210
output                          qmemdcpu_ack_o;
211
output                          qmemdcpu_rty_o;
212
output                          qmemdmmu_err_o;
213
output  [3:0]                    qmemdmmu_tag_o;
214
 
215
//
216
// QMEM and DC
217
//
218
output  [31:0]                   dcqmem_adr_o;
219
output                          dcqmem_cycstb_o;
220
output                          dcqmem_ci_o;
221
output                          dcqmem_we_o;
222
output  [3:0]                    dcqmem_sel_o;
223
output  [3:0]                    dcqmem_tag_o;
224
output  [dw-1:0]         dcqmem_dat_o;
225
input   [dw-1:0]         dcqmem_dat_i;
226
input                           dcqmem_ack_i;
227
input                           dcqmem_rty_i;
228
input                           dcqmem_err_i;
229
input   [3:0]                    dcqmem_tag_i;
230
 
231
`ifdef OR1200_QMEM_IMPLEMENTED
232
 
233
//
234
// Internal regs and wires
235
//
236
wire                            iaddr_qmem_hit;
237
wire                            daddr_qmem_hit;
238
reg     [2:0]                    state;
239
reg                             qmem_dack;
240
reg                             qmem_iack;
241
wire    [31:0]                   qmem_di;
242
wire    [31:0]                   qmem_do;
243
wire                            qmem_en;
244
wire                            qmem_we;
245
`ifdef OR1200_QMEM_BSEL
246
wire  [3:0]       qmem_sel;
247
`endif
248
wire    [31:0]                   qmem_addr;
249
`ifdef OR1200_QMEM_ACK
250
wire              qmem_ack;
251
`else
252
wire              qmem_ack = 1'b1;
253
`endif
254
 
255
//
256
// QMEM and CPU/IMMU
257
//
258
assign qmemicpu_dat_o = qmem_iack ? qmem_do : icqmem_dat_i;
259
assign qmemicpu_ack_o = qmem_iack ? 1'b1 : icqmem_ack_i;
260
assign qmemimmu_rty_o = qmem_iack ? 1'b0 : icqmem_rty_i;
261
assign qmemimmu_err_o = qmem_iack ? 1'b0 : icqmem_err_i;
262
assign qmemimmu_tag_o = qmem_iack ? 4'h0 : icqmem_tag_i;
263
 
264
//
265
// QMEM and IC
266
//
267
assign icqmem_adr_o = iaddr_qmem_hit ? 32'h0000_0000 : qmemimmu_adr_i;
268
assign icqmem_cycstb_o = iaddr_qmem_hit ? 1'b0 : qmemimmu_cycstb_i;
269
assign icqmem_ci_o = iaddr_qmem_hit ? 1'b0 : qmemimmu_ci_i;
270
assign icqmem_sel_o = iaddr_qmem_hit ? 4'h0 : qmemicpu_sel_i;
271
assign icqmem_tag_o = iaddr_qmem_hit ? 4'h0 : qmemicpu_tag_i;
272
 
273
//
274
// QMEM and CPU/DMMU
275
//
276
assign qmemdcpu_dat_o = daddr_qmem_hit ? qmem_do : dcqmem_dat_i;
277
assign qmemdcpu_ack_o = daddr_qmem_hit ? qmem_dack : dcqmem_ack_i;
278
assign qmemdcpu_rty_o = daddr_qmem_hit ? ~qmem_dack : dcqmem_rty_i;
279
assign qmemdmmu_err_o = daddr_qmem_hit ? 1'b0 : dcqmem_err_i;
280
assign qmemdmmu_tag_o = daddr_qmem_hit ? 4'h0 : dcqmem_tag_i;
281
 
282
//
283
// QMEM and DC
284
//
285
assign dcqmem_adr_o = daddr_qmem_hit ? 32'h0000_0000 : qmemdmmu_adr_i;
286
assign dcqmem_cycstb_o = daddr_qmem_hit ? 1'b0 : qmemdmmu_cycstb_i;
287
assign dcqmem_ci_o = daddr_qmem_hit ? 1'b0 : qmemdmmu_ci_i;
288
assign dcqmem_we_o = daddr_qmem_hit ? 1'b0 : qmemdcpu_we_i;
289
assign dcqmem_sel_o = daddr_qmem_hit ? 4'h0 : qmemdcpu_sel_i;
290
assign dcqmem_tag_o = daddr_qmem_hit ? 4'h0 : qmemdcpu_tag_i;
291
assign dcqmem_dat_o = daddr_qmem_hit ? 32'h0000_0000 : qmemdcpu_dat_i;
292
 
293
//
294
// Address comparison whether QMEM was hit
295
//
296
`ifdef OR1200_QMEM_IADDR
297
assign iaddr_qmem_hit = (qmemimmu_adr_i & `OR1200_QMEM_IMASK) == `OR1200_QMEM_IADDR;
298
`else
299
assign iaddr_qmem_hit = 1'b0;
300
`endif
301
 
302
`ifdef OR1200_QMEM_DADDR
303
assign daddr_qmem_hit = (qmemdmmu_adr_i & `OR1200_QMEM_DMASK) == `OR1200_QMEM_DADDR;
304
`else
305
assign daddr_qmem_hit = 1'b0;
306
`endif
307
 
308
//
309
//
310
//
311
assign qmem_en = iaddr_qmem_hit & qmemimmu_cycstb_i | daddr_qmem_hit & qmemdmmu_cycstb_i;
312
assign qmem_we = qmemdmmu_cycstb_i & daddr_qmem_hit & qmemdcpu_we_i;
313
`ifdef OR1200_QMEM_BSEL
314
assign qmem_sel = (qmemdmmu_cycstb_i & daddr_qmem_hit) ? qmemdcpu_sel_i : qmemicpu_sel_i;
315
`endif
316
assign qmem_di = qmemdcpu_dat_i;
317
assign qmem_addr = (qmemdmmu_cycstb_i & daddr_qmem_hit) ? qmemdmmu_adr_i : qmemimmu_adr_i;
318
 
319
//
320
// QMEM control FSM
321
//
322
always @(posedge rst or posedge clk)
323
        if (rst) begin
324
                state <= #1 `OR1200_QMEMFSM_IDLE;
325
                qmem_dack <= #1 1'b0;
326
                qmem_iack <= #1 1'b0;
327
        end
328
        else case (state)       // synopsys parallel_case
329
                `OR1200_QMEMFSM_IDLE: begin
330
                        if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmemdcpu_we_i & qmem_ack) begin
331
                                state <= #1 `OR1200_QMEMFSM_STORE;
332
                                qmem_dack <= #1 1'b1;
333
                                qmem_iack <= #1 1'b0;
334
                        end
335
                        else if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmem_ack) begin
336
                                state <= #1 `OR1200_QMEMFSM_LOAD;
337
                                qmem_dack <= #1 1'b1;
338
                                qmem_iack <= #1 1'b0;
339
                        end
340
                        else if (qmemimmu_cycstb_i & iaddr_qmem_hit & qmem_ack) begin
341
                                state <= #1 `OR1200_QMEMFSM_FETCH;
342
                                qmem_iack <= #1 1'b1;
343
                                qmem_dack <= #1 1'b0;
344
                        end
345
                end
346
                `OR1200_QMEMFSM_STORE: begin
347
                        if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmemdcpu_we_i & qmem_ack) begin
348
                                state <= #1 `OR1200_QMEMFSM_STORE;
349
                                qmem_dack <= #1 1'b1;
350
                                qmem_iack <= #1 1'b0;
351
                        end
352
                        else if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmem_ack) begin
353
                                state <= #1 `OR1200_QMEMFSM_LOAD;
354
                                qmem_dack <= #1 1'b1;
355
                                qmem_iack <= #1 1'b0;
356
                        end
357
                        else if (qmemimmu_cycstb_i & iaddr_qmem_hit & qmem_ack) begin
358
                                state <= #1 `OR1200_QMEMFSM_FETCH;
359
                                qmem_iack <= #1 1'b1;
360
                                qmem_dack <= #1 1'b0;
361
                        end
362
                        else begin
363
                                state <= #1 `OR1200_QMEMFSM_IDLE;
364
                                qmem_dack <= #1 1'b0;
365
                                qmem_iack <= #1 1'b0;
366
                        end
367
                end
368
                `OR1200_QMEMFSM_LOAD: begin
369
                        if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmemdcpu_we_i & qmem_ack) begin
370
                                state <= #1 `OR1200_QMEMFSM_STORE;
371
                                qmem_dack <= #1 1'b1;
372
                                qmem_iack <= #1 1'b0;
373
                        end
374
                        else if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmem_ack) begin
375
                                state <= #1 `OR1200_QMEMFSM_LOAD;
376
                                qmem_dack <= #1 1'b1;
377
                                qmem_iack <= #1 1'b0;
378
                        end
379
                        else if (qmemimmu_cycstb_i & iaddr_qmem_hit & qmem_ack) begin
380
                                state <= #1 `OR1200_QMEMFSM_FETCH;
381
                                qmem_iack <= #1 1'b1;
382
                                qmem_dack <= #1 1'b0;
383
                        end
384
                        else begin
385
                                state <= #1 `OR1200_QMEMFSM_IDLE;
386
                                qmem_dack <= #1 1'b0;
387
                                qmem_iack <= #1 1'b0;
388
                        end
389
                end
390
                `OR1200_QMEMFSM_FETCH: begin
391
                        if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmemdcpu_we_i & qmem_ack) begin
392
                                state <= #1 `OR1200_QMEMFSM_STORE;
393
                                qmem_dack <= #1 1'b1;
394
                                qmem_iack <= #1 1'b0;
395
                        end
396
                        else if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmem_ack) begin
397
                                state <= #1 `OR1200_QMEMFSM_LOAD;
398
                                qmem_dack <= #1 1'b1;
399
                                qmem_iack <= #1 1'b0;
400
                        end
401
                        else if (qmemimmu_cycstb_i & iaddr_qmem_hit & qmem_ack) begin
402
                                state <= #1 `OR1200_QMEMFSM_FETCH;
403
                                qmem_iack <= #1 1'b1;
404
                                qmem_dack <= #1 1'b0;
405
                        end
406
                        else begin
407
                                state <= #1 `OR1200_QMEMFSM_IDLE;
408
                                qmem_dack <= #1 1'b0;
409
                                qmem_iack <= #1 1'b0;
410
                        end
411
                end
412
                default: begin
413
                        state <= #1 `OR1200_QMEMFSM_IDLE;
414
                        qmem_dack <= #1 1'b0;
415
                        qmem_iack <= #1 1'b0;
416
                end
417
        endcase
418
 
419
//
420
// Instantiation of embedded memory
421
//
422
or1200_spram_2048x32 or1200_qmem_ram(
423
        .clk(clk),
424
        .rst(rst),
425
`ifdef OR1200_BIST
426
        // RAM BIST
427
        .mbist_si_i(mbist_si_i),
428
        .mbist_so_o(mbist_so_o),
429
        .mbist_ctrl_i(mbist_ctrl_i),
430
`endif
431
        .addr(qmem_addr[12:2]),
432
`ifdef OR1200_QMEM_BSEL
433
        .sel(qmem_sel),
434
`endif
435
`ifdef OR1200_QMEM_ACK
436
  .ack(qmem_ack),
437
`endif
438
  .ce(qmem_en),
439
        .we(qmem_we),
440
        .oe(1'b1),
441
        .di(qmem_di),
442
        .doq(qmem_do)
443
);
444
 
445
`else  // OR1200_QMEM_IMPLEMENTED
446
 
447
//
448
// QMEM and CPU/IMMU
449
//
450
assign qmemicpu_dat_o = icqmem_dat_i;
451
assign qmemicpu_ack_o = icqmem_ack_i;
452
assign qmemimmu_rty_o = icqmem_rty_i;
453
assign qmemimmu_err_o = icqmem_err_i;
454
assign qmemimmu_tag_o = icqmem_tag_i;
455
 
456
//
457
// QMEM and IC
458
//
459
assign icqmem_adr_o = qmemimmu_adr_i;
460
assign icqmem_cycstb_o = qmemimmu_cycstb_i;
461
assign icqmem_ci_o = qmemimmu_ci_i;
462
assign icqmem_sel_o = qmemicpu_sel_i;
463
assign icqmem_tag_o = qmemicpu_tag_i;
464
 
465
//
466
// QMEM and CPU/DMMU
467
//
468
assign qmemdcpu_dat_o = dcqmem_dat_i;
469
assign qmemdcpu_ack_o = dcqmem_ack_i;
470
assign qmemdcpu_rty_o = dcqmem_rty_i;
471
assign qmemdmmu_err_o = dcqmem_err_i;
472
assign qmemdmmu_tag_o = dcqmem_tag_i;
473
 
474
//
475
// QMEM and DC
476
//
477
assign dcqmem_adr_o = qmemdmmu_adr_i;
478
assign dcqmem_cycstb_o = qmemdmmu_cycstb_i;
479
assign dcqmem_ci_o = qmemdmmu_ci_i;
480
assign dcqmem_we_o = qmemdcpu_we_i;
481
assign dcqmem_sel_o = qmemdcpu_sel_i;
482
assign dcqmem_tag_o = qmemdcpu_tag_i;
483
assign dcqmem_dat_o = qmemdcpu_dat_i;
484
 
485
`ifdef OR1200_BIST
486
assign mbist_so_o = mbist_si_i;
487
`endif
488
 
489
`endif
490
 
491
endmodule

powered by: WebSVN 2.1.0

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