Skip to content

Commit 93b45b2

Browse files
committed
spi: Refactor alignment processes for serial data output and chip select handling
1 parent 1770df6 commit 93b45b2

2 files changed

Lines changed: 61 additions & 58 deletions

File tree

ip/communication/spi/spi_tx.vhd

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -149,29 +149,56 @@ begin
149149
end if;
150150
end process;
151151

152+
-- NOTE: Xilinx doesn't recognise generic functions that have the same definitions like rising_edge/falling_edge, thus, it creates latches instead of FFs
153+
-- So we've to manually state for which SPI mode at what edge has to be sampled.
154+
-- With Intel the previous solution worked perfectly
152155
serial_data_out_and_chip_select_alignment: block
153156
signal spi_chip_select_n_assertion: spi_chip_select_n'subtype;
154157
signal spi_chip_select_n_deassertion: spi_chip_select_n'subtype;
155158
begin
156-
serial_data_out_alignment: process (all)
157-
begin
158-
if tx_active_edge(spi_clk_in, SPI_CLK_POLARITY, SPI_CLK_PHASE) then
159-
serial_data_out <= serial_data_out_internal;
160-
end if;
161-
end process;
162-
163-
chip_select_n_alignment: process (all)
164-
begin
165-
if active_edge_chip_select_n_assertion(spi_clk_in, SPI_CLK_POLARITY) then
166-
spi_chip_select_n_assertion <= spi_chip_select_n_internal;
167-
end if;
168-
169-
if active_edge_chip_select_n_deassertion(spi_clk_in, SPI_CLK_POLARITY) then
170-
spi_chip_select_n_deassertion <= spi_chip_select_n_internal;
171-
end if;
159+
serial_data_out_alignment: case SPI_CLK_POLARITY & SPI_CLK_PHASE generate
160+
when "00" | "11" =>
161+
alignment: process (spi_clk_in)
162+
begin
163+
if falling_edge(spi_clk_in) then
164+
serial_data_out <= serial_data_out_internal;
165+
end if;
166+
end process;
167+
when "01" =>
168+
postpone: process (spi_clk_in)
169+
begin
170+
if rising_edge(spi_clk_in) then
171+
serial_data_out <= serial_data_out_internal;
172+
end if;
173+
end process;
174+
when "10" =>
175+
pass_through: serial_data_out <= serial_data_out_internal;
176+
end generate;
177+
178+
chip_select_n_driver: if CONTROLLER_AND_NOT_PERIPHERAL generate
179+
spi_chip_select_n_alignment: case SPI_CLK_POLARITY generate
180+
when '0' =>
181+
alignment: process (spi_clk_in)
182+
begin
183+
if falling_edge(spi_clk_in) then
184+
spi_chip_select_n_assertion <= spi_chip_select_n_internal;
185+
elsif rising_edge(spi_clk_in) then
186+
spi_chip_select_n_deassertion <= spi_chip_select_n_internal;
187+
end if;
188+
end process;
189+
when '1' =>
190+
alignment: process (spi_clk_in)
191+
begin
192+
pass_through: spi_chip_select_n_assertion <= spi_chip_select_n_internal;
193+
194+
if falling_edge(spi_clk_in) then
195+
spi_chip_select_n_deassertion <= spi_chip_select_n_internal;
196+
end if;
197+
end process;
198+
end generate;
172199

173200
spi_chip_select_n <= spi_chip_select_n_assertion and spi_chip_select_n_deassertion;
174-
end process;
201+
end generate;
175202
end block;
176203

177204
-- SPI clock driver implementation with vendor-specific considerations

ip/communication/spi/tb_spi_interface.vhd

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -109,49 +109,25 @@ begin
109109
signal spi_chip_select_n_assertion: spi_chip_select_n'subtype;
110110
signal spi_chip_select_n_deassertion: spi_chip_select_n'subtype;
111111
begin
112-
serial_data_out_alignment: case SPI_CLK_POLARITY & SPI_CLK_PHASE generate
113-
when "00" | "11" =>
114-
alignment: process (spi_clk_in)
115-
begin
116-
if falling_edge(spi_clk_in) then
117-
serial_data_out_expected <= serial_data_out_internal;
118-
end if;
119-
end process;
120-
when "01" =>
121-
postpone: process (spi_clk_in)
122-
begin
123-
if rising_edge(spi_clk_in) then
124-
serial_data_out_expected <= serial_data_out_internal;
125-
end if;
126-
end process;
127-
when "10" =>
128-
pass_through: serial_data_out_expected <= serial_data_out_internal;
129-
end generate;
130-
131-
chip_select_n_driver: if CONTROLLER_AND_NOT_PERIPHERAL generate
132-
spi_chip_select_n_alignment: case SPI_CLK_POLARITY generate
133-
when '0' =>
134-
alignment: process (spi_clk_in)
135-
begin
136-
if falling_edge(spi_clk_in) then
137-
spi_chip_select_n_assertion <= spi_chip_select_n_internal;
138-
elsif rising_edge(spi_clk_in) then
139-
spi_chip_select_n_deassertion <= spi_chip_select_n_internal;
140-
end if;
141-
end process;
142-
when '1' =>
143-
alignment: process (spi_clk_in)
144-
begin
145-
pass_through: spi_chip_select_n_assertion <= spi_chip_select_n_internal;
146-
147-
if falling_edge(spi_clk_in) then
148-
spi_chip_select_n_deassertion <= spi_chip_select_n_internal;
149-
end if;
150-
end process;
151-
end generate;
112+
serial_data_out_alignment: process (all)
113+
begin
114+
if tx_active_edge(spi_clk_in, SPI_CLK_POLARITY, SPI_CLK_PHASE) then
115+
serial_data_out_expected <= serial_data_out_internal;
116+
end if;
117+
end process;
118+
119+
chip_select_n_alignment: process (all)
120+
begin
121+
if active_edge_chip_select_n_assertion(spi_clk_in, SPI_CLK_POLARITY) then
122+
spi_chip_select_n_assertion <= spi_chip_select_n_internal;
123+
end if;
124+
125+
if active_edge_chip_select_n_deassertion(spi_clk_in, SPI_CLK_POLARITY) then
126+
spi_chip_select_n_deassertion <= spi_chip_select_n_internal;
127+
end if;
152128

153129
spi_chip_select_n_expected <= spi_chip_select_n_assertion and spi_chip_select_n_deassertion;
154-
end generate;
130+
end process;
155131
end block;
156132
------------------------------------------------------------
157133

0 commit comments

Comments
 (0)