Skip to content

Commit 2c57b24

Browse files
committed
library/spi_engine: Update for SDO extension
* Extend SDO support to 8 (symmetrical with SDI support); * Update SDI to use asymmetrical FIFO; * Insert symmetrical FIFO for the SDO; * Insert SPI lane mask configuration instruction to reg 2'b11; * Insert offload active interface for interconnect and execution; * Remove register 8'h3b from spi engine regmap. Prefetching on offload work iff all lanes are active. Signed-off-by: Carlos Souza <carlos.souza@analog.com>
1 parent 7edc334 commit 2c57b24

14 files changed

+344
-110
lines changed

library/spi_engine/axi_spi_engine/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ XILINX_DEPS += ../../spi_engine/interfaces/spi_engine_offload_ctrl.xml
2020
XILINX_DEPS += ../../spi_engine/interfaces/spi_engine_offload_ctrl_rtl.xml
2121

2222
XILINX_LIB_DEPS += util_axis_fifo
23+
XILINX_LIB_DEPS += util_axis_fifo_asym
2324
XILINX_LIB_DEPS += util_cdc
2425

2526
XILINX_INTERFACE_DEPS += spi_engine/interfaces

library/spi_engine/axi_spi_engine/axi_spi_engine.v

Lines changed: 78 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,11 @@ module axi_spi_engine #(
106106

107107
input sdo_data_ready,
108108
output sdo_data_valid,
109-
output [(DATA_WIDTH-1):0] sdo_data,
109+
output [(DATA_WIDTH)-1:0] sdo_data,
110110

111111
output sdi_data_ready,
112112
input sdi_data_valid,
113-
input [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_data,
113+
input [(NUM_OF_SDI * DATA_WIDTH)-1:0] sdi_data,
114114

115115
output sync_ready,
116116
input sync_valid,
@@ -122,7 +122,7 @@ module axi_spi_engine #(
122122
output [15:0] offload0_cmd_wr_data,
123123

124124
output offload0_sdo_wr_en,
125-
output [(DATA_WIDTH-1):0] offload0_sdo_wr_data,
125+
output [(DATA_WIDTH)-1:0] offload0_sdo_wr_data,
126126

127127
output offload0_mem_reset,
128128
output offload0_enable,
@@ -133,7 +133,7 @@ module axi_spi_engine #(
133133
input [7:0] offload_sync_data
134134
);
135135

136-
localparam PCORE_VERSION = 'h010501;
136+
localparam PCORE_VERSION = 'h010600;
137137
localparam S_AXI = 0;
138138
localparam UP_FIFO = 1;
139139

@@ -152,16 +152,15 @@ module axi_spi_engine #(
152152
wire sdo_fifo_almost_empty;
153153
wire up_sdo_fifo_almost_empty;
154154

155-
wire [(DATA_WIDTH-1):0] sdo_fifo_in_data;
155+
wire [DATA_WIDTH-1:0] sdo_fifo_in_data;
156156
wire sdo_fifo_in_ready;
157157
wire sdo_fifo_in_valid;
158158

159-
wire sdi_fifo_out_data_msb_s;
160-
wire [SDI_FIFO_ADDRESS_WIDTH-1:0] sdi_fifo_level;
159+
wire [31:0] sdi_fifo_level;
161160
wire sdi_fifo_almost_full;
162161
wire up_sdi_fifo_almost_full;
163162

