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/] [mor1kx-5.0/] [rtl/] [verilog/] [mor1kx_fetch_cappuccino.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
/* ****************************************************************************
2
  This Source Code Form is subject to the terms of the
3
  Open Hardware Description License, v. 1.0. If a copy
4
  of the OHDL was not distributed with this file, You
5
  can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt
6
 
7
  Description: mor1kx fetch/address stage unit
8
 
9
  basically an interface to the ibus/icache subsystem that can react to
10
  exception and branch signals.
11
 
12
  Copyright (C) 2012 Authors
13
 
14
  Author(s): Julius Baxter <juliusbaxter@gmail.com>
15
             Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
16
 
17
***************************************************************************** */
18
 
19
`include "mor1kx-defines.v"
20
 
21
module mor1kx_fetch_cappuccino
22
  #(
23
    parameter OPTION_OPERAND_WIDTH = 32,
24
    parameter OPTION_RESET_PC = {{(OPTION_OPERAND_WIDTH-13){1'b0}},
25
                                 `OR1K_RESET_VECTOR,8'd0},
26
    parameter OPTION_RF_ADDR_WIDTH = 5,
27
    parameter FEATURE_INSTRUCTIONCACHE = "NONE",
28
    parameter OPTION_ICACHE_BLOCK_WIDTH = 5,
29
    parameter OPTION_ICACHE_SET_WIDTH = 9,
30
    parameter OPTION_ICACHE_WAYS = 2,
31
    parameter OPTION_ICACHE_LIMIT_WIDTH = 32,
32
    parameter FEATURE_IMMU = "NONE",
33
    parameter FEATURE_IMMU_HW_TLB_RELOAD = "NONE",
34
    parameter OPTION_IMMU_SET_WIDTH = 6,
35
    parameter OPTION_IMMU_WAYS = 1
36
    )
37
   (
38
    input                                 clk,
39
    input                                 rst,
40
 
41
    // SPR interface
42
    input [15:0]                           spr_bus_addr_i,
43
    input                                 spr_bus_we_i,
44
    input                                 spr_bus_stb_i,
45
    input [OPTION_OPERAND_WIDTH-1:0]       spr_bus_dat_i,
46
    output [OPTION_OPERAND_WIDTH-1:0]      spr_bus_dat_ic_o,
47
    output                                spr_bus_ack_ic_o,
48
    output [OPTION_OPERAND_WIDTH-1:0]      spr_bus_dat_immu_o,
49
    output                                spr_bus_ack_immu_o,
50
 
51
    input                                 ic_enable,
52
    input                                 immu_enable_i,
53
    input                                 supervisor_mode_i,
54
    output                                ic_hit_o,
55
 
56
    // interface to ibus
57
    input                                 ibus_err_i,
58
    input                                 ibus_ack_i,
59
    input [`OR1K_INSN_WIDTH-1:0]           ibus_dat_i,
60
    output                                ibus_req_o,
61
    output [OPTION_OPERAND_WIDTH-1:0]      ibus_adr_o,
62
    output                                ibus_burst_o,
63
 
64
    // pipeline control input
65
    input                                 padv_i,
66
    input                                 padv_ctrl_i, // needed for immu spr
67
 
68
    // interface to decode unit
69
    output reg [OPTION_OPERAND_WIDTH-1:0] pc_decode_o,
70
    output reg [`OR1K_INSN_WIDTH-1:0]      decode_insn_o,
71
    output reg                            fetch_valid_o,
72
    output [OPTION_RF_ADDR_WIDTH-1:0]      fetch_rfa_adr_o,
73
    output [OPTION_RF_ADDR_WIDTH-1:0]      fetch_rfb_adr_o,
74
    output                                fetch_rf_adr_valid_o,
75
 
76
    // branch/jump indication
77
    input                                 decode_branch_i,
78
    input [OPTION_OPERAND_WIDTH-1:0]       decode_branch_target_i,
79
    input                                 ctrl_branch_exception_i,
80
    input [OPTION_OPERAND_WIDTH-1:0]       ctrl_branch_except_pc_i,
81
    input                                 du_restart_i,
82
    input [OPTION_OPERAND_WIDTH-1:0]       du_restart_pc_i,
83
    input                                 decode_op_brcond_i,
84
    input                                 branch_mispredict_i,
85
    input [OPTION_OPERAND_WIDTH-1:0]       execute_mispredict_target_i,
86
 
87
    // pipeline flush input from control unit
88
    input                                 pipeline_flush_i,
89
 
90
    // rfe instruction is being performed
91
    input                                 doing_rfe_i,
92
 
93
    // instruction ibus error indication out
94
    output reg                            decode_except_ibus_err_o,
95
 
96
    // IMMU exceptions
97
    output reg                            decode_except_itlb_miss_o,
98
    output reg                            decode_except_ipagefault_o,
99
 
100
    output reg                            fetch_exception_taken_o
101
   );
