diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-10-02 13:23:22 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-10-02 13:23:22 -0600 |
| commit | 63ec42cc245b2da9ab97cc4eef6bbd21e08cde07 (patch) | |
| tree | 1b9fd482a6e3cee3eb2245a9d331669cf5e44b8c /rtl/core/decode | |
| parent | 97bc74277d0e9672a55552ed1cded66ecb7d317e (diff) | |
Split decoding of flexible second operand out of data instructions
Diffstat (limited to 'rtl/core/decode')
| -rw-r--r-- | rtl/core/decode/data.sv | 69 | ||||
| -rw-r--r-- | rtl/core/decode/decode.sv | 34 | ||||
| -rw-r--r-- | rtl/core/decode/snd.sv | 77 |
3 files changed, 114 insertions, 66 deletions
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 |
