@@ -72,11 +72,12 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
7272 // //////////////
7373
7474 // Number of ports of the vector register file
75- localparam int unsigned NrWritePorts = 3 ;
76- localparam int unsigned NrReadPorts = 6 ;
75+ localparam int unsigned NrWritePorts = 2 + NumVLSUInterfaces; // 1 for VFU and SLDU each and 1 for each VLSU
76+ localparam int unsigned NrReadPorts = 4 + 2 * NumVLSUInterfaces; // 3 for VFU, 1 for SLDU and 2 for each VLSU interface
7777
7878 // FPU buffer size (need atleast depth of 2 to hide conflicts)
7979 localparam int unsigned FpuBufDepth = 4 ;
80+ localparam int unsigned VlsuBufDepth = 2 ;
8081
8182 // ///////////
8283 // Signals //
@@ -92,8 +93,8 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
9293 vfu_rsp_t vfu_rsp, vfu_rsp_buf;
9394
9495 logic vlsu_req_ready;
95- logic vlsu_rsp_valid;
96- vlsu_rsp_t vlsu_rsp;
96+ logic vlsu_rsp_valid, vlsu_rsp_buf_valid ;
97+ vlsu_rsp_t vlsu_rsp, vlsu_rsp_buf ;
9798
9899 logic vsldu_req_ready;
99100 logic vsldu_rsp_valid;
@@ -104,6 +105,7 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
104105 // buffers store the metadata to commit to the VRF in later cycles
105106
106107 logic [$clog2 (FpuBufDepth)- 1 : 0 ] vfu_buf_usage;
108+ logic [$clog2 (VlsuBufDepth)- 1 : 0 ] vlsu_buf_usage;
107109
108110 typedef struct packed {
109111 vrf_data_t wdata;
@@ -116,6 +118,17 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
116118
117119 vfu_buf_t vfu_buf_data;
118120
121+ typedef struct packed {
122+ vrf_data_t wdata;
123+ vrf_addr_t waddr;
124+ vrf_be_t wbe;
125+ spatz_id_t wid;
126+ vlsu_rsp_t rsp;
127+ logic rsp_valid;
128+ } vlsu_buf_t ;
129+
130+ vlsu_buf_t vlsu_buf_data;
131+
119132 // ///////////////////
120133 // FPU sequencer //
121134 // ///////////////////
@@ -218,7 +231,8 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
218231
219232 spatz_vrf # (
220233 .NrReadPorts (NrReadPorts ),
221- .NrWritePorts (NrWritePorts)
234+ .NrWritePorts (NrWritePorts),
235+ .FpuBufDepth (FpuBufDepth )
222236 ) i_vrf (
223237 .clk_i (clk_i ),
224238 .rst_ni (rst_ni ),
@@ -278,9 +292,9 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
278292 .vfu_rsp_ready_o (vfu_rsp_ready ),
279293 .vfu_rsp_i (vfu_rsp_buf ),
280294 // VLSU
281- .vlsu_req_ready_i (vlsu_req_ready ),
282- .vlsu_rsp_valid_i (vlsu_rsp_valid ),
283- .vlsu_rsp_i (vlsu_rsp ),
295+ .vlsu_req_ready_i (vlsu_req_ready ),
296+ .vlsu_rsp_valid_i (vlsu_rsp_buf_valid ),
297+ .vlsu_rsp_i (vlsu_rsp_buf ),
284298 // VLSD
285299 .vsldu_req_ready_i (vsldu_req_ready ),
286300 .vsldu_rsp_valid_i (vsldu_rsp_valid ),
@@ -331,6 +345,40 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
331345 .data_o (vfu_buf_data ),
332346 .pop_i (vfu_buf_pop )
333347 );
348+
349+ `ifdef DOUBLE_BW
350+ // Buffering of VLSU1 when conflicting with VLSU0
351+ logic vlsu_buf_en, vlsu_buf_push, vlsu_buf_pop, vrf_vlsu_wvalid, vlsu_buf_full, vlsu_buf_empty;
352+
353+ assign vlsu_buf_en = sb_we[VLSU_VD_WD1 ] && (! vrf_wvalid[VLSU_VD_WD1 ] || (vrf_wvalid[VLSU_VD_WD1 ] && ! vlsu_buf_empty));
354+ assign vlsu_buf_push = vlsu_buf_en && ! vlsu_buf_full;
355+ assign vlsu_buf_pop = vrf_wvalid[VLSU_VD_WD1 ] && ! vlsu_buf_empty;
356+ assign vrf_vlsu_wvalid = sb_we[VLSU_VD_WD1 ] && ! vlsu_buf_full;
357+
358+ fifo_v3 # (
359+ .FALL_THROUGH (1'b0 ),
360+ .dtype (vlsu_buf_t ),
361+ .DEPTH (VlsuBufDepth )
362+ ) i_vlsu_buf (
363+ .clk_i (clk_i ),
364+ .rst_ni (rst_ni ),
365+ .flush_i (1'b0 ),
366+ .testmode_i (1'b0 ),
367+ .full_o (vlsu_buf_full ),
368+ .empty_o (vlsu_buf_empty ),
369+ .usage_o (vlsu_buf_usage ),
370+ .data_i ({ vrf_wdata[VLSU_VD_WD1 ],
371+ vrf_waddr[VLSU_VD_WD1 ],
372+ vrf_wbe [VLSU_VD_WD1 ],
373+ sb_id [SB_VLSU_VD_WD1 ],
374+ vlsu_rsp,
375+ vlsu_rsp_valid} ),
376+ .push_i (vlsu_buf_push ),
377+ .data_o (vlsu_buf_data ),
378+ .pop_i (vlsu_buf_pop )
379+ );
380+
381+ `endif
334382`endif
335383
336384 always_comb begin
@@ -343,6 +391,8 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
343391 // Responses
344392 vfu_rsp_buf = vfu_rsp;
345393 vfu_rsp_buf_valid = vfu_rsp_valid;
394+ vlsu_rsp_buf = vlsu_rsp;
395+ vlsu_rsp_buf_valid = vlsu_rsp_valid;
346396
347397 // If the buffering feature is used for the FPU or VLSU,
348398 // Use the metadata to commit the data to the VRF
@@ -361,6 +411,30 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
361411 vfu_rsp_buf_valid = 1'b0 ;
362412 end
363413 end
414+
415+ `ifdef DOUBLE_BW
416+ // VLSU1 buffering
417+ // Check if interface 1 response is being buffered, if so do not send response now
418+ if (vlsu_rsp_valid && (vlsu_rsp.intf_id == 1'b1 ) && vlsu_buf_push)
419+ vlsu_rsp_buf_valid = 1'b0 ;
420+
421+ if (! vlsu_buf_empty) begin
422+ sb_we_buf [VLSU_VD_WD1 ] = 1'b1 ;
423+ vrf_wdata_buf[VLSU_VD_WD1 ] = vlsu_buf_data.wdata;
424+ vrf_waddr_buf[VLSU_VD_WD1 ] = vlsu_buf_data.waddr;
425+ vrf_wbe_buf [VLSU_VD_WD1 ] = vlsu_buf_data.wbe;
426+ sb_buf_id [SB_VLSU_VD_WD1 ] = vlsu_buf_data.wid;
427+ if (vlsu_buf_data.rsp_valid) begin
428+ vlsu_rsp_buf = vlsu_buf_data.rsp;
429+ vlsu_rsp_buf_valid = vrf_wvalid[VLSU_VD_WD1 ];
430+ end
431+ end else begin
432+ // If the buffer is being enabled in this cycle, don't send the response now
433+ if (vlsu_buf_en) begin
434+ vlsu_rsp_buf_valid = 1'b0 ;
435+ end
436+ end
437+ `endif
364438`endif
365439 end // always_comb
366440
@@ -405,6 +479,43 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
405479 // VLSU //
406480 // ////////
407481
482+ `ifdef DOUBLE_BW
483+ spatz_doublebw_vlsu # (
484+ .NrMemPorts (NrMemPorts ),
485+ .spatz_mem_req_t (spatz_mem_req_t ),
486+ .spatz_mem_rsp_t (spatz_mem_rsp_t )
487+ ) i_vlsu (
488+ .clk_i (clk_i ),
489+ .rst_ni (rst_ni ),
490+ // Request
491+ .spatz_req_i (spatz_req ),
492+ .spatz_req_valid_i (spatz_req_valid ),
493+ .spatz_req_ready_o (vlsu_req_ready ),
494+ // Response
495+ .vlsu_rsp_valid_o (vlsu_rsp_valid ),
496+ .vlsu_rsp_o (vlsu_rsp ),
497+ // VRF
498+ .vrf_wvalid_i ({ vrf_vlsu_wvalid, vrf_wvalid[VLSU_VD_WD0 ]} ),
499+ .vrf_waddr_o (vrf_waddr[VLSU_VD_WD1 : VLSU_VD_WD0 ] ),
500+ .vrf_wdata_o (vrf_wdata[VLSU_VD_WD1 : VLSU_VD_WD0 ] ),
501+ .vrf_we_o (sb_we[VLSU_VD_WD1 : VLSU_VD_WD0 ] ),
502+ .vrf_wbe_o (vrf_wbe[VLSU_VD_WD1 : VLSU_VD_WD0 ] ),
503+ .vrf_raddr_o (vrf_raddr[VLSU_VD_RD1 : VLSU_VS2_RD0 ] ),
504+ .vrf_re_o (sb_re[VLSU_VD_RD1 : VLSU_VS2_RD0 ] ),
505+ .vrf_rdata_i (vrf_rdata[VLSU_VD_RD1 : VLSU_VS2_RD0 ] ),
506+ .vrf_rvalid_i (vrf_rvalid[VLSU_VD_RD1 : VLSU_VS2_RD0 ] ),
507+ .vrf_id_o ({ sb_id[SB_VLSU_VD_WD1 ], sb_id[VLSU_VD_RD1 ], sb_id[VLSU_VS2_RD1 ], // VLSU Interface-1
508+ sb_id[SB_VLSU_VD_WD0 ], sb_id[VLSU_VD_RD0 ], sb_id[VLSU_VS2_RD0 ]} ), // VLSU Interface-0
509+ // Interface Memory
510+ .spatz_mem_req_o (spatz_mem_req_o ),
511+ .spatz_mem_req_valid_o (spatz_mem_req_valid_o ),
512+ .spatz_mem_req_ready_i (spatz_mem_req_ready_i ),
513+ .spatz_mem_rsp_i (spatz_mem_rsp_i ),
514+ .spatz_mem_rsp_valid_i (spatz_mem_rsp_valid_i ),
515+ .spatz_mem_finished_o (spatz_mem_finished ),
516+ .spatz_mem_str_finished_o (spatz_mem_str_finished )
517+ );
518+ `else
408519 spatz_vlsu # (
409520 .NrMemPorts (NrMemPorts ),
410521 .spatz_mem_req_t (spatz_mem_req_t ),
@@ -439,6 +550,7 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
439550 .spatz_mem_finished_o (spatz_mem_finished ),
440551 .spatz_mem_str_finished_o (spatz_mem_str_finished )
441552 );
553+ `endif
442554
443555 // /////////
444556 // VSLDU //
0 commit comments