--------------------------------------------------------------------------------
-- File Name: sram16k1.vhd
--------------------------------------------------------------------------------
-- Copyright (C) 1999 Free Model Foundry
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation.
--
-- MODIFICATION HISTORY:
--
-- version: | author: | mod date: | changes made:
-- V1.0 R. Steele 99 JAN 09 Initial release
--
--------------------------------------------------------------------------------
-- PART DESCRIPTION:
--
-- Library: MEM
-- Technology: not ECL
-- Part: SRAM16K1
--
-- Description: 16K X 1 SRAM
--------------------------------------------------------------------------------
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE IEEE.VITAL_timing.ALL;
USE IEEE.VITAL_primitives.ALL;
LIBRARY FMF; USE FMF.gen_utils.ALL;
USE FMF.conversions.ALL;
--------------------------------------------------------------------------------
-- ENTITY DECLARATION
--------------------------------------------------------------------------------
ENTITY sram16k1 IS
GENERIC (
-- tipd delays: interconnect path delays
tipd_OENeg : VitalDelayType01 := VitalZeroDelay01;
tipd_WENeg : VitalDelayType01 := VitalZeroDelay01;
tipd_CENeg : VitalDelayType01 := VitalZeroDelay01;
tipd_CE : VitalDelayType01 := VitalZeroDelay01;
tipd_D0 : VitalDelayType01 := VitalZeroDelay01;
tipd_A0 : VitalDelayType01 := VitalZeroDelay01;
tipd_A1 : VitalDelayType01 := VitalZeroDelay01;
tipd_A2 : VitalDelayType01 := VitalZeroDelay01;
tipd_A3 : VitalDelayType01 := VitalZeroDelay01;
tipd_A4 : VitalDelayType01 := VitalZeroDelay01;
tipd_A5 : VitalDelayType01 := VitalZeroDelay01;
tipd_A6 : VitalDelayType01 := VitalZeroDelay01;
tipd_A7 : VitalDelayType01 := VitalZeroDelay01;
tipd_A8 : VitalDelayType01 := VitalZeroDelay01;
tipd_A9 : VitalDelayType01 := VitalZeroDelay01;
tipd_A10 : VitalDelayType01 := VitalZeroDelay01;
tipd_A11 : VitalDelayType01 := VitalZeroDelay01;
tipd_A12 : VitalDelayType01 := VitalZeroDelay01;
tipd_A13 : VitalDelayType01 := VitalZeroDelay01;
-- tpd delays
tpd_OENeg_D0 : VitalDelayType01Z := UnitDelay01Z;
tpd_CENeg_D0 : VitalDelayType01Z := UnitDelay01Z;
tpd_A0_D0 : VitalDelayType01 := UnitDelay01;
-- tpw values: pulse widths
tpw_WENeg_negedge : VitalDelayType := UnitDelay;
tpw_WENeg_posedge : VitalDelayType := UnitDelay;
-- tsetup values: setup times
tsetup_D0_WENeg : VitalDelayType := UnitDelay;
tsetup_D0_CENeg : VitalDelayType := UnitDelay;
-- thold values: hold times
thold_D0_WENeg : VitalDelayType := UnitDelay;
thold_D0_CENeg : VitalDelayType := UnitDelay;
-- generic control parameters
InstancePath : STRING := DefaultInstancePath;
TimingChecksOn : BOOLEAN := DefaultTimingChecks;
MsgOn : BOOLEAN := DefaultMsgOn;
XOn : BOOLEAN := DefaultXOn;
SeverityMode : SEVERITY_LEVEL := WARNING;
-- For FMF SDF technology file usage
TimingModel : STRING := DefaultTimingModel
);
PORT (
A0 : IN std_logic := 'X';
A1 : IN std_logic := 'X';
A2 : IN std_logic := 'X';
A3 : IN std_logic := 'X';
A4 : IN std_logic := 'X';
A5 : IN std_logic := 'X';
A6 : IN std_logic := 'X';
A7 : IN std_logic := 'X';
A8 : IN std_logic := 'X';
A9 : IN std_logic := 'X';
A10 : IN std_logic := 'X';
A11 : IN std_logic := 'X';
A12 : IN std_logic := 'X';
A13 : IN std_logic := 'X';
D0 : INOUT std_logic := 'X';
OENeg : IN std_logic := 'X';
WENeg : IN std_logic := 'X';
CENeg : IN std_logic := 'X';
CE : IN std_logic := 'X'
);
ATTRIBUTE VITAL_LEVEL0 of sram16k1 : ENTITY IS TRUE;
END sram16k1;
--------------------------------------------------------------------------------
-- ARCHITECTURE DECLARATION
--------------------------------------------------------------------------------
ARCHITECTURE vhdl_behavioral of sram16k1 IS
ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE;
----------------------------------------------------------------------------
-- Note that this style of model departs significantly from the original
-- intent of the VITAL spec. The timing checks section does not generate
-- any 'X' values for output results since the array only stores integer
-- values. So, to check for timing errors one will have to monitor the
-- warning messages closely. Also, the path delay procedures are included
-- in their own processes which are generated as a function of data width.
-- This method together with the behavior block aids in reducing coding
-- by converting the address bus and data bus to vectors. Scalars on the
-- input ports is necessary for backannotation of wire delays.
----------------------------------------------------------------------------
CONSTANT partID : STRING := "SRAM 16K X 1";
CONSTANT MaxData : NATURAL := 1;
CONSTANT TotalLOC : NATURAL := 16383;
CONSTANT HiAbit : NATURAL := 13;
CONSTANT HiDbit : NATURAL := 0;
CONSTANT DataWidth : NATURAL := 1;
SIGNAL D0_ipd : std_ulogic := 'X';
SIGNAL A0_ipd : std_ulogic := 'X';
SIGNAL A1_ipd : std_ulogic := 'X';
SIGNAL A2_ipd : std_ulogic := 'X';
SIGNAL A3_ipd : std_ulogic := 'X';
SIGNAL A4_ipd : std_ulogic := 'X';
SIGNAL A5_ipd : std_ulogic := 'X';
SIGNAL A6_ipd : std_ulogic := 'X';
SIGNAL A7_ipd : std_ulogic := 'X';
SIGNAL A8_ipd : std_ulogic := 'X';
SIGNAL A9_ipd : std_ulogic := 'X';
SIGNAL A10_ipd : std_ulogic := 'X';
SIGNAL A11_ipd : std_ulogic := 'X';
SIGNAL A12_ipd : std_ulogic := 'X';
SIGNAL A13_ipd : std_ulogic := 'X';
SIGNAL OENeg_ipd : std_ulogic := 'X';
SIGNAL WENeg_ipd : std_ulogic := 'X';
SIGNAL CENeg_ipd : std_ulogic := 'X';
SIGNAL CE_ipd : std_ulogic := 'X';
BEGIN
----------------------------------------------------------------------------
-- Wire Delays
----------------------------------------------------------------------------
WireDelay : BLOCK
BEGIN
w_1: VitalWireDelay (OENeg_ipd, OENeg, tipd_OENeg);
w_2: VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg);
w_3: VitalWireDelay (CENeg_ipd, CENeg, tipd_CENeg);
w_4: VitalWireDelay (CE_ipd, CE, tipd_CE);
w_5: VitalWireDelay (D0_ipd, D0, tipd_D0);
w_13: VitalWireDelay (A0_ipd, A0, tipd_A0);
w_14: VitalWireDelay (A1_ipd, A1, tipd_A1);
w_15: VitalWireDelay (A2_ipd, A2, tipd_A2);
w_16: VitalWireDelay (A3_ipd, A3, tipd_A3);
w_17: VitalWireDelay (A4_ipd, A4, tipd_A4);
w_18: VitalWireDelay (A5_ipd, A5, tipd_A5);
w_19: VitalWireDelay (A6_ipd, A6, tipd_A6);
w_20: VitalWireDelay (A7_ipd, A7, tipd_A7);
w_21: VitalWireDelay (A8_ipd, A8, tipd_A8);
w_22: VitalWireDelay (A9_ipd, A9, tipd_A9);
w_23: VitalWireDelay (A10_ipd, A10, tipd_A10);
w_24: VitalWireDelay (A11_ipd, A11, tipd_A11);
w_25: VitalWireDelay (A12_ipd, A12, tipd_A12);
w_26: VitalWireDelay (A13_ipd, A13, tipd_A13);
END BLOCK;
----------------------------------------------------------------------------
-- Main Behavior Block
----------------------------------------------------------------------------
Behavior: BLOCK
PORT (
AddressIn : IN std_logic_vector(HiAbit downto 0);
DataIn : IN std_logic_vector(HiDbit downto 0);
DataOut : OUT std_logic_vector(HiDbit downto 0);
OENegIn : IN std_ulogic := 'X';
WENegIn : IN std_ulogic := 'X';
CENegIn : IN std_ulogic := 'X';
CEIn : IN std_ulogic := 'X'
);
PORT MAP (
DataOut(0) => D0,
DataIn(0) => D0_ipd,
AddressIn(0) => A0_ipd,
AddressIn(1) => A1_ipd,
AddressIn(2) => A2_ipd,
AddressIn(3) => A3_ipd,
AddressIn(4) => A4_ipd,
AddressIn(5) => A5_ipd,
AddressIn(6) => A6_ipd,
AddressIn(7) => A7_ipd,
AddressIn(8) => A8_ipd,
AddressIn(9) => A9_ipd,
AddressIn(10) => A10_ipd,
AddressIn(11) => A11_ipd,
AddressIn(12) => A12_ipd,
AddressIn(13) => A13_ipd,
OENegIn => OENeg_ipd,
WENegIn => WENeg_ipd,
CENegIn => CENeg_ipd,
CEIn => CE_ipd
-- CEIn => OPEN
);
SIGNAL D_zd : std_logic_vector(HiDbit DOWNTO 0);
BEGIN
------------------------------------------------------------------------
-- Behavior Process
------------------------------------------------------------------------
Behavior : PROCESS (OENegIn, WENegIn, CENegIn, CEIn, AddressIn, DataIn)
-- Timing Check Variables
VARIABLE Tviol_D0_WENeg: X01 := '0';
VARIABLE TD_D0_WENeg : VitalTimingDataType;
VARIABLE Tviol_D0_CENeg: X01 := '0';
VARIABLE TD_D0_CENeg : VitalTimingDataType;
VARIABLE Pviol_WENeg : X01 := '0';
VARIABLE PD_WENeg : VitalPeriodDataType := VitalPeriodDataInit;
-- Memory array declaration
TYPE MemStore IS ARRAY (0 to TotalLOC) OF NATURAL
RANGE 0 TO MaxData;
-- Functionality Results Variables
VARIABLE Violation : X01 := '0';
VARIABLE DataDrive : std_logic_vector(HiDbit DOWNTO 0)
:= (OTHERS => 'X');
VARIABLE DataTemp : NATURAL RANGE 0 TO MaxData := 0;
VARIABLE Location : NATURAL RANGE 0 TO TotalLOC := 0;
VARIABLE MemData : MemStore;
-- No Weak Values Variables
VARIABLE OENeg_nwv : UX01 := 'X';
VARIABLE WENeg_nwv : UX01 := 'X';
VARIABLE CENeg_nwv : UX01 := 'X';
VARIABLE CE_nwv : UX01 := 'X';
BEGIN
OENeg_nwv := To_UX01 (s => OENegIn);
WENeg_nwv := To_UX01 (s => WENegIn);
CENeg_nwv := To_UX01 (s => CENegIn);
CE_nwv := To_UX01 (s => CEIn);
-- CE_nwv := '1';
--------------------------------------------------------------------
-- Timing Check Section
--------------------------------------------------------------------
IF (TimingChecksOn) THEN
VitalSetupHoldCheck (
TestSignal => DataIn,
TestSignalName => "Data",
RefSignal => WENeg,
RefSignalName => "WENeg",
SetupHigh => tsetup_D0_WENeg,
SetupLow => tsetup_D0_WENeg,
HoldHigh => thold_D0_WENeg,
HoldLow => thold_D0_WENeg,
CheckEnabled => (CENeg ='0' and CE ='1'and OENeg ='1'),
RefTransition => '/',
HeaderMsg => InstancePath & PartID,
TimingData => TD_D0_WENeg,
XOn => XOn,
MsgOn => MsgOn,
Violation => Tviol_D0_WENeg );
VitalSetupHoldCheck (
TestSignal => DataIn,
TestSignalName => "Data",
RefSignal => CENeg,
RefSignalName => "CENeg",
SetupHigh => tsetup_D0_CENeg,
SetupLow => tsetup_D0_CENeg,
HoldHigh => thold_D0_CENeg,
HoldLow => thold_D0_CENeg,
CheckEnabled => (WENeg ='0' and OENeg ='1'),
RefTransition => '/',
HeaderMsg => InstancePath & PartID,
TimingData => TD_D0_CENeg,
XOn => XOn,
MsgOn => MsgOn,
Violation => Tviol_D0_CENeg );
VitalPeriodPulseCheck (
TestSignal => WENegIn,
TestSignalName => "WENeg",
PulseWidthLow => tpw_WENeg_negedge,
PeriodData => PD_WENeg,
XOn => XOn,
MsgOn => MsgOn,
Violation => Pviol_WENeg,
HeaderMsg => InstancePath & PartID,
CheckEnabled => TRUE );
Violation := Pviol_WENeg OR Tviol_D0_WENeg OR Tviol_D0_CENeg;
ASSERT Violation = '0'
REPORT InstancePath & partID & ": simulation may be" &
" inaccurate due to timing violations"
SEVERITY SeverityMode;
END IF; -- Timing Check Section
--------------------------------------------------------------------
-- Functional Section
--------------------------------------------------------------------
DataDrive := (OTHERS => 'Z');
IF (CE_nwv = '1' AND CENeg_nwv = '0') THEN
IF (OENeg_nwv = '0' OR WENeg_nwv = '0') THEN
Location := To_Nat(AddressIn);
IF (OENeg_nwv = '0' AND WENeg_nwv = '1') THEN
DataTemp := MemData(Location);
DataDrive := To_slv(DataTemp, DataWidth);
ELSE
DataTemp := To_Nat(DataIn);
MemData(Location) := DataTemp;
END IF;
END IF;
END IF;
--------------------------------------------------------------------
-- Output Section
--------------------------------------------------------------------
D_zd <= DataDrive;
END PROCESS;
------------------------------------------------------------------------
-- Path Delay Processes generated as a function of data width
------------------------------------------------------------------------
DataOut_Width : FOR i IN HiDbit DOWNTO 0 GENERATE
DataOut_Delay : PROCESS (D_zd(i))
VARIABLE D_GlitchData:VitalGlitchDataArrayType(HiDbit Downto 0);
BEGIN
VitalPathDelay01Z (
OutSignal => DataOut(i),
OutSignalName => "Data",
OutTemp => D_zd(i),
Mode => OnEvent,
GlitchData => D_GlitchData(i),
Paths => (
0 => (InputChangeTime => OENeg_ipd'LAST_EVENT,
PathDelay => tpd_OENeg_D0,
PathCondition => TRUE),
1 => (InputChangeTime => CENeg_ipd'LAST_EVENT,
PathDelay => tpd_CENeg_D0,
PathCondition => TRUE),
2 => (InputChangeTime => AddressIn(0)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
3 => (InputChangeTime => AddressIn(1)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
4 => (InputChangeTime => AddressIn(2)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
5 => (InputChangeTime => AddressIn(3)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
6 => (InputChangeTime => AddressIn(4)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
7 => (InputChangeTime => AddressIn(5)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
8 => (InputChangeTime => AddressIn(6)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
9 => (InputChangeTime => AddressIn(7)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
10 => (InputChangeTime => AddressIn(8)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
11 => (InputChangeTime => AddressIn(9)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
12 => (InputChangeTime => AddressIn(10)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
13 => (InputChangeTime => AddressIn(11)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
14 => (InputChangeTime => AddressIn(12)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE),
15 => (InputChangeTime => AddressIn(13)'LAST_EVENT,
PathDelay => VitalExtendToFillDelay(tpd_A0_D0),
PathCondition => TRUE)
)
);
END PROCESS;
END GENERATE;
END BLOCK;
END vhdl_behavioral;