diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-09-25 23:21:32 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-09-25 23:21:32 -0600 |
| commit | 43829e0400f0a7aaccbb1ebefb44a38c41749e77 (patch) | |
| tree | 686740ccd520b06e74aae080ef5d3d3abbfff4b5 /rtl/core/decode | |
| parent | 8c7b6113c51215de9f57f016681bfcc43513ee37 (diff) | |
Implement shifter decoding
Diffstat (limited to 'rtl/core/decode')
| -rw-r--r-- | rtl/core/decode/data.sv | 78 | ||||
| -rw-r--r-- | rtl/core/decode/decode.sv | 36 |
2 files changed, 85 insertions, 29 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 diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv index fad7edc..a202694 100644 --- a/rtl/core/decode/decode.sv +++ b/rtl/core/decode/decode.sv @@ -3,17 +3,16 @@ module core_decode ( - input word insn, - input psr_flags flags, - - output logic execute, - undefined, - writeback, - update_flags, - branch, - output ptr branch_offset, - output reg_num rd, - output alu_op data_op + input word insn, + input psr_flags flags, + + output logic execute, + undefined, + writeback, + update_flags, + branch, + output ptr branch_offset, + output alu_decode alu ); logic cond_undefined; @@ -36,17 +35,14 @@ module core_decode ); //TODO - reg_num rn; logic restore_spsr; logic data_writeback, data_update_flags; - reg_num data_rd; - alu_op data_group_op; + alu_decode data_alu; core_decode_data group_data ( - .op(data_group_op), - .rd(data_rd), + .decode(data_alu), .writeback(data_writeback), .update_flags(data_update_flags), .* @@ -58,23 +54,21 @@ module core_decode branch = 0; writeback = 0; update_flags = 0; - rd = 4'bxxxx; - data_op = 4'bxxxx; + alu = {($bits(alu)){1'bx}}; priority casez(insn `FIELD_OP) `GROUP_B: begin branch = 1; if(branch_link) begin - rd = `R14; + alu.rd = `R14; writeback = 1; //TODO: Valor de LR end end `GROUP_ALU: begin - rd = data_rd; + alu = data_alu; writeback = data_writeback; - data_op = data_group_op; update_flags = data_update_flags; end |
