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 | |
| parent | 97bc74277d0e9672a55552ed1cded66ecb7d317e (diff) | |
Split decoding of flexible second operand out of data instructions
Diffstat (limited to '')
| -rw-r--r-- | rtl/core/arm810.sv | 2 | ||||
| -rw-r--r-- | rtl/core/cycles.sv | 30 | ||||
| -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 | ||||
| -rw-r--r-- | rtl/core/isa.sv | 39 | ||||
| -rw-r--r-- | rtl/core/uarch.sv | 18 |
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 { |
