Skip to content

Commit 24bd474

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 234d589 commit 24bd474

14 files changed

+345
-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: 79 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,44 @@ 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+
.FIFO_LIMITED(0),
484+
.ADDRESS_WIDTH_PERSPECTIVE(0)
485+
) i_sdi_fifo(
485486
.s_axis_aclk(spi_clk),
486487
.s_axis_aresetn(spi_resetn),
487488
.s_axis_ready(sdi_data_ready),
488489
.s_axis_valid(sdi_data_valid),
489490
.s_axis_data(sdi_data),
490491
.s_axis_room(),
491492
.s_axis_tlast(),
493+
.s_axis_tkeep(),
492494
.s_axis_full(),
493495
.s_axis_almost_full(sdi_fifo_almost_full),
496+
494497
.m_axis_aclk(clk),
495498
.m_axis_aresetn(up_sw_resetn),
496499
.m_axis_ready(sdi_fifo_out_ready),
497500
.m_axis_valid(sdi_fifo_out_valid),
498501
.m_axis_data(sdi_fifo_out_data),
499502
.m_axis_tlast(),
503+
.m_axis_tkeep(),
500504
.m_axis_level(sdi_fifo_level),
501505
.m_axis_empty(),
502506
.m_axis_almost_empty());
@@ -508,22 +512,31 @@ module axi_spi_engine #(
508512
.DATA_WIDTH(8),
509513
.ASYNC_CLK(ASYNC_SPI_CLK),
510514
.ADDRESS_WIDTH(SYNC_FIFO_ADDRESS_WIDTH),
511-
.M_AXIS_REGISTERED(0)
515+
.M_AXIS_REGISTERED(0),
516+
.TLAST_EN(0),
517+
.TKEEP_EN(0)
512518
) i_sync_fifo (
513519
.s_axis_aclk(spi_clk),
514520
.s_axis_aresetn(spi_resetn),
515521
.s_axis_ready(sync_ready),
516522
.s_axis_valid(sync_valid),
517523
.s_axis_data(sync_data),
518524
.s_axis_room(),
525+
.s_axis_tlast(),
526+
.s_axis_tkeep(),
519527
.s_axis_full(),
528+
.s_axis_almost_full(),
529+
520530
.m_axis_aclk(clk),
521531
.m_axis_aresetn(up_sw_resetn),
522532
.m_axis_ready(1'b1),
523533
.m_axis_valid(sync_fifo_valid),
524534
.m_axis_data(sync_fifo_data),
535+
.m_axis_tlast(),
536+
.m_axis_tkeep(),
525537
.m_axis_level(),
526-
.m_axis_empty());
538+
.m_axis_empty(),
539+
.m_axis_almost_empty());
527540

528541
// synchronization FIFO for the offload command interface
529542
wire up_offload0_cmd_wr_en_s;
@@ -533,50 +546,68 @@ module axi_spi_engine #(
533546
.DATA_WIDTH(16),
534547
.ASYNC_CLK(ASYNC_SPI_CLK),
535548
.ADDRESS_WIDTH(SYNC_FIFO_ADDRESS_WIDTH),
536-
.M_AXIS_REGISTERED(0)
549+
.M_AXIS_REGISTERED(0),
550+
.TLAST_EN(0),
551+
.TKEEP_EN(0)
537552
) i_offload_cmd_fifo (
538553
.s_axis_aclk(clk),
539554
.s_axis_aresetn(up_sw_resetn),
540555
.s_axis_ready(),
541556
.s_axis_valid(up_offload0_cmd_wr_en_s),
542557
.s_axis_data(up_offload0_cmd_wr_data_s),
543558
.s_axis_room(),
559+
.s_axis_tlast(),
560+
.s_axis_tkeep(),
544561
.s_axis_full(),
562+
.s_axis_almost_full(),
563+
545564
.m_axis_aclk(spi_clk),
546565
.m_axis_aresetn(spi_resetn),
547566
.m_axis_ready(1'b1),
548567
.m_axis_valid(offload0_cmd_wr_en),
549568
.m_axis_data(offload0_cmd_wr_data),
569+
.m_axis_tlast(),
570+
.m_axis_tkeep(),
550571
.m_axis_level(),
551-
.m_axis_empty());
572+
.m_axis_empty(),
573+
.m_axis_almost_empty());
552574

