diff options
Diffstat (limited to '')
| -rw-r--r-- | rtl/core/arm810.sv | 2 | ||||
| -rw-r--r-- | rtl/core/control/control.sv | 1 | ||||
| -rw-r--r-- | rtl/core/control/stall.sv | 11 | ||||
| -rw-r--r-- | rtl/core/control/writeback.sv | 20 | ||||
| -rw-r--r-- | rtl/core/psr.sv | 37 |
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 |
