diff --git a/alu.sv b/alu.sv index 61a87a58..20b8b638 100644 --- a/alu.sv +++ b/alu.sv @@ -327,11 +327,11 @@ module riscv_alu `ALU_XOR: result_o = operand_a_i ^ operand_b_i; // Shift Operations - `ALU_SLL: result_o = shift_left_result; + `ALU_SLL: result_o = shift_left_result; `ALU_SRL, `ALU_SRA, - `ALU_ROR: result_o = shift_result; + `ALU_ROR: result_o = shift_result; // Extension Operations `ALU_EXTBZ, diff --git a/compressed_decoder.sv b/compressed_decoder.sv index af65f933..9606baf0 100644 --- a/compressed_decoder.sv +++ b/compressed_decoder.sv @@ -44,7 +44,7 @@ module riscv_compressed_decoder always_comb begin illegal_instr_o = 1'b0; - instr_o = 'X; + instr_o = 'x; unique case (instr_i[1:0]) // C0 @@ -126,30 +126,34 @@ module riscv_compressed_decoder 2'b11: begin unique case ({instr_i[12], instr_i[6:5]}) - 3'b001, + 3'b000: begin + // c.sub -> sub rd', rd', rs2' + instr_o = {2'b01, 5'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[9:7], `OPCODE_OP}; + end + + 3'b001: begin + // c.xor -> xor rd', rd', rs2' + instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b100, 2'b01, instr_i[9:7], `OPCODE_OP}; + end + + 3'b010: begin + // c.or -> or rd', rd', rs2' + instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b110, 2'b01, instr_i[9:7], `OPCODE_OP}; + end + + 3'b011: begin + // c.and -> and rd', rd', rs2' + instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], `OPCODE_OP}; + end + 3'b100, 3'b101, 3'b110, 3'b111: begin - // 001: c.sll -> sll rd', rd', rs2' - // 100: c.xor -> xor rd', rd', rs2' - // 101: c.srl -> srl rd', rd', rs2' - // 110: c.or -> or rd', rd', rs2' - // 111: c.and -> and rd', rd', rs2' - instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], instr_i[12], instr_i[6:5], 2'b01, instr_i[9:7], `OPCODE_OP}; - end - - 3'b000, - 3'b010: begin - // 000: c.addw - // 010: c.subw + // 100: c.subw + // 101: c.addw illegal_instr_o = 1'b1; end - - 3'b011: begin - // c.sub -> sub rd', rd', rs2' - instr_o = {2'b01, 5'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[9:7], `OPCODE_OP}; - end endcase end endcase diff --git a/controller.sv b/controller.sv index 4e796b4b..3ac1e51b 100644 --- a/controller.sv +++ b/controller.sv @@ -127,7 +127,7 @@ module riscv_controller enum logic [3:0] { RESET, BOOT_SET, SLEEP, FIRST_FETCH, DECODE, BRANCH_DELAY, FLUSH_EX, FLUSH_WB, - DBG_SIGNAL, DBG_WAIT } ctrl_fsm_cs, ctrl_fsm_ns; + DBG_WAIT_BRANCH, DBG_SIGNAL, DBG_WAIT } ctrl_fsm_cs, ctrl_fsm_ns; logic reg_d_ex_is_reg_a_id; logic reg_d_ex_is_reg_b_id; @@ -319,17 +319,19 @@ module riscv_controller // take care of debug // branch conditional will be handled in next state - if(trap_hit_i && jump_in_dec_i != `BRANCH_COND) + if (trap_hit_i) begin // halt pipeline immediately halt_if_o = 1'b1; - halt_id_o = 1'b1; - // TODO: take a second look at this // make sure the current instruction has been executed // before changing state to non-decode - //if (~stall_ex_o) - ctrl_fsm_ns = DBG_SIGNAL; + if (id_valid_i) begin + if (jump_in_id_i == `BRANCH_COND) + ctrl_fsm_ns = DBG_WAIT_BRANCH; + else + ctrl_fsm_ns = DBG_SIGNAL; + end end end else @@ -367,13 +369,26 @@ module riscv_controller ctrl_fsm_ns = DECODE; end + // a branch was in ID when a debug trap is hit + DBG_WAIT_BRANCH: + begin + halt_if_o = 1'b1; + + if (branch_decision_i) begin + // there is a branch in the EX stage that is taken + pc_mux_sel_o = `PC_BRANCH; + pc_set_o = 1'b1; + end + + ctrl_fsm_ns = DBG_SIGNAL; + end + // now we can signal to the debugger that our pipeline is empty and it // can examine our current state DBG_SIGNAL: begin dbg_trap_o = 1'b1; halt_if_o = 1'b1; - halt_id_o = 1'b1; ctrl_fsm_ns = DBG_WAIT; end @@ -383,19 +398,15 @@ module riscv_controller DBG_WAIT: begin halt_if_o = 1'b1; - halt_id_o = 1'b1; if(dbg_set_npc_i == 1'b1) begin - halt_id_o = 1'b0; pc_mux_sel_o = `PC_DBG_NPC; pc_set_o = 1'b1; ctrl_fsm_ns = DBG_WAIT; end if(dbg_stall_i == 1'b0) begin - halt_if_o = 1'b0; - halt_id_o = 1'b0; - ctrl_fsm_ns = DECODE; + ctrl_fsm_ns = BRANCH_DELAY; end end @@ -403,7 +414,6 @@ module riscv_controller FLUSH_EX: begin halt_if_o = 1'b1; - halt_id_o = 1'b1; if(ex_valid_i) ctrl_fsm_ns = FLUSH_WB; @@ -413,7 +423,6 @@ module riscv_controller FLUSH_WB: begin halt_if_o = 1'b1; - halt_id_o = 1'b1; if (~fetch_enable_i) begin // we are requested to go to sleep @@ -422,7 +431,6 @@ module riscv_controller end else begin // unstall pipeline and continue operation halt_if_o = 1'b0; - halt_id_o = 1'b0; if (id_valid_i) ctrl_fsm_ns = DECODE; diff --git a/cs_registers.sv b/cs_registers.sv index 0836fd13..72c22e84 100644 --- a/cs_registers.sv +++ b/cs_registers.sv @@ -31,17 +31,18 @@ module riscv_cs_registers ) ( // Clock and Reset - input logic clk, - input logic rst_n, + input logic clk, + input logic rst_n, // Core and Cluster ID - input logic [4:0] core_id_i, - input logic [4:0] cluster_id_i, + input logic [4:0] core_id_i, + input logic [4:0] cluster_id_i, // Interface to registers (SRAM like) - input logic [11:0] csr_addr_i, - input logic [31:0] csr_wdata_i, - input logic [1:0] csr_op_i, + input logic csr_access_i, + input logic [11:0] csr_addr_i, + input logic [31:0] csr_wdata_i, + input logic [1:0] csr_op_i, output logic [31:0] csr_rdata_o, // Interrupts @@ -270,29 +271,32 @@ module riscv_cs_registers pccr_index = '0; perf_rdata = '0; - unique case (csr_addr_i) - 12'h7A0: begin - is_pcer = 1'b1; - perf_rdata[N_PERF_COUNTERS-1:0] = PCER_q; - end - 12'h7A1: begin - is_pcmr = 1'b1; - perf_rdata[1:0] = PCMR_q; - end - 12'h79F: begin - is_pccr = 1'b1; - pccr_all_sel = 1'b1; - end - default:; - endcase + // only perform csr access if we actually care about the read data + if (csr_access_i) begin + unique case (csr_addr_i) + 12'h7A0: begin + is_pcer = 1'b1; + perf_rdata[N_PERF_COUNTERS-1:0] = PCER_q; + end + 12'h7A1: begin + is_pcmr = 1'b1; + perf_rdata[1:0] = PCMR_q; + end + 12'h79F: begin + is_pccr = 1'b1; + pccr_all_sel = 1'b1; + end + default:; + endcase - // look for 780 to 79F, Performance Counter Counter Registers - if (csr_addr_i[11:5] == 7'b0111100) begin - is_pccr = 1'b1; + // look for 780 to 79F, Performance Counter Counter Registers + if (csr_addr_i[11:5] == 7'b0111100) begin + is_pccr = 1'b1; - pccr_index = csr_addr_i[4:0]; + pccr_index = csr_addr_i[4:0]; - perf_rdata = PCCR_q[csr_addr_i[4:0]]; + perf_rdata = PCCR_q[csr_addr_i[4:0]]; + end end end diff --git a/debug_unit.sv b/debug_unit.sv index d7165fa5..f0630ae4 100644 --- a/debug_unit.sv +++ b/debug_unit.sv @@ -5,15 +5,16 @@ // // // Additional contributions by: // // Andreas Traber - atraber@student.ethz.ch // +// Sven Stucki - svstucki@student.ethz.ch // // // // // // Create Date: 11/07/2014 // -// Design Name: Pipelined OpenRISC Processor // +// Design Name: RISC-V processor core // // Module Name: debug_unit.sv // -// Project Name: OR10N // +// Project Name: RI5CY // // Language: SystemVerilog // // // -// Description: Debug Controller for the pipelined processor // +// Description: Debug controller // // // // // // Revision: // @@ -22,9 +23,6 @@ // changed port and signal names // // // // // -// // -// // -// // //////////////////////////////////////////////////////////////////////////////// @@ -32,59 +30,68 @@ module riscv_debug_unit ( - input logic clk, - input logic rst_n, + input logic clk, + input logic rst_n, // signals to Debug Interface - input logic dbginf_stall_i, - output logic dbginf_bp_o, - input logic dbginf_strobe_i, - output logic dbginf_ack_o, - input logic dbginf_we_i, - input logic [15:0] dbginf_addr_i, - input logic [31:0] dbginf_data_i, - output logic [31:0] dbginf_data_o, + input logic dbginf_stall_i, + output logic dbginf_bp_o, + input logic dbginf_strobe_i, + output logic dbginf_ack_o, + input logic dbginf_we_i, + input logic [15:0] dbginf_addr_i, + input logic [31:0] dbginf_data_i, + output logic [31:0] dbginf_data_o, // signals to core - output logic dbg_st_en_o, // Single-step trace mode enabled - output logic [1:0] dbg_dsr_o, // debug stop register + output logic dbg_st_en_o, // Single-step trace mode enabled + output logic [1:0] dbg_dsr_o, // debug stop register - output logic stall_core_o, - output logic flush_pipe_o, - input logic trap_i, + output logic stall_core_o, + output logic flush_pipe_o, + input logic trap_i, - output logic sp_mux_o, - output logic regfile_mux_o, - output logic regfile_we_o, - output logic [11:0] regfile_addr_o, - output logic [31:0] regfile_wdata_o, - input logic [31:0] regfile_rdata_i, + output logic sp_mux_o, + output logic regfile_mux_o, + output logic regfile_we_o, + output logic [11:0] regfile_addr_o, + output logic [31:0] regfile_wdata_o, + input logic [31:0] regfile_rdata_i, // Signals for PPC & NPC register - input logic [31:0] curr_pc_if_i, - input logic [31:0] curr_pc_id_i, + input logic [31:0] curr_pc_if_i, + input logic [31:0] curr_pc_id_i, + input logic [31:0] branch_pc_i, + + input logic [1:0] jump_in_ex_i, + input logic branch_taken_i, output logic [31:0] npc_o, output logic set_npc_o +); - ); // registers for debug control - logic [1:0] DSR_DP, DSR_DN; // Debug Stop Register: IIE, INTE - logic [1:0] DMR1_DP, DMR1_DN; // only single step trace and branch trace bits + logic [1:0] DSR_DP, DSR_DN; // Debug Stop Register: IIE, INTE + logic [1:0] DMR1_DP, DMR1_DN; // only single step trace and branch trace bits // BP control FSM - enum logic [2:0] {Idle, Trap, DebugStall, StallCore} BP_State_SN, BP_State_SP; + enum logic [2:0] {Idle, Trap, DebugStall, StallCore} BP_State_SN, BP_State_SP; + + // ppc/npc tracking + enum logic [1:0] {IFID, IFEX, IDEX} pc_tracking_fsm_cs, pc_tracking_fsm_ns; + logic [31:0] ppc_int, npc_int; // ack to debug interface assign dbginf_ack_o = dbginf_strobe_i && ((BP_State_SP == StallCore) || (dbginf_addr_i[15:11] == 5'b00110)); + always_comb begin - BP_State_SN = BP_State_SP; - stall_core_o = 1'b0; - dbginf_bp_o = 1'b0; - flush_pipe_o = 1'b0; + BP_State_SN = BP_State_SP; + stall_core_o = 1'b0; + dbginf_bp_o = 1'b0; + flush_pipe_o = 1'b0; case (BP_State_SP) Idle: @@ -152,15 +159,15 @@ module riscv_debug_unit // address decoding, first stage: evaluate higher 5 Bits to detect if debug regs are accessed if(dbginf_addr_i[15:11] == 5'b00110) begin // second stage: evaluate Bits 10:0 to detect which part of debug registers is accessed - casex(dbginf_addr_i[10:0]) + case (dbginf_addr_i[10:0]) 11'd0: begin // NPC set_npc_o = dbginf_we_i; - dbginf_data_o = curr_pc_if_i; + dbginf_data_o = npc_int; end 11'd1: begin // PPC - dbginf_data_o = curr_pc_id_i; + dbginf_data_o = ppc_int; end 11'd16: begin // SP_DMR1 @@ -169,6 +176,7 @@ module riscv_debug_unit else dbginf_data_o[`DMR1_ST+1:`DMR1_ST] = DMR1_DP; end + 11'd20: begin // SP_DSR // currently we only handle IIE and INTE if(dbginf_we_i == 1'b1) @@ -176,8 +184,9 @@ module riscv_debug_unit else dbginf_data_o[7:6] = DSR_DP[1:0]; end + default: ; - endcase // casex [10:0] + endcase end // check if internal registers (GPR or SPR) are accessed else if(BP_State_SP == StallCore) @@ -196,8 +205,8 @@ module riscv_debug_unit // some other SPR is accessed else begin - sp_mux_o = 1'b1; - regfile_addr_o = dbginf_addr_i[11:0]; + sp_mux_o = 1'b1; + regfile_addr_o = dbginf_addr_i[11:0]; if(dbginf_we_i == 1'b1) regfile_we_o = 1'b1; @@ -208,18 +217,67 @@ module riscv_debug_unit end end - // normal FF setup - always_ff@(posedge clk or negedge rst_n) begin - if (~rst_n) begin - DMR1_DP <= 2'b0; - DSR_DP <= 'b0; - BP_State_SP <= Idle; + + always_comb + begin + pc_tracking_fsm_ns = pc_tracking_fsm_cs; + + ppc_int = curr_pc_id_i; + npc_int = curr_pc_if_i; + + // PPC/NPC mux + unique case (pc_tracking_fsm_cs) + IFID: begin + ppc_int = curr_pc_id_i; + npc_int = curr_pc_if_i; + end + + IFEX: begin + ppc_int = branch_pc_i; + npc_int = curr_pc_if_i; + end + + IDEX: begin + ppc_int = branch_pc_i; + npc_int = curr_pc_id_i; + + if (set_npc_o) + pc_tracking_fsm_ns = IFEX; + end + + default: begin + pc_tracking_fsm_ns = IFID; + end + endcase + + // set state if trap is encountered + if (stall_core_o && (BP_State_SP != StallCore)) begin + pc_tracking_fsm_ns = IFID; + + if (jump_in_ex_i == `BRANCH_COND) begin + if (branch_taken_i) + pc_tracking_fsm_ns = IFEX; + else + pc_tracking_fsm_ns = IDEX; + end + end + end + + + always_ff@(posedge clk, negedge rst_n) + begin + if (rst_n == 1'b0) begin + DMR1_DP <= 2'b0; + DSR_DP <= 'b0; + BP_State_SP <= Idle; + pc_tracking_fsm_cs <= IFID; end else begin - DMR1_DP <= DMR1_DN; - DSR_DP <= DSR_DN; - BP_State_SP <= BP_State_SN; + DMR1_DP <= DMR1_DN; + DSR_DP <= DSR_DN; + BP_State_SP <= BP_State_SN; + pc_tracking_fsm_cs <= pc_tracking_fsm_ns; end - end // always_ff@ (posedge clk or negedge rst_n) + end endmodule // debug_unit diff --git a/decoder.sv b/decoder.sv index 0fb91d58..1ffd221c 100644 --- a/decoder.sv +++ b/decoder.sv @@ -81,8 +81,8 @@ module riscv_decoder // hwloop signals output logic [2:0] hwloop_we_o, // write enable for hwloop regs + output logic hwloop_target_mux_sel_o, // selects immediate for hwloop target output logic hwloop_start_mux_sel_o, // selects hwloop start address input - output logic hwloop_end_mux_sel_o, // selects hwloop end address input output logic hwloop_cnt_mux_sel_o, // selects hwloop counter input // jump/branches @@ -144,8 +144,8 @@ module riscv_decoder prepost_useincr_o = 1'b1; hwloop_we = 3'b0; + hwloop_target_mux_sel_o = 1'b0; hwloop_start_mux_sel_o = 1'b0; - hwloop_end_mux_sel_o = 1'b0; hwloop_cnt_mux_sel_o = 1'b0; csr_access_o = 1'b0; @@ -577,7 +577,7 @@ module riscv_decoder /////////////////////////////////////////////// `OPCODE_HWLOOP: begin - jump_target_mux_sel_o = `JT_HWLP; // get PC + I imm from jump target adder + hwloop_target_mux_sel_o = 1'b0; unique case (instr_rdata_i[14:12]) 3'b000: begin @@ -585,31 +585,44 @@ module riscv_decoder hwloop_we[0] = 1'b1; hwloop_start_mux_sel_o = 1'b0; end + 3'b001: begin // lp.endi: set end address to PC + I-type immediate hwloop_we[1] = 1'b1; - hwloop_end_mux_sel_o = 1'b0; // jump target end + 3'b010: begin // lp.count: initialize counter from rs1 hwloop_we[2] = 1'b1; hwloop_cnt_mux_sel_o = 1'b1; rega_used_o = 1'b1; end + 3'b011: begin // lp.counti: initialize counter from I-type immediate hwloop_we[2] = 1'b1; hwloop_cnt_mux_sel_o = 1'b0; end + 3'b100: begin // lp.setup: initialize counter from rs1, set start address to // next instruction and end address to PC + I-type immediate hwloop_we = 3'b111; hwloop_start_mux_sel_o = 1'b1; - hwloop_end_mux_sel_o = 1'b0; hwloop_cnt_mux_sel_o = 1'b1; rega_used_o = 1'b1; end + + 3'b101: begin + // lp.setupi: initialize counter from rs1, set start address to + // next instruction and end address to PC + I-type immediate + hwloop_we = 3'b111; + hwloop_target_mux_sel_o = 1'b1; + hwloop_start_mux_sel_o = 1'b1; + hwloop_cnt_mux_sel_o = 1'b1; + rega_used_o = 1'b1; + end + default: begin illegal_insn_o = 1'b1; end diff --git a/id_stage.sv b/id_stage.sv index e31311e0..54744ca1 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -38,7 +38,9 @@ module riscv_id_stage input logic clk, input logic rst_n, - input logic fetch_enable_i, + input logic test_en_i, + + input logic fetch_enable_i, output logic core_busy_o, output logic is_decoding_o, @@ -81,7 +83,9 @@ module riscv_id_stage input logic ex_valid_i, // EX stage is done input logic wb_valid_i, // WB stage is done - // To the Pipeline ID/EX + // Pipeline ID/EX + output logic [31:0] branch_pc_ex_o, + output logic [31:0] alu_operand_a_ex_o, output logic [31:0] alu_operand_b_ex_o, output logic [31:0] alu_operand_c_ex_o, @@ -253,10 +257,11 @@ module riscv_id_stage logic [1:0] hwloop_regid; logic [2:0] hwloop_we; logic hwloop_jump; + logic hwloop_target_mux_sel; logic hwloop_start_mux_sel; - logic hwloop_end_mux_sel; logic hwloop_cnt_mux_sel; + logic [31:0] hwloop_target; logic [31:0] hwloop_start; logic [31:0] hwloop_end; logic [31:0] hwloop_cnt; @@ -332,23 +337,26 @@ module riscv_id_stage // hwloop register id assign hwloop_regid = instr[8:7]; // rd contains hwloop register id + // hwloop target mux + always_comb + begin + unique case (hwloop_target_mux_sel) + 1'b0: hwloop_target = current_pc_id_i + imm_i_type; + 1'b1: hwloop_target = current_pc_id_i + {imm_z_type[30:0], 1'b0}; + endcase + end + // hwloop start mux always_comb begin unique case (hwloop_start_mux_sel) - 1'b0: hwloop_start = jump_target; // for PC + I imm + 1'b0: hwloop_start = hwloop_target; // for PC + I imm 1'b1: hwloop_start = current_pc_if_i; // for next PC endcase end // hwloop end mux - always_comb - begin - unique case (hwloop_end_mux_sel) - 1'b0: hwloop_end = jump_target; // for PC + I imm - 1'b1: hwloop_end = jump_target; // TODO: PC + (Z imm << 1) for lp.setupi - endcase - end + assign hwloop_end = hwloop_target; // hwloop cnt mux always_comb @@ -373,9 +381,11 @@ module riscv_id_stage begin : jump_target_mux unique case (jump_target_mux_sel) `JT_JAL: jump_target = current_pc_id_i + imm_uj_type; - `JT_JALR: jump_target = regfile_data_ra_id + imm_i_type; // cannot forward rs1 as path is too long `JT_COND: jump_target = current_pc_id_i + imm_sb_type; - `JT_HWLP: jump_target = current_pc_id_i + imm_i_type; + + // JALR: Cannot forward RS1, since the path is too long + `JT_JALR: jump_target = regfile_data_ra_id + imm_i_type; + default: jump_target = regfile_data_ra_id + imm_i_type; endcase end @@ -503,6 +513,8 @@ module riscv_id_stage .clk ( clk ), .rst_n ( rst_n ), + .test_en_i ( test_en_i ), + // Read port a .raddr_a_i ( regfile_addr_ra_id ), .rdata_a_o ( regfile_data_ra_id ), @@ -592,8 +604,8 @@ module riscv_id_stage // hwloop signals .hwloop_we_o ( hwloop_we ), + .hwloop_target_mux_sel_o ( hwloop_target_mux_sel ), .hwloop_start_mux_sel_o ( hwloop_start_mux_sel ), - .hwloop_end_mux_sel_o ( hwloop_end_mux_sel ), .hwloop_cnt_mux_sel_o ( hwloop_cnt_mux_sel ), // jump/branches @@ -804,6 +816,18 @@ module riscv_id_stage // |___|____/ |_____/_/\_\ |_| |___|_| |_____|_____|___|_| \_|_____| // // // ///////////////////////////////////////////////////////////////////////////////// + always_ff @(posedge clk, negedge rst_n) + begin + if (rst_n == 1'b0) + begin + branch_pc_ex_o <= '0; + end + else begin + if (jump_in_id_o == `BRANCH_COND && id_valid_o) + branch_pc_ex_o <= current_pc_id_i; + end + end + always_ff @(posedge clk, negedge rst_n) begin : ID_EX_PIPE_REGISTERS if (rst_n == 1'b0) diff --git a/if_stage.sv b/if_stage.sv index 4d38a903..fdd8636b 100644 --- a/if_stage.sv +++ b/if_stage.sv @@ -85,6 +85,7 @@ module riscv_if_stage // from debug unit input logic [31:0] dbg_npc_i, + input logic dbg_set_npc_i, // pipeline stall input logic halt_if_i, @@ -353,7 +354,7 @@ module riscv_if_stage // take care of jumps and branches // only send one branch request per jump/branch - if (branch_req_Q == 1'b0) begin + if (dbg_set_npc_i || (branch_req_Q == 1'b0)) begin if (pc_set_i) begin valid = 1'b0; diff --git a/include/defines.sv b/include/defines.sv index 35b3bd0d..69846875 100644 --- a/include/defines.sv +++ b/include/defines.sv @@ -56,10 +56,10 @@ `define OPCODE_CUST1 7'h2b // PULP custom -`define OPCODE_STORE_POST 7'h27 -`define OPCODE_LOAD_POST 7'h07 -`define OPCODE_HWLOOP 7'h6b -`define OPCODE_PULP_OP 7'h57 +`define OPCODE_LOAD_POST 7'h0b +`define OPCODE_STORE_POST 7'h2b +`define OPCODE_PULP_OP 7'h5b +`define OPCODE_HWLOOP 7'h7b // instruction masks (for tracer) @@ -280,7 +280,6 @@ `define BRANCH_COND 2'b11 // conditional branches // jump target mux -`define JT_HWLP 2'b00 `define JT_JAL 2'b01 `define JT_JALR 2'b10 `define JT_COND 2'b11 diff --git a/register_file.sv b/register_file.sv index 3a6af5e7..19c4c362 100644 --- a/register_file.sv +++ b/register_file.sv @@ -1,154 +1,156 @@ -module riscv_register_file -#( - parameter ADDR_WIDTH = 5, - parameter DATA_WIDTH = 32 -) -( - // Clock and Reset - input logic clk, - input logic rst_n, - - //Read port R1 - input logic [ADDR_WIDTH-1:0] raddr_a_i, - output logic [DATA_WIDTH-1:0] rdata_a_o, - - //Read port R2 - input logic [ADDR_WIDTH-1:0] raddr_b_i, - output logic [DATA_WIDTH-1:0] rdata_b_o, - - //Read port R3 - input logic [ADDR_WIDTH-1:0] raddr_c_i, - output logic [DATA_WIDTH-1:0] rdata_c_o, - - // Write port W1 - input logic [ADDR_WIDTH-1:0] waddr_a_i, - input logic [DATA_WIDTH-1:0] wdata_a_i, - input logic we_a_i, - - // Write port W2 - input logic [ADDR_WIDTH-1:0] waddr_b_i, - input logic [DATA_WIDTH-1:0] wdata_b_i, - input logic we_b_i -); - - localparam NUM_WORDS = 2**ADDR_WIDTH; - - logic [DATA_WIDTH-1:0] MemContentxDP[NUM_WORDS]; - - logic [NUM_WORDS-1:1] WAddrOneHotxDa; - logic [NUM_WORDS-1:1] WAddrOneHotxDb; - logic [NUM_WORDS-1:1] WAddrOneHotxDb_reg; - - logic [NUM_WORDS-1:1] ClocksxC; - logic [DATA_WIDTH-1:0] WDataIntxDa; - logic [DATA_WIDTH-1:0] WDataIntxDb; - - logic clk_int; - - logic we_int; - - int unsigned i; - int unsigned j; - int unsigned k; - - genvar x; - genvar y; - - assign we_int = we_a_i | we_b_i; - - cluster_clock_gating CG_WE_GLOBAL - ( - .clk_o(clk_int), - .en_i(we_int), - .test_en_i(1'b0), - .clk_i(clk) - ); - - //----------------------------------------------------------------------------- - //-- READ : Read address decoder RAD - //----------------------------------------------------------------------------- - assign rdata_a_o = MemContentxDP[raddr_a_i]; - assign rdata_b_o = MemContentxDP[raddr_b_i]; - assign rdata_c_o = MemContentxDP[raddr_c_i]; - - //----------------------------------------------------------------------------- - //-- WRITE : Write Address Decoder (WAD), combinatorial process - //----------------------------------------------------------------------------- - always_comb - begin : p_WADa - for(i=1; i