Download as pdf or txt
Download as pdf or txt
You are on page 1of 16

Vamsi Krishna B MAVEN SILICON VLSI

DESIGN INTERNSHIP

SPI DESIGN PROJECT

INTRODUCTION

This project report presents a


comprehensive account of the design and implementation of the SPI
(Serial Peripheral Interface) Master Core in Verilog. The primary
objective of this project was to acquire practical experience in designing
and implementing digital circuits using Verilog, as well as to deepen our
understanding of the SPI protocol and its various applications.

The report begins with an overview of the project's objectives and scope,
followed by a discussion on SPI protocol, highlighting its features,
advantages, and disadvantages compared to other serial communication
protocols. The core section details the design and implementation of the
SPI Master Core in Verilog, including an in-depth explanation of the
Verilog code, the IO ports, registers, and external connections utilized in
the design.

The testing process used to verify the functionality of the SPI Master
Core and the results obtained are thoroughly discussed. The report
concludes with a summary of the project's key findings and suggests
potential future work to enhance the design and implementation of the
SPI Master Core. This project has provided valuable experience in digital
circuit design using Verilog and a profound understanding of the SPI
protocol and its applications. We hope this report will be a valuable
resource for anyone interested in learning more about the SPI protocol
and its implementation in Verilog.

1|Page
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

DESIGN AND IMPLEMENTATION


The
design and implementation of the SPI Master Core in Verilog involved
several steps, including definingthe IO ports, registers, and external
connections used in the design, as well as writing the Verilog code
toimplement the SPI protocol.
The Overall Implementation contains following subfiles.
SPI_DEFINES.V
The Verilog code “spi_defines.v” defines various parameters and
constants for configuring an SPI (SerialPeripheral Interface) module.
Here is a summary of the key aspects covered in this code:
Clock Generator Divider Length: The code provides options for setting
the SPI divider length, whichdetermines the clock frequency for SPI
communication. You can choose between different divider lengths,such
as 8, 16, 24, or 32.
Max Number Of Bits That Can Be Sent/Received At Once: It defines the
maximum number of bits thatcan be sent or received in a single SPI
transfer. Options are available for different character lengths,including 8,
16, 24, 32, 64, or 128 bits.
Number of Devices Select Signals: The code defines the number of
devices select signals (SS) that can beused in the SPI interface. You can
choose from options like 8, 16, 24, or 32 device select signals.
Register Offsets: The code provides register offsets for various SPI
registers, such as RX (Receive), TX(Transmit), Control (CTRL), Divide
(for clock division settings), and SS (Device Select).No. of Bits in CTRL
Register: It specifies the number of bits in the Control (CTRL) register,
which is set to14 bits.
Control Register Bit Position: The code defines the bit positions within
the Control (CTRL) register forvarious control signals and settings, such
as ASS (Auto Slave Select), IE (Interrupt Enable), LSB (LeastSignificant
Bit First), TX/RX edge selection, GO (Start Transfer), and character
length configuration.

SPI_CLGEN.V

2|Page
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

The Verilog module “spi_clgen” appears to be a clock generator


module for an SPI (Serial Peripheral Interface) interface. It generates the
serial clock (SCLK) and provides control signals for clock polarity
(CPOL) based on the defined SPI configuration parameters. Here's a
brief conclusion of this code:
The module takes several input signals, including the system clock
“wb_clk_in”, a reset signal “wb_rst”,“tip” for transfer-in-progress
indication, “go” for initiating transfers, “last_clk” for tracking the last clock
cycle, “divider” for configuring the clock divider, and several output
signals, including the generated serial clock “sclk_out”, “cpol_0”, and
“cpol_1” for clock polarity.
The code uses a counter “cnt” to count half periods of the clock. It is
updated during each clock cycle and is reset in case of a reset signal or
when the transfer is in progress (“tip” is asserted). The counter is used to
determine when to toggle the SCLK signal.
The generation of the serial clock “sclk_out” is synchronized with the
system clock and depends on the counter value, the divider, and the
“last_clk” signal. It ensures that the SCLK transitions are generated at
the appropriate times.
The module also detects the positive and negative edges of the
generated clock and sets the “cpol_0” and“cpol_1” signals based on the
SPI mode's clock polarity requirements. These signals are adjusted
based on the SCLK signal's edges and the divider value.

