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_rf_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: Register file for cappuccino pipeline
8
  Handles reading the register file rams and register bypassing.
9
 
10
  Copyright (C) 2012 Authors
11
 
12
  Author(s): Julius Baxter <juliusbaxter@gmail.com>
13
             Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
14
 
15
***************************************************************************** */
16
 
17
`include "mor1kx-defines.v"
18
 
19
module mor1kx_rf_cappuccino
20
  #(
21
    parameter FEATURE_FASTCONTEXTS = "NONE",
22
    parameter OPTION_RF_CLEAR_ON_INIT = 0,
23
    parameter OPTION_RF_NUM_SHADOW_GPR = 0,
24
    parameter OPTION_RF_ADDR_WIDTH = 5,
25
    parameter OPTION_RF_WORDS = 32,
26
    parameter FEATURE_DEBUGUNIT = "NONE",
27
    parameter OPTION_OPERAND_WIDTH = 32
28
    )
29
   (
30
    input                             clk,
31
    input                             rst,
32
 
33
    // pipeline control signal in
34
    input                             padv_decode_i,
35
    input                             padv_execute_i,
36
    input                             padv_ctrl_i,
37
 
38
 
39
    input                             decode_valid_i,
40
 
41
    input                             fetch_rf_adr_valid_i,
42
 
43
    // GPR numbers
44
    input [OPTION_RF_ADDR_WIDTH-1:0]  fetch_rfa_adr_i,
45
    input [OPTION_RF_ADDR_WIDTH-1:0]  fetch_rfb_adr_i,
46
 
47
    input [OPTION_RF_ADDR_WIDTH-1:0]  decode_rfa_adr_i,
48
    input [OPTION_RF_ADDR_WIDTH-1:0]  decode_rfb_adr_i,
49
 
50
    input [OPTION_RF_ADDR_WIDTH-1:0]  execute_rfd_adr_i,
51
    input [OPTION_RF_ADDR_WIDTH-1:0]  ctrl_rfd_adr_i,
52
    input [OPTION_RF_ADDR_WIDTH-1:0]  wb_rfd_adr_i,
53
 
54
    // SPR interface
55
    input [15:0]                       spr_bus_addr_i,
56
    input                             spr_bus_stb_i,
57
    input                             spr_bus_we_i,
58
    input [OPTION_OPERAND_WIDTH-1:0]  spr_bus_dat_i,
59
    output                            spr_gpr_ack_o,
60
    output [OPTION_OPERAND_WIDTH-1:0] spr_gpr_dat_o,
61
 
62
    // Write back signal indications
63
    input                             execute_rf_wb_i,
64
    input                             ctrl_rf_wb_i,
65
    input                             wb_rf_wb_i,
66
 
67
    input [OPTION_OPERAND_WIDTH-1:0]  result_i,
68
    input [OPTION_OPERAND_WIDTH-1:0]  ctrl_alu_result_i,
69
 
70
    input                             pipeline_flush_i,
71
 
72
    output [OPTION_OPERAND_WIDTH-1:0] decode_rfa_o,
73
    output [OPTION_OPERAND_WIDTH-1:0] decode_rfb_o,
74
    output [OPTION_OPERAND_WIDTH-1:0] execute_rfa_o,
75
    output [OPTION_OPERAND_WIDTH-1:0] execute_rfb_o
76
    );
77
 
78
`include "mor1kx_utils.vh"
79
   localparam RF_ADDR_WIDTH = calc_rf_addr_width(OPTION_RF_ADDR_WIDTH,
80
                                                 OPTION_RF_NUM_SHADOW_GPR);
81
 
82
   wire [OPTION_OPERAND_WIDTH-1:0]    rfa_ram_o;
83
   wire [OPTION_OPERAND_WIDTH-1:0]    rfb_ram_o;
84
 
85
   reg [OPTION_OPERAND_WIDTH-1:0]     wb_hazard_result;
86
   reg [OPTION_OPERAND_WIDTH-1:0]     execute_rfa;
87
   reg [OPTION_OPERAND_WIDTH-1:0]     execute_rfb;
88
 
89
   wire [RF_ADDR_WIDTH-1:0]           rfa_rdad;
90
   wire [RF_ADDR_WIDTH-1:0]           rfb_rdad;
91
 
92
   wire                               rfa_rden;
93
   wire                               rfb_rden;
94
 
95
   wire                               rf_wren;
96
   wire [RF_ADDR_WIDTH-1:0]            rf_wradr;
97
   wire [OPTION_OPERAND_WIDTH-1:0]    rf_wrdat;
98
 
99
   reg                                flushing;
100
 
