summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-10-02 11:15:34 -0600
committerAlejandro Soto <alejandro@34project.org>2023-10-02 23:29:46 -0600
commitfbe3ab39675d338eb6d5388b7deacf98a3a8ae2d (patch)
tree6a3a8479031d1434a18af4385713dd48207d3814 /rtl
parent70d7dc9489f4d5b91d8138e0a341eec4ad7f15b0 (diff)
rtl/core: implement ldrex/strex decode
Diffstat (limited to 'rtl')
-rw-r--r--rtl/core/decode/decode.sv10
-rw-r--r--rtl/core/decode/isa.sv13
-rw-r--r--rtl/core/decode/ldst/exclusive.sv27
-rw-r--r--rtl/core/decode/ldst/misc.sv1
-rw-r--r--rtl/core/decode/ldst/multiple.sv1
-rw-r--r--rtl/core/decode/ldst/single.sv1
-rw-r--r--rtl/core/decode/mux.sv20
-rw-r--r--rtl/core/uarch.sv1
8 files changed, 68 insertions, 6 deletions
diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv
index b00e06f..219f975 100644
--- a/rtl/core/decode/decode.sv
+++ b/rtl/core/decode/decode.sv
@@ -127,6 +127,16 @@ module core_decode
.*
);
+ reg_num ldst_ex_snd_r;
+ ldst_decode ldst_exclusive;
+
+ core_decode_ldst_exclusive group_ldst_ex
+ (
+ .snd_r(ldst_ex_snd_r),
+ .decode(ldst_exclusive),
+ .*
+ );
+
ldst_decode ldst_addr;
data_decode data_ldst;
diff --git a/rtl/core/decode/isa.sv b/rtl/core/decode/isa.sv
index 2ad5b40..6784eca 100644
--- a/rtl/core/decode/isa.sv
+++ b/rtl/core/decode/isa.sv
@@ -162,7 +162,18 @@
`define FIELD_LDST_MULT_RN [19:16]
`define FIELD_LDST_MULT_LIST [15:0]
-// Instrucciones atómicas de intercambio registro-memoria
+// Instrucciones para operaciones atómicas optimistas (monitor exclusivo)
+
+`define INSN_LDREX 28'b0001100_1_????_????_1111_1001_1111
+`define INSN_STREX 28'b0001100_0_????_????_1111_1001_????
+`define GROUP_LDST_EX `INSN_LDREX, `INSN_STREX
+
+`define FIELD_LDST_EX_LD [20]
+`define FIELD_LDST_EX_RN [19:16]
+`define FIELD_LDST_EX_RD [15:12]
+`define FIELD_LDST_EX_R_OK [3:0]
+
+// Instrucciones atómicas de intercambio registro-memoria (deprecadas)
`define INSN_SWP 28'b00010000_????_????_0000_1001_????
`define INSN_SWPB 28'b00010100_????_????_0000_1001_????
diff --git a/rtl/core/decode/ldst/exclusive.sv b/rtl/core/decode/ldst/exclusive.sv
new file mode 100644
index 0000000..7942a04
--- /dev/null
+++ b/rtl/core/decode/ldst/exclusive.sv
@@ -0,0 +1,27 @@
+`include "core/decode/isa.sv"
+`include "core/uarch.sv"
+
+module core_decode_ldst_exclusive
+(
+ input word insn,
+
+ output ldst_decode decode,
+ output reg_num snd_r
+);
+
+ assign snd_r = insn `FIELD_LDST_EX_R_OK;
+
+ assign decode.rn = insn `FIELD_LDST_EX_RN;
+ assign decode.rd = insn `FIELD_LDST_EX_RD;
+ assign decode.size = LDST_WORD;
+ assign decode.load = insn `FIELD_LDST_EX_LD;
+ assign decode.increment = 0;
+ assign decode.writeback = 0;
+ assign decode.exclusive = 1;
+ assign decode.sign_extend = 0;
+ assign decode.pre_indexed = 0;
+ assign decode.unprivileged = 0;
+ assign decode.user_regs = 0;
+ assign decode.regs = 16'b0;
+
+endmodule
diff --git a/rtl/core/decode/ldst/misc.sv b/rtl/core/decode/ldst/misc.sv
index 4e4a17e..72d648c 100644
--- a/rtl/core/decode/ldst/misc.sv
+++ b/rtl/core/decode/ldst/misc.sv
@@ -19,6 +19,7 @@ module core_decode_ldst_misc
assign decode.load = insn `FIELD_LDST_LD;
assign decode.increment = insn `FIELD_LDST_MISC_U;
assign decode.writeback = !p || w;
+ assign decode.exclusive = 0;
assign decode.sign_extend = insn `FIELD_LDST_MISC_S;
assign decode.pre_indexed = p;
assign decode.unprivileged = 0;
diff --git a/rtl/core/decode/ldst/multiple.sv b/rtl/core/decode/ldst/multiple.sv
index 0ecd674..c822ab0 100644
--- a/rtl/core/decode/ldst/multiple.sv
+++ b/rtl/core/decode/ldst/multiple.sv
@@ -18,6 +18,7 @@ module core_decode_ldst_multiple
assign decode.load = l;
assign decode.increment = insn `FIELD_LDST_MULT_U;
assign decode.writeback = insn `FIELD_LDST_MULT_W;
+ assign decode.exclusive = 0;
assign decode.sign_extend = 0;
assign decode.pre_indexed = insn `FIELD_LDST_MULT_P;
assign decode.unprivileged = 0;
diff --git a/rtl/core/decode/ldst/single.sv b/rtl/core/decode/ldst/single.sv
index 402c17b..af096a7 100644
--- a/rtl/core/decode/ldst/single.sv
+++ b/rtl/core/decode/ldst/single.sv
@@ -17,6 +17,7 @@ module core_decode_ldst_single
assign decode.load = insn `FIELD_LDST_LD;
assign decode.increment = insn `FIELD_LDST_SINGLE_U;
assign decode.writeback = !p || w;
+ assign decode.exclusive = 0;
assign decode.sign_extend = 0;
assign decode.pre_indexed = p;
assign decode.unprivileged = !p && w;
diff --git a/rtl/core/decode/mux.sv b/rtl/core/decode/mux.sv
index 297ad33..6f0451a 100644
--- a/rtl/core/decode/mux.sv
+++ b/rtl/core/decode/mux.sv
@@ -18,12 +18,14 @@ module core_decode_mux
data_is_imm,
data_shift_by_reg_if_reg,
- input ldst_decode ldst_single,
- ldst_misc,
+ input ldst_decode ldst_misc,
+ ldst_single,
ldst_multiple,
+ ldst_exclusive,
input logic ldst_single_is_imm,
ldst_misc_off_is_imm,
- input reg_num ldst_misc_off_reg,
+ input reg_num ldst_ex_snd_r,
+ ldst_misc_off_reg,
input logic[7:0] ldst_misc_off_imm,
input logic ldst_mult_restore_spsr,
input data_decode data_ldst,
@@ -135,6 +137,14 @@ module core_decode_mux
update_flags = mul_update_flags;
end
+ `GROUP_LDST_EX: begin
+ dec_ldst = ldst_exclusive;
+ ldst_addr = ldst_exclusive;
+
+ dec_snd.r = ldst_ex_snd_r;
+ dec_snd.is_imm = ldst_exclusive.load;
+ end
+
`GROUP_LDST_MISC: begin
dec_ldst = ldst_misc;
ldst_addr = ldst_misc;
@@ -255,10 +265,10 @@ module core_decode_mux
// Codificación coincide con ldst
`GROUP_MUL: ;
- `GROUP_LDST_SINGLE, `GROUP_LDST_MISC, `GROUP_LDST_MULT: begin
+ `GROUP_LDST_SINGLE, `GROUP_LDST_MISC, `GROUP_LDST_MULT, `GROUP_LDST_EX: begin
ldst = 1;
dec_data = data_ldst;
- writeback = dec_ldst.writeback || dec_ldst.load;
+ writeback = dec_ldst.writeback || dec_ldst.load || dec_ldst.exclusive;
end
default: ;
diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv
index 38b0130..a474274 100644
--- a/rtl/core/uarch.sv
+++ b/rtl/core/uarch.sv
@@ -150,6 +150,7 @@ typedef struct packed
logic load,
increment,
writeback,
+ exclusive,
sign_extend,
pre_indexed,
unprivileged,