summaryrefslogtreecommitdiff
path: root/rtl/core
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-10-02 13:23:22 -0600
committerAlejandro Soto <alejandro@34project.org>2022-10-02 13:23:22 -0600
commit63ec42cc245b2da9ab97cc4eef6bbd21e08cde07 (patch)
tree1b9fd482a6e3cee3eb2245a9d331669cf5e44b8c /rtl/core
parent97bc74277d0e9672a55552ed1cded66ecb7d317e (diff)
Split decoding of flexible second operand out of data instructions
Diffstat (limited to '')
-rw-r--r--rtl/core/arm810.sv2
-rw-r--r--rtl/core/cycles.sv30
-rw-r--r--rtl/core/decode/data.sv69
-rw-r--r--rtl/core/decode/decode.sv34
-rw-r--r--rtl/core/decode/snd.sv77
-rw-r--r--rtl/core/isa.sv39
-rw-r--r--rtl/core/uarch.sv18
7 files changed, 164 insertions, 105 deletions
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv
index 81d9883..9befe0f 100644
--- a/rtl/core/arm810.sv
+++ b/rtl/core/arm810.sv
@@ -31,6 +31,7 @@ module arm810
logic dec_execute, dec_undefined, dec_writeback, dec_branch, dec_update_flags;
ptr dec_branch_offset;
+ snd_decode dec_snd;
data_decode dec_data;
core_decode decode
@@ -41,6 +42,7 @@ module arm810
.branch(dec_branch),
.update_flags(dec_update_flags),
.branch_offset(dec_branch_offset),
+ .snd_ctrl(dec_snd),
.data_ctrl(dec_data),
.*
);
diff --git a/rtl/core/cycles.sv b/rtl/core/cycles.sv
index c32bff0..7cb65a3 100644
--- a/rtl/core/cycles.sv
+++ b/rtl/core/cycles.sv
@@ -8,6 +8,7 @@ module core_cycles
dec_writeback,
dec_update_flags,
input ptr dec_branch_offset,
+ input snd_decode dec_snd,
input data_decode dec_data,
input ptr fetch_insn_pc,
input psr_flags next_flags,
@@ -109,27 +110,28 @@ module core_cycles
if(dec_execute & ~bubble) begin
bubble <=
(dec_update_flags & update_flags)
- | (final_writeback & ((rd == dec_data.rn) | (rd == dec_data.r_snd)));
+ | (final_writeback & ((rd == dec_data.rn) | (rd == dec_snd.r)));
branch <= dec_branch;
update_flags <= dec_update_flags;
branch_target <= pc_visible + dec_branch_offset;
- data_snd_is_imm <= dec_data.snd_is_imm;
- data_snd_shift_by_reg <= dec_data.snd_shift_by_reg;
- data_imm <= dec_data.imm;
- data_shift_imm <= dec_data.shift_imm;
-
alu <= dec_data.op;
- shifter.shl <= dec_data.shl;
- shifter.shr <= dec_data.shr;
- shifter.ror <= dec_data.ror;
- shifter.put_carry <= dec_data.put_carry;
- shifter.sign_extend <= dec_data.sign_extend;
-
ra <= dec_data.rn;
- rb <= dec_data.r_snd;
- r_shift <= dec_data.r_shift;
+
+ data_snd_is_imm <= dec_snd.is_imm;
+ data_snd_shift_by_reg <= dec_snd.shift_by_reg;
+ data_imm <= dec_snd.imm;
+ data_shift_imm <= dec_snd.shift_imm;
+
+ shifter.shl <= dec_snd.shl;
+ shifter.shr <= dec_snd.shr;
+ shifter.ror <= dec_snd.ror;
+ shifter.put_carry <= dec_snd.put_carry;
+ shifter.sign_extend <= dec_snd.sign_extend;
+
+ rb <= dec_snd.r;
+ r_shift <= dec_snd.r_shift;
c_in <= next_flags.c;
final_rd <= dec_data.rd;
diff --git a/rtl/core/decode/data.sv b/rtl/core/decode/data.sv
index a649440..e2a44df 100644
--- a/rtl/core/decode/data.sv
+++ b/rtl/core/decode/data.sv
@@ -6,45 +6,25 @@ module core_decode_data
input word insn,
output data_decode decode,
- output logic writeback,
+ output logic snd_is_imm,
+ snd_shift_by_reg_if_reg,
+ writeback,
update_flags,
- restore_spsr,
- undefined
+ restore_spsr
);
alu_op op;
- reg_num rn, rd, r_snd, r_shift;
- logic snd_shift_by_reg, snd_is_imm, shl, shr, ror, put_carry, sign_extend;
- logic[7:0] imm;
- logic[5:0] shift_imm;
+ reg_num rn, rd;
assign decode.op = op;
assign decode.rn = rn;
assign decode.rd = rd;
- assign decode.r_snd = r_snd;
- assign decode.r_shift = r_shift;
- assign decode.snd_shift_by_reg = snd_shift_by_reg;
- assign decode.snd_is_imm = snd_is_imm;
- assign decode.shl = shl;
- assign decode.shr = shr;
- assign decode.ror = ror;
- assign decode.put_carry = put_carry;
- assign decode.sign_extend = sign_extend;
- assign decode.imm = imm;
- assign decode.shift_imm = shift_imm;
-
assign rn = insn `FIELD_DATA_RN;
assign rd = insn `FIELD_DATA_RD;
assign op = insn `FIELD_DATA_OPCODE;
- assign r_snd = insn `FIELD_DATA_RM;
- assign r_shift = insn `FIELD_DATA_RS;
- assign imm = insn `FIELD_DATA_IMM8;
- assign snd_is_imm = insn `FIELD_DATA_IMM;
- assign snd_shift_by_reg = ~snd_is_imm & insn `FIELD_DATA_REGSHIFT;
- assign undefined = snd_shift_by_reg & insn `FIELD_DATA_ZEROIFREG;
- logic[1:0] shift_op;
- assign shift_op = insn `FIELD_DATA_SHIFT;
+ assign snd_is_imm = insn `FIELD_DATA_IMM;
+ assign snd_shift_by_reg_if_reg = insn `FIELD_DATA_REGSHIFT;
always_comb begin
unique case(op)
@@ -60,41 +40,6 @@ module core_decode_data
if(restore_spsr)
update_flags = 0;
-
- ror = snd_is_imm;
- shr = ~snd_is_imm;
- put_carry = 0;
- sign_extend = 1'bx;
-
- if(snd_is_imm)
- shift_imm = {1'b0, insn `FIELD_DATA_ROR8, 1'b0};
- else begin
- shift_imm = {1'b0, insn `FIELD_DATA_SHIFTIMM};
-
- case(shift_op)
- `SHIFT_LSL: shr = 0;
- `SHIFT_LSR: sign_extend = 0;
- `SHIFT_ASR: sign_extend = 1;
- `SHIFT_ROR: ;
- endcase
-
- if(~snd_shift_by_reg & (shift_imm == 0))
- case(shift_op)
- `SHIFT_LSL: ;
-
- `SHIFT_LSR, `SHIFT_ASR:
- shift_imm = 6'd32;
-
- `SHIFT_ROR: begin
- // RRX
- shift_imm = 6'd1;
- put_carry = 1;
- sign_extend = 0;
- end
- endcase
- else if(shift_op == `SHIFT_ROR)
- ror = 1;
- end
end
endmodule
diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv
index f7d7be8..f4de2d0 100644
--- a/rtl/core/decode/decode.sv
+++ b/rtl/core/decode/decode.sv
@@ -12,12 +12,12 @@ module core_decode
update_flags,
branch,
output ptr branch_offset,
+ output snd_decode snd_ctrl,
output data_decode data_ctrl
);
logic cond_undefined;
- //TODO
core_decode_conds conds
(
.cond(insn `FIELD_COND),
@@ -25,6 +25,18 @@ module core_decode
.*
);
+ logic snd_is_imm, snd_shift_by_reg_if_reg, snd_undefined;
+ snd_decode snd;
+
+ core_decode_snd snd_operand
+ (
+ .decode(snd),
+ .is_imm(snd_is_imm),
+ .shift_by_reg_if_reg(snd_shift_by_reg_if_reg),
+ .undefined(snd_undefined),
+ .*
+ );
+
logic branch_link;
core_decode_branch group_branch
@@ -37,7 +49,7 @@ module core_decode
//TODO
logic restore_spsr;
- logic data_writeback, data_update_flags, data_undefined;
+ logic data_writeback, data_update_flags, data_is_imm, data_shift_by_reg_if_reg;
data_decode data;
core_decode_data group_data
@@ -45,7 +57,8 @@ module core_decode
.decode(data),
.writeback(data_writeback),
.update_flags(data_update_flags),
- .undefined(data_undefined),
+ .snd_is_imm(data_is_imm),
+ .snd_shift_by_reg_if_reg(data_shift_by_reg_if_reg),
.*
);
@@ -57,6 +70,13 @@ module core_decode
update_flags = 0;
data_ctrl = {($bits(data_ctrl)){1'bx}};
+ snd_ctrl = {($bits(snd_ctrl)){1'bx}};
+ snd_ctrl.shl = 0;
+ snd_ctrl.shr = 0;
+ snd_ctrl.ror = 0;
+ snd_is_imm = 1'bx;
+ snd_shift_by_reg_if_reg = 1'bx;
+
priority casez(insn `FIELD_OP)
`GROUP_B: begin
branch = 1;
@@ -68,10 +88,15 @@ module core_decode
end
`GROUP_ALU: begin
+ snd_is_imm = data_is_imm;
+ snd_shift_by_reg_if_reg = data_shift_by_reg_if_reg;
+
+ snd_ctrl = snd;
data_ctrl = data;
+
writeback = data_writeback;
update_flags = data_update_flags;
- undefined = undefined | data_undefined;
+ undefined = undefined | snd_undefined;
end
`INSN_MUL: ;
@@ -88,6 +113,7 @@ module core_decode
undefined = 1;
branch = 1'bx;
writeback = 1'bx;
+ snd_ctrl = {($bits(snd_ctrl)){1'bx}};
end
endcase
end
diff --git a/rtl/core/decode/snd.sv b/rtl/core/decode/snd.sv
new file mode 100644
index 0000000..5110d57
--- /dev/null
+++ b/rtl/core/decode/snd.sv
@@ -0,0 +1,77 @@
+`include "core/isa.sv"
+`include "core/uarch.sv"
+
+module core_decode_snd
+(
+ input word insn,
+ input logic is_imm,
+ shift_by_reg_if_reg,
+
+ output snd_decode decode,
+ output logic undefined
+);
+
+ reg_num r, r_shift;
+ logic shift_by_reg, shl, shr, ror, put_carry, sign_extend;
+ logic[7:0] imm;
+ logic[5:0] shift_imm;
+
+ assign decode.r = r;
+ assign decode.r_shift = r_shift;
+ assign decode.shift_by_reg = shift_by_reg;
+ assign decode.is_imm = is_imm;
+ assign decode.shl = shl;
+ assign decode.shr = shr;
+ assign decode.ror = ror;
+ assign decode.put_carry = put_carry;
+ assign decode.sign_extend = sign_extend;
+ assign decode.imm = imm;
+ assign decode.shift_imm = shift_imm;
+
+ assign r = insn `FIELD_SND_RM;
+ assign r_shift = insn `FIELD_SND_RS;
+ assign imm = insn `FIELD_SND_IMM8;
+ assign shift_by_reg = ~is_imm & shift_by_reg_if_reg;
+ assign undefined = shift_by_reg & insn `FIELD_SND_ZEROIFREG;
+
+ logic[1:0] shift_op;
+ assign shift_op = insn `FIELD_SND_SHIFT;
+
+ always_comb begin
+ ror = is_imm;
+ shr = ~is_imm;
+ put_carry = 0;
+ sign_extend = 1'bx;
+
+ if(is_imm)
+ shift_imm = {1'b0, insn `FIELD_SND_ROR8, 1'b0};
+ else begin
+ shift_imm = {1'b0, insn `FIELD_SND_SHIFTIMM};
+
+ case(shift_op)
+ `SHIFT_LSL: shr = 0;
+ `SHIFT_LSR: sign_extend = 0;
+ `SHIFT_ASR: sign_extend = 1;
+ `SHIFT_ROR: ;
+ endcase
+
+ if(~shift_by_reg & (shift_imm == 0))
+ case(shift_op)
+ `SHIFT_LSL: ;
+
+ `SHIFT_LSR, `SHIFT_ASR:
+ shift_imm = 6'd32;
+
+ `SHIFT_ROR: begin
+ // RRX
+ shift_imm = 6'd1;
+ put_carry = 1;
+ sign_extend = 0;
+ end
+ endcase
+ else if(shift_op == `SHIFT_ROR)
+ ror = 1;
+ end
+ end
+
+endmodule
diff --git a/rtl/core/isa.sv b/rtl/core/isa.sv
index 35610c2..7f32914 100644
--- a/rtl/core/isa.sv
+++ b/rtl/core/isa.sv
@@ -21,6 +21,21 @@
`define COND_AL 4'b1110
`define COND_UD 4'b1111 // Indefnido antes de ARMv5
+// Segundo operando de varios grupos de instrucciones
+
+`define FIELD_SND_ROR8 [11:8]
+`define FIELD_SND_IMM8 [7:0]
+`define FIELD_SND_SHIFTIMM [11:7]
+`define FIELD_SND_RS [11:8]
+`define FIELD_SND_ZEROIFREG [7]
+`define FIELD_SND_SHIFT [6:5]
+`define FIELD_SND_RM [3:0]
+
+`define SHIFT_LSL 2'b00
+`define SHIFT_LSR 2'b01
+`define SHIFT_ASR 2'b10
+`define SHIFT_ROR 2'b11
+
// Instrucciones de salto
`define INSN_B 28'b101_0_????????????????????????
@@ -52,24 +67,12 @@
`define GROUP_ALU 28'b00_?_????_?_????_????_????????????
-`define FIELD_DATA_IMM [25]
-`define FIELD_DATA_OPCODE [24:21]
-`define FIELD_DATA_S [20]
-`define FIELD_DATA_RN [19:16]
-`define FIELD_DATA_RD [15:12]
-`define FIELD_DATA_ROR8 [11:8]
-`define FIELD_DATA_IMM8 [7:0]
-`define FIELD_DATA_SHIFTIMM [11:7]
-`define FIELD_DATA_RS [11:8]
-`define FIELD_DATA_ZEROIFREG [7]
-`define FIELD_DATA_SHIFT [6:5]
-`define FIELD_DATA_REGSHIFT [4]
-`define FIELD_DATA_RM [3:0]
-
-`define SHIFT_LSL 2'b00
-`define SHIFT_LSR 2'b01
-`define SHIFT_ASR 2'b10
-`define SHIFT_ROR 2'b11
+`define FIELD_DATA_IMM [25]
+`define FIELD_DATA_OPCODE [24:21]
+`define FIELD_DATA_S [20]
+`define FIELD_DATA_RN [19:16]
+`define FIELD_DATA_RD [15:12]
+`define FIELD_DATA_REGSHIFT [4]
// Instrucciones de multiplicación
diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv
index 0c5bc84..22f0578 100644
--- a/rtl/core/uarch.sv
+++ b/rtl/core/uarch.sv
@@ -58,13 +58,17 @@ typedef logic[4:0] psr_mode;
typedef struct packed
{
- alu_op op;
- reg_num rn,
- rd,
- r_snd,
+ alu_op op;
+ reg_num rn,
+ rd;
+} data_decode;
+
+typedef struct packed
+{
+ reg_num r,
r_shift;
- logic snd_shift_by_reg,
- snd_is_imm,
+ logic shift_by_reg,
+ is_imm,
shl,
shr,
ror,
@@ -72,7 +76,7 @@ typedef struct packed
sign_extend;
logic[7:0] imm;
logic[5:0] shift_imm;
-} data_decode;
+} snd_decode;
typedef struct packed
{