@@ -21,7 +21,8 @@ module spatz_doublebw_vlsu
2121 parameter type spatz_mem_rsp_t = logic ,
2222 // Dependant parameters. DO NOT CHANGE!
2323 localparam int unsigned NrInterfaces = NrMemPorts / spatz_pkg :: N_FU ,
24- localparam int unsigned IdWidth = idx_width (NrOutstandingLoads)
24+ localparam int unsigned IdWidth = idx_width (NrOutstandingLoads),
25+ localparam int unsigned SpatzMemBytes = NrMemPorts * ELENB
2526 ) (
2627 input logic clk_i,
2728 input logic rst_ni,
@@ -482,7 +483,10 @@ module spatz_doublebw_vlsu
482483 // The second interface starts from half of the vector to straighten the write-back VRF access pattern
483484 // To ensure that the 2 interfaces do not also conflict at the TCDM, there is HW scrambling of addresses to TCDM
484485 // such that they access different superbanks.
485- if (! mem_is_indexed && ! mem_is_strided && intf == 1 ) offset + = (mem_spatz_req.vl / 2 );
486+ if (! mem_is_indexed && ! mem_is_strided && intf == 1 ) begin
487+ // Align the vector length with SpatzMemBytes bytes
488+ offset + = ((mem_spatz_req.vl + (SpatzMemBytes / 2 )) >> $clog2 (SpatzMemBytes) << $clog2 (SpatzMemBytes)) / 2 ;
489+ end
486490
487491 addr = mem_spatz_req.rs1 + offset;
488492 mem_req_addr[intf][fu] = (addr >> MAXEW ) << MAXEW ;
@@ -504,7 +508,7 @@ module spatz_doublebw_vlsu
504508
505509 // The second interface starts from half of the vector to straighten the write-back VRF access pattern
506510 if (intf == 1 ) begin
507- vd_vreg_addr[intf] + = commit_insn_q.vl / ( 2 * N_FU * ELENB );
511+ vd_vreg_addr[intf] + = ( commit_insn_q.vl + (SpatzMemBytes / 2 )) >> $clog2 (SpatzMemBytes );
508512 vs2_vreg_idx_addr[intf] + = ((mem_spatz_req.vl >> (mem_spatz_req.vtype.vsew - int '(mem_spatz_req.op_mem.ew))) / (2 * N_FU * ELENB ));
509513 end
510514
@@ -643,6 +647,15 @@ module spatz_doublebw_vlsu
643647 logic [NrInterfaces- 1 : 0 ] vrf_commit_intf_valid, vrf_commit_intf_valid_q;
644648 logic [NrInterfaces- 1 : 0 ] resp_overlap;
645649
650+ // Some metadata tracking to handle small vector length scenario
651+ commit_metadata_t commit_insn_q_rsp;
652+ `FF (commit_insn_q_rsp, commit_insn_q, '0 )
653+
654+ // Check if the vector length is small such that only one of the interface is participating,
655+ // In this case bypass check for a valid response from the second interface
656+ logic vrf_commit_bypass;
657+ assign vrf_commit_bypass = commit_insn_q_rsp.vl <= ( NrMemPorts * ELENB / 2 ) ? 1'b1 : 1'b0 ;
658+
646659 for (genvar intf = 0 ; intf < NrInterfaces; intf++ ) begin : gen_vrf_req_register_intf
647660 spill_register # (
648661 .T (vrf_req_t)
@@ -675,12 +688,13 @@ module spatz_doublebw_vlsu
675688
676689 // To track a valid response on an interface until both interfaces finish and can send to the VRF
677690 // When this happens the FF is cleared
678- // `FFLARNC(vrf_valid_rsp_q[intf], 1'b1, vrf_valid_rsp[intf], vlsu_rsp_valid_o & ~resp_overlap[intf], 1'b0, clk_i, rst_ni)
679691 assign vrf_valid_rsp_d[intf] = (vlsu_rsp_valid_o & ~ resp_overlap[intf]) ? 1'b0 : (vrf_valid_rsp[intf] ? 1'b1 : vrf_valid_rsp_q[intf]);
680692 `FF (vrf_valid_rsp_q[intf], vrf_valid_rsp_d[intf], 1'b0 )
681693
694+ // vrf_commit_intf_valid tracks if an interface is ready for completion
695+ // If only one of the interface has completed, track the completion in vrf_commit_intf_valid_q
682696 // Check if either a previously tracked response or there is a response in the current cycle
683- assign vrf_commit_intf_valid[intf] = vrf_valid_rsp[intf] | vrf_valid_rsp_q[intf];
697+ assign vrf_commit_intf_valid[intf] = vrf_valid_rsp[intf] | vrf_valid_rsp_q[intf] | (intf == 1 ? vrf_commit_bypass : 1'b0 ) ;
684698 `FF (vrf_commit_intf_valid_q[intf], vrf_commit_intf_valid[intf], 1'b0 );
685699 end
686700
@@ -694,11 +708,14 @@ module spatz_doublebw_vlsu
694708 // Check if interface 1 is the interface trying to commit, if so take resp information from interface 1
695709 // If both interfaces in sync, interface 1 is given priority
696710 assign resp_intf = vrf_commit_intf_valid_q [1 ] == 1'b0 ? 1'b1 : 1'b0 ;
711+
712+ // Check is both interfaces has reached to a completion and if the last write to the VRF is also done
713+ // Assign the instruction id from the interface that completes the last
697714 assign vlsu_rsp_o = & vrf_commit_intf_valid && | vrf_req_valid_q ? vrf_req_q[resp_intf].rsp : '{ id: commit_insn_q.id, default : '0 } ;
698715
699716 // Send response back to the controller to indicate end of request
700717 // Check if both the interfaces have completed request and have a valid response to send
701- // Check if atleast one interface has a valid (interfaces can send responses asynchronously, but they finish the request together )
718+ // Check if atleast one interface has a valid (interfaces can send responses asynchronously to the VRF )
702719 // Set reponse high if one of the interfaces has a ready indicating the response has been written to the VRF
703720 assign vlsu_rsp_valid_o = & vrf_commit_intf_valid && | vrf_req_valid_q ? | vrf_req_ready_q : vlsu_finished_req && ! commit_insn_q.is_load;
704721
0 commit comments