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 136

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
// $Log: not supported by cvs2svn $
50
// Revision 1.2  2004/04/05 08:40:26  lampret
51
// Merged branch_qmem into main tree.
52
//
53
// Revision 1.1.2.4  2004/01/11 22:45:46  andreje
54
// Separate instruction and data QMEM decoders, QMEM acknowledge and byte-select added
55
//
56
// Revision 1.1.2.3  2003/12/17 13:36:58  simons
57
// Qmem mbist signals fixed.
58
//
59
// Revision 1.1.2.2  2003/12/09 11:46:48  simons
60
// Mbist nameing changed, Artisan ram instance signal names fixed, some synthesis waning fixed.
61
//
62
// Revision 1.1.2.1  2003/07/08 15:45:26  lampret
63
// Added embedded memory QMEM.
64
//
65
//
66
 
67
// synopsys translate_off
68
`include "timescale.v"
69
// synopsys translate_on
70
`include "or1200_defines.v"
71
 
72
`define OR1200_QMEMFSM_IDLE     3'd0
73
`define OR1200_QMEMFSM_STORE    3'd1
74
`define OR1200_QMEMFSM_LOAD     3'd2
75
`define OR1200_QMEMFSM_FETCH    3'd3
76
 
77
//
78
// Embedded memory
79
//
80
module or1200_qmem_top(
81
        // Rst, clk and clock control
82
        clk, rst,
83
 
84
`ifdef OR1200_BIST
85
        // RAM BIST
86
        mbist_si_i, mbist_so_o, mbist_ctrl_i,
87
`endif
88
 
89
        // QMEM and CPU/IMMU
90
        qmemimmu_adr_i,
91
        qmemimmu_cycstb_i,
92
        qmemimmu_ci_i,
93
        qmemicpu_sel_i,
94
        qmemicpu_tag_i,
95
        qmemicpu_dat_o,
96
        qmemicpu_ack_o,
97
        qmemimmu_rty_o,
98
        qmemimmu_err_o,
99
        qmemimmu_tag_o,
100
 
101
        // QMEM and IC
102
        icqmem_adr_o,
103
        icqmem_cycstb_o,
104
        icqmem_ci_o,
105
        icqmem_sel_o,
106
        icqmem_tag_o,
107
        icqmem_dat_i,
108
        icqmem_ack_i,
109
        icqmem_rty_i,
110
        icqmem_err_i,
111
        icqmem_tag_i,
112
 
113
        // QMEM and CPU/DMMU
114
        qmemdmmu_adr_i,
115
        qmemdmmu_cycstb_i,
116
        qmemdmmu_ci_i,
117
        qmemdcpu_we_i,
118
        qmemdcpu_sel_i,
119
        qmemdcpu_tag_i,
120
        qmemdcpu_dat_i,
121
        qmemdcpu_dat_o,
122
        qmemdcpu_ack_o,
123
        qmemdcpu_rty_o,
124
        qmemdmmu_err_o,
125
        qmemdmmu_tag_o,
126
 
127
        // QMEM and DC
128
        dcqmem_adr_o, dcqmem_cycstb_o, dcqmem_ci_o,
129
        dcqmem_we_o, dcqmem_sel_o, dcqmem_tag_o, dcqmem_dat_o,
130
        dcqmem_dat_i, dcqmem_ack_i, dcqmem_rty_i, dcqmem_err_i, dcqmem_tag_i
131
 
132
);
133
 
134
parameter dw = `OR1200_OPERAND_WIDTH;
135
 
136
//
137
// I/O
138
//
139
 
140
//
141
// Clock and reset
142
//
143
input                           clk;
144
input                           rst;
145
 
146
`ifdef OR1200_BIST
147
//
148
// RAM BIST
149
//
150
input mbist_si_i;
151
input [`OR1200_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i;
152
output mbist_so_o;
153
`endif
154
 
155
//
156
// QMEM and CPU/IMMU
157
//
158
input   [31:0]                   qmemimmu_adr_i;
159
input                           qmemimmu_cycstb_i;
160
input                           qmemimmu_ci_i;
161
input   [3:0]                    qmemicpu_sel_i;
162
input   [3:0]                    qmemicpu_tag_i;
163
output  [31:0]                   qmemicpu_dat_o;
164
output                          qmemicpu_ack_o;
165
output                          qmemimmu_rty_o;
166
output                          qmemimmu_err_o;
167
output  [3:0]                    qmemimmu_tag_o;
168
 
169
//
170
// QMEM and IC
171
//
172
output  [31:0]                   icqmem_adr_o;
173
output                          icqmem_cycstb_o;
174
output                          icqmem_ci_o;
175
output  [3:0]                    icqmem_sel_o;
176
output  [3:0]                    icqmem_tag_o;
177
input   [31:0]                   icqmem_dat_i;
178
input                           icqmem_ack_i;
179
input                           icqmem_rty_i;
180
input                           icqmem_err_i;
181
input   [3:0]                    icqmem_tag_i;
182
 
183
//
184
// QMEM and CPU/DMMU
185
//
186
input   [31:0]                   qmemdmmu_adr_i;
187
input                           qmemdmmu_cycstb_i;
188
input                           qmemdmmu_ci_i;
189
input                           qmemdcpu_we_i;
190
input   [3:0]                    qmemdcpu_sel_i;
191
input   [3:0]                    qmemdcpu_tag_i;
192
input   [31:0]                   qmemdcpu_dat_i;
193
output  [31:0]                   qmemdcpu_dat_o;
194
output                          qmemdcpu_ack_o;
195
output                          qmemdcpu_rty_o;
196
output                          qmemdmmu_err_o;
197
output  [3:0]                    qmemdmmu_tag_o;
198
 
199
//
200
// QMEM and DC
201
//
202
output  [31:0]                   dcqmem_adr_o;
203
output                          dcqmem_cycstb_o;
204
output                          dcqmem_ci_o;
205
output                          dcqmem_we_o;
206
output  [3:0]                    dcqmem_sel_o;
207
output  [3:0]                    dcqmem_tag_o;
208
output  [dw-1:0]         dcqmem_dat_o;
209
input   [dw-1:0]         dcqmem_dat_i;
210
input                           dcqmem_ack_i;
211
input                           dcqmem_rty_i;
212
input                           dcqmem_err_i;
213
input   [3:0]                    dcqmem_tag_i;
214
 
215
`ifdef OR1200_QMEM_IMPLEMENTED
216
 
217
//
218
// Internal regs and wires
219
//
220
wire                            iaddr_qmem_hit;
221
wire                            daddr_qmem_hit;
222
reg     [2:0]                    state;
223
reg                             qmem_dack;
224
reg                             qmem_iack;
225
wire    [31:0]                   qmem_di;
226
wire    [31:0]                   qmem_do;
227
wire                            qmem_en;
228
wire                            qmem_we;
229
`ifdef OR1200_QMEM_BSEL
230
wire  [3:0]       qmem_sel;
231
`endif
232
wire    [31:0]                   qmem_addr;
233
`ifdef OR1200_QMEM_ACK
234
wire              qmem_ack;
235
`else
236
wire              qmem_ack = 1'b1;
237
`endif
238
 
239
//
240
// QMEM and CPU/IMMU
241
//
242
assign qmemicpu_dat_o = qmem_iack ? qmem_do : icqmem_dat_i;
243
assign qmemicpu_ack_o = qmem_iack ? 1'b1 : icqmem_ack_i;
244
assign qmemimmu_rty_o = qmem_iack ? 1'b0 : icqmem_rty_i;
245
assign qmemimmu_err_o = qmem_iack ? 1'b0 : icqmem_err_i;
246
assign qmemimmu_tag_o = qmem_iack ? 4'h0 : icqmem_tag_i;
247
 
248
//
249
// QMEM and IC
250
//
251
assign icqmem_adr_o = iaddr_qmem_hit ? 32'h0000_0000 : qmemimmu_adr_i;
252
assign icqmem_cycstb_o = iaddr_qmem_hit ? 1'b0 : qmemimmu_cycstb_i;
253
assign icqmem_ci_o = iaddr_qmem_hit ? 1'b0 : qmemimmu_ci_i;
254
assign icqmem_sel_o = iaddr_qmem_hit ? 4'h0 : qmemicpu_sel_i;
255
assign icqmem_tag_o = iaddr_qmem_hit ? 4'h0 : qmemicpu_tag_i;
256
 
257
//
258
// QMEM and CPU/DMMU
259
//
260
assign qmemdcpu_dat_o = daddr_qmem_hit ? qmem_do : dcqmem_dat_i;
261
assign qmemdcpu_ack_o = daddr_qmem_hit ? qmem_dack : dcqmem_ack_i;
262
assign qmemdcpu_rty_o = daddr_qmem_hit ? ~qmem_dack : dcqmem_rty_i;
263
assign qmemdmmu_err_o = daddr_qmem_hit ? 1'b0 : dcqmem_err_i;
264
assign qmemdmmu_tag_o = daddr_qmem_hit ? 4'h0 : dcqmem_tag_i;
265
 
266
//
267
// QMEM and DC
268
//
269
assign dcqmem_adr_o = daddr_qmem_hit ? 32'h0000_0000 : qmemdmmu_adr_i;
270
assign dcqmem_cycstb_o = daddr_qmem_hit ? 1'b0 : qmemdmmu_cycstb_i;
271
assign dcqmem_ci_o = daddr_qmem_hit ? 1'b0 : qmemdmmu_ci_i;
272
assign dcqmem_we_o = daddr_qmem_hit ? 1'b0 : qmemdcpu_we_i;
273
assign dcqmem_sel_o = daddr_qmem_hit ? 4'h0 : qmemdcpu_sel_i;
274
assign dcqmem_tag_o = daddr_qmem_hit ? 4'h0 : qmemdcpu_tag_i;
275
assign dcqmem_dat_o = daddr_qmem_hit ? 32'h0000_0000 : qmemdcpu_dat_i;
276
 
277
//
278
// Address comparison whether QMEM was hit
279
//
280
`ifdef OR1200_QMEM_IADDR
281
assign iaddr_qmem_hit = (qmemimmu_adr_i & `OR1200_QMEM_IMASK) == `OR1200_QMEM_IADDR;
282
`else
283
assign iaddr_qmem_hit = 1'b0;
284
`endif
285
 
286
`ifdef OR1200_QMEM_DADDR
287
assign daddr_qmem_hit = (qmemdmmu_adr_i & `OR1200_QMEM_DMASK) == `OR1200_QMEM_DADDR;
288
`else
289
assign daddr_qmem_hit = 1'b0;
290
`endif
291
 
292
//
293
//
294
//
295
assign qmem_en = iaddr_qmem_hit & qmemimmu_cycstb_i | daddr_qmem_hit & qmemdmmu_cycstb_i;
296
assign qmem_we = qmemdmmu_cycstb_i & daddr_qmem_hit & qmemdcpu_we_i;
297
`ifdef OR1200_QMEM_BSEL
298
assign qmem_sel = (qmemdmmu_cycstb_i & daddr_qmem_hit) ? qmemdcpu_sel_i : qmemicpu_sel_i;
299
`endif
300
assign qmem_di = qmemdcpu_dat_i;
301
assign qmem_addr = (qmemdmmu_cycstb_i & daddr_qmem_hit) ? qmemdmmu_adr_i : qmemimmu_adr_i;
302
 
303
//
304
// QMEM control FSM
305
//
306
always @(posedge rst or posedge clk)
307
        if (rst) begin
308
                state <= #1 `OR1200_QMEMFSM_IDLE;
309
                qmem_dack <= #1 1'b0;
310
                qmem_iack <= #1 1'b0;
311
        end
312
        else case (state)       // synopsys parallel_case
313
                `OR1200_QMEMFSM_IDLE: begin
314
                        if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmemdcpu_we_i & qmem_ack) begin
315
                                state <= #1 `OR1200_QMEMFSM_STORE;
316
                                qmem_dack <= #1 1'b1;
317
                                qmem_iack <= #1 1'b0;
318
                        end
319
                        else if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmem_ack) begin