101
   // Keep track of the flush signal, this is needed to not wrongly assert
102
   // execute_hazard after an exception (or rfe) has happened.
103
   // What happens in that case is that the instruction in execute stage is
104
   // invalid until the next padv_decode, so it's execute_rfd_adr can not be
105
   // used to evaluate the execute_hazard.
106
   always @(posedge clk)
107
     if (pipeline_flush_i)
108
       flushing <= 1;
109
     else if (padv_decode_i)
110
       flushing <= 0;
111
 
112
   // Detect hazards
113
   reg execute_hazard_a;
114
   reg execute_hazard_b;
115
   always @(posedge clk)
116
     if (pipeline_flush_i) begin
117
        execute_hazard_a <= 0;
118
        execute_hazard_b <= 0;
119
     end else if (padv_decode_i & !flushing) begin
120
        execute_hazard_a <= execute_rf_wb_i &
121
                            (execute_rfd_adr_i == decode_rfa_adr_i);
122
        execute_hazard_b <= execute_rf_wb_i &
123
                            (execute_rfd_adr_i == decode_rfb_adr_i);
124
     end
125
 
126
   reg [OPTION_OPERAND_WIDTH-1:0] execute_hazard_result_r;
127
   always @(posedge clk)
128
     if (decode_valid_i)
129
       execute_hazard_result_r <= ctrl_alu_result_i;
130
 
131
   wire [OPTION_OPERAND_WIDTH-1:0] execute_hazard_result;
132
   assign execute_hazard_result = decode_valid_i ? ctrl_alu_result_i :
133
                                  execute_hazard_result_r;
134
 
135
   reg ctrl_hazard_a;
136
   reg ctrl_hazard_b;
137
   always @(posedge clk)
138
      if (padv_decode_i) begin
139
         ctrl_hazard_a <= ctrl_rf_wb_i & (ctrl_rfd_adr_i == decode_rfa_adr_i);
140
         ctrl_hazard_b <= ctrl_rf_wb_i & (ctrl_rfd_adr_i == decode_rfb_adr_i);
141
     end
142
 
143
   reg [OPTION_OPERAND_WIDTH-1:0] ctrl_hazard_result_r;
144
   always @(posedge clk)
145
     if (decode_valid_i)
146
       ctrl_hazard_result_r <= result_i;
147
 
148
   wire [OPTION_OPERAND_WIDTH-1:0] ctrl_hazard_result;
149
   assign ctrl_hazard_result = decode_valid_i ? result_i : ctrl_hazard_result_r;
150
 
151
   reg wb_hazard_a;
152
   reg wb_hazard_b;
