From 43829e0400f0a7aaccbb1ebefb44a38c41749e77 Mon Sep 17 00:00:00 2001 From: Alejandro Soto Date: Sun, 25 Sep 2022 23:21:32 -0600 Subject: Implement shifter decoding --- rtl/core/arm810.sv | 6 ++-- rtl/core/cycles.sv | 41 ++++++++++++------------- rtl/core/decode/data.sv | 78 ++++++++++++++++++++++++++++++++++++++++++----- rtl/core/decode/decode.sv | 36 +++++++++------------- rtl/core/isa.sv | 24 +++++++++++---- rtl/core/uarch.sv | 18 +++++++++++ 6 files changed, 143 insertions(+), 60 deletions(-) (limited to 'rtl') diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv index 71b6925..5dc8172 100644 --- a/rtl/core/arm810.sv +++ b/rtl/core/arm810.sv @@ -30,8 +30,7 @@ module arm810 logic dec_execute, dec_undefined, dec_writeback, dec_branch, dec_update_flags; ptr dec_branch_offset; - reg_num dec_rd; - alu_op dec_data_op; + alu_decode dec_alu; core_decode decode ( @@ -41,9 +40,8 @@ module arm810 .writeback(dec_writeback), .branch(dec_branch), .update_flags(dec_update_flags), - .rd(dec_rd), .branch_offset(dec_branch_offset), - .data_op(dec_data_op), + .alu(dec_alu), .* ); diff --git a/rtl/core/cycles.sv b/rtl/core/cycles.sv index 3520467..ff4eb34 100644 --- a/rtl/core/cycles.sv +++ b/rtl/core/cycles.sv @@ -2,26 +2,25 @@ module core_cycles ( - input logic clk, - dec_execute, - dec_branch, - dec_writeback, - dec_update_flags, - input reg_num dec_rd, - input ptr dec_branch_offset, - input alu_op dec_data_op, - input ptr fetch_insn_pc, + input logic clk, + dec_execute, + dec_branch, + dec_writeback, + dec_update_flags, + input ptr dec_branch_offset, + input alu_decode dec_alu, + input ptr fetch_insn_pc, - output logic stall, - branch, - writeback, - update_flags, - output reg_num rd, - output ptr branch_target, - pc, - pc_visible, - output psr_mode reg_mode, - output alu_op data_op + output logic stall, + branch, + writeback, + update_flags, + output reg_num rd, + output ptr branch_target, + pc, + pc_visible, + output psr_mode reg_mode, + output alu_op data_op ); enum @@ -50,8 +49,8 @@ module core_cycles end pc <= fetch_insn_pc; - rd <= dec_rd; - data_op <= dec_data_op; + rd <= dec_alu.rd; + data_op <= dec_alu.op; update_flags <= dec_update_flags; end end 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 diff --git a/rtl/core/isa.sv b/rtl/core/isa.sv index 1778d33..35610c2 100644 --- a/rtl/core/isa.sv +++ b/rtl/core/isa.sv @@ -52,12 +52,24 @@ `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_SHIFTER [11:0] +`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 // Instrucciones de multiplicación diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv index 07b479d..c4dd961 100644 --- a/rtl/core/uarch.sv +++ b/rtl/core/uarch.sv @@ -56,4 +56,22 @@ typedef logic[4:0] psr_mode; `define MODE_UND 5'b11011 `define MODE_SYS 5'b11111 +typedef struct packed +{ + 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; +} alu_decode; + `endif -- cgit v1.2.3