../src/lowrisc_ibex_ibex_core_0.1/rtl/ibex_wb_stage.sv Cov: 72.9%
1: // Copyright lowRISC contributors.
2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3: // SPDX-License-Identifier: Apache-2.0
4:
5: /**
6: * Writeback Stage
7: *
8: * Writeback is an optional third pipeline stage. It writes data back to the register file that was
9: * produced in the ID/EX stage or awaits a response to a load/store (LSU writes direct to register
10: * file for load data). If the writeback stage is not present (WritebackStage == 0) this acts as
11: * a simple passthrough to write data direct to the register file.
12: */
13:
14: `include "prim_assert.sv"
15:
16: module ibex_wb_stage #(
17: parameter bit WritebackStage = 1'b0
18: ) (
19: input logic clk_i,
20: input logic rst_ni,
21:
22: input logic en_wb_i,
23: input ibex_pkg::wb_instr_type_e instr_type_wb_i,
24: input logic [31:0] pc_id_i,
25:
26: output logic ready_wb_o,
27: output logic rf_write_wb_o,
28: output logic outstanding_load_wb_o,
29: output logic outstanding_store_wb_o,
30: output logic [31:0] pc_wb_o,
31:
32: input logic [4:0] rf_waddr_id_i,
33: input logic [31:0] rf_wdata_id_i,
34: input logic rf_we_id_i,
35:
36: input logic [31:0] rf_wdata_lsu_i,
37: input logic rf_we_lsu_i,
38:
39: output logic [31:0] rf_wdata_fwd_wb_o,
40:
41: output logic [4:0] rf_waddr_wb_o,
42: output logic [31:0] rf_wdata_wb_o,
43: output logic rf_we_wb_o,
44:
45: input logic lsu_resp_valid_i,
46:
47: output logic instr_done_wb_o
48: );
49:
50: import ibex_pkg::*;
51:
52: // 0 == RF write from ID
53: // 1 == RF write from LSU
54: logic [31:0] rf_wdata_wb_mux [2];
55: logic [1:0] rf_wdata_wb_mux_we;
56:
57: if(WritebackStage) begin : g_writeback_stage
58: logic [31:0] rf_wdata_wb_q;
59: logic rf_we_wb_q;
60: logic [4:0] rf_waddr_wb_q;
61:
62: logic wb_done;
63:
64: logic wb_valid_q;
65: logic [31:0] wb_pc_q;
66: wb_instr_type_e wb_instr_type_q;
67:
68: logic wb_valid_d;
69:
70: // Stage becomes valid if an instruction enters for ID/EX and valid is cleared when instruction
71: // is done
72: assign wb_valid_d = (en_wb_i & ready_wb_o) | (wb_valid_q & ~wb_done);
73:
74: // Writeback for non load/store instructions always completes in a cycle (so instantly done)
75: // Writeback for load/store must wait for response to be received by the LSU
76: // Signal only relevant if wb_valid_q set
77: assign wb_done = (wb_instr_type_q == WB_INSTR_OTHER) | lsu_resp_valid_i;
78:
79: always_ff @(posedge clk_i or negedge rst_ni) begin
80: if(~rst_ni) begin
81: wb_valid_q <= 1'b0;
82: end else begin
83: wb_valid_q <= wb_valid_d;
84: end
85: end
86:
87: always_ff @(posedge clk_i) begin
88: if(en_wb_i) begin
89: rf_we_wb_q <= rf_we_id_i;
90: rf_waddr_wb_q <= rf_waddr_id_i;
91: rf_wdata_wb_q <= rf_wdata_id_i;
92: wb_instr_type_q <= instr_type_wb_i;
93: wb_pc_q <= pc_id_i;
94: end
95: end
96:
97: assign rf_waddr_wb_o = rf_waddr_wb_q;
98: assign rf_wdata_wb_mux[0] = rf_wdata_wb_q;
99: assign rf_wdata_wb_mux_we[0] = rf_we_wb_q & wb_valid_q;
100:
101: assign ready_wb_o = ~wb_valid_q | wb_done;
102:
103: // Instruction in writeback will be writing to register file if either rf_we is set or writeback
104: // is awaiting load data. This is used for determining RF read hazards in ID/EX
105: assign rf_write_wb_o = wb_valid_q & (rf_we_wb_q | (wb_instr_type_q == WB_INSTR_LOAD));
106:
107: assign outstanding_load_wb_o = wb_valid_q & (wb_instr_type_q == WB_INSTR_LOAD);
108: assign outstanding_store_wb_o = wb_valid_q & (wb_instr_type_q == WB_INSTR_STORE);
109:
110: assign pc_wb_o = wb_pc_q;
111:
112: assign instr_done_wb_o = wb_valid_q & wb_done;
113:
114: // Forward data that will be written to the RF back to ID to resolve data hazards. The flopped
115: // rf_wdata_wb_q is used rather than rf_wdata_wb_o as the latter includes read data from memory
116: // that returns too late to be used on the forwarding path.
117: assign rf_wdata_fwd_wb_o = rf_wdata_wb_q;
118: end else begin : g_bypass_wb
119: // without writeback stage just pass through register write signals
120: assign rf_waddr_wb_o = rf_waddr_id_i;
121: assign rf_wdata_wb_mux[0] = rf_wdata_id_i;
122: assign rf_wdata_wb_mux_we[0] = rf_we_id_i;
123:
124: // ready needs to be constant 1 without writeback stage (otherwise ID/EX stage will stall)
125: assign ready_wb_o = 1'b1;
126:
127: // Unused Writeback stage only IO & wiring
128: // Assign inputs and internal wiring to unused signals to satisfy lint checks
129: // Tie-off outputs to constant values
130: logic unused_clk;
131: logic unused_rst;
132: logic unused_en_wb;
133: wb_instr_type_e unused_instr_type_wb;
134: logic [31:0] unused_pc_id;
135: logic unused_lsu_resp_valid;
136:
137: assign unused_clk = clk_i;
138: assign unused_rst = rst_ni;
139: assign unused_en_wb = en_wb_i;
140: assign unused_instr_type_wb = instr_type_wb_i;
141: assign unused_pc_id = pc_id_i;
142: assign unused_lsu_resp_valid = lsu_resp_valid_i;
143:
144: assign outstanding_load_wb_o = 1'b0;
145: assign outstanding_store_wb_o = 1'b0;
146: assign pc_wb_o = '0;
147: assign rf_write_wb_o = 1'b0;
148: assign rf_wdata_fwd_wb_o = 32'b0;
149: assign instr_done_wb_o = 1'b0;
150: end
151:
152: assign rf_wdata_wb_mux[1] = rf_wdata_lsu_i;
153: assign rf_wdata_wb_mux_we[1] = rf_we_lsu_i;
154:
155: // RF write data can come from ID results (all RF writes that aren't because of loads will come
156: // from here) or the LSU (RF writes for load data)
157: assign rf_wdata_wb_o = rf_wdata_wb_mux_we[0] ? rf_wdata_wb_mux[0] : rf_wdata_wb_mux[1];
158: assign rf_we_wb_o = |rf_wdata_wb_mux_we;
159:
160: `ASSERT(RFWriteFromOneSourceOnly, $onehot0(rf_wdata_wb_mux_we))
161: endmodule
162: