OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_processor/] [new_lm32/] [rtl/] [lm32_load_store_unit.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
//   ==================================================================
2
//   >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
3
//   ------------------------------------------------------------------
4
//   Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
5
//   ALL RIGHTS RESERVED
6
//   ------------------------------------------------------------------
7
//
8
//   IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
9
//
10
//   Permission:
11
//
12
//      Lattice Semiconductor grants permission to use this code
13
//      pursuant to the terms of the Lattice Semiconductor Corporation
14
//      Open Source License Agreement.
15
//
16
//   Disclaimer:
17
//
18
//      Lattice Semiconductor provides no warranty regarding the use or
19
//      functionality of this code. It is the user's responsibility to
20
//      verify the user's design for consistency and functionality through
21
//      the use of formal verification methods.
22
//
23
//   --------------------------------------------------------------------
24
//
25
//                  Lattice Semiconductor Corporation
26
//                  5555 NE Moore Court
27
//                  Hillsboro, OR 97214
28
//                  U.S.A
29
//
30
//                  TEL: 1-800-Lattice (USA and Canada)
31
//                         503-286-8001 (other locations)
32
//
33
//                  web: http://www.latticesemi.com/
34
//                  email: techsupport@latticesemi.com
35
//
36
//   --------------------------------------------------------------------
37
//                         FILE DETAILS
38
// Project      : LatticeMico32
39
// File         : lm32_load_store_unit.v
40
// Title        : Load and store unit
41
// Dependencies : lm32_include.v
42
// Version      : 6.1.17
43
//              : Initial Release
44
// Version      : 7.0SP2, 3.0
45
//              : No Change
46
// Version      : 3.1
47
//              : Instead of disallowing an instruction cache miss on a data cache
48
//              : miss, both can now occur at the same time. If both occur at same
49
//              : time, then restart address is the address of instruction that
50
//              : caused data cache miss.
51
// Version      : 3.2
52
//              : EBRs use SYNC resets instead of ASYNC resets.
53
// Version      : 3.3
54
//              : Support for new non-cacheable Data Memory that is accessible by
55
//              : the data port and has a one cycle access latency.
56
// Version      : 3.4
57
//              : No change
58
// Version      : 3.5
59
//              : Bug fix: Inline memory is correctly generated if it is not a
60
//              : power-of-two
61
// =============================================================================
62
 
63
`include "lm32_include.v"
64
 
65
/////////////////////////////////////////////////////
66
// Module interface
67
/////////////////////////////////////////////////////
68
 
69
module lm32_load_store_unit (
70
    // ----- Inputs -------
71
    clk_i,
72
    rst_i,
73
    // From pipeline
74
    stall_a,
75
    stall_x,
76
    stall_m,
77
    kill_m,
78
    exception_m,
79
    store_operand_x,
80
    load_store_address_x,
81
    load_store_address_m,
82
    load_store_address_w,
83
`ifdef CFG_MMU_ENABLED
84
    load_d,
85
    store_d,
86
`endif
87
    load_x,
88
    store_x,
89
    load_q_x,
90
    store_q_x,
91
    load_q_m,
92
    store_q_m,
93
    sign_extend_x,
94
    size_x,
95
`ifdef CFG_DCACHE_ENABLED
96
    dflush,
97
`endif
98
`ifdef CFG_IROM_ENABLED
99
    irom_data_m,
100
`endif
101
`ifdef CFG_MMU_ENABLED
102
    dtlb_enable,
103
    tlbpaddr,
104
    tlbvaddr,
105
    dtlb_update,
106
    dtlb_flush,
107
    dtlb_invalidate,
108
`endif
109
    // From Wishbone
110
    d_dat_i,
111
    d_ack_i,
112
    d_err_i,
113
    d_rty_i,
114
    // ----- Outputs -------
115
    // To pipeline
116
`ifdef CFG_DCACHE_ENABLED
117
    dcache_refill_request,
118
    dcache_restart_request,
119
    dcache_stall_request,
120
    dcache_refilling,
121
`endif
122
`ifdef CFG_IROM_ENABLED
123
    irom_store_data_m,
124
    irom_address_xm,
125
    irom_we_xm,
126
    irom_stall_request_x,
127
`endif
128
    load_data_w,
129
    stall_wb_load,
130
`ifdef CFG_MMU_ENABLED
131
    dtlb_stall_request,
132
    dtlb_miss_vfn,
133
    dtlb_miss_x,
134
    dtlb_fault_x,
135
`endif
136
    // To Wishbone
137
    d_dat_o,
138
    d_adr_o,
139
    d_cyc_o,
140
    d_sel_o,
141
    d_stb_o,
142
    d_we_o,
143
    d_cti_o,
144
    d_lock_o,
145
    d_bte_o
146
    );
147
 
148
/////////////////////////////////////////////////////
149
// Parameters
150
/////////////////////////////////////////////////////
151
 
152
parameter associativity = 1;                            // Associativity of the cache (Number of ways)
153
parameter sets = 512;                                   // Number of sets
154
parameter bytes_per_line = 16;                          // Number of bytes per cache line
155
parameter base_address = 0;                             // Base address of cachable memory
156
parameter limit = 0;                                    // Limit (highest address) of cachable memory
157
 
158
// For bytes_per_line == 4, we set 1 so part-select range isn't reversed, even though not really used
159
localparam addr_offset_width = bytes_per_line == 4 ? 1 : `CLOG2(bytes_per_line)-2;
160
localparam addr_offset_lsb = 2;
161
localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1);
162
 