102
 
103
   // registers
104
   reg [OPTION_OPERAND_WIDTH-1:0]          pc_fetch;
105
   reg [OPTION_OPERAND_WIDTH-1:0]          pc_addr;
106
   reg                                    ctrl_branch_exception_r;
107
 
108
   wire                                   bus_access_done;
109
   wire                                   ctrl_branch_exception_edge;
110
   wire                                   stall_fetch_valid;
111
   wire                                   addr_valid;
112
   reg                                    flush;
113
   wire                                   flushing;
114
 
115
   reg                                    nop_ack;
116
 
117
   reg                                    imem_err;
118
   wire                                   imem_ack;
119
   wire [`OR1K_INSN_WIDTH-1:0]             imem_dat;
120
 
121
   wire                                   ic_ack;
122
   wire [`OR1K_INSN_WIDTH-1:0]             ic_dat;
123
 
124
   wire                                   ic_refill;
125
   wire                                   ic_refill_req;
126
   wire                                   ic_refill_done;
127
   wire                                   ic_invalidate;
128
   wire [OPTION_OPERAND_WIDTH-1:0]         ic_addr;
129
   wire [OPTION_OPERAND_WIDTH-1:0]         ic_addr_match;
130
 
131
   wire                                   ic_access;
132
 
133
 
134
   wire [OPTION_OPERAND_WIDTH-1:0]         immu_phys_addr;
135
   wire                                   immu_cache_inhibit;
136
   wire                                   pagefault;
137
   wire                                   tlb_miss;
138
   wire                                   except_itlb_miss;
139
   wire                                   except_ipagefault;
140
 
141
   wire                                   immu_busy;
142
 
143
   wire                                   tlb_reload_req;
144
   reg                                    tlb_reload_ack;
145
   wire [OPTION_OPERAND_WIDTH-1:0]         tlb_reload_addr;
146
   reg [OPTION_OPERAND_WIDTH-1:0]          tlb_reload_data;
147
   wire                                   tlb_reload_pagefault;
148
   wire                                   tlb_reload_busy;
149
 
150
   reg                                    fetching_brcond;
151
   reg                                    fetching_mispredicted_branch;
152
   wire                                   mispredict_stall;
153
 
154
   reg                                    exception_while_tlb_reload;
155
   wire                                   except_ipagefault_clear;
156
 
157
   assign bus_access_done = (imem_ack | imem_err | nop_ack) & !immu_busy &
158
                            !tlb_reload_busy;
159
   assign ctrl_branch_exception_edge = ctrl_branch_exception_i &
160
                                       !ctrl_branch_exception_r;
161
 
162
   /* used to keep fetch_valid_o high during stall */
163
   assign stall_fetch_valid = !padv_i & fetch_valid_o;
164
 
165
   assign addr_valid = bus_access_done & padv_i &
166
                       !(except_itlb_miss | except_ipagefault) |
167
                       decode_except_itlb_miss_o & ctrl_branch_exception_i |