164-
wire [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_fifo_out_data;
163+
wire [DATA_WIDTH-1:0] sdi_fifo_out_data;
165164
wire sdi_fifo_out_ready;
166165
wire sdi_fifo_out_valid;
167166

@@ -325,15 +324,6 @@ module axi_spi_engine #(
325324
end
326325
end
327326

328-
generate
329-
if (NUM_OF_SDI > 1) begin
330-
// Only the first two SDI data can be recovered through AXI regmap
331-
assign sdi_fifo_out_data_msb_s = sdi_fifo_out_data[DATA_WIDTH+:DATA_WIDTH];
332-
end else begin
333-
assign sdi_fifo_out_data_msb_s = sdi_fifo_out_data;
334-
end
335-
endgenerate
336-
337327
reg [7:0] offload_sdo_mem_address_width = OFFLOAD0_SDO_MEM_ADDRESS_WIDTH;
338328
reg [7:0] offload_cmd_mem_address_width = OFFLOAD0_CMD_MEM_ADDRESS_WIDTH;
339329
reg [7:0] sdi_fifo_address_width = SDI_FIFO_ADDRESS_WIDTH;
@@ -356,10 +346,9 @@ module axi_spi_engine #(
356346
8'h31: up_rdata_ff <= offload_sync_id;
357347
8'h34: up_rdata_ff <= cmd_fifo_room;
358348
8'h35: up_rdata_ff <= sdo_fifo_room;
359-
8'h36: up_rdata_ff <= (sdi_fifo_out_valid == 1) ? sdi_fifo_level + 1 : sdi_fifo_level; /* beacuse of first-word-fall-through */
349+
8'h36: up_rdata_ff <= (sdi_fifo_out_valid == 1) ? sdi_fifo_level + 1 : sdi_fifo_level; /* because of first-word-fall-through */
360350
8'h3a: up_rdata_ff <= sdi_fifo_out_data[DATA_WIDTH-1:0];
361-
8'h3b: up_rdata_ff <= sdi_fifo_out_data_msb_s; /* store SDI's 32 bits MSB, if exists */
362-
8'h3c: up_rdata_ff <= sdi_fifo_out_data; /* PEEK register */
351+
8'h3c: up_rdata_ff <= sdi_fifo_out_data[DATA_WIDTH-1:0]; /* PEEK register */
363352
8'h40: up_rdata_ff <= {offload0_enable_reg};
364353
8'h41: up_rdata_ff <= {offload0_enabled_s};
365354
8'h80: up_rdata_ff <= CFG_INFO_0;
@@ -421,7 +410,9 @@ module axi_spi_engine #(
421410
.ASYNC_CLK(ASYNC_SPI_CLK),
422411
.M_AXIS_REGISTERED(0),
423412
.ALMOST_EMPTY_THRESHOLD(1),
424-
.ALMOST_FULL_THRESHOLD(1)
413+
.ALMOST_FULL_THRESHOLD(1),
414+
.TLAST_EN(0),
415+
.TKEEP_EN(0)
425416
) i_cmd_fifo (
426417
.s_axis_aclk(clk),
427418
.s_axis_aresetn(up_sw_resetn),
@@ -430,22 +421,25 @@ module axi_spi_engine #(
430421
.s_axis_data(cmd_fifo_in_data),
431422
.s_axis_room(cmd_fifo_room),
432423
.s_axis_tlast(1'b0),
424+
.s_axis_tkeep(),
433425
.s_axis_full(),
434426
.s_axis_almost_full(),
427+
435428
.m_axis_aclk(spi_clk),
436429
.m_axis_aresetn(spi_resetn),
437430
.m_axis_ready(cmd_ready),
438431
.m_axis_valid(cmd_valid),
439432
.m_axis_data(cmd_data),
440433
.m_axis_tlast(),
434+
.m_axis_tkeep(),
435+
.m_axis_level(),
441436
.m_axis_empty(),
442-
.m_axis_almost_empty(cmd_fifo_almost_empty),
443-
.m_axis_level());
437+
.m_axis_almost_empty(cmd_fifo_almost_empty));
444438

445439
assign sdo_fifo_in_valid = up_wreq_s == 1'b1 && up_waddr_s == 8'h39;
446-
assign sdo_fifo_in_data = up_wdata_s[(DATA_WIDTH-1):0];
440+
assign sdo_fifo_in_data = up_wdata_s[DATA_WIDTH-1:0];
447441

