summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-10-03 07:44:27 -0600
committerAlejandro Soto <alejandro@34project.org>2023-10-03 07:44:27 -0600
commit6ddd97b7289b043c41ac65ae35931bd5b5acfaeb (patch)
treef03430dedaae6e02352e74d35d8daed174be6031 /rtl
parent548187dfc392d0beef4cc86e7d3d22d885276e5d (diff)
rtl/core/control: reject strex after exceptions
Diffstat (limited to 'rtl')
-rw-r--r--rtl/core/control/control.sv4
-rw-r--r--rtl/core/control/cycles.sv4
-rw-r--r--rtl/core/control/ldst/ldst.sv32
-rw-r--r--rtl/core/control/writeback.sv5
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)