320
                                state <= #1 `OR1200_QMEMFSM_LOAD;
321
                                qmem_dack <= #1 1'b1;
322
                                qmem_iack <= #1 1'b0;
323
                        end
324
                        else if (qmemimmu_cycstb_i & iaddr_qmem_hit & qmem_ack) begin
325
                                state <= #1 `OR1200_QMEMFSM_FETCH;
326
                                qmem_iack <= #1 1'b1;
327
                                qmem_dack <= #1 1'b0;
328
                        end
329
                end
330
                `OR1200_QMEMFSM_STORE: begin
331
                        if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmemdcpu_we_i & qmem_ack) begin
332
                                state <= #1 `OR1200_QMEMFSM_STORE;
333
                                qmem_dack <= #1 1'b1;
334
                                qmem_iack <= #1 1'b0;
335
                        end
336
                        else if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmem_ack) begin
337
                                state <= #1 `OR1200_QMEMFSM_LOAD;
338
                                qmem_dack <= #1 1'b1;
339
                                qmem_iack <= #1 1'b0;
340
                        end
341
                        else if (qmemimmu_cycstb_i & iaddr_qmem_hit & qmem_ack) begin
342
                                state <= #1 `OR1200_QMEMFSM_FETCH;
343
                                qmem_iack <= #1 1'b1;
