diff options
| author | Alejandro Soto <alejandro@34project.org> | 2023-10-03 07:44:27 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2023-10-03 07:44:27 -0600 |
| commit | 6ddd97b7289b043c41ac65ae35931bd5b5acfaeb (patch) | |
| tree | f03430dedaae6e02352e74d35d8daed174be6031 | |
| parent | 548187dfc392d0beef4cc86e7d3d22d885276e5d (diff) | |
rtl/core/control: reject strex after exceptions
| -rw-r--r-- | rtl/core/control/control.sv | 4 | ||||
| -rw-r--r-- | rtl/core/control/cycles.sv | 4 | ||||
| -rw-r--r-- | rtl/core/control/ldst/ldst.sv | 32 | ||||
| -rw-r--r-- | rtl/core/control/writeback.sv | 5 |
4 files changed, 31 insertions, 14 deletions
diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv index 6090f2d..27be940 100644 --- a/rtl/core/control/control.sv +++ b/rtl/core/control/control.sv @@ -112,8 +112,8 @@ module core_control .* ); - word mem_offset, ldst_read; - logic ldst, ldst_next, ldst_writeback, pop_valid; + word mem_offset, ldst_read, strex_ok; + logic ldst, ldst_next, ldst_reject, ldst_writeback, pop_valid; reg_num popped; logic[1:0] ldst_shift; diff --git a/rtl/core/control/cycles.sv b/rtl/core/control/cycles.sv index 5779990..772697d 100644 --- a/rtl/core/control/cycles.sv +++ b/rtl/core/control/cycles.sv @@ -18,6 +18,7 @@ module core_control_cycles mul_ready, pop_valid, trivial_shift, + ldst_reject, ldst_writeback, data_snd_shift_by_reg, @@ -109,6 +110,9 @@ module core_control_cycles if(mem_ready && mem_fault) next_state = ESCALATE; + + if(ldst_reject) + next_state = ISSUE; end MUL: diff --git a/rtl/core/control/ldst/ldst.sv b/rtl/core/control/ldst/ldst.sv index 57f8edc..aa5c957 100644 --- a/rtl/core/control/ldst/ldst.sv +++ b/rtl/core/control/ldst/ldst.sv @@ -8,6 +8,7 @@ module core_control_ldst input insn_decode dec, input logic issue, mem_ready, + mem_ex_fail, input word rd_value_b, q_alu, q_shifter, @@ -28,14 +29,16 @@ module core_control_ldst pop_valid, ldst, ldst_next, + ldst_reject, ldst_writeback, output logic[1:0] ldst_shift, output word ldst_read, + strex_ok, output reg_num popped ); word base; - logic pre, increment, sign_extend; + logic block_strex, increment, pre, sign_extend; reg_num popped_upper, popped_lower; reg_list mem_regs, next_regs_upper, next_regs_lower; ldst_size size; @@ -44,6 +47,9 @@ module core_control_ldst assign ldst_next = !cycle.transfer || mem_ready; assign mem_data_wr = mem_ex_lock ? alu_b : q_shifter; + assign strex_ok = {31'd0, mem_ex_fail || block_strex}; + assign ldst_reject = mem_ex_lock && mem_write && block_strex; + core_control_ldst_pop pop ( .regs(mem_regs), @@ -65,11 +71,12 @@ module core_control_ldst ); always_ff @(posedge clk or negedge rst_n) - if(!rst_n) begin + if (!rst_n) begin pre <= 0; ldst <= 0; size <= LDST_WORD; increment <= 0; + block_strex <= 1; sign_extend <= 0; ldst_writeback <= 0; @@ -81,11 +88,11 @@ module core_control_ldst mem_offset <= 0; mem_ex_lock <= 0; end else begin - if(mem_start) + if (mem_start) mem_start <= 0; - if(next_cycle.issue) begin - if(issue) begin + if (next_cycle.issue) begin + if (issue) begin ldst <= dec.ctrl.ldst; mem_user <= dec.ldst.unprivileged; end @@ -99,19 +106,24 @@ module core_control_ldst mem_regs <= dec.ldst.regs; mem_write <= !dec.ldst.load; mem_ex_lock <= dec.ldst.exclusive; - end else if(next_cycle.transfer) begin - if(!cycle.transfer) begin + end else if (next_cycle.transfer) begin + if (!cycle.transfer) begin ldst <= 0; mem_offset <= alu_b; end - if(ldst_next) begin + if (ldst_next) begin base <= pre ? q_alu : alu_a; mem_regs <= increment ? next_regs_lower : next_regs_upper; end - mem_start <= !cycle.transfer || (mem_ready && pop_valid); - end else if(cycle.escalate) + mem_start <= (!cycle.transfer || (mem_ready && pop_valid)) && !ldst_reject; + + if (block_strex) + block_strex <= !mem_ex_lock || mem_write; + end else if (cycle.escalate) begin ldst <= 0; + block_strex <= 1; + end end endmodule diff --git a/rtl/core/control/writeback.sv b/rtl/core/control/writeback.sv index 50e780d..027a7d7 100644 --- a/rtl/core/control/writeback.sv +++ b/rtl/core/control/writeback.sv @@ -10,11 +10,11 @@ module core_control_writeback input word q_alu, ldst_read, input logic mem_ready, - mem_ex_fail, mem_ex_lock, mem_write, input word mul_q_hi, mul_q_lo, + strex_ok, input ctrl_cycle cycle, next_cycle, @@ -28,6 +28,7 @@ module core_control_writeback input logic issue, pop_valid, ldst_next, + ldst_reject, output reg_num rd, final_rd, @@ -64,7 +65,7 @@ module core_control_writeback writeback = 0; if(cycle.transfer) - wr_value = (mem_ex_lock && mem_write) ? {31'd0, mem_ex_fail} : ldst_read; + wr_value = (mem_ex_lock && mem_write) ? strex_ok : ldst_read; else if(cycle.base_writeback) wr_value = saved_base; else if(cycle.mul || cycle.mul_hi_wb) |
