| module ibex_wb_stage ( |
| clk_i, |
| rst_ni, |
| en_wb_i, |
| instr_type_wb_i, |
| pc_id_i, |
| instr_is_compressed_id_i, |
| instr_perf_count_id_i, |
| ready_wb_o, |
| rf_write_wb_o, |
| outstanding_load_wb_o, |
| outstanding_store_wb_o, |
| pc_wb_o, |
| perf_instr_ret_wb_o, |
| perf_instr_ret_compressed_wb_o, |
| perf_instr_ret_wb_spec_o, |
| perf_instr_ret_compressed_wb_spec_o, |
| rf_waddr_id_i, |
| rf_wdata_id_i, |
| rf_we_id_i, |
| rf_wdata_lsu_i, |
| rf_we_lsu_i, |
| rf_wdata_fwd_wb_o, |
| rf_waddr_wb_o, |
| rf_wdata_wb_o, |
| rf_we_wb_o, |
| lsu_resp_valid_i, |
| lsu_resp_err_i, |
| instr_done_wb_o |
| ); |
| parameter [0:0] ResetAll = 1'b0; |
| parameter [0:0] WritebackStage = 1'b0; |
| input wire clk_i; |
| input wire rst_ni; |
| input wire en_wb_i; |
| input wire [1:0] instr_type_wb_i; |
| input wire [31:0] pc_id_i; |
| input wire instr_is_compressed_id_i; |
| input wire instr_perf_count_id_i; |
| output wire ready_wb_o; |
| output wire rf_write_wb_o; |
| output wire outstanding_load_wb_o; |
| output wire outstanding_store_wb_o; |
| output wire [31:0] pc_wb_o; |
| output wire perf_instr_ret_wb_o; |
| output wire perf_instr_ret_compressed_wb_o; |
| output wire perf_instr_ret_wb_spec_o; |
| output wire perf_instr_ret_compressed_wb_spec_o; |
| input wire [4:0] rf_waddr_id_i; |
| input wire [31:0] rf_wdata_id_i; |
| input wire rf_we_id_i; |
| input wire [31:0] rf_wdata_lsu_i; |
| input wire rf_we_lsu_i; |
| output wire [31:0] rf_wdata_fwd_wb_o; |
| output wire [4:0] rf_waddr_wb_o; |
| output wire [31:0] rf_wdata_wb_o; |
| output wire rf_we_wb_o; |
| input wire lsu_resp_valid_i; |
| input wire lsu_resp_err_i; |
| output wire instr_done_wb_o; |
| wire [31:0] rf_wdata_wb_mux [0:1]; |
| wire [1:0] rf_wdata_wb_mux_we; |
| generate |
| if (WritebackStage) begin : g_writeback_stage |
| reg [31:0] rf_wdata_wb_q; |
| reg rf_we_wb_q; |
| reg [4:0] rf_waddr_wb_q; |
| wire wb_done; |
| reg wb_valid_q; |
| reg [31:0] wb_pc_q; |
| reg wb_compressed_q; |
| reg wb_count_q; |
| reg [1:0] wb_instr_type_q; |
| wire wb_valid_d; |
| assign wb_valid_d = (en_wb_i & ready_wb_o) | (wb_valid_q & ~wb_done); |
| assign wb_done = (wb_instr_type_q == 2'd2) | lsu_resp_valid_i; |
| always @(posedge clk_i or negedge rst_ni) |
| if (!rst_ni) |
| wb_valid_q <= 1'b0; |
| else |
| wb_valid_q <= wb_valid_d; |
| if (ResetAll) begin : g_wb_regs_ra |
| always @(posedge clk_i or negedge rst_ni) |
| if (!rst_ni) begin |
| rf_we_wb_q <= 1'sb0; |
| rf_waddr_wb_q <= 1'sb0; |
| rf_wdata_wb_q <= 1'sb0; |
| wb_instr_type_q <= 2'd0; |
| wb_pc_q <= 1'sb0; |
| wb_compressed_q <= 1'sb0; |
| wb_count_q <= 1'sb0; |
| end |
| else if (en_wb_i) begin |
| rf_we_wb_q <= rf_we_id_i; |
| rf_waddr_wb_q <= rf_waddr_id_i; |
| rf_wdata_wb_q <= rf_wdata_id_i; |
| wb_instr_type_q <= instr_type_wb_i; |
| wb_pc_q <= pc_id_i; |
| wb_compressed_q <= instr_is_compressed_id_i; |
| wb_count_q <= instr_perf_count_id_i; |
| end |
| end |
| else begin : g_wb_regs_nr |
| always @(posedge clk_i) |
| if (en_wb_i) begin |
| rf_we_wb_q <= rf_we_id_i; |
| rf_waddr_wb_q <= rf_waddr_id_i; |
| rf_wdata_wb_q <= rf_wdata_id_i; |
| wb_instr_type_q <= instr_type_wb_i; |
| wb_pc_q <= pc_id_i; |
| wb_compressed_q <= instr_is_compressed_id_i; |
| wb_count_q <= instr_perf_count_id_i; |
| end |
| end |
| assign rf_waddr_wb_o = rf_waddr_wb_q; |
| assign rf_wdata_wb_mux[0] = rf_wdata_wb_q; |
| assign rf_wdata_wb_mux_we[0] = rf_we_wb_q & wb_valid_q; |
| assign ready_wb_o = ~wb_valid_q | wb_done; |
| assign rf_write_wb_o = wb_valid_q & (rf_we_wb_q | (wb_instr_type_q == 2'd0)); |
| assign outstanding_load_wb_o = wb_valid_q & (wb_instr_type_q == 2'd0); |
| assign outstanding_store_wb_o = wb_valid_q & (wb_instr_type_q == 2'd1); |
| assign pc_wb_o = wb_pc_q; |
| assign instr_done_wb_o = wb_valid_q & wb_done; |
| assign perf_instr_ret_wb_spec_o = wb_count_q; |
| assign perf_instr_ret_compressed_wb_spec_o = perf_instr_ret_wb_spec_o & wb_compressed_q; |
| assign perf_instr_ret_wb_o = (instr_done_wb_o & wb_count_q) & ~(lsu_resp_valid_i & lsu_resp_err_i); |
| assign perf_instr_ret_compressed_wb_o = perf_instr_ret_wb_o & wb_compressed_q; |
| assign rf_wdata_fwd_wb_o = rf_wdata_wb_q; |
| end |
| else begin : g_bypass_wb |
| assign rf_waddr_wb_o = rf_waddr_id_i; |
| assign rf_wdata_wb_mux[0] = rf_wdata_id_i; |
| assign rf_wdata_wb_mux_we[0] = rf_we_id_i; |
| assign perf_instr_ret_wb_spec_o = 1'b0; |
| assign perf_instr_ret_compressed_wb_spec_o = 1'b0; |
| assign perf_instr_ret_wb_o = (instr_perf_count_id_i & en_wb_i) & ~(lsu_resp_valid_i & lsu_resp_err_i); |
| assign perf_instr_ret_compressed_wb_o = perf_instr_ret_wb_o & instr_is_compressed_id_i; |
| assign ready_wb_o = 1'b1; |
| wire unused_clk; |
| wire unused_rst; |
| wire [1:0] unused_instr_type_wb; |
| wire [31:0] unused_pc_id; |
| assign unused_clk = clk_i; |
| assign unused_rst = rst_ni; |
| assign unused_instr_type_wb = instr_type_wb_i; |
| assign unused_pc_id = pc_id_i; |
| assign outstanding_load_wb_o = 1'b0; |
| assign outstanding_store_wb_o = 1'b0; |
| assign pc_wb_o = 1'sb0; |
| assign rf_write_wb_o = 1'b0; |
| assign rf_wdata_fwd_wb_o = 32'b00000000000000000000000000000000; |
| assign instr_done_wb_o = 1'b0; |
| end |
| endgenerate |
| assign rf_wdata_wb_mux[1] = rf_wdata_lsu_i; |
| assign rf_wdata_wb_mux_we[1] = rf_we_lsu_i; |
| assign rf_wdata_wb_o = ({32 {rf_wdata_wb_mux_we[0]}} & rf_wdata_wb_mux[0]) | ({32 {rf_wdata_wb_mux_we[1]}} & rf_wdata_wb_mux[1]); |
| assign rf_we_wb_o = |rf_wdata_wb_mux_we; |
| endmodule |