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

Subversion Repositories Aquarius

[/] [Aquarius/] [trunk/] [verilog/] [mem.v] - Blame information for rev 11

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

Line No. Rev Author Line
1 2 thorn_aitc
//======================================================
2
// Aquarius Project
3
//    SuperH-2 ISA Compatible RISC CPU
4
//------------------------------------------------------
5
// Module      : Memory Access Unit
6
//------------------------------------------------------
7
// File        : mem.v
8
// Library     : none
9
// Description : Memory Access Unit in CPU.
10
// Simulator   : Icarus Verilog (Cygwin)
11
// Synthesizer : Xilinx XST (Windows XP)
12
// Author      : Thorn Aitch
13
//------------------------------------------------------
14
// Revision Number : 1
15
// Date of Change  : 31st March 2002
16
// Creator         : Thorn Aitch
17
// Description     : Initial Design                               
18
//------------------------------------------------------
19
// Revision Number : 2
20
// Date of Change  : 7th April 2002
21
// Modifier        : Thorn Aitch
22
// Description     : adopt WISHBONE                                       
23
//------------------------------------------------------
24
// Revision Number : 3
25
// Date of Change  : 30th April 2003
26
// Modifier        : Thorn Aitch
27 11 thorn_aitc
// Description     : Release Version 1.0          
28
//------------------------------------------------------
29
// Revision Number : 4
30
// Date of Change  : 10th December 2003
31
// Modifier        : Thorn Aitch
32
// Description     : Release Version 1.1
33
//                   Inhibit substitution of "x"
34
//                   except for defalut statement whose
35
//                   case describes all logic spaces.
36 2 thorn_aitc
//======================================================
37
// Copyright (C) 2002-2003, Thorn Aitch
38
//
39
// Designs can be altered while keeping list of
40
// modifications "the same as in GNU" No money can
41
// be earned by selling the designs themselves, but
42
// anyone can get money by selling the implementation
43
// of the design, such as ICs based on some cores, 
44
// boards based on some schematics or Layouts, and
45
// even GUI interfaces to text mode drivers.
46
// "The same as GPL SW" Any update to the design
47
// should be documented and returned to the design. 
48
// Any derivative work based on the IP should be free
49
// under OpenIP License. Derivative work means any
50
// update, change or improvement on the design. 
51
// Any work based on the design can be either made
52
// free under OpenIP license or protected by any other
53
// license. Work based on the design means any work uses
54
// the OpenIP Licensed core as a building black without
55
// changing anything on it with any other blocks to
56
// produce larger design.  There is NO WARRANTY on the
57
// functionality or performance of the design on the
58
// real hardware implementation.
59
// On the other hand, the SuperH-2 ISA (Instruction Set
60
// Architecture) executed by Aquarius is rigidly
61
// the property of Renesas Corp. Then you have all 
62
// responsibility to judge if there are not any 
63
// infringements to Renesas's rights regarding your 
64
// Aquarius adoption into your design. 
65
// By adopting Aquarius, the user assumes all 
66
// responsibility for its use.
67
// This project may cause any damages around you, for 
68
// example, loss of properties, data, money, profits,
69
// life, or business etc. By adopting this source, 
70
// the user assumes all responsibility for its use.
71
//======================================================
72
 
73
`include "timescale.v"
74
`include "defines.v"
75
 
76
//*********************************
77
// Memory Access Unit Specification
78
//*********************************
79
// The Memory Access Unit handles memory access
80
// that is  instruction fetch and data read/write.
81
// Also should detect address error exception.
82
 
