Skip to content

Commit 88ed47a

Browse files
committed
SPI Engine Execution: pipeline sdo alignment
Split path between sdo data input and sdo shift register, which includes a barrel shifter. Signed-off-by: Laez Barbosa <laez.barbosa@analog.com>
1 parent 3c56531 commit 88ed47a

File tree

4 files changed

+48
-17
lines changed

4 files changed

+48
-17
lines changed

docs/regmap/adi_regmap_spi_engine.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ ENDTITLE
99
REG
1010
0x00
1111
VERSION
12-
Version of the peripheral. Follows semantic versioning. Current version 1.03.00.
12+
Version of the peripheral. Follows semantic versioning. Current version 1.03.01.
1313
ENDREG
1414

1515
FIELD
@@ -25,7 +25,7 @@ RO
2525
ENDFIELD
2626

2727
FIELD
28-
[7:0] 0x00000000
28+
[7:0] 0x00000001
2929
VERSION_PATCH
3030
RO
3131
ENDFIELD

library/spi_engine/axi_spi_engine/axi_spi_engine.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ module axi_spi_engine #(
133133
input [7:0] offload_sync_data
134134
);
135135

136-
localparam PCORE_VERSION = 'h010300;
136+
localparam PCORE_VERSION = 'h010301;
137137
localparam S_AXI = 0;
138138
localparam UP_FIFO = 1;
139139

library/spi_engine/spi_engine_execution/spi_engine_execution.v

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ module spi_engine_execution #(
163163

164164
wire end_of_sdi_latch;
165165

166+
wire sample_sdo;
167+
166168
(* direct_enable = "yes" *) wire cs_gen;
167169

168170
spi_engine_execution_shiftreg #(
@@ -186,17 +188,21 @@ module spi_engine_execution #(
186188
.sdi_data_ready(sdi_data_ready),
187189
.sdo_enabled(sdo_enabled),
188190
.sdi_enabled(sdi_enabled),
189-
.current_instr(inst_d1),
191+
.current_cmd(cmd_d1),
190192
.sdo_idle_state(sdo_idle_state),
191193
.left_aligned(left_aligned),
192194
.word_length(word_length),
195+
.sample_sdo(sample_sdo),
196+
.sdo_io_ready(sdo_io_ready),
193197
.transfer_active(transfer_active),
194198
.trigger_tx(trigger_tx),
195199
.trigger_rx(trigger_rx),
196200
.first_bit(first_bit),
197201
.cs_activate(cs_activate),
198202
.end_of_sdi_latch(end_of_sdi_latch));
199203

