Master, 4 slaves, Shared Decode and Mux block

Introduction

Working through Rob's example using LCS 2016 45 Port Views plus LCS 2016 70 SpaceShip

Use case has

  • One master
  • 2 Slaves - unique address and data width
  • 2 Memory Models - unique address and data width
  • Entity for Decoder, and Multiplexing
  • 1 common bus for all slave responses

Observations

  • When using map, I might as well of created individual elements on the port.

BusPkg - defines the unconstrained system types

library IEEE ; 
  use ieee.std_logic_1164.all ;
  
package BusPkg is
  -- defines basic types and views for an unconstrained system 
 type BusType is
   record
      Sel           : Std_uLogic;
      Address       : unresolved_unsigned;
      Read_Write    : Std_uLogic;
      WriteData     : Std_uLogic_Vector;
      DataValid     : Std_uLogic;
      ReadData      : Std_uLogic_Vector;
   end record BusType;
   
 type BusArray is array (natural range <>) of BusArray;
   
 view MasterView of BusType is
      Sel           : out;
      Address       : out;
      Read_Write    : out;
      WriteData     : out;
      DataValid     : in;
      ReadData      : in;
end view MasterView;

alias SlaveView is MasterView'CONVERSE ;

view SlaveArrayView of BusArray is
      others : view SlaveView;
end view SlaveArrayView;

end package BusPkg ;

SystemPkg - Defines the address and data ranges for each component in the system

library IEEE ; 
  use ieee.std_logic_1164.all ;

package SystemPkg is
  -- Defines the System Interfaces as designed
  subtpe SlaveArrayRange is integer range 1 to 4 ; 
  
  subtype MasterAddressRange is integer range 31 downto 0 ; 
  subtype MasterDataRange is integer range 31 downto 0 ; 
  subtype MasterIfType is BusType(
       Address(MasterAddressRange), 
       WriteData(MasterDataRange), 
       ReadData(MasterDataRange) 
  ) ;

  constant Slave1ID : integer := 1 ;
  subtype Slave1AddressRange is integer range 10 downto 0 ; 
  subtype Slave1DataRange is integer range 7 downto 0 ; 
  subtype Slave1IfType is BusType(
       Address(Slave1AddressRange), 
       WriteData(Slave1DataRange), 
       ReadData(Slave1DataRange) 
  ) ;
  subtype Slave1Range is integer range ... ;   

  constant Slave2ID : integer := 2 ;
  subtype Slave2AddressRange is integer range 10 downto 0 ; 
  subtype Slave2DataRange is integer range 7 downto 0 ; 
  subtype Slave2IfType is BusType(
       Address(Slave2AddressRange), 
       WriteData(Slave2DataRange), 
       ReadData(Slave2DataRange) 
  ) ;
  subtype Slave2Range is integer range ... ;   

  constant Memory1ID : integer := 3 ;
  subtype Memory1AddressRange is integer range 31 downto 0 ; 
  subtype Memory1DataRange is integer range 31 downto 0 ; 
  subtype Memory1IfType is BusType(
       Address(Memory1AddressRange), 
       WriteData(Memory1DataRange), 
       ReadData(Memory1DataRange) 
  ) ;
  subtype Memory1Range is integer range ... ;   

  constant Memory2ID : integer := 4 ;
  subtype Memory2AddressRange is integer range 31 downto 0 ; 
  subtype Memory2DataRange is integer range 31 downto 0 ; 
  subtype Memory2IfType is BusType(
       Address(Memory2AddressRange), 
       WriteData(Memory2DataRange), 
       ReadData(Memory2DataRange) 
  ) ;
  subtype Memory2Range is integer range ... ;   

end package SystemPkg ;

master_slave_exchange - Manages the details of connecting a master and slave

library IEEE ; 
  use ieee.std_logic_1164.all ;
  use work.BusPkg.all ;

entity Decode_Mux is
  port (
    master   : view MasterView'CONVERSE; 
    slave    : view SlaveArrayView'CONVERSE
  ) ;
end entity Decode_Mux ;
architecture exchange of Decode_Mux is 
begin
  process (...)
  being
    for i in 1 to 4 loop 
      slave(i).Address     <= master.Address;
      slave(i).Read_Write  <= master.Read_Write;
      slave(i).WriteData   <= master.WriteData;
    end loop ;
    
    case to_integer(Master.Address) is
      when Slave1Range =>
        slave(Slave1ID).Select    <= master.Select;
        master.DataValid   <= slave(Slave1ID).DataValid;
        master.ReadData    <= slave(Slave1ID).ReadData ;
        
      when Slave2Range =>
        slave(Slave2ID).Select    <= master.Select;
        master.DataValid   <= slave(Slave2ID).DataValid;
        master.ReadData    <= slave(Slave2ID).ReadData ;
    
      when Memory1Range =>
        slave(Memory1ID).Select      <= master.Select;
        master.DataValid     <= slave(Memory1ID).DataValid;
        master.ReadData      <= slave(Memory1ID).ReadData ;
        
      when Memory2Range =>
        slave(Memory2ID)Select      <= master.Select;
        master.DataValid    <= slave(Memory2ID).DataValid;
        master.ReadData     <= slave(Memory2ID).ReadData ;
    
      when others =>   null ; 
    end case ; 
  end process ; 
