Skip to content

Commit

Permalink
controller, spatz: Fix chaining for multiple interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
mp-17 committed May 18, 2024
1 parent 29261da commit 08840f6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 10 deletions.
5 changes: 4 additions & 1 deletion hw/ip/spatz/src/spatz.sv
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
spatz_id_t [NrReadPorts+NrWritePorts-1:0] sb_id;

spatz_controller #(
.NrMemPorts (NrMemPorts ),
.NrVregfilePorts (NrReadPorts+NrWritePorts),
.NrWritePorts (NrWritePorts ),
.RegisterRsp (RegisterRsp ),
Expand Down Expand Up @@ -330,7 +331,9 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
.vrf_re_o (sb_re[VLSU_VD_RD1:VLSU_VS2_RD0] ),
.vrf_rdata_i (vrf_rdata[VLSU_VD_RD1:VLSU_VS2_RD0] ),
.vrf_rvalid_i (vrf_rvalid[VLSU_VD_RD1:VLSU_VS2_RD0] ),
.vrf_id_o ({sb_id[SB_VLSU_VD_WD1:SB_VLSU_VD_WD0], sb_id[VLSU_VD_RD1:VLSU_VS2_RD0]}),
// .vrf_id_o ({sb_id[SB_VLSU_VD_WD1:SB_VLSU_VD_WD0], sb_id[VLSU_VD_RD1:VLSU_VS2_RD0]}),
.vrf_id_o ({sb_id[SB_VLSU_VD_WD1], sb_id[VLSU_VD_RD1], sb_id[VLSU_VS2_RD1],
sb_id[SB_VLSU_VD_WD0], sb_id[VLSU_VD_RD0], sb_id[VLSU_VS2_RD0]}),
// Interface Memory
.spatz_mem_req_o (spatz_mem_req_o ),
.spatz_mem_req_valid_o (spatz_mem_req_valid_o ),
Expand Down
48 changes: 39 additions & 9 deletions hw/ip/spatz/src/spatz_controller.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ module spatz_controller
import fpnew_pkg::roundmode_e;
import fpnew_pkg::fmt_mode_t;
#(
parameter int unsigned NrMemPorts = 1,
parameter int unsigned NrVregfilePorts = 1,
parameter int unsigned NrWritePorts = 1,
parameter bit RegisterRsp = 0,
parameter type spatz_issue_req_t = logic,
parameter type spatz_issue_rsp_t = logic,
parameter type spatz_rsp_t = logic
parameter type spatz_rsp_t = logic,
// Dependant parameters. DO NOT CHANGE!
localparam int unsigned NrInterfaces = NrMemPorts / spatz_pkg::N_FU
) (
input logic clk_i,
input logic rst_ni,
Expand Down Expand Up @@ -238,13 +241,23 @@ module spatz_controller
`FF(scoreboard_q, scoreboard_d, '0)

// Did the instruction write to the VRF in the previous cycle?
logic [NrParallelInstructions-1:0] wrote_result_q, wrote_result_d;
logic [NrInterfaces-1:0] [NrParallelInstructions-1:0] wrote_result_q, wrote_result_d;
// Did the instruction write to the VRF in the previous cycle with all its interfaces?
logic [NrParallelInstructions-1:0] wrote_result_all_intf_q;
`FF(wrote_result_q, wrote_result_d, '0)

// Did the instruction write twice to the VRF in the previous two cycles?
logic [NrParallelInstructions-1:0] wrote_result_twice_d, wrote_result_twice_q;
`FF(wrote_result_twice_q, wrote_result_twice_d, '0)

// Is this instruction a narrowing or widening instruction?
logic [NrParallelInstructions-1:0] narrow_wide_q, narrow_wide_d;
`FF(narrow_wide_q, narrow_wide_d, '0)

// Is this an instruction that reads the VRF with more than one interface?
logic [NrParallelInstructions-1:0] is_multi_intf_rd_d, is_multi_intf_rd_q;
`FF(is_multi_intf_rd_q, is_multi_intf_rd_d, '0)

// Did this narrowing instruction write to the VRF in the previous cycle?
logic [NrParallelInstructions-1:0] wrote_result_narrowing_q, wrote_result_narrowing_d;
`FF(wrote_result_narrowing_q, wrote_result_narrowing_d, '0)
Expand All @@ -255,32 +268,42 @@ module spatz_controller
write_table_d = write_table_q;
scoreboard_d = scoreboard_q;
narrow_wide_d = narrow_wide_q;
is_multi_intf_rd_d = is_multi_intf_rd_q;
wrote_result_narrowing_d = wrote_result_narrowing_q;

// Nobody wrote to the VRF yet
wrote_result_d = '0;
sb_enable_o = '0;
wrote_result_twice_d = '0;
wrote_result_d = '0;
sb_enable_o = '0;

wrote_result_all_intf_q = '1;
for (int unsigned intf = 0; intf < NrInterfaces; intf++)
wrote_result_all_intf_q &= wrote_result_q[intf];

for (int unsigned port = 0; port < NrVregfilePorts; port++)
// Enable the VRF port if the dependant instructions wrote in the previous cycle
sb_enable_o[port] = sb_enable_i[port] && &(~scoreboard_q[sb_id_i[port]].deps | wrote_result_q) && (!(|scoreboard_q[sb_id_i[port]].deps) || !scoreboard_q[sb_id_i[port]].prevent_chaining);
sb_enable_o[port] = sb_enable_i[port] && &(~scoreboard_q[sb_id_i[port]].deps | (is_multi_intf_rd_q[sb_id_i[port]] ? wrote_result_twice_q : wrote_result_all_intf_q)) && (!(|scoreboard_q[sb_id_i[port]].deps) || !scoreboard_q[sb_id_i[port]].prevent_chaining);

// Store the decisions
if (sb_enable_o[SB_VFU_VD_WD]) begin
wrote_result_twice_d[sb_id_i[SB_VFU_VD_WD]] = wrote_result_all_intf_q[sb_id_i[SB_VFU_VD_WD]] && sb_wrote_result_i[SB_VFU_VD_WD - SB_VFU_VD_WD] && !wrote_result_twice_q[sb_id_i[SB_VFU_VD_WD]];
wrote_result_narrowing_d[sb_id_i[SB_VFU_VD_WD]] = sb_wrote_result_i[SB_VFU_VD_WD - SB_VFU_VD_WD] ^ narrow_wide_q[sb_id_i[SB_VFU_VD_WD]];
wrote_result_d[sb_id_i[SB_VFU_VD_WD]] = sb_wrote_result_i[SB_VFU_VD_WD - SB_VFU_VD_WD] && (!narrow_wide_q[sb_id_i[SB_VFU_VD_WD]] || wrote_result_narrowing_q[sb_id_i[SB_VFU_VD_WD]]);
wrote_result_d[sb_id_i[SB_VFU_VD_WD]] = {2{sb_wrote_result_i[SB_VFU_VD_WD - SB_VFU_VD_WD] && (!narrow_wide_q[sb_id_i[SB_VFU_VD_WD]] || wrote_result_narrowing_q[sb_id_i[SB_VFU_VD_WD]])}};
end
if (sb_enable_o[SB_VLSU_VD_WD0]) begin
wrote_result_twice_d[sb_id_i[SB_VLSU_VD_WD0]] = wrote_result_all_intf_q[sb_id_i[SB_VLSU_VD_WD0]] && sb_wrote_result_i[SB_VLSU_VD_WD0 - SB_VFU_VD_WD] && !wrote_result_twice_q[sb_id_i[SB_VLSU_VD_WD0]];
wrote_result_narrowing_d[sb_id_i[SB_VLSU_VD_WD0]] = sb_wrote_result_i[SB_VLSU_VD_WD0 - SB_VFU_VD_WD] ^ narrow_wide_q[sb_id_i[SB_VLSU_VD_WD0]];
wrote_result_d[sb_id_i[SB_VLSU_VD_WD0]] = sb_wrote_result_i[SB_VLSU_VD_WD0 - SB_VFU_VD_WD] && (!narrow_wide_q[sb_id_i[SB_VLSU_VD_WD0]] || wrote_result_narrowing_q[sb_id_i[SB_VLSU_VD_WD0]]);
wrote_result_d[0][sb_id_i[SB_VLSU_VD_WD0]] = sb_wrote_result_i[SB_VLSU_VD_WD0 - SB_VFU_VD_WD] && (!narrow_wide_q[sb_id_i[SB_VLSU_VD_WD0]] || wrote_result_narrowing_q[sb_id_i[SB_VLSU_VD_WD0]]);
end
if (sb_enable_o[SB_VLSU_VD_WD1]) begin
wrote_result_twice_d[sb_id_i[SB_VLSU_VD_WD1]] = wrote_result_all_intf_q[sb_id_i[SB_VLSU_VD_WD1]] && sb_wrote_result_i[SB_VLSU_VD_WD1 - SB_VFU_VD_WD] && !wrote_result_twice_q[sb_id_i[SB_VLSU_VD_WD1]];
wrote_result_narrowing_d[sb_id_i[SB_VLSU_VD_WD1]] = sb_wrote_result_i[SB_VLSU_VD_WD1 - SB_VFU_VD_WD] ^ narrow_wide_q[sb_id_i[SB_VLSU_VD_WD1]];
wrote_result_d[sb_id_i[SB_VLSU_VD_WD1]] = sb_wrote_result_i[SB_VLSU_VD_WD1 - SB_VFU_VD_WD] && (!narrow_wide_q[sb_id_i[SB_VLSU_VD_WD1]] || wrote_result_narrowing_q[sb_id_i[SB_VLSU_VD_WD1]]);
wrote_result_d[1][sb_id_i[SB_VLSU_VD_WD1]] = sb_wrote_result_i[SB_VLSU_VD_WD1 - SB_VFU_VD_WD] && (!narrow_wide_q[sb_id_i[SB_VLSU_VD_WD1]] || wrote_result_narrowing_q[sb_id_i[SB_VLSU_VD_WD1]]);
end
if (sb_enable_o[SB_VSLDU_VD_WD]) begin
wrote_result_twice_d[sb_id_i[SB_VSLDU_VD_WD]] = wrote_result_all_intf_q[sb_id_i[SB_VSLDU_VD_WD]] && sb_wrote_result_i[SB_VSLDU_VD_WD - SB_VFU_VD_WD] && !wrote_result_twice_q[sb_id_i[SB_VSLDU_VD_WD]];
wrote_result_narrowing_d[sb_id_i[SB_VSLDU_VD_WD]] = sb_wrote_result_i[SB_VSLDU_VD_WD - SB_VFU_VD_WD] ^ narrow_wide_q[sb_id_i[SB_VSLDU_VD_WD]];
wrote_result_d[sb_id_i[SB_VSLDU_VD_WD]] = sb_wrote_result_i[SB_VSLDU_VD_WD - SB_VFU_VD_WD] && (!narrow_wide_q[sb_id_i[SB_VSLDU_VD_WD]] || wrote_result_narrowing_q[sb_id_i[SB_VSLDU_VD_WD]]);
wrote_result_d[sb_id_i[SB_VSLDU_VD_WD]] = {2{sb_wrote_result_i[SB_VSLDU_VD_WD - SB_VFU_VD_WD] && (!narrow_wide_q[sb_id_i[SB_VSLDU_VD_WD]] || wrote_result_narrowing_q[sb_id_i[SB_VSLDU_VD_WD]])}};
end

// A unit has finished its VRF access. Reset the scoreboard. For each instruction, check
Expand All @@ -295,6 +318,7 @@ module spatz_controller

scoreboard_d[vfu_rsp_i.id] = '0;
narrow_wide_d[vfu_rsp_i.id] = 1'b0;
is_multi_intf_rd_d[vfu_rsp_i.id] = 1'b0;
wrote_result_narrowing_d[vfu_rsp_i.id] = 1'b0;
for (int unsigned insn = 0; insn < NrParallelInstructions; insn++)
scoreboard_d[insn].deps[vfu_rsp_i.id] = 1'b0;
Expand All @@ -309,6 +333,7 @@ module spatz_controller

scoreboard_d[vlsu_rsp_i.id] = '0;
narrow_wide_d[vlsu_rsp_i.id] = 1'b0;
is_multi_intf_rd_d[vfu_rsp_i.id] = 1'b0;
wrote_result_narrowing_d[vlsu_rsp_i.id] = 1'b0;
for (int unsigned insn = 0; insn < NrParallelInstructions; insn++)
scoreboard_d[insn].deps[vlsu_rsp_i.id] = 1'b0;
Expand All @@ -323,6 +348,7 @@ module spatz_controller

scoreboard_d[vsldu_rsp_i.id] = '0;
narrow_wide_d[vsldu_rsp_i.id] = 1'b0;
is_multi_intf_rd_d[vfu_rsp_i.id] = 1'b0;
wrote_result_narrowing_d[vsldu_rsp_i.id] = 1'b0;
for (int unsigned insn = 0; insn < NrParallelInstructions; insn++)
scoreboard_d[insn].deps[vsldu_rsp_i.id] = 1'b0;
Expand Down Expand Up @@ -358,6 +384,10 @@ module spatz_controller
// Is this a narrowing or widening instruction?
if (spatz_req.op_arith.is_narrowing || spatz_req.op_arith.widen_vs1 || spatz_req.op_arith.widen_vs2)
narrow_wide_d[spatz_req.id] = 1'b1;

// Is this an instruction that reads the VRF with more than one interface?
if (spatz_req.op inside {VSE, VSSE, VSXE})
is_multi_intf_rd_d[spatz_req.id] = 1'b1;
end

// An instruction never depends on itself
Expand Down

0 comments on commit 08840f6

Please sign in to comment.