83
//-------------------
84
// WISHBONE DATASHEET
85
//-------------------
86
// Based on the WISHBONE Specification Revision : B.1
87
// See http://www.opencores.org/
88
//
89
// CPU is defined as MASTER module.
90
//
91
//(1)Signal Names
92
// CLK_I : clock input
93
// RST_I : reset input
94
// CYC_O : show bus cycle or read-modify-write cycle
95
// STB_O : strobe
96
// ACK_I : bus acknowledge
97
// ADR_O[31:0] : address output
98
// DAT_I[31:0] : data input (Read data)
99
// DAT_O[31:0] : data output (Write data)
100
// WE_O : read(0)/write(1)
101
// SEL_O[3:0] : valid data position
102
// TAG0_I : Instruction Fetch Width(=IF_WIDTH)
103
//
104
//(2)Data Organization
105
// Nomenclature : 8bit
106
// Big Endian Only
107
// Terminology : DWORD(32bit) means "Long Word" as SuperH's term.
108
//               WORD(16bit) and Byte(8bit) have same meanings.
109
//
110
// [External data bus alignment]
111
//            A1 A0
112
// READ  LONG ** |-HH-|-HL-|-LH-|-LL-|
113
// READ  WORD 0* |--H-|--L-|****|****|
114
// READ  WORD 1* |****|****|--H-|--L-|
115
// READ  BYTE 00 |--B-|****|****|****| 
116
// READ  BYTE 01 |****|--B-|****|****|
117
// READ  BYTE 10 |****|****|--B-|****|
118
// READ  BYTE 11 |****|****|****|--B-|
119
// WRITE LOMG ** |-HH-|-HL-|-LH-|-LL-|
120
// WRITE WORD ** |--H-|--L-|--H-|--L-|
121
// WRITE BYTE ** |--B-|--B-|--B-|--B-|
122
// 
123
// FETCH from LONG space ** |-HH-|-HL-|-LH-|-LL-|
124
// FETCH from WORD space 0* |--H-|--L-|****|****|
125
// FETCH from WORD space 1* |****|****|--H-|--L-| 
126
 
127
//--------------
128
// State Machine
129
//--------------
130
// [State Definition] 
131
// S0 `S_IDLE      :idle
132
// S1 `S_IFEX      :external fetch
133
// S2 `S_MAEX      :external data access
134
// S3 `S_MAEX_IFPD :external data access, pending fetch
135
// S4 `S_IDLE_IFKP :idle, keeping lower un-decoded instruction
136
// S5 `S_IFIN      :internal fetch from just keeping one
137
// S6 `S_MAEX_IFKP :extenal data access, keeping lower un-decoded instruction
138
// S7 `S_MAEX_IFIN :external data access and do internal fetch from just keeping
139
// ---
140
// [Internal Signal]
141
// IF_KEEP  : fetching from "long boundary" and IF_WIDTH=1
142
// IF_FORCE : IF_JP=1 or next fetch address is from "long boundary"
143
// ---
144
// [State Transition]
145
// S0 -> S0 no event
146
// S0 -> S1 by fetch request
147
// S0 -> S2 by data access request
148
// S0 -> S3 by both fetch request and data access request
149
// S0 -> S4 n/a
150
// S0 -> S5 n/a
151
// S0 -> S6 n/a
152
// S0 -> S7 n/a
153
// ---
154
// S1 -> S0 no event; IF_KEEP=0
155
// S1 -> S1 by fetch request; IF_FORCE=1 or IF_KEEP=0
156
// S1 -> S2 by data access request; IF_KEEP=0
157
// S1 -> S3 by both fetch and data access request; IF_KEEP=0
158
// S1 -> S4 no event; IF_KEEP=1
159
// S1 -> S5 by fetch request; IF_FORCE=0 and IF_KEEP=1
160
// S1 -> S6 by data access request; IF_KEEP=1
161
// S1 -> S7 by both fetch and data access request; IF_KEEP=1
162
// ---
163
// S2 -> S0 no event
164
// S2 -> S1 by fetch request
165
// S2 -> S2 by data access request
166
// S2 -> S3 by both fetch request and data access request
167
// S2 -> S4 n/a
168
// S2 -> S5 n/a
169
// S2 -> S6 n/a
170
// S2 -> S7 n/a
171
// ---
172
// S3 -> S0 n/a 
173
// S3 -> S1 always
174
// S3 -> S2 n/a
175
// S3 -> S3 n/a
176
// S3 -> S4 n/a
177
// S3 -> S5 n/a
178
// S3 -> S6 n/a
179
// S3 -> S7 n/a
180
// ---
181
// S4 -> S0 n/a
182
// S4 -> S1 by fetch request; IF_FORCE=1
183
// S4 -> S2 n/a
184
// S4 -> S3 by both fetch request and data access request; IF_FORCE=1
185
// S4 -> S4 no event
186
// S4 -> S5 by fetch request; IF_FORCE=0
187
// S4 -> S6 by data access request
188
// S4 -> S7 by both fetch request and data access request; IF_FORCE=0
189
// ---
190
// S5 -> S0 no event
191
// S5 -> S1 by fetch request
192
// S5 -> S2 by data access request
193
// S5 -> S3 by both fetch request and data access request
194
// S5 -> S4 n/a
195
// S5 -> S5 n/a
196
// S5 -> S6 n/a
197
// S5 -> S7 n/a
198
// ---
199
// S6 -> S0 n/a 
200
// S6 -> S1 by fetch request; IF_FORCE=1
201
// S6 -> S2 n/a
202
// S6 -> S3 by both fetch request and data access request; IF_FORCE=1
203
// S6 -> S4 no event
204
// S6 -> S5 by fetch request; IF_FORCE=0  
205
// S6 -> S6 by data access request
206
// S6 -> S7 by both fetch request and data access request; IF_FORCE=0
207
// ---
208
// S7 -> S0 no event 
209
// S7 -> S1 by fetch request
210
// S7 -> S2 by data access request
211
// S7 -> S3 by both fetch request and data access request
212
// S7 -> S4 n/a
213
// S7 -> S5 n/a
214
// S7 -> S6 n/a
215
// S7 -> S7 n/a
216
// ---
217
 