553575
assign up_offload0_cmd_wr_en_s = up_wreq_s == 1'b1 && up_waddr_s == 8'h44;
554576
assign up_offload0_cmd_wr_data_s = up_wdata_s[15:0];
555577

556578
// synchronization FIFO for the offload SDO interface
557579
wire up_offload0_sdo_wr_en_s;
558-
wire [DATA_WIDTH-1:0] up_offload0_sdo_wr_data_s;
580+
wire [(DATA_WIDTH-1):0] up_offload0_sdo_wr_data_s;
559581

560582
util_axis_fifo #(
561583
.DATA_WIDTH(DATA_WIDTH),
562584
.ASYNC_CLK(ASYNC_SPI_CLK),
563585
.ADDRESS_WIDTH(SYNC_FIFO_ADDRESS_WIDTH),
564-
.M_AXIS_REGISTERED(0)
586+
.M_AXIS_REGISTERED(0),
587+
.TLAST_EN(0),
588+
.TKEEP_EN(0)
565589
) i_offload_sdo_fifo (
566590
.s_axis_aclk(clk),
567591
.s_axis_aresetn(up_sw_resetn),
568592
.s_axis_ready(),
569593
.s_axis_valid(up_offload0_sdo_wr_en_s),
570594
.s_axis_data(up_offload0_sdo_wr_data_s),
571595
.s_axis_room(),
596+
.s_axis_tlast(),
597+
.s_axis_tkeep(),
572598
.s_axis_full(),
599+
.s_axis_almost_full(),
600+
573601
.m_axis_aclk(spi_clk),
574602
.m_axis_aresetn(spi_resetn),
575603
.m_axis_ready(1'b1),
576604
.m_axis_valid(offload0_sdo_wr_en),
577605
.m_axis_data(offload0_sdo_wr_data),
606+
.m_axis_tlast(),
607+
.m_axis_tkeep(),
578608
.m_axis_level(),
579-
.m_axis_empty());
609+
.m_axis_empty(),
610+
.m_axis_almost_empty());
580611

581612
assign up_offload0_sdo_wr_en_s = up_wreq_s == 1'b1 && up_waddr_s == 8'h45;
582613
assign up_offload0_sdo_wr_data_s = up_wdata_s[DATA_WIDTH-1:0];
@@ -586,22 +617,31 @@ module axi_spi_engine #(
586617
.DATA_WIDTH(8),
587618
.ASYNC_CLK(ASYNC_SPI_CLK),
588619
.ADDRESS_WIDTH(SYNC_FIFO_ADDRESS_WIDTH),
589-
.M_AXIS_REGISTERED(0)
620+
.M_AXIS_REGISTERED(0),
621+
.TLAST_EN(0),
622+
.TKEEP_EN(0)
590623
) i_offload_sync_fifo (
591624
.s_axis_aclk(spi_clk),
592625
.s_axis_aresetn(spi_resetn),
593626
.s_axis_ready(offload_sync_ready),
594627
.s_axis_valid(offload_sync_valid),
595628
.s_axis_data(offload_sync_data),
596629
.s_axis_room(),
630+
.s_axis_tlast(),
631+
.s_axis_tkeep(),
597632
.s_axis_full(),
633+
.s_axis_almost_full(),
634+
598635
.m_axis_aclk(clk),
599636
.m_axis_aresetn(up_sw_resetn),
600637
.m_axis_ready(1'b1),
601638
.m_axis_valid(offload_sync_fifo_valid),
602639
.m_axis_data(offload_sync_fifo_data),
640+
.m_axis_tlast(),
641+
.m_axis_tkeep(),
603642
.m_axis_level(),
604-
.m_axis_empty());
643+
.m_axis_empty(),
644+
.m_axis_almost_empty());
605645

606646
end else begin /* ASYNC_SPI_CLK == 0 */
607647

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)