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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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