218
//-----------------------------------------
219
// Memory Access Controller Basic Operation
220
//-----------------------------------------
221
// [Example]
222
//            | | | | | | | | | | | | | | | | | | | | | | | | | |
223
//     pipe      D E M W       D     D E M         M
224
//                               D     D - E     D - E
225
//                               F D       D         D
226
//                                         F         F
227
//     IF_issue              0 F       F-F(*2)   F-F(*3)   
228
//     MA_issue  0 M                   M         M  
229
//     IF_stall                                  1 0 
230
//    (other_stall)                    1 0 
231
//     bus cycle     B           B       B B       B B
232
//     address out   A           A       A A
233
//     write data    W                   W
234
//     xxDR            R(*1)       R       R R
235
//            (*1:should forward to next EX)
236
//            (*2:load destination register contention)
237
//            (*3:IF-MA contention)
238
 
239
//*************************************************
240
// Module Definition
241
//*************************************************
242
module mem(
243
// system signal
244
    CLK, RST,
245
// WISHBONE external bus signal
246
    CYC, STB, ACK,
247
    ADR, DATI, DATO,
248
    WE, SEL,
249
    IF_WIDTH,
250
// pipeline slot edge
251
    SLOT,
252
// instruction fetch control
253
    IF_ISSUE, IF_JP, IF_AD,
254
    IF_DR, IF_BUS, IF_STALL,
255
// data access control
256
    MA_ISSUE, KEEP_CYC, MA_WR, MA_SZ,
257
    MA_AD, MA_DW, MA_DR
258
    );
259
//-------------------
260
// Module I/O Signals
261
//-------------------
262
    // (WISHBONE)
263
    input  CLK;           // clock
264
    input  RST;           // reset
265
    output CYC;           // cycle output
266
    output STB;           // strobe
267
    input  ACK;           // external memory ready
268
    output [31:0] ADR;    // external address
269
    input  [31:0] DATI;   // external data read bus
270
    output [31:0] DATO;   // external data write bus
271
    output WE;            // external write/read
272
    output [3:0] SEL;     // external valid data position
273
    input  IF_WIDTH;      // external fetch space width (IF_WIDTH)
274
    // (To/From other blocks)
275
    output SLOT;          // pipeline slot edge
276
    input  IF_ISSUE;      // fetch request
277
    input  IF_JP;         // fetch caused by jump
278
    input  [31:0] IF_AD;  // fetch address
279
    output [15:0] IF_DR;  // fetched instruction
280
    output IF_BUS;        // fetch access done to extenal bus
281
    output IF_STALL;      // fetch and memory access contention
282
    input  MA_ISSUE;      // memory access request
283
    input  KEEP_CYC;      // request read-modify-write (To be issued on READ-CYC to keep CYC_O on)
284
    input  MA_WR;         // memory access kind : Write(1)/Read(0)
285
    input  [1:0] MA_SZ;   // memory access size : 00 byte, 01 word, 10 long, 11 inhibitted
286
    input  [31:0] MA_AD;  // memory access address
287
    input  [31:0] MA_DW;  // memory write data
288
    output [31:0] MA_DR;  // memory read data
289
 
290
 
291
//-----------------
292
// Internal Signals
293
//-----------------
294
    reg    CYC;
295
    reg    STB;
296
    reg    [31:0] ADR;
297
    reg    [31:0] DATO;
298
    reg    WE;
299
    reg    [3:0] SEL;
300
 
301
    reg    [31:0] ADR_PREV;         // previous ADR to be latched
302
    reg    [31:0] DATO_PREV;        // previous DATO to be latched
303
    reg    CYC_PREV, NEXT_KEEP_CYC; // previous CYC to be latched, keep CYC assertion
304
    reg    [3:0] SEL_PREV;          // previous SEL to be latched
305
    reg    [15:0] IF_DR;     // output to decoder 
306
    reg    [31:0] IF_DR_PREV;// directly latched DATI for instruction
307
    reg    [31:0] MA_DR;     // output to datapath (sign extended)
308
    reg    [31:0] MA_DR_PREV;// directly latched DATI for data
309
    reg    IF_BUS;           // a instruction in lower 16bit of long size fetched instructions(32bit)
310
    reg    IF_STALL;
311
    reg    [15:0] IF_BUF;    // buffer to keep the lower 16bit of previous long fetch
312
    reg    IF_KEEP;          // fetching was from "long boundary" AND IF_WIDTH=1
313
    reg    IF_FORCE;         // IF_JP=1 or next fetch address is from "long boundary"
314
    reg    [2:0] STATE;      // state
315
    reg    [2:0] NEXT_STATE; // next state
316
    reg    [1:0] ACCESS_SZ;  // current data access size
317
    reg    NXTBUS;           // next state is exernal bus
318
    reg    MEMEND;           // finish memory cycle or no memory cycle
319
    reg    MEMACK;           // memory control unit can accept next memory request
320
    reg [1:0] MA_ACCESS_SZ;  // latched ACCESS_SZ to extend sign bit of MA_DR output
321
    reg [1:0] MA_ADR;        // latched lower 2bit of ADR to extend sign bit of MA_DR output
322
    reg [2:0] IF_STATE;      // latched STATE to make IF_DR from IF_DR_PREV
323
    reg IF_ADR1;             // latched ADR[1] to make IF_DR from IF_DR_PREV
324
    reg [15:0] IF_IF_BUF;    // latched IF_BUF to make IF_DR from IF_DR_PREV
325
    wire SLOT;               // pipeline slot edge (= MEMACK)
326
 
327
    integer i;
328
 
329
//-----------------
330
// Make signal SLOT
331
//-----------------
332
    assign SLOT = MEMACK;
333
 
334
//-----------------------------------------------------------------------
335
// Make MEMACK : shows memory control unit can accept next memory request
336
//-----------------------------------------------------------------------
337
//     MEMACK = memory controller can accept next request (not equal ACK),
338
//              and if memory controller is generating external bus cycle now,
339
//              MEMACK confirms current bus cycle will be finished in this clock cycle.
340
//     MEMEND = finish memory cycle or no memory cycle
341
//     NXTBUS = begin memory cycle (next cycle is external bus)
342
//     ACK    = shows only "bus cycle finished"  
343
 
344
    always @(NEXT_STATE or MEMEND) begin
345
        case (NEXT_STATE)
346
            //`S_MAEX_IFPD : MEMACK <= 1'b0;
347
            default     : MEMACK <= MEMEND;
348
        endcase
349
    end
350
    // May be MEMACK can be generated from ~IF_STALL & MEMEND
351
    // From timing point of view, ACK should be 
352
    // combined at final stage of the MEMACK logic, not MEMEND.
353
 
354
    always @(STATE or ACK) begin
355
        case (STATE)
356
            `S_IDLE      : MEMEND <= 1'b1;
357
            `S_IDLE_IFKP : MEMEND <= 1'b1;
358
            `S_IFIN      : MEMEND <= 1'b1;
359
            default      : if (ACK == 1'b1)
360
                               MEMEND <= 1'b1;
361
                           else
362
                               MEMEND <= 1'b0;
363
        endcase
364
    end
365
 
366
    always @(NEXT_STATE) begin
367
        if ((NEXT_STATE[1] == 1'b1) || (NEXT_STATE == `S_IFEX))
368
            NXTBUS <= 1'b1;
369
        else
370
            NXTBUS <= 1'b0;
371
    end
372
 
