summaryrefslogtreecommitdiff
path: root/rtl/core
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/core')
-rw-r--r--rtl/core/arm810.sv6
-rw-r--r--rtl/core/control/control.sv20
-rw-r--r--rtl/core/control/cycles.sv13
-rw-r--r--rtl/core/control/issue.sv9
-rw-r--r--rtl/core/control/psr.sv56
-rw-r--r--rtl/core/control/select.sv5
-rw-r--r--rtl/core/control/stall.sv7
-rw-r--r--rtl/core/control/writeback.sv3
-rw-r--r--rtl/core/decode/decode.sv7
-rw-r--r--rtl/core/decode/isa.sv2
-rw-r--r--rtl/core/decode/mux.sv13
-rw-r--r--rtl/core/psr.sv65
-rw-r--r--rtl/core/uarch.sv6
13 files changed, 161 insertions, 51 deletions
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv
index 7fbb895..89a2a68 100644
--- a/rtl/core/arm810.sv
+++ b/rtl/core/arm810.sv
@@ -76,16 +76,12 @@ module arm810
.*
);
- word psr_rd, psr_wr;
+ word cpsr_rd, spsr_rd, psr_wr;
logic psr_write, psr_saved, update_flags, psr_wr_flags, psr_wr_control;
psr_mode mode;
psr_flags flags;
psr_intmask intmask;
- //TODO
- assign psr_write = 0;
- assign psr_saved = 0;
-
core_psr psr
(
.mask(intmask),
diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv
index 82aad33..9f398dc 100644
--- a/rtl/core/control/control.sv
+++ b/rtl/core/control/control.sv
@@ -8,9 +8,12 @@ module core_control
input insn_decode dec,
input ptr insn_pc,
+ input psr_mode mode,
input psr_flags flags,
alu_flags,
- input word rd_value_a,
+ input word cpsr_rd,
+ spsr_rd,
+ rd_value_a,
rd_value_b,
q_alu,
q_shifter,
@@ -57,7 +60,12 @@ module core_control
mul_long,
mul_start,
mul_signed,
- coproc
+ coproc,
+ psr_saved,
+ psr_write,
+ psr_wr_flags,
+ psr_wr_control,
+ output word psr_wr
);
ctrl_cycle cycle, next_cycle;
@@ -118,6 +126,14 @@ module core_control
.*
);
+ word psr_wb;
+ logic psr, final_psr_write, final_restore_spsr;
+
+ core_control_psr ctrl_psr
+ (
+ .*
+ );
+
logic final_writeback, final_update_flags;
reg_num final_rd;
diff --git a/rtl/core/control/cycles.sv b/rtl/core/control/cycles.sv
index ca47f10..b7a7829 100644
--- a/rtl/core/control/cycles.sv
+++ b/rtl/core/control/cycles.sv
@@ -6,6 +6,7 @@ module core_control_cycles
rst_n,
halt,
mul,
+ psr,
ldst,
bubble,
exception,
@@ -39,7 +40,8 @@ module core_control_cycles
EXCEPTION,
MUL,
MUL_ACC_LD,
- MUL_HI_WB
+ MUL_HI_WB,
+ PSR
} state, next_state;
// TODO: debe estar escrito de tal forma que Quartus infiera una FSM
@@ -53,6 +55,7 @@ module core_control_cycles
assign cycle.mul = state == MUL;
assign cycle.mul_acc_ld = state == MUL_ACC_LD;
assign cycle.mul_hi_wb = state == MUL_HI_WB;
+ assign cycle.psr = state == PSR;
assign next_cycle.issue = next_state == ISSUE;
assign next_cycle.rd_indirect_shift = next_state == RD_INDIRECT_SHIFT;
@@ -63,6 +66,7 @@ module core_control_cycles
assign next_cycle.mul = next_state == MUL;
assign next_cycle.mul_acc_ld = next_state == MUL_ACC_LD;
assign next_cycle.mul_hi_wb = next_state == MUL_HI_WB;
+ assign next_cycle.psr = next_state == PSR;
always_comb begin
next_state = ISSUE;
@@ -109,8 +113,11 @@ module core_control_cycles
if(bubble)
next_state = ISSUE;
- else if(next_state == ISSUE && ldst) begin
- next_state = TRANSFER;
+ else if(next_state == ISSUE) begin
+ if(ldst)
+ next_state = TRANSFER;
+ else if(psr)
+ next_state = PSR;
end
end
diff --git a/rtl/core/control/issue.sv b/rtl/core/control/issue.sv
index d124a0d..ffdf250 100644
--- a/rtl/core/control/issue.sv
+++ b/rtl/core/control/issue.sv
@@ -23,7 +23,10 @@ module core_control_issue
next_pc_visible
);
- assign issue = next_cycle.issue && dec.ctrl.execute && !next_bubble && !halt;
+ logic valid;
+
+ assign valid = !next_bubble && !halt;
+ assign issue = next_cycle.issue && dec.ctrl.execute && valid;
assign next_pc_visible = insn_pc + 2;
always_ff @(posedge clk or negedge rst_n)
@@ -32,14 +35,14 @@ module core_control_issue
undefined <= 0;
pc_visible <= 2;
end else if(next_cycle.issue) begin
- if(issue) begin
+ if(valid) begin
undefined <= dec.ctrl.undefined;
`ifdef VERILATOR
if(dec.ctrl.undefined)
$display("[core] undefined insn: [0x%08x] %08x", insn_pc << 2, insn);
- end
`endif
+ end
pc <= insn_pc;
pc_visible <= next_pc_visible;
diff --git a/rtl/core/control/psr.sv b/rtl/core/control/psr.sv
new file mode 100644
index 0000000..758b730
--- /dev/null
+++ b/rtl/core/control/psr.sv
@@ -0,0 +1,56 @@
+`include "core/uarch.sv"
+
+module core_control_psr
+(
+ input logic clk,
+ rst_n,
+
+ input insn_decode dec,
+ input word cpsr_rd,
+ spsr_rd,
+ alu_b,
+ input psr_mode mode,
+
+ input ctrl_cycle next_cycle,
+ input logic issue,
+
+ output logic psr,
+ psr_saved,
+ psr_write,
+ psr_wr_flags,
+ psr_wr_control,
+ final_psr_write,
+ final_restore_spsr,
+ output word psr_wb,
+ psr_wr,
+ output psr_mode reg_mode
+);
+
+ assign psr_wb = psr_saved ? spsr_rd : cpsr_rd;
+ assign psr_wr = final_restore_spsr ? spsr_rd : alu_b;
+ assign psr_write = next_cycle.issue && (final_psr_write || final_restore_spsr);
+
+ //TODO: casos donde esto no es cierto
+ assign reg_mode = mode;
+
+ always_ff @(posedge clk or negedge rst_n)
+ if(!rst_n) begin
+ psr <= 0;
+ psr_saved <= 0;
+ psr_wr_flags <= 0;
+ psr_wr_control <= 0;
+
+ final_psr_write <= 0;
+ final_restore_spsr <= 0;
+ end else if(next_cycle.issue) begin
+ psr <= issue && dec.ctrl.psr;
+ psr_saved <= dec.psr.saved;
+ psr_wr_flags <= dec.psr.wr_flags;
+ psr_wr_control <= dec.psr.wr_control;
+
+ final_psr_write <= issue && dec.psr.write;
+ final_restore_spsr <= issue && dec.psr.restore_spsr;
+ end else if(next_cycle.psr)
+ psr <= 0;
+
+endmodule
diff --git a/rtl/core/control/select.sv b/rtl/core/control/select.sv
index 3cc0ca5..1ea2c31 100644
--- a/rtl/core/control/select.sv
+++ b/rtl/core/control/select.sv
@@ -17,14 +17,11 @@ module core_control_select
mul_r_add_hi,
output reg_num ra,
- rb,
- output psr_mode reg_mode
+ rb
);
reg_num r_shift, last_ra, last_rb;
- assign reg_mode = `MODE_SVC; //TODO
-
always_comb begin
ra = last_ra;
rb = last_rb;
diff --git a/rtl/core/control/stall.sv b/rtl/core/control/stall.sv
index d2c4de8..085f11e 100644
--- a/rtl/core/control/stall.sv
+++ b/rtl/core/control/stall.sv
@@ -10,6 +10,8 @@ module core_control_stall
input ctrl_cycle next_cycle,
input logic final_update_flags,
+ final_restore_spsr,
+ final_psr_write,
final_writeback,
input reg_num final_rd,
@@ -19,13 +21,14 @@ module core_control_stall
next_bubble
);
- logic pc_rd_hazard, pc_wr_hazard, rn_pc_hazard, snd_pc_hazard, flags_hazard;
+ logic pc_rd_hazard, pc_wr_hazard, rn_pc_hazard, snd_pc_hazard, psr_hazard, flags_hazard;
assign stall = !next_cycle.issue || next_bubble || halt;
assign halted = halt && !next_bubble;
- assign next_bubble = pc_rd_hazard || pc_wr_hazard || flags_hazard;
+ assign next_bubble = pc_rd_hazard || pc_wr_hazard || flags_hazard || psr_hazard;
//FIXME: pc_rd_hazard no debería definirse sin final_writeback?
+ assign psr_hazard = final_psr_write || final_restore_spsr;
assign pc_rd_hazard = final_writeback && (rn_pc_hazard || snd_pc_hazard);
assign pc_wr_hazard = final_writeback && final_rd == `R15;
assign rn_pc_hazard = dec.data.uses_rn && dec.data.rn == `R15;
diff --git a/rtl/core/control/writeback.sv b/rtl/core/control/writeback.sv
index f28e9a9..824d867 100644
--- a/rtl/core/control/writeback.sv
+++ b/rtl/core/control/writeback.sv
@@ -18,6 +18,7 @@ module core_control_writeback
next_cycle,
input word saved_base,
vector,
+ psr_wb,
input reg_num ra,
popped,
mul_r_add_hi,
@@ -65,6 +66,8 @@ module core_control_writeback
wr_value = saved_base;
else if(cycle.mul || cycle.mul_hi_wb)
wr_value = mul_q_lo;
+ else if(cycle.psr)
+ wr_value = psr_wb;
else
// Ruta combinacional larga
wr_value = q_alu;
diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv
index 7d666f3..f16db9a 100644
--- a/rtl/core/decode/decode.sv
+++ b/rtl/core/decode/decode.sv
@@ -27,6 +27,7 @@ module core_decode
assign dec.coproc = dec_coproc;
assign dec_ctrl.mul = mul;
+ assign dec_ctrl.psr = psr;
assign dec_ctrl.ldst = ldst;
assign dec_ctrl.branch = branch;
assign dec_ctrl.coproc = coproc;
@@ -35,7 +36,7 @@ module core_decode
assign dec_ctrl.undefined = undefined;
assign dec_ctrl.conditional = conditional;
- assign dec_psr.saved = spsr;
+ assign dec_psr.saved = psr_saved;
assign dec_psr.write = psr_write;
assign dec_psr.wr_flags = psr_wr_flags;
assign dec_psr.wr_control = psr_wr_control;
@@ -43,8 +44,8 @@ module core_decode
assign dec_psr.restore_spsr = restore_spsr;
logic execute, undefined, conditional, writeback, update_flags,
- restore_spsr, branch, ldst, mul, coproc, spsr, psr_write,
- psr_wr_flags, psr_wr_control;
+ restore_spsr, branch, ldst, mul, psr, coproc, psr_saved,
+ psr_write, psr_wr_flags, psr_wr_control;
core_decode_mux mux
(
diff --git a/rtl/core/decode/isa.sv b/rtl/core/decode/isa.sv
index 4f2578d..1273a8b 100644
--- a/rtl/core/decode/isa.sv
+++ b/rtl/core/decode/isa.sv
@@ -194,7 +194,7 @@
`define GROUP_MSR 28'b0_0_?_1_0_?_1_0_????_1111_0000_0000_????
-`define FIELD_MRS_R [24]
+`define FIELD_MRS_R [22]
`define FIELD_MRS_RD [15:12]
`define FIELD_MSR_I [25]
`define FIELD_MSR_R [22]
diff --git a/rtl/core/decode/mux.sv b/rtl/core/decode/mux.sv
index e8d930e..51fe14b 100644
--- a/rtl/core/decode/mux.sv
+++ b/rtl/core/decode/mux.sv
@@ -55,8 +55,9 @@ module core_decode_mux
branch,
ldst,
mul,
+ psr,
coproc,
- spsr,
+ psr_saved,
psr_write,
psr_wr_flags,
psr_wr_control,
@@ -78,7 +79,8 @@ module core_decode_mux
conditional = 0;
restore_spsr = 0;
- spsr = 0;
+ psr = 0;
+ psr_saved = 0;
psr_write = 0;
update_flags = 0;
psr_wr_flags = 1;
@@ -189,7 +191,8 @@ module core_decode_mux
dec_data.rd = mrs_rd;
dec_data.uses_rn = 0;
- spsr = mrs_spsr;
+ psr = 1;
+ psr_saved = mrs_spsr;
writeback = 1;
conditional = 1;
end
@@ -201,9 +204,10 @@ module core_decode_mux
snd_ror_if_imm = 1;
snd_shift_by_reg_if_reg = 0;
- spsr = msr_spsr;
+ psr = 1;
dec_snd = snd;
psr_write = 1;
+ psr_saved = msr_spsr;
conditional = 1;
psr_wr_flags = msr_fields.f;
psr_wr_control = msr_fields.c;
@@ -233,6 +237,7 @@ module core_decode_mux
execute = 0;
mul = 1'bx;
+ psr = 1'bx;
ldst = 1'bx;
branch = 1'bx;
coproc = 1'bx;
diff --git a/rtl/core/psr.sv b/rtl/core/psr.sv
index ac672ed..c1fe0fd 100644
--- a/rtl/core/psr.sv
+++ b/rtl/core/psr.sv
@@ -16,7 +16,8 @@ module core_psr
output psr_flags flags,
output psr_intmask mask,
output psr_mode mode,
- output word psr_rd
+ output word cpsr_rd,
+ spsr_rd
);
typedef struct packed
@@ -42,7 +43,7 @@ module core_psr
psr_mode m;
} psr_word;
- psr_word rd_word, wr_word;
+ psr_word cpsr_word /*verilator public*/, spsr_word, wr_word;
psr_flags next_flags;
psr_state cpsr, spsr, spsr_svc, spsr_abt, spsr_und, spsr_irq, spsr_fiq,
wr_state, wr_clean;
@@ -50,34 +51,46 @@ module core_psr
assign mode = cpsr.mode;
assign mask = cpsr.mask;
assign flags = cpsr.flags;
- assign psr_rd = rd_word;
assign wr_word = psr_wr;
+ assign cpsr_rd = cpsr_word;
+ assign spsr_rd = spsr_word;
assign {wr_state.flags, wr_state.mask, wr_state.mode} = {wr_word.nzcv, wr_word.if_, wr_word.m};
`ifdef VERILATOR
- psr_word cpsr_word /*verilator public*/,
- spsr_svc_word /*verilator public*/,
+ psr_word spsr_svc_word /*verilator public*/,
spsr_abt_word /*verilator public*/,
spsr_und_word /*verilator public*/,
spsr_fiq_word /*verilator public*/,
spsr_irq_word /*verilator public*/;
- assign {cpsr_word.nzcv, cpsr_word.if_, cpsr_word.m} = {cpsr.flags, cpsr.mask, cpsr.mode};
+ always_comb begin
+ spsr_svc_word = {$bits(spsr_svc_word){1'b0}};
+ spsr_abt_word = {$bits(spsr_abt_word){1'b0}};
+ spsr_und_word = {$bits(spsr_und_word){1'b0}};
+ spsr_irq_word = {$bits(spsr_irq_word){1'b0}};
+ spsr_fiq_word = {$bits(spsr_fiq_word){1'b0}};
+
+ spsr_svc_word.a = 1;
+ spsr_abt_word.a = 1;
+ spsr_und_word.a = 1;
+ spsr_irq_word.a = 1;
+ spsr_fiq_word.a = 1;
- assign {spsr_svc_word.nzcv, spsr_svc_word.if_, spsr_svc_word.m}
- = {spsr_svc.flags, spsr_svc.mask, spsr_svc.mode};
+ {spsr_svc_word.nzcv, spsr_svc_word.if_, spsr_svc_word.m}
+ = {spsr_svc.flags, spsr_svc.mask, spsr_svc.mode};
- assign {spsr_abt_word.nzcv, spsr_abt_word.if_, spsr_abt_word.m}
- = {spsr_abt.flags, spsr_abt.mask, spsr_abt.mode};
+ {spsr_abt_word.nzcv, spsr_abt_word.if_, spsr_abt_word.m}
+ = {spsr_abt.flags, spsr_abt.mask, spsr_abt.mode};
- assign {spsr_und_word.nzcv, spsr_und_word.if_, spsr_und_word.m}
- = {spsr_und.flags, spsr_und.mask, spsr_und.mode};
+ {spsr_und_word.nzcv, spsr_und_word.if_, spsr_und_word.m}
+ = {spsr_und.flags, spsr_und.mask, spsr_und.mode};
- assign {spsr_irq_word.nzcv, spsr_irq_word.if_, spsr_irq_word.m}
- = {spsr_irq.flags, spsr_irq.mask, spsr_irq.mode};
+ {spsr_irq_word.nzcv, spsr_irq_word.if_, spsr_irq_word.m}
+ = {spsr_irq.flags, spsr_irq.mask, spsr_irq.mode};
- assign {spsr_fiq_word.nzcv, spsr_fiq_word.if_, spsr_fiq_word.m}
- = {spsr_fiq.flags, spsr_fiq.mask, spsr_fiq.mode};
+ {spsr_fiq_word.nzcv, spsr_fiq_word.if_, spsr_fiq_word.m}
+ = {spsr_fiq.flags, spsr_fiq.mask, spsr_fiq.mode};
+ end
`endif
always_comb begin
@@ -85,13 +98,21 @@ module core_psr
if(!alu_v_valid)
next_flags.v = flags.v;
- rd_word = {$bits(rd_word){1'b0}};
- rd_word.a = 1;
+ unique case(mode)
+ `MODE_SVC: spsr = spsr_svc;
+ `MODE_ABT: spsr = spsr_abt;
+ `MODE_UND: spsr = spsr_und;
+ `MODE_IRQ: spsr = spsr_irq;
+ `MODE_FIQ: spsr = spsr_fiq;
+ default: spsr = cpsr;
+ endcase
+
+ cpsr_word = {$bits(cpsr_word){1'b0}};
+ spsr_word = {$bits(spsr_word){1'b0}};
+ {cpsr_word.a, spsr_word.a} = 2'b11;
- if(saved)
- {rd_word.nzcv, rd_word.if_, rd_word.m} = {spsr.flags, spsr.mask, spsr.mode};
- else
- {rd_word.nzcv, rd_word.if_, rd_word.m} = {flags, mask, mode};
+ {cpsr_word.nzcv, cpsr_word.if_, cpsr_word.m} = {flags, mask, mode};
+ {spsr_word.nzcv, spsr_word.if_, spsr_word.m} = {spsr.flags, spsr.mask, spsr.mode};
wr_clean = wr_state;
unique case(wr_state.mode)
diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv
index e089e35..3aff072 100644
--- a/rtl/core/uarch.sv
+++ b/rtl/core/uarch.sv
@@ -86,7 +86,8 @@ typedef struct packed
branch,
coproc,
ldst,
- mul;
+ mul,
+ psr;
} ctrl_decode;
typedef struct packed
@@ -194,7 +195,8 @@ typedef struct packed
exception,
mul,
mul_acc_ld,
- mul_hi_wb;
+ mul_hi_wb,
+ psr;
} ctrl_cycle;
typedef struct packed