448-
util_axis_fifo #(
442+
util_axis_fifo #(
449443
.DATA_WIDTH(DATA_WIDTH),
450444
.ASYNC_CLK(ASYNC_SPI_CLK),
451445
.ADDRESS_WIDTH(SDO_FIFO_ADDRESS_WIDTH),
@@ -460,6 +454,7 @@ module axi_spi_engine #(
460454
.s_axis_data(sdo_fifo_in_data),
461455
.s_axis_room(sdo_fifo_room),
462456
.s_axis_tlast(1'b0),
457+
.s_axis_tkeep(),
463458
.s_axis_full(),
464459
.s_axis_almost_full(),
465460
.m_axis_aclk(spi_clk),
@@ -468,35 +463,43 @@ module axi_spi_engine #(
468463
.m_axis_valid(sdo_data_valid),
469464
.m_axis_data(sdo_data),
470465
.m_axis_tlast(),
466+
.m_axis_tkeep(),
471467
.m_axis_level(),
472468
.m_axis_empty(),
473469
.m_axis_almost_empty(sdo_fifo_almost_empty));
474470

475471
assign sdi_fifo_out_ready = up_rreq_s == 1'b1 && up_raddr_s == 8'h3a;
476472

477-
util_axis_fifo #(
478-
.DATA_WIDTH(NUM_OF_SDI * DATA_WIDTH),
473+
util_axis_fifo_asym #(
479474
.ASYNC_CLK(ASYNC_SPI_CLK),
480-
.ADDRESS_WIDTH(SDI_FIFO_ADDRESS_WIDTH),
475+
.S_DATA_WIDTH(NUM_OF_SDI * DATA_WIDTH),
476+
.M_DATA_WIDTH(DATA_WIDTH),
477+
.ADDRESS_WIDTH(SDO_FIFO_ADDRESS_WIDTH),
481478
.M_AXIS_REGISTERED(0),
482479
.ALMOST_EMPTY_THRESHOLD(1),
483-
.ALMOST_FULL_THRESHOLD(31)
484-
) i_sdi_fifo (
480+
.ALMOST_FULL_THRESHOLD(1),
481+
.TLAST_EN(0),
482+
.TKEEP_EN(0),
483+
.REDUCED_FIFO(0)
484+
) i_sdi_fifo(
485485
.s_axis_aclk(spi_clk),
486486
.s_axis_aresetn(spi_resetn),
487487
.s_axis_ready(sdi_data_ready),
488488
.s_axis_valid(sdi_data_valid),
489489
.s_axis_data(sdi_data),
490490
.s_axis_room(),
491491
.s_axis_tlast(),
492+
.s_axis_tkeep(),
492493
.s_axis_full(),
493494
.s_axis_almost_full(sdi_fifo_almost_full),
495+
494496
.m_axis_aclk(clk),
495497
.m_axis_aresetn(up_sw_resetn),
496498
.m_axis_ready(sdi_fifo_out_ready),
497499
.m_axis_valid(sdi_fifo_out_valid),
498500
.m_axis_data(sdi_fifo_out_data),
499501
.m_axis_tlast(),
502+
.m_axis_tkeep(),
500503
.m_axis_level(sdi_fifo_level),
501504
.m_axis_empty(),
502505
.m_axis_almost_empty());
@@ -508,22 +511,31 @@ module axi_spi_engine #(
508511
.DATA_WIDTH(8),
509512
.ASYNC_CLK(ASYNC_SPI_CLK),
510513
.ADDRESS_WIDTH(SYNC_FIFO_ADDRESS_WIDTH),
511-
.M_AXIS_REGISTERED(0)
514+
.M_AXIS_REGISTERED(0),
515+
.TLAST_EN(0),
516+
.TKEEP_EN(0)
512517
) i_sync_fifo (
513518
.s_axis_aclk(spi_clk),
514519
.s_axis_aresetn(spi_resetn),
515520
.s_axis_ready(sync_ready),
516521
.s_axis_valid(sync_valid),
517522
.s_axis_data(sync_data),
518523
.s_axis_room(),
524+
.s_axis_tlast(),
525+
.s_axis_tkeep(),
519526
.s_axis_full(),
527+
.s_axis_almost_full(),
528+
520529
.m_axis_aclk(clk),
521530
.m_axis_aresetn(up_sw_resetn),
522531
.m_axis_ready(1'b1),
523532
.m_axis_valid(sync_fifo_valid),
524533
.m_axis_data(sync_fifo_data),
534+
.m_axis_tlast(),
535+
.m_axis_tkeep(),
525536
.m_axis_level(),
526-
.m_axis_empty());
537+
.m_axis_empty(),
538+
.m_axis_almost_empty());
527539

528540
// synchronization FIFO for the offload command interface
529541
wire up_offload0_cmd_wr_en_s;
@@ -533,50 +545,68 @@ module axi_spi_engine #(
533545
.DATA_WIDTH(16),
534546
.ASYNC_CLK(ASYNC_SPI_CLK),
535547
.ADDRESS_WIDTH(SYNC_FIFO_ADDRESS_WIDTH),
536-
.M_AXIS_REGISTERED(0)
548+
.M_AXIS_REGISTERED(0),
549+
.TLAST_EN(0),
550+
.TKEEP_EN(0)
537551
) i_offload_cmd_fifo (
538552
.s_axis_aclk(clk),
539553
.s_axis_aresetn(up_sw_resetn),
540554
.s_axis_ready(),
541555
.s_axis_valid(up_offload0_cmd_wr_en_s),
542556
.s_axis_data(up_offload0_cmd_wr_data_s),
543557
.s_axis_room(),
558+
.s_axis_tlast(),
559+
.s_axis_tkeep(),
544560
.s_axis_full(),
561+
.s_axis_almost_full(),
562+
545563
.m_axis_aclk(spi_clk),
546564
.m_axis_aresetn(spi_resetn),
547565
.m_axis_ready(1'b1),
548566
.m_axis_valid(offload0_cmd_wr_en),
549567
.m_axis_data(offload0_cmd_wr_data),
568+
.m_axis_tlast(),
569+
.m_axis_tkeep(),
550570
.m_axis_level(),
551-
.m_axis_empty());
571+
.m_axis_empty(),
572+
.m_axis_almost_empty());
552573

553574
assign up_offload0_cmd_wr_en_s = up_wreq_s == 1'b1 && up_waddr_s == 8'h44;
554575
assign up_offload0_cmd_wr_data_s = up_wdata_s[15:0];
555576

556577
// synchronization FIFO for the offload SDO interface
557578
wire up_offload0_sdo_wr_en_s;
558-
wire [DATA_WIDTH-1:0] up_offload0_sdo_wr_data_s;
579+
wire [(DATA_WIDTH-1):0] up_offload0_sdo_wr_data_s;
559580

560581
util_axis_fifo #(
561582
.DATA_WIDTH(DATA_WIDTH),
562583
.ASYNC_CLK(ASYNC_SPI_CLK),
563584
.ADDRESS_WIDTH(SYNC_FIFO_ADDRESS_WIDTH),
564-
.M_AXIS_REGISTERED(0)
585+
.M_AXIS_REGISTERED(0),
586+
.TLAST_EN(0),
587+
.TKEEP_EN(0)
565588
) i_offload_sdo_fifo (
566589
.s_axis_aclk(clk),
567590
.s_axis_aresetn(up_sw_resetn),
568591
.s_axis_ready(),
569592
.s_axis_valid(up_offload0_sdo_wr_en_s),
570593
.s_axis_data(up_offload0_sdo_wr_data_s),
571594
.s_axis_room(),
595+
.s_axis_tlast(),
596+
.s_axis_tkeep(),
572597
.s_axis_full(),
598+
.s_axis_almost_full(),
599+
573600
.m_axis_aclk(spi_clk),
574601
.m_axis_aresetn(spi_resetn),
575602
.m_axis_ready(1'b1),
576603
.m_axis_valid(offload0_sdo_wr_en),
577604
.m_axis_data(offload0_sdo_wr_data),
605+
.m_axis_tlast(),
606+
.m_axis_tkeep(),
578607
.m_axis_level(),
579-
.m_axis_empty());
608+
.m_axis_empty(),
609+
.m_axis_almost_empty());
580610