204+
assign sample_sdo = sdo_data_valid && ((trigger_tx && last_bit) || (wait_for_io || exec_transfer_cmd));
205+
200206
assign cs_gen = inst_d1 == CMD_CHIPSELECT
201207
&& ((cs_sleep_counter_compare == 1'b1) || cs_sleep_early_exit)
202208
&& (cs_sleep_repeat == 1'b0)
@@ -380,7 +386,7 @@ module spi_engine_execution #(
380386
assign sync = cmd_d1[7:0];
381387

382388
assign io_ready1 = (sdi_data_valid == 1'b0 || sdi_data_ready == 1'b1) &&
383-
(sdo_enabled == 1'b0 || last_transfer == 1'b1 || sdo_data_valid == 1'b1);
389+
(sdo_enabled == 1'b0 || last_transfer == 1'b1 || sdo_io_ready == 1'b1);
384390
assign io_ready2 = (sdi_enabled == 1'b0 || sdi_data_ready == 1'b1) &&
385391
(sdo_enabled == 1'b0 || last_transfer == 1'b1 || sdo_data_valid == 1'b1);
386392

library/spi_engine/spi_engine_execution/spi_engine_execution_shiftreg.v

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ module spi_engine_execution_shiftreg #(
4848
input resetn,
4949

5050
// spi io
51-
input sdi,
51+
input [NUM_OF_SDI-1:0] sdi,
5252
output sdo_int,
5353
input echo_sclk,
5454

@@ -63,12 +63,14 @@ module spi_engine_execution_shiftreg #(
6363
// cfg and status
6464
input sdo_enabled,
6565
input sdi_enabled,
66-
input [2:0] current_instr,
66+
input [15:0] current_cmd,
6767
input sdo_idle_state,
6868
input [7:0] left_aligned,
6969
input [7:0] word_length,
7070

7171
// timing from main fsm
72+
input sample_sdo,
73+
output reg sdo_io_ready,
7274
input transfer_active,
7375
input trigger_tx,
7476
input trigger_rx,
@@ -79,17 +81,37 @@ module spi_engine_execution_shiftreg #(
7981

8082
reg [7:0] sdi_counter = 8'b0;
8183
reg [(DATA_WIDTH-1):0] data_sdo_shift = 'h0;
84+
reg [(DATA_WIDTH-1):0] aligned_sdo_data, sdo_data_d;
8285
wire last_sdi_bit;
8386
reg [SDI_DELAY+1:0] trigger_rx_d = {(SDI_DELAY+2){1'b0}};
8487
wire trigger_rx_s;
88+
wire [2:0] current_instr = current_cmd[14:12];
8589

8690
always @(posedge clk) begin
87-
if (resetn == 1'b0)
91+
if (resetn == 1'b0) begin
8892
sdo_data_ready <= 1'b0;
89-
else if (sdo_enabled == 1'b1 && first_bit == 1'b1 && trigger_tx == 1'b1 && transfer_active == 1'b1)
93+
end else if (sdo_toshiftreg) begin
9094
sdo_data_ready <= 1'b1;
91-
else if (sdo_data_valid == 1'b1)
95+
end else if (sdo_data_valid == 1'b1) begin
9296
sdo_data_ready <= 1'b0;
97+
end
98+
end
99+
100+
// pipelined shifter for sdo_data
101+
always @(posedge clk ) begin
102+
if (resetn == 1'b0) begin
103+
aligned_sdo_data <= 0;
104+
sdo_io_ready <= 1'b0;
105+
end else begin
106+
if (transfer_active == 1'b1 && trigger_tx == 1'b1) begin
107+
sdo_io_ready <= 1'b0;
108+
end
109+
if (sample_sdo) begin
110+
sdo_data_d <= sdo_data;
111+
sdo_io_ready <= 1'b1;
112+
end
113+
aligned_sdo_data <= sdo_data_d << left_aligned;
114+
end
93115
end
94116

95117
// Load the SDO parallel data into the SDO shift register. In case of a custom
@@ -98,13 +120,16 @@ module spi_engine_execution_shiftreg #(
98120
if (!sdo_enabled || (current_instr != CMD_TRANSFER)) begin
99121
data_sdo_shift <= {DATA_WIDTH{sdo_idle_state}};
100122
end else if (transfer_active == 1'b1 && trigger_tx == 1'b1) begin
101-
if (first_bit == 1'b1)
102-
data_sdo_shift <= sdo_data << left_aligned; //TODO: check if this could/should be pipelined
103-
else
104-
data_sdo_shift <= {data_sdo_shift[(DATA_WIDTH-2):0], 1'b0};
123+
if (first_bit == 1'b1) begin
124+
data_sdo_shift <= aligned_sdo_data;
125+
end else begin
126+
data_sdo_shift <= {data_sdo_shift[(DATA_WIDTH-2):0], 1'b0};
127+
end
105128
end
106129
end
107130
assign sdo_int = data_sdo_shift[DATA_WIDTH-1];
131+
assign sdo_toshiftreg = (transfer_active && trigger_tx && first_bit && sdo_enabled);
132+
108133

109134
// In case of an interface with high clock rate (SCLK > 50MHz), the latch of
110135
// the SDI line can be delayed with 1, 2 or 3 SPI core clock cycle.
@@ -203,7 +228,7 @@ module spi_engine_execution_shiftreg #(
203228
// sdi_data_valid is synchronous to SPI clock, so synchronize the
204229
// last_sdi_bit to SPI clock
205230

206-
reg [3:0] last_sdi_bit_m = 4'b0; //FIXME: bad synchronizer (cs_activate shouldn't be connected here), also why not just use sync_bits?
231+
reg [3:0] last_sdi_bit_m = 4'b0; //FIXME: why not just use sync_bits?
207232
always @(posedge clk) begin
208233
if (cs_activate) begin
209234
last_sdi_bit_m <= 4'b0;
@@ -228,8 +253,8 @@ module spi_engine_execution_shiftreg #(
228253
if (cs_activate) begin
229254
num_of_transfers <= 8'b0;
230255
end else begin
231-
if (cmd_d1[15:12] == 4'b0) begin
232-
num_of_transfers <= cmd_d1[7:0] + 1'b1; // cmd_d1 contains the NUM_OF_TRANSFERS - 1
256+
if (current_instr == CMD_TRANSFER) begin
257+
num_of_transfers <= current_cmd[7:0] + 1'b1; // current_cmd contains the NUM_OF_TRANSFERS - 1
233258
end
234259
end
235260
end

0 commit comments

Comments
 (0)