Skip to content
Snippets Groups Projects
Commit 48239128 authored by Alban Gruin's avatar Alban Gruin
Browse files

scoreboard: size and timing improvements


Signed-off-by: default avatarAlban Gruin <alban.gruin@irit.fr>
parent a6b1c6cb
Branches
No related tags found
No related merge requests found
......@@ -239,70 +239,45 @@ module scoreboard #(
// RD clobber process
// -------------------
// rd_clobber output: output currently clobbered destination registers
logic [2**ariane_pkg::REG_ADDR_SIZE-1:0][NR_ENTRIES:0] gpr_clobber_vld;
logic [2**ariane_pkg::REG_ADDR_SIZE-1:0][NR_ENTRIES:0] fpr_clobber_vld;
ariane_pkg::fu_t [NR_ENTRIES:0] clobber_fu;
always_comb begin : clobber_assign
gpr_clobber_vld = '0;
fpr_clobber_vld = '0;
// default (highest entry hast lowest prio in arbiter tree below)
clobber_fu[NR_ENTRIES] = ariane_pkg::NONE;
for (int unsigned i = 0; i < 2**ariane_pkg::REG_ADDR_SIZE; i++) begin
gpr_clobber_vld[i][NR_ENTRIES] = 1'b1;
fpr_clobber_vld[i][NR_ENTRIES] = 1'b1;
end
// check for all valid entries and set the clobber accordingly
for (int unsigned i = 0; i < NR_ENTRIES; i++) begin
gpr_clobber_vld[mem_q[i].sbe.rd][i] = ~mem_q[i].pending & mem_q[i].issued & ~mem_q[i].is_rd_fpr_flag;
fpr_clobber_vld[mem_q[i].sbe.rd][i] = ~mem_q[i].pending & mem_q[i].issued & mem_q[i].is_rd_fpr_flag;
clobber_fu[i] = mem_q[i].sbe.fu;
logic [2**ariane_pkg::REG_ADDR_SIZE-1:0][NR_ENTRIES-1:0] gpr_clobber_vld;
logic [2**ariane_pkg::REG_ADDR_SIZE-1:0][NR_ENTRIES-1:0] fpr_clobber_vld;
ariane_pkg::fu_t [NR_ENTRIES-1:0] clobber_fu;
for (genvar i = 0; i < 2**ariane_pkg::REG_ADDR_SIZE; i++) begin
for (genvar j = 0; j < NR_ENTRIES; j++) begin
assign gpr_clobber_vld[i][j] = mem_q[j].sbe.rd == i & ~mem_q[j].pending & mem_q[j].issued & ~mem_q[j].is_rd_fpr_flag & i != 0;
assign fpr_clobber_vld[i][j] = mem_q[j].sbe.rd == i & ~mem_q[j].pending & mem_q[j].issued & mem_q[j].is_rd_fpr_flag;
end
end
// GPR[0] is always free
gpr_clobber_vld[0] = '0;
for (genvar k = 0; k < NR_ENTRIES; k++) begin
assign clobber_fu[k] = mem_q[k].sbe.fu;
end
for (genvar k = 0; k < 2**ariane_pkg::REG_ADDR_SIZE; k++) begin : gen_sel_clobbers
// get fu that is going to clobber this register (there should be only one)
rr_arb_tree #(
.NumIn(NR_ENTRIES+1),
.DataType(ariane_pkg::fu_t),
.ExtPrio(1'b1),
.AxiVldRdy(1'b1)
) i_sel_gpr_clobbers (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( 1'b0 ),
.rr_i ( '0 ),
.req_i ( gpr_clobber_vld[k] ),
.gnt_o ( ),
.data_i ( clobber_fu ),
.gnt_i ( 1'b1 ),
.req_o ( ),
.data_o ( rd_clobber_gpr_o[k] ),
.idx_o ( )
for (genvar k = 0; k < 2**ariane_pkg::REG_ADDR_SIZE; k++) begin
logic [$clog2(NR_ENTRIES)-1:0] gpr_clobber_idx, fpr_clobber_idx;
logic gpr_no_clobber, fpr_no_clobber;
lzc #(
.WIDTH ( NR_ENTRIES ),
.MODE ( 0 )
) lzc_gpr_clobbers (
.in_i ( gpr_clobber_vld[k] ),
.cnt_o ( gpr_clobber_idx ),
.empty_o ( gpr_no_clobber )
);
rr_arb_tree #(
.NumIn(NR_ENTRIES+1),
.DataType(ariane_pkg::fu_t),
.ExtPrio(1'b1),
.AxiVldRdy(1'b1)
) i_sel_fpr_clobbers (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( 1'b0 ),
.rr_i ( '0 ),
.req_i ( fpr_clobber_vld[k] ),
.gnt_o ( ),
.data_i ( clobber_fu ),
.gnt_i ( 1'b1 ),
.req_o ( ),
.data_o ( rd_clobber_fpr_o[k] ),
.idx_o ( )
lzc #(
.WIDTH ( NR_ENTRIES ),
.MODE ( 0 )
) lzc_fpr_clobbers (
.in_i ( fpr_clobber_vld[k] ),
.cnt_o ( fpr_clobber_idx ),
.empty_o ( fpr_no_clobber )
);
assign rd_clobber_gpr_o[k] = (gpr_no_clobber) ? ariane_pkg::NONE : clobber_fu[gpr_clobber_idx];
assign rd_clobber_fpr_o[k] = (fpr_no_clobber) ? ariane_pkg::NONE : clobber_fu[fpr_clobber_idx];
end
// ----------------------------------
......@@ -310,6 +285,7 @@ module scoreboard #(
// ----------------------------------
// read operand interface: same logic as register file
logic [NR_ENTRIES+NR_WB_PORTS-1:0] rs1_fwd_req, rs2_fwd_req, rs3_fwd_req;
logic [$clog2(NR_WB_PORTS+NR_ENTRIES)-1:0] rs1_fwd_idx, rs2_fwd_idx, rs3_fwd_idx;
logic [NR_ENTRIES+NR_WB_PORTS-1:0][riscv::XLEN-1:0] rs_data;
logic rs1_valid, rs2_valid;
......@@ -327,72 +303,44 @@ module scoreboard #(
assign rs_data[k+NR_WB_PORTS] = mem_q[k].sbe.result;
end
// check whether we are accessing GPR[0], rs3 is only used with the FPR!
assign rs1_valid_o = rs1_valid & ((|rs1_i) | ariane_pkg::is_rs1_fpr(issue_instr_o.op));
assign rs2_valid_o = rs2_valid & ((|rs2_i) | ariane_pkg::is_rs2_fpr(issue_instr_o.op));
// use fixed prio here
// this implicitly gives higher prio to WB ports
rr_arb_tree #(
.NumIn(NR_ENTRIES+NR_WB_PORTS),
.DataWidth(riscv::XLEN),
.ExtPrio(1'b1),
.AxiVldRdy(1'b1)
) i_sel_rs1 (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( 1'b0 ),
.rr_i ( '0 ),
.req_i ( rs1_fwd_req ),
.gnt_o ( ),
.data_i ( rs_data ),
.gnt_i ( 1'b1 ),
.req_o ( rs1_valid ),
.data_o ( rs1_o ),
.idx_o ( )
lzc #(
.WIDTH ( NR_WB_PORTS+NR_ENTRIES ),
.MODE ( 0 )
) i_lzc_rs1_wb (
.in_i ( rs1_fwd_req ),
.cnt_o ( rs1_fwd_idx ),
.empty_o ( )
);
rr_arb_tree #(
.NumIn(NR_ENTRIES+NR_WB_PORTS),
.DataWidth(riscv::XLEN),
.ExtPrio(1'b1),
.AxiVldRdy(1'b1)
) i_sel_rs2 (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( 1'b0 ),
.rr_i ( '0 ),
.req_i ( rs2_fwd_req ),
.gnt_o ( ),
.data_i ( rs_data ),
.gnt_i ( 1'b1 ),
.req_o ( rs2_valid ),
.data_o ( rs2_o ),
.idx_o ( )
lzc #(
.WIDTH ( NR_WB_PORTS+NR_ENTRIES ),
.MODE ( 0 )
) i_lzc_rs2_wb (
.in_i ( rs2_fwd_req ),
.cnt_o ( rs2_fwd_idx ),
.empty_o ( )
);
riscv::xlen_t rs3;
rr_arb_tree #(
.NumIn(NR_ENTRIES+NR_WB_PORTS),
.DataWidth(riscv::XLEN),
.ExtPrio(1'b1),
.AxiVldRdy(1'b1)
) i_sel_rs3 (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( 1'b0 ),
.rr_i ( '0 ),
.req_i ( rs3_fwd_req ),
.gnt_o ( ),
.data_i ( rs_data ),
.gnt_i ( 1'b1 ),
.req_o ( rs3_valid_o ),
.data_o ( rs3 ),
.idx_o ( )
lzc #(
.WIDTH ( NR_WB_PORTS+NR_ENTRIES ),
.MODE ( 0 )
) i_lzc_rs3_wb (
.in_i ( rs3_fwd_req ),
.cnt_o ( rs3_fwd_idx ),
.empty_o ( )
);
assign rs3_o = rs3[ariane_pkg::FLEN-1:0];
assign rs1_valid = |rs1_fwd_req;
assign rs2_valid = |rs2_fwd_req;
assign rs3_valid_o = |rs3_fwd_req;
assign rs1_o = (rs1_valid) ? rs_data[rs1_fwd_idx] : '0;
assign rs2_o = (rs2_valid) ? rs_data[rs2_fwd_idx] : '0;
assign rs3_o = (rs3_valid_o) ? rs_data[rs3_fwd_idx] : '0;
// check whether we are accessing GPR[0], rs3 is only used with the FPR!
assign rs1_valid_o = rs1_valid & ((|rs1_i) | ariane_pkg::is_rs1_fpr(issue_instr_o.op));
assign rs2_valid_o = rs2_valid & ((|rs2_i) | ariane_pkg::is_rs2_fpr(issue_instr_o.op));
// sequential process
always_ff @(posedge clk_i or negedge rst_ni) begin : regs
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment