async_1Mx16.vhd
640 lines
| 20.5 KiB
| text/x-vhdl
|
VhdlLexer
pellion
|
r287 | --************************************************************************ | ||
--** MODEL : async_1Mx16.vhd ** | ||||
--** COMPANY : Cypress Semiconductor ** | ||||
--** REVISION: 1.0 Created new base model ** | ||||
--************************************************************************ | ||||
-------------------------------------------------------------------------------JC\/ | ||||
--Library ieee,work; | ||||
Library ieee; | ||||
-------------------------------------------------------------------------------JC/\ | ||||
Use IEEE.Std_Logic_1164.All; | ||||
use IEEE.Std_Logic_unsigned.All; | ||||
-------------------------------------------------------------------------------JC\/ | ||||
--use work.package_timing.all; | ||||
--use work.package_utility.all; | ||||
Library lpp; | ||||
use lpp.package_timing.all; | ||||
use lpp.package_utility.all; | ||||
-------------------------------------------------------------------------------JC/\ | ||||
------------------------ | ||||
-- Entity Description | ||||
------------------------ | ||||
Entity CY7C1061DV33 is | ||||
generic | ||||
(ADDR_BITS : integer := 20; | ||||
DATA_BITS : integer := 16; | ||||
depth : integer := 1048576; | ||||
TimingInfo : BOOLEAN := TRUE; | ||||
TimingChecks : std_logic := '1' | ||||
); | ||||
Port ( | ||||
CE1_b : IN Std_Logic; -- Chip Enable CE1# | ||||
CE2 : IN Std_Logic; -- Chip Enable CE2 | ||||
WE_b : IN Std_Logic; -- Write Enable WE# | ||||
OE_b : IN Std_Logic; -- Output Enable OE# | ||||
BHE_b : IN std_logic; -- Byte Enable High BHE# | ||||
BLE_b : IN std_logic; -- Byte Enable Low BLE# | ||||
A : IN Std_Logic_Vector(addr_bits-1 downto 0); -- Address Inputs A | ||||
DQ : INOUT Std_Logic_Vector(DATA_BITS-1 downto 0):=(others=>'Z') -- Read/Write Data IO | ||||
); | ||||
End CY7C1061DV33; | ||||
----------------------------- | ||||
-- End Entity Description | ||||
----------------------------- | ||||
----------------------------- | ||||
-- Architecture Description | ||||
----------------------------- | ||||
Architecture behave_arch Of CY7C1061DV33 Is | ||||
Type mem_array_type Is array (depth-1 downto 0) of std_logic_vector(DATA_BITS-1 downto 0); | ||||
signal write_enable : std_logic; | ||||
signal read_enable : std_logic; | ||||
signal byte_enable : std_logic; | ||||
signal CE_b :std_logic; | ||||
signal data_skew : Std_Logic_Vector(DATA_BITS-1 downto 0); | ||||
signal address_internal,address_skew: Std_Logic_Vector(addr_bits-1 downto 0); | ||||
constant tSD_dataskew : time := tSD - 1 ns; | ||||
constant tskew :time := 1 ns; | ||||
begin | ||||
CE_b <= CE1_b or not(CE2); | ||||
byte_enable <= not(BHE_b and BLE_b); | ||||
write_enable <= not(CE1_b) and CE2 and not(WE_b) and not(BHE_b and BLE_b); | ||||
read_enable <= not(CE1_b) and CE2 and (WE_b) and not(OE_b) and not(BHE_b and BLE_b); | ||||
data_skew <= DQ after 1 ns; -- changed on feb 15 | ||||
address_skew <= A after 1 ns; | ||||
process (OE_b) | ||||
begin | ||||
if (OE_b'event and OE_b = '1' and write_enable /= '1') then | ||||
DQ <=(others=>'Z') after tHZOE; | ||||
end if; | ||||
end process; | ||||
process (CE_b) | ||||
begin | ||||
if (CE_b'event and CE_b = '1') then | ||||
DQ <=(others=>'Z') after tHZCE; | ||||
end if; | ||||
end process; | ||||
process (write_enable'delayed(tHA)) | ||||
begin | ||||
if (write_enable'delayed(tHA) = '0' and TimingInfo) then | ||||
assert (A'last_event = 0 ns) or (A'last_event > tHA) | ||||
report "Address hold time tHA violated"; | ||||
end if; | ||||
end process; | ||||
process (write_enable'delayed(tHD)) | ||||
begin | ||||
if (write_enable'delayed(tHD) = '0' and TimingInfo) then | ||||
assert (DQ'last_event > tHD) or (DQ'last_event = 0 ns) | ||||
report "Data hold time tHD violated"; | ||||
end if; | ||||
end process; | ||||
-- main process | ||||
process | ||||
VARIABLE mem_array: mem_array_type; | ||||
--- Variables for timing checks | ||||
VARIABLE tPWE_chk : TIME := -10 ns; | ||||
VARIABLE tAW_chk : TIME := -10 ns; | ||||
VARIABLE tSD_chk : TIME := -10 ns; | ||||
VARIABLE tRC_chk : TIME := 0 ns; | ||||
VARIABLE tBAW_chk : TIME := 0 ns; | ||||
VARIABLE tBBW_chk : TIME := 0 ns; | ||||
VARIABLE tBCW_chk : TIME := 0 ns; | ||||
VARIABLE tBDW_chk : TIME := 0 ns; | ||||
VARIABLE tSA_chk : TIME := 0 ns; | ||||
VARIABLE tSA_skew : TIME := 0 ns; | ||||
VARIABLE tAint_chk : TIME := -10 ns; | ||||
VARIABLE write_flag : BOOLEAN := TRUE; | ||||
VARIABLE accesstime : TIME := 0 ns; | ||||
begin | ||||
if (address_skew'event) then | ||||
tSA_skew := NOW; | ||||
end if; | ||||
-- start of write | ||||
if (write_enable = '1' and write_enable'event) then | ||||
DQ(DATA_BITS-1 downto 0)<=(others=>'Z') after tHZWE; | ||||
if (A'last_event >= tSA) then | ||||
address_internal <= A; | ||||
tPWE_chk := NOW; | ||||
tAW_chk := A'last_event; | ||||
tAint_chk := NOW; | ||||
write_flag := TRUE; | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Address setup violated"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
-- end of write (with CE high or WE high) | ||||
elsif (write_enable = '0' and write_enable'event) then | ||||
--- check for pulse width | ||||
if (NOW - tPWE_chk >= tPWE or NOW - tPWE_chk <= 0.1 ns or NOW = 0 ns) then | ||||
--- pulse width OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Pulse Width violation"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
if (NOW > 0 ns) then | ||||
if (tSA_skew - tAint_chk > tskew ) then | ||||
assert FALSE | ||||
report "Negative address setup"; | ||||
write_flag := FALSE; | ||||
end if; | ||||
end if; | ||||
--- check for address setup with write end, i.e., tAW | ||||
if (NOW - tAW_chk >= tAW or NOW = 0 ns) then | ||||
--- tAW OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Address setup tAW violation"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
--- check for data setup with write end, i.e., tSD | ||||
if (NOW - tSD_chk >= tSD_dataskew or NOW - tSD_chk <= 0.1 ns or NOW = 0 ns) then | ||||
--- tSD OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Data setup tSD violation"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
-- perform write operation if no violations | ||||
if (write_flag = TRUE) then | ||||
if (BLE_b = '1' and BLE_b'last_event = write_enable'last_event and NOW /= 0 ns) then | ||||
mem_array(conv_integer1(address_internal))(7 downto 0) := data_skew(7 downto 0); | ||||
end if; | ||||
if (BHE_b = '1' and BHE_b'last_event = write_enable'last_event and NOW /= 0 ns) then | ||||
mem_array(conv_integer1(address_internal))(15 downto 8) := data_skew(15 downto 8); | ||||
end if; | ||||
if (BLE_b = '0' and NOW - tBAW_chk >= tBW) then | ||||
mem_array(conv_integer1(address_internal))(7 downto 0) := data_skew(7 downto 0); | ||||
elsif (NOW - tBAW_chk < tBW and NOW - tBAW_chk > 0.1 ns and NOW > 0 ns) then | ||||
assert FALSE report "Insufficient pulse width for lower byte to be written"; | ||||
end if; | ||||
if (BHE_b = '0' and NOW - tBBW_chk >= tBW) then | ||||
mem_array(conv_integer1(address_internal))(15 downto 8) := data_skew(15 downto 8); | ||||
elsif (NOW - tBBW_chk < tBW and NOW - tBBW_chk > 0.1 ns and NOW > 0 ns) then | ||||
assert FALSE report "Insufficient pulse width for higher byte to be written"; | ||||
end if; | ||||
end if; | ||||
-- end of write (with BLE high) | ||||
elsif (BLE_b'event and not(BHE_b'event) and write_enable = '1') then | ||||
if (BLE_b = '0') then | ||||
--- Reset timing variables | ||||
tAW_chk := A'last_event; | ||||
tBAW_chk := NOW; | ||||
write_flag := TRUE; | ||||
elsif (BLE_b = '1') then | ||||
--- check for pulse width | ||||
if (NOW - tPWE_chk >= tPWE) then | ||||
--- tPWE OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Pulse Width violation"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
--- check for address setup with write end, i.e., tAW | ||||
if (NOW - tAW_chk >= tAW) then | ||||
--- tAW OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Address setup tAW violation for Lower Byte Write"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
--- check for byte write setup with write end, i.e., tBW | ||||
if (NOW - tBAW_chk >= tBW) then | ||||
--- tBW OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Lower Byte setup tBW violation"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
--- check for data setup with write end, i.e., tSD | ||||
if (NOW - tSD_chk >= tSD_dataskew or NOW - tSD_chk <= 0.1 ns or NOW = 0 ns) then | ||||
--- tSD OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Data setup tSD violation for Lower Byte Write"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
--- perform WRITE operation if no violations | ||||
if (write_flag = TRUE) then | ||||
mem_array(conv_integer1(address_internal))(7 downto 0) := data_skew(7 downto 0); | ||||
if (BHE_b = '0') then | ||||
mem_array(conv_integer1(address_internal))(15 downto 8) := data_skew(15 downto 8); | ||||
end if; | ||||
end if; | ||||
--- Reset timing variables | ||||
tAW_chk := A'last_event; | ||||
tBAW_chk := NOW; | ||||
write_flag := TRUE; | ||||
end if; | ||||
-- end of write (with BHE high) | ||||
elsif (BHE_b'event and not(BLE_b'event) and write_enable = '1') then | ||||
if (BHE_b = '0') then | ||||
--- Reset timing variables | ||||
tAW_chk := A'last_event; | ||||
tBBW_chk := NOW; | ||||
write_flag := TRUE; | ||||
elsif (BHE_b = '1') then | ||||
--- check for pulse width | ||||
if (NOW - tPWE_chk >= tPWE) then | ||||
--- tPWE OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Pulse Width violation"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
--- check for address setup with write end, i.e., tAW | ||||
if (NOW - tAW_chk >= tAW) then | ||||
--- tAW OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Address setup tAW violation for Upper Byte Write"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
--- check for byte setup with write end, i.e., tBW | ||||
if (NOW - tBBW_chk >= tBW) then | ||||
--- tBW OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Upper Byte setup tBW violation"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
--- check for data setup with write end, i.e., tSD | ||||
if (NOW - tSD_chk >= tSD_dataskew or NOW - tSD_chk <= 0.1 ns or NOW = 0 ns) then | ||||
--- tSD OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Data setup tSD violation for Upper Byte Write"; | ||||
end if; | ||||
write_flag := FALSE; | ||||
end if; | ||||
--- perform WRITE operation if no violations | ||||
if (write_flag = TRUE) then | ||||
mem_array(conv_integer1(address_internal))(15 downto 8) := data_skew(15 downto 8); | ||||
if (BLE_b = '0') then | ||||
mem_array(conv_integer1(address_internal))(7 downto 0) := data_skew(7 downto 0); | ||||
end if; | ||||
end if; | ||||
--- Reset timing variables | ||||
tAW_chk := A'last_event; | ||||
tBBW_chk := NOW; | ||||
write_flag := TRUE; | ||||
end if; | ||||
end if; | ||||
--- END OF WRITE | ||||
if (data_skew'event and read_enable /= '1') then | ||||
tSD_chk := NOW; | ||||
end if; | ||||
--- START of READ | ||||
--- Tri-state the data bus if CE or OE disabled | ||||
if (read_enable = '0' and read_enable'event) then | ||||
if (OE_b'last_event >= CE_b'last_event) then | ||||
DQ <=(others=>'Z') after tHZCE; | ||||
elsif (CE_b'last_event > OE_b'last_event) then | ||||
DQ <=(others=>'Z') after tHZOE; | ||||
end if; | ||||
end if; | ||||
--- Address-controlled READ operation | ||||
if (A'event) then | ||||
if (A'last_event = CE_b'last_event and CE_b = '1') then | ||||
DQ <=(others=>'Z') after tHZCE; | ||||
end if; | ||||
if (NOW - tRC_chk >= tRC or NOW - tRC_chk <= 0.1 ns or tRC_chk = 0 ns) then | ||||
--- tRC OK, do nothing | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Read Cycle time tRC violation"; | ||||
end if; | ||||
end if; | ||||
if (read_enable = '1') then | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0) <= mem_array (conv_integer1(A))(7 downto 0) after tAA; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8) <= mem_array (conv_integer1(A))(15 downto 8) after tAA; | ||||
end if; | ||||
tRC_chk := NOW; | ||||
end if; | ||||
if (write_enable = '1') then | ||||
--- do nothing | ||||
end if; | ||||
end if; | ||||
if (read_enable = '0' and read_enable'event) then | ||||
DQ <=(others=>'Z') after tHZCE; | ||||
if (NOW - tRC_chk >= tRC or tRC_chk = 0 ns or A'last_event = read_enable'last_event) then | ||||
--- tRC_chk needs to be reset when read ends | ||||
tRC_CHK := 0 ns; | ||||
else | ||||
if (TimingInfo) then | ||||
assert FALSE | ||||
report "Read Cycle time tRC violation"; | ||||
end if; | ||||
tRC_CHK := 0 ns; | ||||
end if; | ||||
end if; | ||||
--- READ operation triggered by CE/OE/BHE/BLE | ||||
if (read_enable = '1' and read_enable'event) then | ||||
tRC_chk := NOW; | ||||
--- CE triggered READ | ||||
if (CE_b'last_event = read_enable'last_event ) then -- changed rev2 | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after tACE; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after tACE; | ||||
end if; | ||||
end if; | ||||
--- OE triggered READ | ||||
if (OE_b'last_event = read_enable'last_event) then | ||||
-- if address or CE changes before OE such that tAA/tACE > tDOE | ||||
if (CE_b'last_event < tACE - tDOE and A'last_event < tAA - tDOE) then | ||||
if (A'last_event < CE_b'last_event) then | ||||
accesstime:=tAA-A'last_event; | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after accesstime; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after accesstime; | ||||
end if; | ||||
else | ||||
accesstime:=tACE-CE_b'last_event; | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after accesstime; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after accesstime; | ||||
end if; | ||||
end if; | ||||
-- if address changes before OE such that tAA > tDOE | ||||
elsif (A'last_event < tAA - tDOE) then | ||||
accesstime:=tAA-A'last_event; | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after accesstime; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after accesstime; | ||||
end if; | ||||
-- if CE changes before OE such that tACE > tDOE | ||||
elsif (CE_b'last_event < tACE - tDOE) then | ||||
accesstime:=tACE-CE_b'last_event; | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after accesstime; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after accesstime; | ||||
end if; | ||||
-- if OE changes such that tDOE > tAA/tACE | ||||
else | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after tDOE; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after tDOE; | ||||
end if; | ||||
end if; | ||||
end if; | ||||
--- END of OE triggered READ | ||||
--- BLE/BHE triggered READ | ||||
if (BLE_b'last_event = read_enable'last_event or BHE_b'last_event = read_enable'last_event) then | ||||
-- if address or CE changes before BHE/BLE such that tAA/tACE > tDBE | ||||
if (CE_b'last_event < tACE - tDBE and A'last_event < tAA - tDBE) then | ||||
if (A'last_event < BLE_b'last_event) then | ||||
accesstime:=tAA-A'last_event; | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after accesstime; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after accesstime; | ||||
end if; | ||||
else | ||||
accesstime:=tACE-CE_b'last_event; | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after accesstime; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after accesstime; | ||||
end if; | ||||
end if; | ||||
-- if address changes before BHE/BLE such that tAA > tDBE | ||||
elsif (A'last_event < tAA - tDBE) then | ||||
accesstime:=tAA-A'last_event; | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after accesstime; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after accesstime; | ||||
end if; | ||||
-- if CE changes before BHE/BLE such that tACE > tDBE | ||||
elsif (CE_b'last_event < tACE - tDBE) then | ||||
accesstime:=tACE-CE_b'last_event; | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after accesstime; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after accesstime; | ||||
end if; | ||||
-- if BHE/BLE changes such that tDBE > tAA/tACE | ||||
else | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after tDBE; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after tDBE; | ||||
end if; | ||||
end if; | ||||
end if; | ||||
-- END of BHE/BLE controlled READ | ||||
if (WE_b'last_event = read_enable'last_event) then | ||||
if (BLE_b = '0') then | ||||
DQ (7 downto 0)<= mem_array (conv_integer1(A)) (7 downto 0) after tACE; | ||||
end if; | ||||
if (BHE_b = '0') then | ||||
DQ (15 downto 8)<= mem_array (conv_integer1(A)) (15 downto 8) after tACE; | ||||
end if; | ||||
end if; | ||||
end if; | ||||
--- END OF CE/OE/BHE/BLE controlled READ | ||||
--- If either BHE or BLE toggle during read mode | ||||
if (BLE_b'event and BLE_b = '0' and read_enable = '1' and not(read_enable'event)) then | ||||
DQ (7 downto 0) <= mem_array (conv_integer1(A)) (7 downto 0) after tDBE; | ||||
end if; | ||||
if (BHE_b'event and BHE_b = '0' and read_enable = '1' and not(read_enable'event)) then | ||||
DQ (15 downto 8) <= mem_array (conv_integer1(A)) (15 downto 8) after tDBE; | ||||
end if; | ||||
--- tri-state bus depending on BHE/BLE | ||||
if (BLE_b'event and BLE_b = '1') then | ||||
DQ (7 downto 0) <= (others=>'Z') after tHZBE; | ||||
end if; | ||||
if (BHE_b'event and BHE_b = '1') then | ||||
DQ (15 downto 8) <=(others=>'Z') after tHZBE; | ||||
end if; | ||||
wait on write_enable, A, read_enable, DQ, BLE_b, BHE_b, data_skew,address_skew; | ||||
end process; | ||||
end behave_arch; | ||||