SPI_CLGEN_TB.V
The Verilog module “spi_clgen_tb” is a testbench for the
“spi_clgen” module, which is a clock generator for an SPI (Serial
Peripheral Interface) interface. This testbench defines the test
environment and simulates the behaviour of the clock generator. Here's
a brief conclusion of this testbench code:
Signal Declarations: The testbench defines various signals to simulate
the clock generator module, including “wb_clk_in”, “wb_rst” for reset,
“go” for transfer initiation, “tip” for transfer-in-progress indication,
“last_clk” for tracking the last clock cycle, and “divider” for configuring the
clock divider. It also declares “sclk_out”, “cpol_0”, and “cpol_1” as wires
to observe the output signals from the clock generator.

3|Page
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

Instantiation of DUT: The testbench instantiates the Device Under Test


(DUT), which is the “spi_clgen” module, and connects the input and
output signals accordingly.
Clock Generation: The testbench generates a clock signal “wb_clk_in”
using an “always” block. It toggles the clock every 5-time units,
simulating the system clock.
Signal Initialization: In the “initial block”, the testbench initializes various
signals to simulate different conditions. It initially sets the reset signal,
“wb_rst”, high and then lowers it after a delay. It sets the “divider”, “tip”,
and “go” signals to specific values to simulate a transfer initiation with a
certain divider value. It also sets “tip” and “last_clk” to observe the
behaviour of the clock generator under these conditions.

SPI_SHIFT_REG.V
The Verilog module “spi_shift_reg” appears to be an
implementation of a shift register for an SPI (Serial Peripheral Interface)
interface. It handles the parallel-to-serial (TX) and serial-to-parallel (RX)
data shifting based on clock edges and data configuration. Here's a brief
conclusion of this code:
Input and Output Signals: The module has various input signals such as
clock edges (“rx_negedge” and “tx_negedge”), system clock “wb_clk_in”,
reset signal “wb_rst”, “go” for transfer initiation, “miso” for input data,
“lsb” for least significant bit first, “sclk” for the serial clock, “cpol_0”, and
“cpol_1” for clock polarity configuration. It also takes inputs for byte
selection, latch control, character length “len”, and parallel input data
“p_in”. The module provides outputs for parallel output data “p_out”,
transfer-in-progress indication “tip”, “mosi” for serial output data, and a
“last” signal.
Internal Registers: The module maintains several internal registers, such
as “char_count” for character bit counting, “master_data” as the shift
register, “tx_bit_pos” for tracking the next bit position in the TX shift
register, and “rx_bit_pos” for tracking the next bit position in the RX shift
register.
Clock Edge Calculation: The module determines the edge of the serial
clock for both TX and RX using the input signals “rx_negedge” and
“tx_negedge”. This information is used to control data shifting.

4|Page
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

Character Bit Counter: It keeps track of character bits and counts them
based on the character length and clock polarity. It also ensures that the
last character bit is correctly identified.
Transfer-in-Progress Indicator (TIP): It calculates the transfer-in-
progress indicator based on the state of the go, tip, and last signals,
ensuring that it is set when a transfer is in progress and cleared
appropriately.
Serial Data Output (MOSI): It calculates the serial data output (“mosi”) by
shifting bits from the “master_data” shift register based on the “tx_clk”
and the “tx_bit_pos”.
Parallel Output Data (p_out): The module provides the parallel output
data as “p_out”, which is directly sourced from the “master_data” shift
register.
Latching of Data: The module implements logic for latching data from the
parallel input “p_in”. Depending on the byte selection and latch control, it
correctly loads data into the shift register, considering the SPI mode's
character length.
Receiving Bits from the Serial Line: The module handles the reception of
bits from the serial line (“miso”) and shifts them into the “master_data”
shift register when the “rx_clk” is enabled.

