--FILENAME: wgenerator_SN54LS161.vhd -- -- DISCLAIMER -- -- This code is the sole property of the Institute for Technology -- Development (ITD), Jackson, Mississippi, and is distributed for -- the purpose of providing examples of VHDL models written to -- modeling standards. This code may not be used for commercial -- purposes, and may not be redistributed without permission from -- the Institute for Technology Development. ITD assumes no -- responsibility for errors, omissions, uses made, or decisions -- based on its use. No warranties, expressed or implied, are given. -- -- This is a modified IEEE WAVES package. It was written specifically -- to apply test vectors to the model being tested. -- -- ------------------------------------------------------------------ library STD_PACK ; use STD_PACK.BASICDEFS.all ; use STD.Textio.all ; library FRAMES ; use FRAMES.Waves_Frames.all ; library DEVICE ; use DEVICE.Waves_Device.all ; use DEVICE.Waves_Objects.all ; library EVENTS ; use EVENTS.Waves_Utilities.all ; package body wgenerator_SN54LS161 is constant O_Pins : PINSET := NEW_PINSET (( TP_qa, TP_qb, TP_qc, TP_qd, TP_rc )) ; constant I_Pins : PINSET := ALL_PINS and not O_PINS ; constant EMPTY_EVENT : INTEGER := -1 ; procedure SN54LS161_Test( signal Connect : inout Waves_Port_List) is constant Period : Time := 100 ns ; constant Uncertainty_Pct : real := 0.05 ; constant TDelay : EVENT_TIME := ETIME (Period - Uncertainty_Pct * Period); constant FSA : FRAME_SET_ARRAY := ADD_FRAME_SET_ARRAY ( NEW_FRAME_SET_ARRAY ( I_PINS, INPUT_FRAMES), NEW_FRAME_SET_ARRAY ( O_PINS, STROBED_OUTPUT_FRAMES(TDelay)) ); variable TD1 : TIME_DATA := NEW_TIME_DATA ( FSA ) ; variable T1 : WAVE_TIMING := (Period, TD1) ; constant Pulse : Time := 1 ns ; constant PulseDelay : EVENT_TIME := ETIME (Pulse - Uncertainty_Pct * Pulse); constant FSA_pulse : FRAME_SET_ARRAY := ADD_FRAME_SET_ARRAY ( NEW_FRAME_SET_ARRAY ( I_PINS, INPUT_FRAMES), NEW_FRAME_SET_ARRAY ( O_PINS, STROBED_OUTPUT_FRAMES(PulseDelay)) ); variable TD1_pulse : TIME_DATA := NEW_TIME_DATA ( FSA_pulse ) ; variable TP : WAVE_TIMING := (Pulse, TD1_pulse) ; -- Order of signals: -- -- (qa, qb, qc, qd, rc, -- clr, clk, a, b, c, d, enp, load, ent) -- variable CLEAR_TV_SET : WAVE_SLICE_LIST (1 to 2) := ( ( "00000" & "000000000", T1), ( "00000" & "100000000", T1) ) ; variable CLK_PULSE : WAVE_SLICE_LIST (1 to 6) := ( ( "00000" & "001111010", T1), ( "00000" & "101111000", T1), ( "XXXX0" & "1P1111000", T1), ( "00000" & "011111000", T1), ( "00000" & "111111000", T1), ( "XXXX0" & "1N1111000", T1) ) ; variable CLR_PULSE : WAVE_SLICE_LIST (1 to 4) := ( ( "00000" & "001111010", T1), ( "00000" & "P01111010", T1), ( "00000" & "101111010", T1), ( "XXXX0" & "N01111010", T1) ) ; variable DATA_SETUP : WAVE_SLICE_LIST (1 to 4) := ( ( "00000" & "000000010", T1), ( "00000" & "100000000", T1), ( "?????" & "101111000", TP), ( "XXXX0" & "111111000", T1) ) ; variable ENABLE_SETUP : WAVE_SLICE_LIST (1 to 8) := ( ( "00000" & "000000110", T1), ( "00000" & "100000110", T1), ( "?????" & "100000111", TP), ( "XXXXX" & "110000111", T1), ( "00000" & "000000011", T1), ( "00000" & "100000011", T1), ( "?????" & "100000111", TP), ( "XXXXX" & "110000111", T1) ) ; variable LOAD_SETUP : WAVE_SLICE_LIST (1 to 10) := ( ( "00000" & "000000010", T1), ( "00000" & "100000010", T1), ( "?????" & "100000000", TP), ( "XXXX0" & "110000000", T1), ( "00000" & "001111000", T1), ( "00000" & "101111000", T1), ( "11110" & "111111000", T1), ( "11110" & "100000000", T1), ( "?????" & "100000010", TP), ( "XXXX0" & "110000010", T1) ) ; -- variable CLEAR_SETUP : WAVE_SLICE_LIST (1 to 3) := ( -- -- ( "00000" -- & "000000111", T1), -- -- ( "?????" -- & "100000111", TP), -- -- ( "XXXXX" -- & "110000111", T1) -- ) ; variable HOLD_TIME : WAVE_SLICE_LIST (1 to 12) := ( ( "00000" & "000000111", T1), ( "00000" & "100000111", T1), ( "?????" & "110000111", TP), ( "XXXXX" & "110000101", T1), ( "00000" & "000110101", T1), ( "00000" & "100110101", T1), ( "?????" & "110110101", TP), ( "XXXXX" & "111001101", T1), ( "00000" & "000000111", T1), ( "00000" & "100000111", T1), ( "?????" & "110000111", TP), ( "XXXX0" & "110000010", T1) ) ; variable UNKNOWNS : WAVE_SLICE_LIST (1 to 11) := ( ( "00000" & "000000111", T1), ( "XXXXX" & "X00000111", T1), ( "00000" & "000000111", T1), ( "00000" & "100000111", T1), ( "XXXXX" & "1X0000111", T1), ( "00000" & "000000111", T1), ( "00000" & "100000111", T1), ( "XXXXX" & "110000X11", T1), ( "00000" & "000000111", T1), ( "00000" & "1000001X1", T1), ( "XXXXX" & "1100001X1", T1) ) ; variable NORMAL : WAVE_SLICE_LIST (1 to 39) := ( ( "00000" & "001111111", T1), ( "00000" & "101111111", T1), ( "00000" & "101111101", T1), ( "11111" & "111111101", T1), ( "11111" & "111111111", T1), ( "11111" & "101111111", T1), ( "00000" & "111111111", T1), ( "00000" & "101111111", T1), ( "10000" & "111111111", T1), ( "10000" & "101111111", T1), ( "01000" & "111111111", T1), ( "01000" & "101111111", T1), ( "11000" & "111111111", T1), ( "11000" & "101111111", T1), ( "00100" & "111111111", T1), ( "00100" & "101111111", T1), ( "10100" & "111111111", T1), ( "10100" & "101111111", T1), ( "01100" & "111111111", T1), ( "01100" & "101111111", T1), ( "11100" & "111111111", T1), ( "11100" & "101111111", T1), ( "00010" & "111111111", T1), ( "00010" & "101111111", T1), ( "10010" & "111111111", T1), ( "10010" & "101111111", T1), ( "01010" & "111111111", T1), ( "01010" & "101111111", T1), ( "11010" & "111111111", T1), ( "11010" & "101111111", T1), ( "00110" & "111111111", T1), ( "00110" & "101111111", T1), ( "10110" & "111111111", T1), ( "10110" & "101111111", T1), ( "01110" & "111111111", T1), ( "01110" & "101111111", T1), ( "11111" & "111111111", T1), ( "11111" & "101111111", T1), ( "11110" & "101111110", T1) ) ; begin assert false report "Clear Counter" severity note ; APPLY_LIST(CONNECT, CLEAR_TV_SET) ; assert false report "Clock Pulse Width Violation" severity note ; APPLY_LIST(CONNECT, CLK_PULSE) ; assert false report "Clear Pulse Width Violation" severity note ; APPLY_LIST(CONNECT, CLR_PULSE) ; assert false report "Data Setup Time Violation" severity note ; APPLY_LIST(CONNECT, DATA_SETUP) ; assert false report "Enable Setup Time Violation" severity note ; APPLY_LIST(CONNECT, ENABLE_SETUP) ; assert false report "Load Setup Time Violation" severity note ; APPLY_LIST(CONNECT, LOAD_SETUP) ; -- -- assert false -- report "Clear Inactive Setup Time Violation" -- severity note ; -- APPLY_LIST(CONNECT, CLEAR_SETUP) ; assert false report "Hold Time Violation" severity note ; APPLY_LIST(CONNECT, HOLD_TIME) ; assert false report "Unknown Values on Control Inputs" severity note ; APPLY_LIST(CONNECT, UNKNOWNS) ; assert false report "Normal Operation" severity note ; APPLY_LIST(CONNECT, NORMAL) ; end ; procedure SN54LS161_Test_From_File( signal Connect : out Waves_Port_List ; Input_File_Name : String) is ---------------------------------------------------------------------- -- The following declarations are used when only the PERIOD field is -- read from the external file. ---------------------------------------------------------------------- constant FSA : FRAME_SET_ARRAY := ADD_FRAME_SET_ARRAY ( NEW_FRAME_SET_ARRAY (I_PINS, INPUT_FRAMES), NEW_FRAME_SET_ARRAY (O_PINS, OUTPUT_FRAMES) ); variable PERIOD_TD : TIME_DATA := NEW_TIME_DATA (FSA) ; ---------------------------------------------------------------------- -- The following declarations are used when only the INDEX field is -- read from the external file. ---------------------------------------------------------------------- constant Period1 : Time := 100 ns ; constant Uncertainty_Pct1 : real := 0.05 ; constant TDelay1 : EVENT_TIME := ETIME (Period1 - (Uncertainty_Pct1 * Period1)); constant FSA1 : FRAME_SET_ARRAY := ADD_FRAME_SET_ARRAY ( NEW_FRAME_SET_ARRAY ( I_PINS, INPUT_FRAMES), NEW_FRAME_SET_ARRAY ( O_PINS, STROBED_OUTPUT_FRAMES(TDelay1)) ); variable INDEX_TD1 : TIME_DATA := NEW_TIME_DATA ( FSA1 ) ; constant Period2 : Time := 1 ns ; constant Uncertainty_Pct2 : real := 0.05 ; constant TDelay2 : EVENT_TIME := ETIME (Period2 - Uncertainty_Pct2 * Period2); constant FSA2 : FRAME_SET_ARRAY := ADD_FRAME_SET_ARRAY ( NEW_FRAME_SET_ARRAY ( I_PINS, INPUT_FRAMES), NEW_FRAME_SET_ARRAY ( O_PINS, STROBED_OUTPUT_FRAMES(TDelay2)) ); variable INDEX_TD2 : TIME_DATA := NEW_TIME_DATA ( FSA2 ) ; variable SN54LS161_TIMING : WAVE_TIMING_LIST (1 to 2) := ( (Period1, INDEX_TD1), (Period2, INDEX_TD2) ) ; ---------------------------------------------------------------------- -- The following declarations are used when both the PERIOD field and -- the INDEX field are read from the external file. The uncertainty -- periods are the same as those used when only the INDEX field is set. ---------------------------------------------------------------------- variable SN54LS161_UNCERTAINTY : TIME_DATA_LIST (1 to 2) := ( INDEX_TD1, INDEX_TD2 ) ; ---------------------------------------------------------------------- -- The following declarations are used when neither the PERIOD field -- nor the INDEX field is read from the external file. ---------------------------------------------------------------------- constant Default_Period : Time := 100 ns ; constant Uncertainty_Pct : real := 0.05 ; constant Default_TDelay : EVENT_TIME := ETIME (Default_Period - Uncertainty_Pct * Default_Period); constant Default_FSA : FRAME_SET_ARRAY := ADD_FRAME_SET_ARRAY ( NEW_FRAME_SET_ARRAY ( I_PINS, INPUT_FRAMES), NEW_FRAME_SET_ARRAY ( O_PINS, STROBED_OUTPUT_FRAMES(Default_TDelay)) ); variable TD2 : TIME_DATA := NEW_TIME_DATA ( Default_FSA ) ; variable DEFAULT_TIMING : WAVE_TIMING := (Default_Period, TD2) ; --------------------------------------------------------------------- file Input_File : Text is in Input_File_Name ; variable SN54LS161_FILE_SLICE : FILE_SLICE ; variable WAVEFORM : WAVE_SLICE ; variable use_period_and_index : BOOLEAN := FALSE; variable use_period : BOOLEAN := FALSE; variable use_index : BOOLEAN := FALSE; begin while not SN54LS161_FILE_SLICE.END_OF_FILE loop READ_FILE_SLICE(Input_File, SN54LS161_FILE_SLICE); if (SN54LS161_FILE_SLICE.PERIOD_SET = TRUE) then if (SN54LS161_FILE_SLICE.INDEX_SET = TRUE) then use_period_and_index := TRUE; use_period := FALSE; use_index := FALSE; else use_period := TRUE; use_period_and_index := FALSE; use_index := FALSE; end if; elsif (SN54LS161_FILE_SLICE.INDEX_SET = TRUE) then use_index := TRUE; use_period_and_index := FALSE; use_period := FALSE; end if; if (use_period_and_index = TRUE) then assert SN54LS161_FILE_SLICE.INDEX >= SN54LS161_UNCERTAINTY'LEFT and SN54LS161_FILE_SLICE.INDEX <= SN54LS161_UNCERTAINTY'RIGHT report "Error - Index out of range in file format" severity ERROR; WAVEFORM := (SN54LS161_FILE_SLICE.CODES, (SN54LS161_FILE_SLICE.PERIOD, SN54LS161_UNCERTAINTY(SN54LS161_FILE_SLICE.INDEX))); APPLY_SLICE(CONNECT, WAVEFORM) ; elsif (use_period = TRUE) then WAVEFORM := (SN54LS161_FILE_SLICE.CODES, (SN54LS161_FILE_SLICE.PERIOD, PERIOD_TD)); APPLY_SLICE(CONNECT, WAVEFORM) ; elsif (use_index = TRUE) then assert SN54LS161_FILE_SLICE.INDEX >= SN54LS161_TIMING'LEFT and SN54LS161_FILE_SLICE.INDEX <= SN54LS161_TIMING'RIGHT report "Error - Index out of range in file format" severity ERROR; WAVEFORM := (SN54LS161_FILE_SLICE.CODES, SN54LS161_TIMING(SN54LS161_FILE_SLICE.INDEX)); APPLY_SLICE(CONNECT, WAVEFORM) ; else WAVEFORM := (SN54LS161_FILE_SLICE.CODES, DEFAULT_TIMING); APPLY_SLICE(CONNECT, WAVEFORM) ; end if; end loop ; end ; end wgenerator_SN54LS161 ;