SPI Interface Use Case

Introduction

Working through the SPI bus using LCS 2016 45 Port Views plus LCS 2016 70 Space Ship

Use case has

  • One QSPI bus master
  • 8 QSPI Slaves
  • 8 SPI Slaves

After this version, for looking forward see: SPI exploring what is next Use Cases

SPI package

library IEEE ; 
  use ieee.std_logic_1164.all ;
  
package SpiPkg is
  type qspi_master_r is record
        mosi : std_logic_vector(3 downto 0);            -- Data from master to slave
        miso : std_logic_vector(3 downto 0);            -- Data from slave to master
        sclk : std_logic;                               -- Serial clock
        ssel : std_logic_vector(15 downto 0);           -- Chip selects
  end record qspi_master_r;

  view qspi_master_view of qspi_master_r is
        mosi : out;
        miso : in;
        sclk : out;
        ssel : out;
  end view qspi_master_view;
  
  type qspi_master_vector is array(integer range <>) of qspi_master_r ; 

  type qspi_slave_r is record
        mosi : std_logic_vector(3 downto 0);            -- Data from master to slave
        miso : std_logic_vector(3 downto 0);            -- Data from slave to master
        sclk : std_logic;                               -- Serial clock
        ssel : std_logic;                               -- Chip select
  end record qspi_slave_r;

  type qspi_slave_vector is array(integer range <>) of qspi_slave_r; 

  view qspi_slave_view of qspi_slave_r is
        mosi : in;
        miso : out;
        sclk : in;
        ssel : in;
  end view qspi_slave_view;

  type spi_slave_r is record
        mosi : std_logic;                               -- Data from master to slave
        miso : std_logic;                               -- Data from slave to master
        sclk : std_logic;                               -- Serial clock
        ssel : std_logic;                               -- Chip select
  end record spi_slave_r;

  type spi_slave_vector is array(integer range <>) of spi_slave_r; 

  view spi_slave_view of spi_slave_r is
        mosi : in;
        miso : out;
        sclk : in;
        ssel : in;
  end view spi_slave_view;
end package SpiPkg ;

Chipper Basic: Connecting the Master and Slaves

Issues?
  • Verbose but capable.
  • Details of the connectivity exposed in the top level netlist

---------------------------------------------------------
-- chipper_basic
--   connect a quad SPI master to
--   8 qspi slaves and
--   8 spi slaves
--   ssel has one bit per slave
--
library IEEE ; 
  use ieee.std_logic_1164.all ;
  use work.SpiPkg.all ;

entity chipper_basic is
  port (
    ..
  ) ;
end entity chipper_basic ;
architecture structural of chipper_basic is

  -- connections for the SPI intefaces 
  signal qspi_master_bus : qspi_master_r;
  signal qspi_slave_bus  : qspi_slave_vector(7 downto 0); 
  signal spi_slave_bus   : spi_slave_vector (7 downto 0); 
  
  -- SPI Components
  component qspi_master (qspi_master_bus : view qspi_master_view ) ;
  component qspi_slave  (qspi_slave_bus  : view qspi_slave_view ) ;
  component spi_slave   (spi_slave_bus   : view spi_slave_view ) ;

begin

  -- create the interconnect.  ssel has one bit per slave
  gen_qspi_slave_bus : for i in qspi_slave_bus'range generate 
  begin
    qspi_slave_bus(i).mosi <=> qspi_master_bus.mosi;
    qspi_slave_bus(i).miso <=> qspi_master_bus.miso;
    qspi_slave_bus(i).sclk <=> qspi_master_bus.sclk;
    qspi_slave_bus(i).ssel <=> qspi_master_bus.ssel(i);
  end generate gen_qspi_slave_bus ;

  gen_spi_slave_bus : for i in spi_slave_bus'range generate 
  begin
    spi_slave_bus(i).mosi <=> qspi_master_bus.mosi(0);
    spi_slave_bus(i).miso <=> qspi_master_bus.miso(0);
    spi_slave_bus(i).sclk <=> qspi_master_bus.sclk;
    spi_slave_bus(i).ssel <=> qspi_master_bus.ssel(i+8);
  end generate gen_spi_slave_bus ;

  -- instantiate the components
  qspi_master_1 : qspi_master port map (qspi_master_bus => qspi_master_bus) ;

  gen_qspi_slaves : for i in qspi_slave_bus'range generate 
  begin
    qspi_slave_1 : qspi_slave port map (qspi_slave_bus => qspi_slave_bus(i)) ;
  end generate gen_spi_slaves ;
  
  gen_spi_slaves : for i in spi_slave_bus'range generate 
  begin
    spi_slave_1 : spi_slave port map (spi_slave_bus => spi_slave_bus(i)) ;
  end generate gen_spi_slaves ;
  
