--Propery of Tecphos Inc. See WrimmLicense.txt for license details
|
--Propery of Tecphos Inc. See WrimmLicense.txt for license details
|
--Latest version of all Wrimm project files available at http://opencores.org/project,wrimm
|
--Latest version of all Wrimm project files available at http://opencores.org/project,wrimm
|
--See WrimmManual.pdf for the Wishbone Datasheet and implementation details.
|
--See WrimmManual.pdf for the Wishbone Datasheet and implementation details.
|
--See wrimm subversion project for version history
|
--See wrimm subversion project for version history
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
|
|
use work.WrimmPackage.all;
|
use work.WrimmPackage.all;
|
|
|
entity Wrimm is
|
entity Wrimm is
|
port (
|
port (
|
WbClk : in std_logic;
|
WbClk : in std_logic;
|
WbRst : out std_logic;
|
WbRst : out std_logic;
|
|
|
WbMasterIn : in WbMasterOutArray; --Signals from Masters
|
WbMasterIn : in WbMasterOutArray; --Signals from Masters
|
WbMasterOut : out WbSlaveOutArray; --Signals to Masters
|
WbMasterOut : out WbSlaveOutArray; --Signals to Masters
|
|
|
--WbSlaveIn : out WbMasterOutArray;
|
--WbSlaveIn : out WbMasterOutArray;
|
--WbSlaveOut : in WbSlaveOutArray;
|
--WbSlaveOut : in WbSlaveOutArray;
|
|
|
StatusRegs : in StatusArrayType;
|
StatusRegs : in StatusArrayType;
|
|
|
SettingRegs : out SettingArrayType;
|
SettingRegs : out SettingArrayType;
|
SettingRsts : in SettingArrayBitType;
|
SettingRsts : in SettingArrayBitType;
|
|
|
Triggers : out TriggerArrayType;
|
Triggers : out TriggerArrayType;
|
TriggerClr : in TriggerArrayType;
|
TriggerClr : in TriggerArrayType;
|
|
|
rstZ : in std_logic); --Asynchronous reset
|
rstZ : in std_logic); --Asynchronous reset
|
end entity Wrimm;
|
end entity Wrimm;
|
|
|
architecture behavior of Wrimm is
|
architecture behavior of Wrimm is
|
signal wbStrobe : std_logic; --Internal Wishbone signals
|
signal wbStrobe : std_logic; --Internal Wishbone signals
|
signal validAddress : std_logic;
|
signal validAddress : std_logic;
|
signal wbAddr : WbAddrType;
|
signal wbAddr : WbAddrType;
|
signal wbSData,wbMData : WbDataType;
|
signal wbSData,wbMData : WbDataType;
|
signal wbWrEn,wbCyc : std_logic;
|
signal wbWrEn,wbCyc : std_logic;
|
signal wbAck,wbRty,wbErr : std_logic;
|
signal wbAck,wbRty,wbErr : std_logic;
|
--signal wbMDataTag : std_logic_vector(0 to 1);
|
--signal wbMDataTag : std_logic_vector(0 to 1);
|
--signal wbCycType : std_logic_vector(0 to 2);
|
--signal wbCycType : std_logic_vector(0 to 2);
|
|
|
signal iSettingRegs : SettingArrayType;
|
signal iSettingRegs : SettingArrayType;
|
signal iTriggers : TriggerArrayType;
|
signal iTriggers : TriggerArrayType;
|
signal statusEnable : StatusArrayBitType;
|
signal statusEnable : StatusArrayBitType;
|
signal settingEnable : SettingArrayBitType;
|
signal settingEnable : SettingArrayBitType;
|
signal triggerEnable : TriggerArrayType;
|
signal triggerEnable : TriggerArrayType;
|
signal grant : WbMasterGrantType;
|
signal grant : WbMasterGrantType;
|
|
|
begin
|
begin
|
SettingRegs <= iSettingRegs;
|
SettingRegs <= iSettingRegs;
|
Triggers <= iTriggers;
|
Triggers <= iTriggers;
|
|
|
--=============================================================================
|
--=============================================================================
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Master Round Robin Arbitration
|
-- Master Round Robin Arbitration
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
procArb: process(WbClk,rstZ) is --Round robin arbitration (descending)
|
procArb: process(WbClk,rstZ) is --Round robin arbitration (descending)
|
variable vGrant : WbMasterGrantType;
|
variable vGrant : WbMasterGrantType;
|
begin
|
begin
|
if (rstZ='0') then
|
if (rstZ='0') then
|
vGrant := (Others=>'0');
|
vGrant := (Others=>'0');
|
vGrant(vGrant'left) := '1';
|
vGrant(vGrant'left) := '1';
|
elsif rising_edge(WbClk) then
|
elsif rising_edge(WbClk) then
|
loopGrant: for i in WbMasterType loop
|
loopGrant: for i in WbMasterType loop
|
if vGrant(i)='1' and WbMasterIn(i).Cyc='0' then --else maintain grant
|
if vGrant(i)='1' and WbMasterIn(i).Cyc='0' then --else maintain grant
|
loopNewGrantA: for j in i to WbMasterType'right loop --last master with cyc=1 will be selected
|
loopNewGrantA: for j in i to WbMasterType'right loop --last master with cyc=1 will be selected
|
if WbMasterIn(j).Cyc='1' then
|
if WbMasterIn(j).Cyc='1' then
|
vGrant := (Others=>'0');
|
vGrant := (Others=>'0');
|
vGrant(j) := '1';
|
vGrant(j) := '1';
|
end if;
|
end if;
|
end loop loopNewGrantA;
|
end loop loopNewGrantA;
|
if i/=WbMasterType'left then
|
if i/=WbMasterType'left then
|
loopNewGrantB: for j in WbMasterType'left to WbMasterType'pred(i) loop
|
loopNewGrantB: for j in WbMasterType'left to WbMasterType'pred(i) loop
|
if WbMasterIn(j).Cyc='1' then
|
if WbMasterIn(j).Cyc='1' then
|
vGrant := (Others=>'0');
|
vGrant := (Others=>'0');
|
vGrant(j) := '1';
|
vGrant(j) := '1';
|
end if;
|
end if;
|
end loop loopNewGrantB; --grant only moves after new requester
|
end loop loopNewGrantB; --grant only moves after new requester
|
end if;
|
end if;
|
end if;
|
end if;
|
end loop loopGrant;
|
end loop loopGrant;
|
end if; --Clk
|
end if; --Clk
|
grant <= vGrant;
|
grant <= vGrant;
|
end process procArb;
|
end process procArb;
|
--=============================================================================
|
--=============================================================================
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Master Multiplexers
|
-- Master Multiplexers
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
procWbMasterIn: process(grant,WbMasterIn) is
|
procWbMasterIn: process(grant,WbMasterIn) is
|
variable vSlaveOut : WbMasterOutType;
|
variable vSlaveOut : WbMasterOutType;
|
begin
|
begin
|
loopGrantInMux: for i in WbMasterType loop
|
loopGrantInMux: for i in WbMasterType loop
|
vSlaveOut := WbMasterIn(i);
|
vSlaveOut := WbMasterIn(i);
|
exit when grant(i)='1';
|
exit when grant(i)='1';
|
end loop loopGrantInMux;
|
end loop loopGrantInMux;
|
wbStrobe <= vSlaveOut.Strobe;
|
wbStrobe <= vSlaveOut.Strobe;
|
wbWrEn <= vSlaveOut.WrEn;
|
wbWrEn <= vSlaveOut.WrEn;
|
wbAddr <= vSlaveOut.Addr;
|
wbAddr <= vSlaveOut.Addr;
|
wbMData <= vSlaveOut.Data;
|
wbMData <= vSlaveOut.Data;
|
--wbMDataTag <= vSlaveOut.DataTag;
|
--wbMDataTag <= vSlaveOut.DataTag;
|
wbCyc <= vSlaveOut.Cyc;
|
wbCyc <= vSlaveOut.Cyc;
|
--wbCycType <= vSlaveOut.CycType;
|
--wbCycType <= vSlaveOut.CycType;
|
end process procWbMasterIn;
|
end process procWbMasterIn;
|
procWbMasterOut: process(grant,wbSData,wbAck,wbErr,wbRty) is
|
procWbMasterOut: process(grant,wbSData,wbAck,wbErr,wbRty) is
|
begin
|
begin
|
loopGrantOutMux: for i in grant'range loop
|
loopGrantOutMux: for i in grant'range loop
|
WbMasterOut(i).Ack <= grant(i) and wbAck;
|
WbMasterOut(i).Ack <= grant(i) and wbAck;
|
WbMasterOut(i).Err <= grant(i) and wbErr;
|
WbMasterOut(i).Err <= grant(i) and wbErr;
|
WbMasterOut(i).Rty <= grant(i) and wbRty;
|
WbMasterOut(i).Rty <= grant(i) and wbRty;
|
WbMasterOut(i).Data <= wbSData; --Data out can always be active.
|
WbMasterOut(i).Data <= wbSData; --Data out can always be active.
|
end loop loopGrantOutMux;
|
end loop loopGrantOutMux;
|
end process procWbMasterOut;
|
end process procWbMasterOut;
|
|
|
wbAck <= wbStrobe and validAddress;
|
wbAck <= wbStrobe and validAddress;
|
wbErr <= wbStrobe and not(validAddress);
|
wbErr <= wbStrobe and not(validAddress);
|
wbRty <= '0';
|
wbRty <= '0';
|
WbRst <= '0';
|
WbRst <= '0';
|
--=============================================================================
|
--=============================================================================
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Address Decode, Asynchronous
|
-- Address Decode, Asynchronous
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
procAddrDecode: process(wbAddr) is
|
procAddrDecode: process(wbAddr) is
|
variable vValidAddress : std_logic;
|
variable vValidAddress : std_logic;
|
begin
|
begin
|
vValidAddress := '0';
|
vValidAddress := '0';
|
loopStatusEn: for f in StatusFieldType loop
|
loopStatusEn: for f in StatusFieldType loop
|
if StatusParams(f).Address=wbAddr then
|
if StatusParams(f).Address=wbAddr then
|
statusEnable(f) <= '1';
|
statusEnable(f) <= '1';
|
vValidAddress := '1';
|
vValidAddress := '1';
|
else
|
else
|
statusEnable(f) <= '0';
|
statusEnable(f) <= '0';
|
end if;
|
end if;
|
end loop loopStatusEn;
|
end loop loopStatusEn;
|
loopSettingEn: for f in SettingFieldType loop
|
loopSettingEn: for f in SettingFieldType loop
|
if SettingParams(f).Address=wbAddr then
|
if SettingParams(f).Address=wbAddr then
|
settingEnable(f) <= '1';
|
settingEnable(f) <= '1';
|
vValidAddress := '1';
|
vValidAddress := '1';
|
else
|
else
|
settingEnable(f) <= '0';
|
settingEnable(f) <= '0';
|
end if;
|
end if;
|
end loop loopSettingEn;
|
end loop loopSettingEn;
|
loopTriggerEn: for f in TriggerFieldType loop
|
loopTriggerEn: for f in TriggerFieldType loop
|
if TriggerParams(f).Address=wbAddr then
|
if TriggerParams(f).Address=wbAddr then
|
triggerEnable(f) <= '1';
|
triggerEnable(f) <= '1';
|
vValidAddress := '1';
|
vValidAddress := '1';
|
else
|
else
|
triggerEnable(f) <= '0';
|
triggerEnable(f) <= '0';
|
end if;
|
end if;
|
end loop loopTriggerEn;
|
end loop loopTriggerEn;
|
validAddress <= vValidAddress;
|
validAddress <= vValidAddress;
|
end process procAddrDecode;
|
end process procAddrDecode;
|
--=============================================================================
|
--=============================================================================
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Read
|
-- Read
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
procRegRead: process(StatusRegs,iSettingRegs,iTriggers,statusEnable,settingEnable,triggerEnable) is
|
procRegRead: process(StatusRegs,iSettingRegs,iTriggers,statusEnable,settingEnable,triggerEnable) is
|
variable vWbSData : WbDataType;
|
variable vWbSData : WbDataType;
|
begin
|
begin
|
vWbSData := (Others=>'0');
|
vWbSData := (Others=>'0');
|
loopStatusRegs : for f in StatusFieldType loop
|
loopStatusRegs : for f in StatusFieldType loop
|
if statusEnable(f)='1' then
|
if statusEnable(f)='1' then
|
vWbSData(StatusParams(f).MSBLoc to (StatusParams(f).MSBLoc + StatusParams(f).BitWidth - 1)) := StatusRegs(f)((WbDataBits-StatusParams(f).BitWidth) to WbDataBits-1);
|
vWbSData(StatusParams(f).MSBLoc to (StatusParams(f).MSBLoc + StatusParams(f).BitWidth - 1)) := StatusRegs(f)((WbDataBits-StatusParams(f).BitWidth) to WbDataBits-1);
|
end if; --Address
|
end if; --Address
|
end loop loopStatusRegs;
|
end loop loopStatusRegs;
|
loopSettingRegs : for f in SettingFieldType loop
|
loopSettingRegs : for f in SettingFieldType loop
|
if settingEnable(f)='1' then
|
if settingEnable(f)='1' then
|
vWbSData(SettingParams(f).MSBLoc to (SettingParams(f).MSBLoc + SettingParams(f).BitWidth - 1)) := iSettingRegs(f)((WbDataBits-SettingParams(f).BitWidth) to WbDataBits-1);
|
vWbSData(SettingParams(f).MSBLoc to (SettingParams(f).MSBLoc + SettingParams(f).BitWidth - 1)) := iSettingRegs(f)((WbDataBits-SettingParams(f).BitWidth) to WbDataBits-1);
|
end if; --Address
|
end if; --Address
|
end loop loopSettingRegs;
|
end loop loopSettingRegs;
|
loopTriggerRegs : for f in TriggerFieldType loop
|
loopTriggerRegs : for f in TriggerFieldType loop
|
if triggerEnable(f)='1' then
|
if triggerEnable(f)='1' then
|
vWbSData(TriggerParams(f).BitLoc) := iTriggers(f);
|
vWbSData(TriggerParams(f).BitLoc) := iTriggers(f);
|
end if; --Address
|
end if; --Address
|
end loop loopTriggerRegs;
|
end loop loopTriggerRegs;
|
wbSData <= vWbSData;
|
wbSData <= vWbSData;
|
end process procRegRead;
|
end process procRegRead;
|
--=============================================================================
|
--=============================================================================
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Write, Reset, Clear
|
-- Write, Reset, Clear
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
procRegWrite: process(WbClk,rstZ) is
|
procRegWrite: process(WbClk,rstZ) is
|
begin
|
begin
|
if (rstZ='0') then
|
if (rstZ='0') then
|
loopSettingRegDefault : for f in SettingFieldType loop
|
loopSettingRegDefault : for f in SettingFieldType loop
|
iSettingRegs(f) <= SettingParams(f).Default;
|
iSettingRegs(f) <= SettingParams(f).Default;
|
end loop loopSettingRegDefault;
|
end loop loopSettingRegDefault;
|
loopTriggerRegDefault : for f in TriggerFieldType loop
|
loopTriggerRegDefault : for f in TriggerFieldType loop
|
iTriggers(f) <= '0';
|
iTriggers(f) <= '0';
|
end loop loopTriggerRegDefault;
|
end loop loopTriggerRegDefault;
|
elsif rising_edge(WbClk) then
|
elsif rising_edge(WbClk) then
|
loopSettingRegWr : for f in SettingFieldType loop
|
loopSettingRegWr : for f in SettingFieldType loop
|
if settingEnable(f)='1' and wbStrobe='1' and wbWrEn='1' then
|
if settingEnable(f)='1' and wbStrobe='1' and wbWrEn='1' then
|
iSettingRegs(f)((WbDataBits-SettingParams(f).BitWidth) to WbDataBits-1) <= wbMData(SettingParams(f).MSBLoc to (SettingParams(f).MSBLoc + SettingParams(f).BitWidth-1));
|
iSettingRegs(f)((WbDataBits-SettingParams(f).BitWidth) to WbDataBits-1) <= wbMData(SettingParams(f).MSBLoc to (SettingParams(f).MSBLoc + SettingParams(f).BitWidth-1));
|
end if;
|
end if;
|
end loop loopSettingRegWr;
|
end loop loopSettingRegWr;
|
loopSettingRegRst : for f in SettingFieldType loop
|
loopSettingRegRst : for f in SettingFieldType loop
|
if SettingRsts(f)='1' then
|
if SettingRsts(f)='1' then
|
iSettingRegs(f) <= SettingParams(f).Default;
|
iSettingRegs(f) <= SettingParams(f).Default;
|
end if;
|
end if;
|
end loop loopSettingRegRst;
|
end loop loopSettingRegRst;
|
loopTriggerRegWr : for f in TriggerFieldType loop
|
loopTriggerRegWr : for f in TriggerFieldType loop
|
if triggerEnable(f)='1' and wbStrobe='1' and wbWrEn='1' then
|
if triggerEnable(f)='1' and wbStrobe='1' and wbWrEn='1' then
|
iTriggers(f) <= wbMData(TriggerParams(f).BitLoc);
|
iTriggers(f) <= wbMData(TriggerParams(f).BitLoc);
|
elsif TriggerClr(f)='1' then
|
elsif TriggerClr(f)='1' then
|
iTriggers(f) <= '0';
|
iTriggers(f) <= '0';
|
end if; --Address or clear
|
end if; --Address or clear
|
end loop loopTriggerRegWr;
|
end loop loopTriggerRegWr;
|
end if; --Clk
|
end if; --Clk
|
end process procRegWrite;
|
end process procRegWrite;
|
|
|
|
|