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

scoreboard: use LZCs instead of rr_arb_trees REPLACE THIS


Signed-off-by: default avatarAlban Gruin <alban.gruin@irit.fr>
parent 434ff5a4
No related branches found
No related tags found
No related merge requests found
...@@ -249,70 +249,45 @@ module scoreboard #( ...@@ -249,70 +249,45 @@ module scoreboard #(
// RD clobber process // RD clobber process
// ------------------- // -------------------
// rd_clobber output: output currently clobbered destination registers // 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-1:0] gpr_clobber_vld;
logic [2**ariane_pkg::REG_ADDR_SIZE-1:0][NR_ENTRIES:0] fpr_clobber_vld; logic [2**ariane_pkg::REG_ADDR_SIZE-1:0][NR_ENTRIES-1:0] fpr_clobber_vld;
ariane_pkg::fu_t [NR_ENTRIES:0] clobber_fu; ariane_pkg::fu_t [NR_ENTRIES-1:0] clobber_fu;
always_comb begin : clobber_assign for (genvar i = 0; i < 2**ariane_pkg::REG_ADDR_SIZE; i++) begin
gpr_clobber_vld = '0; for (genvar j = 0; j < NR_ENTRIES; j++) begin
fpr_clobber_vld = '0; 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;
// 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;
end end
end
// GPR[0] is always free for (genvar k = 0; k < NR_ENTRIES; k++) begin
gpr_clobber_vld[0] = '0; assign clobber_fu[k] = mem_q[k].sbe.fu;
end end
for (genvar k = 0; k < 2**ariane_pkg::REG_ADDR_SIZE; k++) begin : gen_sel_clobbers for (genvar k = 0; k < 2**ariane_pkg::REG_ADDR_SIZE; k++) begin
// get fu that is going to clobber this register (there should be only one) logic [$clog2(NR_ENTRIES)-1:0] gpr_clobber_idx, fpr_clobber_idx;
rr_arb_tree #( logic gpr_no_clobber, fpr_no_clobber;
.NumIn(NR_ENTRIES+1),
.DataType(ariane_pkg::fu_t), lzc #(
.ExtPrio(1'b1), .WIDTH ( NR_ENTRIES ),
.AxiVldRdy(1'b1) .MODE ( 0 )
) i_sel_gpr_clobbers ( ) lzc_gpr_clobbers (
.clk_i ( clk_i ), .in_i ( gpr_clobber_vld[k] ),
.rst_ni ( rst_ni ), .cnt_o ( gpr_clobber_idx ),
.flush_i ( 1'b0 ), .empty_o ( gpr_no_clobber )
.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 ( )
); );
rr_arb_tree #(
.NumIn(NR_ENTRIES+1), lzc #(
.DataType(ariane_pkg::fu_t), .WIDTH ( NR_ENTRIES ),
.ExtPrio(1'b1), .MODE ( 0 )
.AxiVldRdy(1'b1) ) lzc_fpr_clobbers (
) i_sel_fpr_clobbers ( .in_i ( fpr_clobber_vld[k] ),
.clk_i ( clk_i ), .cnt_o ( fpr_clobber_idx ),
.rst_ni ( rst_ni ), .empty_o ( fpr_no_clobber )
.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 ( )
); );
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 end
// ---------------------------------- // ----------------------------------
...@@ -320,6 +295,7 @@ module scoreboard #( ...@@ -320,6 +295,7 @@ module scoreboard #(
// ---------------------------------- // ----------------------------------
// read operand interface: same logic as register file // 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 [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 [NR_ENTRIES+NR_WB_PORTS-1:0][riscv::XLEN-1:0] rs_data;
logic rs1_valid, rs2_valid; logic rs1_valid, rs2_valid;
...@@ -337,72 +313,44 @@ module scoreboard #( ...@@ -337,72 +313,44 @@ module scoreboard #(
assign rs_data[k+NR_WB_PORTS] = mem_q[k].sbe.result; assign rs_data[k+NR_WB_PORTS] = mem_q[k].sbe.result;
end end
// check whether we are accessing GPR[0], rs3 is only used with the FPR! lzc #(
assign rs1_valid_o = rs1_valid & ((|rs1_i) | ariane_pkg::is_rs1_fpr(issue_instr_o.op)); .WIDTH ( NR_WB_PORTS+NR_ENTRIES ),
assign rs2_valid_o = rs2_valid & ((|rs2_i) | ariane_pkg::is_rs2_fpr(issue_instr_o.op)); .MODE ( 0 )
) i_lzc_rs1_wb (
// use fixed prio here .in_i ( rs1_fwd_req ),
// this implicitly gives higher prio to WB ports .cnt_o ( rs1_fwd_idx ),
rr_arb_tree #( .empty_o ( )
.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 ( )
); );
rr_arb_tree #( lzc #(
.NumIn(NR_ENTRIES+NR_WB_PORTS), .WIDTH ( NR_WB_PORTS+NR_ENTRIES ),
.DataWidth(riscv::XLEN), .MODE ( 0 )
.ExtPrio(1'b1), ) i_lzc_rs2_wb (
.AxiVldRdy(1'b1) .in_i ( rs2_fwd_req ),
) i_sel_rs2 ( .cnt_o ( rs2_fwd_idx ),
.clk_i ( clk_i ), .empty_o ( )
.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 ( )
); );
riscv::xlen_t rs3; lzc #(
.WIDTH ( NR_WB_PORTS+NR_ENTRIES ),
rr_arb_tree #( .MODE ( 0 )
.NumIn(NR_ENTRIES+NR_WB_PORTS), ) i_lzc_rs3_wb (
.DataWidth(riscv::XLEN), .in_i ( rs3_fwd_req ),
.ExtPrio(1'b1), .cnt_o ( rs3_fwd_idx ),
.AxiVldRdy(1'b1) .empty_o ( )
) 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 ( )
); );
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 // sequential process
always_ff @(posedge clk_i or negedge rst_ni) begin : regs 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