summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rtl/core/decode/data.sv90
-rw-r--r--rtl/core/isa.sv47
-rw-r--r--rtl/core/psr.sv9
-rw-r--r--rtl/core/uarch.sv8
4 files changed, 140 insertions, 14 deletions
diff --git a/rtl/core/decode/data.sv b/rtl/core/decode/data.sv
new file mode 100644
index 0000000..7958631
--- /dev/null
+++ b/rtl/core/decode/data.sv
@@ -0,0 +1,90 @@
+`include "core/isa.sv"
+`include "core/psr.sv"
+`include "core/uarch.sv"
+
+module core_decode_data
+(
+ input logic[31:0] insn,
+ input psr_flags flags,
+
+ output alu_op op,
+ output reg_num rn,
+ rd,
+ output logic writeback,
+ update_flags,
+ restore_spsr,
+ zero_fst,
+ negate_fst,
+ negate_snd,
+ carry_in
+);
+
+ assign rn = insn `FIELD_DATA_RN;
+ assign rd = insn `FIELD_DATA_RD;
+
+ always_comb begin
+ update_flags = insn `FIELD_DATA_S;
+ writeback = 1;
+
+ op = ALU_ADD;
+ zero_fst = 0;
+ negate_fst = 0;
+ negate_snd = 0;
+ carry_in = 0;
+
+ unique case(insn `FIELD_DATA_OPCODE)
+ `DATA_ADD: ;
+
+ `DATA_AND: op = ALU_AND;
+ `DATA_EOR: op = ALU_XOR;
+ `DATA_ORR: op = ALU_ORR;
+ `DATA_SUB: negate_snd = 1;
+ `DATA_RSB: negate_fst = 1;
+ `DATA_ADC: carry_in = flags.c;
+ `DATA_MOV: zero_fst = 1;
+ `DATA_CMN: writeback = 0;
+
+ `DATA_MVN: begin
+ zero_fst = 1;
+ negate_snd = 1;
+ end
+
+ `DATA_SBC: begin
+ negate_snd = 1;
+ carry_in = flags.c;
+ end
+
+ `DATA_RSC: begin
+ negate_fst = 1;
+ carry_in = flags.c;
+ end
+
+ `DATA_BIC: begin
+ op = ALU_AND;
+ negate_snd = 1;
+ carry_in = 1;
+ end
+
+ `DATA_TST: begin
+ op = ALU_AND;
+ writeback = 0;
+ end
+
+ `DATA_TEQ: begin
+ op = ALU_XOR;
+ writeback = 0;
+ end
+
+ `DATA_CMP: begin
+ writeback = 0;
+ negate_snd = 1;
+ end
+
+ endcase
+
+ restore_spsr = (rd == `R15) & update_flags;
+ if(restore_spsr)
+ update_flags = 0;
+ end
+
+endmodule
diff --git a/rtl/core/isa.sv b/rtl/core/isa.sv
index 5efe8cd..be012d1 100644
--- a/rtl/core/isa.sv
+++ b/rtl/core/isa.sv
@@ -2,7 +2,11 @@
`define CORE_ISA_SV
`define FIELD_COND [31:28]
-`define FIELD_OP [31:28]
+`define FIELD_OP [27:0]
+
+typedef logic[3:0] reg_num;
+
+`define R15 4'b1111
`define COND_EQ 4'b0000
`define COND_NE 4'b0001
@@ -28,8 +32,8 @@
`define GROUP_B 28'b101_?_????????????????????????
-`define FIELD_B_L [24]
-`define FIELD_B_OFF [23:0]
+`define FIELD_B_L [24]
+`define FIELD_B_OFFSET [23:0]
// Instrucciones de procesamiento de datos (aritmético-lógicas y MOV)
@@ -50,16 +54,31 @@
`define INSN_BIC 28'b00_?_1110_?_????_????_????????????
`define INSN_MVN 28'b00_?_1111_?_0000_????_????????????
-`define GROUP_CMP 28'b00_?_10??_1_????_0000_????????????
-`define GROUP_MOV 28'b00_?_11?1_?_0000_????_????????????
-`define GROUP_AL 28'b00_?_????_?_????_????_????????????
-
-`define FIELD_DATA_IMM [25]
-`define FIELD_DATA_OPCODE [24:21]
-`define FIELD_DATA_SET_FLAGS [20]
-`define FIELD_DATA_RN [19:16]
-`define FIELD_DATA_RD [15:12]
-`define FIELD_DATA_SHIFTER [11:0]
+`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 DATA_AND 4'b0000
+`define DATA_EOR 4'b0001
+`define DATA_SUB 4'b0010
+`define DATA_RSB 4'b0011
+`define DATA_ADD 4'b0100
+`define DATA_ADC 4'b0101
+`define DATA_SBC 4'b0110
+`define DATA_RSC 4'b0111
+`define DATA_TST 4'b1000
+`define DATA_TEQ 4'b1001
+`define DATA_CMP 4'b1010
+`define DATA_CMN 4'b1011
+`define DATA_ORR 4'b1100
+`define DATA_MOV 4'b1101
+`define DATA_BIC 4'b1110
+`define DATA_MVN 4'b1111
// Instrucciones de multiplicación
@@ -176,6 +195,6 @@
`define INSN_SWI 28'b1111_????????????????????????
-`defin FIELD_SWI_IMM [23:0]
+`define FIELD_SWI_IMM [23:0]
`endif
diff --git a/rtl/core/psr.sv b/rtl/core/psr.sv
new file mode 100644
index 0000000..a66751a
--- /dev/null
+++ b/rtl/core/psr.sv
@@ -0,0 +1,9 @@
+`ifndef CORE_PSR_SV
+`define CORE_PSR_SV
+
+typedef struct packed
+{
+ logic n, z, c, v;
+} psr_flags;
+
+`endif
diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv
index a08ddef..c5a449c 100644
--- a/rtl/core/uarch.sv
+++ b/rtl/core/uarch.sv
@@ -4,4 +4,12 @@
// Decodifica como andeq r0, r0, r0
`define NOP 32'd0
+typedef enum logic[1:0]
+{
+ ALU_ADD,
+ ALU_AND,
+ ALU_ORR,
+ ALU_XOR
+} alu_op;
+
`endif