diff --git a/controller.sv b/controller.sv index c1313d6b..1c5b58cd 100644 --- a/controller.sv +++ b/controller.sv @@ -72,7 +72,10 @@ module riscv_controller // LSU input logic data_req_ex_i, // data memory access is currently performed in EX stage + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED input logic data_misaligned_i, + `endif // ONLY_ALIGNED input logic data_load_event_i, // CONFIG_REGION: MUL_SUPPORT @@ -146,7 +149,10 @@ module riscv_controller output logic halt_if_o, output logic halt_id_o, + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED output logic misaligned_stall_o, + `endif // ONLY_ALIGNED output logic jr_stall_o, output logic load_stall_o, @@ -581,8 +587,11 @@ module riscv_controller end end + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED // stall because of misaligned data access assign misaligned_stall_o = data_misaligned_i; + `endif // ONLY_ALIGNED // Forwarding control unit @@ -624,12 +633,15 @@ module riscv_controller `endif // THREE_PORT_REG_FILE end + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED // for misaligned memory accesses if (data_misaligned_i) begin operand_a_fw_mux_sel_o = SEL_FW_EX; operand_b_fw_mux_sel_o = SEL_REGFILE; end + `endif // ONLY_ALIGNED // CONFIG_REGION: MUL_SUPPORT `ifdef MUL_SUPPORT else if (mult_multicycle_i) begin diff --git a/decoder.sv b/decoder.sv index 958440c4..1a4b0e96 100644 --- a/decoder.sv +++ b/decoder.sv @@ -33,7 +33,10 @@ module riscv_decoder ( // singals running to/from controller input logic deassert_we_i, // deassert we, we are stalled or not active + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED input logic data_misaligned_i, // misaligned data load/store in progress + `endif // ONLY_ALIGNED // CONFIG_REGION: MUL_SUPPORT `ifdef MUL_SUPPORT // MUL related control signals @@ -1172,6 +1175,8 @@ module riscv_decoder illegal_insn_o = 1'b1; end + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED // misaligned access was detected by the LSU // TODO: this section should eventually be moved out of the decoder if (data_misaligned_i == 1'b1) @@ -1200,6 +1205,7 @@ module riscv_decoder scalar_replication_o = 1'b0; `endif // VEC_SUPPORT end + `endif // ONLY_ALIGNED // CONFIG_REGION: MUL_SUPPORT `ifdef MUL_SUPPORT else if (mult_multicycle_i) begin diff --git a/id_stage.sv b/id_stage.sv index b070fc19..23d78455 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -184,14 +184,21 @@ module riscv_id_stage output logic [1:0] data_reg_offset_ex_o, output logic data_load_event_ex_o, + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED output logic data_misaligned_ex_o, + `endif // ONLY_ALIGNED // CONFIG_REGION: PREPOST_SUPPORT `ifdef PREPOST_SUPPORT output logic prepost_useincr_ex_o, `endif // PREPOST_SUPPORT + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED input logic data_misaligned_i, + `endif // ONLY_ALIGNED + // Interrupt signals input logic [31:0] irq_i, @@ -721,7 +728,13 @@ module riscv_id_stage IMMB_I: imm_b = imm_i_type; IMMB_S: imm_b = imm_s_type; IMMB_U: imm_b = imm_u_type; + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED IMMB_PCINCR: imm_b = (is_compressed_i && (~data_misaligned_i)) ? 32'h2 : 32'h4; + `else + IMMB_PCINCR: imm_b = (is_compressed_i) ? 32'h2 : 32'h4; + `endif // ONLY_ALIGNED + IMMB_S2: imm_b = imm_s2_type; IMMB_BI: imm_b = imm_bi_type; IMMB_S3: imm_b = imm_s3_type; @@ -992,7 +1005,10 @@ module riscv_id_stage ( // controller related signals .deassert_we_i ( deassert_we ), + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED .data_misaligned_i ( data_misaligned_i ), + `endif // ONLY_ALIGNED // CONFIG_REGION: MUL_SUPPORT `ifdef MUL_SUPPORT .mult_multicycle_i ( mult_multicycle_i ), @@ -1136,7 +1152,10 @@ module riscv_id_stage // LSU .data_req_ex_i ( data_req_ex_o ), + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED .data_misaligned_i ( data_misaligned_i ), + `endif // ONLY_ALIGNED .data_load_event_i ( data_load_event_ex_o ), // ALU @@ -1210,7 +1229,10 @@ module riscv_id_stage .halt_if_o ( halt_if_o ), .halt_id_o ( halt_id ), + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED .misaligned_stall_o ( misaligned_stall ), + `endif // ONLY_ALIGNED .jr_stall_o ( jr_stall ), .load_stall_o ( load_stall ), @@ -1374,10 +1396,15 @@ always_ff @(posedge clk, negedge rst_n) data_reg_offset_ex_o <= 2'b0; data_req_ex_o <= 1'b0; data_load_event_ex_o <= 1'b0; + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED data_misaligned_ex_o <= 1'b0; + `endif // ONLY_ALIGNED pc_ex_o <= '0; branch_in_ex_o <= 1'b0; end + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED else if (data_misaligned_i) begin // misaligned data access case if (ex_ready_i) @@ -1403,7 +1430,8 @@ always_ff @(posedge clk, negedge rst_n) `endif // PREPOST_SUPPORT data_misaligned_ex_o <= 1'b1; end - end + end + `endif // ONLY_ALIGNED // CONFIG_REGION: MUL_SUPPORT `ifdef MUL_SUPPORT else if (mult_multicycle_i) begin @@ -1488,7 +1516,10 @@ always_ff @(posedge clk, negedge rst_n) end else begin data_load_event_ex_o <= 1'b0; end + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED data_misaligned_ex_o <= 1'b0; + `endif // ONLY_ALIGNED if ((jump_in_id == BRANCH_COND) || data_load_event_id) begin pc_ex_o <= pc_id_i; end @@ -1501,7 +1532,10 @@ always_ff @(posedge clk, negedge rst_n) csr_op_ex_o <= CSR_OP_NONE; data_req_ex_o <= 1'b0; data_load_event_ex_o <= 1'b0; + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED data_misaligned_ex_o <= 1'b0; + `endif // ONLY_ALIGNED branch_in_ex_o <= 1'b0; end end @@ -1510,7 +1544,12 @@ always_ff @(posedge clk, negedge rst_n) // stall control + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED assign id_ready_o = ((~misaligned_stall) & (~jr_stall) & (~load_stall) & ex_ready_i); + `else + assign id_ready_o = ((~jr_stall) & (~load_stall) & ex_ready_i); + `endif // ONLY_ALIGNED assign id_valid_o = (~halt_id) & id_ready_o; diff --git a/load_store_unit.sv b/load_store_unit.sv index b2563355..cd79d39b 100644 --- a/load_store_unit.sv +++ b/load_store_unit.sv @@ -66,8 +66,12 @@ module riscv_load_store_unit input logic addr_useincr_ex_i, // use a + b or just a for address -> from ex stage `endif // PREPOST_SUPPORT + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED input logic data_misaligned_ex_i, // misaligned access in last ld/st -> from ID/EX pipeline output logic data_misaligned_o, // misaligned access was detected -> to controller + `endif // ONLY_ALIGNED + // exception signals output logic load_err_o, @@ -94,8 +98,10 @@ module riscv_load_store_unit logic [3:0] data_be; logic [31:0] data_wdata; + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED logic misaligned_st; // high if we are currently performing the second part of a misaligned store - + `endif // ONLY_ALIGNED enum logic [1:0] { IDLE, WAIT_RVALID, WAIT_RVALID_EX_STALL, IDLE_EX_STALL } CS, NS; @@ -107,6 +113,8 @@ module riscv_load_store_unit case (data_type_ex_i) // Data type 00 Word, 01 Half word, 11,10 byte 2'b00: begin // Writing a word + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED if (misaligned_st == 1'b0) begin // non-misaligned case case (data_addr_int[1:0]) @@ -125,10 +133,15 @@ module riscv_load_store_unit 2'b11: data_be = 4'b0111; endcase; // case (data_addr_int[1:0]) end + `else + data_be = 4'b1111; + `endif // ONLY_ALIGNED end 2'b01: begin // Writing a half word + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED if (misaligned_st == 1'b0) begin // non-misaligned case case (data_addr_int[1:0]) @@ -142,6 +155,12 @@ module riscv_load_store_unit begin // misaligned case data_be = 4'b0001; end + `else + case (data_addr_int[1]) + 1'b0: data_be = 4'b0011; + 1'b1: data_be = 4'b1100; + endcase; // case (data_addr_int[1]) + `endif // ONLY_ALIGNED end 2'b10, @@ -209,17 +228,25 @@ module riscv_load_store_unit // take care of misaligned words always_comb begin + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED case (rdata_offset_q) 2'b00: rdata_w_ext = data_rdata_i[31:0]; 2'b01: rdata_w_ext = {data_rdata_i[ 7:0], rdata_q[31:8]}; 2'b10: rdata_w_ext = {data_rdata_i[15:0], rdata_q[31:16]}; 2'b11: rdata_w_ext = {data_rdata_i[23:0], rdata_q[31:24]}; endcase + `else + rdata_w_ext = data_rdata_i[31:0]; + `endif // ONLY_ALIGNED + endcase end // sign extension for half words always_comb begin + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED case (rdata_offset_q) 2'b00: begin @@ -253,6 +280,24 @@ module riscv_load_store_unit rdata_h_ext = {{16{data_rdata_i[7]}}, data_rdata_i[7:0], rdata_q[31:24]}; end endcase // case (rdata_offset_q) + `else + case (rdata_offset_q[1]) + 1'b0: + begin + if (data_sign_ext_q == 1'b0) + rdata_h_ext = {16'h0000, data_rdata_i[15:0]}; + else + rdata_h_ext = {{16{data_rdata_i[15]}}, data_rdata_i[15:0]}; + end + + 1'b1: + begin + if (data_sign_ext_q == 1'b0) + rdata_h_ext = {16'h0000, data_rdata_i[31:16]}; + else + rdata_h_ext = {{16{data_rdata_i[31]}}, data_rdata_i[31:16]}; + end + `endif // ONLY_ALIGNED end // sign extension for bytes @@ -322,10 +367,16 @@ module riscv_load_store_unit // store the data coming from memory in rdata_q. // In all other cases, rdata_q gets the value that we are // writing to the register file + + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED if ((data_misaligned_ex_i == 1'b1) || (data_misaligned_o == 1'b1)) rdata_q <= data_rdata_i; else rdata_q <= data_rdata_ext; + `else + rdata_q <= data_rdata_ext; + `endif // ONLY_ALIGNED end end end @@ -339,7 +390,10 @@ module riscv_load_store_unit assign data_we_o = data_we_ex_i; assign data_be_o = data_be; + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED assign misaligned_st = data_misaligned_ex_i; + `endif // ONLY_ALIGNED assign load_err_o = data_gnt_i && data_err_i && ~data_we_o; assign store_err_o = data_gnt_i && data_err_i && data_we_o; @@ -447,6 +501,8 @@ module riscv_load_store_unit endcase end + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED // check for misaligned accesses that need a second memory access // If one is detected, this is signaled with data_misaligned_o to // the controller which selectively stalls the pipeline @@ -470,6 +526,7 @@ module riscv_load_store_unit endcase // case (data_type_ex_i) end end + `endif // ONLY_ALIGNED // CONFIG_REGION: LSU_ADDER_SUPPORT `ifdef LSU_ADDER_SUPPORT diff --git a/riscv_core.sv b/riscv_core.sv index 1b09b6ba..3e8ab679 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -126,7 +126,10 @@ module riscv_core logic useincr_addr_ex; // Active when post increment `endif // PREPOST_SUPPORT + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED logic data_misaligned; + `endif // ONLY_ALIGNED // CONFIG_REGION: MUL_SUPPORT `ifdef MUL_SUPPORT @@ -217,7 +220,10 @@ module riscv_core logic data_req_ex; logic [31:0] data_pc_ex; logic data_load_event_ex; + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED logic data_misaligned_ex; + `endif // ONLY_ALIGNED // stall control logic halt_if; @@ -551,14 +557,20 @@ module riscv_core .data_reg_offset_ex_o ( data_reg_offset_ex ), // to load store unit .data_load_event_ex_o ( data_load_event_ex ), // to load store unit + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED .data_misaligned_ex_o ( data_misaligned_ex ), // to load store unit + `endif // ONLY_ALIGNED // CONFIG_REGION: PREPOST_SUPPORT `ifdef PREPOST_SUPPORT .prepost_useincr_ex_o ( useincr_addr_ex ), `endif // PREPOST_SUPPORT + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED .data_misaligned_i ( data_misaligned ), + `endif // ONLY_ALIGNED // Interrupt Signals .irq_i ( irq_i ), // incoming interrupts @@ -748,8 +760,11 @@ module riscv_core .addr_useincr_ex_i ( useincr_addr_ex ), `endif // PREPOST_SUPPORT + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED .data_misaligned_ex_i ( data_misaligned_ex ), // from ID/EX pipeline .data_misaligned_o ( data_misaligned ), + `endif // ONLY_ALIGNED // exception signals .load_err_o ( lsu_load_err ), @@ -1018,7 +1033,10 @@ module riscv_core .ex_data_wdata ( data_wdata_o ), .wb_bypass ( ex_stage_i.branch_in_ex_i ), + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED .lsu_misaligned ( data_misaligned ), + `endif // ONLY_ALIGNED .wb_valid ( wb_valid ), .wb_reg_addr ( id_stage_i.registers_i.waddr_a_i ), diff --git a/riscv_simchecker.sv b/riscv_simchecker.sv index f0b6cddb..3d06883d 100644 --- a/riscv_simchecker.sv +++ b/riscv_simchecker.sv @@ -79,7 +79,10 @@ module riscv_simchecker input logic [31:0] ex_data_addr, input logic [31:0] ex_data_wdata, + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED input logic lsu_misaligned, + `endif // ONLY_ALIGNED input logic wb_bypass, input logic wb_valid, @@ -181,7 +184,12 @@ module riscv_simchecker trace.mem_access.push_back(mem_acc); end + // CONFIG_REGION: ONLY_ALIGNED + `ifndef ONLY_ALIGNED end while ((!ex_valid || lsu_misaligned) && (!wb_bypass)); + `else + end while ((!ex_valid) && (!wb_bypass)); + `endif // ONLY_ALIGNED trace.wb_bypass = wb_bypass;