Make branches, slt and left shifts one cycle faster

This commit is contained in:
Olof Kindgren 2025-01-28 23:14:03 +01:00
parent 91628a056a
commit 2f23449f0f
3 changed files with 14 additions and 17 deletions

View file

@ -8,7 +8,6 @@ module serv_bufreg2
input wire [1:0] i_lsb,
input wire i_byte_valid,
output wire o_sh_done,
output wire o_sh_done_r,
//Control
input wire i_op_b_sel,
input wire i_shift_op,
@ -36,8 +35,8 @@ module serv_bufreg2
shifted out at the appropriate time to end up in the correct
position in rd
shift : Data is shifted in during init. After that, the six LSB are used as
a downcounter (with bit 5 initially set to 0) that triggers
o_sh_done and o_sh_done_r when they wrap around to indicate that
a downcounter (with bit 5 initially set to 0) that trigger
o_sh_done when they wrap around to indicate that
the requested number of shifts have been performed
*/
wire [5:0] dat_shamt = (i_shift_op & !i_init) ?
@ -47,7 +46,6 @@ module serv_bufreg2
{dat[6] & !(i_shift_op & i_cnt_done),dat[5:1]};
assign o_sh_done = dat_shamt[5];
assign o_sh_done_r = dat[5];
assign o_q =
((i_lsb == 2'd3) & dat[24]) |

View file

@ -29,7 +29,6 @@ module serv_state
output wire o_ctrl_trap,
input wire i_ctrl_misalign,
input wire i_sh_done,
input wire i_sh_done_r,
output wire [1:0] o_mem_bytecnt,
input wire i_mem_misalign,
//Control
@ -91,6 +90,8 @@ module serv_state
//been calculated.
wire take_branch = i_branch_op & (!i_cond_branch | (i_alu_cmp^i_bne_or_bge));
wire last_init = o_cnt_done & o_init;
//valid signal for mdu
assign o_mdu_valid = MDU & !o_cnt_en & init_done & i_mdu_op;
@ -100,16 +101,16 @@ module serv_state
//Right shift. o_sh_done
//Mem ops. i_dbus_ack
//MDU ops. i_mdu_ready
assign o_rf_wreq = (i_shift_op & (i_sh_right ? (i_sh_done & !o_cnt_en & init_done) : stage_two_req)) |
assign o_rf_wreq = (i_shift_op & (i_sh_right ? (i_sh_done & !o_cnt_en & init_done) : last_init)) |
i_dbus_ack | (MDU & i_mdu_ready) |
(i_branch_op & stage_two_req & !misalign_trap_sync) |
(i_rd_alu_en & i_alu_rd_sel1 & stage_two_req);
(i_branch_op & (last_init & !trap_pending)) |
(i_rd_alu_en & i_alu_rd_sel1 & last_init);
assign o_dbus_cyc = !o_cnt_en & init_done & i_dbus_en & !i_mem_misalign;
//Prepare RF for reads when a new instruction is fetched
// or when stage one caused an exception (rreq implies a write request too)
assign o_rf_rreq = i_ibus_ack | (stage_two_req & misalign_trap_sync);
assign o_rf_rreq = i_ibus_ack | (trap_pending & last_init);
assign o_rf_rd_en = i_rd_op & !o_init;
@ -124,7 +125,8 @@ module serv_state
shift : Shift in during phase 1. Continue shifting between phases (except
for the first cycle after init). Shift out during phase 2
*/
assign o_bufreg_en = (o_cnt_en & (o_init | ((o_ctrl_trap | i_branch_op) & i_two_stage_op))) | (i_shift_op & !stage_two_req & (i_sh_right | i_sh_done_r) & init_done);
assign o_bufreg_en = (o_cnt_en & (o_init | ((o_ctrl_trap | i_branch_op) & i_two_stage_op))) | (i_shift_op & init_done & (i_sh_right ? !stage_two_req : i_sh_done));
assign o_ibus_cyc = ibus_cyc & !i_rst;
@ -215,15 +217,15 @@ module serv_state
assign o_ctrl_trap = WITH_CSR & (i_e_op | i_new_irq | misalign_trap_sync);
generate
if (WITH_CSR) begin : gen_csr
reg misalign_trap_sync_r;
//trap_pending is only guaranteed to have correct value during the
// last cycle of the init stage
wire trap_pending = WITH_CSR & ((take_branch & i_ctrl_misalign & !ALIGN) |
(i_dbus_en & i_mem_misalign));
generate
if (WITH_CSR) begin : gen_csr
reg misalign_trap_sync_r;
always @(posedge i_clk) begin
if (i_ibus_ack | o_cnt_done | i_rst)
misalign_trap_sync_r <= !(i_ibus_ack | i_rst) & ((trap_pending & o_init) | misalign_trap_sync_r);

View file

@ -153,7 +153,6 @@ module serv_top
wire mem_half;
wire [1:0] mem_bytecnt;
wire sh_done;
wire sh_done_r;
wire byte_valid;
wire mem_misalign;
@ -255,7 +254,6 @@ module serv_top
.o_ctrl_trap (trap),
.i_ctrl_misalign(lsb[1]),
.i_sh_done (sh_done),
.i_sh_done_r (sh_done_r),
.o_mem_bytecnt (mem_bytecnt),
.i_mem_misalign (mem_misalign),
//Control
@ -406,7 +404,6 @@ module serv_top
.i_lsb (lsb),
.i_byte_valid (byte_valid),
.o_sh_done (sh_done),
.o_sh_done_r (sh_done_r),
//Control
.i_op_b_sel (op_b_sel),
.i_shift_op (shift_op),