581611
assign up_offload0_sdo_wr_en_s = up_wreq_s == 1'b1 && up_waddr_s == 8'h45;
582612
assign up_offload0_sdo_wr_data_s = up_wdata_s[DATA_WIDTH-1:0];
@@ -586,22 +616,31 @@ module axi_spi_engine #(
586616
.DATA_WIDTH(8),
587617
.ASYNC_CLK(ASYNC_SPI_CLK),
588618
.ADDRESS_WIDTH(SYNC_FIFO_ADDRESS_WIDTH),
589-
.M_AXIS_REGISTERED(0)
619+
.M_AXIS_REGISTERED(0),
620+
.TLAST_EN(0),
621+
.TKEEP_EN(0)
590622
) i_offload_sync_fifo (
591623
.s_axis_aclk(spi_clk),
592624
.s_axis_aresetn(spi_resetn),
593625
.s_axis_ready(offload_sync_ready),
594626
.s_axis_valid(offload_sync_valid),
595627
.s_axis_data(offload_sync_data),
596628
.s_axis_room(),
629+
.s_axis_tlast(),
630+
.s_axis_tkeep(),
597631
.s_axis_full(),
632+
.s_axis_almost_full(),
633+
598634
.m_axis_aclk(clk),
599635
.m_axis_aresetn(up_sw_resetn),
600636
.m_axis_ready(1'b1),
601637
.m_axis_valid(offload_sync_fifo_valid),
602638
.m_axis_data(offload_sync_fifo_data),
639+
.m_axis_tlast(),
640+
.m_axis_tkeep(),
603641
.m_axis_level(),
604-
.m_axis_empty());
642+
.m_axis_empty(),
643+
.m_axis_almost_empty());
605644

606645
end else begin /* ASYNC_SPI_CLK == 0 */
607646

library/spi_engine/axi_spi_engine/axi_spi_engine_ip.tcl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ adi_ip_ttcl axi_spi_engine "axi_spi_engine_constr.ttcl"
2424
adi_ip_add_core_dependencies [list \
2525
analog.com:$VIVADO_IP_LIBRARY:util_axis_fifo:1.0 \
2626
analog.com:$VIVADO_IP_LIBRARY:util_cdc:1.0 \
27+
analog.com:$VIVADO_IP_LIBRARY:util_axis_fifo_asym:1.0 \
2728
]
2829

2930
set_property company_url {https://wiki.analog.com/resources/fpga/peripherals/spi_engine/axi} [ipx::current_core]

library/spi_engine/scripts/spi_engine.tcl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ proc spi_engine_create {{name "spi_engine"} {data_width 32} {async_spi_clk 1} {n
7171
ad_connect $offload/trigger trigger
7272

7373
ad_connect $execution/spi m_spi
74+
ad_connect $interconnect/m_offload_active_ctrl $execution/s_offload_active_ctrl
7475

7576
if {$sdo_streaming == 1} {
7677
ad_connect $offload/s_axis_sdo s_axis_sample

library/spi_engine/spi_engine_execution/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LIBRARY_NAME := spi_engine_execution
88

99
GENERIC_DEPS += spi_engine_execution.v
1010
GENERIC_DEPS += spi_engine_execution_shiftreg.v
11+
GENERIC_DEPS += spi_engine_execution_shiftreg_data_assemble.v
1112

1213
XILINX_DEPS += spi_engine_execution_constr.ttcl
1314
XILINX_DEPS += spi_engine_execution_ip.tcl
@@ -16,6 +17,8 @@ XILINX_DEPS += ../../spi_engine/interfaces/spi_engine.xml
1617
XILINX_DEPS += ../../spi_engine/interfaces/spi_engine_ctrl.xml
1718
XILINX_DEPS += ../../spi_engine/interfaces/spi_engine_ctrl_rtl.xml
1819
XILINX_DEPS += ../../spi_engine/interfaces/spi_engine_rtl.xml
20+
XILINX_DEPS += ../../spi_engine/interfaces/spi_engine_interconnect_ctrl.xml
21+
XILINX_DEPS += ../../spi_engine/interfaces/spi_engine_interconnect_ctrl_rtl.xml
1922

2023
XILINX_INTERFACE_DEPS += spi_engine/interfaces
2124

0 commit comments

Comments
 (0)