end architecture structural ; 

Chipper Basic, except SSEL specifies an address

  • Has decode logic in the interface

---------------------------------------------------------
-- chipper_basic_decode
--   connect a quad SPI master to
--   8 qspi slaves and
--   8 spi slaves
--   ssel is the address for each slave
--
library IEEE ; 
  use ieee.std_logic_1164.all ;
  use work.SpiPkg.all ;

entity chipper_basic_decode is
  port (
    ..
  ) ;
end entity chipper_basic_decode ;
architecture structural of chipper_basic_decode is
  -- ...  unchanged
begin
  -- create the interconnect.  ssel is the address for each slave
  gen_qspi_slave_bus : for i in qspi_slave_bus'range generate 
    signal ssel : std_logic ; 
  begin
    ssel <= qspi_master_bus.ssel ?= i ;
    qspi_slave_bus(i).mosi <=> qspi_master_bus.mosi;
    qspi_slave_bus(i).miso <=> qspi_master_bus.miso;
    qspi_slave_bus(i).sclk <=> qspi_master_bus.sclk;
    qspi_slave_bus(i).ssel <=  ssel;
  end generate gen_qspi_slave_bus ;

  gen_spi_slave_bus : for i in spi_slave_bus'range generate 
  begin
    spi_slave_bus(i).mosi <=> qspi_master_bus.mosi(0);
    spi_slave_bus(i).miso <=> qspi_master_bus.miso(0);
    spi_slave_bus(i).sclk <=> qspi_master_bus.sclk;
    spi_slave_bus(i).ssel <=  qspi_master_bus.ssel ?= i+8;
  end generate gen_spi_slave_bus ;
  
  -- instantiate the components
    -- ...  unchanged
  
end architecture structural ; 

Abstracting connections with entities - today

Comments * capable but verbose * good enough? probably for now.

---------------------------------------------------------
--  qspi_master_qspi_slave_exchange
--    connect qspi master to qspi slave
--
library IEEE ; 
  use ieee.std_logic_1164.all ;
  use work.SpiPkg.all ;

entity qspi_master_qspi_slave_exchange is
  generic (index : integer ) ; 
  port (
    master : view qspi_master_view; 
    slave  : view qspi_slave_view
  ) ;
end entity qspi_master_spi_slave_exchange ;
architecture exchange of qspi_master_spi_slave_exchange is 
begin
  slave.mosi <=> master.mosi;
  slave.miso <=> master.miso;
  slave.sclk <=> master.sclk;
  slave.ssel <=> master.ssel(index);
end architecture exchange ;


---------------------------------------------------------
--  qspi_master_spi_slave_exchange
--    connect qspi master to spi slave
--
library IEEE ; 
  use ieee.std_logic_1164.all ;
  use work.SpiPkg.all ;

entity qspi_master_spi_slave_exchange is
  generic (index : integer ) ; 
  port (
    master : view qspi_master_view;
    slave  : view spi_slave_view
  ) ;
end entity qspi_master_spi_slave_exchange ;
architecture exchange of qspi_master_spi_slave_exchange is 
begin
  slave.mosi <=> master.mosi(0);
  slave.miso <=> master.miso(0);
  slave.sclk <=> master.sclk;
  slave.ssel <=> master.ssel(index);
end architecture exchange ;


---------------------------------------------------------
-- chipper_entity_connect
--   connect a quad SPI master to
--   8 qspi slaves and
--   8 spi slaves
--   ssel is the address for each slave
--
library IEEE ; 
  use ieee.std_logic_1164.all ;
  use work.SpiPkg.all ;

entity chipper_entity_connect is
  port (
    ..
  ) ;
end entity chipper_entity_connect ;
architecture structural of chipper_entity_connect is
  -- ...  unchanged
begin
  -- create the interconnect.  ssel is the address for each slave
  gen_qspi_slave_bus : for i in qspi_slave_bus'range generate 
  begin
    qspi_master_qspi_slave_exchange_1 : qspi_master_qspi_slave_exchange
       generic map (index => i)
       port map (
         master => qspi_master_bus,
         slave  => qspi_slave_bus(i)
       ) ;
  end generate gen_qspi_slave_bus ;

  gen_spi_slave_bus : for i in spi_slave_bus'range generate 
  begin
    qspi_master_spi_slave_exchange_1 : qspi_master_spi_slave_exchange
       generic map (index => i+8)
       port map (
         master => qspi_master_bus,
         slave  => spi_slave_bus(i)
       ) ;
  end generate gen_spi_slave_bus ;
  
  -- instantiate the components
    -- ...  unchanged
  
end architecture structural ; 
Topic revision: r6 - 2017-04-02 - 16:07:50 - PatrickLehmann
 
Copyright © 2008-2025 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback