Skip to content

Commit 07bf239

Browse files
author
fcandelario
committed
Addition of Burst Mode for SPI byte transactions
1 parent 77d1e30 commit 07bf239

10 files changed

+995
-28
lines changed

src/SpiController.vhd

+26-5
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
-- Contributor(s):
77
-- Guy Eschemann (original Author of SPI.vhd)
88
-- Jacob Albers
9+
-- fernandoka
910
--
1011
-- Description:
1112
-- SPI Controller Verification Component
1213
--
1314
-- Revision History:
1415
-- Date Version Description
16+
-- 11/2024 2024.03 Addition of Burst Mode for SPI byte transactions
1517
-- 03/2024 2024.03 Updated SafeResize to use ModelID
1618
-- 06/2022 2022.06 Initial version
1719
--
@@ -92,6 +94,7 @@ architecture model of SpiController is
9294
signal OptSpiMode : SpiModeType := SPI_MODE;
9395
signal CPOL : std_logic := '0';
9496
signal CPHA : std_logic := '0';
97+
signal SpiBurstModeEna : boolean := false;
9598
-- SPI Clock Signals
9699
signal SpiClk : std_logic := '0';
97100
signal OptSclkPeriod : SpiClkType := SCLK_PERIOD;
@@ -209,6 +212,13 @@ begin
209212
to_string(TransRec.IntToModel),
210213
INFO);
211214