344
                                qmem_dack <= #1 1'b0;
345
                        end
346
                        else begin
347
                                state <= #1 `OR1200_QMEMFSM_IDLE;
348
                                qmem_dack <= #1 1'b0;
349
                                qmem_iack <= #1 1'b0;
350
                        end
351
                end
352
                `OR1200_QMEMFSM_LOAD: begin
353
                        if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmemdcpu_we_i & qmem_ack) begin
354
                                state <= #1 `OR1200_QMEMFSM_STORE;
355
                                qmem_dack <= #1 1'b1;
356
                                qmem_iack <= #1 1'b0;
357
                        end
358
                        else if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmem_ack) begin
359
                                state <= #1 `OR1200_QMEMFSM_LOAD;
360
                                qmem_dack <= #1 1'b1;
361
                                qmem_iack <= #1 1'b0;
362
                        end
363
                        else if (qmemimmu_cycstb_i & iaddr_qmem_hit & qmem_ack) begin
364
                                state <= #1 `OR1200_QMEMFSM_FETCH;
365
                                qmem_iack <= #1 1'b1;
366
                                qmem_dack <= #1 1'b0;
367
                        end
368
                        else begin
369
                                state <= #1 `OR1200_QMEMFSM_IDLE;
370
                                qmem_dack <= #1 1'b0;
371
                                qmem_iack <= #1 1'b0;
372
                        end
373
                end
374
                `OR1200_QMEMFSM_FETCH: begin
375
                        if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmemdcpu_we_i & qmem_ack) begin
376
                                state <= #1 `OR1200_QMEMFSM_STORE;
377
                                qmem_dack <= #1 1'b1;
378
                                qmem_iack <= #1 1'b0;
379
                        end
380
                        else if (qmemdmmu_cycstb_i & daddr_qmem_hit & qmem_ack) begin
381
                                state <= #1 `OR1200_QMEMFSM_LOAD;