373
//-------------------
374
// Main State Machine
375
//-------------------
376
    // state machine F/F
377
    always @(posedge CLK or posedge RST) begin
378
        if (RST == 1'b1)
379
            STATE <= `S_IDLE ;
380
        else
381
            STATE <= NEXT_STATE;
382
    end
383
 
384
    // make IF_KEEP
385
    always @(ADR or IF_WIDTH) begin
386
        IF_KEEP <= (~ADR[1]) & (~ADR[0]) & IF_WIDTH;
387
    end
388
 
389
    // make IF_FORCE
390
    always @(IF_JP or IF_AD) begin
391
      //IF_FORCE <= IF_JP | ((~IF_AD[1]) & (~IF_AD[0]));
392
        IF_FORCE <= IF_JP | (~IF_AD[1]);
393
    end
394
 
395
    // make NEXT_STATE : state machine combinational circuit
396
    always @(STATE or IF_ISSUE or MA_ISSUE or IF_FORCE or IF_KEEP or ACK) begin
397
        case (STATE)
398
            `S_IDLE: // S0 idle
399
                     if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
400
                else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
401
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
402
                else NEXT_STATE <= `S_MAEX_IFPD;
403
            `S_IFEX: // S1 external fetch
404
                     if (ACK == 1'b0) NEXT_STATE <= `S_IFEX;
405
                else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b000) NEXT_STATE <= `S_IDLE;
406
                else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b001) NEXT_STATE <= `S_IDLE_IFKP;
407
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1000) NEXT_STATE <= `S_IFEX;
408
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1010) NEXT_STATE <= `S_IFEX;
409
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1001) NEXT_STATE <= `S_IFIN;
410
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1011) NEXT_STATE <= `S_IFEX;
411
                else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b010) NEXT_STATE <= `S_MAEX;
412
                else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b011) NEXT_STATE <= `S_MAEX_IFKP;
413
                else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b110) NEXT_STATE <= `S_MAEX_IFPD;
414
                else NEXT_STATE <= `S_MAEX_IFIN;
415
            `S_MAEX: // S2 external data access
416
                     if (ACK == 1'b0) NEXT_STATE <= `S_MAEX;
417
                else if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
418
                else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
419
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
420
                else NEXT_STATE <= `S_MAEX_IFPD;
421
            `S_MAEX_IFPD: // S3 external data access, pending fetch
422
                     if (ACK == 1'b0) NEXT_STATE <= `S_MAEX_IFPD;
423
                else NEXT_STATE <= `S_IFEX;
424
            `S_IDLE_IFKP: // S4 idle, keeping lower un-decodeed instruction
425
                     if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b101) NEXT_STATE <= `S_IFEX;
426
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b100) NEXT_STATE <= `S_IFIN;
427
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX_IFKP;
428
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b111) NEXT_STATE <= `S_MAEX_IFPD;
429
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b110) NEXT_STATE <= `S_MAEX_IFIN;
430
                else NEXT_STATE <= `S_IDLE_IFKP;
431
            `S_IFIN: // S5 internal fetch from just keeping one
432
                     if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
433
                else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
434
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
435
                else NEXT_STATE <= `S_MAEX_IFPD;
436
            `S_MAEX_IFKP: // S6 extenal data access, keeping lower un- decoded instruction
437
                     if (ACK == 1'b0) NEXT_STATE <= `S_MAEX_IFKP;
438
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b101) NEXT_STATE <= `S_IFEX;
439
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b100) NEXT_STATE <= `S_IFIN;
440
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX_IFKP;
441
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b111) NEXT_STATE <= `S_MAEX_IFPD;
442
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b110) NEXT_STATE <= `S_MAEX_IFIN;
443
                else NEXT_STATE <= `S_IDLE_IFKP;
444
            `S_MAEX_IFIN: // S7 external data access and do internal fetch from just keeping
