Skip to content

Commit

Permalink
SPI Engine Execution: pipeline sdo alignment
Browse files Browse the repository at this point in the history
Split path between sdo data input and sdo shift register, which includes a barrel shifter.

Signed-off-by: Laez Barbosa <[email protected]>
  • Loading branch information
LBFFilho committed Oct 29, 2024
1 parent 5d5e13d commit 47a4cf0
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 16 deletions.
4 changes: 2 additions & 2 deletions docs/regmap/adi_regmap_spi_engine.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ENDTITLE
REG
0x00
VERSION
Version of the peripheral. Follows semantic versioning. Current version 1.03.00.
Version of the peripheral. Follows semantic versioning. Current version 1.03.01.
ENDREG

FIELD
Expand All @@ -25,7 +25,7 @@ RO
ENDFIELD

FIELD
[7:0] 0x00000000
[7:0] 0x00000001
VERSION_PATCH
RO
ENDFIELD
Expand Down
2 changes: 1 addition & 1 deletion library/spi_engine/axi_spi_engine/axi_spi_engine.v
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ module axi_spi_engine #(
input [7:0] offload_sync_data
);

localparam PCORE_VERSION = 'h010300;
localparam PCORE_VERSION = 'h010301;
localparam S_AXI = 0;
localparam UP_FIFO = 1;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ module spi_engine_execution #(

wire end_of_sdi_latch;

wire sample_sdo;

(* direct_enable = "yes" *) wire cs_gen;

spi_engine_execution_shiftreg #(
Expand All @@ -186,10 +188,11 @@ module spi_engine_execution #(
.sdi_data_ready(sdi_data_ready),
.sdo_enabled(sdo_enabled),
.sdi_enabled(sdi_enabled),
.current_instr(inst_d1),
.current_cmd(cmd_d1),
.sdo_idle_state(sdo_idle_state),
.left_aligned(left_aligned),
.word_length(word_length),
.sample_sdo(sample_sdo),
.transfer_active(transfer_active),
.trigger_tx(trigger_tx),
.trigger_rx(trigger_rx),
Expand All @@ -198,6 +201,8 @@ module spi_engine_execution #(
.end_of_sdi_latch(end_of_sdi_latch)
);

assign sample_sdo = (trigger_tx && last_bit) || exec_transfer_cmd;

assign cs_gen = inst_d1 == CMD_CHIPSELECT
&& ((cs_sleep_counter_compare == 1'b1) || cs_sleep_early_exit)
&& (cs_sleep_repeat == 1'b0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ module spi_engine_execution_shiftreg #(
input resetn,

// spi io
input sdi,
input [NUM_OF_SDI-1:0] sdi,
output sdo_int,
input echo_sclk,

Expand All @@ -63,12 +63,13 @@ module spi_engine_execution_shiftreg #(
// cfg and status
input sdo_enabled,
input sdi_enabled,
input [2:0] current_instr,
input [15:0] current_cmd,
input sdo_idle_state,
input [7:0] left_aligned,
input [7:0] word_length,

// timing from main fsm
input sample_sdo,
input transfer_active,
input trigger_tx,
input trigger_rx,
Expand All @@ -79,17 +80,32 @@ module spi_engine_execution_shiftreg #(

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

always @(posedge clk) begin
if (resetn == 1'b0)
if (resetn == 1'b0) begin
sdo_data_ready <= 1'b0;
else if (sdo_enabled == 1'b1 && first_bit == 1'b1 && trigger_tx == 1'b1 && transfer_active == 1'b1)
end else if (sdo_enabled == 1'b1 && first_bit == 1'b1 && trigger_tx == 1'b1 && transfer_active == 1'b1) begin
sdo_data_ready <= 1'b1;
else if (sdo_data_valid == 1'b1)
end else if (sdo_data_valid == 1'b1) begin
sdo_data_ready <= 1'b0;
end
end

// pipelined shifter for sdo_data
always @(posedge clk ) begin
if (resetn == 1'b0) begin
aligned_sdo_data <= 0;
end else begin
if (sample_sdo) begin
sdo_data_d <= sdo_data;
end
aligned_sdo_data <= sdo_data_d << left_aligned;
end
end

// Load the SDO parallel data into the SDO shift register. In case of a custom
Expand All @@ -98,10 +114,11 @@ module spi_engine_execution_shiftreg #(
if (!sdo_enabled || (current_instr != CMD_TRANSFER)) begin
data_sdo_shift <= {DATA_WIDTH{sdo_idle_state}};
end else if (transfer_active == 1'b1 && trigger_tx == 1'b1) begin
if (first_bit == 1'b1)
data_sdo_shift <= sdo_data << left_aligned; //TODO: check if this could/should be pipelined
else
data_sdo_shift <= {data_sdo_shift[(DATA_WIDTH-2):0], 1'b0};
if (first_bit == 1'b1) begin
data_sdo_shift <= aligned_sdo_data;
end else begin
data_sdo_shift <= {data_sdo_shift[(DATA_WIDTH-2):0], 1'b0};
end
end
end
assign sdo_int = data_sdo_shift[DATA_WIDTH-1];
Expand Down Expand Up @@ -203,7 +220,7 @@ module spi_engine_execution_shiftreg #(
// sdi_data_valid is synchronous to SPI clock, so synchronize the
// last_sdi_bit to SPI clock

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?
reg [3:0] last_sdi_bit_m = 4'b0; //FIXME: why not just use sync_bits?
always @(posedge clk) begin
if (cs_activate) begin
last_sdi_bit_m <= 4'b0;
Expand All @@ -228,8 +245,8 @@ module spi_engine_execution_shiftreg #(
if (cs_activate) begin
num_of_transfers <= 8'b0;
end else begin
if (cmd_d1[15:12] == 4'b0) begin
num_of_transfers <= cmd_d1[7:0] + 1'b1; // cmd_d1 contains the NUM_OF_TRANSFERS - 1
if (current_instr == CMD_TRANSFER) begin
num_of_transfers <= current_cmd[7:0] + 1'b1; // current_cmd contains the NUM_OF_TRANSFERS - 1
end
end
end
Expand Down

0 comments on commit 47a4cf0

Please sign in to comment.