163
/////////////////////////////////////////////////////
164
// Inputs
165
/////////////////////////////////////////////////////
166
 
167
input clk_i;                                            // Clock
168
input rst_i;                                            // Reset
169
 
170
input stall_a;                                          // A stage stall
171
input stall_x;                                          // X stage stall
172
input stall_m;                                          // M stage stall
173
input kill_m;                                           // Kill instruction in M stage
174
input exception_m;                                      // An exception occured in the M stage
175
 
176
input [`LM32_WORD_RNG] store_operand_x;                 // Data read from register to store
177
input [`LM32_WORD_RNG] load_store_address_x;            // X stage load/store address
178
input [`LM32_WORD_RNG] load_store_address_m;            // M stage load/store address
179
input [1:0] load_store_address_w;                       // W stage load/store address (only least two significant bits are needed)
180
`ifdef CFG_MMU_ENABLED
181
input load_d;                                           // Load instruction in D stage
182
input store_d;                                          // Store instruction in D stage
183
`endif
184
input load_x;                                           // Load instruction in X stage
185
input store_x;                                          // Store instruction in X stage
186
input load_q_x;                                         // Load instruction in X stage
187
input store_q_x;                                        // Store instruction in X stage
188
input load_q_m;                                         // Load instruction in M stage
189
input store_q_m;                                        // Store instruction in M stage
190
input sign_extend_x;                                    // Whether load instruction in X stage should sign extend or zero extend
191
input [`LM32_SIZE_RNG] size_x;                          // Size of load or store (byte, hword, word)
192
 
193
`ifdef CFG_DCACHE_ENABLED
194
input dflush;                                           // Flush the data cache
195
`endif
196
 
197
`ifdef CFG_IROM_ENABLED
198
input [`LM32_WORD_RNG] irom_data_m;                     // Data from Instruction-ROM
199
`endif
200
 
201
`ifdef CFG_MMU_ENABLED
202
input dtlb_enable;                                      // Data TLB enable
203
input [`LM32_WORD_RNG] tlbpaddr;                        // TLBPADDR CSR
204
input [`LM32_WORD_RNG] tlbvaddr;                        // TLBVADDR CSR
205
input dtlb_update;                                      // Data TLB update
206
input dtlb_flush;                                       // Data TLB flush
207
input dtlb_invalidate;                                  // Data TLB invalidate
208
`endif
209
 
210
input [`LM32_WORD_RNG] d_dat_i;                         // Data Wishbone interface read data
211
input d_ack_i;                                          // Data Wishbone interface acknowledgement
212
input d_err_i;                                          // Data Wishbone interface error
213
input d_rty_i;                                          // Data Wishbone interface retry
214
 
215
/////////////////////////////////////////////////////
216
// Outputs
217
/////////////////////////////////////////////////////
218
 
219
`ifdef CFG_DCACHE_ENABLED
220
output dcache_refill_request;                           // Request to refill data cache
221
wire   dcache_refill_request;
222
output dcache_restart_request;                          // Request to restart the instruction that caused a data cache miss
223
wire   dcache_restart_request;
224
output dcache_stall_request;                            // Data cache stall request
225
wire   dcache_stall_request;
226
output dcache_refilling;
227
wire   dcache_refilling;
228
`endif
229
 
230
`ifdef CFG_IROM_ENABLED
231
output [`LM32_WORD_RNG] irom_store_data_m;              // Store data to Instruction ROM
232
wire   [`LM32_WORD_RNG] irom_store_data_m;
233
output [`LM32_WORD_RNG] irom_address_xm;                // Load/store address to Instruction ROM
234
wire   [`LM32_WORD_RNG] irom_address_xm;
235
output irom_we_xm;                                      // Write-enable of 2nd port of Instruction ROM
236
wire   irom_we_xm;
237
output irom_stall_request_x;                            // Stall instruction in D stage
238
wire   irom_stall_request_x;
239
`endif
240
 
241
output [`LM32_WORD_RNG] load_data_w;                    // Result of a load instruction
242
reg    [`LM32_WORD_RNG] load_data_w;
243
output stall_wb_load;                                   // Request to stall pipeline due to a load from the Wishbone interface
244
reg    stall_wb_load;
245
 
246
`ifdef CFG_MMU_ENABLED
247
output dtlb_stall_request;                              // Data TLB stall request
248
wire   dtlb_stall_request;
249
output [`LM32_WORD_RNG] dtlb_miss_vfn;                  // Virtual frame number of missed load or store address
250
wire   [`LM32_WORD_RNG] dtlb_miss_vfn;
251
output dtlb_miss_x;                                     // Indicates if a data TLB miss has occured
252
wire   dtlb_miss_x;
253
output dtlb_fault_x;                                    // Indicates if a data TLB fault has occured in X stage
254
wire   dtlb_fault_x;
255
`endif
256
 
257
output [`LM32_WORD_RNG] d_dat_o;                        // Data Wishbone interface write data
258
reg    [`LM32_WORD_RNG] d_dat_o;
259
output [`LM32_WORD_RNG] d_adr_o;                        // Data Wishbone interface address
260
reg    [`LM32_WORD_RNG] d_adr_o;
261
output d_cyc_o;                                         // Data Wishbone interface cycle
262
reg    d_cyc_o;
263
output [`LM32_BYTE_SELECT_RNG] d_sel_o;                 // Data Wishbone interface byte select
264
reg    [`LM32_BYTE_SELECT_RNG] d_sel_o;
265
output d_stb_o;                                         // Data Wishbone interface strobe
266
reg    d_stb_o;
267
output d_we_o;                                          // Data Wishbone interface write enable
268
reg    d_we_o;
269
output [`LM32_CTYPE_RNG] d_cti_o;                       // Data Wishbone interface cycle type
270
reg    [`LM32_CTYPE_RNG] d_cti_o;
271
output d_lock_o;                                        // Date Wishbone interface lock bus
272
reg    d_lock_o;
273
output [`LM32_BTYPE_RNG] d_bte_o;                       // Data Wishbone interface burst type
274
wire   [`LM32_BTYPE_RNG] d_bte_o;
275
 
276
/////////////////////////////////////////////////////
277
// Internal nets and registers
278
/////////////////////////////////////////////////////
279
 
280
// Microcode pipeline registers - See inputs for description
281
reg [`LM32_SIZE_RNG] size_m;
282
reg [`LM32_SIZE_RNG] size_w;
283
reg sign_extend_m;
284
reg sign_extend_w;
285
reg [`LM32_WORD_RNG] store_data_x;
286
reg [`LM32_WORD_RNG] store_data_m;
287
reg [`LM32_BYTE_SELECT_RNG] byte_enable_x;
288
reg [`LM32_BYTE_SELECT_RNG] byte_enable_m;
289
wire [`LM32_WORD_RNG] data_m;
290
reg [`LM32_WORD_RNG] data_w;
291
 
292
`ifdef CFG_DCACHE_ENABLED
293
wire dcache_select_x;                                   // Select data cache to load from / store to
294
reg dcache_select_m;
295
wire [`LM32_WORD_RNG] dcache_data_m;                    // Data read from cache
296
wire [`LM32_WORD_RNG] dcache_refill_address;            // Address to refill data cache from
297
reg dcache_refill_ready;                                // Indicates the next word of refill data is ready
298
wire [`LM32_CTYPE_RNG] first_cycle_type;                // First Wishbone cycle type
299
wire [`LM32_CTYPE_RNG] next_cycle_type;                 // Next Wishbone cycle type
300
wire last_word;                                         // Indicates if this is the last word in the cache line
301
wire [`LM32_WORD_RNG] first_address;                    // First cache refill address
302
`endif
303
`ifdef CFG_DRAM_ENABLED
304
wire dram_select_x;                                     // Select data RAM to load from / store to
305
reg dram_select_m;
306
reg dram_bypass_en;                                     // RAW in data RAM; read latched (bypass) value rather than value from memory
307
reg [`LM32_WORD_RNG] dram_bypass_data;                  // Latched value of store'd data to data RAM
308
wire [`LM32_WORD_RNG] dram_data_out;                    // Data read from data RAM
309
wire [`LM32_WORD_RNG] dram_data_m;                      // Data read from data RAM: bypass value or value from memory
310
wire [`LM32_WORD_RNG] dram_store_data_m;                // Data to write to RAM
311
`endif
312
wire wb_select_x;                                       // Select Wishbone to load from / store to
313
`ifdef CFG_IROM_ENABLED
314
wire irom_select_x;                                     // Select instruction ROM to load from / store to
315
reg  irom_select_m;
316
`endif
317
reg wb_select_m;
318
reg [`LM32_WORD_RNG] wb_data_m;                         // Data read from Wishbone
319
reg wb_load_complete;                                   // Indicates when a Wishbone load is complete
320
`ifdef CFG_MMU_ENABLED
321
wire [`LM32_WORD_RNG] physical_load_store_address_m;    // X stage physical load/store address
322
wire cache_inhibit_x;                                   // Indicates if data cache should be bypassed
323
`endif
324
 
325
/////////////////////////////////////////////////////
326
// Functions
327
/////////////////////////////////////////////////////
328
 
329
/////////////////////////////////////////////////////
330
// Instantiations
331
/////////////////////////////////////////////////////
332
 
333
`ifdef CFG_DRAM_ENABLED
334
`define LM32_DRAM_WIDTH `CLOG2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)
335
`define LM32_DRAM_RNG (`LM32_DRAM_WIDTH-1+2):2
336
 
337
// Data RAM
338
lm32_ram #(
339
    .data_width    (`LM32_WORD_WIDTH),
340
    .address_width (`LM32_DRAM_WIDTH),
341
    .init_file     (`CFG_DRAM_INIT_FILE)
342
  ) ram (
343
    // ----- Inputs -------
344
    .read_clk      (clk_i),
345
    .write_clk     (clk_i),
346
    .reset         (rst_i),
347
    .enable_read   (!stall_x),
348
    .read_address  (load_store_address_x[`LM32_DRAM_RNG]),
349
    .enable_write  (!stall_m),
350
    .write_address (load_store_address_m[`LM32_DRAM_RNG]),
351
    .write_data    (dram_store_data_m),
352
    .write_enable  (store_q_m & dram_select_m),
353
    // ----- Outputs -------
354
    .read_data     (dram_data_out)
355
    );
356
 
357
   /*----------------------------------------------------------------------
358
    EBRs cannot perform reads from location 'written to' on the same clock
359
    edge. Therefore bypass logic is required to latch the store'd value
360
    and use it for the load (instead of value from memory).
361
    ----------------------------------------------------------------------*/
362
   always @(posedge clk_i `CFG_RESET_SENSITIVITY)
363
     if (rst_i == `TRUE)
364
       begin
365
          dram_bypass_en <= `FALSE;
366
          dram_bypass_data <= 0;
367
       end
368
     else
369
       begin
370
          if (stall_x == `FALSE)
371
            dram_bypass_data <= dram_store_data_m;
372
 
373
          if (   (stall_m == `FALSE)
374
              && (stall_x == `FALSE)
375
              && (store_q_m == `TRUE)
376
              && (   (load_x == `TRUE)
377
                  || (store_x == `TRUE)
378
                 )
379
              && (load_store_address_x[(`LM32_WORD_WIDTH-1):2] == load_store_address_m[(`LM32_WORD_WIDTH-1):2])
380
             )
381
            dram_bypass_en <= `TRUE;
382
          else
383
            if (   (dram_bypass_en == `TRUE)
384
                && (stall_x == `FALSE)
385
               )
386
              dram_bypass_en <= `FALSE;
387
       end
388
 
389
   assign dram_data_m = dram_bypass_en ? dram_bypass_data : dram_data_out;
390
`endif
391
 
392
`ifdef CFG_DCACHE_ENABLED
393
// Data cache
394
lm32_dcache #(
395
    .associativity          (associativity),
396
    .sets                   (sets),
397
    .bytes_per_line         (bytes_per_line),
398
    .base_address           (base_address),
399
    .limit                  (limit)
400
    ) dcache (
401
    // ----- Inputs -----
402
    .clk_i                  (clk_i),
403
    .rst_i                  (rst_i),
404
    .stall_a                (stall_a),
405
    .stall_x                (stall_x),
406
    .stall_m                (stall_m),
407
    .address_x              (load_store_address_x),
408
`ifdef CFG_MMU_ENABLED
409
    /* VIPT cache, address_m is (only) used for tag */
410
    .address_m              (physical_load_store_address_m),
411
`else
412
    .address_m              (load_store_address_m),
413
`endif
414
    .load_q_m               (load_q_m & dcache_select_m),
415
    .store_q_m              (store_q_m & dcache_select_m),
416
    .store_data             (store_data_m),
417
    .store_byte_select      (byte_enable_m & {4{dcache_select_m}}),
418
    .refill_ready           (dcache_refill_ready),
419
    .refill_data            (wb_data_m),
420
    .dflush                 (dflush),
421
`ifdef CFG_MMU_ENABLED
422
    .dtlb_miss_x            (dtlb_miss_x),
423
`endif
424
    // ----- Outputs -----
425
    .stall_request          (dcache_stall_request),
426
    .restart_request        (dcache_restart_request),
427
    .refill_request         (dcache_refill_request),
428
    .refill_address         (dcache_refill_address),
429
    .refilling              (dcache_refilling),
430
    .load_data              (dcache_data_m)
431
    );
432
`endif
433
 
434
`ifdef CFG_MMU_ENABLED
435
// Data TLB
436
lm32_dtlb dtlb (
437
    // ----- Inputs -----
438
    .clk_i                  (clk_i),
439
    .rst_i                  (rst_i),
440
    .enable                 (dtlb_enable),
441
    .stall_x                (stall_x),
442
    .stall_m                (stall_m),
443
    .address_x              (load_store_address_x),
444
    .address_m              (load_store_address_m),
445
    .load_d                 (load_d),
446
    .store_d                (store_d),
447
    .load_q_x               (load_q_x),
448
    .store_q_x              (store_q_x),
449
    .tlbpaddr               (tlbpaddr),
450
    .tlbvaddr               (tlbvaddr),
451
    .update                 (dtlb_update),
452
    .flush                  (dtlb_flush),
453
    .invalidate             (dtlb_invalidate),
454
    // ----- Outputs -----
455
    .physical_load_store_address_m (physical_load_store_address_m),
456
    .stall_request          (dtlb_stall_request),
457
    .miss_vfn               (dtlb_miss_vfn),
458
    .miss_x                 (dtlb_miss_x),
459
    .fault_x                (dtlb_fault_x),
460
    .cache_inhibit_x        (cache_inhibit_x)
461
    );
462
`endif
463
 
464
/////////////////////////////////////////////////////
465
// Combinational Logic
466
/////////////////////////////////////////////////////
467
 
468
// Select where data should be loaded from / stored to
469
`ifdef CFG_DRAM_ENABLED
470
   assign dram_select_x =    (load_store_address_x >= `CFG_DRAM_BASE_ADDRESS)