SPI_SHIFT_REG_TB.V
The Verilog module “spi_shift_reg_tb” is a testbench designed to
test the functionality of the “spi_shift_reg” module, which appears to be
an implementation of a shift register for an SPI (Serial Peripheral
Interface) interface.
Here's a brief conclusion of this testbench code:
Signal Declarations: The testbench defines numerous signals to control
and monitor the behavior of the DUT (“spi_shift_reg”), including clock
edges (“rx_negedge” and “tx_negedge”), system clock “wb_clk_in”, reset
signal “wb_rst”, transfer initiation signal “go”, “miso” for input data, “lsb”
for least significant bit first, “sclk” for the serial clock, and “cpol_0” and
“cpol_1” for clock polarity configuration. It also defines signals for byte

5|Page
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

selection, latch control, character length “len”, and parallel input data
“p_in”. Output signals include “p_out”, “tip”, “mosi”, and “last”.
Parameters: The testbench defines parameters such as “T” for the clock
period and “divider_value” to configure the divider length, which
influences the serial clock (“sclk”) generation.
DUT Instantiation: The testbench instantiates the Device Under Test
(DUT), which is the “spi_shift_reg” module, and connects the input and
output signals accordingly.
Clock Generation: The testbench generates the system clock wb_clk_in
and the serial clock “sclk”. It toggles these clocks based on the
configured time intervals and the “divider_value”. The clock generation
ensures that the DUT operates in a timed environment.
Tasks for Edge Configuration: The testbench defines tasks (“t1” and “t2”)
to set the “rx_negedge” and “tx_negedge” signals, allowing for the
testing of different clock edge configurations.
Initialization: The “initialize” task is used to set various input signals to
their initial values before testing. It sets parameters such as character
length, data values, and control signals to specific initial states.
Simulation Scenario: The testbench defines a specific simulation
scenario where it configures input signals, initiates a reset, sets various
parameters, and monitors the behaviour of the DUT. It models data
transmission (“miso”), clock polarity configuration, and other aspects of
the SPI interface. The scenario includes delays to simulate data transfer
and clock behaviour.

SPI_TOP.V
The Verilog module “spi_top” serves as the central control unit for
an SPI (Serial Peripheral Interface) Master, managing clock generation,
data transfer, and control for communication with multiple slave devices.
Here's a brief conclusion regarding the primary elements and
functionality of the “spi_top” module:
Signal Declarations: The “spi_top” module includes various input and
output signals to interface with the surrounding environment and control

6|Page
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

the SPI functionality. These signals include clock and reset signals
(“wb_clk_in” and “wb_rst_in”), address and data signals (“wb_adr_in”
and “wb_dat_in”), chip select and write enable signals (“wb_sel_in” and
“wb_we_in”), control signals for bus transactions (“wb_stb_in” and
“wb_cyc_in”), and acknowledgments and interrupts signals
(“wb_ack_out” and “wb_int_o”). Additionally, it manages signals for slave
select (“ss_pad_o”), serial clock (“sclk_out”), and data lines (“mosi” and
“miso”).
Divider and Control Registers: The module defines and manages
registers for divider, control, and slave select. It includes the “divider”
register for controlling the clock frequency, the “ctrl” register for
configuring various aspects of the SPI interface, and the “ss” register for
selecting one of up to 32 slave devices.
Clock Generation: It instantiates a clock generator module (“spi_clgen”)
to generate the system clock (“wb_clk_in”) and serial clock (“sclk_out”).
The generated clocks are essential for synchronized data transfer.
Data Shifting: Data transfer is managed by the “spi_shift_reg” module,
which handles data shifting, both for transmission and reception. The
module configures data based on the selected slave and ensures data is
sent and received correctly.
Register Access and Control: The module allows for read and write
access to the configured registers, enabling configuration of various
parameters, including character length and clock polarity. It also
manages acknowledgment and interrupt generation based on specific
conditions.
Slave Device Selection: The “ss_pad_o” signal selects a specific slave
device from a group of up to 32 devices based on various conditions.

SPI_SLAVE.V
The Verilog module “spi_slave” appears to represent a simple SPI
(Serial Peripheral Interface) slave device, which receives and transmits
data as part of an SPI communication protocol. Here's a brief conclusion
regarding this module's functionality:
Signal Declarations: The module has input signals, including “sclk” for
the serial clock and “mosi” for the master's output data. It also receives

7|Page
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

the “ss_pad_o” signal, which is a combination of slave select signals for


selecting this particular slave device. The “miso” output signal repress
ents the data transmitted by this slave.
Data Registers: The module includes two data registers, “temp1” and
“temp2”, each 128 bits wide, which store data being received from and
transmitted to the SPI master. These registers are shifted in
synchronization with the serial clock “sclk”.
Control Signals: The module uses two control signals, “rx_slave” and
“tx_slave”, to determine whether the slave is in receive or transmit mode.
The “rx_slave” signal is set when the slave is receiving data, and
“tx_slave” is set when it's transmitting data.
Data Shifting: The module shifts the received and transmitted data into
the “temp1” and “temp2” registers, respectively, based on the rising and
falling edges of the serial clock “sclk”. It does this by checking the state
of “rx_slave” and “tx_slave”. Data is shifted into the registers one bit at a
time, with the most significant bit (MSB) being the first.
MISO Generation: The module generates the MISO (Master In Slave
Out) signal, which represents the data that this slave sends back to the
master. It does this by extracting the MSB from “temp1” when in receive
mode and from “temp2” when in transmit mode. These MSB values are
combined with a logical OR operation and assigned to the “miso” output
signal.

WISHBONE_MASTER.V
The Verilog module “wishbone_master” appears to be an
implementation of a Wishbone master interface.
It is designed to initiate Wishbone bus cycles, which include single read
and write operations. Below is a concise summary of this module's
functionality:
Input and Output Signals: The module takes several input signals,
including the system clock (“clk_in”),reset (“rst_in”), acknowledge

8|Page
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

("ack_in"), data input ("dat_in"), and control signals ("adr_o",


"cyc_o",“stb_o”, “we_o”, “dat_o”, and “sel_o”). These signals are used to
control and monitor the Wishbone bus operation.
Internal Signals: Internal signals like “adr_temp”, “sel_temp”, “dat_temp”,
“we_temp”, “cyc_temp” and “stb_temp” are declared and used for
managing the Wishbone bus cycles and storing temporary values during
the operations.
Initialize Task: The module includes an “initialize” task, which resets all
the internal signals to zero. This task is used to initialize the state of the
module, setting it to a known starting condition.
Single Write Task: The “single_write” task is responsible for initiating a
single write operation on the Wishbone bus. It is used to set the address,
data, select lines, and control signals to perform the write operation. The
task waits for an acknowledgment (“ack_in”) and then clears the control
signals to end the operation.
Signal Assignments: The module includes several "always" blocks that
assign values to the output signals based on the values of internal
signals. These assignments include the address (“adr_o”), write enable
(“we_o”), data output ("dat_o"), select lines ("sel_o"), cycle ("cyc_o"),
and strobe ("stb_o") signals.
Reset Handling: The module includes reset handling for the ”cyc_o” and
“stb_o” signals to ensure they are de-asserted during a reset condition
(“rst_in”).

TB.V
The provided Verilog module "tb" is a testbench that assesses the
functionality of an SPI communication system that includes a Wishbone
interface, a SPI master, and a SPI slave. It utilizes a set of test scenarios
to validate different configurations of the system.
Here's a brief conclusion regarding the key aspects of this testbench
code:
Module Instantiation: The testbench instantiates three main modules:
“wishbone_master”, “spi_top”, and “spi_slave”. These modules represent
the Wishbone master, the SPI master, and the SPI slave, respectively.

9|Page
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

The interconnection of these modules allows for comprehensive testing


of the SPI communication system.
Clock Generation: The testbench generates a system clock ("wb_clk_in")
with a period of “T” (as specified by the parameter) and utilizes this clock
for simulating the operation of the system.
Reset Task: The “rst” task is provided to apply a reset signal to the
system by asserting and de-asserting the “wb_rst_in” signal. This task
ensures that the system starts in a known state before each test
scenario.
Test Scenarios: The testbench includes multiple initial blocks, each
representing a different test scenario with specific configuration settings
for the SPI master. These test scenarios configure various parameters
such as clock polarity, clock edge, least significant bit (LSB) order, and
character length. After configuration, they allow the simulation to run for
a certain duration (through the “repeat” and “wait” statements), and then
the simulation is finished.
Clock Generation and Timing Control: The testbench continuously
toggles the clock signal with half the specified period to ensure that the
system operates in a timed environment. It also uses wait statements to
control the timing and duration of each test scenario.
Completion and Termination: At the end of each test scenario, the
“$finish” statement is used to terminate the simulation.

SPECIFICATIONS

WISHBONE INTERFACE SIGNALS

10 | P a g e
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

SPI EXTERNAL CONNECTIONS

CORE REGISTER LIST

DATA RECEIVE REGISTER [RxX]

11 | P a g e
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

The Data Receive registers hold the value of received data of the last executed
transfer. Valid bits depend on the character length field in the CTRL register (i.e. if
CTRL[9:3] is set to 0x08, bit RxL[7:0] holds the received data). If character length is
less or equal to 32 bits, Rx1,Rx2 and Rx3 are not used, if character length is less
than 64 bits, Rx2 and Rx3 are not used and so on.

DATA TRANSMIT REGISTER [TxX]

TxX The Data Transmit registers hold the data to be transmitted in the next transfer.
Valid bits depend on the character length field in the CTRL register (i.e. if CTRL[9:3]
is set to 0x08, the bit Tx0[7:0] will be transmitted in next transfer). If character length
is less or equal to 32 bits, Tx1, Tx2 and Tx3 are not used, if character len is less than
64 bits, Tx2 and Tx3 are not used and so on.

CONTROL AND STATUS REGISTER [CTRL]

DIVIDER REGISTER [DIVIDER]

The value in this field is the frequency divider of the system clock wb_clk_i to
generate the serial clock on the output sclk_pad_o. The desired frequency is
obtained according to the following equation:

SLAVE SELECT REGISTER [SS]

If CTRL[ASS] bit is cleared, writing 1 to any bit location of this field sets the proper
ss_pad_o line to an active state and writing 0 sets the line back to inactive state. If

12 | P a g e
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

CTRL[ASS] bit is set, writing 1 to any bit location of this field will select appropriate
ss_pad_o line to be automatically driven to active state for the duration of the
transfer, and will be driven to inactive state for the rest of the time.

ASS
If this bit is set, ss_pad_o signals are generated automatically. This means
that slave select signal, which is selected in SS register is asserted by the SPI
controller, when transfer is started by setting CTRL[GO_BSY] and is de-asserted
after transfer is finished. If this bit is cleared, slave select signals are asserted and
de-aserted by writing and clearing bits in SS register.

IE
If this bit is set, the interrupt output is set active after a transfer is finished. The
Interrupt signal is deasserted after a Read or Write to any register.

LSB
If this bit is set, the LSB is sent first on the line (bit TxL[0]), and the first bit
received from the line will be put in the LSB position in the Rx register (bit RxL[0]). If
this bit is cleared, the MSB is transmitted/received first (which bit in TxX/RxX register
that is depends on the CHAR_LEN field in the CTRL register).

Tx_NEG
If this bit is set, the mosi_pad_o signal is changed on the falling edge of a
sclk_pad_o clock signal, or otherwise the mosi_pad_o signal is changed on the
rising edge of sclk_pad_o.

Rx_NEG
If this bit is set, the miso_pad_i signal is latched on the falling edge of a
sclk_pad_o clock signal, or otherwise the miso_pad_i signal is latched on the rising
edge of sclk_pad_o.

GO_BSY
Writing 1 to this bit starts the transfer. This bit remains set during the transfer
and is automatically cleared after the transfer finished. Writing 0 to this bit has no
effect.

CHAR_LEN

13 | P a g e
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

This field specifies how many bits are transmitted in one transfer. Up to 64
bits can be transmitted.

CHAR_LEN = 0x01 … 1 bit

CHAR_LEN = 0x02 … 2 bits

CHAR_LEN = 0x7f … 127 bits

CHAR_LEN = 0x00 … 128 bits

BLOCK DIAGRAM & ARCHITECTURE

14 | P a g e
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

ss_pad_o

sclk_pad_o
WISHBONE MASTER SPI MASTER CORE SPI SERIAL
SLAVE
Spi_Top.v
Wishbone_Master.v mosi_pad_o
Spi_Slave.v

miso_pad_i

15 | P a g e
Vamsi Krishna B MAVEN SILICON VLSI
DESIGN INTERNSHIP

16 | P a g e

You might also like