168
                       decode_except_ipagefault_o & ctrl_branch_exception_i |
169
                       doing_rfe_i;
170
 
171
   assign except_itlb_miss = tlb_miss & immu_enable_i & bus_access_done &
172
                             !mispredict_stall & !doing_rfe_i;
173
   assign except_ipagefault = pagefault & immu_enable_i & bus_access_done &
174
                              !mispredict_stall & !doing_rfe_i |
175
                              tlb_reload_pagefault;
176
 
177
   assign fetch_rfa_adr_o = imem_dat[`OR1K_RA_SELECT];
178
   assign fetch_rfb_adr_o = imem_dat[`OR1K_RB_SELECT];
179
   assign fetch_rf_adr_valid_o = bus_access_done & padv_i;
180
 
181
   // Signal to indicate that the ongoing bus access should be flushed
182
   always @(posedge clk `OR_ASYNC_RST)
183
     if (rst)
184
       flush <= 0;
185
     else if (bus_access_done & padv_i | du_restart_i)
186
       flush <= 0;
187
     else if (pipeline_flush_i)
188
       flush <= 1;
189
 
190
   // pipeline_flush_i comes on the same edge as branch_except_occur during
191
   // rfe, but on an edge later when an exception occurs, but we always need
192
   // to keep on flushing when the branch signal comes in.
193
   assign flushing = pipeline_flush_i | ctrl_branch_exception_edge | flush;
194
 
195
   // Branch misprediction stall logic
196
   always @(posedge clk `OR_ASYNC_RST)
197
     if (rst)
198
       fetching_brcond <= 0;
199
     else if (pipeline_flush_i)
200
       fetching_brcond <= 0;
201
     else if (decode_op_brcond_i & addr_valid)
202
       fetching_brcond <= 1;
203
     else if (bus_access_done & padv_i | du_restart_i)
204
       fetching_brcond <= 0;
205
 
206
   always @(posedge clk `OR_ASYNC_RST)
207
     if (rst)
208
       fetching_mispredicted_branch <= 0;
209
     else if (pipeline_flush_i)
210
       fetching_mispredicted_branch <= 0;
211
     else if (bus_access_done & padv_i | du_restart_i)
212
       fetching_mispredicted_branch <= 0;
213
     else if (fetching_brcond & branch_mispredict_i & padv_i)
214
       fetching_mispredicted_branch <= 1;
215
 
216
   assign mispredict_stall = fetching_mispredicted_branch |
217
                             branch_mispredict_i & fetching_brcond;
218
 
219
   always @(posedge clk `OR_ASYNC_RST)
220
     if (rst)
221
       ctrl_branch_exception_r <= 1'b0;
222
     else
223
       ctrl_branch_exception_r <= ctrl_branch_exception_i;
224
 
225
   // calculate address stage pc
226
   always @(*)
227
      if (rst)
228
        pc_addr = OPTION_RESET_PC;
229
      else if (du_restart_i)
230
        pc_addr = du_restart_pc_i;
231
      else if (ctrl_branch_exception_i & !fetch_exception_taken_o)
232
        pc_addr = ctrl_branch_except_pc_i;
233
      else if (branch_mispredict_i | fetching_mispredicted_branch)
234
        pc_addr = execute_mispredict_target_i;
235
      else if (decode_branch_i)
236
        pc_addr = decode_branch_target_i;
237
      else
238
        pc_addr = pc_fetch + 4;
239
 
240
   // Register fetch pc from address stage
241
   always @(posedge clk `OR_ASYNC_RST)
242
      if (rst)
243
        pc_fetch <= OPTION_RESET_PC;
244
      else if (addr_valid | du_restart_i)
245
        pc_fetch <= pc_addr;
246
 
247
   // fetch_exception_taken_o generation
248
   always @(posedge clk `OR_ASYNC_RST)
249
     if (rst)
250
       fetch_exception_taken_o <= 1'b0;
