rv_cpu.v 6.97 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
/*
 
 uRV - a tiny and dumb RISC-V core
 Copyright (c) 2015 twl <twlostow@printf.cc>.

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 3.0 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library.
 
*/

`include "rv_defs.v"

`timescale 1ns/1ps

module rv_cpu
  (
   input 	 clk_i,
   input 	 rst_i,

   // instruction mem I/F
   output [31:0] im_addr_o,
   input [31:0]  im_data_i,
   input 	 im_valid_i,

   // data mem I/F
   output [31:0] dm_addr_o,
   output [31:0] dm_data_s_o,
   input [31:0]  dm_data_l_i,
   output [3:0]  dm_data_select_o,
40 41 42 43 44 45
   input 	 dm_ready_i,

   output 	 dm_store_o,
   output 	 dm_load_o,
   input 	 dm_load_done_i,
   input 	 dm_store_done_i 
46 47 48 49 50 51
   );

   wire 	 f_stall;
   wire 	 w_stall;
   wire 	 x_stall;
   wire 	 x_kill;
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
52
   wire 	 f_kill;
53
 
54
   wire [31:0] 	 f2d_pc, f2d_pc_plus_4, f2d_ir;
55 56 57
   wire 	 f2d_ir_valid;
   wire [31:0] 	 x2f_pc_bra;
   wire 	 x2f_bra;
58 59
   wire 	 f2d_valid;
   
60

61
   wire 	 f_stall_req;
62
   
63 64

   wire 	 d2x_valid;
65
   
66 67 68 69 70 71 72 73
   wire [31:0] 	 d2x_pc;
   wire [4:0] 	 rf_rs1, d2x_rs1;
   wire [4:0] 	 rf_rs2, d2x_rs2;
   wire [4:0] 	 d2x_rd;
   wire [4:0] 	 d2x_shamt;
   wire [2:0] 	 d2x_fun;
   wire [4:0] 	 d2x_opcode;
   wire 	 d2x_shifter_sign;
74 75 76 77 78 79

   wire [31:0] 	 d2x_imm;
   wire d2x_is_signed_compare;
   wire d2x_is_signed_alu_op;
   wire d2x_is_add_o;
   wire d2x_is_shift_o;
80
   
81
   wire 	 d2x_load_hazard;
82 83
   wire 	 d_stall, d_kill;

84 85 86 87 88 89 90 91
   
   rv_fetch fetch
     (
      .clk_i(clk_i),
      .rst_i(rst_i),
      .im_addr_o(im_addr_o),
      .im_data_i(im_data_i),
      .im_valid_i(im_valid_i),
92

93
      .f_stall_i(f_stall),
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
94
      .f_kill_i(f_kill),
95
      .f_valid_o(f2d_valid),
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
96
      
97 98
      .f_ir_o(f2d_ir),
      .f_pc_o(f2d_pc),
99

100 101 102 103 104
      .x_pc_bra_i(x2f_pc_bra),
      .x_bra_i(x2f_bra)
      );

   
105
   rv_decode decode
106 107 108 109
     (
      .clk_i(clk_i),
      .rst_i(rst_i),

110 111
      .d_stall_i(d_stall),
      .d_kill_i(d_kill),
112

113 114
      .f_ir_i(f2d_ir),
      .f_pc_i(f2d_pc),
115 116
      .f_valid_i(f2d_valid),

117

118 119
      .rf_rs1_o(rf_rs1),
      .rf_rs2_o(rf_rs2),
120 121

      .x_load_hazard_o(d2x_load_hazard),
122 123
      
      .x_valid_o(d2x_valid),
124 125 126 127 128 129 130 131 132 133 134
      .x_pc_o(d2x_pc),
      .x_rs1_o(d2x_rs1),
      .x_rs2_o(d2x_rs2),
      
      .x_rd_o(d2x_rd),

      .x_shamt_o(d2x_shamt),
      .x_fun_o(d2x_fun),

      .x_opcode_o(d2x_opcode),
      .x_shifter_sign_o(d2x_shifter_sign),
135 136 137 138 139 140

      .x_imm_o(d2x_imm),
      .x_is_signed_compare_o(d2x_is_signed_compare),
      .x_is_signed_alu_op_o(d2x_is_signed_alu_op),
      .x_is_add_o(d2x_is_add),
      .x_is_shift_o(d2x_is_shift)
141 142
      );

Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
143 144 145 146 147 148 149 150 151
      wire [4:0] 	 x2w_rd;
   wire [31:0] 	 x2w_rd_value;
   wire [31:0] 	 x2w_dm_addr;
   wire 	 x2w_rd_write;
   wire [2:0] 	 x2w_fun;
   wire 	 x2w_store;
   wire 	 x2w_load;
      

152 153 154 155 156 157
   wire [31:0] 	 x_rs2_value, x_rs1_value;
   
   wire [4:0] 	 rf_rd;
   wire [31:0] 	 rf_rd_value;
   wire 	 rf_rd_write;

Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
158 159


160
   wire [31:0] 	 rf_bypass_rd_value = x2w_rd_value;
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
161 162 163 164
 //x2w_rd_value;
   wire  	 rf_bypass_rd_write = rf_rd_write && !x2w_load;
