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 ;