summaryrefslogtreecommitdiff
path: root/rtl/core/decode/data.sv
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/core/decode/data.sv')
-rw-r--r--rtl/core/decode/data.sv78
1 files changed, 70 insertions, 8 deletions
diff --git a/rtl/core/decode/data.sv b/rtl/core/decode/data.sv
index e132975..89b9967 100644
--- a/rtl/core/decode/data.sv
+++ b/rtl/core/decode/data.sv
@@ -3,19 +3,46 @@
module core_decode_data
(
- input word insn,
-
- output alu_op op,
- output reg_num rn,
- rd,
- output logic writeback,
- update_flags,
- restore_spsr
+ input word insn,
+
+ output alu_decode decode,
+ output logic writeback,
+ update_flags,
+ restore_spsr,
+ undefined
);
+ 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;
+
+ 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 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;
always_comb begin
unique case(op)
@@ -31,6 +58,41 @@ 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