471
                          && (load_store_address_x <= `CFG_DRAM_LIMIT);
472
`endif
473
 
474
`ifdef CFG_IROM_ENABLED
475
   assign irom_select_x =    (load_store_address_x >= `CFG_IROM_BASE_ADDRESS)
476
                          && (load_store_address_x <= `CFG_IROM_LIMIT);
477
`endif
478
 
479
`ifdef CFG_DCACHE_ENABLED
480
   assign dcache_select_x =    (load_store_address_x >= `CFG_DCACHE_BASE_ADDRESS)
481
                            && (load_store_address_x <= `CFG_DCACHE_LIMIT)
482
`ifdef CFG_DRAM_ENABLED
483
                            && (dram_select_x == `FALSE)
484
`endif
485
`ifdef CFG_IROM_ENABLED
486
                            && (irom_select_x == `FALSE)
487
`endif
488
`ifdef CFG_MMU_ENABLED
489
                            && (cache_inhibit_x == `FALSE)
490
`endif
491
                     ;
492
`endif
493
 
494
   assign wb_select_x =    `TRUE
495
`ifdef CFG_DCACHE_ENABLED
496
                        && !dcache_select_x
497
`endif
498
`ifdef CFG_DRAM_ENABLED
499
                        && !dram_select_x
500
`endif
501
`ifdef CFG_IROM_ENABLED
502
                        && !irom_select_x
503
`endif
504
                     ;
505
 
506
// Make sure data to store is in correct byte lane
507
always @(*)
508
begin
509
    case (size_x)
510
    `LM32_SIZE_BYTE:  store_data_x = {4{store_operand_x[7:0]}};
511
    `LM32_SIZE_HWORD: store_data_x = {2{store_operand_x[15:0]}};
512
    `LM32_SIZE_WORD:  store_data_x = store_operand_x;
513
    default:          store_data_x = {`LM32_WORD_WIDTH{1'bx}};
514
    endcase
515
end
516
 
517
// Generate byte enable accoring to size of load or store and address being accessed
518
always @(*)
519
begin
520
    casez ({size_x, load_store_address_x[1:0]})
521
    {`LM32_SIZE_BYTE, 2'b11}:  byte_enable_x = 4'b0001;
522
    {`LM32_SIZE_BYTE, 2'b10}:  byte_enable_x = 4'b0010;
523
    {`LM32_SIZE_BYTE, 2'b01}:  byte_enable_x = 4'b0100;
524
    {`LM32_SIZE_BYTE, 2'b00}:  byte_enable_x = 4'b1000;
525
    {`LM32_SIZE_HWORD, 2'b1?}: byte_enable_x = 4'b0011;
526
    {`LM32_SIZE_HWORD, 2'b0?}: byte_enable_x = 4'b1100;
527
    {`LM32_SIZE_WORD, 2'b??}:  byte_enable_x = 4'b1111;
528
    default:                   byte_enable_x = 4'bxxxx;
529
    endcase
530
end
531
 
532
`ifdef CFG_DRAM_ENABLED
533
// Only replace selected bytes
534
assign dram_store_data_m[`LM32_BYTE_0_RNG] = byte_enable_m[0] ? store_data_m[`LM32_BYTE_0_RNG] : dram_data_m[`LM32_BYTE_0_RNG];
535
assign dram_store_data_m[`LM32_BYTE_1_RNG] = byte_enable_m[1] ? store_data_m[`LM32_BYTE_1_RNG] : dram_data_m[`LM32_BYTE_1_RNG];
536
assign dram_store_data_m[`LM32_BYTE_2_RNG] = byte_enable_m[2] ? store_data_m[`LM32_BYTE_2_RNG] : dram_data_m[`LM32_BYTE_2_RNG];
537
assign dram_store_data_m[`LM32_BYTE_3_RNG] = byte_enable_m[3] ? store_data_m[`LM32_BYTE_3_RNG] : dram_data_m[`LM32_BYTE_3_RNG];
538
`endif
539
 
540
`ifdef CFG_IROM_ENABLED
541
// Only replace selected bytes
542
assign irom_store_data_m[`LM32_BYTE_0_RNG] = byte_enable_m[0] ? store_data_m[`LM32_BYTE_0_RNG] : irom_data_m[`LM32_BYTE_0_RNG];
543
assign irom_store_data_m[`LM32_BYTE_1_RNG] = byte_enable_m[1] ? store_data_m[`LM32_BYTE_1_RNG] : irom_data_m[`LM32_BYTE_1_RNG];
544
assign irom_store_data_m[`LM32_BYTE_2_RNG] = byte_enable_m[2] ? store_data_m[`LM32_BYTE_2_RNG] : irom_data_m[`LM32_BYTE_2_RNG];
545
assign irom_store_data_m[`LM32_BYTE_3_RNG] = byte_enable_m[3] ? store_data_m[`LM32_BYTE_3_RNG] : irom_data_m[`LM32_BYTE_3_RNG];
546
`endif
547
 
548
`ifdef CFG_IROM_ENABLED
549
   // Instead of implementing a byte-addressable instruction ROM (for store byte instruction),
550
   // a load-and-store architecture is used wherein a 32-bit value is loaded, the requisite
551
   // byte is replaced, and the whole 32-bit value is written back
552
 
553
   assign irom_address_xm = ((irom_select_m == `TRUE) && (store_q_m == `TRUE))
554
                            ? load_store_address_m
555
                            : load_store_address_x;
556
 
557
   // All store instructions perform a write operation in the M stage
558
   assign irom_we_xm =    (irom_select_m == `TRUE)
559
                       && (store_q_m == `TRUE);
560
 
561
   // A single port in instruction ROM is available to load-store unit for doing loads/stores.
562
   // Since every store requires a load (in X stage) and then a store (in M stage), we cannot
563
   // allow load (or store) instructions sequentially after the store instructions to proceed
564
   // until the store instruction has vacated M stage (i.e., completed the store operation)
565
   assign irom_stall_request_x =    (irom_select_x == `TRUE)
566
                                 && (store_q_x == `TRUE);
567
`endif
568
 
569
`ifdef CFG_DCACHE_ENABLED
570
 `ifdef CFG_DRAM_ENABLED
571
  `ifdef CFG_IROM_ENABLED
572
   // WB + DC + DRAM + IROM
573
   assign data_m = wb_select_m == `TRUE
574
                   ? wb_data_m
575
                   : dram_select_m == `TRUE
576
                     ? dram_data_m
577
                     : irom_select_m == `TRUE
578
                       ? irom_data_m
579
                       : dcache_data_m;
580
  `else
581
   // WB + DC + DRAM
582
   assign data_m = wb_select_m == `TRUE
583
                   ? wb_data_m
584
                   : dram_select_m == `TRUE
585
                     ? dram_data_m
586
                     : dcache_data_m;
587
  `endif
588
 `else
589
  `ifdef CFG_IROM_ENABLED
590
   // WB + DC + IROM
591
   assign data_m = wb_select_m == `TRUE
592
                   ? wb_data_m
593
                   : irom_select_m == `TRUE
594
                     ? irom_data_m
595
                     : dcache_data_m;
596
  `else
597
   // WB + DC
598
   assign data_m = wb_select_m == `TRUE
599
                   ? wb_data_m
600
                   : dcache_data_m;
601
  `endif
602
 `endif
603
`else
604
 `ifdef CFG_DRAM_ENABLED
605
  `ifdef CFG_IROM_ENABLED
606
   // WB + DRAM + IROM
607
   assign data_m = wb_select_m == `TRUE
608
                   ? wb_data_m
609
                   : dram_select_m == `TRUE
610
                     ? dram_data_m
611
                     : irom_data_m;
612
  `else
613
   // WB + DRAM
614
   assign data_m = wb_select_m == `TRUE
615
                   ? wb_data_m
616
                   : dram_data_m;
617
  `endif
618
 `else
619
  `ifdef CFG_IROM_ENABLED
620
   // WB + IROM
621
   assign data_m = wb_select_m == `TRUE
622
                   ? wb_data_m
623
                   : irom_data_m;
624
  `else
625
   // WB
626
   assign data_m = wb_data_m;
627
  `endif
628
 `endif
629
`endif
630
 
631
// Sub-word selection and sign/zero-extension for loads
632
always @(*)
633
begin
634
    casez ({size_w, load_store_address_w[1:0]})
635
    {`LM32_SIZE_BYTE, 2'b11}:  load_data_w = {{24{sign_extend_w & data_w[7]}}, data_w[7:0]};
636
    {`LM32_SIZE_BYTE, 2'b10}:  load_data_w = {{24{sign_extend_w & data_w[15]}}, data_w[15:8]};
637
    {`LM32_SIZE_BYTE, 2'b01}:  load_data_w = {{24{sign_extend_w & data_w[23]}}, data_w[23:16]};
638
    {`LM32_SIZE_BYTE, 2'b00}:  load_data_w = {{24{sign_extend_w & data_w[31]}}, data_w[31:24]};
639
    {`LM32_SIZE_HWORD, 2'b1?}: load_data_w = {{16{sign_extend_w & data_w[15]}}, data_w[15:0]};
640
    {`LM32_SIZE_HWORD, 2'b0?}: load_data_w = {{16{sign_extend_w & data_w[31]}}, data_w[31:16]};
641
    {`LM32_SIZE_WORD, 2'b??}:  load_data_w = data_w;
642
    default:                   load_data_w = {`LM32_WORD_WIDTH{1'bx}};
643
    endcase
644
end
645
 
646
// Unused/constant Wishbone signals
647
assign d_bte_o = `LM32_BTYPE_LINEAR;
648
 
649
`ifdef CFG_DCACHE_ENABLED
650
// Generate signal to indicate last word in cache line
651
generate
652
    case (bytes_per_line)
653
    4:
654
    begin
655
assign first_cycle_type = `LM32_CTYPE_END;
656
assign next_cycle_type = `LM32_CTYPE_END;
657
assign last_word = `TRUE;
658
assign first_address = {dcache_refill_address[`LM32_WORD_WIDTH-1:2], 2'b00};
659
    end
660
    8:
661
    begin
662
assign first_cycle_type = `LM32_CTYPE_INCREMENTING;
663
assign next_cycle_type = `LM32_CTYPE_END;
664
assign last_word = (&d_adr_o[addr_offset_msb:addr_offset_lsb]) == 1'b1;
665
assign first_address = {dcache_refill_address[`LM32_WORD_WIDTH-1:addr_offset_msb+1], {addr_offset_width{1'b0}}, 2'b00};
666
    end
667
    default:
668
    begin
669
assign first_cycle_type = `LM32_CTYPE_INCREMENTING;
670
assign next_cycle_type = d_adr_o[addr_offset_msb:addr_offset_lsb+1] == {addr_offset_width-1{1'b1}} ? `LM32_CTYPE_END : `LM32_CTYPE_INCREMENTING;
671
assign last_word = (&d_adr_o[addr_offset_msb:addr_offset_lsb]) == 1'b1;
672
assign first_address = {dcache_refill_address[`LM32_WORD_WIDTH-1:addr_offset_msb+1], {addr_offset_width{1'b0}}, 2'b00};
673
    end
674
    endcase
675
endgenerate
676
`endif
677
 
678
/////////////////////////////////////////////////////
679
// Sequential Logic
680
/////////////////////////////////////////////////////
681
 
682
// Data Wishbone interface
683
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
684
begin
685
    if (rst_i == `TRUE)
686
    begin
687
        d_cyc_o <= `FALSE;
688
        d_stb_o <= `FALSE;
689
        d_dat_o <= {`LM32_WORD_WIDTH{1'b0}};
690
        d_adr_o <= {`LM32_WORD_WIDTH{1'b0}};
691
        d_sel_o <= {`LM32_BYTE_SELECT_WIDTH{`FALSE}};
692
        d_we_o <= `FALSE;
693
        d_cti_o <= `LM32_CTYPE_END;
694
        d_lock_o <= `FALSE;
695
        wb_data_m <= {`LM32_WORD_WIDTH{1'b0}};
696
        wb_load_complete <= `FALSE;
697
        stall_wb_load <= `FALSE;
698
`ifdef CFG_DCACHE_ENABLED
699
        dcache_refill_ready <= `FALSE;
700
`endif
701
    end
702
    else
703
    begin
704
`ifdef CFG_DCACHE_ENABLED
705
        // Refill ready should only be asserted for a single cycle
706
        dcache_refill_ready <= `FALSE;
707
`endif
708
        // Is a Wishbone cycle already in progress?
709
        if (d_cyc_o == `TRUE)
710
        begin
711
            // Is the cycle complete?
712
            if ((d_ack_i == `TRUE) || (d_err_i == `TRUE))
713
            begin
714
`ifdef CFG_DCACHE_ENABLED
715
                if ((dcache_refilling == `TRUE) && (!last_word))
716
                begin
717
                    // Fetch next word of cache line
718
                    d_adr_o[addr_offset_msb:addr_offset_lsb] <= d_adr_o[addr_offset_msb:addr_offset_lsb] + 1'b1;
719
                end
720
                else
721
`endif
722
                begin
723
                    // Refill/access complete
724
                    d_cyc_o <= `FALSE;
725
                    d_stb_o <= `FALSE;
726
                    d_lock_o <= `FALSE;
727
                end
728
`ifdef CFG_DCACHE_ENABLED
729
                d_cti_o <= next_cycle_type;
730
                // If we are performing a refill, indicate to cache next word of data is ready
731
                dcache_refill_ready <= dcache_refilling;
732
`endif
733
                // Register data read from Wishbone interface
734
                wb_data_m <= d_dat_i;
735
                // Don't set when stores complete - otherwise we'll deadlock if load in m stage
736
                wb_load_complete <= !d_we_o;
737
            end
738
            // synthesis translate_off
739
            if (d_err_i == `TRUE)
740
                $display ("Data bus error. Address: %x", d_adr_o);
741
            // synthesis translate_on
742
        end
743
        else
744
        begin
745
`ifdef CFG_DCACHE_ENABLED
746
            if (dcache_refill_request == `TRUE)
747
            begin
748
                // Start cache refill
749
                d_adr_o <= first_address;
750
                d_cyc_o <= `TRUE;
751
                d_sel_o <= {`LM32_WORD_WIDTH/8{`TRUE}};
752
                d_stb_o <= `TRUE;
753
                d_we_o <= `FALSE;
754
                d_cti_o <= first_cycle_type;
755
                //d_lock_o <= `TRUE;
756
            end
757
            else
758
`endif
759
                 if (   (store_q_m == `TRUE)
760
                     && (stall_m == `FALSE)
761
`ifdef CFG_DRAM_ENABLED
762
                     && (dram_select_m == `FALSE)
763
`endif
764
`ifdef CFG_IROM_ENABLED
765
                     && (irom_select_m == `FALSE)
766
`endif
767
                    )
768
            begin
769
                // Data cache is write through, so all stores go to memory
770
                d_dat_o <= store_data_m;
771
                d_adr_o <=
772
`ifdef CFG_MMU_ENABLED
773
                    (dtlb_enable) ? physical_load_store_address_m :
774
`endif
775
                    load_store_address_m;
776
                d_cyc_o <= `TRUE;
777
                d_sel_o <= byte_enable_m;
778
                d_stb_o <= `TRUE;
779
                d_we_o <= `TRUE;
780
                d_cti_o <= `LM32_CTYPE_END;
781
            end
782
            else if (   (load_q_m == `TRUE)
783
                     && (wb_select_m == `TRUE)
784
                     && (wb_load_complete == `FALSE)
785
                     // stall_m will be TRUE, because stall_wb_load will be TRUE
786
                    )
787
            begin
788
                // Read requested address
789
                stall_wb_load <= `FALSE;
790
                d_adr_o <=
791
`ifdef CFG_MMU_ENABLED
792
                    (dtlb_enable) ? physical_load_store_address_m :
793
`endif
794
                    load_store_address_m;
795
                d_cyc_o <= `TRUE;
796
                d_sel_o <= byte_enable_m;
797
                d_stb_o <= `TRUE;
798
                d_we_o <= `FALSE;
799
                d_cti_o <= `LM32_CTYPE_END;
800
            end
801
        end
802
        // Clear load/store complete flag when instruction leaves M stage
803
        if (stall_m == `FALSE)
804
            wb_load_complete <= `FALSE;
805
        // When a Wishbone load first enters the M stage, we need to stall it
806
        if ((load_q_x == `TRUE) && (wb_select_x == `TRUE) && (stall_x == `FALSE))
807
            stall_wb_load <= `TRUE;
808
        // Clear stall request if load instruction is killed
809
        if ((kill_m == `TRUE) || (exception_m == `TRUE))
810
            stall_wb_load <= `FALSE;
811
    end
812
end
813
 
814
// Pipeline registers
815
 
816
// X/M stage pipeline registers
817
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
818
begin
819
    if (rst_i == `TRUE)
820
    begin
821
        sign_extend_m <= `FALSE;
822
        size_m <= 2'b00;
823
        byte_enable_m <= `FALSE;
824
        store_data_m <= {`LM32_WORD_WIDTH{1'b0}};
825
`ifdef CFG_DCACHE_ENABLED
826
        dcache_select_m <= `FALSE;
827
`endif
828
`ifdef CFG_DRAM_ENABLED
829
        dram_select_m <= `FALSE;
830
`endif
831
`ifdef CFG_IROM_ENABLED
832
        irom_select_m <= `FALSE;
833
`endif
834
        wb_select_m <= `FALSE;
835
    end
836
    else
837
    begin
838
        if (stall_m == `FALSE)
839
        begin
840
            sign_extend_m <= sign_extend_x;
841
            size_m <= size_x;
842
            byte_enable_m <= byte_enable_x;
843
            store_data_m <= store_data_x;
844
`ifdef CFG_DCACHE_ENABLED
845
            dcache_select_m <= dcache_select_x;
846
`endif
847
`ifdef CFG_DRAM_ENABLED
848
            dram_select_m <= dram_select_x;
849
`endif
850
`ifdef CFG_IROM_ENABLED
851
            irom_select_m <= irom_select_x;
852
`endif
853
            wb_select_m <= wb_select_x;
854
        end
855
    end
856
end
857
 
858
// M/W stage pipeline registers
859
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
860
begin
861
    if (rst_i == `TRUE)
862
    begin
863
        size_w <= 2'b00;
864
        data_w <= {`LM32_WORD_WIDTH{1'b0}};
865
        sign_extend_w <= `FALSE;
866
    end
867
    else
868
    begin
869
        size_w <= size_m;
870
        data_w <= data_m;
871
        sign_extend_w <= sign_extend_m;
872
    end
873
end
874
 
875
/////////////////////////////////////////////////////
876
// Behavioural Logic
877
/////////////////////////////////////////////////////
878
 
879
// synthesis translate_off
880
 
881
// Check for non-aligned loads or stores
882
always @(posedge clk_i)
883
begin
884
    if (((load_q_m == `TRUE) || (store_q_m == `TRUE)) && (stall_m == `FALSE))
885
    begin
886
        if ((size_m === `LM32_SIZE_HWORD) && (load_store_address_m[0] !== 1'b0))
887
            $display ("Warning: Non-aligned halfword access. Address: 0x%0x Time: %0t.", load_store_address_m, $time);
888
        if ((size_m === `LM32_SIZE_WORD) && (load_store_address_m[1:0] !== 2'b00))
889
            $display ("Warning: Non-aligned word access. Address: 0x%0x Time: %0t.", load_store_address_m, $time);
890
    end
891
end
892
 
893
// synthesis translate_on
894
 
895
endmodule

powered by: WebSVN 2.1.0

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