Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 61 additions & 2 deletions docs/library/spi_engine/instruction-format.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Configuration Write Instruction
== == == == == == = = = = = = = = = =

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

.. list-table::
Expand Down Expand Up @@ -174,7 +174,66 @@ is the minimum, needed by the internal logic.
- Time
- The amount of time to wait.

.. _spi_engine configutarion-registers:
Loop Start Instruction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

== == == == == == = = = = = = = = = =
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
== == == == == == = = = = = = = = = =
1 0 0 1 r r r r n n n n n n n n
== == == == == == = = = = = = = = = =

The Loop Start instruction indicates the start of a loop region, that will be
executed a specified number of times. Together with the Loop End Instruction,
this implements hardware instruction looping. All instructions between the loop
start and loop end will be executed the specified number of times automatically
by the SPI Engine. **Looping is only supported with instruction offloading,
The Loop Start and Loop End instructions will be treated as NOPs otherwise.**


.. list-table::
:widths: 10 15 75
:header-rows: 1

* - Bits
- Name
- Description
* - r
- Reserved
- Must always be 0.
* - n
- Loop count
- The number of times the loop will be repeated.

Loop End Instruction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

== == == == == == = = = = = = = = = =
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
== == == == == == = = = = = = = = = =
1 0 0 0 r r r r r r r r r r r r
== == == == == == = = = = = = = = = =

The Loop End instruction indicates the end of a loop region. Together with the
Loop Start Instruction, this implements hardware instruction looping. All
instructions between the loop start and loop end will be executed automatically
by the SPI Engine, for the number of repeats specified on the Loop Start
instruction. **Looping is only supported with instruction offloading, The Loop
Start and Loop End instructions will be treated as NOPs otherwise.**


.. list-table::
:widths: 10 15 75
:header-rows: 1

* - Bits
- Name
- Description
* - r
- Reserved
- Must always be 0.

.. _spi_engine configuration-registers:

Configuration Registers
--------------------------------------------------------------------------------
Expand Down
12 changes: 6 additions & 6 deletions library/spi_engine/spi_engine_execution/spi_engine_execution.v
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ module spi_engine_execution #(
output reg three_wire
);

localparam CMD_TRANSFER = 2'b00;
localparam CMD_CHIPSELECT = 2'b01;
localparam CMD_WRITE = 2'b10;
localparam CMD_MISC = 2'b11;
localparam CMD_TRANSFER = 4'b0000;
localparam CMD_CHIPSELECT = 4'b0001;
localparam CMD_WRITE = 4'b0010;
localparam CMD_MISC = 4'b0011;

localparam MISC_SYNC = 1'b0;
localparam MISC_SLEEP = 1'b1;
Expand Down Expand Up @@ -141,8 +141,8 @@ module spi_engine_execution #(

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

wire [1:0] inst = cmd[13:12];
wire [1:0] inst_d1 = cmd_d1[13:12];
wire [3:0] inst = cmd[15:12];
wire [3:0] inst_d1 = cmd_d1[15:12];

wire exec_cmd = cmd_ready && cmd_valid;
wire exec_transfer_cmd = exec_cmd && inst == CMD_TRANSFER;
Expand Down
31 changes: 30 additions & 1 deletion library/spi_engine/spi_engine_offload/spi_engine_offload.v
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ module spi_engine_offload #(
wire spi_enable;
wire trigger_posedge;

wire [7:0] cmd_repeat_count_s;
wire cmd_repeat_start_s;
wire cmd_repeat_end_s;
wire repeat_jump_s;
reg repeat_loop = 1'b0;
reg [7:0] repeat_count;
reg [CMD_MEM_ADDRESS_WIDTH-1:0] repeat_start_addr;

assign cmd_valid = spi_active;
assign sdo_data_valid = spi_active;

Expand Down Expand Up @@ -237,7 +245,6 @@ module spi_engine_offload #(
assign ctrl_enabled = spi_enable | spi_active;
end endgenerate

assign spi_cmd_rd_addr_next = spi_cmd_rd_addr + 1;

wire trigger_s;
sync_bits #(
Expand Down Expand Up @@ -314,4 +321,26 @@ module spi_engine_offload #(
sdo_mem[ctrl_sdo_wr_addr] <= ctrl_sdo_wr_data;
end

// Hardware Loop implementation
assign cmd_repeat_count_s = cmd[7:0];
assign cmd_repeat_start_s = (cmd[15:12] == 4'b1000);
assign cmd_repeat_end_s = (cmd[15:12] == 4'b1001);
assign repeat_jump_s = cmd_valid && cmd_ready && cmd_repeat_end_s && repeat_loop;
assign spi_cmd_rd_addr_next = (repeat_jump_s) ? repeat_start_addr : spi_cmd_rd_addr + 1;
always @(posedge spi_clk ) begin
if (!spi_resetn) begin
repeat_loop <= 1'b0;
repeat_count <= 0;
end else begin
if (cmd_valid && cmd_ready && cmd_repeat_start_s) begin
repeat_loop <= 1'b1;
repeat_count <= cmd_repeat_count_s;
repeat_start_addr <= spi_cmd_rd_addr_next;
end else if (repeat_jump_s) begin
repeat_count <= repeat_count-1;
repeat_loop <= (repeat_count == 1) ? 1'b0 : 1'b1;
end
end
end

endmodule