summaryrefslogtreecommitdiff
path: root/rtl/core
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rtl/core/arm810.sv2
-rw-r--r--rtl/core/control/control.sv1
-rw-r--r--rtl/core/control/stall.sv11
-rw-r--r--rtl/core/control/writeback.sv20
-rw-r--r--rtl/core/psr.sv37
5 files changed, 16 insertions, 55 deletions
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv
index 026f09b..7fbb895 100644
--- a/rtl/core/arm810.sv
+++ b/rtl/core/arm810.sv
@@ -56,7 +56,6 @@ module arm810
logic explicit_branch, writeback, c_in;
ptr branch_target, pc_visible;
psr_mode reg_mode;
- psr_flags wb_alu_flags;
alu_op alu_ctrl;
shifter_control shifter_ctrl;
word alu_a, alu_b, wr_value;
@@ -93,7 +92,6 @@ module arm810
.write(psr_write),
.saved(psr_saved),
.wr_flags(psr_wr_flags),
- .alu_flags(wb_alu_flags),
.wr_control(psr_wr_control),
.*
);
diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv
index 4bff86e..82aad33 100644
--- a/rtl/core/control/control.sv
+++ b/rtl/core/control/control.sv
@@ -37,7 +37,6 @@ module core_control
output ptr branch_target,
pc_visible,
output psr_mode reg_mode,
- output psr_flags wb_alu_flags,
output alu_op alu,
output word alu_a,
alu_b,
diff --git a/rtl/core/control/stall.sv b/rtl/core/control/stall.sv
index d590325..d2c4de8 100644
--- a/rtl/core/control/stall.sv
+++ b/rtl/core/control/stall.sv
@@ -10,9 +10,7 @@ module core_control_stall
input ctrl_cycle next_cycle,
input logic final_update_flags,
- update_flags,
final_writeback,
- writeback,
input reg_num final_rd,
output logic halted,
@@ -21,8 +19,7 @@ module core_control_stall
next_bubble
);
- logic pc_rd_hazard, pc_wr_hazard, rn_pc_hazard, snd_pc_hazard,
- flags_hazard, flags_dependency, updating_flags;
+ logic pc_rd_hazard, pc_wr_hazard, rn_pc_hazard, snd_pc_hazard, flags_hazard;
assign stall = !next_cycle.issue || next_bubble || halt;
assign halted = halt && !next_bubble;
@@ -32,13 +29,9 @@ module core_control_stall
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;
+ assign flags_hazard = dec.ctrl.conditional && final_update_flags;
assign snd_pc_hazard = !dec.snd.is_imm && dec.snd.r == `R15;
- assign flags_hazard = flags_dependency && updating_flags;
-
- assign updating_flags = final_update_flags || update_flags;
- assign flags_dependency = dec.psr.update_flags || dec.ctrl.conditional;
-
always_ff @(posedge clk or negedge rst_n)
bubble <= !rst_n ? 0 : next_cycle.issue && next_bubble;
diff --git a/rtl/core/control/writeback.sv b/rtl/core/control/writeback.sv
index 5d6d7c6..f28e9a9 100644
--- a/rtl/core/control/writeback.sv
+++ b/rtl/core/control/writeback.sv
@@ -31,8 +31,7 @@ module core_control_writeback
final_writeback,
update_flags,
final_update_flags,
- output word wr_value,
- output psr_flags wb_alu_flags
+ output word wr_value
);
reg_num last_rd;
@@ -79,6 +78,12 @@ module core_control_writeback
wr_value = vector;
else if(next_cycle.mul_hi_wb)
wr_value = mul_q_hi;
+
+ update_flags = 0;
+ if(next_cycle.issue)
+ update_flags = final_update_flags;
+ else if(next_cycle.exception)
+ update_flags = 0;
end
always_ff @(posedge clk or negedge rst_n)
@@ -86,14 +91,9 @@ module core_control_writeback
last_rd <= 0;
final_rd <= 0;
final_writeback <= 0;
-
- update_flags <= 0;
final_update_flags <= 0;
-
- wb_alu_flags <= {$bits(wb_alu_flags){1'b0}};
end else begin
last_rd <= rd;
- wb_alu_flags <= alu_flags;
if(next_cycle.issue)
final_rd <= dec.data.rd;
@@ -110,12 +110,6 @@ module core_control_writeback
else if(next_cycle.exception)
final_writeback <= 1;
- update_flags <= 0;
- if(next_cycle.issue)
- update_flags <= final_update_flags;
- else if(next_cycle.exception)
- update_flags <= 0;
-
if(next_cycle.issue)
final_update_flags <= issue && dec.psr.update_flags;
else if(next_cycle.exception)
diff --git a/rtl/core/psr.sv b/rtl/core/psr.sv
index 1931c2c..ac672ed 100644
--- a/rtl/core/psr.sv
+++ b/rtl/core/psr.sv
@@ -42,27 +42,14 @@ module core_psr
psr_mode m;
} psr_word;
- /* Este diseño de doble búfer es importante por rendimiento. Reducirlo
- * a uno más "sencillo" tiene una pérdida de casi 40MHz en Fmax.
- * Esto se debe a que el CPSR es el mayor mercado del core, se encuentra
- * conectado a cycles, regs, alu y decode. La dependencia con decode en
- * particular es crítica debido a que el condition code se especifica en
- * términos de banderas de CPSR. Una ruta combinacional que atraviese flags
- * iniciaría en cycles, tomaría valores de regs, llegaría a ALU, caería
- * en flags y, debido al operand forwarding que se necesita por hazards de
- * pipeline, esa misma señal seguiría combinacionalmente hacia decode para
- * finalmente registrar en cycles nuevamente. Tal cosa es impermisible.
- */
-
- logic pending_update;
psr_word rd_word, wr_word;
- psr_flags next_flags, wr_alu_flags;
+ psr_flags next_flags;
psr_state cpsr, spsr, spsr_svc, spsr_abt, spsr_und, spsr_irq, spsr_fiq,
wr_state, wr_clean;
assign mode = cpsr.mode;
assign mask = cpsr.mask;
- assign flags = pending_update ? wr_alu_flags : cpsr.flags;
+ assign flags = cpsr.flags;
assign psr_rd = rd_word;
assign wr_word = psr_wr;
assign {wr_state.flags, wr_state.mask, wr_state.mode} = {wr_word.nzcv, wr_word.if_, wr_word.m};
@@ -94,13 +81,9 @@ module core_psr
`endif
always_comb begin
- next_flags = flags;
-
- if(update_flags) begin
- next_flags = alu_flags;
- if(~alu_v_valid)
- next_flags.v = flags.v;
- end
+ next_flags = alu_flags;
+ if(!alu_v_valid)
+ next_flags.v = flags.v;
rd_word = {$bits(rd_word){1'b0}};
rd_word.a = 1;
@@ -135,9 +118,6 @@ module core_psr
always_ff @(posedge clk or negedge rst_n)
if(!rst_n) begin
- wr_alu_flags <= 4'b0000;
- pending_update <= 0;
-
cpsr.mode <= `MODE_SVC;
cpsr.flags <= 4'b0000;
cpsr.mask.i <= 1;
@@ -149,12 +129,9 @@ module core_psr
spsr_irq <= {$bits(spsr_svc){1'b0}};
spsr_fiq <= {$bits(spsr_svc){1'b0}};
end else begin
- wr_alu_flags <= next_flags;
- pending_update <= !write && update_flags;
-
if(!write) begin
- if(pending_update)
- cpsr.flags <= wr_alu_flags;
+ if(update_flags)
+ cpsr.flags <= next_flags;
end else if(!saved)
cpsr <= wr_clean;
else