251
     else if (fetch_exception_taken_o)
252
       fetch_exception_taken_o <= 1'b0;
253
     else if (ctrl_branch_exception_i & bus_access_done & padv_i)
254
       fetch_exception_taken_o <= 1'b1;
255
     else
256
       fetch_exception_taken_o <= 1'b0;
257
 
258
   // fetch_valid_o generation
259
   always @(posedge clk `OR_ASYNC_RST)
260
     if (rst)
261
       fetch_valid_o <= 1'b0;
262
     else if (pipeline_flush_i)
263
       fetch_valid_o <= 1'b0;
264
     else if (bus_access_done & padv_i & !mispredict_stall & !immu_busy &
265
              !tlb_reload_busy | stall_fetch_valid)
266
       fetch_valid_o <= 1'b1;
267
     else
268
       fetch_valid_o <= 1'b0;
269
 
270
   // Register instruction coming in
271
   always @(posedge clk `OR_ASYNC_RST)
272
     if (rst)
273
       decode_insn_o <= {`OR1K_OPCODE_NOP,26'd0};
274
     else if (imem_err | flushing)
275
       decode_insn_o <= {`OR1K_OPCODE_NOP,26'd0};
276
     else if (bus_access_done & padv_i & !mispredict_stall)
277
       decode_insn_o <= imem_dat;
278
 
279
   // Register PC for later stages
280
   always @(posedge clk)
281
     if (bus_access_done & padv_i & !mispredict_stall)
282
       pc_decode_o <= pc_fetch;
283
 
284
   always @(posedge clk `OR_ASYNC_RST)
285
     if (rst)
286
       decode_except_ibus_err_o <= 0;
287
     else if (du_restart_i)
288
       decode_except_ibus_err_o <= 0;
289
     else if (imem_err)
290
       decode_except_ibus_err_o <= 1;
291
     else if (decode_except_ibus_err_o & ctrl_branch_exception_i)
292
       decode_except_ibus_err_o <= 0;
293
 
294
   always @(posedge clk `OR_ASYNC_RST)
295
     if (rst)
296
       decode_except_itlb_miss_o <= 0;
297
     else if (du_restart_i)
298
       decode_except_itlb_miss_o <= 0;
299
     else if (tlb_reload_busy)
300
       decode_except_itlb_miss_o <= 0;
301
     else if (except_itlb_miss)
302
       decode_except_itlb_miss_o <= 1;
303
     else if (decode_except_itlb_miss_o & ctrl_branch_exception_i)
304
       decode_except_itlb_miss_o <= 0;
305
 
306
   assign except_ipagefault_clear = decode_except_ipagefault_o &
307
                                    ctrl_branch_exception_i;
308
 
309
   always @(posedge clk `OR_ASYNC_RST)
310
     if (rst)
311
       decode_except_ipagefault_o <= 0;
312
     else if (du_restart_i)
313
       decode_except_ipagefault_o <= 0;
314
     else if (except_ipagefault)
315
       decode_except_ipagefault_o <= 1;
316
     else if (except_ipagefault_clear)
317
       decode_except_ipagefault_o <= 0;
318
 
319
   // Bus access logic
320
   localparam [2:0]
321
     IDLE               = 0,
322
     READ               = 1,
323
     TLB_RELOAD         = 2,
324
     IC_REFILL          = 3;
325
 
326
   reg [2:0] state;
327
 
328
   reg [OPTION_OPERAND_WIDTH-1:0] ibus_adr;
329
   wire [OPTION_OPERAND_WIDTH-1:0] next_ibus_adr;
330
   reg [`OR1K_INSN_WIDTH-1:0]      ibus_dat;
331
   reg                            ibus_req;
332
   reg                            ibus_ack;
333
 
334
   wire                           ibus_access;
335
 
336
   //
337
   // Under certain circumstances, there is a need to insert an nop
338
   // into the pipeline in order for it to move forward.
339
   // Here those conditions are handled and an acknowledged signal
340
   // is generated.
341
   //
342
   always @(posedge clk `OR_ASYNC_RST)
343
     if (rst)
344
       nop_ack <= 0;
345
     else
346
       nop_ack <= padv_i & !bus_access_done & !(ibus_req & ibus_access) &
347
                  ((immu_enable_i & (tlb_miss | pagefault) &
348
                    !tlb_reload_busy) |
349
                   ctrl_branch_exception_edge & !tlb_reload_busy |
350
                   exception_while_tlb_reload & !tlb_reload_busy |
351
                   tlb_reload_pagefault |
352
                   mispredict_stall);
353
 
354
   assign ibus_access = (!ic_access | tlb_reload_busy | ic_invalidate) &
355
                        !ic_refill |
356
                        (state != IDLE) & (state != IC_REFILL) |
357
                        ibus_ack;
358
   assign imem_ack = ibus_access ? ibus_ack : ic_ack;
359
   assign imem_dat = (nop_ack | except_itlb_miss | except_ipagefault) ?
360
                     {`OR1K_OPCODE_NOP,26'd0} :
361
                     ibus_access ? ibus_dat : ic_dat;
362
   assign ibus_adr_o = ibus_adr;
363
   assign ibus_req_o = ibus_req;
364
   assign ibus_burst_o = !ibus_access & ic_refill & !ic_refill_done;
365
 
366
   assign next_ibus_adr = (OPTION_ICACHE_BLOCK_WIDTH == 5) ?
367
                          {ibus_adr[31:5], ibus_adr[4:0] + 5'd4} : // 32 byte
368
                          {ibus_adr[31:4], ibus_adr[3:0] + 4'd4};  // 16 byte
369
 
370
   always @(posedge clk `OR_ASYNC_RST)
371
     if (rst)
372
       imem_err <= 0;
373
     else
374
       imem_err <= ibus_err_i;
375
 
376
   always @(posedge clk) begin
377
      ibus_ack <= 0;
378
      exception_while_tlb_reload <= 0;
379
      tlb_reload_ack <= 0;
380
 
381
      case (state)
382
        IDLE: begin
383
           ibus_req <= 0;
384
           if (padv_i & ibus_access & !ibus_ack & !imem_err & !nop_ack) begin
385
              if (tlb_reload_req) begin
386
                 ibus_adr <= tlb_reload_addr;
387
                 ibus_req <= 1;
388
                 state <= TLB_RELOAD;
389
              end else if (immu_enable_i) begin
390
                 ibus_adr <= immu_phys_addr;
391
                 if (!tlb_miss & !pagefault & !immu_busy) begin
392
                    ibus_req <= 1;
393
                    state <= READ;
394
                 end
395
              end else if (!ctrl_branch_exception_i | doing_rfe_i) begin
396
                 ibus_adr <= pc_fetch;
397
                 ibus_req <= 1;
398
                 state <= READ;
399
              end
400
           end else if (ic_refill_req) begin
401
              ibus_adr <= ic_addr_match;
402
              ibus_req <= 1;
403
              state <= IC_REFILL;
404
           end
405
        end
406
 
407
        IC_REFILL: begin
408
           ibus_req <= 1;
409
           if (ibus_ack_i) begin
410
              ibus_adr <= next_ibus_adr;
411
              if (ic_refill_done) begin
412
                 ibus_req <= 0;
413
                 state <= IDLE;
414
              end
415
           end
416
           if (ibus_err_i) begin
417
              ibus_req <= 0;
418
              state <= IDLE;
419
           end
420
        end
421
 
422
        READ: begin
423
           ibus_ack <= ibus_ack_i;
424
           ibus_dat <= ibus_dat_i;
425
           if (ibus_ack_i | ibus_err_i) begin
426
              ibus_req <= 0;
427
              state <= IDLE;
428
           end
429
        end
430
 
431
        TLB_RELOAD: begin
432
           if (ctrl_branch_exception_i)
433
             exception_while_tlb_reload <= 1;
434
 
435
           ibus_adr <= tlb_reload_addr;
436
           tlb_reload_data <= ibus_dat_i;
437
           tlb_reload_ack <= ibus_ack_i & tlb_reload_req;
438
 
439
           if (!tlb_reload_req)
440
             state <= IDLE;
441
 
442
           ibus_req <= tlb_reload_req;
443
           if (ibus_ack_i | tlb_reload_ack)
444
             ibus_req <= 0;
445
        end
446
 
447
        default:
448
          state <= IDLE;
449
      endcase // case (state)
450
 
451
      if (rst) begin
452
         ibus_req <= 0;
453
         state <= IDLE;
454
      end
455
   end
456
 
457
 
458
   assign ic_addr = (addr_valid | du_restart_i) ? pc_addr : pc_fetch;
459
   assign ic_addr_match = immu_enable_i ? immu_phys_addr : pc_fetch;
460
 
461
generate
462
if (FEATURE_INSTRUCTIONCACHE!="NONE") begin : icache_gen
463
   reg                                    ic_enable_r;
464
   always @(posedge clk `OR_ASYNC_RST)
465
     if (rst)
466
       ic_enable_r <= 0;
467
     else if (ic_enable & !ibus_req)
468
       ic_enable_r <= 1;
469
     else if (!ic_enable & !ic_refill)
470
       ic_enable_r <= 0;
471
   wire ic_enabled = ic_enable & ic_enable_r;
472
   wire ic_refill_allowed = (!((tlb_miss | pagefault) & immu_enable_i) &
473
                              !ctrl_branch_exception_i & !pipeline_flush_i &
474
                              !mispredict_stall | doing_rfe_i) &
475
                              !tlb_reload_busy & !immu_busy;
476
   wire ic_req = padv_i & !decode_except_ibus_err_o &
477
                   !decode_except_itlb_miss_o & !except_itlb_miss &
478
                   !decode_except_ipagefault_o & !except_ipagefault &
479
                   ic_access & ic_refill_allowed;
480
 
481
   if (OPTION_ICACHE_LIMIT_WIDTH == OPTION_OPERAND_WIDTH) begin
482
      assign ic_access = ic_enabled &
483
                         !(immu_cache_inhibit & immu_enable_i);
484
   end else if (OPTION_ICACHE_LIMIT_WIDTH < OPTION_OPERAND_WIDTH) begin
485
      assign ic_access = ic_enabled &
486
                         ic_addr_match[OPTION_OPERAND_WIDTH-1:
487
                                       OPTION_ICACHE_LIMIT_WIDTH] == 0 &
488
                         !(immu_cache_inhibit & immu_enable_i);
489
   end else begin
490
      initial begin
491
         $display("ERROR: OPTION_ICACHE_LIMIT_WIDTH > OPTION_OPERAND_WIDTH");
492
         $finish();
493
      end
494
   end
495
 
496
   /* mor1kx_icache AUTO_TEMPLATE (
497
    // Outputs
498
    .cpu_ack_o                  (ic_ack),
499
    .cpu_dat_o                  (ic_dat[OPTION_OPERAND_WIDTH-1:0]),
500
    .spr_bus_dat_o              (spr_bus_dat_ic_o),
501
    .spr_bus_ack_o              (spr_bus_ack_ic_o),
502
    .refill_o                   (ic_refill),
503
    .refill_req_o               (ic_refill_req),
504
    .refill_done_o              (ic_refill_done),
505
    .invalidate_o               (ic_invalidate),
506
    // Inputs
507
    .rst                        (rst),
508
    .ic_imem_err_i      (imem_err),
509
    .ic_access_i                (ic_access),
510
    .cpu_adr_i                  (ic_addr),
511
    .cpu_adr_match_i            (ic_addr_match),
512
    .cpu_req_i                  (ic_req),
513
    .wradr_i                    (ibus_adr),
514
    .wrdat_i                    (ibus_dat_i),
515
    .we_i                       (ibus_ack_i),
516
    );*/
517
 
518
   mor1kx_icache
519
     #(
520
       .OPTION_ICACHE_BLOCK_WIDTH(OPTION_ICACHE_BLOCK_WIDTH),
521
       .OPTION_ICACHE_SET_WIDTH(OPTION_ICACHE_SET_WIDTH),
522
       .OPTION_ICACHE_WAYS(OPTION_ICACHE_WAYS),
523
       .OPTION_ICACHE_LIMIT_WIDTH(OPTION_ICACHE_LIMIT_WIDTH)
524
       )
525
   mor1kx_icache
526
     (/*AUTOINST*/
527
      // Outputs
528
      .refill_o                         (ic_refill),             // Templated
529
      .refill_req_o                     (ic_refill_req),         // Templated
530
      .refill_done_o                    (ic_refill_done),        // Templated
531
      .invalidate_o                     (ic_invalidate),         // Templated
532
      .cpu_ack_o                        (ic_ack),                // Templated
533
      .cpu_dat_o                        (ic_dat[OPTION_OPERAND_WIDTH-1:0]), // Templated
534
      .spr_bus_dat_o                    (spr_bus_dat_ic_o),      // Templated
535
      .spr_bus_ack_o                    (spr_bus_ack_ic_o),      // Templated
536
      .cache_hit_o                      (ic_hit_o),
537
      // Inputs
538
      .clk                              (clk),
539
      .rst                              (rst),           // Templated
540
      .ic_imem_err_i    (imem_err),
541
      .ic_access_i                      (ic_access),             // Templated
542
      .cpu_adr_i                        (ic_addr),               // Templated
543
      .cpu_adr_match_i                  (ic_addr_match),         // Templated
544
      .cpu_req_i                        (ic_req),                // Templated
545
      .wradr_i                          (ibus_adr),              // Templated
546
      .wrdat_i                          (ibus_dat_i),            // Templated
547
      .we_i                             (ibus_ack_i),            // Templated
548
      .spr_bus_addr_i                   (spr_bus_addr_i[15:0]),
549
      .spr_bus_we_i                     (spr_bus_we_i),
550
      .spr_bus_stb_i                    (spr_bus_stb_i),
551
      .spr_bus_dat_i                    (spr_bus_dat_i[OPTION_OPERAND_WIDTH-1:0]));
552
end else begin // block: icache_gen
553
   assign ic_access = 0;
554
   assign ic_refill = 0;
555
   assign ic_refill_req = 1'b0;
556
   assign ic_refill_done = 0;
557
   assign ic_ack = 0;
558
   assign ic_hit_o = 0;
559
   assign ic_dat = 0;
560
   assign ic_invalidate = 0;
561
   assign spr_bus_dat_ic_o = 0;
562
   assign spr_bus_ack_ic_o = 0;
563
end
564
endgenerate
565
 
566
generate
567
if (FEATURE_IMMU!="NONE") begin : immu_gen
568
   wire  [OPTION_OPERAND_WIDTH-1:0] virt_addr = ic_addr;
569
   wire                             immu_spr_bus_stb;
570
   wire                             immu_enable;
571
   // small hack to delay immu spr reads by one cycle
572
   // ideally the spr accesses should work so that the address is presented
573
   // in execute stage and the delayed data should be available in control
574
   // stage, but this is not how things currently work.
575
   assign immu_spr_bus_stb = spr_bus_stb_i & (!padv_ctrl_i | spr_bus_we_i);
576
 
577
   assign immu_enable = immu_enable_i & !pipeline_flush_i & !mispredict_stall;
578
 
579
   /* mor1kx_immu AUTO_TEMPLATE (
580
    .enable_i                           (immu_enable),
581
    .busy_o                             (immu_busy),
582
    .phys_addr_o                        (immu_phys_addr),
583
    .cache_inhibit_o                    (immu_cache_inhibit),
584
    .tlb_miss_o                         (tlb_miss),
585
    .tlb_reload_req_o                   (tlb_reload_req),
586
    .tlb_reload_addr_o                  (tlb_reload_addr),
587
    .tlb_reload_pagefault_o             (tlb_reload_pagefault),
588
    .tlb_reload_ack_i                   (tlb_reload_ack),
589
    .tlb_reload_data_i                  (tlb_reload_data),
590
    .tlb_reload_busy_o                  (tlb_reload_busy),
591
    .tlb_reload_pagefault_clear_i       (except_ipagefault_clear),
592
    .pagefault_o                        (pagefault),
593
    .spr_bus_dat_o                      (spr_bus_dat_immu_o),
594
    .spr_bus_ack_o                      (spr_bus_ack_immu_o),
595
    .spr_bus_stb_i                      (immu_spr_bus_stb),
596
    .virt_addr_i                        (virt_addr),
597
    .virt_addr_match_i                  (pc_fetch),
598
    ); */
599
   mor1kx_immu
600
     #(
601
       .FEATURE_IMMU_HW_TLB_RELOAD(FEATURE_IMMU_HW_TLB_RELOAD),
602
       .OPTION_OPERAND_WIDTH(OPTION_OPERAND_WIDTH),
603
       .OPTION_IMMU_SET_WIDTH(OPTION_IMMU_SET_WIDTH),
604
       .OPTION_IMMU_WAYS(OPTION_IMMU_WAYS)
605
       )
606
   mor1kx_immu
607
     (/*AUTOINST*/
608
      // Outputs
609
      .busy_o                           (immu_busy),             // Templated
610
      .phys_addr_o                      (immu_phys_addr),        // Templated
611
      .cache_inhibit_o                  (immu_cache_inhibit),    // Templated
612
      .tlb_miss_o                       (tlb_miss),              // Templated
613
      .pagefault_o                      (pagefault),             // Templated
614
      .tlb_reload_req_o                 (tlb_reload_req),        // Templated
615
      .tlb_reload_addr_o                (tlb_reload_addr),       // Templated
616
      .tlb_reload_pagefault_o           (tlb_reload_pagefault),  // Templated
617
      .tlb_reload_busy_o                (tlb_reload_busy),       // Templated
618
      .spr_bus_dat_o                    (spr_bus_dat_immu_o),    // Templated
619
      .spr_bus_ack_o                    (spr_bus_ack_immu_o),    // Templated
620
      // Inputs
621
      .clk                              (clk),
622
      .rst                              (rst),
623
      .enable_i                         (immu_enable),           // Templated
624
      .virt_addr_i                      (virt_addr),             // Templated
625
      .virt_addr_match_i                (pc_fetch),              // Templated
626
      .supervisor_mode_i                (supervisor_mode_i),
627
      .tlb_reload_ack_i                 (tlb_reload_ack),        // Templated
628
      .tlb_reload_data_i                (tlb_reload_data),       // Templated
629
      .tlb_reload_pagefault_clear_i     (except_ipagefault_clear), // Templated
630
      .spr_bus_addr_i                   (spr_bus_addr_i[15:0]),
631
      .spr_bus_we_i                     (spr_bus_we_i),
632
      .spr_bus_stb_i                    (immu_spr_bus_stb),      // Templated
633
      .spr_bus_dat_i                    (spr_bus_dat_i[OPTION_OPERAND_WIDTH-1:0]));
634
end else begin
635
   assign immu_cache_inhibit = 0;
636
   assign immu_busy = 0;
637
   assign tlb_miss = 0;
638
   assign pagefault = 0;
639
   assign tlb_reload_busy = 0;
640
   assign tlb_reload_req = 0;
641
   assign tlb_reload_pagefault = 0;
642
end
643
endgenerate
644
 
645
endmodule // mor1kx_fetch_cappuccino

powered by: WebSVN 2.1.0

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