// x2w_rd_write && !w_stall;

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
   
   rv_regfile regfile
     (
      .clk_i(clk_i),
      .rst_i(rst_i),

      .x_stall_i(x_stall),
      .w_stall_i(w_stall),

      .rf_rs1_i(rf_rs1),
      .rf_rs2_i(rf_rs2),

      .d_rs1_i(d2x_rs1),
      .d_rs2_i(d2x_rs2),

      .x_rs1_value_o(x_rs1_value),
      .x_rs2_value_o(x_rs2_value),
182
      
183 184
      .w_rd_i(rf_rd),
      .w_rd_value_i(rf_rd_value),
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
185 186 187 188
      .w_rd_store_i(rf_rd_write),

      .w_bypass_rd_write_i(rf_bypass_rd_write),
      .w_bypass_rd_value_i(rf_bypass_rd_value)
189 190
      );

Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
191 192
   
   wire 	 x_load_comb;
193
   wire 	 x2w_load_hazard;
194
   
195

196
   wire 	 w_stall_req;
197 198 199 200 201 202 203 204 205
   
   rv_exec execute
     (
      .clk_i(clk_i),
      .rst_i(rst_i),

      .x_stall_i(x_stall),
      .x_kill_i(x_kill),
      .x_stall_req_o(x_stall_req),
206 207 208 209
      .w_stall_req_i(w_stall_req),

      .d_valid_i(d2x_valid),

210
      .d_load_hazard_i(d2x_load_hazard),
211 212 213
      .d_pc_i(d2x_pc),
      .d_rd_i(d2x_rd),
      .d_fun_i(d2x_fun),
214 215 216 217 218
      .d_imm_i(d2x_imm),
      .d_is_signed_compare_i(d2x_is_signed_compare),
      .d_is_signed_alu_op_i(d2x_is_signed_alu_op),
      .d_is_add_i(d2x_is_add),
      .d_is_shift_i(d2x_is_shift),
219 220 221 222 223 224

      .rf_rs1_value_i(x_rs1_value),
      .rf_rs2_value_i(x_rs2_value),
   
      .d_opcode_i(d2x_opcode),
      .d_shifter_sign_i(d2x_shifter_sign),
225
  
226 227 228 229

      .f_branch_target_o (x2f_pc_bra), // fixme: consistent naming
      .f_branch_take_o (x2f_bra),

Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
230

231
      .w_load_hazard_o(x2w_load_hazard),
232 233 234
   // Writeback stage I/F
      .w_fun_o(x2w_fun),
      .w_load_o(x2w_load),
235
      .w_store_o(x2w_store),
236 237 238 239 240 241 242 243 244
   
      .w_dm_addr_o(x2w_dm_addr),
      .w_rd_o(x2w_rd),
      .w_rd_value_o(x2w_rd_value),
      .w_rd_write_o(x2w_rd_write),

      .dm_addr_o(dm_addr_o),
      .dm_data_s_o(dm_data_s_o),
      .dm_data_select_o(dm_data_select_o),
245 246 247
      .dm_store_o(dm_store_o),
      .dm_load_o(dm_load_o),
      .dm_ready_i(dm_ready_i)
248 249
   );

250 251
   

252 253 254 255 256 257
   rv_writeback writeback
     (
      .clk_i(clk_i),
      .rst_i(rst_i),

      .w_stall_i(w_stall),
258 259
      .w_stall_req_o(w_stall_req),
      
260 261
      .x_fun_i(x2w_fun),
      .x_load_i(x2w_load),
262
      .x_load_hazard_i(x2w_load_hazard),
263 264
      .x_store_i(x2w_store),
      
265 266 267 268 269 270
      .x_rd_i(x2w_rd),
      .x_rd_value_i(x2w_rd_value),
      .x_rd_write_i(x2w_rd_write),
      .x_dm_addr_i(x2w_dm_addr),
      
      .dm_data_l_i(dm_data_l_i),
271 272 273 274
      .dm_load_done_i(dm_load_done_i),
      .dm_store_done_i(dm_store_done_i),
      
      
275 276 277 278 279
      .rf_rd_value_o(rf_rd_value),
      .rf_rd_o(rf_rd),
      .rf_rd_write_o(rf_rd_write)
   );

280
   reg 		 x2f_bra_d0, x2f_bra_d1;
281

282
   always@(posedge clk_i)
283 284 285 286 287 288 289 290
     if(rst_i) begin
	x2f_bra_d0 <= 0;
	x2f_bra_d1 <= 0;
     end else if (!x_stall) begin
	x2f_bra_d0 <= x2f_bra;
	x2f_bra_d1 <= x2f_bra_d0;
     end
   
291
     
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
292 293
// load to Rd in W stage while Rs1/Rs2==RD in fetch stage: assert interlock

294
   
295
/* -----\/----- EXCLUDED -----\/-----
296 297
   reg 		 interlock_load, interlock_load_d0 = 0;
   
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
298
   always@*
299
     interlock_load <= d_load_hazard && x_load_comb;
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
300 301

   always@(posedge clk_i)
302 303 304 305
     if(interlock_load_d0)
       interlock_load_d0 <= 0;
     else
       interlock_load_d0 <= interlock_load;   
306
 -----/\----- EXCLUDED -----/\----- */
307 308

      
309 310 311 312 313 314
   assign f_stall =  x_stall_req || w_stall_req;
// || (interlock_load && !interlock_load_d0);
   assign x_stall =  x_stall_req || w_stall_req;
// || (interlock_load && !interlock_load_d0);
   assign d_stall =  x_stall_req || w_stall_req;
// || (interlock_load && !interlock_load_d0);
315
   assign w_stall =  0;
316

317 318
   assign x_kill = x2f_bra || x2f_bra_d0 || x2f_bra_d1;
   assign d_kill = x2f_bra || x2f_bra_d0;
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
319
   assign f_kill = x2f_bra ;
320

Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
321 322
   
   
323

Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
324 325
   
//&& ~x_bra_d0;
326 327 328 329 330 331 332
   
      
endmodule // rv_cpu