summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rtl/core/arm810.sv6
-rw-r--r--rtl/core/cycles.sv41
-rw-r--r--rtl/core/decode/data.sv78
-rw-r--r--rtl/core/decode/decode.sv36
-rw-r--r--rtl/core/isa.sv24
-rw-r--r--rtl/core/uarch.sv18
6 files changed, 143 insertions, 60 deletions
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