445
                     if (ACK == 1'b0) NEXT_STATE <= `S_MAEX_IFIN;
446
                else if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
447
                else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
448
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
449
                else NEXT_STATE <= `S_MAEX_IFPD;
450
 
451
            default: NEXT_STATE <= `S_IDLE;
452
        endcase
453
    end
454
 
455
//-------------------------------
456
// ADR : external addresss output
457
//-------------------------------
458
    // selector
459
    always @(NEXT_STATE or MA_AD or IF_AD) begin
460
        if (NEXT_STATE[1] == 1'b1) //memory access
461
            ADR_PREV <= MA_AD;
462
        else                       // instruction fetch
463
            ADR_PREV <= IF_AD;
464
    end
465
    // output
466
    always @(posedge CLK) begin
467
        if ((NXTBUS == 1'b1) && (MEMEND == 1'b1)) begin
468
            ADR <= ADR_PREV;
469
        end
470
    end
471
 
472
//-------------------------------------
473
// ACCESS_SZ : current data access size
474
//-------------------------------------
475
    always @(posedge CLK) begin
476
        if ((NXTBUS == 1'b1) && (MEMEND == 1'b1)) begin
477
            ACCESS_SZ <= MA_SZ; // have meaning only when data access
478
        end
479
    end
480
 
481
//----------------------------
482
// DATO : external data output
483
//----------------------------
484
    // prepare
485
    always @(MA_SZ or MA_DW) begin
486
        case (MA_SZ)
487
            2'b00: begin // byte
488
                       DATO_PREV[31:24] <= MA_DW[7:0];
489
                       DATO_PREV[23:16] <= MA_DW[7:0];
490
                       DATO_PREV[15: 8] <= MA_DW[7:0];
491
                       DATO_PREV[ 7: 0] <= MA_DW[7:0];
492
                   end
493
            2'b01: begin // word
494
                       DATO_PREV[31:24] <= MA_DW[15:8];
495
                       DATO_PREV[23:16] <= MA_DW[ 7:0];
496
                       DATO_PREV[15: 8] <= MA_DW[15:8];
497
                       DATO_PREV[ 7: 0] <= MA_DW[ 7:0];
498
                   end
499
            2'b10: begin // long
500
                       DATO_PREV[31:24] <= MA_DW[31:24];
501
                       DATO_PREV[23:16] <= MA_DW[23:16];
502
                       DATO_PREV[15: 8] <= MA_DW[15: 8];
503
                       DATO_PREV[ 7: 0] <= MA_DW[ 7: 0];
504
                   end
505
            default: // 2'b11 don't care
506
                   begin
507 11 thorn_aitc
                       DATO_PREV[31:24] <= MA_DW[31:24]; // Thorn Aitch 2003/12/10
508
                       DATO_PREV[23:16] <= MA_DW[23:16]; // Thorn Aitch 2003/12/10
509
                       DATO_PREV[15: 8] <= MA_DW[15: 8]; // Thorn Aitch 2003/12/10
510
                       DATO_PREV[ 7: 0] <= MA_DW[15: 8]; // Thorn Aitch 2003/12/10
511 2 thorn_aitc
                   end
512
        endcase
513
    end
514
 
515
    // output
516
    always @(posedge CLK) begin
517
        if ((NXTBUS == 1'b1) && (MEMEND == 1'b1) && (MA_WR == 1'b1))
518
            DATO <= DATO_PREV;
519
    end
520
 
521
//----------------------------
522
// IF_DR : fetched instruction
523
//----------------------------
524
    // capture DATI    
525
    always @(posedge CLK) begin
526
        if ((MEMEND == 1'b1) & ((STATE == `S_IFEX) | ((STATE[2] == 1'b1) && (STATE[0] == 1'b1))))
527
        begin
528
            IF_STATE   <= STATE;
529
            IF_ADR1    <= ADR[1];
530
            IF_IF_BUF  <= IF_BUF;
531
            IF_DR_PREV <= DATI;
532
        end
533
    end
534
    // output to IF_DR
535
    always @(IF_STATE or IF_ADR1 or IF_DR_PREV or IF_IF_BUF) begin
536
        if (IF_STATE == `S_IFEX)
537
            begin
538
                // IF from 0,4,8,C
539
                if (IF_ADR1 == 1'b0)
540
                    begin
541
                        IF_DR <= IF_DR_PREV[31:16];
542
                    end
543
                // IF from 2,6,A,E
544
                else
545
                    IF_DR <= IF_DR_PREV[15:0];
546
            end
547
        else
548
        // IF from IF_BUF
549 11 thorn_aitc
            //if ((IF_STATE[2] == 1'b1) && (IF_STATE[0] == 1'b1)) // `S_IFIN or `S_MAEX_IFIN
550
            //    IF_DR <= IF_IF_BUF;       // Thorn Aitch 2003/12/10
551
            //else                                          // Thorn Aitch 2003/12/10
552
            //    IF_DR <= 32'hxxxxxxxx;    // Thorn Aitch 2003/12/10
553
                  IF_DR <= IF_IF_BUF;               // Thorn Aitch 2003/12/10
554 2 thorn_aitc
    end
555
    // output
556
    //always @(posedge CLK) begin
557
    //   if ((MEMEND == 1'b1) & ((STATE == `S_IFEX) | ((STATE[2] == 1'b1) && (STATE[0] == 1'b1))))
558
    //    begin
559
    //        IF_DR <= IF_DR_PREV;
560
    //    end
561
    //end
562
 
563
//---------------------------------------------------------------
564
// IF_BUF : buffer to keep the lower 16bit of previous long fetch
565
//---------------------------------------------------------------
566
    always @(posedge CLK) begin
567
        if (MEMEND == 1'b1) begin
568
            if (STATE == `S_IFEX)
569
                // IF from long space external
570
                if ((IF_WIDTH == 1'b1) && (ADR[1] == 1'b0))
571
                    IF_BUF <= DATI[15:0];
572
        end
573
    end
574
 
575
//------------------
576
// MA_DR : read data
577
//------------------
578
    // capture DATI
579
    always @(posedge CLK) begin
580
        if (ACK == 1'b1) begin // it must be captured by ACK (not MEMEND)
581
            if ((STATE[1] == 1'b1) && (WE == 1'b0)) begin
582
                MA_ACCESS_SZ <= ACCESS_SZ;
583
                MA_ADR <= ADR[1:0];
584
                MA_DR_PREV <= DATI;
585
            end
586
        end
587
    end
588
   // output to MA_DR with Sign Extended
589
    always @(MA_ACCESS_SZ or MA_DR_PREV or MA_ADR) begin
590
        case (MA_ACCESS_SZ)
591
            2'b00: begin //byte
592
                       if ({MA_ADR[1], MA_ADR[0]} == 2'b00)
593
                           begin
594
                               for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[31];
595
                               MA_DR[7:0] <= MA_DR_PREV[31:24];
596
                           end
597
                       else if ({MA_ADR[1], MA_ADR[0]} == 2'b01)
598
                           begin
599
                               for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[23];
600
                               MA_DR[7:0] <= MA_DR_PREV[23:16];
601
                           end
602
                       else if ({MA_ADR[1], MA_ADR[0]} == 2'b10)
603
                           begin
604
                               for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[15];
605
                               MA_DR[7:0] <= MA_DR_PREV[15:8];
606
                           end
607
                       else if ({MA_ADR[1], MA_ADR[0]} == 2'b11)
608
                           begin
609
                               for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[7];
610
                               MA_DR[7:0] <= MA_DR_PREV[7:0];
611
                           end
612
                   end
613
            2'b01: begin //word
614
                       if (MA_ADR[1] == 1'b0)
615
                           begin
616
                               for (i = 16 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[31];
617
                               MA_DR[15:0] <= MA_DR_PREV[31:16];
618
                           end
619
                       else
620
                           begin
621
                               for (i = 16 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[15];
622
                               MA_DR[15:0] <= MA_DR_PREV[15:0];
623
                           end
624
                   end
625
            2'b10: begin //long
626
                       MA_DR[31:0] <= MA_DR_PREV[31:0];
627
                   end
628
            default : begin
629 11 thorn_aitc
                          //MA_DR[31:0] <= 32'hxxxxxxxx;    // Thorn Aitch 2003/12/10 
630
                                         MA_DR[31:0] <= MA_DR_PREV[31:0];  // Thorn Aitch 2003/12/10
631 2 thorn_aitc
                      end
632
        endcase
633
    end
634
    // output
635
    //always @(posedge CLK) begin
636
    //    if (ACK == 1'b1) begin // it must be captured by ACK (not MEMEND)
637
    //        if ((STATE[1] == 1'b1) && (WE == 1'b0)) begin
638
    //            MA_DR <= MA_DR_PREV;
639
    //        end
640
    //    end
641
    //end
642
 
643
//------------------------------------------
644
// IF_BUS : fetch access done to extenal bus
645
//------------------------------------------
646
    always @(posedge CLK) begin
647
        if (MEMEND == 1'b1) begin
648
            if (NEXT_STATE == `S_IFEX)
649
                IF_BUS <= 1'b1;
650
           else
651
                IF_BUS <= 1'b0;
652
        end
653
    end
654
 
655
//----------------------------------------------
656
// IF_STALL : fetch and memory access contention
657
//----------------------------------------------
658
    always @(NEXT_STATE) begin
659
        if (NEXT_STATE == `S_MAEX_IFPD)
660
            IF_STALL <= 1'b1;
661
        else
662
            IF_STALL <= 1'b0;
663
    end
664
 
665
//-------------------------
666
// WE : WISHBONE write/read
667
//-------------------------
668
    // WE
669
    always @(posedge CLK) begin
670
        if (MEMEND == 1'b1) begin
671
            if (((NEXT_STATE[1] == 1'b1) && (MA_WR == 1'b0)) || (NEXT_STATE == `S_IFEX))
672
                WE <= 1'b0; // read
673
            else
674
                WE <= 1'b1; // write
675
        end
676
    end
677
 
678
//--------------------------
679
// STB : WISHBONE bus strobe
680
//--------------------------
681
    always @(posedge CLK) begin
682
        if (MEMEND == 1'b1) begin
683
            STB <= NXTBUS;
684
        end
685
    end
686
 
687
//------------------------------------
688
// CYC :WOSHBONE show cycle to be kept
689
//------------------------------------
690
    //     req     STB CYC
691
    //     ---------------
692
    //     RD,CYC  off off
693
    //     nop     on  on
694
    //     WR      off on
695
    //     nop     on  on
696
    //             off off  
697
    // prepare
698
    always @(NXTBUS or NEXT_KEEP_CYC) begin
699
        if ((NXTBUS == 1'b1) || (NEXT_KEEP_CYC == 1'b1))
700
            CYC_PREV <= 1'b1;
701
        else
702
            CYC_PREV <= 1'b0;
703
    end
704
    // remember for next cyc
705
    always @(posedge CLK) begin
706
        if (MEMEND == 1'b1) begin
707
            NEXT_KEEP_CYC <= KEEP_CYC;
708
        end
709
    end
710
    // output
711
    always @(posedge CLK) begin
712
        if (MEMEND == 1'b1) begin
713
            CYC <= CYC_PREV;
714
        end
715
    end
716
 
717
//----------------------------------------
718
// SEL : WISHBONE show valid data position
719
//----------------------------------------
720
    // prepare
721
    always @(NEXT_STATE or MA_SZ or MA_AD or IF_AD) begin
722
      //if ((NEXT_STATE == `S_IFEX) && (IF_AD[1:0] == 2'b00))
723
        if ((NEXT_STATE == `S_IFEX) && (IF_AD[1] == 1'b0))
724
            SEL_PREV <= 4'b1111;
725
      //else if ((NEXT_STATE == `S_IFEX) && (IF_AD[1:0] == 2'b10))
726
        else if ((NEXT_STATE == `S_IFEX) && (IF_AD[1] == 1'b1))
727
            SEL_PREV <= 4'b0011;
728
        else
729
            if (NEXT_STATE[1] == 1'b1)
730
                begin
731
                    if (MA_SZ == 2'b10)
732
                        SEL_PREV <= 4'b1111;
733
                    else if ((MA_SZ == 2'b01) && (MA_AD[1] == 1'b0))
734
                        SEL_PREV <= 4'b1100;
735
                    else if ((MA_SZ == 2'b01) && (MA_AD[1] == 1'b1))
736
                        SEL_PREV <= 4'b0011;
737
                    else if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b00))
738
                        SEL_PREV <= 4'b1000;
739
                    else if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b01))
740
                        SEL_PREV <= 4'b0100;
741
                    else if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b10))
742
                        SEL_PREV <= 4'b0010;
743
                    else //if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b11))
744
                        SEL_PREV <= 4'b0001;
745
                end
746
            else SEL_PREV <= 4'b0000;
747
    end
748
    // output
749
    always @(posedge CLK) begin
750
        if ((NXTBUS == 1'b1) && (MEMEND == 1'b1)) begin
751
            SEL <= SEL_PREV;
752
        end
753
    end
754
 
755
//======================================================
756
  endmodule
757
//======================================================

powered by: WebSVN 2.1.0

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