215+
when SpiOptionType'pos(SET_SPI_BURST_MODE) =>
216+
SpiBurstModeEna <= TransRec.BoolToModel;
217+
-- Log SPI mode change
218+
Log(ModelID, "Set SPI Burst Mode = " &
219+
to_string(TransRec.BoolToModel),
220+
INFO);
221+
212222
when others =>
213223
Alert(ModelID, OPT_ERR_MSG &
214224
to_string(SpiOptionType'val(TransRec.Options)),
@@ -235,6 +245,7 @@ begin
235245

236246
SpiTxHandler : process
237247
variable TxData : std_logic_vector(7 downto 0);
248+
variable BurstEna : boolean := false;
238249

239250
begin
240251
wait for 0 ns;
@@ -259,10 +270,13 @@ begin
259270

260271
-- SPI Mode: Propogate any SPI Mode changes
261272
SetSpiParams(OptSpiMode, CPOL, CPHA);
273+
BurstEna := SpiBurstModeEna;
262274

263275
-- SCLK: Wait for correct SpiClk phase before engaging CSEL
264-
wait until SpiClk = CPOL and SpiClk'event;
265-
CSEL <= '0';
276+
if CSEL='1' then
277+
wait until SpiClk = CPOL and SpiClk'event;
278+
CSEL <= '0';
279+
end if;
266280

267281
-- Transmit TxData byte bit by bit
268282
for BitIdx in 7 downto 0 loop
@@ -275,12 +289,19 @@ begin
275289
end if;
276290

277291
PICO <= TxData(BitIdx) when OptSpiMode = 1 or OptSpiMode = 3;
292+
293+
Log(ModelID, "Loop: SPI Controller TxData: " & to_string(TxData) &
294+
", PICO # " & to_string(TxData(BitIdx)) &
295+
", BitIdx # " & to_string(BitIdx),
296+
DEBUG);
278297
end loop;
279298

280-
wait until SpiClk /= CPOL and SpiClk'event;
281299
Increment(TransmitDoneCount);
282-
CSEL <= '1';
283-
PICO <= '0';
300+
if not BurstEna or ((TransmitDoneCount+1)=TransmitRequestCount) then
301+
wait until SpiClk /= CPOL and SpiClk'event;
302+
CSEL <= '1';
303+
PICO <= '0';
304+
end if;
284305

285306
end loop ControllerTxLoop;
286307
end process SpiTxHandler;

src/SpiPeripheral.vhd

+45-18
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
-- Contributor(s):
77
-- Guy Eschemann (original Author of SPI.vhd)
88
-- Jacob Albers
9+
-- fernandoka
910
--
1011
-- Description:
1112
-- SPI Peripheral Verification Component
1213
--
1314
-- Revision History:
1415
-- Date Version Description
16+
-- 11/2024 2024.03 Addition of Burst Mode for SPI byte transactions
1517
-- 04/2024 2024.04 Initial version
1618
--
1719
-- This file is part of OSVVM.
@@ -220,15 +222,19 @@ begin
220222
-- SPI Peripheral Receive Functionality
221223
----------------------------------------------------------------------------
222224
SpiRxHandler : process
223-
variable RxData : std_logic_vector(7 downto 0) := (others => '0');
224-
variable BitCnt : integer;
225+
variable RxData : std_logic_vector(7 downto 0) := (others => '0');
226+
variable BitCnt : integer;
227+
variable CsIsLow : boolean := false;
225228

226229
begin
227230
wait for 0 ns;
228231

229232
PeripheralRxLoop : loop
230233
BitCnt := 0;
231-
wait until falling_edge(CSEL);
234+
if not CsIsLow then
235+
wait until falling_edge(CSEL);
236+
CsIsLow := true;
237+
end if;
232238

233239
-- SPI Mode: Propogate SPI Mode changes
234240
SetSpiParams(OptSpiMode, CPOL, CPHA);
@@ -237,18 +243,23 @@ begin
237243
-- Clock in bits while CSEL low
238244
while CSEL = '0' and BitCnt <= RxData'length - 1 loop
239245
if OptSpiMode = 0 or OptSpiMode = 3 then
240-
wait until rising_edge(SCLK);
246+
wait until rising_edge(SCLK) or rising_edge(CSEL);
241247
else
242-
wait until falling_edge(SCLK);
248+
wait until falling_edge(SCLK) or rising_edge(CSEL);
243249
end if;
244250

245-
RxData := RxData(RxData'high - 1 downto RxData'low) &
246-
PICO;
247-
BitCnt := BitCnt + 1; -- Counter feels lazy but *shrug*
251+
CsIsLow := CSEL='0'; -- Update CsIsLow
252+
if CsIsLow then
253+
RxData := RxData(RxData'high - 1 downto RxData'low) &
254+
PICO;
255+
BitCnt := BitCnt + 1; -- Counter feels lazy but *shrug*
256+
end if;
248257
end loop;
249258

259+
if BitCnt=RxData'length then
250260
Push(ReceiveFifo, RxData);
251261
Increment(ReceiveCount);
262+
end if;
252263
end loop PeripheralRxLoop;
253264

254265
end process SpiRxHandler;
@@ -257,17 +268,24 @@ begin
257268
-- SPI Peripheral Transmit Functionality
258269
----------------------------------------------------------------------------
259270
SpiTxHandler : process
260-
variable TxData : std_logic_vector(7 downto 0);
261-
variable BitIdx : integer;
262-
271+
variable TxData : std_logic_vector(7 downto 0);
272+
variable BitIdx : integer;
273+
variable CsIsLow : boolean := false;
274+
variable TransmitIsPending : boolean := false;
263275
begin
264276
wait for 0 ns;
265277

266278
PeripheralTxLoop : loop
267-
wait until CSEL = '0';
268-
if not Empty(TransmitFifo) then
279+
if not CsIsLow then
280+
wait until falling_edge(CSEL);
281+
CsIsLow := true;
282+
end if;
283+
284+
285+
if not Empty(TransmitFifo) and not TransmitIsPending then
269286
TxData := Pop(TransmitFifo);
270-
else
287+
TransmitIsPending := true;
288+
elsif not TransmitIsPending then
271289
TxData := (others => '0');
272290
end if;
273291

@@ -277,14 +295,23 @@ begin
277295
POCI <= TxData(BitIdx) when OptSpiMode = 0 or OptSpiMode = 2;
278296

279297
if OptSpiMode = 0 or OptSpiMode = 3 then
280-
wait until falling_edge(SCLK);
298+
wait until falling_edge(SCLK) or rising_edge(CSEL);
281299
else
282-
wait until rising_edge(SCLK);
300+
wait until rising_edge(SCLK) or rising_edge(CSEL);
283301
end if;
284302

285-
POCI <= TxData(BitIdx) when OptSpiMode = 1 or OptSpiMode = 3;
286-
BitIdx := BitIdx - 1;
303+
CsIsLow := CSEL='0'; -- Update CsIsLow
304+
if CsIsLow then
305+
POCI <= TxData(BitIdx) when OptSpiMode = 1 or OptSpiMode = 3;
306+
BitIdx := BitIdx - 1;
307+
end if;
287308
end loop;
309+
310+
if BitIdx<0 then
311+
Increment(TransmitDoneCount);
312+
TransmitIsPending := false;
313+
end if;
314+
288315
end loop PeripheralTxLoop;
289316
end process SpiTxHandler;
290317
end architecture model;

src/SpiTbPkg.vhd

+22-1
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
-- Contributor(s):
77
-- Guy Eschemann (original Author)
88
-- Jacob Albers
9+
-- fernandoka
910
--
1011
-- Description:
1112
-- Constant and Transaction Support for OSVVM SPI VC
1213
--
1314
-- Revision History:
1415
-- Date Version Description
16+
-- 11/2024 2024.03 Addition of Burst Mode for SPI byte transactions
1517
-- 04/2024 2024.04 Initial version
1618
-- 06/2022 2022.06 Initial version
1719
--
@@ -79,7 +81,8 @@ package SpiTbPkg is
7981
----------------------------------------------------------------------------
8082
type SpiOptionType is (
8183
SET_SCLK_PERIOD,
82-
SET_SPI_MODE
84+
SET_SPI_MODE,
85+
SET_SPI_BURST_MODE
8386
);
8487

8588
----------------------------------------------------------------------------
@@ -116,6 +119,11 @@ package SpiTbPkg is
116119
signal CPHA : out std_logic
117120
);
118121

122+
procedure SetSpiBurstMode(
123+
signal TransactionRec : inout StreamRecType;
124+
constant SpiBurstModeEna : boolean
125+
);
126+
119127
----------------------------------------------------------------------------
120128
-- SPI Parameter Helpers
121129
----------------------------------------------------------------------------
@@ -164,6 +172,19 @@ package body SpiTbPkg is
164172
CPHA <= GetCPHA(OptSpiMode);
165173
end procedure SetSpiParams;
166174

175+
----------------------------------------------------------------------------
176+
-- SetSpiBurstMode: Sets SPI device byte transaction characteristics
177+
----------------------------------------------------------------------------
178+
procedure SetSpiBurstMode(
179+
signal TransactionRec : inout StreamRecType;
180+
constant SpiBurstModeEna : boolean
181+
) is
182+
begin
183+
SetModelOptions(TransactionRec,
184+
SpiOptionType'pos(SET_SPI_BURST_MODE),
185+
SpiBurstModeEna);
186+
end procedure SetSpiBurstMode;
187+
167188
----------------------------------------------------------------------------
168189
-- GetCPOL: Helper function for SetSpiMode returns CPOL value
169190
----------------------------------------------------------------------------

testbench/TbSpi.vhd

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,15 @@ begin
8181
------------------------------------------------------------
8282
-- Create Clock
8383
------------------------------------------------------------
84-
Osvvm.ClockResetPkg.CreateClock(
84+
Osvvm.TbUtilPkg.CreateClock(
8585
Clk => Clk,
8686
Period => tperiod_Clk
8787
);
8888

8989
------------------------------------------------------------
9090
-- Create Reset
9191
------------------------------------------------------------
92-
Osvvm.ClockResetPkg.CreateReset(
92+
Osvvm.TbUtilPkg.CreateReset(
9393
Reset => n_Reset,
9494
ResetActive => '0',
9595
Clk => Clk,

0 commit comments

Comments
 (0)