153
   always @(posedge clk `OR_ASYNC_RST)
154
     if (rst) begin
155
        wb_hazard_a <= 0;
156
        wb_hazard_b <= 0;
157
     end else if (padv_decode_i) begin
158
        wb_hazard_a <= wb_rf_wb_i & (wb_rfd_adr_i == decode_rfa_adr_i);
159
        wb_hazard_b <= wb_rf_wb_i & (wb_rfd_adr_i == decode_rfb_adr_i);
160
     end
161
 
162
   always @(posedge clk)
163
     if (padv_decode_i)
164
       wb_hazard_result <= result_i;
165
 
166
   // Bypassing to decode stage
167
   //
168
   // Since the decode stage doesn't read from the register file, we have to
169
   // save any writes to the current read addresses in decode stage until
170
   // fetch latch in new values.
171
   // When fetch latch in the new values, and a writeback happens at the
172
   // same time, we bypass that value too.
173
 
174
   // Port A
175
   reg                            use_last_wb_a;
176
   reg                            wb_to_decode_bypass_a;
177
   reg [OPTION_OPERAND_WIDTH-1:0] wb_to_decode_result_a;
178
   always @(posedge clk)
179
     if (fetch_rf_adr_valid_i) begin
180
        wb_to_decode_result_a <= result_i;
181
        wb_to_decode_bypass_a <= wb_rf_wb_i & (wb_rfd_adr_i == fetch_rfa_adr_i);
182
        use_last_wb_a <= 0;
183
     end else if (wb_rf_wb_i) begin
184
        if (decode_rfa_adr_i == wb_rfd_adr_i) begin
185
           wb_to_decode_result_a <= result_i;
186
           use_last_wb_a <= 1;
187
        end
188
     end
189
 
190
   wire execute_to_decode_bypass_a;
191
   assign execute_to_decode_bypass_a = ctrl_rf_wb_i &
192
                                       (ctrl_rfd_adr_i == decode_rfa_adr_i);
193
 
194
   wire ctrl_to_decode_bypass_a;
195
   assign ctrl_to_decode_bypass_a = use_last_wb_a | wb_rf_wb_i &
196
                                    (wb_rfd_adr_i == decode_rfa_adr_i);
197
 
198
   wire [OPTION_OPERAND_WIDTH-1:0] ctrl_to_decode_result_a;
199
   assign ctrl_to_decode_result_a = use_last_wb_a ?
200
                                  wb_to_decode_result_a : result_i;
201
 
202
   // Port B
203
   reg                            use_last_wb_b;
204
   reg                            wb_to_decode_bypass_b;
205
   reg [OPTION_OPERAND_WIDTH-1:0] wb_to_decode_result_b;
206
   always @(posedge clk)
207
     if (fetch_rf_adr_valid_i) begin
208
        wb_to_decode_result_b <= result_i;
209
        wb_to_decode_bypass_b <= wb_rf_wb_i & (wb_rfd_adr_i == fetch_rfb_adr_i);
210
        use_last_wb_b <= 0;
211
     end else if (wb_rf_wb_i) begin
212
        if (decode_rfb_adr_i == wb_rfd_adr_i) begin
213
           wb_to_decode_result_b <= result_i;
214
           use_last_wb_b <= 1;
215
        end
216
     end
217
 
218
   wire execute_to_decode_bypass_b;
219
   assign execute_to_decode_bypass_b = ctrl_rf_wb_i &
220
                                       (ctrl_rfd_adr_i == decode_rfb_adr_i);
221
 
222
   wire ctrl_to_decode_bypass_b;
223
   assign ctrl_to_decode_bypass_b = use_last_wb_b | wb_rf_wb_i &
224
                                    (wb_rfd_adr_i == decode_rfb_adr_i);
225
 
226
   wire [OPTION_OPERAND_WIDTH-1:0] ctrl_to_decode_result_b;
227
   assign ctrl_to_decode_result_b = use_last_wb_b ?
228
                                  wb_to_decode_result_b : result_i;
229
 
230
 
231
   assign decode_rfa_o = execute_to_decode_bypass_a ? ctrl_alu_result_i :
232
                         ctrl_to_decode_bypass_a ? ctrl_to_decode_result_a :
233
                         wb_to_decode_bypass_a ? wb_to_decode_result_a :
234
                         rfa_ram_o;
235
 
236
   assign decode_rfb_o = execute_to_decode_bypass_b ? ctrl_alu_result_i :
237
                         ctrl_to_decode_bypass_b ? ctrl_to_decode_result_b :
238
                         wb_to_decode_bypass_b ? wb_to_decode_result_b :
239
                         rfb_ram_o;
240
 
241
   assign execute_rfa_o = execute_hazard_a ? execute_hazard_result :
242
                          ctrl_hazard_a ? ctrl_hazard_result :
243
                          wb_hazard_a ? wb_hazard_result :
244
                          execute_rfa;
245
 
246
   assign execute_rfb_o = execute_hazard_b ? execute_hazard_result :
247
                          ctrl_hazard_b ? ctrl_hazard_result :
248
                          wb_hazard_b ? wb_hazard_result :
249
                          execute_rfb;
250
 
251
   always @(posedge clk)
252
     if (padv_decode_i) begin
253
        execute_rfa <= decode_rfa_o;
254
        execute_rfb <= decode_rfb_o;
255
     end
256
 
257
generate
258
if (FEATURE_DEBUGUNIT!="NONE" || FEATURE_FASTCONTEXTS!="NONE" ||
259
    OPTION_RF_NUM_SHADOW_GPR > 0) begin
260
   wire                            spr_gpr_we;
261
   wire                            spr_gpr_re;
262
   assign spr_gpr_we = (spr_bus_addr_i[15:9] == 7'h2) &
263
                       spr_bus_stb_i & spr_bus_we_i;
264
   assign spr_gpr_re = (spr_bus_addr_i[15:9] == 7'h2) &
265
                       spr_bus_stb_i & !spr_bus_we_i & !padv_ctrl_i;
266
 
267
   reg  spr_gpr_read_ack;
268
   always @(posedge clk)
269
     spr_gpr_read_ack <= spr_gpr_re;
270
 
271
   assign spr_gpr_ack_o = spr_gpr_we & !wb_rf_wb_i |
272
                          spr_gpr_re & spr_gpr_read_ack;
273
 
274
   wire [RF_ADDR_WIDTH-1:0] wb_rfd_adr_expand;
275
   assign wb_rfd_adr_expand[OPTION_RF_ADDR_WIDTH-1:0] = wb_rfd_adr_i;
276
 
277
   assign rf_wren =  wb_rf_wb_i | spr_gpr_we;
278
   assign rf_wradr = wb_rf_wb_i ? wb_rfd_adr_expand : spr_bus_addr_i[RF_ADDR_WIDTH-1:0];
279
   assign rf_wrdat = wb_rf_wb_i ? result_i : spr_bus_dat_i;
280
 
281
   // Zero-pad unused parts of vector
282
   if (OPTION_RF_NUM_SHADOW_GPR > 0) begin
283
      assign wb_rfd_adr_expand[RF_ADDR_WIDTH-1:OPTION_RF_ADDR_WIDTH] =
284
             {(RF_ADDR_WIDTH-OPTION_RF_ADDR_WIDTH){1'b0}};
285
      assign rfa_rdad[RF_ADDR_WIDTH-1:OPTION_RF_ADDR_WIDTH] =
286
             {(RF_ADDR_WIDTH-OPTION_RF_ADDR_WIDTH){1'b0}};
287
      assign rfb_rdad[RF_ADDR_WIDTH-1:OPTION_RF_ADDR_WIDTH] =
288
             {(RF_ADDR_WIDTH-OPTION_RF_ADDR_WIDTH){1'b0}};
289
   end
290
 
291
end else begin
292
   assign spr_gpr_ack_o = 1;
293
 
294
   assign rf_wren =  wb_rf_wb_i;
295
   assign rf_wradr = wb_rfd_adr_i;
296
   assign rf_wrdat = result_i;
297
end
298
endgenerate
299
 
300
   assign rfa_rdad[OPTION_RF_ADDR_WIDTH-1:0] = fetch_rfa_adr_i;
301
   assign rfb_rdad[OPTION_RF_ADDR_WIDTH-1:0] = fetch_rfb_adr_i;
302
   assign rfa_rden = fetch_rf_adr_valid_i;
303
   assign rfb_rden = fetch_rf_adr_valid_i;
304
 
305
   mor1kx_simple_dpram_sclk
306
     #(
307
       .ADDR_WIDTH      (RF_ADDR_WIDTH),
308
       .DATA_WIDTH      (OPTION_OPERAND_WIDTH),
309
       .CLEAR_ON_INIT   (OPTION_RF_CLEAR_ON_INIT),
310
       .ENABLE_BYPASS   (0)
311
       )
312
   rfa
313
     (
314
      .clk              (clk),
315
      .dout             (rfa_ram_o),
316
      .raddr            (rfa_rdad),
317
      .re               (rfa_rden),
318
      .waddr            (rf_wradr),
319
      .we               (rf_wren),
320
      .din              (rf_wrdat)
321
      );
322
 
323
   mor1kx_simple_dpram_sclk
324
     #(
325
       .ADDR_WIDTH      (RF_ADDR_WIDTH),
326
       .DATA_WIDTH      (OPTION_OPERAND_WIDTH),
327
       .CLEAR_ON_INIT   (OPTION_RF_CLEAR_ON_INIT),
328
       .ENABLE_BYPASS   (0)
329
       )
330
   rfb
331
     (
332
      .clk              (clk),
333
      .dout             (rfb_ram_o),
334
      .raddr            (rfb_rdad),
335
      .re               (rfb_rden),
336
      .waddr            (rf_wradr),
337
      .we               (rf_wren),
338
      .din              (rf_wrdat)
339
      );
340
 
341
generate
342
if (FEATURE_DEBUGUNIT!="NONE" || FEATURE_FASTCONTEXTS!="NONE" ||
343
    OPTION_RF_NUM_SHADOW_GPR > 0) begin : rfspr_gen
344
   mor1kx_simple_dpram_sclk
345
     #(
346
       .ADDR_WIDTH      (RF_ADDR_WIDTH),
347
       .DATA_WIDTH      (OPTION_OPERAND_WIDTH),
348
       .CLEAR_ON_INIT   (OPTION_RF_CLEAR_ON_INIT),
349
       .ENABLE_BYPASS   (0)
350
       )
351
   rfspr
352
     (
353
      .clk              (clk),
354
      .dout             (spr_gpr_dat_o),
355
      .raddr            (spr_bus_addr_i[RF_ADDR_WIDTH-1:0]),
356
      .re               (1'b1),
357
      .waddr            (rf_wradr),
358
      .we               (rf_wren),
359
      .din              (rf_wrdat)
360
      );
361
end else begin
362
   assign spr_gpr_dat_o = 0;
363
end
364
endgenerate
365
 
366
endmodule // mor1kx_rf_cappuccino

powered by: WebSVN 2.1.0

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