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 ;