end architecture exchange ; 

end architecture exchange ;

System Basic: Connecting the Master and Slaves

Uses an entity with generic to do the interconnect

---------------------------------------------------------
-- system_basic
--   Master
--   2 slaves and
--   2 Memory Modules
--
library IEEE ; 
  use ieee.std_logic_1164.all ;
  use work.BusPkg.all ;
  use work.SystemPkg.all ;

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

  -- connections for the SPI intefaces 
  signal master_bus  :  BusType(
       Address(MasterAddressRange), 
       WriteData(MasterDataRange), 
       ReadData(MasterDataRange) );
  signal slave_array_bus  : BusArray(SlaveArrayRange)(
       Address(MasterAddressRange), 
       WriteData(MasterDataRange), 
       ReadData(MasterDataRange) ) ; 

  -- SPI Components
  component Master  port (master_bus : view MasterIfType; ...  ) ;
  component Slave1  port (slave_bus  : view Slave1IfType; ...  ) ;
  component Slave2  port (slave_bus  : view Slave1IfType; ...  ) ;
  component Memory1 port (memory_bus  : view Memory1IfType; ...  ) ;
  component Memory2 port (memory_bus  : view Memory2IfType; ...  ) ;
  
  component Decode_Mux is
    port (
      master : view MasterBusView'CONVERSE; 
      slave  : view SlaveBusView'CONVERSE
    ) ;
  end compoenent Decode_Mux;


begin

  -- Master Instance 
  master_1 : Master port map (master_bus => master_bus, ... ) ;

  
  -- Decode Mux Instance 
  Decode_Mux_1 : Decode_Mux port map (master => master_bus, slave => slave_array_bus ) ;
     
  -- Slave1 Instance 
  slave_1 : Slave1 port map (slave_bus => map ( 
     Address     => slave_array_bus(Slave1ID).Address(Slave1AddressRange), 
     Read_Write  => slave_array_bus(Slave1ID).Read_Write,
     WriteData   => slave_array_bus(Slave1ID).WriteData(Slave1DataRange),
     Select      => slave_array_bus(Slave1ID).Select,
     DataValid   => slave_array_bus(Slave1ID).DataValid,
     ReadData    => slave_array_bus(Slave1ID).ReadData(Slave1DataRange)
   ) ; 
     
    -- Slave2 Instance 
  slave_2 : Slave2 port map (slave_bus => map ( 
     Address     => slave_array_bus(Slave2ID).Address(Slave2AddressRange), 
     Read_Write  => slave_array_bus(Slave2ID).Read_Write,
     WriteData   => slave_array_bus(Slave2ID).WriteData(Slave2DataRange),
     Select      => slave_array_bus(Slave2ID).Select,
     DataValid   => slave_array_bus(Slave2ID).DataValid,
     ReadData    => slave_array_bus(Slave2ID).ReadData(Slave2DataRange)
   ) ; 

  -- Memory1 Instance 
  slave_1 : Memory1 port map (slave_bus => map ( 
     Address     => slave_array_bus(Memory1ID).Address(Memory1AddressRange), 
     Read_Write  => slave_array_bus(Memory1ID).Read_Write,
     WriteData   => slave_array_bus(Memory1ID).WriteData(Memory1DataRange),
     Select      => slave_array_bus(Memory1ID).Select,
     DataValid   => slave_array_bus(Memory1ID).DataValid,
     ReadData    => slave_array_bus(Memory1ID).ReadData(Memory1DataRange)
   ) ; 
     
    -- Memory2 Instance 
  slave_2 : Memory2 port map (slave_bus => map ( 
     Address     => slave_array_bus(Memory2ID).Address(Memory2AddressRange), 
     Read_Write  => slave_array_bus(Memory2ID).Read_Write,
     WriteData   => slave_array_bus(Memory2ID).WriteData(Memory2DataRange),
     Select      => slave_array_bus(Memory2ID).Select,
     DataValid   => slave_array_bus(Memory2ID).DataValid,
     ReadData    => slave_array_bus(Memory2ID).ReadData(Memory2DataRange)
   ) ; 
     
end architecture structural ; 
Topic revision: r2 - 2017-04-02 - 15:45:29 - 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