Skip to content

Commit 2eba037

Browse files
committed
SPI Engine: add offload looping
Add two instructions for hardware looping: Loop Start and Loop End. This implementations makes it so both instructions only work on Offload mode, being ignored for direct SPI. Signed-off-by: Laez Barbosa <laez.barbosa@analog.com>
1 parent aa51783 commit 2eba037

File tree

3 files changed

+97
-9
lines changed

3 files changed

+97
-9
lines changed

docs/library/spi_engine/instruction-format.rst

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Configuration Write Instruction
9898
== == == == == == = = = = = = = = = =
9999

100100
The configuration writes instruction updates a
101-
:ref:`spi_engine configutarion-registers`
101+
:ref:`spi_engine configuration-registers`
102102
of the SPI Engine execution module with a new value.
103103

104104
.. list-table::
@@ -174,7 +174,66 @@ is the minimum, needed by the internal logic.
174174
- Time
175175
- The amount of time to wait.
176176

177-
.. _spi_engine configutarion-registers:
177+
Loop Start Instruction
178+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
179+
180+
== == == == == == = = = = = = = = = =
181+
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
182+
== == == == == == = = = = = = = = = =
183+
1 0 0 1 r r r r n n n n n n n n
184+
== == == == == == = = = = = = = = = =
185+
186+
The Loop Start instruction indicates the start of a loop region, that will be
187+
executed a specified number of times. Together with the Loop End Instruction,
188+
this implements hardware instruction looping. All instructions between the loop
189+
start and loop end will be executed the specified number of times automatically
190+
by the SPI Engine. **Looping is only supported with instruction offloading,
191+
The Loop Start and Loop End instructions will be treated as NOPs otherwise.**
192+
193+
194+
.. list-table::
195+
:widths: 10 15 75
196+
:header-rows: 1
197+
198+
* - Bits
199+
- Name
200+
- Description
201+
* - r
202+
- Reserved
203+
- Must always be 0.
204+
* - n
205+
- Loop count
206+
- The number of times the loop will be repeated.
207+
208+
Loop End Instruction
209+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
210+
211+
== == == == == == = = = = = = = = = =
212+
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
213+
== == == == == == = = = = = = = = = =
214+
1 0 0 0 r r r r r r r r r r r r
215+
== == == == == == = = = = = = = = = =
216+
217+
The Loop End instruction indicates the end of a loop region. Together with the
218+
Loop Start Instruction, this implements hardware instruction looping. All
219+
instructions between the loop start and loop end will be executed automatically
220+
by the SPI Engine, for the number of repeats specified on the Loop Start
221+
instruction. **Looping is only supported with instruction offloading, The Loop
222+
Start and Loop End instructions will be treated as NOPs otherwise.**
223+
224+
225+
.. list-table::
226+
:widths: 10 15 75
227+
:header-rows: 1
228+
229+
* - Bits
230+
- Name
231+
- Description
232+
* - r
233+
- Reserved
234+
- Must always be 0.
235+
236+
.. _spi_engine configuration-registers:
178237

179238
Configuration Registers
180239
--------------------------------------------------------------------------------

library/spi_engine/spi_engine_execution/spi_engine_execution.v

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ module spi_engine_execution #(
7676
output reg three_wire
7777
);
7878

79-
localparam CMD_TRANSFER = 2'b00;
80-
localparam CMD_CHIPSELECT = 2'b01;
81-
localparam CMD_WRITE = 2'b10;
82-
localparam CMD_MISC = 2'b11;
79+
localparam CMD_TRANSFER = 4'b0000;
80+
localparam CMD_CHIPSELECT = 4'b0001;
81+
localparam CMD_WRITE = 4'b0010;
82+
localparam CMD_MISC = 4'b0011;
8383

8484
localparam MISC_SYNC = 1'b0;
8585
localparam MISC_SLEEP = 1'b1;
@@ -141,8 +141,8 @@ module spi_engine_execution #(
141141

142142
reg [SDI_DELAY+1:0] trigger_rx_d = {(SDI_DELAY+2){1'b0}};
143143

144-
wire [1:0] inst = cmd[13:12];
145-
wire [1:0] inst_d1 = cmd_d1[13:12];
144+
wire [3:0] inst = cmd[15:12];
145+
wire [3:0] inst_d1 = cmd_d1[15:12];
146146

147147
wire exec_cmd = cmd_ready && cmd_valid;
148148
wire exec_transfer_cmd = exec_cmd && inst == CMD_TRANSFER;

library/spi_engine/spi_engine_offload/spi_engine_offload.v

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ module spi_engine_offload #(
103103
wire spi_enable;
104104
wire trigger_posedge;
105105

106+
wire [7:0] cmd_repeat_count_s;
107+
wire cmd_repeat_start_s;
108+
wire cmd_repeat_end_s;
109+
wire repeat_jump_s;
110+
reg repeat_loop = 1'b0;
111+
reg [7:0] repeat_count;
112+
reg [CMD_MEM_ADDRESS_WIDTH-1:0] repeat_start_addr;
113+
106114
assign cmd_valid = spi_active;
107115
assign sdo_data_valid = spi_active;
108116

@@ -237,7 +245,6 @@ module spi_engine_offload #(
237245
assign ctrl_enabled = spi_enable | spi_active;
238246
end endgenerate
239247

240-
assign spi_cmd_rd_addr_next = spi_cmd_rd_addr + 1;
241248

242249
wire trigger_s;
243250
sync_bits #(
@@ -314,4 +321,26 @@ module spi_engine_offload #(
314321
sdo_mem[ctrl_sdo_wr_addr] <= ctrl_sdo_wr_data;
315322
end
316323

324+
// Hardware Loop implementation
325+
assign cmd_repeat_count_s = cmd[7:0];
326+
assign cmd_repeat_start_s = (cmd[15:12] == 4'b1000);
327+
assign cmd_repeat_end_s = (cmd[15:12] == 4'b1001);
328+
assign repeat_jump_s = cmd_valid && cmd_ready && cmd_repeat_end_s && repeat_loop;
329+
assign spi_cmd_rd_addr_next = (repeat_jump_s) ? repeat_start_addr : spi_cmd_rd_addr + 1;
330+
always @(posedge spi_clk ) begin
331+
if (!spi_resetn) begin
332+
repeat_loop <= 1'b0;
333+
repeat_count <= 0;
334+
end else begin
335+
if (cmd_valid && cmd_ready && cmd_repeat_start_s) begin
336+
repeat_loop <= 1'b1;
337+
repeat_count <= cmd_repeat_count_s;
338+
repeat_start_addr <= spi_cmd_rd_addr_next;
339+
end else if (repeat_jump_s) begin
340+
repeat_count <= repeat_count-1;
341+
repeat_loop <= (repeat_count == 1) ? 1'b0 : 1'b1;
342+
end
343+
end
344+
end
345+
317346
endmodule

0 commit comments

Comments
 (0)