382
                                qmem_dack <= #1 1'b1;
383
                                qmem_iack <= #1 1'b0;
384
                        end
385
                        else if (qmemimmu_cycstb_i & iaddr_qmem_hit & qmem_ack) begin
386
                                state <= #1 `OR1200_QMEMFSM_FETCH;
387
                                qmem_iack <= #1 1'b1;
388
                                qmem_dack <= #1 1'b0;
389
                        end
390
                        else begin
391
                                state <= #1 `OR1200_QMEMFSM_IDLE;
392
                                qmem_dack <= #1 1'b0;
393
                                qmem_iack <= #1 1'b0;
394
                        end
395
                end
396
                default: begin
397
                        state <= #1 `OR1200_QMEMFSM_IDLE;
398
                        qmem_dack <= #1 1'b0;
399
                        qmem_iack <= #1 1'b0;
400
                end
401
        endcase
402
 
403
//
404
// Instantiation of embedded memory
405
//
406
or1200_spram_2048x32 or1200_qmem_ram(
407
        .clk(clk),
408
        .rst(rst),
409
`ifdef OR1200_BIST
410
        // RAM BIST
411
        .mbist_si_i(mbist_si_i),
412
        .mbist_so_o(mbist_so_o),
413
        .mbist_ctrl_i(mbist_ctrl_i),
414
`endif
415
        .addr(qmem_addr[12:2]),
416
`ifdef OR1200_QMEM_BSEL
417
        .sel(qmem_sel),
418
`endif
419
`ifdef OR1200_QMEM_ACK
420
  .ack(qmem_ack),
421
`endif
422
  .ce(qmem_en),
423
        .we(qmem_we),
424
        .oe(1'b1),
425
        .di(qmem_di),
426
        .doq(qmem_do)
427
);
428
 
429
`else  // OR1200_QMEM_IMPLEMENTED
430
 
431
//
432
// QMEM and CPU/IMMU
433
//
434
assign qmemicpu_dat_o = icqmem_dat_i;
435
assign qmemicpu_ack_o = icqmem_ack_i;
436
assign qmemimmu_rty_o = icqmem_rty_i;
437
assign qmemimmu_err_o = icqmem_err_i;
438
assign qmemimmu_tag_o = icqmem_tag_i;
439
 
440
//
441
// QMEM and IC
442
//
443
assign icqmem_adr_o = qmemimmu_adr_i;
444
assign icqmem_cycstb_o = qmemimmu_cycstb_i;
445
assign icqmem_ci_o = qmemimmu_ci_i;
446
assign icqmem_sel_o = qmemicpu_sel_i;
447
assign icqmem_tag_o = qmemicpu_tag_i;
448
 
449
//
450
// QMEM and CPU/DMMU
451
//
452
assign qmemdcpu_dat_o = dcqmem_dat_i;
453
assign qmemdcpu_ack_o = dcqmem_ack_i;
454
assign qmemdcpu_rty_o = dcqmem_rty_i;
455
assign qmemdmmu_err_o = dcqmem_err_i;
456
assign qmemdmmu_tag_o = dcqmem_tag_i;
457
 
458
//
459
// QMEM and DC
460
//
461
assign dcqmem_adr_o = qmemdmmu_adr_i;
462
assign dcqmem_cycstb_o = qmemdmmu_cycstb_i;
463
assign dcqmem_ci_o = qmemdmmu_ci_i;
464
assign dcqmem_we_o = qmemdcpu_we_i;
465
assign dcqmem_sel_o = qmemdcpu_sel_i;
466
assign dcqmem_tag_o = qmemdcpu_tag_i;
467
assign dcqmem_dat_o = qmemdcpu_dat_i;
468
 
469
`ifdef OR1200_BIST
470
assign mbist_so_o = mbist_si_i;
471
`endif
472
 
473
`endif
474
 
475
endmodule

powered by: WebSVN 2.1.0

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