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

powered by: WebSVN 2.1.0

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