Master, 4 slaves, Separate Decode and Mux block, Separate/Individual Slave Busses

Introduction

Working through Rob's example using LCS 2016 45a Port Views plus LCS 2016 70 Space Ship

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
  • Uses separate bus for each interface

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;
      
  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 ;
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 ;

Decode_Mux - Decoding and Multiplexing between Master and slaves

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

entity Decode_Mux is
  port (
    master   : view MasterView'CONVERSE of MasterIfType; 
    slave1   : view SlaveView'CONVERSE  of Slave1IfType;
    slave2   : view SlaveView'CONVERSE  of Slave2IfType;
    Memory1  : view SlaveView'CONVERSE  of Memory1IfType;
    Memory2  : view SlaveView'CONVERSE  of Memory2IfType
  ) ;
end entity Decode_Mux ;
architecture exchange of Decode_Mux is 
begin
  process (...)
  being
    case to_integer(Master.Address) is
      when Slave1Range =>
        slave1.Address     <= master.Address(Slave1AddressRange);
        slave1.Read_Write  <= master.Read_Write;
        slave1.WriteData   <= master.WriteData(Slave1DataRange);
        slave1.Select      <= master.Select;
        master.DataValid   <= slave1.DataValid;
        master.ReadData(Slave1DataRange) <= slave1.ReadData ;
        
      when Slave2Range =>
        slave2.Address     <= master.Address(Slave2AddressRange);
        slave2.Read_Write  <= master.Read_Write;
        slave2.WriteData   <= master.WriteData(Slave2DataRange);
        slave2.Select      <= master.Select;
        master.DataValid   <= slave2.DataValid;
        master.ReadData(Slave2DataRange) <= slave2.ReadData ;
    
      when Memory1Range =>
        memory1.Address     <= master.Address(Memory1AddressRange);
        memory1.Read_Write  <= master.Read_Write;
        memory1.WriteData   <= master.WriteData(Memory1DataRange);
        memory1.Select      <= master.Select;
        master.DataValid    <= memory1.DataValid;
        master.ReadData(Memory1DataRange) <= Memory1.ReadData ;
        
      when Memory2Range =>
        memory2.Address     <= master.Address(Memory2AddressRange);
        memory2.Read_Write  <= master.Read_Write;
        memory2.WriteData   <= master.WriteData(Memory2DataRange);
        memory2.Select      <= master.Select;
        master.DataValid    <= memory2.DataValid;
        master.ReadData(Memory2DataRange) <= Memory2.ReadData ;
    
      when others => 
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  : MasterIfType;
  signal Slave1_bus  : Slave1IfType;
  signal Slave2_bus  : Slave2IfType;
  signal Memory1_bus : Memory1IfType;
  signal Memory2_bus : Memory2IfType;

  -- Components
  component Master  port (master_bus  : view MasterView of MasterIfType; ...  ) ;
  component Slave1  port (slave_bus   : view SlaveView of Slave1IfType; ...  ) ;
  component Slave2  port (slave_bus   : view SlaveView of Slave2IfType; ...  ) ;
  component Memory1 port (memory_bus  : view SlaveView of Memory1IfType; ...  ) ;
  component Memory2 port (memory_bus  : view SlaveView of Memory2IfType; ...  ) ;
  
  component Decode_Mux is
    port (
    master   : view MasterView'CONVERSE of MasterIfType; 
    slave1   : view SlaveView'CONVERSE  of Slave1IfType;
    slave2   : view SlaveView'CONVERSE  of Slave2IfType;
    Memory1  : view SlaveView'CONVERSE  of Memory1IfType;
    Memory2  : view SlaveView'CONVERSE  of Memory2IfType
    ) ;
  end component Decode_Mux ;


begin

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

  -- Decoder  
  Decode_Mux_1 : Decode_Mux 
    port map (
      master   =>  master_bus, 
      slave1   =>  slave1_bus, 
      slave2   =>  slave2_bus, 
      Memory1  =>  Memory1_bus,
      Memory2  =>  Memory2_bus
    ) ;
     
  -- Slave1 Instance 
  slave_1 : Slave1 port map (slave_bus => slave1_bus, ... ) ;
       
  -- Slave2 Instance 
  slave_2 : Slave2 port map (slave_bus => slave2_bus, ... ) ;

  -- Memory1 Instance 
  memory_1 : Memory1 port map (memory_bus => memory1_bus, ... ) ;

  -- Memory2 Instance 
  memory_2 : Memory2 port map (memory_bus => memory2_bus, ... ) ;
     
end architecture structural ; 
Topic revision: r3 - 2017-04-02 - 16:07:49 - 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