SPI Interface - exploring what is next Use Cases

Introduction

Continuing with the SPI interface with
  • One QSPI bus master
  • 8 QSPI Slaves
  • 8 SPI Slaves

Explore what additional syntax we may need to add in a future revision.

Based on: SPI with Port View and Space ship
Based on LCS: LCS 2016 45a Port Views plus LCS 2016 70 Space Ship

Alternative 1: Abstracting connections with map procedures

* A map procedure is a callable container of concurrent code. * Issues: cannot be used on interface * A little better than an entity, but not a lot

  map procedure qspi_master_spi_slave_exch is
  parameter (
      index : integer ;  
      signal slave : view spi_slave_view; 
      signal master : view qspi_master_view 
  ) is 
  begin
    slave.mosi <=> master.mosi(0);
    slave.miso <=> master.miso(0);
    slave.sclk <=> master.sclk;
    slave.ssel <=> master.ssel(index);
  end map procedure qspi_master_spi_slave_exch ;


  gen_spi_slave_bus : for i in spi_slave_bus'range generate 
  begin
    qspi_master_spi_slave_exch (
       index => i+8,
       slave  => spi_slave_bus(i),
       master => qspi_master_bus
    ) ;
  end generate gen_spi_slave_bus ;

Alternative 2: Abstracting connections with conversion like map function

  • Create a map function that works like a conversion.
  • Potentially usable in a port map.
  • Issues: 2 functions

  package SpiPkg is 
    -- . . .
    
    map function s_to_qm (signal slave : view spi_slave_view) return qspi_master_view is
    begin 
      return (
        mosi             => unaffected, 
        miso(0)          => slave.miso, 
        miso(3 downto 1) => unaffected,
        sclk             => unaffected, 
        ssel             => unaffected
      ) ;
    end map function s_to_qm ; 

    map function qm_to_s(signal master : view qspi_master_view; i : integer ) return spi_slave_view is
      return (
         mosi => master.mosi(0), 
         miso => unaffected, 
         sclk => master.sclk, 
         ssel => master.ssel(i)
       ) ; 
    end map function qm_to_s ; 
  end package SpiPkg ; 

    -- creating connections
    gen_spi_slave_bus : for i in spi_slave_bus'range generate 
      s_to_qm(spi_slave_bus(i)) <=> qm_to_s(qspi_master_bus, i) ;
    end generate gen_spi_slave_bus ;

Alternative 2b: Using the conversion like map function on a component instance

    -- Alternately no need to create connections, do mapping on component instances
    qspi_master_1 : qspi_master port map (qspi_master_bus => qspi_master_bus) ;

    gen_qspi_slaves : for i in qspi_slave_bus'range generate 
      qspi_slave_1 : qspi_slave port map (qs_to_qm(qspi_slave_bus) => qm_to_s(qspi_master_bus, i)) ;
    end generate gen_spi_slaves ;
    
    gen_spi_slaves : for i in spi_slave_bus'range generate 
      spi_slave_1 : spi_slave port map (s_to_qm(spi_slave_bus) => qm_to_s(qspi_master_bus, i)) ;
    end generate gen_spi_slaves ;

Alternative 2c: Does a map conversion require a designation on the interface since it is different

    -- Alternately no need to create connections, do mapping on component instances
    ... 

    gen_qspi_slaves : for i in qspi_slave_bus'range generate 
      qspi_slave_1 : qspi_slave port map (map qs_to_qm(qspi_slave_bus) => map qm_to_s(qspi_master_bus, i)) ;
    end generate gen_spi_slaves ;
    
    ... 

Alternative 2d: Allowing others in a map function

  package SpiPkg is 
    -- . . .
    
    map function s_to_qm (signal slave : view spi_slave_view) return qspi_master_view is
    begin 
      return (
        miso(0)          => slave.miso, 
        miso(3 downto 1) => unaffected,
        others           => unaffected
      ) ;
    end map function s_to_qm ; 

    map function qm_to_s(signal master : view qspi_master_view ; i : integer) return spi_slave_view is
    begin
      return (
         mosi => master.mosi(0), 
         miso => unaffected, 
         sclk => master.sclk, 
         ssel => master.ssel(i)
       ) ; 
    end map function qm_to_s ; 
  end package SpiPkg ; 

Alternative 3: Map function that connects actual to formal.

  • Specifies how the parameters of the map function connects to the formal
  • One function specified on an actual

    -- Definition in a package:    
    map function qm_to_qs(signal master : view qspi_master_view ; i : integer ) to qspi_slave_view is
    begin
      map (
         mosi  <=  master.mosi, 
         miso  =>  master.miso, 
         sclk  <=  master.sclk, 
         ssel  <=  master.ssel(i)
       ) ; 
    end map function qm_to_s ; 

    map function qm_to_s(signal master : view qspi_master_view ; i : integer ) to spi_slave_view is
    begin
      map (
         mosi  <=  master.mosi(0), 
         miso  =>  master.miso(0), 
         sclk  <=  master.sclk, 
         ssel  <=  master.ssel(i)
       ) ; 
    end map function qm_to_s ; 
    
    
    -- Usage in an entity:    
    qspi_master_1 : qspi_master (qspi_master_bus => qspi_master_bus) ;

    gen_qspi_slaves : for i in qspi_slave_bus'range generate 
      qspi_slave_1 : qspi_slave port map (qspi_slave_bus => map qm_to_qs(qspi_master_bus, i)) ;
    end generate gen_spi_slaves ;
    
    gen_spi_slaves : for i in spi_slave_bus'range generate 
      spi_slave_1 : spi_slave port map (spi_slave_bus => map qm_to_s(qspi_master_bus, i)) ;
    end generate gen_spi_slaves ;
 

Alternative 4: Create a map function that overloads spaceship

  • Requires additional static parameters as generics
  • Issues: cannot be used on entity interface

  map function "<=>"
    generic (index : integer)  
    parameter (signal slave : view slave_view ; signal master : view master_view) is
  begin 
    slave.mosi <=> master.mosi(0);
    slave.miso <=> master.miso(0);
    slave.sclk <=> master.sclk;
    slave.ssel <=> master.ssel(index);
  end function "<=>" ;
  
    gen_spi_slave_bus : for i in spi_slave_bus'range generate
      spi_slave_bus(i) <=> qspi_master_bus generic map (index => i) ;
    end generate gen_spi_slave_bus ;

Alternative 5: Extending capability of spaceship with map ()

  • Currently a separate LCS 70a

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

Alternative 6: A silly alternative as an abbreviated map ()

  for qspi_slave_bus(i) map (
                mosi => qspi_master_bus.mosi,
                miso => qspi_master_bus.miso,
                sclk => qspi_master_bus.sclk,
                ssel => ssel
   );
Topic revision: r6 - 2017-04-02 - 16:07:50 - PatrickLehmann
 
Copyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback