@@ -196,6 +196,14 @@ module axi_spi_engine #(
196196 reg [7 :0 ] offload_sync_id = 'h00;
197197 reg offload_sync_id_pending = 1'b0 ;
198198
199+ reg [2 :0 ] active_lane_count = 1 ;
200+ reg [SDI_FIFO_ADDRESS_WIDTH- 1 :0 ] sdi_input_level = 0 ;
201+ reg [SDI_FIFO_ADDRESS_WIDTH- 1 :0 ] sdi_input_level_next;
202+ wire [SDI_FIFO_ADDRESS_WIDTH- 1 :0 ] sdi_level_s;
203+ wire sdi_output_read;
204+ wire sdi_output_read_sync;
205+
206+
199207 generate if (MM_IF_TYPE == S_AXI) begin
200208
201209 // assign clock and reset
@@ -343,7 +351,7 @@ module axi_spi_engine #(
343351 8'h31 : up_rdata_ff <= offload_sync_id;
344352 8'h34 : up_rdata_ff <= cmd_fifo_room;
345353 8'h35 : up_rdata_ff <= sdo_fifo_room;
346- 8'h36 : up_rdata_ff <= (sdi_fifo_out_valid == 1 ) ? sdi_fifo_level + 1 : sdi_fifo_level; /* because of first-word-fall-through */
354+ 8'h36 : up_rdata_ff <= sdi_level_s;
347355 8'h3a : up_rdata_ff <= sdi_fifo_out_data[DATA_WIDTH- 1 :0 ];
348356 8'h3c : up_rdata_ff <= sdi_fifo_out_data[DATA_WIDTH- 1 :0 ]; /* PEEK register */
349357 8'h40 : up_rdata_ff <= {offload0_enable_reg};
@@ -471,21 +479,41 @@ module axi_spi_engine #(
471479 always @(posedge spi_clk) begin
472480 if (! spi_resetn) begin
473481 sdi_fifo_tkeep_int <= {(NUM_OF_SDIO* DATA_WIDTH/ 8 ){1'b1 }};
482+ active_lane_count <= 1 ;
474483 end else begin
475484 if (cmd_valid && cmd_ready && cmd_data[15 :8 ] == 8'h23 ) begin
476- for (i = 0 ; i < NUM_OF_SDIO; i = i + 1 ) begin
485+ for (i = 0 ; i < NUM_OF_SDIO; i = i + 1 ) begin
477486 sdi_fifo_tkeep_int[i* DATA_WIDTH/ 8 + :DATA_WIDTH/ 8 ] <= {DATA_WIDTH/ 8 {cmd_data[i]}};
478- end
487+ end
488+ active_lane_count <= (cmd_data[7 :0 ] == 8'h01 ) ? 1 : NUM_OF_SDIO;
479489 end
480490 end
481491 end
482492 assign sdi_fifo_tkeep = sdi_fifo_tkeep_int;
483493
494+ always @(* ) begin
495+ sdi_input_level_next = sdi_input_level;
496+ if (sdi_data_ready && sdi_data_valid) begin
497+ sdi_input_level_next = sdi_input_level_next + active_lane_count;
498+ end
499+ if (sdi_output_read_sync) begin
500+ sdi_input_level_next = sdi_input_level_next - 1 ;
501+ end
502+ end
503+
504+ always @(posedge spi_clk) begin
505+ if (! spi_resetn) begin
506+ sdi_input_level <= 0 ;
507+ end else begin
508+ sdi_input_level <= sdi_input_level_next;
509+ end
510+ end
511+
484512 util_axis_fifo_asym #(
485513 .ASYNC_CLK(ASYNC_SPI_CLK),
486514 .S_DATA_WIDTH(NUM_OF_SDIO * DATA_WIDTH),
487515 .M_DATA_WIDTH(DATA_WIDTH),
488- .ADDRESS_WIDTH(SDO_FIFO_ADDRESS_WIDTH ),
516+ .ADDRESS_WIDTH(SDI_FIFO_ADDRESS_WIDTH ),
489517 .M_AXIS_REGISTERED(0 ),
490518 .ALMOST_EMPTY_THRESHOLD(1 ),
491519 .ALMOST_FULL_THRESHOLD(1 ),
@@ -515,6 +543,7 @@ module axi_spi_engine #(
515543 .m_axis_almost_empty());
516544
517545 assign sdi_fifo_out_ready = up_rreq_s == 1'b1 && up_raddr_s == 8'h3a ;
546+ assign sdi_output_read = (sdi_fifo_out_ready || find_next_valid_fifo_value) && sdi_fifo_out_valid;
518547
519548 always @(posedge clk) begin
520549 if (rstn == 1'b0 ) begin
@@ -740,4 +769,24 @@ module axi_spi_engine #(
740769 .out_clk (clk),
741770 .out_bits ({up_cmd_fifo_almost_empty, up_sdi_fifo_almost_full, up_sdo_fifo_almost_empty}));
742771
772+ sync_event #(
773+ .NUM_OF_EVENTS (1 ),
774+ .ASYNC_CLK (ASYNC_SPI_CLK)
775+ ) i_sdi_output_read_sync (
776+ .in_clk (clk),
777+ .in_event (sdi_output_read),
778+ .out_clk (spi_clk),
779+ .out_event (sdi_output_read_sync));
780+
781+ sync_data #(
782+ .NUM_OF_BITS (SDI_FIFO_ADDRESS_WIDTH),
783+ .ASYNC_CLK (ASYNC_SPI_CLK)
784+ ) i_sdi_level_sync (
785+ .in_clk (spi_clk),
786+ .in_data (sdi_input_level),
787+ .out_clk (clk),
788+ .out_data (sdi_level_s)
789+ );
790+
791+
743792endmodule
0 commit comments