-- Copyright (C) 1991-2015 Altera Corporation. All rights reserved. -- Your use of Altera Corporation's design tools, logic functions -- and other software and tools, and its AMPP partner logic -- functions, and any output files from any of the foregoing -- (including device programming or simulation files), and any -- associated documentation or information are expressly subject -- to the terms and conditions of the Altera Program License -- Subscription Agreement, the Altera Quartus II License Agreement, -- the Altera MegaCore Function License Agreement, or other -- applicable license agreement, including, without limitation, -- that your use is for the sole purpose of programming logic -- devices manufactured by Altera and sold by Altera or its -- authorized distributors. Please refer to the applicable -- agreement for further details. -- Quartus II 15.0.0 Build 145 04/22/2015 library IEEE; use IEEE.std_logic_1164.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; package cycloneive_atom_pack is function str_to_bin (lut_mask : string ) return std_logic_vector; function product(list : std_logic_vector) return std_logic ; function alt_conv_integer(arg : in std_logic_vector) return integer; -- default generic values CONSTANT DefWireDelay : VitalDelayType01 := (0 ns, 0 ns); CONSTANT DefPropDelay01 : VitalDelayType01 := (0 ns, 0 ns); CONSTANT DefPropDelay01Z : VitalDelayType01Z := (OTHERS => 0 ns); CONSTANT DefSetupHoldCnst : TIME := 0 ns; CONSTANT DefPulseWdthCnst : TIME := 0 ns; -- default control options -- CONSTANT DefGlitchMode : VitalGlitchKindType := OnEvent; -- change default delay type to Transport : for spr 68748 CONSTANT DefGlitchMode : VitalGlitchKindType := VitalTransport; CONSTANT DefGlitchMsgOn : BOOLEAN := FALSE; CONSTANT DefGlitchXOn : BOOLEAN := FALSE; CONSTANT DefMsgOnChecks : BOOLEAN := TRUE; CONSTANT DefXOnChecks : BOOLEAN := TRUE; -- output strength mapping -- UX01ZWHL- CONSTANT PullUp : VitalOutputMapType := "UX01HX01X"; CONSTANT NoPullUpZ : VitalOutputMapType := "UX01ZX01X"; CONSTANT PullDown : VitalOutputMapType := "UX01LX01X"; -- primitive result strength mapping CONSTANT wiredOR : VitalResultMapType := ( 'U', 'X', 'L', '1' ); CONSTANT wiredAND : VitalResultMapType := ( 'U', 'X', '0', 'H' ); CONSTANT L : VitalTableSymbolType := '0'; CONSTANT H : VitalTableSymbolType := '1'; CONSTANT x : VitalTableSymbolType := '-'; CONSTANT S : VitalTableSymbolType := 'S'; CONSTANT R : VitalTableSymbolType := '/'; CONSTANT U : VitalTableSymbolType := 'X'; CONSTANT V : VitalTableSymbolType := 'B'; -- valid clock signal (non-rising) -- Declare array types for CAM_SLICE TYPE cycloneive_mem_data IS ARRAY (0 to 31) of STD_LOGIC_VECTOR (31 downto 0); function int2str( value : integer ) return string; function map_x_to_0 (value : std_logic) return std_logic; function SelectDelay (CONSTANT Paths: IN VitalPathArray01Type) return TIME; function int2bit (arg : boolean) return std_logic; function int2bit (arg : integer) return std_logic; function bin2int (s : bit_vector) return integer; function bin2int (s : bit) return integer; function bin2int (s : std_logic_vector) return integer; function bin2int (s : std_logic) return integer; function int2bin (arg : integer; size : integer) return std_logic_vector; function int2bin (arg : boolean; size : integer) return std_logic_vector; function calc_sum_len( widtha : integer; widthb : integer) return integer; end cycloneive_atom_pack; library IEEE; use IEEE.std_logic_1164.all; package body cycloneive_atom_pack is type masklength is array (4 downto 1) of std_logic_vector(3 downto 0); function str_to_bin (lut_mask : string) return std_logic_vector is variable slice : masklength := (OTHERS => "0000"); variable mask : std_logic_vector(15 downto 0); begin for i in 1 to lut_mask'length loop case lut_mask(i) is when '0' => slice(i) := "0000"; when '1' => slice(i) := "0001"; when '2' => slice(i) := "0010"; when '3' => slice(i) := "0011"; when '4' => slice(i) := "0100"; when '5' => slice(i) := "0101"; when '6' => slice(i) := "0110"; when '7' => slice(i) := "0111"; when '8' => slice(i) := "1000"; when '9' => slice(i) := "1001"; when 'a' => slice(i) := "1010"; when 'A' => slice(i) := "1010"; when 'b' => slice(i) := "1011"; when 'B' => slice(i) := "1011"; when 'c' => slice(i) := "1100"; when 'C' => slice(i) := "1100"; when 'd' => slice(i) := "1101"; when 'D' => slice(i) := "1101"; when 'e' => slice(i) := "1110"; when 'E' => slice(i) := "1110"; when others => slice(i) := "1111"; end case; end loop; mask := (slice(1) & slice(2) & slice(3) & slice(4)); return (mask); end str_to_bin; function product (list: std_logic_vector) return std_logic is begin for i in 0 to 31 loop if list(i) = '0' then return ('0'); end if; end loop; return ('1'); end product; function alt_conv_integer(arg : in std_logic_vector) return integer is variable result : integer; begin result := 0; for i in arg'range loop if arg(i) = '1' then result := result + 2**i; end if; end loop; return result; end alt_conv_integer; function int2str( value : integer ) return string is variable ivalue,index : integer; variable digit : integer; variable line_no: string(8 downto 1) := " "; begin ivalue := value; index := 1; if (ivalue = 0) then line_no := " 0"; end if; while (ivalue > 0) loop digit := ivalue MOD 10; ivalue := ivalue/10; case digit is when 0 => line_no(index) := '0'; when 1 => line_no(index) := '1'; when 2 => line_no(index) := '2'; when 3 => line_no(index) := '3'; when 4 => line_no(index) := '4'; when 5 => line_no(index) := '5'; when 6 => line_no(index) := '6'; when 7 => line_no(index) := '7'; when 8 => line_no(index) := '8'; when 9 => line_no(index) := '9'; when others => ASSERT FALSE REPORT "Illegal number!" SEVERITY ERROR; end case; index := index + 1; end loop; return line_no; end; function map_x_to_0 (value : std_logic) return std_logic is begin if (Is_X (value) = TRUE) then return '0'; else return value; end if; end; function SelectDelay (CONSTANT Paths : IN VitalPathArray01Type) return TIME IS variable Temp : TIME; variable TransitionTime : TIME := TIME'HIGH; variable PathDelay : TIME := TIME'HIGH; begin for i IN Paths'RANGE loop next when not Paths(i).PathCondition; next when Paths(i).InputChangeTime > TransitionTime; Temp := Paths(i).PathDelay(tr01); if Paths(i).InputChangeTime < TransitionTime then PathDelay := Temp; else if Temp < PathDelay then PathDelay := Temp; end if; end if; TransitionTime := Paths(i).InputChangeTime; end loop; return PathDelay; end; function int2bit (arg : integer) return std_logic is variable int_val : integer := arg; variable result : std_logic; begin if (int_val = 0) then result := '0'; else result := '1'; end if; return result; end int2bit; function int2bit (arg : boolean) return std_logic is variable int_val : boolean := arg; variable result : std_logic; begin if (int_val ) then result := '1'; else result := '0'; end if; return result; end int2bit; function bin2int (s : bit_vector) return integer is constant temp : bit_vector(s'high-s'low DOWNTO 0) := s; variable result : integer := 0; begin for i in temp'range loop if (temp(i) = '1') then result := result + (2**i); end if; end loop; return(result); end bin2int; function bin2int (s : bit) return integer is constant temp : bit := s; variable result : integer := 0; begin if (temp = '1') then result := 1; else result := 0; end if; return(result); end bin2int; function bin2int (s : std_logic_vector) return integer is constant temp : std_logic_vector(s'high-s'low DOWNTO 0) := s; variable result : integer := 0; begin for i in temp'range loop if (temp(i) = '1') then result := result + (2**i); end if; end loop; return(result); end bin2int; function bin2int (s : std_logic) return integer is constant temp : std_logic := s; variable result : integer := 0; begin if (temp = '1') then result := 1; else result := 0; end if; return(result); end bin2int; function int2bin (arg : integer; size : integer) return std_logic_vector is variable int_val : integer := arg; variable result : std_logic_vector(size-1 downto 0); begin for i in 0 to result'left loop if ((int_val mod 2) = 0) then result(i) := '0'; else result(i) := '1'; end if; int_val := int_val/2; end loop; return result; end int2bin; function int2bin (arg : boolean; size : integer) return std_logic_vector is variable result : std_logic_vector(size-1 downto 0); begin if(arg)then result := (OTHERS => '1'); else result := (OTHERS => '0'); end if; return result; end int2bin; function calc_sum_len( widtha : integer; widthb : integer) return integer is variable result: integer; begin if(widtha >= widthb) then result := widtha + 1; else result := widthb + 1; end if; return result; end calc_sum_len; end cycloneive_atom_pack; Library ieee; use ieee.std_logic_1164.all; Package cycloneive_pllpack is procedure find_simple_integer_fraction( numerator : in integer; denominator : in integer; max_denom : in integer; fraction_num : out integer; fraction_div : out integer); procedure find_m_and_n_4_manual_phase ( inclock_period : in integer; vco_phase_shift_step : in integer; clk0_mult: in integer; clk1_mult: in integer; clk2_mult: in integer; clk3_mult: in integer; clk4_mult: in integer; clk5_mult: in integer; clk6_mult: in integer; clk7_mult: in integer; clk8_mult: in integer; clk9_mult: in integer; clk0_div : in integer; clk1_div : in integer; clk2_div : in integer; clk3_div : in integer; clk4_div : in integer; clk5_div : in integer; clk6_div : in integer; clk7_div : in integer; clk8_div : in integer; clk9_div : in integer; clk0_used : in string; clk1_used : in string; clk2_used : in string; clk3_used : in string; clk4_used : in string; clk5_used : in string; clk6_used : in string; clk7_used : in string; clk8_used : in string; clk9_used : in string; m : out integer; n : out integer ); function gcd (X: integer; Y: integer) return integer; function count_digit (X: integer) return integer; function scale_num (X: integer; Y: integer) return integer; function lcm (A1: integer; A2: integer; A3: integer; A4: integer; A5: integer; A6: integer; A7: integer; A8: integer; A9: integer; A10: integer; P: integer) return integer; function output_counter_value (clk_divide: integer; clk_mult : integer ; M: integer; N: integer ) return integer; function counter_mode (duty_cycle: integer; output_counter_value: integer) return string; function counter_high (output_counter_value: integer := 1; duty_cycle: integer) return integer; function counter_low (output_counter_value: integer; duty_cycle: integer) return integer; function mintimedelay (t1: integer; t2: integer; t3: integer; t4: integer; t5: integer; t6: integer; t7: integer; t8: integer; t9: integer; t10: integer) return integer; function maxnegabs (t1: integer; t2: integer; t3: integer; t4: integer; t5: integer; t6: integer; t7: integer; t8: integer; t9: integer; t10: integer) return integer; function counter_time_delay ( clk_time_delay: integer; m_time_delay: integer; n_time_delay: integer) return integer; function get_phase_degree (phase_shift: integer; clk_period: integer) return integer; function counter_initial (tap_phase: integer; m: integer; n: integer) return integer; function counter_ph (tap_phase: integer; m : integer; n: integer) return integer; function ph_adjust (tap_phase: integer; ph_base : integer) return integer; function translate_string (mode : string) return string; function str2int (s : string) return integer; function dqs_str2int (s : string) return integer; end cycloneive_pllpack; package body cycloneive_pllpack is -- finds the closest integer fraction of a given pair of numerator and denominator. procedure find_simple_integer_fraction( numerator : in integer; denominator : in integer; max_denom : in integer; fraction_num : out integer; fraction_div : out integer) is constant MAX_ITER : integer := 20; type INT_ARRAY is array ((MAX_ITER-1) downto 0) of integer; variable quotient_array : INT_ARRAY; variable int_loop_iter : integer; variable int_quot : integer; variable m_value : integer; variable d_value : integer; variable old_m_value : integer; variable swap : integer; variable loop_iter : integer; variable num : integer; variable den : integer; variable i_max_iter : integer; begin loop_iter := 0; if (numerator = 0) then num := 1; else num := numerator; end if; if (denominator = 0) then den := 1; else den := denominator; end if; i_max_iter := max_iter; while (loop_iter < i_max_iter) loop int_quot := num / den; quotient_array(loop_iter) := int_quot; num := num - (den*int_quot); loop_iter := loop_iter+1; if ((num = 0) or (max_denom /= -1) or (loop_iter = i_max_iter)) then -- calculate the numerator and denominator if there is a restriction on the -- max denom value or if the loop is ending m_value := 0; d_value := 1; -- get the rounded value at this stage for the remaining fraction if (den /= 0) then m_value := (2*num/den); end if; -- calculate the fraction numerator and denominator at this stage for int_loop_iter in (loop_iter-1) downto 0 loop if (m_value = 0) then m_value := quotient_array(int_loop_iter); d_value := 1; else old_m_value := m_value; m_value := (quotient_array(int_loop_iter)*m_value) + d_value; d_value := old_m_value; end if; end loop; -- if the denominator is less than the maximum denom_value or if there is no restriction save it if ((d_value <= max_denom) or (max_denom = -1)) then if ((m_value = 0) or (d_value = 0)) then fraction_num := numerator; fraction_div := denominator; else fraction_num := m_value; fraction_div := d_value; end if; end if; -- end the loop if the denomitor has overflown or the numerator is zero (no remainder during this round) if (((d_value > max_denom) and (max_denom /= -1)) or (num = 0)) then i_max_iter := loop_iter; end if; end if; -- swap the numerator and denominator for the next round swap := den; den := num; num := swap; end loop; end find_simple_integer_fraction; -- find the M and N values for Manual phase based on the following 5 criterias: -- 1. The PFD frequency (i.e. Fin / N) must be in the range 5 MHz to 720 MHz -- 2. The VCO frequency (i.e. Fin * M / N) must be in the range 300 MHz to 1300 MHz -- 3. M is less than 512 -- 4. N is less than 512 -- 5. It's the smallest M/N which satisfies all the above constraints, and is within 2ps -- of the desired vco-phase-shift-step procedure find_m_and_n_4_manual_phase ( inclock_period : in integer; vco_phase_shift_step : in integer; clk0_mult: in integer; clk1_mult: in integer; clk2_mult: in integer; clk3_mult: in integer; clk4_mult: in integer; clk5_mult: in integer; clk6_mult: in integer; clk7_mult: in integer; clk8_mult: in integer; clk9_mult: in integer; clk0_div : in integer; clk1_div : in integer; clk2_div : in integer; clk3_div : in integer; clk4_div : in integer; clk5_div : in integer; clk6_div : in integer; clk7_div : in integer; clk8_div : in integer; clk9_div : in integer; clk0_used : in string; clk1_used : in string; clk2_used : in string; clk3_used : in string; clk4_used : in string; clk5_used : in string; clk6_used : in string; clk7_used : in string; clk8_used : in string; clk9_used : in string; m : out integer; n : out integer ) is constant MAX_M : integer := 511; constant MAX_N : integer := 511; constant MAX_PFD : integer := 720; constant MIN_PFD : integer := 5; constant MAX_VCO : integer := 1600; -- max vco frequency. (in mHz) constant MIN_VCO : integer := 300; -- min vco frequency. (in mHz) constant MAX_OFFSET : real := 0.004; variable vco_period : integer; variable pfd_freq : integer; variable vco_freq : integer; variable vco_ps_step_value : integer; variable i_m : integer; variable i_n : integer; variable i_pre_m : integer; variable i_pre_n : integer; variable closest_vco_step_value : integer; variable i_max_iter : integer; variable loop_iter : integer; variable clk0_div_factor_real : real; variable clk1_div_factor_real : real; variable clk2_div_factor_real : real; variable clk3_div_factor_real : real; variable clk4_div_factor_real : real; variable clk5_div_factor_real : real; variable clk6_div_factor_real : real; variable clk7_div_factor_real : real; variable clk8_div_factor_real : real; variable clk9_div_factor_real : real; variable clk0_div_factor_int : integer; variable clk1_div_factor_int : integer; variable clk2_div_factor_int : integer; variable clk3_div_factor_int : integer; variable clk4_div_factor_int : integer; variable clk5_div_factor_int : integer; variable clk6_div_factor_int : integer; variable clk7_div_factor_int : integer; variable clk8_div_factor_int : integer; variable clk9_div_factor_int : integer; begin vco_period := vco_phase_shift_step * 8; i_pre_m := 0; i_pre_n := 0; closest_vco_step_value := 0; LOOP_1 : for i_n_out in 1 to MAX_N loop for i_m_out in 1 to MAX_M loop clk0_div_factor_real := real(clk0_div * i_m_out) / real(clk0_mult * i_n_out); clk1_div_factor_real := real(clk1_div * i_m_out) / real(clk1_mult * i_n_out); clk2_div_factor_real := real(clk2_div * i_m_out) / real(clk2_mult * i_n_out); clk3_div_factor_real := real(clk3_div * i_m_out) / real(clk3_mult * i_n_out); clk4_div_factor_real := real(clk4_div * i_m_out) / real(clk4_mult * i_n_out); clk5_div_factor_real := real(clk5_div * i_m_out) / real(clk5_mult * i_n_out); clk6_div_factor_real := real(clk6_div * i_m_out) / real(clk6_mult * i_n_out); clk7_div_factor_real := real(clk7_div * i_m_out) / real(clk7_mult * i_n_out); clk8_div_factor_real := real(clk8_div * i_m_out) / real(clk8_mult * i_n_out); clk9_div_factor_real := real(clk9_div * i_m_out) / real(clk9_mult * i_n_out); clk0_div_factor_int := integer(clk0_div_factor_real); clk1_div_factor_int := integer(clk1_div_factor_real); clk2_div_factor_int := integer(clk2_div_factor_real); clk3_div_factor_int := integer(clk3_div_factor_real); clk4_div_factor_int := integer(clk4_div_factor_real); clk5_div_factor_int := integer(clk5_div_factor_real); clk6_div_factor_int := integer(clk6_div_factor_real); clk7_div_factor_int := integer(clk7_div_factor_real); clk8_div_factor_int := integer(clk8_div_factor_real); clk9_div_factor_int := integer(clk9_div_factor_real); if (((abs(clk0_div_factor_real - real(clk0_div_factor_int)) < MAX_OFFSET) or (clk0_used = "unused")) and ((abs(clk1_div_factor_real - real(clk1_div_factor_int)) < MAX_OFFSET) or (clk1_used = "unused")) and ((abs(clk2_div_factor_real - real(clk2_div_factor_int)) < MAX_OFFSET) or (clk2_used = "unused")) and ((abs(clk3_div_factor_real - real(clk3_div_factor_int)) < MAX_OFFSET) or (clk3_used = "unused")) and ((abs(clk4_div_factor_real - real(clk4_div_factor_int)) < MAX_OFFSET) or (clk4_used = "unused")) and ((abs(clk5_div_factor_real - real(clk5_div_factor_int)) < MAX_OFFSET) or (clk5_used = "unused")) and ((abs(clk6_div_factor_real - real(clk6_div_factor_int)) < MAX_OFFSET) or (clk6_used = "unused")) and ((abs(clk7_div_factor_real - real(clk7_div_factor_int)) < MAX_OFFSET) or (clk7_used = "unused")) and ((abs(clk8_div_factor_real - real(clk8_div_factor_int)) < MAX_OFFSET) or (clk8_used = "unused")) and ((abs(clk9_div_factor_real - real(clk9_div_factor_int)) < MAX_OFFSET) or (clk9_used = "unused")) ) then if ((i_m_out /= 0) and (i_n_out /= 0)) then pfd_freq := 1000000 / (inclock_period * i_n_out); vco_freq := (1000000 * i_m_out) / (inclock_period * i_n_out); vco_ps_step_value := (inclock_period * i_n_out) / (8 * i_m_out); if ( (i_m_out < max_m) and (i_n_out < max_n) and (pfd_freq >= min_pfd) and (pfd_freq <= max_pfd) and (vco_freq >= min_vco) and (vco_freq <= max_vco) ) then if (abs(vco_ps_step_value - vco_phase_shift_step) <= 2) then i_pre_m := i_m_out; i_pre_n := i_n_out; exit LOOP_1; else if ((closest_vco_step_value = 0) or (abs(vco_ps_step_value - vco_phase_shift_step) < abs(closest_vco_step_value - vco_phase_shift_step))) then i_pre_m := i_m_out; i_pre_n := i_n_out; closest_vco_step_value := vco_ps_step_value; end if; end if; end if; end if; end if; end loop; end loop; if ((i_pre_m /= 0) and (i_pre_n /= 0)) then find_simple_integer_fraction(i_pre_m, i_pre_n, MAX_N, m, n); else n := 1; m := lcm (clk0_mult, clk1_mult, clk2_mult, clk3_mult, clk4_mult, clk5_mult, clk6_mult, clk7_mult, clk8_mult, clk9_mult, inclock_period); end if; end find_m_and_n_4_manual_phase; -- find the greatest common denominator of X and Y function gcd (X: integer; Y: integer) return integer is variable L, S, R, G : integer := 1; begin if (X < Y) then -- find which is smaller. S := X; L := Y; else S := Y; L := X; end if; R := S; while ( R > 1) loop S := L; L := R; R := S rem L; -- divide bigger number by smaller. -- remainder becomes smaller number. end loop; if (R = 0) then -- if evenly divisible then L is gcd else it is 1. G := L; else G := R; end if; return G; end gcd; -- count the number of digits in the given integer function count_digit (X: integer) return integer is variable count, result: integer := 0; begin result := X; while (result /= 0) loop result := (result / 10); count := count + 1; end loop; return count; end count_digit; -- reduce the given huge number to Y significant digits function scale_num (X: integer; Y: integer) return integer is variable count : integer := 0; variable lc, fac_ten, result: integer := 1; begin count := count_digit(X); for lc in 1 to (count-Y) loop fac_ten := fac_ten * 10; end loop; result := (X / fac_ten); return result; end scale_num; -- find the least common multiple of A1 to A10 function lcm (A1: integer; A2: integer; A3: integer; A4: integer; A5: integer; A6: integer; A7: integer; A8: integer; A9: integer; A10: integer; P: integer) return integer is variable M1, M2, M3, M4, M5 , M6, M7, M8, M9, R: integer := 1; begin M1 := (A1 * A2)/gcd(A1, A2); M2 := (M1 * A3)/gcd(M1, A3); M3 := (M2 * A4)/gcd(M2, A4); M4 := (M3 * A5)/gcd(M3, A5); M5 := (M4 * A6)/gcd(M4, A6); M6 := (M5 * A7)/gcd(M5, A7); M7 := (M6 * A8)/gcd(M6, A8); M8 := (M7 * A9)/gcd(M7, A9); M9 := (M8 * A10)/gcd(M8, A10); if (M9 < 3) then R := 10; elsif (M9 = 3) then R := 9; elsif ((M9 <= 10) and (M9 > 3)) then R := 4 * M9; elsif (M9 > 1000) then R := scale_num(M9,3); else R := M9 ; end if; return R; end lcm; -- find the factor of division of the output clock frequency compared to the VCO function output_counter_value (clk_divide: integer; clk_mult: integer ; M: integer; N: integer ) return integer is variable r_real : real := 1.0; variable r: integer := 1; begin r_real := real(clk_divide * M)/ real(clk_mult * N); r := integer(r_real); return R; end output_counter_value; -- find the mode of each PLL counter - bypass, even or odd function counter_mode (duty_cycle: integer; output_counter_value: integer) return string is variable R: string (1 to 6) := " "; variable counter_value: integer := 1; begin counter_value := (2*duty_cycle*output_counter_value)/100; if output_counter_value = 1 then R := "bypass"; elsif (counter_value REM 2) = 0 then R := " even"; else R := " odd"; end if; return R; end counter_mode; -- find the number of VCO clock cycles to hold the output clock high function counter_high (output_counter_value: integer := 1; duty_cycle: integer) return integer is variable R: integer := 1; variable half_cycle_high : integer := 1; begin half_cycle_high := (duty_cycle * output_counter_value *2)/100 ; if (half_cycle_high REM 2 = 0) then R := half_cycle_high/2 ; else R := (half_cycle_high/2) + 1; end if; return R; end; -- find the number of VCO clock cycles to hold the output clock low function counter_low (output_counter_value: integer; duty_cycle: integer) return integer is variable R, R1: integer := 1; variable half_cycle_high : integer := 1; begin half_cycle_high := (duty_cycle * output_counter_value*2)/100 ; if (half_cycle_high REM 2 = 0) then R1 := half_cycle_high/2 ; else R1 := (half_cycle_high/2) + 1; end if; R := output_counter_value - R1; if (R = 0) then R := 1; end if; return R; end; -- find the smallest time delay amongst t1 to t10 function mintimedelay (t1: integer; t2: integer; t3: integer; t4: integer; t5: integer; t6: integer; t7: integer; t8: integer; t9: integer; t10: integer) return integer is variable m1,m2,m3,m4,m5,m6,m7,m8,m9 : integer := 0; begin if (t1 < t2) then m1 := t1; else m1 := t2; end if; if (m1 < t3) then m2 := m1; else m2 := t3; end if; if (m2 < t4) then m3 := m2; else m3 := t4; end if; if (m3 < t5) then m4 := m3; else m4 := t5; end if; if (m4 < t6) then m5 := m4; else m5 := t6; end if; if (m5 < t7) then m6 := m5; else m6 := t7; end if; if (m6 < t8) then m7 := m6; else m7 := t8; end if; if (m7 < t9) then m8 := m7; else m8 := t9; end if; if (m8 < t10) then m9 := m8; else m9 := t10; end if; if (m9 > 0) then return m9; else return 0; end if; end; -- find the numerically largest negative number, and return its absolute value function maxnegabs (t1: integer; t2: integer; t3: integer; t4: integer; t5: integer; t6: integer; t7: integer; t8: integer; t9: integer; t10: integer) return integer is variable m1,m2,m3,m4,m5,m6,m7,m8,m9 : integer := 0; begin if (t1 < t2) then m1 := t1; else m1 := t2; end if; if (m1 < t3) then m2 := m1; else m2 := t3; end if; if (m2 < t4) then m3 := m2; else m3 := t4; end if; if (m3 < t5) then m4 := m3; else m4 := t5; end if; if (m4 < t6) then m5 := m4; else m5 := t6; end if; if (m5 < t7) then m6 := m5; else m6 := t7; end if; if (m6 < t8) then m7 := m6; else m7 := t8; end if; if (m7 < t9) then m8 := m7; else m8 := t9; end if; if (m8 < t10) then m9 := m8; else m9 := t10; end if; if (m9 < 0) then return (0 - m9); else return 0; end if; end; -- adjust the phase (tap_phase) with the largest negative number (ph_base) function ph_adjust (tap_phase: integer; ph_base : integer) return integer is begin return (tap_phase + ph_base); end; -- find the time delay for each PLL counter function counter_time_delay (clk_time_delay: integer; m_time_delay: integer; n_time_delay: integer) return integer is variable R: integer := 0; begin R := clk_time_delay + m_time_delay - n_time_delay; return R; end; -- calculate the given phase shift (in ps) in terms of degrees function get_phase_degree (phase_shift: integer; clk_period: integer) return integer is variable result: integer := 0; begin result := ( phase_shift * 360 ) / clk_period; -- to round up the calculation result if (result > 0) then result := result + 1; elsif (result < 0) then result := result - 1; else result := 0; end if; return result; end; -- find the number of VCO clock cycles to wait initially before the first rising -- edge of the output clock function counter_initial (tap_phase: integer; m: integer; n: integer) return integer is variable R: integer; variable R1: real; begin R1 := (real(abs(tap_phase)) * real(m))/(360.0 * real(n)) + 0.6; -- Note NCSim VHDL had problem in rounding up for 0.5 - 0.99. -- This checking will ensure that the rounding up is done. if (R1 >= 0.5) and (R1 <= 1.0) then R1 := 1.0; end if; R := integer(R1); return R; end; -- find which VCO phase tap (0 to 7) to align the rising edge of the output clock to function counter_ph (tap_phase: integer; m: integer; n: integer) return integer is variable R: integer := 0; begin -- 0.5 is added for proper rounding of the tap_phase. R := integer(real(integer(real(tap_phase * m / n)+ 0.5) REM 360)/45.0) rem 8; return R; end; -- convert given string to length 6 by padding with spaces function translate_string (mode : string) return string is variable new_mode : string (1 to 6) := " "; begin if (mode = "bypass") then new_mode := "bypass"; elsif (mode = "even") then new_mode := " even"; elsif (mode = "odd") then new_mode := " odd"; end if; return new_mode; end; function str2int (s : string) return integer is variable len : integer := s'length; variable newdigit : integer := 0; variable sign : integer := 1; variable digit : integer := 0; begin for i in 1 to len loop case s(i) is when '-' => if i = 1 then sign := -1; else ASSERT FALSE REPORT "Illegal Character "& s(i) & "i n string parameter! " SEVERITY ERROR; end if; when '0' => digit := 0; when '1' => digit := 1; when '2' => digit := 2; when '3' => digit := 3; when '4' => digit := 4; when '5' => digit := 5; when '6' => digit := 6; when '7' => digit := 7; when '8' => digit := 8; when '9' => digit := 9; when others => ASSERT FALSE REPORT "Illegal Character "& s(i) & "in string parameter! " SEVERITY ERROR; end case; newdigit := newdigit * 10 + digit; end loop; return (sign*newdigit); end; function dqs_str2int (s : string) return integer is variable len : integer := s'length; variable newdigit : integer := 0; variable sign : integer := 1; variable digit : integer := 0; variable err : boolean := false; begin for i in 1 to len loop case s(i) is when '-' => if i = 1 then sign := -1; else ASSERT FALSE REPORT "Illegal Character "& s(i) & " in string parameter! " SEVERITY ERROR; err := true; end if; when '0' => digit := 0; when '1' => digit := 1; when '2' => digit := 2; when '3' => digit := 3; when '4' => digit := 4; when '5' => digit := 5; when '6' => digit := 6; when '7' => digit := 7; when '8' => digit := 8; when '9' => digit := 9; when others => -- set error flag err := true; end case; if (err) then err := false; else newdigit := newdigit * 10 + digit; end if; end loop; return (sign*newdigit); end; end cycloneive_pllpack; -- -- -- DFFE Model -- -- LIBRARY IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; entity cycloneive_dffe is generic( TimingChecksOn: Boolean := True; XOn: Boolean := DefGlitchXOn; MsgOn: Boolean := DefGlitchMsgOn; MsgOnChecks: Boolean := DefMsgOnChecks; XOnChecks: Boolean := DefXOnChecks; InstancePath: STRING := "*"; tpd_PRN_Q_negedge : VitalDelayType01 := DefPropDelay01; tpd_CLRN_Q_negedge : VitalDelayType01 := DefPropDelay01; tpd_CLK_Q_posedge : VitalDelayType01 := DefPropDelay01; tpd_ENA_Q_posedge : VitalDelayType01 := DefPropDelay01; tsetup_D_CLK_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_D_CLK_noedge_negedge : VitalDelayType := DefSetupHoldCnst; tsetup_ENA_CLK_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_D_CLK_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_D_CLK_noedge_negedge : VitalDelayType := DefSetupHoldCnst; thold_ENA_CLK_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tipd_D : VitalDelayType01 := DefPropDelay01; tipd_CLRN : VitalDelayType01 := DefPropDelay01; tipd_PRN : VitalDelayType01 := DefPropDelay01; tipd_CLK : VitalDelayType01 := DefPropDelay01; tipd_ENA : VitalDelayType01 := DefPropDelay01); port( Q : out STD_LOGIC := '0'; D : in STD_LOGIC; CLRN : in STD_LOGIC; PRN : in STD_LOGIC; CLK : in STD_LOGIC; ENA : in STD_LOGIC); attribute VITAL_LEVEL0 of cycloneive_dffe : entity is TRUE; end cycloneive_dffe; -- architecture body -- architecture behave of cycloneive_dffe is attribute VITAL_LEVEL0 of behave : architecture is TRUE; signal D_ipd : STD_ULOGIC := 'U'; signal CLRN_ipd : STD_ULOGIC := 'U'; signal PRN_ipd : STD_ULOGIC := 'U'; signal CLK_ipd : STD_ULOGIC := 'U'; signal ENA_ipd : STD_ULOGIC := 'U'; begin --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (D_ipd, D, tipd_D); VitalWireDelay (CLRN_ipd, CLRN, tipd_CLRN); VitalWireDelay (PRN_ipd, PRN, tipd_PRN); VitalWireDelay (CLK_ipd, CLK, tipd_CLK); VitalWireDelay (ENA_ipd, ENA, tipd_ENA); end block; -------------------- -- BEHAVIOR SECTION -------------------- VITALBehavior : process (D_ipd, CLRN_ipd, PRN_ipd, CLK_ipd, ENA_ipd) -- timing check results VARIABLE Tviol_D_CLK : STD_ULOGIC := '0'; VARIABLE Tviol_ENA_CLK : STD_ULOGIC := '0'; VARIABLE TimingData_D_CLK : VitalTimingDataType := VitalTimingDataInit; VARIABLE TimingData_ENA_CLK : VitalTimingDataType := VitalTimingDataInit; -- functionality results VARIABLE Violation : STD_ULOGIC := '0'; VARIABLE PrevData_Q : STD_LOGIC_VECTOR(0 to 7); VARIABLE D_delayed : STD_ULOGIC := 'U'; VARIABLE CLK_delayed : STD_ULOGIC := 'U'; VARIABLE ENA_delayed : STD_ULOGIC := 'U'; VARIABLE Results : STD_LOGIC_VECTOR(1 to 1) := (others => '0'); -- output glitch detection variables VARIABLE Q_VitalGlitchData : VitalGlitchDataType; CONSTANT dffe_Q_tab : VitalStateTableType := ( ( L, L, x, x, x, x, x, x, x, L ), ( L, H, L, H, H, x, x, H, x, H ), ( L, H, L, H, x, L, x, H, x, H ), ( L, H, L, x, H, H, x, H, x, H ), ( L, H, H, x, x, x, H, x, x, S ), ( L, H, x, x, x, x, L, x, x, H ), ( L, H, x, x, x, x, H, L, x, S ), ( L, x, L, L, L, x, H, H, x, L ), ( L, x, L, L, x, L, H, H, x, L ), ( L, x, L, x, L, H, H, H, x, L ), ( L, x, x, x, x, x, x, x, x, S )); begin ------------------------ -- Timing Check Section ------------------------ if (TimingChecksOn) then VitalSetupHoldCheck ( Violation => Tviol_D_CLK, TimingData => TimingData_D_CLK, TestSignal => D_ipd, TestSignalName => "D", RefSignal => CLK_ipd, RefSignalName => "CLK", SetupHigh => tsetup_D_CLK_noedge_posedge, SetupLow => tsetup_D_CLK_noedge_posedge, HoldHigh => thold_D_CLK_noedge_posedge, HoldLow => thold_D_CLK_noedge_posedge, CheckEnabled => TO_X01(( (NOT PRN_ipd) ) OR ( (NOT CLRN_ipd) ) OR ( (NOT ENA_ipd) )) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/DFFE", XOn => XOnChecks, MsgOn => MsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_ENA_CLK, TimingData => TimingData_ENA_CLK, TestSignal => ENA_ipd, TestSignalName => "ENA", RefSignal => CLK_ipd, RefSignalName => "CLK", SetupHigh => tsetup_ENA_CLK_noedge_posedge, SetupLow => tsetup_ENA_CLK_noedge_posedge, HoldHigh => thold_ENA_CLK_noedge_posedge, HoldLow => thold_ENA_CLK_noedge_posedge, CheckEnabled => TO_X01(( (NOT PRN_ipd) ) OR ( (NOT CLRN_ipd) ) ) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/DFFE", XOn => XOnChecks, MsgOn => MsgOnChecks ); end if; ------------------------- -- Functionality Section ------------------------- Violation := Tviol_D_CLK or Tviol_ENA_CLK; VitalStateTable( StateTable => dffe_Q_tab, DataIn => ( Violation, CLRN_ipd, CLK_delayed, Results(1), D_delayed, ENA_delayed, PRN_ipd, CLK_ipd), Result => Results, NumStates => 1, PreviousDataIn => PrevData_Q); D_delayed := D_ipd; CLK_delayed := CLK_ipd; ENA_delayed := ENA_ipd; ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => Q, OutSignalName => "Q", OutTemp => Results(1), Paths => ( 0 => (PRN_ipd'last_event, tpd_PRN_Q_negedge, TRUE), 1 => (CLRN_ipd'last_event, tpd_CLRN_Q_negedge, TRUE), 2 => (CLK_ipd'last_event, tpd_CLK_Q_posedge, TRUE)), GlitchData => Q_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end behave; -- -- -- cycloneive_mux21 Model -- -- LIBRARY IEEE; use ieee.std_logic_1164.all; use IEEE.VITAL_Timing.all; use work.cycloneive_atom_pack.all; entity cycloneive_mux21 is generic( TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; InstancePath: STRING := "*"; tpd_A_MO : VitalDelayType01 := DefPropDelay01; tpd_B_MO : VitalDelayType01 := DefPropDelay01; tpd_S_MO : VitalDelayType01 := DefPropDelay01; tipd_A : VitalDelayType01 := DefPropDelay01; tipd_B : VitalDelayType01 := DefPropDelay01; tipd_S : VitalDelayType01 := DefPropDelay01); port ( A : in std_logic := '0'; B : in std_logic := '0'; S : in std_logic := '0'; MO : out std_logic); attribute VITAL_LEVEL0 of cycloneive_mux21 : entity is TRUE; end cycloneive_mux21; architecture AltVITAL of cycloneive_mux21 is attribute VITAL_LEVEL0 of AltVITAL : architecture is TRUE; signal A_ipd, B_ipd, S_ipd : std_logic; begin --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (A_ipd, A, tipd_A); VitalWireDelay (B_ipd, B, tipd_B); VitalWireDelay (S_ipd, S, tipd_S); end block; -------------------- -- BEHAVIOR SECTION -------------------- VITALBehavior : process (A_ipd, B_ipd, S_ipd) -- output glitch detection variables VARIABLE MO_GlitchData : VitalGlitchDataType; variable tmp_MO : std_logic; begin ------------------------- -- Functionality Section ------------------------- if (S_ipd = '1') then tmp_MO := B_ipd; else tmp_MO := A_ipd; end if; ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => MO, OutSignalName => "MO", OutTemp => tmp_MO, Paths => ( 0 => (A_ipd'last_event, tpd_A_MO, TRUE), 1 => (B_ipd'last_event, tpd_B_MO, TRUE), 2 => (S_ipd'last_event, tpd_S_MO, TRUE)), GlitchData => MO_GlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end AltVITAL; -- -- -- cycloneive_mux41 Model -- -- LIBRARY IEEE; use ieee.std_logic_1164.all; use IEEE.VITAL_Timing.all; use work.cycloneive_atom_pack.all; entity cycloneive_mux41 is generic( TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; InstancePath: STRING := "*"; tpd_IN0_MO : VitalDelayType01 := DefPropDelay01; tpd_IN1_MO : VitalDelayType01 := DefPropDelay01; tpd_IN2_MO : VitalDelayType01 := DefPropDelay01; tpd_IN3_MO : VitalDelayType01 := DefPropDelay01; tpd_S_MO : VitalDelayArrayType01(1 downto 0) := (OTHERS => DefPropDelay01); tipd_IN0 : VitalDelayType01 := DefPropDelay01; tipd_IN1 : VitalDelayType01 := DefPropDelay01; tipd_IN2 : VitalDelayType01 := DefPropDelay01; tipd_IN3 : VitalDelayType01 := DefPropDelay01; tipd_S : VitalDelayArrayType01(1 downto 0) := (OTHERS => DefPropDelay01) ); port ( IN0 : in std_logic := '0'; IN1 : in std_logic := '0'; IN2 : in std_logic := '0'; IN3 : in std_logic := '0'; S : in std_logic_vector(1 downto 0) := (OTHERS => '0'); MO : out std_logic ); attribute VITAL_LEVEL0 of cycloneive_mux41 : entity is TRUE; end cycloneive_mux41; architecture AltVITAL of cycloneive_mux41 is attribute VITAL_LEVEL0 of AltVITAL : architecture is TRUE; signal IN0_ipd, IN1_ipd, IN2_ipd, IN3_ipd : std_logic; signal S_ipd : std_logic_vector(1 downto 0); begin --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (IN0_ipd, IN0, tipd_IN0); VitalWireDelay (IN1_ipd, IN1, tipd_IN1); VitalWireDelay (IN2_ipd, IN2, tipd_IN2); VitalWireDelay (IN3_ipd, IN3, tipd_IN3); VitalWireDelay (S_ipd(0), S(0), tipd_S(0)); VitalWireDelay (S_ipd(1), S(1), tipd_S(1)); end block; -------------------- -- BEHAVIOR SECTION -------------------- VITALBehavior : process (IN0_ipd, IN1_ipd, IN2_ipd, IN3_ipd, S_ipd(0), S_ipd(1)) -- output glitch detection variables VARIABLE MO_GlitchData : VitalGlitchDataType; variable tmp_MO : std_logic; begin ------------------------- -- Functionality Section ------------------------- if ((S_ipd(1) = '1') AND (S_ipd(0) = '1')) then tmp_MO := IN3_ipd; elsif ((S_ipd(1) = '1') AND (S_ipd(0) = '0')) then tmp_MO := IN2_ipd; elsif ((S_ipd(1) = '0') AND (S_ipd(0) = '1')) then tmp_MO := IN1_ipd; else tmp_MO := IN0_ipd; end if; ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => MO, OutSignalName => "MO", OutTemp => tmp_MO, Paths => ( 0 => (IN0_ipd'last_event, tpd_IN0_MO, TRUE), 1 => (IN1_ipd'last_event, tpd_IN1_MO, TRUE), 2 => (IN2_ipd'last_event, tpd_IN2_MO, TRUE), 3 => (IN3_ipd'last_event, tpd_IN3_MO, TRUE), 4 => (S_ipd(0)'last_event, tpd_S_MO(0), TRUE), 5 => (S_ipd(1)'last_event, tpd_S_MO(1), TRUE)), GlitchData => MO_GlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end AltVITAL; -- -- -- cycloneive_and1 Model -- -- LIBRARY IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.VITAL_Timing.all; use work.cycloneive_atom_pack.all; -- entity declaration -- entity cycloneive_and1 is generic( TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; InstancePath: STRING := "*"; tpd_IN1_Y : VitalDelayType01 := DefPropDelay01; tipd_IN1 : VitalDelayType01 := DefPropDelay01); port( Y : out STD_LOGIC; IN1 : in STD_LOGIC); attribute VITAL_LEVEL0 of cycloneive_and1 : entity is TRUE; end cycloneive_and1; -- architecture body -- architecture AltVITAL of cycloneive_and1 is attribute VITAL_LEVEL0 of AltVITAL : architecture is TRUE; SIGNAL IN1_ipd : STD_ULOGIC := 'U'; begin --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (IN1_ipd, IN1, tipd_IN1); end block; -------------------- -- BEHAVIOR SECTION -------------------- VITALBehavior : process (IN1_ipd) -- functionality results VARIABLE Results : STD_LOGIC_VECTOR(1 to 1) := (others => 'X'); ALIAS Y_zd : STD_ULOGIC is Results(1); -- output glitch detection variables VARIABLE Y_GlitchData : VitalGlitchDataType; begin ------------------------- -- Functionality Section ------------------------- Y_zd := TO_X01(IN1_ipd); ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => Y, OutSignalName => "Y", OutTemp => Y_zd, Paths => (0 => (IN1_ipd'last_event, tpd_IN1_Y, TRUE)), GlitchData => Y_GlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end AltVITAL; --------------------------------------------------------------------- -- -- Entity Name : cycloneive_lcell_comb -- -- Description : Cyclone II LCELL_COMB VHDL simulation model -- -- --------------------------------------------------------------------- LIBRARY IEEE; use IEEE.std_logic_1164.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; entity cycloneive_lcell_comb is generic ( lut_mask : std_logic_vector(15 downto 0) := (OTHERS => '1'); sum_lutc_input : string := "datac"; dont_touch : string := "off"; lpm_type : string := "cycloneive_lcell_comb"; TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; MsgOnChecks: Boolean := DefMsgOnChecks; XOnChecks: Boolean := DefXOnChecks; InstancePath: STRING := "*"; tpd_dataa_combout : VitalDelayType01 := DefPropDelay01; tpd_datab_combout : VitalDelayType01 := DefPropDelay01; tpd_datac_combout : VitalDelayType01 := DefPropDelay01; tpd_datad_combout : VitalDelayType01 := DefPropDelay01; tpd_cin_combout : VitalDelayType01 := DefPropDelay01; tpd_dataa_cout : VitalDelayType01 := DefPropDelay01; tpd_datab_cout : VitalDelayType01 := DefPropDelay01; tpd_datac_cout : VitalDelayType01 := DefPropDelay01; tpd_datad_cout : VitalDelayType01 := DefPropDelay01; tpd_cin_cout : VitalDelayType01 := DefPropDelay01; tipd_dataa : VitalDelayType01 := DefPropDelay01; tipd_datab : VitalDelayType01 := DefPropDelay01; tipd_datac : VitalDelayType01 := DefPropDelay01; tipd_datad : VitalDelayType01 := DefPropDelay01; tipd_cin : VitalDelayType01 := DefPropDelay01 ); port ( dataa : in std_logic := '1'; datab : in std_logic := '1'; datac : in std_logic := '1'; datad : in std_logic := '1'; cin : in std_logic := '0'; combout : out std_logic; cout : out std_logic ); attribute VITAL_LEVEL0 of cycloneive_lcell_comb : entity is TRUE; end cycloneive_lcell_comb; architecture vital_lcell_comb of cycloneive_lcell_comb is attribute VITAL_LEVEL0 of vital_lcell_comb : architecture is TRUE; signal dataa_ipd : std_logic; signal datab_ipd : std_logic; signal datac_ipd : std_logic; signal datad_ipd : std_logic; signal cin_ipd : std_logic; begin --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (dataa_ipd, dataa, tipd_dataa); VitalWireDelay (datab_ipd, datab, tipd_datab); VitalWireDelay (datac_ipd, datac, tipd_datac); VitalWireDelay (datad_ipd, datad, tipd_datad); VitalWireDelay (cin_ipd, cin, tipd_cin); end block; VITALtiming : process(dataa_ipd, datab_ipd, datac_ipd, datad_ipd, cin_ipd) variable combout_VitalGlitchData : VitalGlitchDataType; variable cout_VitalGlitchData : VitalGlitchDataType; -- output variables variable combout_tmp : std_logic; variable cout_tmp : std_logic; begin -- lut_mask_var := lut_mask; ------------------------ -- Timing Check Section ------------------------ if (sum_lutc_input = "datac") then -- combout combout_tmp := VitalMUX(data => lut_mask, dselect => (datad_ipd, datac_ipd, datab_ipd, dataa_ipd)); elsif (sum_lutc_input = "cin") then -- combout combout_tmp := VitalMUX(data => lut_mask, dselect => (datad_ipd, cin_ipd, datab_ipd, dataa_ipd)); end if; -- cout cout_tmp := VitalMUX(data => lut_mask, dselect => ('0', cin_ipd, datab_ipd, dataa_ipd)); ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => combout, OutSignalName => "COMBOUT", OutTemp => combout_tmp, Paths => (0 => (dataa_ipd'last_event, tpd_dataa_combout, TRUE), 1 => (datab_ipd'last_event, tpd_datab_combout, TRUE), 2 => (datac_ipd'last_event, tpd_datac_combout, TRUE), 3 => (datad_ipd'last_event, tpd_datad_combout, TRUE), 4 => (cin_ipd'last_event, tpd_cin_combout, TRUE)), GlitchData => combout_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); VitalPathDelay01 ( OutSignal => cout, OutSignalName => "COUT", OutTemp => cout_tmp, Paths => (0 => (dataa_ipd'last_event, tpd_dataa_cout, TRUE), 1 => (datab_ipd'last_event, tpd_datab_cout, TRUE), 2 => (datac_ipd'last_event, tpd_datac_cout, TRUE), 3 => (datad_ipd'last_event, tpd_datad_cout, TRUE), 4 => (cin_ipd'last_event, tpd_cin_cout, TRUE)), GlitchData => cout_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end vital_lcell_comb; --------------------------------------------------------------------- -- -- Entity Name : cycloneive_routing_wire -- -- Description : Cycloneive Routing Wire VHDL simulation model -- -- --------------------------------------------------------------------- LIBRARY IEEE; use IEEE.std_logic_1164.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; ENTITY cycloneive_routing_wire is generic ( MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; tpd_datain_dataout : VitalDelayType01 := DefPropDelay01; tpd_datainglitch_dataout : VitalDelayType01 := DefPropDelay01; tipd_datain : VitalDelayType01 := DefPropDelay01 ); PORT ( datain : in std_logic; dataout : out std_logic ); attribute VITAL_LEVEL0 of cycloneive_routing_wire : entity is TRUE; end cycloneive_routing_wire; ARCHITECTURE behave of cycloneive_routing_wire is attribute VITAL_LEVEL0 of behave : architecture is TRUE; signal datain_ipd : std_logic; signal datainglitch_inert : std_logic; begin --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (datain_ipd, datain, tipd_datain); end block; VITAL: process(datain_ipd, datainglitch_inert) variable datain_inert_VitalGlitchData : VitalGlitchDataType; variable dataout_VitalGlitchData : VitalGlitchDataType; begin ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => datainglitch_inert, OutSignalName => "datainglitch_inert", OutTemp => datain_ipd, Paths => (1 => (datain_ipd'last_event, tpd_datainglitch_dataout, TRUE)), GlitchData => datain_inert_VitalGlitchData, Mode => VitalInertial, XOn => XOn, MsgOn => MsgOn ); VitalPathDelay01 ( OutSignal => dataout, OutSignalName => "dataout", OutTemp => datainglitch_inert, Paths => (1 => (datain_ipd'last_event, tpd_datain_dataout, TRUE)), GlitchData => dataout_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end behave; --/////////////////////////////////////////////////////////////////////////// -- -- Entity Name : cycloneive_mn_cntr -- -- Description : Timing simulation model for the M and N counter. This is a -- common model for the input counter and the loop feedback -- counter of the Cycloneive PLL. -- --/////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; USE IEEE.std_logic_unsigned.all; USE IEEE.VITAL_Timing.all; USE IEEE.VITAL_Primitives.all; ENTITY cycloneive_mn_cntr is PORT( clk : IN std_logic; reset : IN std_logic := '0'; cout : OUT std_logic; initial_value : IN integer := 1; modulus : IN integer := 1; time_delay : IN integer := 0 ); END cycloneive_mn_cntr; ARCHITECTURE behave of cycloneive_mn_cntr is begin process (clk, reset) variable count : integer := 1; variable first_rising_edge : boolean := true; variable tmp_cout : std_logic; begin if (reset = '1') then count := 1; tmp_cout := '0'; first_rising_edge := true; elsif (clk'event) then if (clk = '1' and first_rising_edge) then first_rising_edge := false; tmp_cout := clk; elsif (not first_rising_edge) then if (count < modulus) then count := count + 1; else count := 1; tmp_cout := not tmp_cout; end if; end if; end if; cout <= transport tmp_cout after time_delay * 1 ps; end process; end behave; --///////////////////////////////////////////////////////////////////////////// -- -- Entity Name : cycloneive_scale_cntr -- -- Description : Timing simulation model for the output scale-down counters. -- This is a common model for the C0, C1, C2, C3, C4 and C5 -- output counters of the Cycloneive PLL. -- --///////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.VITAL_Timing.all; USE IEEE.VITAL_Primitives.all; ENTITY cycloneive_scale_cntr is PORT( clk : IN std_logic; reset : IN std_logic := '0'; initial : IN integer := 1; high : IN integer := 1; low : IN integer := 1; mode : IN string := "bypass"; ph_tap : IN integer := 0; cout : OUT std_logic ); END cycloneive_scale_cntr; ARCHITECTURE behave of cycloneive_scale_cntr is begin process (clk, reset) variable tmp_cout : std_logic := '0'; variable count : integer := 1; variable output_shift_count : integer := 1; variable first_rising_edge : boolean := false; begin if (reset = '1') then count := 1; output_shift_count := 1; tmp_cout := '0'; first_rising_edge := false; elsif (clk'event) then if (mode = " off") then tmp_cout := '0'; elsif (mode = "bypass") then tmp_cout := clk; first_rising_edge := true; elsif (not first_rising_edge) then if (clk = '1') then if (output_shift_count = initial) then tmp_cout := clk; first_rising_edge := true; else output_shift_count := output_shift_count + 1; end if; end if; elsif (output_shift_count < initial) then if (clk = '1') then output_shift_count := output_shift_count + 1; end if; else count := count + 1; if (mode = " even" and (count = (high*2) + 1)) then tmp_cout := '0'; elsif (mode = " odd" and (count = high*2)) then tmp_cout := '0'; elsif (count = (high + low)*2 + 1) then tmp_cout := '1'; count := 1; -- reset count end if; end if; end if; cout <= transport tmp_cout; end process; end behave; --///////////////////////////////////////////////////////////////////////////// -- -- Entity Name : cycloneive_pll_reg -- -- Description : Simulation model for a simple DFF. -- This is required for the generation of the bit slip-signals. -- No timing, powers upto 0. -- --///////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; ENTITY cycloneive_pll_reg is PORT( clk : in std_logic; ena : in std_logic := '1'; d : in std_logic; clrn : in std_logic := '1'; prn : in std_logic := '1'; q : out std_logic ); end cycloneive_pll_reg; ARCHITECTURE behave of cycloneive_pll_reg is begin process (clk, prn, clrn) variable q_reg : std_logic := '0'; begin if (prn = '0') then q_reg := '1'; elsif (clrn = '0') then q_reg := '0'; elsif (clk'event and clk = '1' and (ena = '1')) then q_reg := D; end if; Q <= q_reg; end process; end behave; --/////////////////////////////////////////////////////////////////////////// -- -- Entity Name : cycloneive_pll -- -- Description : Timing simulation model for the Cycloneive PLL. -- In the functional mode, it is also the model for the altpll -- megafunction. -- -- Limitations : Does not support Spread Spectrum and Bandwidth. -- -- Outputs : Up to 10 output clocks, each defined by its own set of -- parameters. Locked output (active high) indicates when the -- PLL locks. clkbad and activeclock are used for -- clock switchover to indicate which input clock has gone -- bad, when the clock switchover initiates and which input -- clock is being used as the reference, respectively. -- scandataout is the data output of the serial scan chain. -- --/////////////////////////////////////////////////////////////////////////// LIBRARY IEEE, std; USE IEEE.std_logic_1164.all; USE IEEE.VITAL_Timing.all; USE IEEE.VITAL_Primitives.all; USE STD.TEXTIO.all; USE work.cycloneive_atom_pack.all; USE work.cycloneive_pllpack.all; USE work.cycloneive_mn_cntr; USE work.cycloneive_scale_cntr; USE work.cycloneive_dffe; USE work.cycloneive_pll_reg; -- New Features : The list below outlines key new features in CYCLONEIVE: -- 1. Dynamic Phase Reconfiguration -- 2. Dynamic PLL Reconfiguration (different protocol) -- 3. More output counters ENTITY cycloneive_pll is GENERIC ( operation_mode : string := "normal"; pll_type : string := "auto"; -- AUTO/FAST/ENHANCED/LEFT_RIGHT/TOP_BOTTOM compensate_clock : string := "clock0"; inclk0_input_frequency : integer := 0; inclk1_input_frequency : integer := 0; self_reset_on_loss_lock : string := "off"; switch_over_type : string := "auto"; switch_over_counter : integer := 1; enable_switch_over_counter : string := "off"; bandwidth : integer := 0; bandwidth_type : string := "auto"; use_dc_coupling : string := "false"; lock_c : integer := 4; sim_gate_lock_device_behavior : string := "off"; lock_high : integer := 0; lock_low : integer := 0; lock_window_ui : string := "0.05"; lock_window : time := 5 ps; test_bypass_lock_detect : string := "off"; clk0_output_frequency : integer := 0; clk0_multiply_by : integer := 0; clk0_divide_by : integer := 0; clk0_phase_shift : string := "0"; clk0_duty_cycle : integer := 50; clk1_output_frequency : integer := 0; clk1_multiply_by : integer := 0; clk1_divide_by : integer := 0; clk1_phase_shift : string := "0"; clk1_duty_cycle : integer := 50; clk2_output_frequency : integer := 0; clk2_multiply_by : integer := 0; clk2_divide_by : integer := 0; clk2_phase_shift : string := "0"; clk2_duty_cycle : integer := 50; clk3_output_frequency : integer := 0; clk3_multiply_by : integer := 0; clk3_divide_by : integer := 0; clk3_phase_shift : string := "0"; clk3_duty_cycle : integer := 50; clk4_output_frequency : integer := 0; clk4_multiply_by : integer := 0; clk4_divide_by : integer := 0; clk4_phase_shift : string := "0"; clk4_duty_cycle : integer := 50; pfd_min : integer := 0; pfd_max : integer := 0; vco_min : integer := 0; vco_max : integer := 0; vco_center : integer := 0; -- ADVANCED USER PARAMETERS m_initial : integer := 1; m : integer := 0; n : integer := 1; c0_high : integer := 1; c0_low : integer := 1; c0_initial : integer := 1; c0_mode : string := "bypass"; c0_ph : integer := 0; c1_high : integer := 1; c1_low : integer := 1; c1_initial : integer := 1; c1_mode : string := "bypass"; c1_ph : integer := 0; c2_high : integer := 1; c2_low : integer := 1; c2_initial : integer := 1; c2_mode : string := "bypass"; c2_ph : integer := 0; c3_high : integer := 1; c3_low : integer := 1; c3_initial : integer := 1; c3_mode : string := "bypass"; c3_ph : integer := 0; c4_high : integer := 1; c4_low : integer := 1; c4_initial : integer := 1; c4_mode : string := "bypass"; c4_ph : integer := 0; m_ph : integer := 0; clk0_counter : string := "unused"; clk1_counter : string := "unused"; clk2_counter : string := "unused"; clk3_counter : string := "unused"; clk4_counter : string := "unused"; c1_use_casc_in : string := "off"; c2_use_casc_in : string := "off"; c3_use_casc_in : string := "off"; c4_use_casc_in : string := "off"; m_test_source : integer := -1; c0_test_source : integer := -1; c1_test_source : integer := -1; c2_test_source : integer := -1; c3_test_source : integer := -1; c4_test_source : integer := -1; vco_multiply_by : integer := 0; vco_divide_by : integer := 0; vco_post_scale : integer := 1; vco_frequency_control : string := "auto"; vco_phase_shift_step : integer := 0; charge_pump_current : integer := 10; loop_filter_r : string := " 1.0"; loop_filter_c : integer := 0; pll_compensation_delay : integer := 0; simulation_type : string := "functional"; lpm_type : string := "cycloneive_pll"; clk0_use_even_counter_mode : string := "off"; clk1_use_even_counter_mode : string := "off"; clk2_use_even_counter_mode : string := "off"; clk3_use_even_counter_mode : string := "off"; clk4_use_even_counter_mode : string := "off"; clk0_use_even_counter_value : string := "off"; clk1_use_even_counter_value : string := "off"; clk2_use_even_counter_value : string := "off"; clk3_use_even_counter_value : string := "off"; clk4_use_even_counter_value : string := "off"; -- Test only init_block_reset_a_count : integer := 1; init_block_reset_b_count : integer := 1; charge_pump_current_bits : integer := 0; lock_window_ui_bits : integer := 0; loop_filter_c_bits : integer := 0; loop_filter_r_bits : integer := 0; test_counter_c0_delay_chain_bits : integer := 0; test_counter_c1_delay_chain_bits : integer := 0; test_counter_c2_delay_chain_bits : integer := 0; test_counter_c3_delay_chain_bits : integer := 0; test_counter_c4_delay_chain_bits : integer := 0; test_counter_c5_delay_chain_bits : integer := 0; test_counter_m_delay_chain_bits : integer := 0; test_counter_n_delay_chain_bits : integer := 0; test_feedback_comp_delay_chain_bits : integer := 0; test_input_comp_delay_chain_bits : integer := 0; test_volt_reg_output_mode_bits : integer := 0; test_volt_reg_output_voltage_bits : integer := 0; test_volt_reg_test_mode : string := "false"; vco_range_detector_high_bits : integer := -1; vco_range_detector_low_bits : integer := -1; scan_chain_mif_file : string := ""; auto_settings : string := "true"; -- Simulation only generics family_name : string := "Cycloneive"; -- VITAL generics XOn : Boolean := DefGlitchXOn; MsgOn : Boolean := DefGlitchMsgOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; TimingChecksOn : Boolean := true; InstancePath : STRING := "*"; tipd_inclk : VitalDelayArrayType01(1 downto 0) := (OTHERS => DefPropDelay01); tipd_ena : VitalDelayType01 := DefPropDelay01; tipd_pfdena : VitalDelayType01 := DefPropDelay01; tipd_areset : VitalDelayType01 := DefPropDelay01; tipd_fbin : VitalDelayType01 := DefPropDelay01; tipd_scanclk : VitalDelayType01 := DefPropDelay01; tipd_scanclkena : VitalDelayType01 := DefPropDelay01; tipd_scandata : VitalDelayType01 := DefPropDelay01; tipd_configupdate : VitalDelayType01 := DefPropDelay01; tipd_clkswitch : VitalDelayType01 := DefPropDelay01; tipd_phaseupdown : VitalDelayType01 := DefPropDelay01; tipd_phasecounterselect : VitalDelayArrayType01(2 DOWNTO 0) := (OTHERS => DefPropDelay01); tipd_phasestep : VitalDelayType01 := DefPropDelay01; tsetup_scandata_scanclk_noedge_negedge : VitalDelayType := DefSetupHoldCnst; thold_scandata_scanclk_noedge_negedge : VitalDelayType := DefSetupHoldCnst; tsetup_scanclkena_scanclk_noedge_negedge : VitalDelayType := DefSetupHoldCnst; thold_scanclkena_scanclk_noedge_negedge : VitalDelayType := DefSetupHoldCnst; use_vco_bypass : string := "false" ); PORT ( inclk : in std_logic_vector(1 downto 0); fbin : in std_logic := '0'; fbout : out std_logic; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; scandata : in std_logic := '0'; scanclk : in std_logic := '0'; scanclkena : in std_logic := '1'; configupdate : in std_logic := '0'; clk : out std_logic_vector(4 downto 0); phasecounterselect : in std_logic_vector(2 downto 0) := "000"; phaseupdown : in std_logic := '0'; phasestep : in std_logic := '0'; clkbad : out std_logic_vector(1 downto 0); activeclock : out std_logic; locked : out std_logic; scandataout : out std_logic; scandone : out std_logic; phasedone : out std_logic; vcooverrange : out std_logic; vcounderrange : out std_logic ); END cycloneive_pll; ARCHITECTURE vital_pll of cycloneive_pll is function get_vco_min_no_division(i_vco_post_scale : INTEGER) return INTEGER is begin if (i_vco_post_scale = 1) then return vco_min * 2; else return vco_min; end if; end; function get_vco_max_no_division(i_vco_post_scale : INTEGER) return INTEGER is begin if (i_vco_post_scale = 1) then return vco_max * 2; else return vco_max; end if; end; TYPE int_array is ARRAY(NATURAL RANGE <>) of integer; TYPE str_array is ARRAY(NATURAL RANGE <>) of string(1 to 6); TYPE str_array1 is ARRAY(NATURAL RANGE <>) of string(1 to 9); TYPE std_logic_array is ARRAY(NATURAL RANGE <>) of std_logic; constant VCO_MIN_NO_DIVISION : integer := get_vco_min_no_division(vco_post_scale); constant VCO_MAX_NO_DIVISION : integer := get_vco_max_no_division(vco_post_scale); -- internal advanced parameter signals signal i_vco_min : integer := vco_min; signal i_vco_max : integer := vco_max; signal i_vco_center : integer; signal i_pfd_min : integer; signal i_pfd_max : integer; signal c_ph_val : int_array(0 to 4) := (OTHERS => 0); signal c_ph_val_tmp : int_array(0 to 4) := (OTHERS => 0); signal c_high_val : int_array(0 to 4) := (OTHERS => 1); signal c_low_val : int_array(0 to 4) := (OTHERS => 1); signal c_initial_val : int_array(0 to 4) := (OTHERS => 1); signal c_mode_val : str_array(0 to 4); signal clk_num : str_array(0 to 4); -- old values signal c_high_val_old : int_array(0 to 4) := (OTHERS => 1); signal c_low_val_old : int_array(0 to 4) := (OTHERS => 1); signal c_ph_val_old : int_array(0 to 4) := (OTHERS => 0); signal c_mode_val_old : str_array(0 to 4); -- hold registers signal c_high_val_hold : int_array(0 to 4) := (OTHERS => 1); signal c_low_val_hold : int_array(0 to 4) := (OTHERS => 1); signal c_ph_val_hold : int_array(0 to 4) := (OTHERS => 0); signal c_mode_val_hold : str_array(0 to 4); -- temp registers signal sig_c_ph_val_tmp : int_array(0 to 4) := (OTHERS => 0); signal c_ph_val_orig : int_array(0 to 4) := (OTHERS => 0); signal real_lock_high : integer := 0; signal i_clk4_counter : integer := 4; signal i_clk3_counter : integer := 3; signal i_clk2_counter : integer := 2; signal i_clk1_counter : integer := 1; signal i_clk0_counter : integer := 0; signal i_charge_pump_current : integer; signal i_loop_filter_r : integer; -- end internal advanced parameter signals -- CONSTANTS CONSTANT SCAN_CHAIN : integer := 144; CONSTANT GPP_SCAN_CHAIN : integer := 234; CONSTANT FAST_SCAN_CHAIN : integer := 180; CONSTANT cntrs : str_array(4 downto 0) := (" C4", " C3", " C2", " C1", " C0"); CONSTANT ss_cntrs : str_array(0 to 3) := (" M", " M2", " N", " N2"); CONSTANT loop_filter_c_arr : int_array(0 to 3) := (0,0,0,0); CONSTANT fpll_loop_filter_c_arr : int_array(0 to 3) := (0,0,0,0); CONSTANT charge_pump_curr_arr : int_array(0 to 15) := (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); CONSTANT num_phase_taps : integer := 8; -- signals signal vcc : std_logic := '1'; signal fbclk : std_logic; signal refclk : std_logic; signal vco_over : std_logic := '0'; signal vco_under : std_logic := '1'; signal pll_locked : boolean := false; signal c_clk : std_logic_array(0 to 4); signal vco_out : std_logic_vector(7 downto 0) := (OTHERS => '0'); -- signals to assign values to counter params signal m_val : integer := 1; signal n_val : integer := 1; signal m_ph_val : integer := 0; signal m_ph_initial : integer := 0; signal m_ph_val_tmp : integer := 0; signal m_initial_val : integer := m_initial; signal m_mode_val : string(1 to 6) := " "; signal n_mode_val : string(1 to 6) := " "; signal lfc_val : integer := 0; signal vco_cur : integer := vco_post_scale; signal cp_curr_val : integer := 0; signal lfr_val : string(1 to 2) := " "; signal cp_curr_old_bit_setting : integer := charge_pump_current_bits; signal cp_curr_val_bit_setting : std_logic_vector(2 downto 0) := (OTHERS => '0'); signal lfr_old_bit_setting : integer := loop_filter_r_bits; signal lfr_val_bit_setting : std_logic_vector(4 downto 0) := (OTHERS => '0'); signal lfc_old_bit_setting : integer := loop_filter_c_bits; signal lfc_val_bit_setting : std_logic_vector(1 downto 0) := (OTHERS => '0'); signal pll_reconfig_display_full_setting : boolean := FALSE; -- display full setting, change to true -- old values signal m_val_old : integer := 1; signal n_val_old : integer := 1; signal m_mode_val_old : string(1 to 6) := " "; signal n_mode_val_old : string(1 to 6) := " "; signal m_ph_val_old : integer := 0; signal lfc_old : integer := 0; signal vco_old : integer := 0; signal cp_curr_old : integer := 0; signal lfr_old : string(1 to 2) := " "; signal num_output_cntrs : integer := 5; signal scanclk_period : time := 1 ps; signal scan_data : std_logic_vector(0 to 143) := (OTHERS => '0'); signal clk_pfd : std_logic_vector(0 to 4); signal clk0_tmp : std_logic; signal clk1_tmp : std_logic; signal clk2_tmp : std_logic; signal clk3_tmp : std_logic; signal clk4_tmp : std_logic; signal update_conf_latches : std_logic := '0'; signal update_conf_latches_reg : std_logic := '0'; signal clkin : std_logic := '0'; signal gate_locked : std_logic := '0'; signal pfd_locked : std_logic := '0'; signal lock : std_logic := '0'; signal about_to_lock : boolean := false; signal reconfig_err : boolean := false; signal inclk_c0 : std_logic; signal inclk_c1 : std_logic; signal inclk_c2 : std_logic; signal inclk_c3 : std_logic; signal inclk_c4 : std_logic; signal inclk_m : std_logic; signal devpor : std_logic; signal devclrn : std_logic; signal inclk0_ipd : std_logic; signal inclk1_ipd : std_logic; signal pfdena_ipd : std_logic; signal areset_ipd : std_logic; signal fbin_ipd : std_logic; signal scanclk_ipd : std_logic; signal scanclkena_ipd, scanclkena_reg : std_logic; signal scandata_ipd : std_logic; signal clkswitch_ipd : std_logic; signal phasecounterselect_ipd : std_logic_vector(2 downto 0); signal phaseupdown_ipd : std_logic; signal phasestep_ipd : std_logic; signal configupdate_ipd : std_logic; -- registered signals signal sig_offset : time := 0 ps; signal sig_refclk_time : time := 0 ps; signal sig_fbclk_period : time := 0 ps; signal sig_vco_period_was_phase_adjusted : boolean := false; signal sig_phase_adjust_was_scheduled : boolean := false; signal sig_stop_vco : std_logic := '0'; signal sig_m_times_vco_period : time := 0 ps; signal sig_new_m_times_vco_period : time := 0 ps; signal sig_got_refclk_posedge : boolean := false; signal sig_got_fbclk_posedge : boolean := false; signal sig_got_second_refclk : boolean := false; signal m_delay : integer := 0; signal n_delay : integer := 0; signal inclk1_tmp : std_logic := '0'; signal reset_low : std_logic := '0'; -- Phase Reconfig SIGNAL phasecounterselect_reg : std_logic_vector(2 DOWNTO 0); SIGNAL phaseupdown_reg : std_logic := '0'; SIGNAL phasestep_reg : std_logic := '0'; SIGNAL phasestep_high_count : integer := 0; SIGNAL update_phase : std_logic := '0'; signal scandataout_tmp : std_logic := '0'; signal scandata_in : std_logic := '0'; signal scandata_out : std_logic := '0'; signal scandone_tmp : std_logic := '1'; signal initiate_reconfig : std_logic := '0'; signal sig_refclk_period : time := (inclk0_input_frequency * 1 ps) * n; signal schedule_vco : std_logic := '0'; signal areset_ena_sig : std_logic := '0'; signal pll_in_test_mode : boolean := false; signal pll_has_just_been_reconfigured : boolean := false; signal inclk_c_from_vco : std_logic_array(0 to 4); signal inclk_m_from_vco : std_logic; SIGNAL inclk0_period : time := 0 ps; SIGNAL last_inclk0_period : time := 0 ps; SIGNAL last_inclk0_edge : time := 0 ps; SIGNAL first_inclk0_edge_detect : STD_LOGIC := '0'; SIGNAL inclk1_period : time := 0 ps; SIGNAL last_inclk1_period : time := 0 ps; SIGNAL last_inclk1_edge : time := 0 ps; SIGNAL first_inclk1_edge_detect : STD_LOGIC := '0'; COMPONENT cycloneive_mn_cntr PORT ( clk : IN std_logic; reset : IN std_logic := '0'; cout : OUT std_logic; initial_value : IN integer := 1; modulus : IN integer := 1; time_delay : IN integer := 0 ); END COMPONENT; COMPONENT cycloneive_scale_cntr PORT ( clk : IN std_logic; reset : IN std_logic := '0'; cout : OUT std_logic; initial : IN integer := 1; high : IN integer := 1; low : IN integer := 1; mode : IN string := "bypass"; ph_tap : IN integer := 0 ); END COMPONENT; COMPONENT cycloneive_dffe GENERIC( TimingChecksOn: Boolean := true; InstancePath: STRING := "*"; XOn: Boolean := DefGlitchXOn; MsgOn: Boolean := DefGlitchMsgOn; MsgOnChecks: Boolean := DefMsgOnChecks; XOnChecks: Boolean := DefXOnChecks; tpd_PRN_Q_negedge : VitalDelayType01 := DefPropDelay01; tpd_CLRN_Q_negedge : VitalDelayType01 := DefPropDelay01; tpd_CLK_Q_posedge : VitalDelayType01 := DefPropDelay01; tpd_ENA_Q_posedge : VitalDelayType01 := DefPropDelay01; tsetup_D_CLK_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_D_CLK_noedge_negedge : VitalDelayType := DefSetupHoldCnst; tsetup_ENA_CLK_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_D_CLK_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_D_CLK_noedge_negedge : VitalDelayType := DefSetupHoldCnst; thold_ENA_CLK_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tipd_D : VitalDelayType01 := DefPropDelay01; tipd_CLRN : VitalDelayType01 := DefPropDelay01; tipd_PRN : VitalDelayType01 := DefPropDelay01; tipd_CLK : VitalDelayType01 := DefPropDelay01; tipd_ENA : VitalDelayType01 := DefPropDelay01); PORT( Q : out STD_LOGIC := '0'; D : in STD_LOGIC := '1'; CLRN : in STD_LOGIC := '1'; PRN : in STD_LOGIC := '1'; CLK : in STD_LOGIC := '0'; ENA : in STD_LOGIC := '1'); END COMPONENT; COMPONENT cycloneive_pll_reg PORT( Q : out STD_LOGIC := '0'; D : in STD_LOGIC := '1'; CLRN : in STD_LOGIC := '1'; PRN : in STD_LOGIC := '1'; CLK : in STD_LOGIC := '0'; ENA : in STD_LOGIC := '1'); END COMPONENT; begin ---------------------- -- INPUT PATH DELAYs ---------------------- WireDelay : block begin VitalWireDelay (inclk0_ipd, inclk(0), tipd_inclk(0)); VitalWireDelay (inclk1_ipd, inclk(1), tipd_inclk(1)); VitalWireDelay (areset_ipd, areset, tipd_areset); VitalWireDelay (pfdena_ipd, pfdena, tipd_pfdena); VitalWireDelay (scanclk_ipd, scanclk, tipd_scanclk); VitalWireDelay (scanclkena_ipd, scanclkena, tipd_scanclkena); VitalWireDelay (scandata_ipd, scandata, tipd_scandata); VitalWireDelay (configupdate_ipd, configupdate, tipd_configupdate); VitalWireDelay (clkswitch_ipd, clkswitch, tipd_clkswitch); VitalWireDelay (phaseupdown_ipd, phaseupdown, tipd_phaseupdown); VitalWireDelay (phasestep_ipd, phasestep, tipd_phasestep); VitalWireDelay (phasecounterselect_ipd(0), phasecounterselect(0), tipd_phasecounterselect(0)); VitalWireDelay (phasecounterselect_ipd(1), phasecounterselect(1), tipd_phasecounterselect(1)); VitalWireDelay (phasecounterselect_ipd(2), phasecounterselect(2), tipd_phasecounterselect(2)); end block; inclk_m <= fbclk when m_test_source = 0 else refclk when m_test_source = 1 else inclk_m_from_vco; areset_ena_sig <= areset_ipd or sig_stop_vco; pll_in_test_mode <= true when (m_test_source /= -1 or c0_test_source /= -1 or c1_test_source /= -1 or c2_test_source /= -1 or c3_test_source /= -1 or c4_test_source /= -1) else false; real_lock_high <= lock_high WHEN (sim_gate_lock_device_behavior = "on") ELSE 0; m1 : cycloneive_mn_cntr port map ( clk => inclk_m, reset => areset_ena_sig, cout => fbclk, initial_value => m_initial_val, modulus => m_val, time_delay => m_delay ); -- add delta delay to inclk1 to ensure inclk0 and inclk1 are processed -- in different simulation deltas. inclk1_tmp <= inclk1_ipd; -- Calculate the inclk0 period PROCESS VARIABLE inclk0_period_tmp : time := 0 ps; BEGIN WAIT UNTIL (inclk0_ipd'EVENT AND inclk0_ipd = '1'); IF (first_inclk0_edge_detect = '0') THEN first_inclk0_edge_detect <= '1'; ELSE last_inclk0_period <= inclk0_period; inclk0_period_tmp := NOW - last_inclk0_edge; END IF; last_inclk0_edge <= NOW; inclk0_period <= inclk0_period_tmp; END PROCESS; -- Calculate the inclk1 period PROCESS VARIABLE inclk1_period_tmp : time := 0 ps; BEGIN WAIT UNTIL (inclk1_ipd'EVENT AND inclk1_ipd = '1'); IF (first_inclk1_edge_detect = '0') THEN first_inclk1_edge_detect <= '1'; ELSE last_inclk1_period <= inclk1_period; inclk1_period_tmp := NOW - last_inclk1_edge; END IF; last_inclk1_edge <= NOW; inclk1_period <= inclk1_period_tmp; END PROCESS; process (inclk0_ipd, inclk1_tmp, clkswitch_ipd) variable input_value : std_logic := '0'; variable current_clock : integer := 0; variable clk0_count, clk1_count : integer := 0; variable clk0_is_bad, clk1_is_bad : std_logic := '0'; variable primary_clk_is_bad : boolean := false; variable current_clk_is_bad : boolean := false; variable got_curr_clk_falling_edge_after_clkswitch : boolean := false; variable switch_over_count : integer := 0; variable active_clock : std_logic := '0'; variable external_switch : boolean := false; variable diff_percent_period : integer := 0; variable buf : line; variable switch_clock : boolean := false; begin if (now = 0 ps) then if (switch_over_type = "manual" and clkswitch_ipd = '1') then current_clock := 1; active_clock := '1'; end if; end if; if (clkswitch_ipd'event and clkswitch_ipd = '1' and switch_over_type = "auto") then external_switch := true; elsif (switch_over_type = "manual") then if (clkswitch_ipd'event and clkswitch_ipd = '1') then switch_clock := true; elsif (clkswitch_ipd'event and clkswitch_ipd = '0') then switch_clock := false; end if; end if; if (switch_clock = true) then if (inclk0_ipd'event or inclk1_tmp'event) then if (current_clock = 0) then current_clock := 1; active_clock := '1'; clkin <= transport inclk1_tmp; elsif (current_clock = 1) then current_clock := 0; active_clock := '0'; clkin <= transport inclk0_ipd; end if; switch_clock := false; end if; end if; -- save the current inclk event value if (inclk0_ipd'event) then input_value := inclk0_ipd; elsif (inclk1_tmp'event) then input_value := inclk1_tmp; end if; -- check if either input clk is bad if (inclk0_ipd'event and inclk0_ipd = '1') then clk0_count := clk0_count + 1; clk0_is_bad := '0'; clk1_count := 0; if (clk0_count > 2) then -- no event on other clk for 2 cycles clk1_is_bad := '1'; if (current_clock = 1) then current_clk_is_bad := true; end if; end if; end if; if (inclk1_tmp'event and inclk1_tmp = '1') then clk1_count := clk1_count + 1; clk1_is_bad := '0'; clk0_count := 0; if (clk1_count > 2) then -- no event on other clk for 2 cycles clk0_is_bad := '1'; if (current_clock = 0) then current_clk_is_bad := true; end if; end if; end if; -- check if the bad clk is the primary clock if (clk0_is_bad = '1') then primary_clk_is_bad := true; else primary_clk_is_bad := false; end if; -- actual switching if (inclk0_ipd'event and current_clock = 0) then if (external_switch) then if (not got_curr_clk_falling_edge_after_clkswitch) then if (inclk0_ipd = '0') then got_curr_clk_falling_edge_after_clkswitch := true; end if; clkin <= transport inclk0_ipd; end if; else clkin <= transport inclk0_ipd; end if; elsif (inclk1_tmp'event and current_clock = 1) then if (external_switch) then if (not got_curr_clk_falling_edge_after_clkswitch) then if (inclk1_tmp = '0') then got_curr_clk_falling_edge_after_clkswitch := true; end if; clkin <= transport inclk1_tmp; end if; else clkin <= transport inclk1_tmp; end if; else if (input_value = '1' and enable_switch_over_counter = "on" and primary_clk_is_bad) then switch_over_count := switch_over_count + 1; end if; if ((input_value = '0')) then if (external_switch and (got_curr_clk_falling_edge_after_clkswitch or current_clk_is_bad)) or (primary_clk_is_bad and clkswitch_ipd /= '1' and (enable_switch_over_counter = "off" or switch_over_count = switch_over_counter)) then got_curr_clk_falling_edge_after_clkswitch := false; if (areset_ipd = '0') then if ((inclk0_period > inclk1_period) and (inclk1_period /= 0 ps)) then diff_percent_period := (( inclk0_period - inclk1_period ) * 100) / inclk1_period; elsif (inclk0_period /= 0 ps) then diff_percent_period := (( inclk1_period - inclk0_period ) * 100) / inclk0_period; end if; if((diff_percent_period > 20)and ( switch_over_type = "auto")) then WRITE(buf,string'("Warning : The input clock frequencies specified for the specified PLL are too far apart for auto-switch-over feature to work properly. Please make sure that the clock frequencies are 20 percent apart for correct functionality.")); writeline(output, buf); end if; end if; if (current_clock = 0) then current_clock := 1; else current_clock := 0; end if; active_clock := not active_clock; switch_over_count := 0; external_switch := false; current_clk_is_bad := false; else if(switch_over_type = "auto") then if(current_clock = 0 and clk0_is_bad = '1' and clk1_is_bad = '0' ) then current_clock := 1; active_clock := not active_clock; end if; if(current_clock = 1 and clk0_is_bad = '0' and clk1_is_bad = '1' ) then current_clock := 0; active_clock := not active_clock; end if; end if; end if; end if; end if; -- schedule outputs clkbad(0) <= clk0_is_bad; clkbad(1) <= clk1_is_bad; activeclock <= active_clock; end process; n1 : cycloneive_mn_cntr port map ( clk => clkin, reset => areset_ipd, cout => refclk, initial_value => n_val, modulus => n_val); inclk_c0 <= refclk when c0_test_source = 1 else fbclk when c0_test_source = 0 else inclk_c_from_vco(0); c0 : cycloneive_scale_cntr port map ( clk => inclk_c0, reset => areset_ena_sig, cout => c_clk(0), initial => c_initial_val(0), high => c_high_val(0), low => c_low_val(0), mode => c_mode_val(0), ph_tap => c_ph_val(0)); inclk_c1 <= refclk when c1_test_source = 1 else fbclk when c1_test_source = 0 else c_clk(0) when c1_use_casc_in = "on" else inclk_c_from_vco(1); c1 : cycloneive_scale_cntr port map ( clk => inclk_c1, reset => areset_ena_sig, cout => c_clk(1), initial => c_initial_val(1), high => c_high_val(1), low => c_low_val(1), mode => c_mode_val(1), ph_tap => c_ph_val(1)); inclk_c2 <= refclk when c2_test_source = 1 else fbclk when c2_test_source = 0 else c_clk(1) when c2_use_casc_in = "on" else inclk_c_from_vco(2); c2 : cycloneive_scale_cntr port map ( clk => inclk_c2, reset => areset_ena_sig, cout => c_clk(2), initial => c_initial_val(2), high => c_high_val(2), low => c_low_val(2), mode => c_mode_val(2), ph_tap => c_ph_val(2)); inclk_c3 <= refclk when c3_test_source = 1 else fbclk when c3_test_source = 0 else c_clk(2) when c3_use_casc_in = "on" else inclk_c_from_vco(3); c3 : cycloneive_scale_cntr port map ( clk => inclk_c3, reset => areset_ena_sig, cout => c_clk(3), initial => c_initial_val(3), high => c_high_val(3), low => c_low_val(3), mode => c_mode_val(3), ph_tap => c_ph_val(3)); inclk_c4 <= refclk when c4_test_source = 1 else fbclk when c4_test_source = 0 else c_clk(3) when (c4_use_casc_in = "on") else inclk_c_from_vco(4); c4 : cycloneive_scale_cntr port map ( clk => inclk_c4, reset => areset_ena_sig, cout => c_clk(4), initial => c_initial_val(4), high => c_high_val(4), low => c_low_val(4), mode => c_mode_val(4), ph_tap => c_ph_val(4)); process(scandone_tmp, lock) begin if (scandone_tmp'event and (scandone_tmp = '1')) then pll_has_just_been_reconfigured <= true; elsif (lock'event and (lock = '1')) then pll_has_just_been_reconfigured <= false; end if; end process; process(inclk_c0, inclk_c1, areset_ipd, sig_stop_vco) variable c0_got_first_rising_edge : boolean := false; variable c0_count : integer := 2; variable c0_initial_count : integer := 1; variable c0_tmp, c1_tmp : std_logic := '0'; variable c1_got_first_rising_edge : boolean := false; variable c1_count : integer := 2; variable c1_initial_count : integer := 1; begin if (areset_ipd = '1' or sig_stop_vco = '1') then c0_count := 2; c1_count := 2; c0_initial_count := 1; c1_initial_count := 1; c0_got_first_rising_edge := false; c1_got_first_rising_edge := false; else if (not c0_got_first_rising_edge) then if (inclk_c0'event and inclk_c0 = '1') then if (c0_initial_count = c_initial_val(0)) then c0_got_first_rising_edge := true; else c0_initial_count := c0_initial_count + 1; end if; end if; elsif (inclk_c0'event) then c0_count := c0_count + 1; if (c0_count = (c_high_val(0) + c_low_val(0)) * 2) then c0_count := 1; end if; end if; if (inclk_c0'event and inclk_c0 = '0') then if (c0_count = 1) then c0_tmp := '1'; c0_got_first_rising_edge := false; else c0_tmp := '0'; end if; end if; if (not c1_got_first_rising_edge) then if (inclk_c1'event and inclk_c1 = '1') then if (c1_initial_count = c_initial_val(1)) then c1_got_first_rising_edge := true; else c1_initial_count := c1_initial_count + 1; end if; end if; elsif (inclk_c1'event) then c1_count := c1_count + 1; if (c1_count = (c_high_val(1) + c_low_val(1)) * 2) then c1_count := 1; end if; end if; if (inclk_c1'event and inclk_c1 = '0') then if (c1_count = 1) then c1_tmp := '1'; c1_got_first_rising_edge := false; else c1_tmp := '0'; end if; end if; end if; end process; locked <= pfd_locked WHEN (test_bypass_lock_detect = "on") ELSE lock; process (scandone_tmp) variable buf : line; begin if (scandone_tmp'event and scandone_tmp = '1') then if (reconfig_err = false) then ASSERT false REPORT "PLL Reprogramming completed with the following values (Values in parantheses indicate values before reprogramming) :" severity note; write (buf, string'(" N modulus = ")); write (buf, n_val); write (buf, string'(" ( ")); write (buf, n_val_old); write (buf, string'(" )")); writeline (output, buf); write (buf, string'(" M modulus = ")); write (buf, m_val); write (buf, string'(" ( ")); write (buf, m_val_old); write (buf, string'(" )")); writeline (output, buf); write (buf, string'(" M ph_tap = ")); write (buf, m_ph_val); write (buf, string'(" ( ")); write (buf, m_ph_val_old); write (buf, string'(" )")); writeline (output, buf); for i in 0 to (num_output_cntrs-1) loop write (buf, clk_num(i)); write (buf, string'(" : ")); write (buf, cntrs(i)); write (buf, string'(" : high = ")); write (buf, c_high_val(i)); write (buf, string'(" (")); write (buf, c_high_val_old(i)); write (buf, string'(") ")); write (buf, string'(" , low = ")); write (buf, c_low_val(i)); write (buf, string'(" (")); write (buf, c_low_val_old(i)); write (buf, string'(") ")); write (buf, string'(" , mode = ")); write (buf, c_mode_val(i)); write (buf, string'(" (")); write (buf, c_mode_val_old(i)); write (buf, string'(") ")); write (buf, string'(" , phase tap = ")); write (buf, c_ph_val(i)); write (buf, string'(" (")); write (buf, c_ph_val_old(i)); write (buf, string'(") ")); writeline(output, buf); end loop; IF (pll_reconfig_display_full_setting) THEN write (buf, string'(" Charge Pump Current (uA) = ")); write (buf, cp_curr_val); write (buf, string'(" ( ")); write (buf, cp_curr_old); write (buf, string'(" ) ")); writeline (output, buf); write (buf, string'(" Loop Filter Capacitor (pF) = ")); write (buf, lfc_val); write (buf, string'(" ( ")); write (buf, lfc_old); write (buf, string'(" ) ")); writeline (output, buf); write (buf, string'(" Loop Filter Resistor (Kohm) = ")); write (buf, lfr_val); write (buf, string'(" ( ")); write (buf, lfr_old); write (buf, string'(" ) ")); writeline (output, buf); write (buf, string'(" VCO_Post_Scale = ")); write (buf, vco_cur); write (buf, string'(" ( ")); write (buf, vco_old); write (buf, string'(" ) ")); writeline (output, buf); ELSE write (buf, string'(" Charge Pump Current (bit setting) = ")); write (buf, alt_conv_integer(cp_curr_val_bit_setting)); write (buf, string'(" ( ")); write (buf, cp_curr_old_bit_setting); write (buf, string'(" ) ")); writeline (output, buf); write (buf, string'(" Loop Filter Capacitor (bit setting) = ")); write (buf, alt_conv_integer(lfc_val_bit_setting)); write (buf, string'(" ( ")); write (buf, lfc_old_bit_setting); write (buf, string'(" ) ")); writeline (output, buf); write (buf, string'(" Loop Filter Resistor (bit setting) = ")); write (buf, alt_conv_integer(lfr_val_bit_setting)); write (buf, string'(" ( ")); write (buf, lfr_old_bit_setting); write (buf, string'(" ) ")); writeline (output, buf); write (buf, string'(" VCO_Post_Scale = ")); write (buf, vco_cur); write (buf, string'(" ( ")); write (buf, vco_old); write (buf, string'(" ) ")); writeline (output, buf); END IF; cp_curr_old_bit_setting <= alt_conv_integer(cp_curr_val_bit_setting); lfc_old_bit_setting <= alt_conv_integer(lfc_val_bit_setting); lfr_old_bit_setting <= alt_conv_integer(lfr_val_bit_setting); else ASSERT false REPORT "Errors were encountered during PLL reprogramming. Please refer to error/warning messages above." severity warning; end if; end if; end process; update_conf_latches <= configupdate_ipd; process (scandone_tmp,areset_ipd,update_conf_latches, c_clk(0), c_clk(1), c_clk(2), c_clk(3), c_clk(4), vco_out, fbclk, scanclk_ipd) variable init : boolean := true; variable low, high : std_logic_vector(7 downto 0); variable low_fast, high_fast : std_logic_vector(3 downto 0); variable mode : string(1 to 6) := "bypass"; variable is_error : boolean := false; variable m_tmp, n_tmp : std_logic_vector(8 downto 0); variable lfr_val_tmp : string(1 to 2) := " "; variable c_high_val_tmp,c_hval : int_array(0 to 4) := (OTHERS => 1); variable c_low_val_tmp,c_lval : int_array(0 to 4) := (OTHERS => 1); variable c_mode_val_tmp : str_array(0 to 4); variable m_val_tmp : integer := 0; variable c0_rising_edge_transfer_done : boolean := false; variable c1_rising_edge_transfer_done : boolean := false; variable c2_rising_edge_transfer_done : boolean := false; variable c3_rising_edge_transfer_done : boolean := false; variable c4_rising_edge_transfer_done : boolean := false; -- variables for scaling of multiply_by and divide_by values variable i_clk0_mult_by : integer := 1; variable i_clk0_div_by : integer := 1; variable i_clk1_mult_by : integer := 1; variable i_clk1_div_by : integer := 1; variable i_clk2_mult_by : integer := 1; variable i_clk2_div_by : integer := 1; variable i_clk3_mult_by : integer := 1; variable i_clk3_div_by : integer := 1; variable i_clk4_mult_by : integer := 1; variable i_clk4_div_by : integer := 1; variable max_d_value : integer := 1; variable new_multiplier : integer := 1; -- internal variables for storing the phase shift number.(used in lvds mode only) variable i_clk0_phase_shift : integer := 1; variable i_clk1_phase_shift : integer := 1; variable i_clk2_phase_shift : integer := 1; -- user to advanced variables variable max_neg_abs : integer := 0; variable i_m_initial : integer; variable i_m : integer := 1; variable i_n : integer := 1; variable i_c_high : int_array(0 to 4); variable i_c_low : int_array(0 to 4); variable i_c_initial : int_array(0 to 4); variable i_c_ph : int_array(0 to 4); variable i_c_mode : str_array(0 to 4); variable i_m_ph : integer; variable output_count : integer; variable new_divisor : integer; variable clk0_cntr : string(1 to 6) := " c0"; variable clk1_cntr : string(1 to 6) := " c1"; variable clk2_cntr : string(1 to 6) := " c2"; variable clk3_cntr : string(1 to 6) := " c3"; variable clk4_cntr : string(1 to 6) := " c4"; variable fbk_cntr : string(1 to 2); variable fbk_cntr_index : integer; variable start_bit : integer; variable quiet_time : time := 0 ps; variable slowest_clk_old : time := 0 ps; variable slowest_clk_new : time := 0 ps; variable i : integer := 0; variable j : integer := 0; variable scanread_active_edge : time := 0 ps; variable got_first_scanclk : boolean := false; variable scanclk_last_rising_edge : time := 0 ps; variable current_scan_data : std_logic_vector(0 to 143) := (OTHERS => '0'); variable index : integer := 0; variable Tviol_scandata_scanclk : std_ulogic := '0'; variable TimingData_scandata_scanclk : VitalTimingDataType := VitalTimingDataInit; variable Tviol_scanclkena_scanclk : std_ulogic := '0'; variable TimingData_scanclkena_scanclk : VitalTimingDataType := VitalTimingDataInit; variable scan_chain_length : integer := GPP_SCAN_CHAIN; variable tmp_rem : integer := 0; variable scanclk_cycles : integer := 0; variable lfc_tmp : std_logic_vector(1 downto 0); variable lfr_tmp : std_logic_vector(5 downto 0); variable lfr_int : integer := 0; variable n_hi,n_lo,m_hi,m_lo : std_logic_vector(7 downto 0); variable buf : line; variable buf_scan_data : STD_LOGIC_VECTOR(0 TO 1) := (OTHERS => '0'); variable buf_scan_data_2 : STD_LOGIC_VECTOR(0 TO 2) := (OTHERS => '0'); function slowest_clk ( C0 : integer; C0_mode : string(1 to 6); C1 : integer; C1_mode : string(1 to 6); C2 : integer; C2_mode : string(1 to 6); C3 : integer; C3_mode : string(1 to 6); C4 : integer; C4_mode : string(1 to 6); C5 : integer; C5_mode : string(1 to 6); C6 : integer; C6_mode : string(1 to 6); C7 : integer; C7_mode : string(1 to 6); C8 : integer; C8_mode : string(1 to 6); C9 : integer; C9_mode : string(1 to 6); refclk : time; m_mod : integer) return time is variable max_modulus : integer := 1; variable q_period : time := 0 ps; variable refclk_int : integer := 0; begin if (C0_mode /= "bypass" and C0_mode /= " off") then max_modulus := C0; end if; if (C1 > max_modulus and C1_mode /= "bypass" and C1_mode /= " off") then max_modulus := C1; end if; if (C2 > max_modulus and C2_mode /= "bypass" and C2_mode /= " off") then max_modulus := C2; end if; if (C3 > max_modulus and C3_mode /= "bypass" and C3_mode /= " off") then max_modulus := C3; end if; if (C4 > max_modulus and C4_mode /= "bypass" and C4_mode /= " off") then max_modulus := C4; end if; if (C5 > max_modulus and C5_mode /= "bypass" and C5_mode /= " off") then max_modulus := C5; end if; if (C6 > max_modulus and C6_mode /= "bypass" and C6_mode /= " off") then max_modulus := C6; end if; if (C7 > max_modulus and C7_mode /= "bypass" and C7_mode /= " off") then max_modulus := C7; end if; if (C8 > max_modulus and C8_mode /= "bypass" and C8_mode /= " off") then max_modulus := C8; end if; if (C9 > max_modulus and C9_mode /= "bypass" and C9_mode /= " off") then max_modulus := C9; end if; refclk_int := refclk / 1 ps; if (m_mod /= 0) then q_period := (refclk_int * max_modulus / m_mod) * 1 ps; end if; return (2*q_period); end slowest_clk; function int2bin (arg : integer; size : integer) return std_logic_vector is variable int_val : integer := arg; variable result : std_logic_vector(size-1 downto 0); begin for i in 0 to result'left loop if ((int_val mod 2) = 0) then result(i) := '0'; else result(i) := '1'; end if; int_val := int_val/2; end loop; return result; end int2bin; function extract_cntr_string (arg:string) return string is variable str : string(1 to 6) := " c0"; begin if (arg = "c0") then str := " c0"; elsif (arg = "c1") then str := " c1"; elsif (arg = "c2") then str := " c2"; elsif (arg = "c3") then str := " c3"; elsif (arg = "c4") then str := " c4"; elsif (arg = "c5") then str := " c5"; elsif (arg = "c6") then str := " c6"; elsif (arg = "c7") then str := " c7"; elsif (arg = "c8") then str := " c8"; elsif (arg = "c9") then str := " c9"; else str := " c0"; end if; return str; end extract_cntr_string; function extract_cntr_index (arg:string) return integer is variable index : integer := 0; begin if (arg(6) = '0') then index := 0; elsif (arg(6) = '1') then index := 1; elsif (arg(6) = '2') then index := 2; elsif (arg(6) = '3') then index := 3; elsif (arg(6) = '4') then index := 4; elsif (arg(6) = '5') then index := 5; elsif (arg(6) = '6') then index := 6; elsif (arg(6) = '7') then index := 7; elsif (arg(6) = '8') then index := 8; else index := 9; end if; return index; end extract_cntr_index; function output_cntr_num (arg:string) return string is variable str : string(1 to 6) := "unused"; begin if (arg = "c0") then str := " clk0"; elsif (arg = "c1") then str := " clk1"; elsif (arg = "c2") then str := " clk2"; elsif (arg = "c3") then str := " clk3"; elsif (arg = "c4") then str := " clk4"; elsif (arg = "c5") then str := " clk5"; elsif (arg = "c6") then str := " clk6"; elsif (arg = "c7") then str := " clk7"; elsif (arg = "c8") then str := " clk8"; elsif (arg = "c9") then str := " clk9"; else str := "unused"; end if; return str; end output_cntr_num; begin IF (areset_ipd'EVENT AND areset_ipd = '1') then c_ph_val <= i_c_ph; END IF; if (init) then if (m = 0) then clk4_cntr := " c4"; clk3_cntr := " c3"; clk2_cntr := " c2"; clk1_cntr := " c1"; clk0_cntr := " c0"; else clk4_cntr := extract_cntr_string(clk4_counter); clk3_cntr := extract_cntr_string(clk3_counter); clk2_cntr := extract_cntr_string(clk2_counter); clk1_cntr := extract_cntr_string(clk1_counter); clk0_cntr := extract_cntr_string(clk0_counter); end if; clk_num(4) <= output_cntr_num(clk4_counter); clk_num(3) <= output_cntr_num(clk3_counter); clk_num(2) <= output_cntr_num(clk2_counter); clk_num(1) <= output_cntr_num(clk1_counter); clk_num(0) <= output_cntr_num(clk0_counter); i_clk0_counter <= extract_cntr_index(clk0_cntr); i_clk1_counter <= extract_cntr_index(clk1_cntr); i_clk2_counter <= extract_cntr_index(clk2_cntr); i_clk3_counter <= extract_cntr_index(clk3_cntr); i_clk4_counter <= extract_cntr_index(clk4_cntr); if (m = 0) then -- convert user parameters to advanced -- set the limit of the divide_by value that can be returned by -- the following function. max_d_value := 1500; -- scale down the multiply_by and divide_by values provided by the design -- before attempting to use them in the calculations below find_simple_integer_fraction(clk0_multiply_by, clk0_divide_by, max_d_value, i_clk0_mult_by, i_clk0_div_by); find_simple_integer_fraction(clk1_multiply_by, clk1_divide_by, max_d_value, i_clk1_mult_by, i_clk1_div_by); find_simple_integer_fraction(clk2_multiply_by, clk2_divide_by, max_d_value, i_clk2_mult_by, i_clk2_div_by); find_simple_integer_fraction(clk3_multiply_by, clk3_divide_by, max_d_value, i_clk3_mult_by, i_clk3_div_by); find_simple_integer_fraction(clk4_multiply_by, clk4_divide_by, max_d_value, i_clk4_mult_by, i_clk4_div_by); if (vco_frequency_control = "manual_phase") then find_m_and_n_4_manual_phase(inclk0_input_frequency, vco_phase_shift_step, i_clk0_mult_by, i_clk1_mult_by, i_clk2_mult_by, i_clk3_mult_by, i_clk4_mult_by, 1,1,1,1,1, i_clk0_div_by, i_clk1_div_by, i_clk2_div_by, i_clk3_div_by, i_clk4_div_by, 1,1,1,1,1, clk0_counter, clk1_counter, clk2_counter, clk3_counter, clk4_counter, "unused","unused","unused","unused","unused", i_m, i_n); elsif (((pll_type = "fast") or (pll_type = "lvds") OR (pll_type = "left_right")) and ((vco_multiply_by /= 0) and (vco_divide_by /= 0))) then i_n := vco_divide_by; i_m := vco_multiply_by; else i_n := 1; if (((pll_type = "fast") or (pll_type = "left_right")) and (compensate_clock = "lvdsclk")) then i_m := i_clk0_mult_by; else i_m := lcm (i_clk0_mult_by, i_clk1_mult_by, i_clk2_mult_by, i_clk3_mult_by, i_clk4_mult_by, 1,1,1,1,1, inclk0_input_frequency); end if; end if; if (pll_type = "flvds") then -- Need to readjust phase shift values when the clock multiply value has been readjusted. new_multiplier := clk0_multiply_by / i_clk0_mult_by; i_clk0_phase_shift := str2int(clk0_phase_shift) * new_multiplier; i_clk1_phase_shift := str2int(clk1_phase_shift) * new_multiplier; i_clk2_phase_shift := str2int(clk2_phase_shift) * new_multiplier; else i_clk0_phase_shift := str2int(clk0_phase_shift); i_clk1_phase_shift := str2int(clk1_phase_shift); i_clk2_phase_shift := str2int(clk2_phase_shift); end if; max_neg_abs := maxnegabs(i_clk0_phase_shift, i_clk1_phase_shift, i_clk2_phase_shift, str2int(clk3_phase_shift), str2int(clk4_phase_shift), 0, 0, 0, 0, 0 ); i_m_ph := counter_ph(get_phase_degree(max_neg_abs,inclk0_input_frequency), i_m, i_n); i_c_ph(0) := counter_ph(get_phase_degree(ph_adjust(i_clk0_phase_shift,max_neg_abs),inclk0_input_frequency), i_m, i_n); i_c_ph(1) := counter_ph(get_phase_degree(ph_adjust(i_clk1_phase_shift,max_neg_abs),inclk0_input_frequency), i_m, i_n); i_c_ph(2) := counter_ph(get_phase_degree(ph_adjust(i_clk2_phase_shift,max_neg_abs),inclk0_input_frequency), i_m, i_n); i_c_ph(3) := counter_ph(get_phase_degree(ph_adjust(str2int(clk3_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); i_c_ph(4) := counter_ph(get_phase_degree(ph_adjust(str2int(clk4_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); i_c_high(0) := counter_high(output_counter_value(i_clk0_div_by, i_clk0_mult_by, i_m, i_n), clk0_duty_cycle); i_c_high(1) := counter_high(output_counter_value(i_clk1_div_by, i_clk1_mult_by, i_m, i_n), clk1_duty_cycle); i_c_high(2) := counter_high(output_counter_value(i_clk2_div_by, i_clk2_mult_by, i_m, i_n), clk2_duty_cycle); i_c_high(3) := counter_high(output_counter_value(i_clk3_div_by, i_clk3_mult_by, i_m, i_n), clk3_duty_cycle); i_c_high(4) := counter_high(output_counter_value(i_clk4_div_by, i_clk4_mult_by, i_m, i_n), clk4_duty_cycle); i_c_low(0) := counter_low(output_counter_value(i_clk0_div_by, i_clk0_mult_by, i_m, i_n), clk0_duty_cycle); i_c_low(1) := counter_low(output_counter_value(i_clk1_div_by, i_clk1_mult_by, i_m, i_n), clk1_duty_cycle); i_c_low(2) := counter_low(output_counter_value(i_clk2_div_by, i_clk2_mult_by, i_m, i_n), clk2_duty_cycle); i_c_low(3) := counter_low(output_counter_value(i_clk3_div_by, i_clk3_mult_by, i_m, i_n), clk3_duty_cycle); i_c_low(4) := counter_low(output_counter_value(i_clk4_div_by, i_clk4_mult_by, i_m, i_n), clk4_duty_cycle); i_m_initial := counter_initial(get_phase_degree(max_neg_abs, inclk0_input_frequency), i_m,i_n); i_c_initial(0) := counter_initial(get_phase_degree(ph_adjust(i_clk0_phase_shift, max_neg_abs), inclk0_input_frequency), i_m, i_n); i_c_initial(1) := counter_initial(get_phase_degree(ph_adjust(i_clk1_phase_shift, max_neg_abs), inclk0_input_frequency), i_m, i_n); i_c_initial(2) := counter_initial(get_phase_degree(ph_adjust(i_clk2_phase_shift, max_neg_abs), inclk0_input_frequency), i_m, i_n); i_c_initial(3) := counter_initial(get_phase_degree(ph_adjust(str2int(clk3_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); i_c_initial(4) := counter_initial(get_phase_degree(ph_adjust(str2int(clk4_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); i_c_mode(0) := counter_mode(clk0_duty_cycle, output_counter_value(i_clk0_div_by, i_clk0_mult_by, i_m, i_n)); i_c_mode(1) := counter_mode(clk1_duty_cycle, output_counter_value(i_clk1_div_by, i_clk1_mult_by, i_m, i_n)); i_c_mode(2) := counter_mode(clk2_duty_cycle, output_counter_value(i_clk2_div_by, i_clk2_mult_by, i_m, i_n)); i_c_mode(3) := counter_mode(clk3_duty_cycle, output_counter_value(i_clk3_div_by, i_clk3_mult_by, i_m, i_n)); i_c_mode(4) := counter_mode(clk4_duty_cycle, output_counter_value(i_clk4_div_by, i_clk4_mult_by, i_m, i_n)); else -- m /= 0 i_n := n; i_m := m; i_m_initial := m_initial; i_m_ph := m_ph; i_c_ph(0) := c0_ph; i_c_ph(1) := c1_ph; i_c_ph(2) := c2_ph; i_c_ph(3) := c3_ph; i_c_ph(4) := c4_ph; i_c_high(0) := c0_high; i_c_high(1) := c1_high; i_c_high(2) := c2_high; i_c_high(3) := c3_high; i_c_high(4) := c4_high; i_c_low(0) := c0_low; i_c_low(1) := c1_low; i_c_low(2) := c2_low; i_c_low(3) := c3_low; i_c_low(4) := c4_low; i_c_initial(0) := c0_initial; i_c_initial(1) := c1_initial; i_c_initial(2) := c2_initial; i_c_initial(3) := c3_initial; i_c_initial(4) := c4_initial; i_c_mode(0) := translate_string(c0_mode); i_c_mode(1) := translate_string(c1_mode); i_c_mode(2) := translate_string(c2_mode); i_c_mode(3) := translate_string(c3_mode); i_c_mode(4) := translate_string(c4_mode); end if; -- user to advanced conversion. m_initial_val <= i_m_initial; n_val <= i_n; m_val <= i_m; if (i_m = 1) then m_mode_val <= "bypass"; else m_mode_val <= " "; end if; if (i_n = 1) then n_mode_val <= "bypass"; else n_mode_val <= " "; end if; m_ph_val <= i_m_ph; m_ph_initial <= i_m_ph; m_val_tmp := i_m; for i in 0 to 4 loop if (i_c_mode(i) = "bypass") then if (pll_type = "fast" or pll_type = "lvds" OR (pll_type = "left_right")) then i_c_high(i) := 16; i_c_low(i) := 16; else i_c_high(i) := 256; i_c_low(i) := 256; end if; end if; c_ph_val(i) <= i_c_ph(i); c_initial_val(i) <= i_c_initial(i); c_high_val(i) <= i_c_high(i); c_low_val(i) <= i_c_low(i); c_mode_val(i) <= i_c_mode(i); c_high_val_tmp(i) := i_c_high(i); c_hval(i) := i_c_high(i); c_low_val_tmp(i) := i_c_low(i); c_lval(i) := i_c_low(i); c_mode_val_tmp(i) := i_c_mode(i); c_ph_val_orig(i) <= i_c_ph(i); c_high_val_hold(i) <= i_c_high(i); c_low_val_hold(i) <= i_c_low(i); c_mode_val_hold(i) <= i_c_mode(i); end loop; scan_chain_length := SCAN_CHAIN; num_output_cntrs <= 5; init := false; elsif (scandone_tmp'EVENT AND scandone_tmp = '1') then c0_rising_edge_transfer_done := false; c1_rising_edge_transfer_done := false; c2_rising_edge_transfer_done := false; c3_rising_edge_transfer_done := false; c4_rising_edge_transfer_done := false; update_conf_latches_reg <= '0'; elsif (update_conf_latches'event and update_conf_latches = '1') then initiate_reconfig <= '1'; elsif (areset_ipd'event AND areset_ipd = '1') then if (scandone_tmp = '0') then scandone_tmp <= '1' AFTER scanclk_period; end if; elsif (scanclk_ipd'event and scanclk_ipd = '1') then IF (initiate_reconfig = '1') THEN initiate_reconfig <= '0'; ASSERT false REPORT "PLL Reprogramming Initiated" severity note; update_conf_latches_reg <= update_conf_latches; reconfig_err <= false; scandone_tmp <= '0'; cp_curr_old <= cp_curr_val; lfc_old <= lfc_val; lfr_old <= lfr_val; vco_old <= vco_cur; -- LF unused : bit 0,1 -- LF Capacitance : bits 2,3 : all values are legal buf_scan_data := scan_data(2 TO 3); IF ((pll_type = "fast") OR (pll_type = "lvds") OR (pll_type = "left_right")) THEN lfc_val <= fpll_loop_filter_c_arr(alt_conv_integer(buf_scan_data)); ELSE lfc_val <= loop_filter_c_arr(alt_conv_integer(buf_scan_data)); END IF; -- LF Resistance : bits 4-8 -- valid values - 00000,00100,10000,10100,11000,11011,11100,11110 IF (scan_data(4 TO 8) = "00000") THEN lfr_val <= "20"; ELSIF (scan_data(4 TO 8) = "00100") THEN lfr_val <= "16"; ELSIF (scan_data(4 TO 8) = "10000") THEN lfr_val <= "12"; ELSIF (scan_data(4 TO 8) = "10100") THEN lfr_val <= "08"; ELSIF (scan_data(4 TO 8) = "11000") THEN lfr_val <= "06"; ELSIF (scan_data(4 TO 8) = "11011") THEN lfr_val <= "04"; ELSIF (scan_data(4 TO 8) = "11100") THEN lfr_val <= "02"; ELSE lfr_val <= "01"; END IF; -- VCO post scale assignment if (scan_data(9) = '1') then -- vco_post_scale = 1 i_vco_max <= VCO_MAX_NO_DIVISION/2; i_vco_min <= VCO_MIN_NO_DIVISION/2; vco_cur <= 1; else i_vco_max <= vco_max; i_vco_min <= vco_min; vco_cur <= 2; end if; -- CP -- Bit 9 : CRBYPASS -- Bit 10-14 : unused -- Bits 15-17 : all values are legal buf_scan_data_2 := scan_data(15 TO 17); cp_curr_val <= charge_pump_curr_arr(alt_conv_integer(buf_scan_data_2)); -- save old values for display info. cp_curr_val_bit_setting <= scan_data(15 TO 17); lfc_val_bit_setting <= scan_data(2 TO 3); lfr_val_bit_setting <= scan_data(4 TO 8); m_val_old <= m_val; n_val_old <= n_val; m_mode_val_old <= m_mode_val; n_mode_val_old <= n_mode_val; WHILE (i < num_output_cntrs) LOOP c_high_val_old(i) <= c_high_val(i); c_low_val_old(i) <= c_low_val(i); c_mode_val_old(i) <= c_mode_val(i); i := i + 1; END LOOP; -- M counter -- 1. Mode - bypass (bit 18) IF (scan_data(18) = '1') THEN n_mode_val <= "bypass"; -- 3. Mode - odd/even (bit 27) ELSIF (scan_data(27) = '1') THEN n_mode_val <= " odd"; ELSE n_mode_val <= " even"; END IF; -- 2. High (bit 19-26) n_hi := scan_data(19 TO 26); -- 4. Low (bit 28-35) n_lo := scan_data(28 TO 35); -- N counter -- 1. Mode - bypass (bit 36) IF (scan_data(36) = '1') THEN m_mode_val <= "bypass"; -- 3. Mode - odd/even (bit 45) ELSIF (scan_data(45) = '1') THEN m_mode_val <= " odd"; ELSE m_mode_val <= " even"; END IF; -- 2. High (bit 37-44) m_hi := scan_data(37 TO 44); -- 4. Low (bit 46-53) m_lo := scan_data(46 TO 53); -- C counters (start bit 54) bit 1:mode(bypass),bit 2-9:high,bit 10:mode(odd/even),bit 11-18:low i := 0; WHILE (i < num_output_cntrs) LOOP -- 1. Mode - bypass IF (scan_data(54 + i * 18 + 0) = '1') THEN c_mode_val_tmp(i) := "bypass"; -- 3. Mode - odd/even ELSIF (scan_data(54 + i * 18 + 9) = '1') THEN c_mode_val_tmp(i) := " odd"; ELSE c_mode_val_tmp(i) := " even"; END IF; -- 2. Hi high := scan_data(54 + i * 18 + 1 TO 54 + i * 18 + 8); c_hval(i) := alt_conv_integer(high); IF (c_hval(i) /= 0) THEN c_high_val_tmp(i) := c_hval(i); ELSE c_high_val_tmp(i) := alt_conv_integer("000000001"); END IF; -- 4. Low low := scan_data(54 + i * 18 + 10 TO 54 + i * 18 + 17); c_lval(i) := alt_conv_integer(low); IF (c_lval(i) /= 0) THEN c_low_val_tmp(i) := c_lval(i); ELSE c_low_val_tmp(i) := alt_conv_integer("000000001"); END IF; i := i + 1; END LOOP; -- Legality Checks -- M counter value IF(scan_data(36) /= '1') THEN IF ((m_hi /= m_lo) and (scan_data(45) /= '1')) THEN reconfig_err <= TRUE; WRITE(buf,string'("Warning : The M counter of the " & family_name & " Fast PLL should be configured for 50%% duty cycle only. In this case the HIGH and LOW moduli programmed will result in a duty cycle other than 50%%, which is illegal. Reconfiguration may not work")); writeline(output, buf); ELSIF (m_hi /= "00000000") THEN m_val_tmp := alt_conv_integer(m_hi) + alt_conv_integer(m_lo); ELSE m_val_tmp := alt_conv_integer("000000001"); END IF; ELSE m_val_tmp := alt_conv_integer("10000000"); END IF; -- N counter value IF(scan_data(18) /= '1') THEN IF ((n_hi /= n_lo)and (scan_data(27) /= '1')) THEN reconfig_err <= TRUE; WRITE(buf,string'("Warning : The N counter of the " & family_name & " Fast PLL should be configured for 50%% duty cycle only. In this case the HIGH and LOW moduli programmed will result in a duty cycle other than 50%%, which is illegal. Reconfiguration may not work")); writeline(output, buf); ELSIF (n_hi /= "00000000") THEN n_val <= alt_conv_integer(n_hi) + alt_conv_integer(n_lo); ELSE n_val <= alt_conv_integer("000000001"); END IF; ELSE n_val <= alt_conv_integer("10000000"); END IF; -- TODO : Give warnings/errors in the following cases? -- 1. Illegal counter values (error) -- 2. Change of mode (warning) -- 3. Only 50% duty cycle allowed for M counter (odd mode - hi-lo=1,even - hi-lo=0) END IF; end if; if (fbclk'event and fbclk = '1') then m_val <= m_val_tmp; end if; if (update_conf_latches_reg = '1') then if (scanclk_ipd'event and scanclk_ipd = '1') then c0_rising_edge_transfer_done := true; c_high_val(0) <= c_high_val_tmp(0); c_mode_val(0) <= c_mode_val_tmp(0); end if; if (scanclk_ipd'event and scanclk_ipd = '1') then c1_rising_edge_transfer_done := true; c_high_val(1) <= c_high_val_tmp(1); c_mode_val(1) <= c_mode_val_tmp(1); end if; if (scanclk_ipd'event and scanclk_ipd = '1') then c2_rising_edge_transfer_done := true; c_high_val(2) <= c_high_val_tmp(2); c_mode_val(2) <= c_mode_val_tmp(2); end if; if (scanclk_ipd'event and scanclk_ipd = '1') then c_high_val(3) <= c_high_val_tmp(3); c_mode_val(3) <= c_mode_val_tmp(3); c3_rising_edge_transfer_done := true; end if; if (scanclk_ipd'event and scanclk_ipd = '1') then c_high_val(4) <= c_high_val_tmp(4); c_mode_val(4) <= c_mode_val_tmp(4); c4_rising_edge_transfer_done := true; end if; end if; if (scanclk_ipd'event and scanclk_ipd = '0' and c0_rising_edge_transfer_done) then c_low_val(0) <= c_low_val_tmp(0); end if; if (scanclk_ipd'event and scanclk_ipd = '0' and c1_rising_edge_transfer_done) then c_low_val(1) <= c_low_val_tmp(1); end if; if (scanclk_ipd'event and scanclk_ipd = '0' and c2_rising_edge_transfer_done) then c_low_val(2) <= c_low_val_tmp(2); end if; if (scanclk_ipd'event and scanclk_ipd = '0' and c3_rising_edge_transfer_done) then c_low_val(3) <= c_low_val_tmp(3); end if; if (scanclk_ipd'event and scanclk_ipd = '0' and c4_rising_edge_transfer_done) then c_low_val(4) <= c_low_val_tmp(4); end if; if (update_phase = '1') then if (vco_out(0)'event and vco_out(0) = '0') then for i in 0 to 4 loop if (c_ph_val(i) = 0) then c_ph_val(i) <= c_ph_val_tmp(i); end if; end loop; if (m_ph_val = 0) then m_ph_val <= m_ph_val_tmp; end if; end if; if (vco_out(1)'event and vco_out(1) = '0') then for i in 0 to 4 loop if (c_ph_val(i) = 1) then c_ph_val(i) <= c_ph_val_tmp(i); end if; end loop; if (m_ph_val = 1) then m_ph_val <= m_ph_val_tmp; end if; end if; if (vco_out(2)'event and vco_out(2) = '0') then for i in 0 to 4 loop if (c_ph_val(i) = 2) then c_ph_val(i) <= c_ph_val_tmp(i); end if; end loop; if (m_ph_val = 2) then m_ph_val <= m_ph_val_tmp; end if; end if; if (vco_out(3)'event and vco_out(3) = '0') then for i in 0 to 4 loop if (c_ph_val(i) = 3) then c_ph_val(i) <= c_ph_val_tmp(i); end if; end loop; if (m_ph_val = 3) then m_ph_val <= m_ph_val_tmp; end if; end if; if (vco_out(4)'event and vco_out(4) = '0') then for i in 0 to 4 loop if (c_ph_val(i) = 4) then c_ph_val(i) <= c_ph_val_tmp(i); end if; end loop; if (m_ph_val = 4) then m_ph_val <= m_ph_val_tmp; end if; end if; if (vco_out(5)'event and vco_out(5) = '0') then for i in 0 to 4 loop if (c_ph_val(i) = 5) then c_ph_val(i) <= c_ph_val_tmp(i); end if; end loop; if (m_ph_val = 5) then m_ph_val <= m_ph_val_tmp; end if; end if; if (vco_out(6)'event and vco_out(6) = '0') then for i in 0 to 4 loop if (c_ph_val(i) = 6) then c_ph_val(i) <= c_ph_val_tmp(i); end if; end loop; if (m_ph_val = 6) then m_ph_val <= m_ph_val_tmp; end if; end if; if (vco_out(7)'event and vco_out(7) = '0') then for i in 0 to 4 loop if (c_ph_val(i) = 7) then c_ph_val(i) <= c_ph_val_tmp(i); end if; end loop; if (m_ph_val = 7) then m_ph_val <= m_ph_val_tmp; end if; end if; end if; if (vco_out(0)'event) then for i in 0 to 4 loop if (c_ph_val(i) = 0) then inclk_c_from_vco(i) <= vco_out(0); end if; end loop; if (m_ph_val = 0) then inclk_m_from_vco <= vco_out(0); end if; end if; if (vco_out(1)'event) then for i in 0 to 4 loop if (c_ph_val(i) = 1) then inclk_c_from_vco(i) <= vco_out(1); end if; end loop; if (m_ph_val = 1) then inclk_m_from_vco <= vco_out(1); end if; end if; if (vco_out(2)'event) then for i in 0 to 4 loop if (c_ph_val(i) = 2) then inclk_c_from_vco(i) <= vco_out(2); end if; end loop; if (m_ph_val = 2) then inclk_m_from_vco <= vco_out(2); end if; end if; if (vco_out(3)'event) then for i in 0 to 4 loop if (c_ph_val(i) = 3) then inclk_c_from_vco(i) <= vco_out(3); end if; end loop; if (m_ph_val = 3) then inclk_m_from_vco <= vco_out(3); end if; end if; if (vco_out(4)'event) then for i in 0 to 4 loop if (c_ph_val(i) = 4) then inclk_c_from_vco(i) <= vco_out(4); end if; end loop; if (m_ph_val = 4) then inclk_m_from_vco <= vco_out(4); end if; end if; if (vco_out(5)'event) then for i in 0 to 4 loop if (c_ph_val(i) = 5) then inclk_c_from_vco(i) <= vco_out(5); end if; end loop; if (m_ph_val = 5) then inclk_m_from_vco <= vco_out(5); end if; end if; if (vco_out(6)'event) then for i in 0 to 4 loop if (c_ph_val(i) = 6) then inclk_c_from_vco(i) <= vco_out(6); end if; end loop; if (m_ph_val = 6) then inclk_m_from_vco <= vco_out(6); end if; end if; if (vco_out(7)'event) then for i in 0 to 4 loop if (c_ph_val(i) = 7) then inclk_c_from_vco(i) <= vco_out(7); end if; end loop; if (m_ph_val = 7) then inclk_m_from_vco <= vco_out(7); end if; end if; ------------------------ -- Timing Check Section ------------------------ if (TimingChecksOn) then VitalSetupHoldCheck ( Violation => Tviol_scandata_scanclk, TimingData => TimingData_scandata_scanclk, TestSignal => scandata_ipd, TestSignalName => "scandata", RefSignal => scanclk_ipd, RefSignalName => "scanclk", SetupHigh => tsetup_scandata_scanclk_noedge_negedge, SetupLow => tsetup_scandata_scanclk_noedge_negedge, HoldHigh => thold_scandata_scanclk_noedge_negedge, HoldLow => thold_scandata_scanclk_noedge_negedge, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & "/cycloneive_pll", XOn => XOnChecks, MsgOn => MsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_scanclkena_scanclk, TimingData => TimingData_scanclkena_scanclk, TestSignal => scanclkena_ipd, TestSignalName => "scanclkena", RefSignal => scanclk_ipd, RefSignalName => "scanclk", SetupHigh => tsetup_scanclkena_scanclk_noedge_negedge, SetupLow => tsetup_scanclkena_scanclk_noedge_negedge, HoldHigh => thold_scanclkena_scanclk_noedge_negedge, HoldLow => thold_scanclkena_scanclk_noedge_negedge, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & "/cycloneive_pll", XOn => XOnChecks, MsgOn => MsgOnChecks ); end if; if (scanclk_ipd'event AND scanclk_ipd = '0' AND now > 0 ps) then scanclkena_reg <= scanclkena_ipd; if (scanclkena_reg = '1') then scandata_in <= scandata_ipd; scandata_out <= scandataout_tmp; end if; end if; if (scanclk_ipd'event and scanclk_ipd = '1' and now > 0 ps) then if (got_first_scanclk) then scanclk_period <= now - scanclk_last_rising_edge; else got_first_scanclk := true; end if; if (scanclkena_reg = '1') then for j in scan_chain_length - 1 downto 1 loop scan_data(j) <= scan_data(j-1); end loop; scan_data(0) <= scandata_in; end if; scanclk_last_rising_edge := now; end if; end process; -- PLL Phase Reconfiguration PROCESS(scanclk_ipd, areset_ipd,phasestep_ipd) VARIABLE i : INTEGER := 0; VARIABLE c_ph : INTEGER := 0; VARIABLE m_ph : INTEGER := 0; VARIABLE select_counter : INTEGER := 0; BEGIN IF (NOW = 0 ps) THEN m_ph_val_tmp <= m_ph_initial; END IF; -- Latch phase enable (same as phasestep) on neg edge of scan clock IF (scanclk_ipd'EVENT AND scanclk_ipd = '0') THEN phasestep_reg <= phasestep_ipd; END IF; IF (phasestep_ipd'EVENT and phasestep_ipd = '1') THEN IF (update_phase = '0') THEN phasestep_high_count <= 0; -- phase adjustments must be 1 cycle apart -- if not, next phasestep cycle is skipped END IF; END IF; -- revert counter phase tap values to POF programmed values -- if PLL is reset IF (areset_ipd'EVENT AND areset_ipd = '1') then c_ph_val_tmp <= c_ph_val_orig; m_ph_val_tmp <= m_ph_initial; END IF; IF (scanclk_ipd'EVENT AND scanclk_ipd = '1') THEN IF (phasestep_reg = '1') THEN IF (phasestep_high_count = 1) THEN phasecounterselect_reg <= phasecounterselect_ipd; phaseupdown_reg <= phaseupdown_ipd; -- start reconfiguration IF (phasecounterselect_ipd < "111") THEN -- no counters selected IF (phasecounterselect_ipd = "000") THEN i := 0; WHILE (i < num_output_cntrs) LOOP c_ph := c_ph_val(i); IF (phaseupdown_ipd = '1') THEN c_ph := (c_ph + 1) mod num_phase_taps; ELSIF (c_ph = 0) THEN c_ph := num_phase_taps - 1; ELSE c_ph := (c_ph - 1) mod num_phase_taps; END IF; c_ph_val_tmp(i) <= c_ph; i := i + 1; END LOOP; ELSIF (phasecounterselect_ipd = "001") THEN m_ph := m_ph_val; IF (phaseupdown_ipd = '1') THEN m_ph := (m_ph + 1) mod num_phase_taps; ELSIF (m_ph = 0) THEN m_ph := num_phase_taps - 1; ELSE m_ph := (m_ph - 1) mod num_phase_taps; END IF; m_ph_val_tmp <= m_ph; ELSE select_counter := alt_conv_integer(phasecounterselect_ipd) - 2; c_ph := c_ph_val(select_counter); IF (phaseupdown_ipd = '1') THEN c_ph := (c_ph + 1) mod num_phase_taps; ELSIF (c_ph = 0) THEN c_ph := num_phase_taps - 1; ELSE c_ph := (c_ph - 1) mod num_phase_taps; END IF; c_ph_val_tmp(select_counter) <= c_ph; END IF; update_phase <= '1','0' AFTER (0.5 * scanclk_period); END IF; END IF; phasestep_high_count <= phasestep_high_count + 1; END IF; END IF; END PROCESS; scandataout_tmp <= scan_data(SCAN_CHAIN - 2); process (schedule_vco, areset_ipd, pfdena_ipd, refclk, fbclk) variable sched_time : time := 0 ps; TYPE time_array is ARRAY (0 to 7) of time; variable init : boolean := true; variable refclk_period : time; variable m_times_vco_period : time; variable new_m_times_vco_period : time; variable phase_shift : time_array := (OTHERS => 0 ps); variable last_phase_shift : time_array := (OTHERS => 0 ps); variable l_index : integer := 1; variable cycle_to_adjust : integer := 0; variable stop_vco : boolean := false; variable locked_tmp : std_logic := '0'; variable pll_is_locked : boolean := false; variable cycles_pfd_low : integer := 0; variable cycles_pfd_high : integer := 0; variable cycles_to_lock : integer := 0; variable cycles_to_unlock : integer := 0; variable got_first_refclk : boolean := false; variable got_second_refclk : boolean := false; variable got_first_fbclk : boolean := false; variable refclk_time : time := 0 ps; variable fbclk_time : time := 0 ps; variable first_fbclk_time : time := 0 ps; variable fbclk_period : time := 0 ps; variable first_schedule : boolean := true; variable vco_val : std_logic := '0'; variable vco_period_was_phase_adjusted : boolean := false; variable phase_adjust_was_scheduled : boolean := false; variable loop_xplier : integer; variable loop_initial : integer := 0; variable loop_ph : integer := 0; variable loop_time_delay : integer := 0; variable initial_delay : time := 0 ps; variable vco_per : time; variable tmp_rem : integer; variable my_rem : integer; variable fbk_phase : integer := 0; variable pull_back_M : integer := 0; variable total_pull_back : integer := 0; variable fbk_delay : integer := 0; variable offset : time := 0 ps; variable tmp_vco_per : integer := 0; variable high_time : time; variable low_time : time; variable got_refclk_posedge : boolean := false; variable got_fbclk_posedge : boolean := false; variable inclk_out_of_range : boolean := false; variable no_warn : boolean := false; variable ext_fbk_cntr_modulus : integer := 1; variable init_clks : boolean := true; variable pll_is_in_reset : boolean := false; variable buf : line; begin if (init) then -- jump-start the VCO -- add 1 ps delay to ensure all signals are updated to initial -- values schedule_vco <= transport not schedule_vco after 1 ps; init := false; end if; if (schedule_vco'event) then if (init_clks) then refclk_period := inclk0_input_frequency * n_val * 1 ps; m_times_vco_period := refclk_period; new_m_times_vco_period := refclk_period; init_clks := false; end if; sched_time := 0 ps; for i in 0 to 7 loop last_phase_shift(i) := phase_shift(i); end loop; cycle_to_adjust := 0; l_index := 1; m_times_vco_period := new_m_times_vco_period; end if; -- areset was asserted if (areset_ipd'event and areset_ipd = '1') then assert false report family_name & " PLL was reset" severity note; -- reset lock parameters pll_is_locked := false; cycles_to_lock := 0; cycles_to_unlock := 0; end if; if (areset_ipd = '1') then pll_is_in_reset := true; got_first_refclk := false; got_second_refclk := false; -- drop VCO taps to 0 for i in 0 to 7 loop vco_out(i) <= transport '0' after 1 ps; end loop; end if; if (schedule_vco'event and (areset_ipd = '1' or stop_vco)) then -- drop VCO taps to 0 for i in 0 to 7 loop vco_out(i) <= transport '0' after last_phase_shift(i); phase_shift(i) := 0 ps; last_phase_shift(i) := 0 ps; end loop; -- reset lock parameters pll_is_locked := false; cycles_to_lock := 0; cycles_to_unlock := 0; got_first_refclk := false; got_second_refclk := false; refclk_time := 0 ps; got_first_fbclk := false; fbclk_time := 0 ps; first_fbclk_time := 0 ps; fbclk_period := 0 ps; first_schedule := true; vco_val := '0'; vco_period_was_phase_adjusted := false; phase_adjust_was_scheduled := false; elsif ((schedule_vco'event or areset_ipd'event) and areset_ipd = '0' and (not stop_vco) and now > 0 ps) then -- note areset deassert time -- note it as refclk_time to prevent false triggering -- of stop_vco after areset if (areset_ipd'event and areset_ipd = '0' and pll_is_in_reset) then refclk_time := now; locked_tmp := '0'; end if; pll_is_in_reset := false; -- calculate loop_xplier : this will be different from m_val -- in external_feedback_mode loop_xplier := m_val; loop_initial := m_initial_val - 1; loop_ph := m_ph_val; -- convert initial value to delay initial_delay := (loop_initial * m_times_vco_period)/loop_xplier; -- convert loop ph_tap to delay my_rem := (m_times_vco_period/1 ps) rem loop_xplier; tmp_vco_per := (m_times_vco_period/1 ps) / loop_xplier; if (my_rem /= 0) then tmp_vco_per := tmp_vco_per + 1; end if; fbk_phase := (loop_ph * tmp_vco_per)/8; pull_back_M := initial_delay/1 ps + fbk_phase; total_pull_back := pull_back_M; if (simulation_type = "timing") then total_pull_back := total_pull_back + pll_compensation_delay; end if; while (total_pull_back > refclk_period/1 ps) loop total_pull_back := total_pull_back - refclk_period/1 ps; end loop; if (total_pull_back > 0) then offset := refclk_period - (total_pull_back * 1 ps); end if; fbk_delay := total_pull_back - fbk_phase; if (fbk_delay < 0) then offset := offset - (fbk_phase * 1 ps); fbk_delay := total_pull_back; end if; -- assign m_delay m_delay <= transport fbk_delay after 1 ps; my_rem := (m_times_vco_period/1 ps) rem loop_xplier; for i in 1 to loop_xplier loop -- adjust cycles tmp_vco_per := (m_times_vco_period/1 ps)/loop_xplier; if (my_rem /= 0 and l_index <= my_rem) then tmp_rem := (loop_xplier * l_index) rem my_rem; cycle_to_adjust := (loop_xplier * l_index) / my_rem; if (tmp_rem /= 0) then cycle_to_adjust := cycle_to_adjust + 1; end if; end if; if (cycle_to_adjust = i) then tmp_vco_per := tmp_vco_per + 1; l_index := l_index + 1; end if; -- calculate high and low periods vco_per := tmp_vco_per * 1 ps; high_time := (tmp_vco_per/2) * 1 ps; if (tmp_vco_per rem 2 /= 0) then high_time := high_time + 1 ps; end if; low_time := vco_per - high_time; -- schedule the rising and falling edges for j in 1 to 2 loop vco_val := not vco_val; if (vco_val = '0') then sched_time := sched_time + high_time; elsif (vco_val = '1') then sched_time := sched_time + low_time; end if; -- schedule the phase taps for k in 0 to 7 loop phase_shift(k) := (k * vco_per)/8; if (first_schedule) then vco_out(k) <= transport vco_val after (sched_time + phase_shift(k)); else vco_out(k) <= transport vco_val after (sched_time + last_phase_shift(k)); end if; end loop; end loop; end loop; -- schedule once more if (first_schedule) then vco_val := not vco_val; if (vco_val = '0') then sched_time := sched_time + high_time; elsif (vco_val = '1') then sched_time := sched_time + low_time; end if; -- schedule the phase taps for k in 0 to 7 loop phase_shift(k) := (k * vco_per)/8; vco_out(k) <= transport vco_val after (sched_time + phase_shift(k)); end loop; first_schedule := false; end if; schedule_vco <= transport not schedule_vco after sched_time; if (vco_period_was_phase_adjusted) then m_times_vco_period := refclk_period; new_m_times_vco_period := refclk_period; vco_period_was_phase_adjusted := false; phase_adjust_was_scheduled := true; vco_per := m_times_vco_period/loop_xplier; for k in 0 to 7 loop phase_shift(k) := (k * vco_per)/8; end loop; end if; end if; -- Bypass lock detect if (refclk'event and refclk = '1' and areset_ipd = '0') then if (test_bypass_lock_detect = "on") then if (pfdena_ipd = '1') then cycles_pfd_low := 0; if (pfd_locked = '0') then if (cycles_pfd_high = lock_high) then assert false report family_name & " PLL locked in test mode on PFD enable assertion." severity warning; pfd_locked <= '1'; end if; cycles_pfd_high := cycles_pfd_high + 1; end if; end if; if (pfdena_ipd = '0') then cycles_pfd_high := 0; if (pfd_locked = '1') then if (cycles_pfd_low = lock_low) then assert false report family_name & " PLL lost lock in test mode on PFD enable de-assertion." severity warning; pfd_locked <= '0'; end if; cycles_pfd_low := cycles_pfd_low + 1; end if; end if; end if; if (refclk'event and refclk = '1' and areset_ipd = '0') then got_refclk_posedge := true; if (not got_first_refclk) then got_first_refclk := true; else got_second_refclk := true; refclk_period := now - refclk_time; -- check if incoming freq. will cause VCO range to be -- exceeded if ( (i_vco_max /= 0 and i_vco_min /= 0 and pfdena_ipd = '1') and (((refclk_period/1 ps)/loop_xplier > i_vco_max) or ((refclk_period/1 ps)/loop_xplier < i_vco_min)) ) then if (pll_is_locked) then if ((refclk_period/1 ps)/loop_xplier > i_vco_max) then assert false report "Input clock freq. is over VCO range. " & family_name & " PLL may lose lock" severity warning; vco_over <= '1'; end if; if ((refclk_period/1 ps)/loop_xplier < i_vco_min) then assert false report "Input clock freq. is under VCO range. " & family_name & " PLL may lose lock" severity warning; vco_under <= '1'; end if; if (inclk_out_of_range) then pll_is_locked := false; locked_tmp := '0'; cycles_to_lock := 0; vco_period_was_phase_adjusted := false; phase_adjust_was_scheduled := false; assert false report family_name & " PLL lost lock." severity note; end if; elsif (not no_warn) then if ((refclk_period/1 ps)/loop_xplier > i_vco_max) then assert false report "Input clock freq. is over VCO range. " & family_name & " PLL may lose lock" severity warning; vco_over <= '1'; end if; if ((refclk_period/1 ps)/loop_xplier < i_vco_min) then assert false report "Input clock freq. is under VCO range. " & family_name & " PLL may lose lock" severity warning; vco_under <= '1'; end if; assert false report " Input clock freq. is not within VCO range : " & family_name & " PLL may not lock. Please use the correct frequency." severity warning; no_warn := true; end if; inclk_out_of_range := true; else vco_over <= '0'; vco_under <= '0'; inclk_out_of_range := false; no_warn := false; end if; end if; end if; if (stop_vco) then stop_vco := false; schedule_vco <= not schedule_vco; end if; refclk_time := now; else got_refclk_posedge := false; end if; -- Update M counter value on feedback clock edge if (fbclk'event and fbclk = '1') then got_fbclk_posedge := true; if (not got_first_fbclk) then got_first_fbclk := true; else fbclk_period := now - fbclk_time; end if; -- need refclk_period here, so initialized to proper value above if ( ( (now - refclk_time > 1.5 * refclk_period) and pfdena_ipd = '1' and pll_is_locked) or ( (now - refclk_time > 5 * refclk_period) and pfdena_ipd = '1' and pll_has_just_been_reconfigured = false) or ( (now - refclk_time > 50 * refclk_period) and pfdena_ipd = '1' and pll_has_just_been_reconfigured = true) ) then stop_vco := true; -- reset got_first_refclk := false; got_first_fbclk := false; got_second_refclk := false; if (pll_is_locked) then pll_is_locked := false; locked_tmp := '0'; assert false report family_name & " PLL lost lock due to loss of input clock or the input clock is not detected within the allowed time frame." severity note; if ((i_vco_max = 0) and (i_vco_min = 0)) then assert false report "Please run timing simulation to check whether the input clock is operating within the supported VCO range or not." severity note; end if; end if; cycles_to_lock := 0; cycles_to_unlock := 0; first_schedule := true; vco_period_was_phase_adjusted := false; phase_adjust_was_scheduled := false; end if; fbclk_time := now; else got_fbclk_posedge := false; end if; if ((got_refclk_posedge or got_fbclk_posedge) and got_second_refclk and pfdena_ipd = '1' and (not inclk_out_of_range)) then -- now we know actual incoming period if ( abs(fbclk_time - refclk_time) <= 5 ps or (got_first_fbclk and abs(refclk_period - abs(fbclk_time - refclk_time)) <= 5 ps)) then -- considered in phase if (cycles_to_lock = real_lock_high) then if (not pll_is_locked) then assert false report family_name & " PLL locked to incoming clock" severity note; end if; pll_is_locked := true; locked_tmp := '1'; cycles_to_unlock := 0; end if; -- increment lock counter only if second part of above -- time check is NOT true if (not(abs(refclk_period - abs(fbclk_time - refclk_time)) <= lock_window)) then cycles_to_lock := cycles_to_lock + 1; end if; -- adjust m_times_vco_period new_m_times_vco_period := refclk_period; else -- if locked, begin unlock if (pll_is_locked) then cycles_to_unlock := cycles_to_unlock + 1; if (cycles_to_unlock = lock_low) then pll_is_locked := false; locked_tmp := '0'; cycles_to_lock := 0; vco_period_was_phase_adjusted := false; phase_adjust_was_scheduled := false; assert false report family_name & " PLL lost lock." severity note; got_first_refclk := false; got_first_fbclk := false; got_second_refclk := false; end if; end if; if ( abs(refclk_period - fbclk_period) <= 2 ps ) then -- frequency is still good if (now = fbclk_time and (not phase_adjust_was_scheduled)) then if ( abs(fbclk_time - refclk_time) > refclk_period/2) then new_m_times_vco_period := m_times_vco_period + (refclk_period - abs(fbclk_time - refclk_time)); vco_period_was_phase_adjusted := true; else new_m_times_vco_period := m_times_vco_period - abs(fbclk_time - refclk_time); vco_period_was_phase_adjusted := true; end if; end if; else phase_adjust_was_scheduled := false; new_m_times_vco_period := refclk_period; end if; end if; end if; if (pfdena_ipd = '0') then if (pll_is_locked) then locked_tmp := 'X'; end if; pll_is_locked := false; cycles_to_lock := 0; end if; -- give message only at time of deassertion if (pfdena_ipd'event and pfdena_ipd = '0') then assert false report "PFDENA deasserted." severity note; elsif (pfdena_ipd'event and pfdena_ipd = '1') then got_first_refclk := false; got_second_refclk := false; refclk_time := now; end if; if (reconfig_err) then lock <= '0'; else lock <= locked_tmp; end if; -- signal to calculate quiet_time sig_refclk_period <= refclk_period; if (stop_vco = true) then sig_stop_vco <= '1'; else sig_stop_vco <= '0'; end if; pll_locked <= pll_is_locked; end process; clk0_tmp <= c_clk(i_clk0_counter); clk_pfd(0) <= clk0_tmp WHEN (pfd_locked = '1') ELSE 'X'; clk(0) <= clk_pfd(0) WHEN (test_bypass_lock_detect = "on") ELSE clk0_tmp when (areset_ipd = '1' or pll_in_test_mode) or (pll_locked and (not reconfig_err)) else 'X'; clk1_tmp <= c_clk(i_clk1_counter); clk_pfd(1) <= clk1_tmp WHEN (pfd_locked = '1') ELSE 'X'; clk(1) <= clk_pfd(1) WHEN (test_bypass_lock_detect = "on") ELSE clk1_tmp when (areset_ipd = '1' or pll_in_test_mode) or (pll_locked and (not reconfig_err)) else 'X'; clk2_tmp <= c_clk(i_clk2_counter); clk_pfd(2) <= clk2_tmp WHEN (pfd_locked = '1') ELSE 'X'; clk(2) <= clk_pfd(2) WHEN (test_bypass_lock_detect = "on") ELSE clk2_tmp when (areset_ipd = '1' or pll_in_test_mode) or (pll_locked and (not reconfig_err)) else 'X'; clk3_tmp <= c_clk(i_clk3_counter); clk_pfd(3) <= clk3_tmp WHEN (pfd_locked = '1') ELSE 'X'; clk(3) <= clk_pfd(3) WHEN (test_bypass_lock_detect = "on") ELSE clk3_tmp when (areset_ipd = '1' or pll_in_test_mode) or (pll_locked and (not reconfig_err)) else 'X'; clk4_tmp <= c_clk(i_clk4_counter); clk_pfd(4) <= clk4_tmp WHEN (pfd_locked = '1') ELSE 'X'; clk(4) <= clk_pfd(4) WHEN (test_bypass_lock_detect = "on") ELSE clk4_tmp when (areset_ipd = '1' or pll_in_test_mode) or (pll_locked and (not reconfig_err)) else 'X'; scandataout <= scandata_out; scandone <= NOT scandone_tmp; phasedone <= NOT update_phase; vcooverrange <= 'Z' WHEN (vco_range_detector_high_bits = -1) ELSE vco_over; vcounderrange <= 'Z' WHEN (vco_range_detector_low_bits = -1) ELSE vco_under; fbout <= fbclk; end vital_pll; -- END ARCHITECTURE VITAL_PLL --------------------------------------------------------------------- -- -- Entity Name : cycloneive_ff -- -- Description : Cycloneive FF VHDL simulation model -- -- --------------------------------------------------------------------- LIBRARY IEEE; use IEEE.std_logic_1164.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; use work.cycloneive_and1; entity cycloneive_ff is generic ( power_up : string := "low"; x_on_violation : string := "on"; lpm_type : string := "cycloneive_ff"; tsetup_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_asdata_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_sclr_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_sload_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_asdata_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_sclr_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_sload_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tpd_clk_q_posedge : VitalDelayType01 := DefPropDelay01; tpd_clrn_q_posedge : VitalDelayType01 := DefPropDelay01; tpd_aload_q_posedge : VitalDelayType01 := DefPropDelay01; tpd_asdata_q: VitalDelayType01 := DefPropDelay01; tipd_clk : VitalDelayType01 := DefPropDelay01; tipd_d : VitalDelayType01 := DefPropDelay01; tipd_asdata : VitalDelayType01 := DefPropDelay01; tipd_sclr : VitalDelayType01 := DefPropDelay01; tipd_sload : VitalDelayType01 := DefPropDelay01; tipd_clrn : VitalDelayType01 := DefPropDelay01; tipd_aload : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; MsgOnChecks: Boolean := DefMsgOnChecks; XOnChecks: Boolean := DefXOnChecks; InstancePath: STRING := "*" ); port ( d : in std_logic := '0'; clk : in std_logic := '0'; clrn : in std_logic := '1'; aload : in std_logic := '0'; sclr : in std_logic := '0'; sload : in std_logic := '0'; ena : in std_logic := '1'; asdata : in std_logic := '0'; devclrn : in std_logic := '1'; devpor : in std_logic := '1'; q : out std_logic ); attribute VITAL_LEVEL0 of cycloneive_ff : entity is TRUE; end cycloneive_ff; architecture vital_lcell_ff of cycloneive_ff is attribute VITAL_LEVEL0 of vital_lcell_ff : architecture is TRUE; signal clk_ipd : std_logic; signal d_ipd : std_logic; signal d_dly : std_logic; signal asdata_ipd : std_logic; signal asdata_dly : std_logic; signal asdata_dly1 : std_logic; signal sclr_ipd : std_logic; signal sload_ipd : std_logic; signal clrn_ipd : std_logic; signal aload_ipd : std_logic; signal ena_ipd : std_logic; component cycloneive_and1 generic (XOn : Boolean := DefGlitchXOn; MsgOn : Boolean := DefGlitchMsgOn; tpd_IN1_Y : VitalDelayType01 := DefPropDelay01; tipd_IN1 : VitalDelayType01 := DefPropDelay01 ); port (Y : out STD_LOGIC; IN1 : in STD_LOGIC ); end component; begin ddelaybuffer: cycloneive_and1 port map(IN1 => d_ipd, Y => d_dly); asdatadelaybuffer: cycloneive_and1 port map(IN1 => asdata_ipd, Y => asdata_dly); asdatadelaybuffer1: cycloneive_and1 port map(IN1 => asdata_dly, Y => asdata_dly1); --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (clk_ipd, clk, tipd_clk); VitalWireDelay (d_ipd, d, tipd_d); VitalWireDelay (asdata_ipd, asdata, tipd_asdata); VitalWireDelay (sclr_ipd, sclr, tipd_sclr); VitalWireDelay (sload_ipd, sload, tipd_sload); VitalWireDelay (clrn_ipd, clrn, tipd_clrn); VitalWireDelay (aload_ipd, aload, tipd_aload); VitalWireDelay (ena_ipd, ena, tipd_ena); end block; VITALtiming : process (clk_ipd, d_dly, asdata_dly1, sclr_ipd, sload_ipd, clrn_ipd, aload_ipd, ena_ipd, devclrn, devpor) variable Tviol_d_clk : std_ulogic := '0'; variable Tviol_asdata_clk : std_ulogic := '0'; variable Tviol_sclr_clk : std_ulogic := '0'; variable Tviol_sload_clk : std_ulogic := '0'; variable Tviol_ena_clk : std_ulogic := '0'; variable TimingData_d_clk : VitalTimingDataType := VitalTimingDataInit; variable TimingData_asdata_clk : VitalTimingDataType := VitalTimingDataInit; variable TimingData_sclr_clk : VitalTimingDataType := VitalTimingDataInit; variable TimingData_sload_clk : VitalTimingDataType := VitalTimingDataInit; variable TimingData_ena_clk : VitalTimingDataType := VitalTimingDataInit; variable q_VitalGlitchData : VitalGlitchDataType; variable iq : std_logic := '0'; variable idata: std_logic := '0'; -- variables for 'X' generation variable violation : std_logic := '0'; begin if (now = 0 ns) then if (power_up = "low") then iq := '0'; elsif (power_up = "high") then iq := '1'; end if; end if; ------------------------ -- Timing Check Section ------------------------ if (TimingChecksOn) then VitalSetupHoldCheck ( Violation => Tviol_d_clk, TimingData => TimingData_d_clk, TestSignal => d, TestSignalName => "DATAIN", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_d_clk_noedge_posedge, SetupLow => tsetup_d_clk_noedge_posedge, HoldHigh => thold_d_clk_noedge_posedge, HoldLow => thold_d_clk_noedge_posedge, CheckEnabled => TO_X01((NOT clrn_ipd) OR (sload_ipd) OR (sclr_ipd) OR (NOT devpor) OR (NOT devclrn) OR (NOT ena_ipd)) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/LCELL_FF", XOn => XOnChecks, MsgOn => MsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_asdata_clk, TimingData => TimingData_asdata_clk, TestSignal => asdata_ipd, TestSignalName => "ASDATA", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_asdata_clk_noedge_posedge, SetupLow => tsetup_asdata_clk_noedge_posedge, HoldHigh => thold_asdata_clk_noedge_posedge, HoldLow => thold_asdata_clk_noedge_posedge, CheckEnabled => TO_X01((NOT clrn_ipd) OR (NOT sload_ipd) OR (NOT devpor) OR (NOT devclrn) OR (NOT ena_ipd)) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/LCELL_FF", XOn => XOnChecks, MsgOn => MsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_sclr_clk, TimingData => TimingData_sclr_clk, TestSignal => sclr_ipd, TestSignalName => "SCLR", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_sclr_clk_noedge_posedge, SetupLow => tsetup_sclr_clk_noedge_posedge, HoldHigh => thold_sclr_clk_noedge_posedge, HoldLow => thold_sclr_clk_noedge_posedge, CheckEnabled => TO_X01((NOT clrn_ipd) OR (NOT devpor) OR (NOT devclrn) OR (NOT ena_ipd)) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/LCELL_FF", XOn => XOnChecks, MsgOn => MsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_sload_clk, TimingData => TimingData_sload_clk, TestSignal => sload_ipd, TestSignalName => "SLOAD", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_sload_clk_noedge_posedge, SetupLow => tsetup_sload_clk_noedge_posedge, HoldHigh => thold_sload_clk_noedge_posedge, HoldLow => thold_sload_clk_noedge_posedge, CheckEnabled => TO_X01((NOT clrn_ipd) OR (NOT devpor) OR (NOT devclrn) OR (NOT ena_ipd)) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/LCELL_FF", XOn => XOnChecks, MsgOn => MsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_ena_clk, TimingData => TimingData_ena_clk, TestSignal => ena_ipd, TestSignalName => "ENA", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_ena_clk_noedge_posedge, SetupLow => tsetup_ena_clk_noedge_posedge, HoldHigh => thold_ena_clk_noedge_posedge, HoldLow => thold_ena_clk_noedge_posedge, CheckEnabled => TO_X01((NOT clrn_ipd) OR (NOT devpor) OR (NOT devclrn) ) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/LCELL_FF", XOn => XOnChecks, MsgOn => MsgOnChecks ); end if; violation := Tviol_d_clk or Tviol_asdata_clk or Tviol_sclr_clk or Tviol_sload_clk or Tviol_ena_clk; if ((devpor = '0') or (devclrn = '0') or (clrn_ipd = '0')) then iq := '0'; elsif (aload_ipd = '1') then iq := asdata_dly1; elsif (violation = 'X' and x_on_violation = "on") then iq := 'X'; elsif clk_ipd'event and clk_ipd = '1' and clk_ipd'last_value = '0' then if (ena_ipd = '1') then if (sclr_ipd = '1') then iq := '0'; elsif (sload_ipd = '1') then iq := asdata_dly1; else iq := d_dly; end if; end if; end if; ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => q, OutSignalName => "Q", OutTemp => iq, Paths => (0 => (clrn_ipd'last_event, tpd_clrn_q_posedge, TRUE), 1 => (aload_ipd'last_event, tpd_aload_q_posedge, TRUE), 2 => (asdata_ipd'last_event, tpd_asdata_q, TRUE), 3 => (clk_ipd'last_event, tpd_clk_q_posedge, TRUE)), GlitchData => q_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end vital_lcell_ff; ---------------------------------------------------------------------------- -- Module Name : cycloneive_ram_register -- Description : Register module for RAM inputs/outputs ---------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.VITAL_Timing.all; USE IEEE.VITAL_Primitives.all; USE work.cycloneive_atom_pack.all; ENTITY cycloneive_ram_register IS GENERIC ( width : INTEGER := 1; preset : STD_LOGIC := '0'; tipd_d : VitalDelayArrayType01(143 DOWNTO 0) := (OTHERS => DefPropDelay01); tipd_clk : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; tipd_stall : VitalDelayType01 := DefPropDelay01; tipd_aclr : VitalDelayType01 := DefPropDelay01; tpw_ena_posedge : VitalDelayType := DefPulseWdthCnst; tpd_clk_q_posedge : VitalDelayType01 := DefPropDelay01; tpd_aclr_q_posedge : VitalDelayType01 := DefPropDelay01; tsetup_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_stall_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_stall_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_aclr_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_aclr_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst ); PORT ( d : IN STD_LOGIC_VECTOR(width - 1 DOWNTO 0); clk : IN STD_LOGIC; ena : IN STD_LOGIC; stall : IN STD_LOGIC; aclr : IN STD_LOGIC; devclrn : IN STD_LOGIC; devpor : IN STD_LOGIC; q : OUT STD_LOGIC_VECTOR(width - 1 DOWNTO 0); aclrout : OUT STD_LOGIC ); END cycloneive_ram_register; ARCHITECTURE reg_arch OF cycloneive_ram_register IS SIGNAL d_ipd : STD_LOGIC_VECTOR(width - 1 DOWNTO 0); SIGNAL clk_ipd : STD_LOGIC; SIGNAL ena_ipd : STD_LOGIC; SIGNAL aclr_ipd : STD_LOGIC; SIGNAL stall_ipd : STD_LOGIC; BEGIN WireDelay : BLOCK BEGIN loopbits : FOR i in d'RANGE GENERATE VitalWireDelay (d_ipd(i), d(i), tipd_d(i)); END GENERATE; VitalWireDelay (clk_ipd, clk, tipd_clk); VitalWireDelay (aclr_ipd, aclr, tipd_aclr); VitalWireDelay (ena_ipd, ena, tipd_ena); VitalWireDelay (stall_ipd, stall, tipd_stall); END BLOCK; PROCESS (d_ipd,ena_ipd,stall_ipd,clk_ipd,aclr_ipd,devclrn,devpor) VARIABLE Tviol_clk_ena : STD_ULOGIC := '0'; VARIABLE Tviol_clk_aclr : STD_ULOGIC := '0'; VARIABLE Tviol_data_clk : STD_ULOGIC := '0'; VARIABLE TimingData_clk_ena : VitalTimingDataType := VitalTimingDataInit; VARIABLE TimingData_clk_stall : VitalTimingDataType := VitalTimingDataInit; VARIABLE TimingData_clk_aclr : VitalTimingDataType := VitalTimingDataInit; VARIABLE TimingData_data_clk : VitalTimingDataType := VitalTimingDataInit; VARIABLE Tviol_ena : STD_ULOGIC := '0'; VARIABLE PeriodData_ena : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE q_VitalGlitchDataArray : VitalGlitchDataArrayType(143 downto 0); VARIABLE CQDelay : TIME := 0 ns; VARIABLE q_reg : STD_LOGIC_VECTOR(width - 1 DOWNTO 0) := (OTHERS => preset); BEGIN IF (aclr_ipd = '1' OR devclrn = '0' OR devpor = '0') THEN q_reg := (OTHERS => preset); ELSIF (clk_ipd = '1' AND clk_ipd'EVENT AND ena_ipd = '1' AND stall_ipd = '0') THEN q_reg := d_ipd; END IF; -- Timing checks VitalSetupHoldCheck ( Violation => Tviol_clk_ena, TimingData => TimingData_clk_ena, TestSignal => ena_ipd, TestSignalName => "ena", RefSignal => clk_ipd, RefSignalName => "clk", SetupHigh => tsetup_ena_clk_noedge_posedge, SetupLow => tsetup_ena_clk_noedge_posedge, HoldHigh => thold_ena_clk_noedge_posedge, HoldLow => thold_ena_clk_noedge_posedge, CheckEnabled => ((aclr_ipd) OR (NOT ena_ipd)) /= '1', RefTransition => '/', HeaderMsg => "/RAM Register VitalSetupHoldCheck", XOn => DefXOnChecks, MsgOn => DefMsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_clk_ena, TimingData => TimingData_clk_stall, TestSignal => stall_ipd, TestSignalName => "stall", RefSignal => clk_ipd, RefSignalName => "clk", SetupHigh => tsetup_stall_clk_noedge_posedge, SetupLow => tsetup_stall_clk_noedge_posedge, HoldHigh => thold_stall_clk_noedge_posedge, HoldLow => thold_stall_clk_noedge_posedge, CheckEnabled => ((aclr_ipd) OR (NOT ena_ipd)) /= '1', RefTransition => '/', HeaderMsg => "/RAM Register VitalSetupHoldCheck", XOn => DefXOnChecks, MsgOn => DefMsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_clk_aclr, TimingData => TimingData_clk_aclr, TestSignal => aclr_ipd, TestSignalName => "aclr", RefSignal => clk_ipd, RefSignalName => "clk", SetupHigh => tsetup_aclr_clk_noedge_posedge, SetupLow => tsetup_aclr_clk_noedge_posedge, HoldHigh => thold_aclr_clk_noedge_posedge, HoldLow => thold_aclr_clk_noedge_posedge, CheckEnabled => ((aclr_ipd) OR (NOT ena_ipd)) /= '1', RefTransition => '/', HeaderMsg => "/RAM Register VitalSetupHoldCheck", XOn => DefXOnChecks, MsgOn => DefMsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_data_clk, TimingData => TimingData_data_clk, TestSignal => d_ipd, TestSignalName => "data", RefSignal => clk_ipd, RefSignalName => "clk", SetupHigh => tsetup_d_clk_noedge_posedge, SetupLow => tsetup_d_clk_noedge_posedge, HoldHigh => thold_d_clk_noedge_posedge, HoldLow => thold_d_clk_noedge_posedge, CheckEnabled => ((aclr_ipd) OR (NOT ena_ipd)) /= '1', RefTransition => '/', HeaderMsg => "/RAM Register VitalSetupHoldCheck", XOn => DefXOnChecks, MsgOn => DefMsgOnChecks ); VitalPeriodPulseCheck ( Violation => Tviol_ena, PeriodData => PeriodData_ena, TestSignal => ena_ipd, TestSignalName => "ena", PulseWidthHigh => tpw_ena_posedge, HeaderMsg => "/RAM Register VitalPeriodPulseCheck", XOn => DefXOnChecks, MsgOn => DefMsgOnChecks ); -- Path Delay Selection CQDelay := SelectDelay ( Paths => ( (0 => (clk_ipd'LAST_EVENT,tpd_clk_q_posedge,TRUE), 1 => (aclr_ipd'LAST_EVENT,tpd_aclr_q_posedge,TRUE)) ) ); q <= TRANSPORT q_reg AFTER CQDelay; END PROCESS; aclrout <= aclr_ipd; END reg_arch; ---------------------------------------------------------------------------- -- Module Name : cycloneive_ram_pulse_generator -- Description : Generate pulse to initiate memory read/write operations ---------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.VITAL_Timing.all; USE IEEE.VITAL_Primitives.all; USE work.cycloneive_atom_pack.all; ENTITY cycloneive_ram_pulse_generator IS GENERIC ( tipd_clk : VitalDelayType01 := (0.5 ns,0.5 ns); tipd_ena : VitalDelayType01 := DefPropDelay01; tpd_clk_pulse_posedge : VitalDelayType01 := DefPropDelay01 ); PORT ( clk,ena : IN STD_LOGIC; delaywrite : IN STD_LOGIC := '0'; pulse,cycle : OUT STD_LOGIC ); ATTRIBUTE VITAL_Level0 OF cycloneive_ram_pulse_generator:ENTITY IS TRUE; END cycloneive_ram_pulse_generator; ARCHITECTURE pgen_arch OF cycloneive_ram_pulse_generator IS SIGNAL clk_ipd,ena_ipd : STD_LOGIC; SIGNAL state : STD_LOGIC; ATTRIBUTE VITAL_Level0 OF pgen_arch:ARCHITECTURE IS TRUE; BEGIN WireDelay : BLOCK BEGIN VitalWireDelay (clk_ipd, clk, tipd_clk); VitalWireDelay (ena_ipd, ena, tipd_ena); END BLOCK; PROCESS (clk_ipd,state) BEGIN IF (state = '1' AND state'EVENT) THEN state <= '0'; ELSIF (clk_ipd = '1' AND clk_ipd'EVENT AND ena_ipd = '1') THEN IF (delaywrite = '1') THEN state <= '1' AFTER 1 NS; -- delayed write ELSE state <= '1'; END IF; END IF; END PROCESS; PathDelay : PROCESS VARIABLE pulse_VitalGlitchData : VitalGlitchDataType; BEGIN WAIT UNTIL state'EVENT; VitalPathDelay01 ( OutSignal => pulse, OutSignalName => "pulse", OutTemp => state, Paths => (0 => (clk_ipd'LAST_EVENT,tpd_clk_pulse_posedge,TRUE)), GlitchData => pulse_VitalGlitchData, Mode => DefGlitchMode, XOn => DefXOnChecks, MsgOn => DefMsgOnChecks ); END PROCESS; cycle <= clk_ipd; END pgen_arch; LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.VITAL_Timing.all; USE IEEE.VITAL_Primitives.all; USE work.cycloneive_atom_pack.all; USE work.cycloneive_ram_register; USE work.cycloneive_ram_pulse_generator; ENTITY cycloneive_ram_block IS GENERIC ( -- -------- GLOBAL PARAMETERS --------- operation_mode : STRING := "single_port"; mixed_port_feed_through_mode : STRING := "dont_care"; ram_block_type : STRING := "auto"; logical_ram_name : STRING := "ram_name"; init_file : STRING := "init_file.hex"; init_file_layout : STRING := "none"; data_interleave_width_in_bits : INTEGER := 1; data_interleave_offset_in_bits : INTEGER := 1; port_a_logical_ram_depth : INTEGER := 0; port_a_logical_ram_width : INTEGER := 0; port_a_first_address : INTEGER := 0; port_a_last_address : INTEGER := 0; port_a_first_bit_number : INTEGER := 0; port_a_address_clear : STRING := "none"; port_a_data_out_clear : STRING := "none"; port_a_data_in_clock : STRING := "clock0"; port_a_address_clock : STRING := "clock0"; port_a_write_enable_clock : STRING := "clock0"; port_a_read_enable_clock : STRING := "clock0"; port_a_byte_enable_clock : STRING := "clock0"; port_a_data_out_clock : STRING := "none"; port_a_data_width : INTEGER := 1; port_a_address_width : INTEGER := 1; port_a_byte_enable_mask_width : INTEGER := 1; port_b_logical_ram_depth : INTEGER := 0; port_b_logical_ram_width : INTEGER := 0; port_b_first_address : INTEGER := 0; port_b_last_address : INTEGER := 0; port_b_first_bit_number : INTEGER := 0; port_b_address_clear : STRING := "none"; port_b_data_out_clear : STRING := "none"; port_b_data_in_clock : STRING := "clock1"; port_b_address_clock : STRING := "clock1"; port_b_write_enable_clock: STRING := "clock1"; port_b_read_enable_clock: STRING := "clock1"; port_b_byte_enable_clock : STRING := "clock1"; port_b_data_out_clock : STRING := "none"; port_b_data_width : INTEGER := 1; port_b_address_width : INTEGER := 1; port_b_byte_enable_mask_width : INTEGER := 1; port_a_read_during_write_mode : STRING := "new_data_no_nbe_read"; port_b_read_during_write_mode : STRING := "new_data_no_nbe_read"; power_up_uninitialized : STRING := "false"; port_b_byte_size : INTEGER := 0; port_a_byte_size : INTEGER := 0; safe_write : STRING := "err_on_2clk"; init_file_restructured : STRING := "unused"; lpm_type : string := "cycloneive_ram_block"; lpm_hint : string := "true"; clk0_input_clock_enable : STRING := "none"; -- ena0,ena2,none clk0_core_clock_enable : STRING := "none"; -- ena0,ena2,none clk0_output_clock_enable : STRING := "none"; -- ena0,none clk1_input_clock_enable : STRING := "none"; -- ena1,ena3,none clk1_core_clock_enable : STRING := "none"; -- ena1,ena3,none clk1_output_clock_enable : STRING := "none"; -- ena1,none mem_init0 : BIT_VECTOR := X"0"; mem_init1 : BIT_VECTOR := X"0"; mem_init2 : BIT_VECTOR := X"0"; mem_init3 : BIT_VECTOR := X"0"; mem_init4 : BIT_VECTOR := X"0"; connectivity_checking : string := "off" ); -- -------- PORT DECLARATIONS --------- PORT ( portadatain : IN STD_LOGIC_VECTOR(port_a_data_width - 1 DOWNTO 0) := (OTHERS => '0'); portaaddr : IN STD_LOGIC_VECTOR(port_a_address_width - 1 DOWNTO 0) := (OTHERS => '0'); portawe : IN STD_LOGIC := '0'; portare : IN STD_LOGIC := '1'; portbdatain : IN STD_LOGIC_VECTOR(port_b_data_width - 1 DOWNTO 0) := (OTHERS => '0'); portbaddr : IN STD_LOGIC_VECTOR(port_b_address_width - 1 DOWNTO 0) := (OTHERS => '0'); portbwe : IN STD_LOGIC := '0'; portbre : IN STD_LOGIC := '1'; clk0 : IN STD_LOGIC := '0'; clk1 : IN STD_LOGIC := '0'; ena0 : IN STD_LOGIC := '1'; ena1 : IN STD_LOGIC := '1'; ena2 : IN STD_LOGIC := '1'; ena3 : IN STD_LOGIC := '1'; clr0 : IN STD_LOGIC := '0'; clr1 : IN STD_LOGIC := '0'; portabyteenamasks : IN STD_LOGIC_VECTOR(port_a_byte_enable_mask_width - 1 DOWNTO 0) := (OTHERS => '1'); portbbyteenamasks : IN STD_LOGIC_VECTOR(port_b_byte_enable_mask_width - 1 DOWNTO 0) := (OTHERS => '1'); devclrn : IN STD_LOGIC := '1'; devpor : IN STD_LOGIC := '1'; portaaddrstall : IN STD_LOGIC := '0'; portbaddrstall : IN STD_LOGIC := '0'; portadataout : OUT STD_LOGIC_VECTOR(port_a_data_width - 1 DOWNTO 0); portbdataout : OUT STD_LOGIC_VECTOR(port_b_data_width - 1 DOWNTO 0) ); END cycloneive_ram_block; ARCHITECTURE block_arch OF cycloneive_ram_block IS COMPONENT cycloneive_ram_pulse_generator PORT ( clk : IN STD_LOGIC; ena : IN STD_LOGIC; delaywrite : IN STD_LOGIC := '0'; pulse : OUT STD_LOGIC; cycle : OUT STD_LOGIC ); END COMPONENT; COMPONENT cycloneive_ram_register GENERIC ( preset : STD_LOGIC := '0'; width : integer := 1 ); PORT ( d : IN STD_LOGIC_VECTOR(width - 1 DOWNTO 0); clk : IN STD_LOGIC; aclr : IN STD_LOGIC; devclrn : IN STD_LOGIC; devpor : IN STD_LOGIC; ena : IN STD_LOGIC; stall : IN STD_LOGIC; q : OUT STD_LOGIC_VECTOR(width - 1 DOWNTO 0); aclrout : OUT STD_LOGIC ); END COMPONENT; FUNCTION cond (condition : BOOLEAN;CONSTANT a,b : INTEGER) RETURN INTEGER IS VARIABLE c: INTEGER; BEGIN IF (condition) THEN c := a; ELSE c := b; END IF; RETURN c; END; SUBTYPE port_type IS BOOLEAN; CONSTANT primary : port_type := TRUE; CONSTANT secondary : port_type := FALSE; CONSTANT primary_port_is_a : BOOLEAN := (port_b_data_width <= port_a_data_width); CONSTANT primary_port_is_b : BOOLEAN := NOT primary_port_is_a; CONSTANT mode_is_rom : BOOLEAN := (operation_mode = "rom"); CONSTANT mode_is_sp : BOOLEAN := (operation_mode = "single_port"); CONSTANT mode_is_dp : BOOLEAN := (operation_mode = "dual_port"); CONSTANT mode_is_bdp : BOOLEAN := (operation_mode = "bidir_dual_port"); CONSTANT wired_mode : BOOLEAN := (port_a_address_width = port_b_address_width) AND (port_a_address_width = 1) AND (port_a_data_width /= port_b_data_width); CONSTANT num_cols : INTEGER := cond(mode_is_rom OR mode_is_sp,1, cond(wired_mode,2,2 ** (ABS(port_b_address_width - port_a_address_width)))); CONSTANT data_width : INTEGER := cond(primary_port_is_a,port_a_data_width,port_b_data_width); CONSTANT data_unit_width : INTEGER := cond(mode_is_rom OR mode_is_sp OR primary_port_is_b,port_a_data_width,port_b_data_width); CONSTANT address_unit_width : INTEGER := cond(mode_is_rom OR mode_is_sp OR primary_port_is_a,port_a_address_width,port_b_address_width); CONSTANT address_width : INTEGER := cond(mode_is_rom OR mode_is_sp OR primary_port_is_b,port_a_address_width,port_b_address_width); CONSTANT byte_size_a : INTEGER := port_a_data_width / port_a_byte_enable_mask_width; CONSTANT byte_size_b : INTEGER := port_b_data_width / port_b_byte_enable_mask_width; CONSTANT out_a_is_reg : BOOLEAN := (port_a_data_out_clock /= "none" AND port_a_data_out_clock /= "UNUSED"); CONSTANT out_b_is_reg : BOOLEAN := (port_b_data_out_clock /= "none" AND port_b_data_out_clock /= "UNUSED"); CONSTANT bytes_a_disabled : STD_LOGIC_VECTOR(port_a_byte_enable_mask_width - 1 DOWNTO 0) := (OTHERS => '0'); CONSTANT bytes_b_disabled : STD_LOGIC_VECTOR(port_b_byte_enable_mask_width - 1 DOWNTO 0) := (OTHERS => '0'); CONSTANT ram_type : BOOLEAN := FALSE; TYPE bool_to_std_logic_map IS ARRAY(TRUE DOWNTO FALSE) OF STD_LOGIC; CONSTANT bool_to_std_logic : bool_to_std_logic_map := ('1','0'); -- Hardware write modes CONSTANT dual_clock : BOOLEAN := (operation_mode = "dual_port" OR operation_mode = "bidir_dual_port") AND (port_b_address_clock = "clock1"); CONSTANT both_new_data_same_port : BOOLEAN := ( ((port_a_read_during_write_mode = "new_data_no_nbe_read") OR (port_a_read_during_write_mode = "dont_care")) AND ((port_b_read_during_write_mode = "new_data_no_nbe_read") OR (port_b_read_during_write_mode = "dont_care")) ); SIGNAL hw_write_mode_a : STRING(3 DOWNTO 1); SIGNAL hw_write_mode_b : STRING(3 DOWNTO 1); SIGNAL delay_write_pulse_a : STD_LOGIC ; SIGNAL delay_write_pulse_b : STD_LOGIC ; CONSTANT be_mask_write_a : BOOLEAN := (port_a_read_during_write_mode = "new_data_with_nbe_read"); CONSTANT be_mask_write_b : BOOLEAN := (port_b_read_during_write_mode = "new_data_with_nbe_read"); CONSTANT old_data_write_a : BOOLEAN := (port_a_read_during_write_mode = "old_data"); CONSTANT old_data_write_b : BOOLEAN := (port_b_read_during_write_mode = "old_data"); SIGNAL read_before_write_a : BOOLEAN; SIGNAL read_before_write_b : BOOLEAN; -- -------- internal signals --------- SIGNAL portadatain_int : STD_LOGIC_VECTOR(port_a_data_width - 1 DOWNTO 0); SIGNAL portaaddr_int : STD_LOGIC_VECTOR(port_a_address_width - 1 DOWNTO 0); SIGNAL portabyteenamasks_int : STD_LOGIC_VECTOR(port_a_byte_enable_mask_width - 1 DOWNTO 0); SIGNAL portbdatain_int : STD_LOGIC_VECTOR(port_b_data_width - 1 DOWNTO 0); SIGNAL portbaddr_int : STD_LOGIC_VECTOR(port_b_address_width - 1 DOWNTO 0); SIGNAL portbbyteenamasks_int : STD_LOGIC_VECTOR(port_b_byte_enable_mask_width - 1 DOWNTO 0); SIGNAL portaaddrstall_int : STD_LOGIC; SIGNAL portbaddrstall_int : STD_LOGIC; -- clock / clock enable SIGNAL clk_a_in,clk_b_in : STD_LOGIC; SIGNAL clk_a_byteena,clk_b_byteena : STD_LOGIC; SIGNAL clk_a_out,clk_b_out : STD_LOGIC; SIGNAL clkena_a_out,clkena_b_out : STD_LOGIC; SIGNAL clkena_out_c0, clkena_out_c1 : STD_LOGIC; SIGNAL write_cycle_a,write_cycle_b : STD_LOGIC; SIGNAL clk_a_rena, clk_a_wena : STD_LOGIC; SIGNAL clk_a_core : STD_LOGIC; SIGNAL clk_b_rena, clk_b_wena : STD_LOGIC; SIGNAL clk_b_core : STD_LOGIC; SUBTYPE one_bit_bus_type IS STD_LOGIC_VECTOR(0 DOWNTO 0); -- asynch clear TYPE clear_mode_type IS ARRAY (port_type'HIGH DOWNTO port_type'LOW) OF BOOLEAN; TYPE clear_vec_type IS ARRAY (port_type'HIGH DOWNTO port_type'LOW) OF STD_LOGIC; SIGNAL datain_a_clr,datain_b_clr : STD_LOGIC; SIGNAL dataout_a_clr,dataout_b_clr : STD_LOGIC; SIGNAL dataout_a_clr_reg, dataout_b_clr_reg : STD_LOGIC; SIGNAL dataout_a_clr_reg_in, dataout_b_clr_reg_in : one_bit_bus_type; SIGNAL dataout_a_clr_reg_out, dataout_b_clr_reg_out : one_bit_bus_type; SIGNAL dataout_a_clr_reg_latch, dataout_b_clr_reg_latch : STD_LOGIC; SIGNAL dataout_a_clr_reg_latch_in, dataout_b_clr_reg_latch_in : one_bit_bus_type; SIGNAL dataout_a_clr_reg_latch_out, dataout_b_clr_reg_latch_out : one_bit_bus_type; SIGNAL addr_a_clr,addr_b_clr : STD_LOGIC; SIGNAL byteena_a_clr,byteena_b_clr : STD_LOGIC; SIGNAL we_a_clr,re_a_clr,we_b_clr,re_b_clr : STD_LOGIC; SIGNAL datain_a_clr_in,datain_b_clr_in : STD_LOGIC; SIGNAL addr_a_clr_in,addr_b_clr_in : STD_LOGIC; SIGNAL byteena_a_clr_in,byteena_b_clr_in : STD_LOGIC; SIGNAL we_a_clr_in,re_a_clr_in,we_b_clr_in,re_b_clr_in : STD_LOGIC; SIGNAL mem_invalidate,mem_invalidate_loc,read_latch_invalidate : clear_mode_type; SIGNAL clear_asserted_during_write : clear_vec_type; -- port A registers SIGNAL we_a_reg : STD_LOGIC; SIGNAL re_a_reg : STD_LOGIC; SIGNAL we_a_reg_in,we_a_reg_out : one_bit_bus_type; SIGNAL re_a_reg_in,re_a_reg_out : one_bit_bus_type; SIGNAL addr_a_reg : STD_LOGIC_VECTOR(port_a_address_width - 1 DOWNTO 0); SIGNAL datain_a_reg : STD_LOGIC_VECTOR(port_a_data_width - 1 DOWNTO 0); SIGNAL dataout_a_reg : STD_LOGIC_VECTOR(port_a_data_width - 1 DOWNTO 0); SIGNAL dataout_a : STD_LOGIC_VECTOR(port_a_data_width - 1 DOWNTO 0); SIGNAL byteena_a_reg : STD_LOGIC_VECTOR(port_a_byte_enable_mask_width- 1 DOWNTO 0); -- port B registers SIGNAL we_b_reg, re_b_reg : STD_LOGIC; SIGNAL re_b_reg_in,re_b_reg_out,we_b_reg_in,we_b_reg_out : one_bit_bus_type; SIGNAL addr_b_reg : STD_LOGIC_VECTOR(port_b_address_width - 1 DOWNTO 0); SIGNAL datain_b_reg : STD_LOGIC_VECTOR(port_b_data_width - 1 DOWNTO 0); SIGNAL dataout_b_reg : STD_LOGIC_VECTOR(port_b_data_width - 1 DOWNTO 0); SIGNAL dataout_b : STD_LOGIC_VECTOR(port_b_data_width - 1 DOWNTO 0); SIGNAL byteena_b_reg : STD_LOGIC_VECTOR(port_b_byte_enable_mask_width- 1 DOWNTO 0); -- pulses TYPE pulse_vec IS ARRAY (port_type'HIGH DOWNTO port_type'LOW) OF STD_LOGIC; SIGNAL write_pulse,read_pulse,read_pulse_feedthru : pulse_vec; SIGNAL rw_pulse : pulse_vec; SIGNAL wpgen_a_clk,wpgen_a_clkena,wpgen_b_clk,wpgen_b_clkena : STD_LOGIC; SIGNAL rpgen_a_clkena,rpgen_b_clkena : STD_LOGIC; SIGNAL ftpgen_a_clkena,ftpgen_b_clkena : STD_LOGIC; SIGNAL rwpgen_a_clkena,rwpgen_b_clkena : STD_LOGIC; -- registered address SIGNAL addr_prime_reg,addr_sec_reg : INTEGER; -- input/output SIGNAL datain_prime_reg,dataout_prime : STD_LOGIC_VECTOR(data_width - 1 DOWNTO 0); SIGNAL datain_sec_reg,dataout_sec : STD_LOGIC_VECTOR(data_unit_width - 1 DOWNTO 0); -- overlapping location write SIGNAL dual_write : BOOLEAN; -- byte enable mask write TYPE be_mask_write_vec IS ARRAY (port_type'HIGH DOWNTO port_type'LOW) OF BOOLEAN; SIGNAL be_mask_write : be_mask_write_vec; -- memory core SUBTYPE mem_word_type IS STD_LOGIC_VECTOR (data_width - 1 DOWNTO 0); SUBTYPE mem_col_type IS STD_LOGIC_VECTOR (data_unit_width - 1 DOWNTO 0); TYPE mem_row_type IS ARRAY (num_cols - 1 DOWNTO 0) OF mem_col_type; TYPE mem_type IS ARRAY ((2 ** address_unit_width) - 1 DOWNTO 0) OF mem_row_type; SIGNAL mem : mem_type; SIGNAL init_mem : BOOLEAN := FALSE; CONSTANT mem_x : mem_type := (OTHERS => (OTHERS => (OTHERS => 'X'))); CONSTANT row_x : mem_row_type := (OTHERS => (OTHERS => 'X')); CONSTANT col_x : mem_col_type := (OTHERS => 'X'); SIGNAL mem_data : mem_row_type; SIGNAL old_mem_data : mem_row_type; SIGNAL mem_unit_data : mem_col_type; -- latches TYPE read_latch_rec IS RECORD prime : mem_row_type; sec : mem_col_type; END RECORD; SIGNAL read_latch : read_latch_rec; -- (row,column) coordinates SIGNAL row_sec,col_sec : INTEGER; -- byte enable TYPE mask_type IS (normal,inverse); TYPE mask_prime_type IS ARRAY(mask_type'HIGH DOWNTO mask_type'LOW) OF mem_word_type; TYPE mask_sec_type IS ARRAY(mask_type'HIGH DOWNTO mask_type'LOW) OF mem_col_type; TYPE mask_rec IS RECORD prime : mask_prime_type; sec : mask_sec_type; END RECORD; SIGNAL mask_vector : mask_rec; SIGNAL mask_vector_common : mem_col_type; FUNCTION get_mask( b_ena : IN STD_LOGIC_VECTOR; mode : port_type; CONSTANT b_ena_width ,byte_size: INTEGER ) RETURN mask_rec IS VARIABLE l : INTEGER; VARIABLE mask : mask_rec := ( (normal => (OTHERS => '0'),inverse => (OTHERS => 'X')), (normal => (OTHERS => '0'),inverse => (OTHERS => 'X')) ); BEGIN FOR l in 0 TO b_ena_width - 1 LOOP IF (b_ena(l) = '0') THEN IF (mode = primary) THEN mask.prime(normal) ((l+1)*byte_size - 1 DOWNTO l*byte_size) := (OTHERS => 'X'); mask.prime(inverse)((l+1)*byte_size - 1 DOWNTO l*byte_size) := (OTHERS => '0'); ELSE mask.sec(normal) ((l+1)*byte_size - 1 DOWNTO l*byte_size) := (OTHERS => 'X'); mask.sec(inverse)((l+1)*byte_size - 1 DOWNTO l*byte_size) := (OTHERS => '0'); END IF; ELSIF (b_ena(l) = 'X' OR b_ena(l) = 'U') THEN IF (mode = primary) THEN mask.prime(normal) ((l+1)*byte_size - 1 DOWNTO l*byte_size) := (OTHERS => 'X'); ELSE mask.sec(normal) ((l+1)*byte_size - 1 DOWNTO l*byte_size) := (OTHERS => 'X'); END IF; END IF; END LOOP; RETURN mask; END get_mask; -- port active for read/write SIGNAL active_a_core_in_vec,active_b_core_in_vec,active_a_core_out,active_b_core_out : one_bit_bus_type; SIGNAL active_a_in,active_b_in : STD_LOGIC; SIGNAL active_write_a : BOOLEAN; SIGNAL active_write_b : BOOLEAN; SIGNAL active_b_in_c0,active_b_core_in_c0,active_b_in_c1,active_b_core_in_c1 : STD_LOGIC; SIGNAL active_a_core_in,active_b_core_in : STD_LOGIC; SIGNAL active_a_core, active_b_core : BOOLEAN; SIGNAL wire_vcc : STD_LOGIC := '1'; SIGNAL wire_gnd : STD_LOGIC := '0'; BEGIN -- memory initialization init_mem <= TRUE; -- hardware write modes hw_write_mode_a <= "R+W" WHEN ((port_a_read_during_write_mode = "old_data") OR (port_a_read_during_write_mode = "new_data_with_nbe_read")) ELSE " FW" WHEN (dual_clock OR ( mixed_port_feed_through_mode = "dont_care" AND both_new_data_same_port )) ELSE " DW"; hw_write_mode_b <= "R+W" WHEN ((port_b_read_during_write_mode = "old_data") OR (port_b_read_during_write_mode = "new_data_with_nbe_read")) ELSE " FW" WHEN (dual_clock OR ( mixed_port_feed_through_mode = "dont_care" AND both_new_data_same_port )) ELSE " DW"; delay_write_pulse_a <= '1' WHEN (hw_write_mode_a /= " FW") ELSE '0'; delay_write_pulse_b <= '1' WHEN (hw_write_mode_b /= " FW") ELSE '0' ; read_before_write_a <= (hw_write_mode_a = "R+W"); read_before_write_b <= (hw_write_mode_b = "R+W"); -- -------- core logic --------------- portadatain_int <= portadatain; portaaddr_int <= portaaddr; portabyteenamasks_int <= portabyteenamasks; portbdatain_int <= portbdatain; portbaddr_int <= portbaddr; portbbyteenamasks_int <= portbbyteenamasks; portaaddrstall_int <= portaaddrstall; portbaddrstall_int <= portbaddrstall; clk_a_in <= clk0; clk_a_wena <= '0' WHEN (port_a_write_enable_clock = "none") ELSE clk0; clk_a_rena <= '0' WHEN (port_a_read_enable_clock = "none") ELSE clk0; clk_a_byteena <= '0' WHEN (port_a_byte_enable_clock = "none" OR port_a_byte_enable_clock = "UNUSED") ELSE clk0; clk_a_out <= '0' WHEN (port_a_data_out_clock = "none" OR port_a_data_out_clock = "UNUSED") ELSE clk0 WHEN (port_a_data_out_clock = "clock0") ELSE clk1; clk_b_in <= clk0 WHEN (port_b_address_clock = "clock0") ELSE clk1; clk_b_byteena <= '0' WHEN (port_b_byte_enable_clock = "none" OR port_b_byte_enable_clock = "UNUSED") ELSE clk0 WHEN (port_b_byte_enable_clock = "clock0") ELSE clk1; clk_b_wena <= '0' WHEN (port_b_write_enable_clock = "none") ELSE clk0 WHEN (port_b_write_enable_clock = "clock0") ELSE clk1; clk_b_rena <= '0' WHEN (port_b_read_enable_clock = "none") ELSE clk0 WHEN (port_b_read_enable_clock = "clock0") ELSE clk1; clk_b_out <= '0' WHEN (port_b_data_out_clock = "none" OR port_b_data_out_clock = "UNUSED") ELSE clk0 WHEN (port_b_data_out_clock = "clock0") ELSE clk1; addr_a_clr_in <= '0' WHEN (port_a_address_clear = "none" OR port_a_address_clear = "UNUSED") ELSE clr0; addr_b_clr_in <= '0' WHEN (port_b_address_clear = "none" OR port_b_address_clear = "UNUSED") ELSE clr0 WHEN (port_b_address_clear = "clear0") ELSE clr1; datain_a_clr_in <= '0'; datain_b_clr_in <= '0'; dataout_a_clr_reg <= '0' WHEN (port_a_data_out_clear = "none" OR port_a_data_out_clear = "UNUSED") ELSE clr0 WHEN (port_a_data_out_clear = "clear0") ELSE clr1; dataout_a_clr <= dataout_a_clr_reg WHEN (port_a_data_out_clock = "none" OR port_a_data_out_clock = "UNUSED") ELSE '0'; dataout_b_clr_reg <= '0' WHEN (port_b_data_out_clear = "none" OR port_b_data_out_clear = "UNUSED") ELSE clr0 WHEN (port_b_data_out_clear = "clear0") ELSE clr1; dataout_b_clr <= dataout_b_clr_reg WHEN (port_b_data_out_clock = "none" OR port_b_data_out_clock = "UNUSED") ELSE '0'; byteena_a_clr_in <= '0'; byteena_b_clr_in <= '0'; we_a_clr_in <= '0'; re_a_clr_in <= '0'; we_b_clr_in <= '0'; re_b_clr_in <= '0'; active_a_in <= '1' WHEN (clk0_input_clock_enable = "none") ELSE ena0 WHEN (clk0_input_clock_enable = "ena0") ELSE ena2; active_a_core_in <= '1' WHEN (clk0_core_clock_enable = "none") ELSE ena0 WHEN (clk0_core_clock_enable = "ena0") ELSE ena2; be_mask_write(primary_port_is_a) <= be_mask_write_a; be_mask_write(primary_port_is_b) <= be_mask_write_b; active_b_in_c0 <= '1' WHEN (clk0_input_clock_enable = "none") ELSE ena0 WHEN (clk0_input_clock_enable = "ena0") ELSE ena2; active_b_in_c1 <= '1' WHEN (clk1_input_clock_enable = "none") ELSE ena1 WHEN (clk1_input_clock_enable = "ena1") ELSE ena3; active_b_in <= active_b_in_c0 WHEN (port_b_address_clock = "clock0") ELSE active_b_in_c1; active_b_core_in_c0 <= '1' WHEN (clk0_core_clock_enable = "none") ELSE ena0 WHEN (clk0_core_clock_enable = "ena0") ELSE ena2; active_b_core_in_c1 <= '1' WHEN (clk1_core_clock_enable = "none") ELSE ena1 WHEN (clk1_core_clock_enable = "ena1") ELSE ena3; active_b_core_in <= active_b_core_in_c0 WHEN (port_b_address_clock = "clock0") ELSE active_b_core_in_c1; active_write_a <= (byteena_a_reg /= bytes_a_disabled); active_write_b <= (byteena_b_reg /= bytes_b_disabled); -- Store core clock enable value for delayed write -- port A core active active_a_core_in_vec(0) <= active_a_core_in; active_core_port_a : cycloneive_ram_register GENERIC MAP ( width => 1 ) PORT MAP ( d => active_a_core_in_vec, clk => clk_a_in, aclr => wire_gnd, devclrn => wire_vcc,devpor => wire_vcc, ena => wire_vcc, stall => wire_gnd, q => active_a_core_out ); active_a_core <= (active_a_core_out(0) = '1'); -- port B core active active_b_core_in_vec(0) <= active_b_core_in; active_core_port_b : cycloneive_ram_register GENERIC MAP ( width => 1 ) PORT MAP ( d => active_b_core_in_vec, clk => clk_b_in, aclr => wire_gnd, devclrn => wire_vcc,devpor => wire_vcc, ena => wire_vcc, stall => wire_gnd, q => active_b_core_out ); active_b_core <= (active_b_core_out(0) = '1'); -- ------ A input registers -- write enable we_a_reg_in(0) <= '0' WHEN mode_is_rom ELSE portawe; we_a_register : cycloneive_ram_register GENERIC MAP ( width => 1 ) PORT MAP ( d => we_a_reg_in, clk => clk_a_wena, aclr => we_a_clr_in, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => active_a_in, q => we_a_reg_out, aclrout => we_a_clr ); we_a_reg <= we_a_reg_out(0); -- read enable re_a_reg_in(0) <= portare; re_a_register : cycloneive_ram_register GENERIC MAP ( width => 1 ) PORT MAP ( d => re_a_reg_in, clk => clk_a_rena, aclr => re_a_clr_in, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => active_a_in, q => re_a_reg_out, aclrout => re_a_clr ); re_a_reg <= re_a_reg_out(0); -- address addr_a_register : cycloneive_ram_register GENERIC MAP ( width => port_a_address_width ) PORT MAP ( d => portaaddr_int, clk => clk_a_in, aclr => addr_a_clr_in, devclrn => devclrn, devpor => devpor, stall => portaaddrstall_int, ena => active_a_in, q => addr_a_reg, aclrout => addr_a_clr ); -- data datain_a_register : cycloneive_ram_register GENERIC MAP ( width => port_a_data_width ) PORT MAP ( d => portadatain_int, clk => clk_a_in, aclr => datain_a_clr_in, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => active_a_in, q => datain_a_reg, aclrout => datain_a_clr ); -- byte enable byteena_a_register : cycloneive_ram_register GENERIC MAP ( width => port_a_byte_enable_mask_width, preset => '1' ) PORT MAP ( d => portabyteenamasks_int, clk => clk_a_byteena, aclr => byteena_a_clr_in, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => active_a_in, q => byteena_a_reg, aclrout => byteena_a_clr ); -- ------ B input registers -- read enable re_b_reg_in(0) <= portbre; re_b_register : cycloneive_ram_register GENERIC MAP ( width => 1 ) PORT MAP ( d => re_b_reg_in, clk => clk_b_rena, aclr => re_b_clr_in, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => active_b_in, q => re_b_reg_out, aclrout => re_b_clr ); re_b_reg <= re_b_reg_out(0); -- write enable we_b_reg_in(0) <= portbwe; we_b_register : cycloneive_ram_register GENERIC MAP ( width => 1 ) PORT MAP ( d => we_b_reg_in, clk => clk_b_wena, aclr => we_b_clr_in, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => active_b_in, q => we_b_reg_out, aclrout => we_b_clr ); we_b_reg <= we_b_reg_out(0); -- address addr_b_register : cycloneive_ram_register GENERIC MAP ( width => port_b_address_width ) PORT MAP ( d => portbaddr_int, clk => clk_b_in, aclr => addr_b_clr_in, devclrn => devclrn, devpor => devpor, stall => portbaddrstall_int, ena => active_b_in, q => addr_b_reg, aclrout => addr_b_clr ); -- data datain_b_register : cycloneive_ram_register GENERIC MAP ( width => port_b_data_width ) PORT MAP ( d => portbdatain_int, clk => clk_b_in, aclr => datain_b_clr_in, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => active_b_in, q => datain_b_reg, aclrout => datain_b_clr ); -- byte enable byteena_b_register : cycloneive_ram_register GENERIC MAP ( width => port_b_byte_enable_mask_width, preset => '1' ) PORT MAP ( d => portbbyteenamasks_int, clk => clk_b_byteena, aclr => byteena_b_clr_in, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => active_b_in, q => byteena_b_reg, aclrout => byteena_b_clr ); datain_prime_reg <= datain_a_reg WHEN primary_port_is_a ELSE datain_b_reg; addr_prime_reg <= alt_conv_integer(addr_a_reg) WHEN primary_port_is_a ELSE alt_conv_integer(addr_b_reg); datain_sec_reg <= (OTHERS => 'U') WHEN (mode_is_rom OR mode_is_sp) ELSE datain_b_reg WHEN primary_port_is_a ELSE datain_a_reg; addr_sec_reg <= alt_conv_integer(addr_b_reg) WHEN primary_port_is_a ELSE alt_conv_integer(addr_a_reg); -- Write pulse generation wpgen_a_clk <= clk_a_in; wpgen_a_clkena <= '1' WHEN (active_a_core AND active_write_a AND (we_a_reg = '1')) ELSE '0'; wpgen_a : cycloneive_ram_pulse_generator PORT MAP ( clk => wpgen_a_clk, ena => wpgen_a_clkena, delaywrite => delay_write_pulse_a, pulse => write_pulse(primary_port_is_a), cycle => write_cycle_a ); wpgen_b_clk <= clk_b_in; wpgen_b_clkena <= '1' WHEN (active_b_core AND active_write_b AND mode_is_bdp AND (we_b_reg = '1')) ELSE '0'; wpgen_b : cycloneive_ram_pulse_generator PORT MAP ( clk => wpgen_b_clk, ena => wpgen_b_clkena, delaywrite => delay_write_pulse_b, pulse => write_pulse(primary_port_is_b), cycle => write_cycle_b ); -- Read pulse generation rpgen_a_clkena <= '1' WHEN (active_a_core AND (re_a_reg = '1') AND (we_a_reg = '0') AND (dataout_a_clr = '0')) ELSE '0'; rpgen_a : cycloneive_ram_pulse_generator PORT MAP ( clk => clk_a_in, ena => rpgen_a_clkena, cycle => clk_a_core, pulse => read_pulse(primary_port_is_a) ); rpgen_b_clkena <= '1' WHEN ((mode_is_dp OR mode_is_bdp) AND active_b_core AND (re_b_reg = '1') AND (we_b_reg = '0') AND (dataout_b_clr = '0')) ELSE '0'; rpgen_b : cycloneive_ram_pulse_generator PORT MAP ( clk => clk_b_in, ena => rpgen_b_clkena, cycle => clk_b_core, pulse => read_pulse(primary_port_is_b) ); -- Read-during-Write pulse generation rwpgen_a_clkena <= '1' WHEN (active_a_core AND (re_a_reg = '1') AND (we_a_reg = '1') AND read_before_write_a AND (dataout_a_clr = '0')) ELSE '0'; rwpgen_a : cycloneive_ram_pulse_generator PORT MAP ( clk => clk_a_in, ena => rwpgen_a_clkena, pulse => rw_pulse(primary_port_is_a) ); rwpgen_b_clkena <= '1' WHEN (active_b_core AND mode_is_bdp AND (re_b_reg = '1') AND (we_b_reg = '1') AND read_before_write_b AND (dataout_b_clr = '0')) ELSE '0'; rwpgen_b : cycloneive_ram_pulse_generator PORT MAP ( clk => clk_b_in, ena => rwpgen_b_clkena, pulse => rw_pulse(primary_port_is_b) ); -- Create internal masks for byte enable processing mask_create : PROCESS (byteena_a_reg,byteena_b_reg) VARIABLE mask : mask_rec; BEGIN IF (byteena_a_reg'EVENT) THEN mask := get_mask(byteena_a_reg,primary_port_is_a,port_a_byte_enable_mask_width,byte_size_a); IF (primary_port_is_a) THEN mask_vector.prime <= mask.prime; ELSE mask_vector.sec <= mask.sec; END IF; END IF; IF (byteena_b_reg'EVENT) THEN mask := get_mask(byteena_b_reg,primary_port_is_b,port_b_byte_enable_mask_width,byte_size_b); IF (primary_port_is_b) THEN mask_vector.prime <= mask.prime; ELSE mask_vector.sec <= mask.sec; END IF; END IF; END PROCESS mask_create; -- (row,col) coordinates row_sec <= addr_sec_reg / num_cols; col_sec <= addr_sec_reg mod num_cols; mem_rw : PROCESS (init_mem, write_pulse,read_pulse,read_pulse_feedthru, rw_pulse, dataout_a_clr, dataout_b_clr, mem_invalidate,mem_invalidate_loc,read_latch_invalidate) -- mem init TYPE rw_type IS ARRAY (port_type'HIGH DOWNTO port_type'LOW) OF BOOLEAN; VARIABLE addr_range_init,row,col,index : INTEGER; VARIABLE mem_init_std : STD_LOGIC_VECTOR((port_a_last_address - port_a_first_address + 1)*port_a_data_width - 1 DOWNTO 0); VARIABLE mem_init : bit_vector(mem_init4'length + mem_init3'length + mem_init2'length + mem_init1'length + mem_init0'length - 1 DOWNTO 0); VARIABLE mem_val : mem_type; -- read/write VARIABLE mem_data_p : mem_row_type; VARIABLE old_mem_data_p : mem_row_type; VARIABLE row_prime,col_prime : INTEGER; VARIABLE access_same_location : BOOLEAN; VARIABLE read_during_write : rw_type; BEGIN -- Latch Clear IF (dataout_a_clr'EVENT AND dataout_a_clr = '1') THEN IF (primary_port_is_a) THEN read_latch.prime <= (OTHERS => (OTHERS => '0')); dataout_prime <= (OTHERS => '0'); ELSE read_latch.sec <= (OTHERS => '0'); dataout_sec <= (OTHERS => '0'); END IF; END IF; IF (dataout_b_clr'EVENT AND dataout_b_clr = '1') THEN IF (primary_port_is_b) THEN read_latch.prime <= (OTHERS => (OTHERS => '0')); dataout_prime <= (OTHERS => '0'); ELSE read_latch.sec <= (OTHERS => '0'); dataout_sec <= (OTHERS => '0'); END IF; END IF; read_during_write := (FALSE,FALSE); -- Memory initialization IF (init_mem'EVENT) THEN -- Initialize output latches to 0 IF (primary_port_is_a) THEN dataout_prime <= (OTHERS => '0'); IF (mode_is_dp OR mode_is_bdp) THEN dataout_sec <= (OTHERS => '0'); END IF; ELSE dataout_sec <= (OTHERS => '0'); IF (mode_is_dp OR mode_is_bdp) THEN dataout_prime <= (OTHERS => '0'); END IF; END IF; IF (power_up_uninitialized = "false" AND (NOT ram_type)) THEN mem_val := (OTHERS => (OTHERS => (OTHERS => '0'))); END IF; IF (primary_port_is_a) THEN addr_range_init := port_a_last_address - port_a_first_address + 1; ELSE addr_range_init := port_b_last_address - port_b_first_address + 1; END IF; IF (init_file_layout = "port_a" OR init_file_layout = "port_b") THEN mem_init := mem_init4 & mem_init3 & mem_init2 & mem_init1 & mem_init0; mem_init_std := to_stdlogicvector(mem_init) ((port_a_last_address - port_a_first_address + 1)*port_a_data_width - 1 DOWNTO 0); FOR row IN 0 TO addr_range_init - 1 LOOP FOR col IN 0 to num_cols - 1 LOOP index := row * data_width; mem_val(row)(col) := mem_init_std(index + (col+1)*data_unit_width -1 DOWNTO index + col*data_unit_width); END LOOP; END LOOP; END IF; mem <= mem_val; END IF; access_same_location := (mode_is_dp OR mode_is_bdp) AND (addr_prime_reg = row_sec); -- Read before Write stage 1 : read data from memory -- Read before Write stage 2 : send data to output IF (rw_pulse(primary)'EVENT) THEN IF (rw_pulse(primary) = '1') THEN read_latch.prime <= mem(addr_prime_reg); ELSE IF (be_mask_write(primary)) THEN FOR i IN 0 TO data_width - 1 LOOP IF (mask_vector.prime(normal)(i) = 'X') THEN row_prime := i / data_unit_width; col_prime := i mod data_unit_width; dataout_prime(i) <= read_latch.prime(row_prime)(col_prime); END IF; END LOOP; ELSE FOR i IN 0 TO data_width - 1 LOOP row_prime := i / data_unit_width; col_prime := i mod data_unit_width; dataout_prime(i) <= read_latch.prime(row_prime)(col_prime); END LOOP; END IF; END IF; END IF; IF (rw_pulse(secondary)'EVENT) THEN IF (rw_pulse(secondary) = '1') THEN read_latch.sec <= mem(row_sec)(col_sec); ELSE IF (be_mask_write(secondary)) THEN FOR i IN 0 TO data_unit_width - 1 LOOP IF (mask_vector.sec(normal)(i) = 'X') THEN dataout_sec(i) <= read_latch.sec(i); END IF; END LOOP; ELSE dataout_sec <= read_latch.sec; END IF; END IF; END IF; -- Write stage 1 : X to buffer -- Write stage 2 : actual data to memory IF (write_pulse(primary)'EVENT) THEN IF (write_pulse(primary) = '1') THEN old_mem_data_p := mem(addr_prime_reg); mem_data_p := mem(addr_prime_reg); FOR i IN 0 TO num_cols - 1 LOOP mem_data_p(i) := mem_data_p(i) XOR mask_vector.prime(inverse)((i + 1)*data_unit_width - 1 DOWNTO i*data_unit_width); END LOOP; read_during_write(secondary) := (access_same_location AND read_pulse(secondary)'EVENT AND read_pulse(secondary) = '1'); IF (read_during_write(secondary)) THEN read_latch.sec <= old_mem_data_p(col_sec); ELSE mem_data <= mem_data_p; END IF; ELSIF (clear_asserted_during_write(primary) /= '1') THEN FOR i IN 0 TO data_width - 1 LOOP IF (mask_vector.prime(normal)(i) = '0') THEN mem(addr_prime_reg)(i / data_unit_width)(i mod data_unit_width) <= datain_prime_reg(i); ELSIF (mask_vector.prime(inverse)(i) = 'X') THEN mem(addr_prime_reg)(i / data_unit_width)(i mod data_unit_width) <= 'X'; END IF; END LOOP; END IF; END IF; IF (write_pulse(secondary)'EVENT) THEN IF (write_pulse(secondary) = '1') THEN read_during_write(primary) := (access_same_location AND read_pulse(primary)'EVENT AND read_pulse(primary) = '1'); IF (read_during_write(primary)) THEN read_latch.prime <= mem(addr_prime_reg); read_latch.prime(col_sec) <= mem(row_sec)(col_sec) XOR mask_vector.sec(inverse); ELSE mem_unit_data <= mem(row_sec)(col_sec) XOR mask_vector.sec(inverse); END IF; IF (access_same_location AND write_pulse(primary)'EVENT AND write_pulse(primary) = '1') THEN mask_vector_common <= mask_vector.prime(inverse)(((col_sec + 1)* data_unit_width - 1) DOWNTO col_sec*data_unit_width) AND mask_vector.sec(inverse); dual_write <= TRUE; END IF; ELSIF (clear_asserted_during_write(secondary) /= '1') THEN FOR i IN 0 TO data_unit_width - 1 LOOP IF (mask_vector.sec(normal)(i) = '0') THEN mem(row_sec)(col_sec)(i) <= datain_sec_reg(i); ELSIF (mask_vector.sec(inverse)(i) = 'X') THEN mem(row_sec)(col_sec)(i) <= 'X'; END IF; END LOOP; END IF; END IF; -- Simultaneous write IF (dual_write AND write_pulse = "00") THEN mem(row_sec)(col_sec) <= mem(row_sec)(col_sec) XOR mask_vector_common; dual_write <= FALSE; END IF; -- Read stage 1 : read data -- Read stage 2 : send data to output IF ((NOT read_during_write(primary)) AND read_pulse(primary)'EVENT) THEN IF (read_pulse(primary) = '1') THEN read_latch.prime <= mem(addr_prime_reg); IF (access_same_location AND write_pulse(secondary) = '1') THEN read_latch.prime(col_sec) <= mem_unit_data; END IF; ELSE FOR i IN 0 TO data_width - 1 LOOP row_prime := i / data_unit_width; col_prime := i mod data_unit_width; dataout_prime(i) <= read_latch.prime(row_prime)(col_prime); END LOOP; END IF; END IF; IF ((NOT read_during_write(secondary)) AND read_pulse(secondary)'EVENT) THEN IF (read_pulse(secondary) = '1') THEN IF (access_same_location AND write_pulse(primary) = '1') THEN read_latch.sec <= mem_data(col_sec); ELSE read_latch.sec <= mem(row_sec)(col_sec); END IF; ELSE dataout_sec <= read_latch.sec; END IF; END IF; -- Same port feed thru IF (read_pulse_feedthru(primary)'EVENT AND read_pulse_feedthru(primary) = '0') THEN IF (be_mask_write(primary)) THEN FOR i IN 0 TO data_width - 1 LOOP IF (mask_vector.prime(normal)(i) = '0') THEN dataout_prime(i) <= datain_prime_reg(i); END IF; END LOOP; ELSE dataout_prime <= datain_prime_reg XOR mask_vector.prime(normal); END IF; END IF; IF (read_pulse_feedthru(secondary)'EVENT AND read_pulse_feedthru(secondary) = '0') THEN IF (be_mask_write(secondary)) THEN FOR i IN 0 TO data_unit_width - 1 LOOP IF (mask_vector.sec(normal)(i) = '0') THEN dataout_sec(i) <= datain_sec_reg(i); END IF; END LOOP; ELSE dataout_sec <= datain_sec_reg XOR mask_vector.sec(normal); END IF; END IF; -- Async clear IF (mem_invalidate'EVENT) THEN IF (mem_invalidate(primary) = TRUE OR mem_invalidate(secondary) = TRUE) THEN mem <= mem_x; END IF; END IF; IF (mem_invalidate_loc'EVENT) THEN IF (mem_invalidate_loc(primary)) THEN mem(addr_prime_reg) <= row_x; END IF; IF (mem_invalidate_loc(secondary)) THEN mem(row_sec)(col_sec) <= col_x; END IF; END IF; IF (read_latch_invalidate'EVENT) THEN IF (read_latch_invalidate(primary)) THEN read_latch.prime <= row_x; END IF; IF (read_latch_invalidate(secondary)) THEN read_latch.sec <= col_x; END IF; END IF; END PROCESS mem_rw; -- Same port feed through ftpgen_a_clkena <= '1' WHEN (active_a_core AND (NOT mode_is_dp) AND (NOT old_data_write_a) AND (we_a_reg = '1') AND (re_a_reg = '1') AND (dataout_a_clr = '0')) ELSE '0'; ftpgen_a : cycloneive_ram_pulse_generator PORT MAP ( clk => clk_a_in, ena => ftpgen_a_clkena, pulse => read_pulse_feedthru(primary_port_is_a) ); ftpgen_b_clkena <= '1' WHEN (active_b_core AND mode_is_bdp AND (NOT old_data_write_b) AND (we_b_reg = '1') AND (re_b_reg = '1') AND (dataout_b_clr = '0')) ELSE '0'; ftpgen_b : cycloneive_ram_pulse_generator PORT MAP ( clk => clk_b_in, ena => ftpgen_b_clkena, pulse => read_pulse_feedthru(primary_port_is_b) ); -- Asynch clear events clear_a : PROCESS(addr_a_clr,we_a_clr,datain_a_clr) BEGIN IF (addr_a_clr'EVENT AND addr_a_clr = '1') THEN clear_asserted_during_write(primary_port_is_a) <= write_pulse(primary_port_is_a); IF (active_write_a AND (write_cycle_a = '1') AND (we_a_reg = '1')) THEN mem_invalidate(primary_port_is_a) <= TRUE,FALSE AFTER 0.5 ns; ELSIF (active_a_core AND re_a_reg = '1' AND dataout_a_clr = '0' AND dataout_a_clr_reg_latch = '0') THEN read_latch_invalidate(primary_port_is_a) <= TRUE,FALSE AFTER 0.5 ns; END IF; END IF; IF ((we_a_clr'EVENT AND we_a_clr = '1') OR (datain_a_clr'EVENT AND datain_a_clr = '1')) THEN clear_asserted_during_write(primary_port_is_a) <= write_pulse(primary_port_is_a); IF (active_write_a AND (write_cycle_a = '1') AND (we_a_reg = '1')) THEN mem_invalidate_loc(primary_port_is_a) <= TRUE,FALSE AFTER 0.5 ns; read_latch_invalidate(primary_port_is_a) <= TRUE,FALSE AFTER 0.5 ns; END IF; END IF; END PROCESS clear_a; clear_b : PROCESS(addr_b_clr,we_b_clr,datain_b_clr) BEGIN IF (addr_b_clr'EVENT AND addr_b_clr = '1') THEN clear_asserted_during_write(primary_port_is_b) <= write_pulse(primary_port_is_b); IF (mode_is_bdp AND active_write_b AND (write_cycle_b = '1') AND (we_b_reg = '1')) THEN mem_invalidate(primary_port_is_b) <= TRUE,FALSE AFTER 0.5 ns; ELSIF ((mode_is_dp OR mode_is_bdp) AND active_b_core AND re_b_reg = '1' AND dataout_b_clr = '0' AND dataout_b_clr_reg_latch = '0') THEN read_latch_invalidate(primary_port_is_b) <= TRUE,FALSE AFTER 0.5 ns; END IF; END IF; IF ((we_b_clr'EVENT AND we_b_clr = '1') OR (datain_b_clr'EVENT AND datain_b_clr = '1')) THEN clear_asserted_during_write(primary_port_is_b) <= write_pulse(primary_port_is_b); IF (mode_is_bdp AND active_write_b AND (write_cycle_b = '1') AND (we_b_reg = '1')) THEN mem_invalidate_loc(primary_port_is_b) <= TRUE,FALSE AFTER 0.5 ns; read_latch_invalidate(primary_port_is_b) <= TRUE,FALSE AFTER 0.5 ns; END IF; END IF; END PROCESS clear_b; -- Clear mux registers (Latch Clear) -- Port A output register clear dataout_a_clr_reg_latch_in(0) <= dataout_a_clr; aclr_a_mux_register : cycloneive_ram_register GENERIC MAP ( width => 1 ) PORT MAP ( d => dataout_a_clr_reg_latch_in, clk => clk_a_core, aclr => wire_gnd, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => wire_vcc, q => dataout_a_clr_reg_latch_out ); dataout_a_clr_reg_latch <= dataout_a_clr_reg_latch_out(0); -- Port B output register clear dataout_b_clr_reg_latch_in(0) <= dataout_b_clr; aclr_b_mux_register : cycloneive_ram_register GENERIC MAP ( width => 1 ) PORT MAP ( d => dataout_b_clr_reg_latch_in, clk => clk_b_core, aclr => wire_gnd, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => wire_vcc, q => dataout_b_clr_reg_latch_out ); dataout_b_clr_reg_latch <= dataout_b_clr_reg_latch_out(0); -- ------ Output registers clkena_out_c0 <= '1' WHEN (clk0_output_clock_enable = "none") ELSE ena0; clkena_out_c1 <= '1' WHEN (clk1_output_clock_enable = "none") ELSE ena1; clkena_a_out <= clkena_out_c0 WHEN (port_a_data_out_clock = "clock0") ELSE clkena_out_c1; clkena_b_out <= clkena_out_c0 WHEN (port_b_data_out_clock = "clock0") ELSE clkena_out_c1; dataout_a <= dataout_prime WHEN primary_port_is_a ELSE dataout_sec; dataout_b <= (OTHERS => 'U') WHEN (mode_is_rom OR mode_is_sp) ELSE dataout_prime WHEN primary_port_is_b ELSE dataout_sec; dataout_a_register : cycloneive_ram_register GENERIC MAP ( width => port_a_data_width ) PORT MAP ( d => dataout_a, clk => clk_a_out, aclr => dataout_a_clr_reg, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => clkena_a_out, q => dataout_a_reg ); dataout_b_register : cycloneive_ram_register GENERIC MAP ( width => port_b_data_width ) PORT MAP ( d => dataout_b, clk => clk_b_out, aclr => dataout_b_clr_reg, devclrn => devclrn, devpor => devpor, stall => wire_gnd, ena => clkena_b_out, q => dataout_b_reg ); portadataout <= dataout_a_reg WHEN out_a_is_reg ELSE dataout_a; portbdataout <= dataout_b_reg WHEN out_b_is_reg ELSE dataout_b; END block_arch; ----------------------------------------------------------------------- -- -- Module Name : cycloneive_mac_data_reg -- -- Description : Simulation model for the data input register of -- Cyclone II MAC_MULT -- ----------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.VITAL_Primitives.all; USE IEEE.VITAL_Timing.all; USE IEEE.std_logic_1164.all; USE work.cycloneive_atom_pack.all; ENTITY cycloneive_mac_data_reg IS GENERIC ( TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; tipd_data : VitalDelayArrayType01(17 downto 0) := (OTHERS => DefPropDelay01); tipd_clk : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; tipd_aclr : VitalDelayType01 := DefPropDelay01; tsetup_data_clk_noedge_posedge : VitalDelayArrayType(17 downto 0) := (OTHERS => DefSetupHoldCnst); thold_data_clk_noedge_posedge : VitalDelayArrayType(17 downto 0) := (OTHERS => DefSetupHoldCnst); tsetup_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tpd_aclr_dataout_posedge : VitalDelayArrayType01(17 downto 0) := (OTHERS => DefPropDelay01); tpd_clk_dataout_posedge : VitalDelayArrayType01(17 downto 0) := (OTHERS => DefPropDelay01); data_width : integer := 18 ); PORT ( -- INPUT PORTS clk : IN std_logic; data : IN std_logic_vector(17 DOWNTO 0); ena : IN std_logic; aclr : IN std_logic; -- OUTPUT PORTS dataout : OUT std_logic_vector(17 DOWNTO 0) ); END cycloneive_mac_data_reg; ARCHITECTURE vital_cycloneive_mac_data_reg OF cycloneive_mac_data_reg IS SIGNAL data_ipd : std_logic_vector(17 DOWNTO 0); SIGNAL aclr_ipd : std_logic; SIGNAL clk_ipd : std_logic; SIGNAL ena_ipd : std_logic; SIGNAL dataout_tmp : std_logic_vector(17 DOWNTO 0) := (OTHERS => '0'); BEGIN --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin g1 : for i in data'range generate VitalWireDelay (data_ipd(i), data(i), tipd_data(i)); end generate; VitalWireDelay (clk_ipd, clk, tipd_clk); VitalWireDelay (aclr_ipd, aclr, tipd_aclr); VitalWireDelay (ena_ipd, ena, tipd_ena); end block; process (clk_ipd, aclr_ipd, data_ipd) begin if (aclr_ipd = '1') then dataout_tmp <= (OTHERS => '0'); elsif (clk_ipd'event and clk_ipd = '1' and (ena_ipd = '1')) then dataout_tmp <= data_ipd; end if; end process; sh: block begin g0 : for i in data'range generate process (data_ipd(i),clk_ipd,ena_ipd) variable Tviol_data_clk : std_ulogic := '0'; variable TimingData_data_clk : VitalTimingDataType := VitalTimingDataInit; variable Tviol_ena_clk : std_ulogic := '0'; variable TimingData_ena_clk : VitalTimingDataType := VitalTimingDataInit; begin ------------------------ -- Timing Check Section ------------------------ if (TimingChecksOn) then VitalSetupHoldCheck ( Violation => Tviol_data_clk, TimingData => TimingData_data_clk, TestSignal => data_ipd(i), TestSignalName => "DATA(i)", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_data_clk_noedge_posedge(i), SetupLow => tsetup_data_clk_noedge_posedge(i), HoldHigh => thold_data_clk_noedge_posedge(i), HoldLow => thold_data_clk_noedge_posedge(i), CheckEnabled => TO_X01((aclr) OR (NOT ena)) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/MAC_DATA_REG", XOn => XOnChecks, MsgOn => MsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_ena_clk, TimingData => TimingData_ena_clk, TestSignal => ena_ipd, TestSignalName => "ENA", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_ena_clk_noedge_posedge, SetupLow => tsetup_ena_clk_noedge_posedge, HoldHigh => thold_ena_clk_noedge_posedge, HoldLow => thold_ena_clk_noedge_posedge, CheckEnabled => TO_X01(aclr) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/MAC_DATA_REG", XOn => XOnChecks, MsgOn => MsgOnChecks ); end if; END PROCESS; end generate g0; end block; ---------------------- -- Path Delay Section ---------------------- PathDelay : block begin g1 : for i in dataout_tmp'range generate VITALtiming : process (dataout_tmp(i)) variable dataout_VitalGlitchData : VitalGlitchDataType; begin VitalPathDelay01 (OutSignal => dataout(i), OutSignalName => "DATAOUT", OutTemp => dataout_tmp(i), Paths => (0 => (clk_ipd'last_event, tpd_clk_dataout_posedge(i), TRUE), 1 => (aclr_ipd'last_event, tpd_aclr_dataout_posedge(i), TRUE)), GlitchData => dataout_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn); end process; end generate; end block; END vital_cycloneive_mac_data_reg; -------------------------------------------------------------------- -- -- Module Name : cycloneive_mac_sign_reg -- -- Description : Simulation model for the sign input register of -- Cyclone II MAC_MULT -- -------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.VITAL_Primitives.all; USE IEEE.VITAL_Timing.all; USE IEEE.std_logic_1164.all; USE work.cycloneive_atom_pack.all; ENTITY cycloneive_mac_sign_reg IS GENERIC ( TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; tsetup_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tpd_clk_q_posedge : VitalDelayType01 := DefPropDelay01; tpd_aclr_q_posedge : VitalDelayType01 := DefPropDelay01; tipd_d : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; tipd_aclr : VitalDelayType01 := DefPropDelay01; tipd_clk : VitalDelayType01 := DefPropDelay01 ); PORT ( -- INPUT PORTS clk : IN std_logic; d : IN std_logic; ena : IN std_logic; aclr : IN std_logic; -- OUTPUT PORTS q : OUT std_logic ); END cycloneive_mac_sign_reg; ARCHITECTURE cycloneive_mac_sign_reg OF cycloneive_mac_sign_reg IS signal d_ipd : std_logic; signal clk_ipd : std_logic; signal aclr_ipd : std_logic; signal ena_ipd : std_logic; begin --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (d_ipd, d, tipd_d); VitalWireDelay (clk_ipd, clk, tipd_clk); VitalWireDelay (aclr_ipd, aclr, tipd_aclr); VitalWireDelay (ena_ipd, ena, tipd_ena); end block; VITALtiming : process (clk_ipd, aclr_ipd) variable Tviol_d_clk : std_ulogic := '0'; variable TimingData_d_clk : VitalTimingDataType := VitalTimingDataInit; variable Tviol_ena_clk : std_ulogic := '0'; variable TimingData_ena_clk : VitalTimingDataType := VitalTimingDataInit; variable q_VitalGlitchData : VitalGlitchDataType; variable q_reg : std_logic := '0'; begin ------------------------ -- Timing Check Section ------------------------ if (TimingChecksOn) then VitalSetupHoldCheck ( Violation => Tviol_d_clk, TimingData => TimingData_d_clk, TestSignal => d, TestSignalName => "D", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_d_clk_noedge_posedge, SetupLow => tsetup_d_clk_noedge_posedge, HoldHigh => thold_d_clk_noedge_posedge, HoldLow => thold_d_clk_noedge_posedge, CheckEnabled => TO_X01((aclr) OR (NOT ena)) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/SIGN_REG", XOn => XOnChecks, MsgOn => MsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_ena_clk, TimingData => TimingData_ena_clk, TestSignal => ena, TestSignalName => "ENA", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_ena_clk_noedge_posedge, SetupLow => tsetup_ena_clk_noedge_posedge, HoldHigh => thold_ena_clk_noedge_posedge, HoldLow => thold_ena_clk_noedge_posedge, CheckEnabled => TO_X01(aclr) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/SIGN_REG", XOn => XOnChecks, MsgOn => MsgOnChecks ); end if; if (aclr_ipd = '1') then q_reg := '0'; elsif (clk_ipd'event and clk_ipd = '1' and (ena_ipd = '1')) then q_reg := d_ipd; end if; ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => q, OutSignalName => "Q", OutTemp => q_reg, Paths => (0 => (clk_ipd'last_event, tpd_clk_q_posedge, TRUE), 1 => (aclr_ipd'last_event, tpd_aclr_q_posedge, TRUE)), GlitchData => q_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; END cycloneive_mac_sign_reg; -------------------------------------------------------------------- -- -- Module Name : cycloneive_mac_mult_internal -- -- Description : Cyclone II MAC_MULT_INTERNAL VHDL simulation model -- -------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.VITAL_Primitives.all; USE IEEE.VITAL_Timing.all; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; USE IEEE.std_logic_unsigned.all; USE work.cycloneive_atom_pack.all; ENTITY cycloneive_mac_mult_internal IS GENERIC ( TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; tipd_dataa : VitalDelayArrayType01(17 downto 0) := (OTHERS => DefPropDelay01); tipd_datab : VitalDelayArrayType01(17 downto 0) := (OTHERS => DefPropDelay01); tipd_signa : VitalDelayType01 := DefPropDelay01; tipd_signb : VitalDelayType01 := DefPropDelay01; tpd_dataa_dataout : VitalDelayArrayType01(18*36 -1 downto 0) :=(others => DefPropDelay01); tpd_datab_dataout : VitalDelayArrayType01(18*36 -1 downto 0) :=(others => DefPropDelay01); tpd_signa_dataout : VitalDelayArrayType01(35 downto 0) :=(others => DefPropDelay01); tpd_signb_dataout : VitalDelayArrayType01(35 downto 0) :=(others => DefPropDelay01); dataa_width : integer := 18; datab_width : integer := 18 ); PORT ( dataa : IN std_logic_vector(17 DOWNTO 0) := (OTHERS => '0'); datab : IN std_logic_vector(17 DOWNTO 0) := (OTHERS => '0'); signa : IN std_logic := '1'; signb : IN std_logic := '1'; dataout : OUT std_logic_vector((dataa_width+datab_width)-1 DOWNTO 0) ); END cycloneive_mac_mult_internal; ARCHITECTURE vital_cycloneive_mac_mult_internal OF cycloneive_mac_mult_internal IS -- Internal variables SIGNAL dataa_ipd : std_logic_vector(17 DOWNTO 0); SIGNAL datab_ipd : std_logic_vector(17 DOWNTO 0); SIGNAL signa_ipd : std_logic; SIGNAL signb_ipd : std_logic; -- padding with 1's for input negation SIGNAL reg_aclr : std_logic; SIGNAL dataout_tmp : STD_LOGIC_VECTOR (dataa_width + datab_width downto 0) := (others => '0'); BEGIN --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin g1 : for i in dataa'range generate VitalWireDelay (dataa_ipd(i), dataa(i), tipd_dataa(i)); end generate; g2 : for i in datab'range generate VitalWireDelay (datab_ipd(i), datab(i), tipd_datab(i)); end generate; VitalWireDelay (signa_ipd, signa, tipd_signa); VitalWireDelay (signb_ipd, signb, tipd_signb); end block; VITALtiming : process(dataa_ipd, datab_ipd, signa_ipd, signb_ipd) begin if((signa_ipd = '0') and (signb_ipd = '1')) then dataout_tmp <= unsigned(dataa_ipd(dataa_width-1 downto 0)) * signed(datab_ipd(datab_width-1 downto 0)); elsif((signa_ipd = '1') and (signb_ipd = '0')) then dataout_tmp <= signed(dataa_ipd(dataa_width-1 downto 0)) * unsigned(datab_ipd(datab_width-1 downto 0)); elsif((signa_ipd = '1') and (signb_ipd = '1')) then dataout_tmp(dataout'range) <= signed(dataa_ipd(dataa_width-1 downto 0)) * signed(datab_ipd(datab_width-1 downto 0)); else --((signa_ipd = '0') and (signb_ipd = '0')) then dataout_tmp(dataout'range) <= unsigned(dataa_ipd(dataa_width-1 downto 0)) * unsigned(datab_ipd(datab_width-1 downto 0)); end if; end process; ---------------------- -- Path Delay Section ---------------------- PathDelay : block begin g1 : for i in dataout'range generate VITALtiming : process (dataout_tmp(i)) variable dataout_VitalGlitchData : VitalGlitchDataType; begin VitalPathDelay01 (OutSignal => dataout(i), OutSignalName => "dataout", OutTemp => dataout_tmp(i), Paths => (0 => (dataa_ipd'last_event, tpd_dataa_dataout(i), TRUE), 1 => (datab_ipd'last_event, tpd_datab_dataout(i), TRUE), 2 => (signa'last_event, tpd_signa_dataout(i), TRUE), 3 => (signb'last_event, tpd_signb_dataout(i), TRUE)), GlitchData => dataout_VitalGlitchData, Mode => DefGlitchMode, MsgOn => FALSE, XOn => TRUE ); end process; end generate; end block; END vital_cycloneive_mac_mult_internal; -------------------------------------------------------------------- -- -- Module Name : cycloneive_mac_mult -- -- Description : Cyclone II MAC_MULT VHDL simulation model -- -------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.VITAL_Primitives.all; USE IEEE.VITAL_Timing.all; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; USE IEEE.std_logic_unsigned.all; USE work.cycloneive_atom_pack.all; USE work.cycloneive_mac_data_reg; USE work.cycloneive_mac_sign_reg; USE work.cycloneive_mac_mult_internal; ENTITY cycloneive_mac_mult IS GENERIC ( dataa_width : integer := 18; datab_width : integer := 18; dataa_clock : string := "none"; datab_clock : string := "none"; signa_clock : string := "none"; signb_clock : string := "none"; TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; lpm_hint : string := "true"; lpm_type : string := "cycloneive_mac_mult" ); PORT ( dataa : IN std_logic_vector(dataa_width-1 DOWNTO 0) := (OTHERS => '0'); datab : IN std_logic_vector(datab_width-1 DOWNTO 0) := (OTHERS => '0'); signa : IN std_logic := '1'; signb : IN std_logic := '1'; clk : IN std_logic := '0'; aclr : IN std_logic := '0'; ena : IN std_logic := '0'; dataout : OUT std_logic_vector((dataa_width+datab_width)-1 DOWNTO 0); devclrn : IN std_logic := '1'; devpor : IN std_logic := '1' ); END cycloneive_mac_mult; ARCHITECTURE vital_cycloneive_mac_mult OF cycloneive_mac_mult IS COMPONENT cycloneive_mac_data_reg GENERIC ( TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; tipd_data : VitalDelayArrayType01(17 downto 0) := (OTHERS => DefPropDelay01); tipd_clk : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; tipd_aclr : VitalDelayType01 := DefPropDelay01; tsetup_data_clk_noedge_posedge : VitalDelayArrayType(17 downto 0) := (OTHERS => DefSetupHoldCnst); thold_data_clk_noedge_posedge : VitalDelayArrayType(17 downto 0) := (OTHERS => DefSetupHoldCnst); tsetup_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tpd_aclr_dataout_posedge : VitalDelayArrayType01(17 downto 0) := (OTHERS => DefPropDelay01); tpd_clk_dataout_posedge : VitalDelayArrayType01(17 downto 0) := (OTHERS => DefPropDelay01); data_width : integer := 18 ); PORT ( -- INPUT PORTS clk : IN std_logic; data : IN std_logic_vector(17 DOWNTO 0); ena : IN std_logic; aclr : IN std_logic; -- OUTPUT PORTS dataout : OUT std_logic_vector(17 DOWNTO 0) ); END COMPONENT; COMPONENT cycloneive_mac_sign_reg GENERIC ( TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; tsetup_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tpd_clk_q_posedge : VitalDelayType01 := DefPropDelay01; tpd_aclr_q_posedge : VitalDelayType01 := DefPropDelay01; tipd_d : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; tipd_aclr : VitalDelayType01 := DefPropDelay01; tipd_clk : VitalDelayType01 := DefPropDelay01 ); PORT ( -- INPUT PORTS clk : IN std_logic; d : IN std_logic; ena : IN std_logic; aclr : IN std_logic; -- OUTPUT PORTS q : OUT std_logic ); END COMPONENT; COMPONENT cycloneive_mac_mult_internal GENERIC ( TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; tipd_dataa : VitalDelayArrayType01(17 downto 0) := (OTHERS => DefPropDelay01); tipd_datab : VitalDelayArrayType01(17 downto 0) := (OTHERS => DefPropDelay01); tipd_signa : VitalDelayType01 := DefPropDelay01; tipd_signb : VitalDelayType01 := DefPropDelay01; tpd_dataa_dataout : VitalDelayArrayType01(18*36 -1 downto 0) :=(others => DefPropDelay01); tpd_datab_dataout : VitalDelayArrayType01(18*36 -1 downto 0) :=(others => DefPropDelay01); tpd_signa_dataout : VitalDelayArrayType01(35 downto 0) :=(others => DefPropDelay01); tpd_signb_dataout : VitalDelayArrayType01(35 downto 0) :=(others => DefPropDelay01); dataa_width : integer := 18; datab_width : integer := 18 ); PORT ( dataa : IN std_logic_vector(17 DOWNTO 0) := (OTHERS => '0'); datab : IN std_logic_vector(17 DOWNTO 0) := (OTHERS => '0'); signa : IN std_logic := '1'; signb : IN std_logic := '1'; dataout : OUT std_logic_vector((dataa_width+datab_width)-1 DOWNTO 0) ); END COMPONENT; -- Internal variables SIGNAL dataa_ipd : std_logic_vector(17 DOWNTO 0); SIGNAL datab_ipd : std_logic_vector(17 DOWNTO 0); SIGNAL idataa_reg : std_logic_vector(17 DOWNTO 0); -- optional register for dataa input SIGNAL idatab_reg : std_logic_vector(17 DOWNTO 0); -- optional register for datab input SIGNAL isigna_reg : std_logic; -- optional register for signa input SIGNAL isignb_reg : std_logic; -- optional register for signb input SIGNAL idataa_int : std_logic_vector(17 DOWNTO 0); -- dataa as seen by the multiplier input SIGNAL idatab_int : std_logic_vector(17 DOWNTO 0); -- datab as seen by the multiplier input SIGNAL isigna_int : std_logic; -- signa as seen by the multiplier input SIGNAL isignb_int : std_logic; -- signb as seen by the multiplier input -- padding with 1's for input negation SIGNAL reg_aclr : std_logic; SIGNAL dataout_tmp : STD_LOGIC_VECTOR (dataa_width + datab_width downto 0) := (others => '0'); BEGIN --------------------- -- INPUT PATH DELAYs --------------------- reg_aclr <= (NOT devpor) OR (NOT devclrn) OR (aclr) ; -- padding input data to full bus width dataa_ipd(dataa_width-1 downto 0) <= dataa; datab_ipd(datab_width-1 downto 0) <= datab; -- Optional input registers for dataa,b and signa,b dataa_reg : cycloneive_mac_data_reg GENERIC MAP ( data_width => dataa_width) PORT MAP ( clk => clk, data => dataa_ipd, ena => ena, aclr => reg_aclr, dataout => idataa_reg); datab_reg : cycloneive_mac_data_reg GENERIC MAP ( data_width => datab_width) PORT MAP ( clk => clk, data => datab_ipd, ena => ena, aclr => reg_aclr, dataout => idatab_reg); signa_reg : cycloneive_mac_sign_reg PORT MAP ( clk => clk, d => signa, ena => ena, aclr => reg_aclr, q => isigna_reg); signb_reg : cycloneive_mac_sign_reg PORT MAP ( clk => clk, d => signb, ena => ena, aclr => reg_aclr, q => isignb_reg); idataa_int <= dataa_ipd WHEN (dataa_clock = "none") ELSE idataa_reg; idatab_int <= datab_ipd WHEN (datab_clock = "none") ELSE idatab_reg; isigna_int <= signa WHEN (signa_clock = "none") ELSE isigna_reg; isignb_int <= signb WHEN (signb_clock = "none") ELSE isignb_reg; mac_multiply : cycloneive_mac_mult_internal GENERIC MAP ( dataa_width => dataa_width, datab_width => datab_width ) PORT MAP ( dataa => idataa_int, datab => idatab_int, signa => isigna_int, signb => isignb_int, dataout => dataout ); END vital_cycloneive_mac_mult; -------------------------------------------------------------------- -- -- Module Name : cycloneive_mac_out -- -- Description : Cyclone II MAC_OUT VHDL simulation model -- -------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.VITAL_Primitives.all; USE IEEE.VITAL_Timing.all; USE IEEE.std_logic_1164.all; USE work.cycloneive_atom_pack.all; ENTITY cycloneive_mac_out IS GENERIC ( dataa_width : integer := 1; output_clock : string := "none"; TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; tipd_dataa : VitalDelayArrayType01(35 downto 0) := (OTHERS => DefPropDelay01); tipd_clk : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; tipd_aclr : VitalDelayType01 := DefPropDelay01; tpd_dataa_dataout :VitalDelayArrayType01(36*36 -1 downto 0) :=(others => DefPropDelay01); tpd_aclr_dataout_posedge : VitalDelayArrayType01(35 downto 0) :=(others => DefPropDelay01); tpd_clk_dataout_posedge :VitalDelayArrayType01(35 downto 0) :=(others => DefPropDelay01); tsetup_dataa_clk_noedge_posedge : VitalDelayArrayType(35 downto 0) := (OTHERS => DefSetupHoldCnst); thold_dataa_clk_noedge_posedge : VitalDelayArrayType(35 downto 0) := (OTHERS => DefSetupHoldCnst); tsetup_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; lpm_hint : string := "true"; lpm_type : string := "cycloneive_mac_out"); PORT ( dataa : IN std_logic_vector(dataa_width-1 DOWNTO 0) := (OTHERS => '0'); clk : IN std_logic := '0'; aclr : IN std_logic := '0'; ena : IN std_logic := '1'; dataout : OUT std_logic_vector(dataa_width-1 DOWNTO 0); devclrn : IN std_logic := '1'; devpor : IN std_logic := '1' ); END cycloneive_mac_out; ARCHITECTURE vital_cycloneive_mac_out OF cycloneive_mac_out IS -- internal variables SIGNAL dataa_ipd : std_logic_vector(dataa'range); SIGNAL clk_ipd : std_logic; SIGNAL aclr_ipd : std_logic; SIGNAL ena_ipd : std_logic; -- optional register SIGNAL use_reg : std_logic; SIGNAL dataout_tmp : std_logic_vector(dataout'range) := (OTHERS => '0'); BEGIN --------------------- -- PATH DELAYs --------------------- WireDelay : block begin g1 : for i in dataa'range generate VitalWireDelay (dataa_ipd(i), dataa(i), tipd_dataa(i)); VITALtiming : process (clk_ipd, aclr_ipd, dataout_tmp(i)) variable dataout_VitalGlitchData : VitalGlitchDataType; begin VitalPathDelay01 ( OutSignal => dataout(i), OutSignalName => "DATAOUT", OutTemp => dataout_tmp(i), Paths => (0 => (clk_ipd'last_event, tpd_clk_dataout_posedge(i), use_reg = '1'), 1 => (aclr_ipd'last_event, tpd_aclr_dataout_posedge(i), use_reg = '1'), 2 => (dataa_ipd(i)'last_event, tpd_dataa_dataout(i), use_reg = '0')), GlitchData => dataout_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end generate; VitalWireDelay (clk_ipd, clk, tipd_clk); VitalWireDelay (aclr_ipd, aclr, tipd_aclr); VitalWireDelay (ena_ipd, ena, tipd_ena); end block; use_reg <= '1' WHEN (output_clock /= "none") ELSE '0'; sh: block begin g0 : for i in dataa'range generate VITALtiming : process (clk_ipd, ena_ipd, dataa_ipd(i)) variable Tviol_dataa_clk : std_ulogic := '0'; variable TimingData_dataa_clk : VitalTimingDataType := VitalTimingDataInit; variable Tviol_ena_clk : std_ulogic := '0'; variable TimingData_ena_clk : VitalTimingDataType := VitalTimingDataInit; begin ------------------------ -- Timing Check Section ------------------------ if (TimingChecksOn) then VitalSetupHoldCheck ( Violation => Tviol_dataa_clk, TimingData => TimingData_dataa_clk, TestSignal => dataa(i), TestSignalName => "D", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_dataa_clk_noedge_posedge(i), SetupLow => tsetup_dataa_clk_noedge_posedge(i), HoldHigh => thold_dataa_clk_noedge_posedge(i), HoldLow => thold_dataa_clk_noedge_posedge(i), CheckEnabled => TO_X01((aclr) OR (NOT use_reg) OR (NOT ena)) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/MAC_DATA_REG", XOn => XOnChecks, MsgOn => MsgOnChecks ); VitalSetupHoldCheck ( Violation => Tviol_ena_clk, TimingData => TimingData_ena_clk, TestSignal => ena, TestSignalName => "ENA", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_ena_clk_noedge_posedge, SetupLow => tsetup_ena_clk_noedge_posedge, HoldHigh => thold_ena_clk_noedge_posedge, HoldLow => thold_ena_clk_noedge_posedge, CheckEnabled => TO_X01((aclr) OR (NOT use_reg)) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/MAC_DATA_REG", XOn => XOnChecks, MsgOn => MsgOnChecks ); end if; END PROCESS; end generate g0; end block; process (clk_ipd, aclr_ipd,ena_ipd, dataa_ipd) begin if (use_reg = '0') then dataout_tmp <= dataa_ipd; else if (aclr_ipd = '1') then dataout_tmp <= (OTHERS => '0'); elsif (clk_ipd'event and clk_ipd = '1' and (ena_ipd = '1')) then dataout_tmp <= dataa_ipd; end if; end if; end process; END vital_cycloneive_mac_out; --------------------------------------------------------------------- -- -- Entity Name : cycloneive_io_ibuf -- -- Description : Cycloneive IO Ibuf VHDL simulation model -- -- --------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; ENTITY cycloneive_io_ibuf IS GENERIC ( tipd_i : VitalDelayType01 := DefPropDelay01; tipd_ibar : VitalDelayType01 := DefPropDelay01; tpd_i_o : VitalDelayType01 := DefPropDelay01; tpd_ibar_o : VitalDelayType01 := DefPropDelay01; XOn : Boolean := DefGlitchXOn; MsgOn : Boolean := DefGlitchMsgOn; differential_mode : string := "false"; bus_hold : string := "false"; simulate_z_as : string := "Z"; lpm_type : string := "cycloneive_io_ibuf" ); PORT ( i : IN std_logic := '0'; ibar : IN std_logic := '0'; o : OUT std_logic ); END cycloneive_io_ibuf; ARCHITECTURE arch OF cycloneive_io_ibuf IS SIGNAL i_ipd : std_logic := '0'; SIGNAL ibar_ipd : std_logic := '0'; SIGNAL o_tmp : std_logic; SIGNAL out_tmp : std_logic; SIGNAL prev_value : std_logic := '0'; BEGIN WireDelay : block begin VitalWireDelay (i_ipd, i, tipd_i); VitalWireDelay (ibar_ipd, ibar, tipd_ibar); end block; PROCESS(i_ipd, ibar_ipd) BEGIN IF (differential_mode = "false") THEN IF (i_ipd = '1') THEN o_tmp <= '1'; prev_value <= '1'; ELSIF (i_ipd = '0') THEN o_tmp <= '0'; prev_value <= '0'; ELSE o_tmp <= i_ipd; END IF; ELSE IF (( i_ipd = '0' ) and (ibar_ipd = '1')) then o_tmp <= '0'; ELSIF (( i_ipd = '1' ) and (ibar_ipd = '0')) then o_tmp <= '1'; ELSIF((( i_ipd = '1' ) and (ibar_ipd = '1')) or (( i_ipd = '0' ) and (ibar_ipd = '0')))then o_tmp <= 'X'; ELSE o_tmp <= 'X'; END IF; END IF; END PROCESS; out_tmp <= prev_value when (bus_hold = "true") else 'Z' when((o_tmp = 'Z') AND (simulate_z_as = "Z")) else 'X' when((o_tmp = 'Z') AND (simulate_z_as = "X")) else '1' when((o_tmp = 'Z') AND (simulate_z_as = "vcc")) else '0' when((o_tmp = 'Z') AND (simulate_z_as = "gnd")) else o_tmp; ---------------------- -- Path Delay Section ---------------------- PROCESS( out_tmp) variable output_VitalGlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01 ( OutSignal => o, OutSignalName => "o", OutTemp => out_tmp, Paths => (0 => (i_ipd'last_event, tpd_i_o, TRUE), 1 => (ibar_ipd'last_event, tpd_ibar_o, TRUE)), GlitchData => output_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); END PROCESS; END arch; --------------------------------------------------------------------- -- -- Entity Name : cycloneive_io_obuf -- -- Description : Cycloneive IO Obuf VHDL simulation model -- -- --------------------------------------------------------------------- LIBRARY IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; ENTITY cycloneive_io_obuf IS GENERIC ( tipd_i : VitalDelayType01 := DefPropDelay01; tipd_oe : VitalDelayType01 := DefPropDelay01; tipd_seriesterminationcontrol : VitalDelayArrayType01(15 DOWNTO 0) := (others => DefPropDelay01 ); tpd_i_o : VitalDelayType01 := DefPropDelay01; tpd_oe_o : VitalDelayType01 := DefPropDelay01; tpd_i_obar : VitalDelayType01 := DefPropDelay01; tpd_oe_obar : VitalDelayType01 := DefPropDelay01; XOn : Boolean := DefGlitchXOn; MsgOn : Boolean := DefGlitchMsgOn; open_drain_output : string := "false"; bus_hold : string := "false"; lpm_type : string := "cycloneive_io_obuf" ); PORT ( i : IN std_logic := '0'; oe : IN std_logic := '1'; seriesterminationcontrol : IN std_logic_vector(15 DOWNTO 0) := (others => '0'); devoe : IN std_logic := '1'; o : OUT std_logic; obar : OUT std_logic ); END cycloneive_io_obuf; ARCHITECTURE arch OF cycloneive_io_obuf IS --INTERNAL Signals SIGNAL i_ipd : std_logic := '0'; SIGNAL oe_ipd : std_logic := '0'; SIGNAL out_tmp : std_logic := 'Z'; SIGNAL out_tmp_bar : std_logic; SIGNAL prev_value : std_logic := '0'; SIGNAL o_tmp : std_logic; SIGNAL obar_tmp : std_logic; SIGNAL o_tmp1 : std_logic; SIGNAL obar_tmp1 : std_logic; SIGNAL seriesterminationcontrol_ipd : std_logic_vector(15 DOWNTO 0) := (others => '0'); BEGIN WireDelay : block begin VitalWireDelay (i_ipd, i, tipd_i); VitalWireDelay (oe_ipd, oe, tipd_oe); g1 :for i in seriesterminationcontrol'range generate VitalWireDelay (seriesterminationcontrol_ipd(i), seriesterminationcontrol(i), tipd_seriesterminationcontrol(i)); end generate; end block; PROCESS( i_ipd, oe_ipd) BEGIN IF (oe_ipd = '1') THEN IF (open_drain_output = "true") THEN IF (i_ipd = '0') THEN out_tmp <= '0'; out_tmp_bar <= '1'; prev_value <= '0'; ELSE out_tmp <= 'Z'; out_tmp_bar <= 'Z'; END IF; ELSE IF (i_ipd = '0') THEN out_tmp <= '0'; out_tmp_bar <= '1'; prev_value <= '0'; ELSE IF (i_ipd = '1') THEN out_tmp <= '1'; out_tmp_bar <= '0'; prev_value <= '1'; ELSE out_tmp <= i_ipd; out_tmp_bar <= i_ipd; END IF; END IF; END IF; ELSE IF (oe_ipd = '0') THEN out_tmp <= 'Z'; out_tmp_bar <= 'Z'; ELSE out_tmp <= 'X'; out_tmp_bar <= 'X'; END IF; END IF; END PROCESS; o_tmp1 <= prev_value WHEN (bus_hold = "true") ELSE out_tmp; obar_tmp1 <= NOT prev_value WHEN (bus_hold = "true") ELSE out_tmp_bar; o_tmp <= o_tmp1 WHEN (devoe = '1') ELSE 'Z'; obar_tmp <= obar_tmp1 WHEN (devoe = '1') ELSE 'Z'; --------------------- -- Path Delay Section ---------------------- PROCESS( o_tmp,obar_tmp) variable o_VitalGlitchData : VitalGlitchDataType; variable obar_VitalGlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01 ( OutSignal => o, OutSignalName => "o", OutTemp => o_tmp, Paths => (0 => (i_ipd'last_event, tpd_i_o, TRUE), 1 => (oe_ipd'last_event, tpd_oe_o, TRUE)), GlitchData => o_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); VitalPathDelay01 ( OutSignal => obar, OutSignalName => "obar", OutTemp => obar_tmp, Paths => (0 => (i_ipd'last_event, tpd_i_obar, TRUE), 1 => (oe_ipd'last_event, tpd_oe_obar, TRUE)), GlitchData => obar_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); END PROCESS; END arch; --------------------------------------------------------------------- -- -- Entity Name : cycloneive_ddio_oe -- -- Description : Cycloneive DDIO_OE VHDL simulation model -- -- --------------------------------------------------------------------- LIBRARY IEEE; LIBRARY altera; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use altera.all; use work.cycloneive_atom_pack.all; ENTITY cycloneive_ddio_oe IS generic( tipd_oe : VitalDelayType01 := DefPropDelay01; tipd_clk : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; tipd_areset : VitalDelayType01 := DefPropDelay01; tipd_sreset : VitalDelayType01 := DefPropDelay01; XOn : Boolean := DefGlitchXOn; MsgOn : Boolean := DefGlitchMsgOn; power_up : string := "low"; async_mode : string := "none"; sync_mode : string := "none"; lpm_type : string := "cycloneive_ddio_oe" ); PORT ( oe : IN std_logic := '1'; clk : IN std_logic := '0'; ena : IN std_logic := '1'; areset : IN std_logic := '0'; sreset : IN std_logic := '0'; dataout : OUT std_logic; dfflo : OUT std_logic; dffhi : OUT std_logic; devclrn : IN std_logic := '1'; devpor : IN std_logic := '1' ); END cycloneive_ddio_oe; ARCHITECTURE arch OF cycloneive_ddio_oe IS component cycloneive_mux21 generic( TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; InstancePath: STRING := "*"; tpd_A_MO : VitalDelayType01 := DefPropDelay01; tpd_B_MO : VitalDelayType01 := DefPropDelay01; tpd_S_MO : VitalDelayType01 := DefPropDelay01; tipd_A : VitalDelayType01 := DefPropDelay01; tipd_B : VitalDelayType01 := DefPropDelay01; tipd_S : VitalDelayType01 := DefPropDelay01 ); port ( A : in std_logic := '0'; B : in std_logic := '0'; S : in std_logic := '0'; MO : out std_logic ); end component; component dffeas generic ( power_up : string := "DONT_CARE"; is_wysiwyg : string := "false"; x_on_violation : string := "on"; lpm_type : string := "DFFEAS"; tsetup_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_asdata_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_sclr_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_sload_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_asdata_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_sclr_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_sload_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tpd_clk_q_posedge : VitalDelayType01 := DefPropDelay01; tpd_clrn_q_negedge : VitalDelayType01 := DefPropDelay01; tpd_prn_q_negedge : VitalDelayType01 := DefPropDelay01; tpd_aload_q_posedge : VitalDelayType01 := DefPropDelay01; tpd_asdata_q: VitalDelayType01 := DefPropDelay01; tipd_clk : VitalDelayType01 := DefPropDelay01; tipd_d : VitalDelayType01 := DefPropDelay01; tipd_asdata : VitalDelayType01 := DefPropDelay01; tipd_sclr : VitalDelayType01 := DefPropDelay01; tipd_sload : VitalDelayType01 := DefPropDelay01; tipd_clrn : VitalDelayType01 := DefPropDelay01; tipd_prn : VitalDelayType01 := DefPropDelay01; tipd_aload : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; MsgOnChecks: Boolean := DefMsgOnChecks; XOnChecks: Boolean := DefXOnChecks; InstancePath: STRING := "*" ); port ( d : in std_logic := '0'; clk : in std_logic := '0'; ena : in std_logic := '1'; clrn : in std_logic := '1'; prn : in std_logic := '1'; aload : in std_logic := '0'; asdata : in std_logic := '1'; sclr : in std_logic := '0'; sload : in std_logic := '0'; devclrn : in std_logic := '1'; devpor : in std_logic := '1'; q : out std_logic ); end component; --Internal Signals SIGNAL oe_ipd : std_logic := '0'; SIGNAL clk_ipd : std_logic := '0'; SIGNAL ena_ipd : std_logic := '0'; SIGNAL areset_ipd : std_logic := '0'; SIGNAL sreset_ipd : std_logic := '0'; SIGNAL ddioreg_aclr : std_logic; SIGNAL ddioreg_prn : std_logic; SIGNAL ddioreg_adatasdata : std_logic; SIGNAL ddioreg_sclr : std_logic; SIGNAL ddioreg_sload : std_logic; SIGNAL dfflo_tmp : std_logic; SIGNAL dffhi_tmp : std_logic; signal nclk : std_logic; signal dataout_tmp : std_logic; BEGIN WireDelay : block begin VitalWireDelay (oe_ipd, oe, tipd_oe); VitalWireDelay (clk_ipd, clk, tipd_clk); VitalWireDelay (ena_ipd, ena, tipd_ena); VitalWireDelay (areset_ipd, areset, tipd_areset); VitalWireDelay (sreset_ipd, sreset, tipd_sreset); end block; nclk <= NOT clk_ipd; PROCESS BEGIN WAIT UNTIL areset_ipd'EVENT OR sreset_ipd'EVENT; IF (async_mode = "clear") THEN ddioreg_aclr <= NOT areset_ipd; ddioreg_prn <= '1'; ELSIF (async_mode = "preset") THEN ddioreg_aclr <= '1'; ddioreg_prn <= NOT areset_ipd; ELSE ddioreg_aclr <= '1'; ddioreg_prn <= '1'; END IF; IF (sync_mode = "clear") THEN ddioreg_adatasdata <= '0'; ddioreg_sclr <= sreset_ipd; ddioreg_sload <= '0'; ELSIF (sync_mode = "preset") THEN ddioreg_adatasdata <= '1'; ddioreg_sclr <= '0'; ddioreg_sload <= sreset_ipd; ELSE ddioreg_adatasdata <= '0'; ddioreg_sclr <= '0'; ddioreg_sload <= '0'; END IF; END PROCESS; ddioreg_hi : dffeas GENERIC MAP ( power_up => power_up ) PORT MAP ( d => oe_ipd, clk => clk_ipd, clrn => ddioreg_aclr, prn => ddioreg_prn, sclr => ddioreg_sclr, sload => ddioreg_sload, asdata => ddioreg_adatasdata, ena => ena_ipd, q => dffhi_tmp, devpor => devpor, devclrn => devclrn ); --DDIO Low Register ddioreg_lo : dffeas GENERIC MAP ( power_up => power_up ) PORT MAP ( d => dffhi_tmp, clk => nclk, clrn => ddioreg_aclr, prn => ddioreg_prn, sclr => ddioreg_sclr, sload => ddioreg_sload, asdata => ddioreg_adatasdata, ena => ena_ipd, q => dfflo_tmp, devpor => devpor, devclrn => devclrn ); --registered output or_gate : cycloneive_mux21 port map ( A => dffhi_tmp, B => dfflo_tmp, S => dfflo_tmp, MO => dataout ); dfflo <= dfflo_tmp ; dffhi <= dffhi_tmp ; END arch; --------------------------------------------------------------------- -- -- Entity Name : cycloneive_latch -- -- Description : Cyclone III latch VHDL simulation model -- -- --------------------------------------------------------------------- Library ieee; use ieee.std_logic_1164.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; entity cycloneive_latch is generic( is_wysiwyg : string := "false"; x_on_violation : string := "on"; lpm_type : string := "cycloneive_latch"; tsetup_d_ena_noedge_negedge : VitalDelayType := DefSetupHoldCnst; thold_d_ena_noedge_negedge : VitalDelayType := DefSetupHoldCnst; tpd_d_q : VitalDelayType01 := DefPropDelay01; tpd_ena_q_negedge : VitalDelayType01 := DefPropDelay01; tpd_clr_q_negedge : VitalDelayType01 := DefPropDelay01; tpd_pre_q_negedge : VitalDelayType01 := DefPropDelay01; tipd_d : VitalDelayType01 := DefPropDelay01; tipd_clr : VitalDelayType01 := DefPropDelay01; tipd_pre : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; MsgOnChecks: Boolean := DefMsgOnChecks; XOnChecks: Boolean := DefXOnChecks; InstancePath: STRING := "*" ); port( d : in std_logic := '0'; ena : in std_logic := '1'; clr : in std_logic := '1'; pre : in std_logic := '1'; q : out std_logic ); attribute VITAL_LEVEL0 of cycloneive_latch : entity is TRUE; end cycloneive_latch; architecture vital_latch of cycloneive_latch is attribute VITAL_LEVEL0 of vital_latch : architecture is TRUE; signal d_ipd : std_logic; signal d_dly : std_logic; signal clr_ipd : std_logic; signal pre_ipd : std_logic; signal ena_ipd : std_logic; begin d_dly <= d_ipd; --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (d_ipd, d, tipd_d); VitalWireDelay (clr_ipd, clr, tipd_clr); VitalWireDelay (pre_ipd, pre, tipd_pre); VitalWireDelay (ena_ipd, ena, tipd_ena); end block; VITALtiming : process ( d_dly, clr_ipd, pre_ipd,ena_ipd) variable Tviol_d_ena : std_ulogic := '0'; variable TimingData_d_ena : VitalTimingDataType := VitalTimingDataInit; variable q_VitalGlitchData : VitalGlitchDataType; variable iq : std_logic := '0'; variable idata: std_logic := '0'; -- variables for 'X' generation variable violation : std_logic := '0'; begin ------------------------ -- Timing Check Section ------------------------ if (TimingChecksOn) then VitalSetupHoldCheck ( Violation => Tviol_d_ena, TimingData => TimingData_d_ena, TestSignal => d_ipd, TestSignalName => "DATAIN", RefSignal => ena_ipd, RefSignalName => "ENA", SetupHigh => tsetup_d_ena_noedge_negedge, SetupLow => tsetup_d_ena_noedge_negedge, HoldHigh => thold_d_ena_noedge_negedge, HoldLow => thold_d_ena_noedge_negedge, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & "/cycloneive_latch", XOn => XOnChecks, MsgOn => MsgOnChecks ); violation := Tviol_d_ena; if ( (clr_ipd = '0')) then iq := '0'; elsif (pre_ipd = '0') then iq := '1'; elsif (violation = 'X' and x_on_violation = "on") then iq := 'X'; elsif (ena_ipd = '1') then iq := d_dly; end if; end if; ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => q, OutSignalName => "Q", OutTemp => iq, Paths => (0 => (clr_ipd'last_event, tpd_clr_q_negedge, TRUE), 1 => (pre_ipd'last_event, tpd_pre_q_negedge, TRUE), 2 => (ena_ipd'last_event, tpd_ena_q_negedge, TRUE)), GlitchData => q_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end vital_latch; --------------------------------------------------------------------- -- -- Entity Name : cycloneive_ddio_out -- -- Description : Cycloneive DDIO_OUT VHDL simulation model -- -- --------------------------------------------------------------------- LIBRARY IEEE; LIBRARY altera; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use altera.all; use work.cycloneive_atom_pack.all; ENTITY cycloneive_ddio_out IS generic( tipd_datainlo : VitalDelayType01 := DefPropDelay01; tipd_datainhi : VitalDelayType01 := DefPropDelay01; tipd_clk : VitalDelayType01 := DefPropDelay01; tipd_clkhi : VitalDelayType01 := DefPropDelay01; tipd_clklo : VitalDelayType01 := DefPropDelay01; tipd_muxsel : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; tipd_areset : VitalDelayType01 := DefPropDelay01; tipd_sreset : VitalDelayType01 := DefPropDelay01; XOn : Boolean := DefGlitchXOn; MsgOn : Boolean := DefGlitchMsgOn; power_up : string := "low"; async_mode : string := "none"; sync_mode : string := "none"; use_new_clocking_model : string := "false"; lpm_type : string := "cycloneive_ddio_out" ); PORT ( datainlo : IN std_logic := '0'; datainhi : IN std_logic := '0'; clk : IN std_logic := '0'; clkhi : IN std_logic := '0'; clklo : IN std_logic := '0'; muxsel : IN std_logic := '0'; ena : IN std_logic := '1'; areset : IN std_logic := '0'; sreset : IN std_logic := '0'; dataout : OUT std_logic; dfflo : OUT std_logic; dffhi : OUT std_logic ; devclrn : IN std_logic := '1'; devpor : IN std_logic := '1' ); END cycloneive_ddio_out; ARCHITECTURE arch OF cycloneive_ddio_out IS component cycloneive_mux21 generic( TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; InstancePath: STRING := "*"; tpd_A_MO : VitalDelayType01 := DefPropDelay01; tpd_B_MO : VitalDelayType01 := DefPropDelay01; tpd_S_MO : VitalDelayType01 := DefPropDelay01; tipd_A : VitalDelayType01 := DefPropDelay01; tipd_B : VitalDelayType01 := DefPropDelay01; tipd_S : VitalDelayType01 := DefPropDelay01 ); port ( A : in std_logic := '0'; B : in std_logic := '0'; S : in std_logic := '0'; MO : out std_logic ); end component; component dffeas generic ( power_up : string := "DONT_CARE"; is_wysiwyg : string := "false"; x_on_violation : string := "on"; lpm_type : string := "DFFEAS"; tsetup_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_asdata_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_sclr_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_sload_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tsetup_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_asdata_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_sclr_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_sload_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_ena_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tpd_clk_q_posedge : VitalDelayType01 := DefPropDelay01; tpd_clrn_q_negedge : VitalDelayType01 := DefPropDelay01; tpd_prn_q_negedge : VitalDelayType01 := DefPropDelay01; tpd_aload_q_posedge : VitalDelayType01 := DefPropDelay01; tpd_asdata_q: VitalDelayType01 := DefPropDelay01; tipd_clk : VitalDelayType01 := DefPropDelay01; tipd_d : VitalDelayType01 := DefPropDelay01; tipd_asdata : VitalDelayType01 := DefPropDelay01; tipd_sclr : VitalDelayType01 := DefPropDelay01; tipd_sload : VitalDelayType01 := DefPropDelay01; tipd_clrn : VitalDelayType01 := DefPropDelay01; tipd_prn : VitalDelayType01 := DefPropDelay01; tipd_aload : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; MsgOnChecks: Boolean := DefMsgOnChecks; XOnChecks: Boolean := DefXOnChecks; InstancePath: STRING := "*" ); port ( d : in std_logic := '0'; clk : in std_logic := '0'; ena : in std_logic := '1'; clrn : in std_logic := '1'; prn : in std_logic := '1'; aload : in std_logic := '0'; asdata : in std_logic := '1'; sclr : in std_logic := '0'; sload : in std_logic := '0'; devclrn : in std_logic := '1'; devpor : in std_logic := '1'; q : out std_logic ); end component; component cycloneive_latch generic( is_wysiwyg : string := "false"; x_on_violation : string := "on"; lpm_type : string := "cycloneive_latch"; tsetup_d_ena_noedge_negedge : VitalDelayType := DefSetupHoldCnst; thold_d_ena_noedge_negedge : VitalDelayType := DefSetupHoldCnst; tpd_d_q : VitalDelayType01 := DefPropDelay01; tpd_ena_q_negedge : VitalDelayType01 := DefPropDelay01; tpd_clr_q_negedge : VitalDelayType01 := DefPropDelay01; tpd_pre_q_negedge : VitalDelayType01 := DefPropDelay01; tipd_d : VitalDelayType01 := DefPropDelay01; tipd_clr : VitalDelayType01 := DefPropDelay01; tipd_pre : VitalDelayType01 := DefPropDelay01; tipd_ena : VitalDelayType01 := DefPropDelay01; TimingChecksOn: Boolean := True; MsgOn: Boolean := DefGlitchMsgOn; XOn: Boolean := DefGlitchXOn; MsgOnChecks: Boolean := DefMsgOnChecks; XOnChecks: Boolean := DefXOnChecks; InstancePath: STRING := "*" ); port( d : in std_logic := '0'; ena : in std_logic := '1'; clr : in std_logic := '1'; pre : in std_logic := '1'; q : out std_logic ); end component; component cycloneive_routing_wire is generic ( MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; tpd_datain_dataout : VitalDelayType01 := DefPropDelay01; tpd_datainglitch_dataout : VitalDelayType01 := DefPropDelay01; tipd_datain : VitalDelayType01 := DefPropDelay01 ); PORT ( datain : in std_logic; dataout : out std_logic ); end component; --Internal Signals SIGNAL datainlo_ipd : std_logic := '0'; SIGNAL datainhi_ipd : std_logic := '0'; SIGNAL clk_ipd : std_logic := '0'; SIGNAL clkhi_ipd : std_logic := '0'; SIGNAL clklo_ipd : std_logic := '0'; SIGNAL muxsel_ipd : std_logic := '0'; SIGNAL ena_ipd : std_logic := '0'; SIGNAL areset_ipd : std_logic := '0'; SIGNAL sreset_ipd : std_logic := '0'; SIGNAL ddioreg_aclr : std_logic; SIGNAL ddioreg_prn : std_logic; SIGNAL ddioreg_adatasdata : std_logic; SIGNAL ddioreg_sclr : std_logic; SIGNAL ddioreg_sload : std_logic; SIGNAL dfflo_tmp : std_logic; SIGNAL dffhi_tmp : std_logic; SIGNAL dataout_tmp : std_logic; Signal mux_sel : std_logic; Signal mux_hi : std_logic; Signal sel_mux_hi_in : std_logic; signal clk1 : std_logic; signal clk_hi : std_logic; signal clk_lo : std_logic; signal muxsel1 : std_logic; signal muxsel2: std_logic; signal clk2 : std_logic; signal muxsel_tmp: std_logic; signal sel_mux_lo_in : std_logic; signal datainlo_tmp : std_logic; signal datainhi_tmp : std_logic; signal dffhi_tmp1 : std_logic; signal bdataout : std_logic; signal hrb_sel: std_logic; BEGIN WireDelay : block begin VitalWireDelay (datainlo_ipd, datainlo, tipd_datainlo); VitalWireDelay (datainhi_ipd, datainhi, tipd_datainhi); VitalWireDelay (clk_ipd, clk, tipd_clk); VitalWireDelay (clkhi_ipd, clkhi, tipd_clkhi); VitalWireDelay (clklo_ipd, clklo, tipd_clklo); VitalWireDelay (muxsel_ipd, muxsel, tipd_muxsel); VitalWireDelay (ena_ipd, ena, tipd_ena); VitalWireDelay (areset_ipd, areset, tipd_areset); VitalWireDelay (sreset_ipd, sreset, tipd_sreset); end block; PROCESS BEGIN WAIT UNTIL areset_ipd'EVENT OR sreset_ipd'EVENT; IF (async_mode = "clear") THEN ddioreg_aclr <= NOT areset_ipd; ddioreg_prn <= '1'; ELSIF (async_mode = "preset") THEN ddioreg_aclr <= '1'; ddioreg_prn <= NOT areset_ipd; ELSE ddioreg_aclr <= '1'; ddioreg_prn <= '1'; END IF; IF (sync_mode = "clear") THEN ddioreg_adatasdata <= '0'; ddioreg_sclr <= sreset_ipd; ddioreg_sload <= '0'; ELSIF (sync_mode = "preset") THEN ddioreg_adatasdata <= '1'; ddioreg_sclr <= '0'; ddioreg_sload <= sreset_ipd; ELSE ddioreg_adatasdata <= '0'; ddioreg_sclr <= '0'; ddioreg_sload <= '0'; END IF; END PROCESS; process(clk_ipd) begin clk1 <= clk_ipd; end process; process(muxsel_ipd) begin muxsel1 <= muxsel_ipd; end process; process(dffhi_tmp) begin dffhi_tmp1 <= dffhi_tmp; end process; --DDIO HIGH Register clk_hi <= ((NOT clkhi_ipd) and ena_ipd) when(use_new_clocking_model = "true") else ((NOT clk_ipd) and ena_ipd); datainhi_tmp <= '1' when (ddioreg_sclr ='0'and ddioreg_sload = '1')else '0'when (ddioreg_sclr ='1'and ddioreg_sload = '0') else datainhi; ddioreg_hi : cycloneive_latch PORT MAP ( d=> datainhi_tmp, ena => clk_hi, pre => ddioreg_prn, clr => ddioreg_aclr, q => dffhi_tmp ); --DDIO Low Register clk_lo <= clklo_ipd when(use_new_clocking_model = "true") else clk_ipd; datainlo_tmp <= datainlo; ddioreg_lo : dffeas GENERIC MAP ( power_up => power_up ) PORT MAP ( d => datainlo_tmp, clk => clk_lo, clrn => ddioreg_aclr, prn => ddioreg_prn, sclr => ddioreg_sclr, sload => ddioreg_sload, asdata => ddioreg_adatasdata, ena => ena_ipd, q => dfflo_tmp, devpor => devpor, devclrn => devclrn ); muxsel2 <= muxsel1; clk2 <= clk1; mux_sel <= muxsel2 when(use_new_clocking_model = "true") else clk2; muxsel_tmp <= NOT mux_sel; sel_mux_lo_in <= dfflo_tmp; sel_mux_hi_in <= dffhi_tmp1; wire_delay : cycloneive_routing_wire port map ( datain => bdataout, dataout => dataout ); sel_mux : cycloneive_mux21 port map ( A => sel_mux_hi_in, B => sel_mux_lo_in, S => muxsel_tmp, MO => bdataout ); dfflo <= dfflo_tmp; dffhi <= dffhi_tmp; END arch; ---------------------------------------------------------------------------------- --Module Name: cycloneive_pseudo_diff_out -- --Description: Simulation model for Cycloneive Pseudo Differential -- -- Output Buffer -- ---------------------------------------------------------------------------------- LIBRARY IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; ENTITY cycloneive_pseudo_diff_out IS GENERIC ( tipd_i : VitalDelayType01 := DefPropDelay01; tpd_i_o : VitalDelayType01 := DefPropDelay01; tpd_i_obar : VitalDelayType01 := DefPropDelay01; XOn : Boolean := DefGlitchXOn; MsgOn : Boolean := DefGlitchMsgOn; lpm_type : string := "cycloneive_pseudo_diff_out" ); PORT ( i : IN std_logic := '0'; o : OUT std_logic; obar : OUT std_logic ); END cycloneive_pseudo_diff_out; ARCHITECTURE arch OF cycloneive_pseudo_diff_out IS SIGNAL i_ipd : std_logic ; SIGNAL o_tmp : std_logic ; SIGNAL obar_tmp : std_logic; BEGIN WireDelay : block begin VitalWireDelay (i_ipd, i, tipd_i); end block; PROCESS( i_ipd) BEGIN IF (i_ipd = '0') THEN o_tmp <= '0'; obar_tmp <= '1'; ELSE IF (i_ipd = '1') THEN o_tmp <= '1'; obar_tmp <= '0'; ELSE o_tmp <= i_ipd; obar_tmp <= i_ipd; END IF; END IF; END PROCESS; --------------------- -- Path Delay Section ---------------------- PROCESS( o_tmp,obar_tmp) variable o_VitalGlitchData : VitalGlitchDataType; variable obar_VitalGlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01 ( OutSignal => o, OutSignalName => "o", OutTemp => o_tmp, Paths => (0 => (i_ipd'last_event, tpd_i_o, TRUE)), GlitchData => o_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); VitalPathDelay01 ( OutSignal => obar, OutSignalName => "obar", OutTemp => obar_tmp, Paths => (0 => (i_ipd'last_event, tpd_i_obar, TRUE)), GlitchData => obar_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); END PROCESS; END arch; ---------------------------------------------------------------------------- -- Module Name : cycloneive_io_pad -- Description : Simulation model for cycloneive IO pad ---------------------------------------------------------------------------- LIBRARY IEEE; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; use IEEE.std_logic_arith.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; ENTITY cycloneive_io_pad IS GENERIC ( lpm_type : string := "cycloneive_io_pad"); PORT ( --INPUT PORTS padin : IN std_logic := '0'; -- Input Pad --OUTPUT PORTS padout : OUT std_logic); -- Output Pad END cycloneive_io_pad; ARCHITECTURE arch OF cycloneive_io_pad IS BEGIN padout <= padin; END arch; library IEEE; use IEEE.std_logic_1164.all; entity cycloneive_asmiblock is generic ( lpm_type : string := "cycloneive_asmiblock"; enable_sim : string := "false" ); port ( dclkin : in std_logic; scein : in std_logic; oe : in std_logic; sdoin : in std_logic; data0out: out std_logic ); end entity cycloneive_asmiblock; architecture behavior of cycloneive_asmiblock is -- component asmi_sim_model is port(dclk: in std_logic; ncso: in std_logic; asdo: in std_logic; data0: out std_logic); end component; signal dclk_wire, ncs, data0 : std_logic; begin process(dclkin, scein, oe, data0) begin if (oe = '0') then dclk_wire <= dclkin; ncs <= scein; data0 <= sdoin; elsif (oe = '1' ) then dclk_wire <= 'Z'; ncs <= 'Z'; data0 <= 'Z'; else dclk_wire <= 'X'; ncs <= 'X'; data0 <= 'X'; end if; end process; ----------------------------------------------------- -- Instantiate module to represent Active Serial pins ----------------------------------------------------- -- sim_model_inst : asmi_sim_model port map(dclk => dclk_wire, ncso => ncs, asdo => data0, data0 => data0out); end architecture; --///////////////////////////////////////////////////////////////////////////// -- -- Entity Name : cycloneive_ena_reg -- -- Description : Simulation model for a simple DFF. -- This is used for the gated clock generation -- Powers upto 1. -- --///////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; ENTITY cycloneive_ena_reg is generic ( TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; tsetup_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tpd_clk_q_posedge : VitalDelayType01 := DefPropDelay01; tipd_d : VitalDelayType01 := DefPropDelay01; tipd_clk : VitalDelayType01 := DefPropDelay01 ); PORT ( clk : in std_logic; ena : in std_logic := '1'; d : in std_logic; clrn : in std_logic := '1'; prn : in std_logic := '1'; q : out std_logic ); attribute VITAL_LEVEL0 of cycloneive_ena_reg : entity is TRUE; end cycloneive_ena_reg; ARCHITECTURE behave of cycloneive_ena_reg is attribute VITAL_LEVEL0 of behave : architecture is TRUE; signal d_ipd : std_logic; signal clk_ipd : std_logic; begin --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (d_ipd, d, tipd_d); VitalWireDelay (clk_ipd, clk, tipd_clk); end block; VITALtiming : process (clk_ipd, prn, clrn) variable Tviol_d_clk : std_ulogic := '0'; variable TimingData_d_clk : VitalTimingDataType := VitalTimingDataInit; variable q_VitalGlitchData : VitalGlitchDataType; variable q_reg : std_logic := '1'; begin ------------------------ -- Timing Check Section ------------------------ if (TimingChecksOn) then VitalSetupHoldCheck ( Violation => Tviol_d_clk, TimingData => TimingData_d_clk, TestSignal => d, TestSignalName => "D", RefSignal => clk_ipd, RefSignalName => "CLK", SetupHigh => tsetup_d_clk_noedge_posedge, SetupLow => tsetup_d_clk_noedge_posedge, HoldHigh => thold_d_clk_noedge_posedge, HoldLow => thold_d_clk_noedge_posedge, CheckEnabled => TO_X01((clrn) OR (NOT ena)) /= '1', RefTransition => '/', HeaderMsg => InstancePath & "/cycloneive_ena_reg", XOn => XOnChecks, MsgOn => MsgOnChecks ); end if; if (prn = '0') then q_reg := '1'; elsif (clrn = '0') then q_reg := '0'; elsif (clk_ipd'event and clk_ipd = '1' and clk_ipd'last_value = '0' and (ena = '1')) then q_reg := d_ipd; end if; ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => q, OutSignalName => "Q", OutTemp => q_reg, Paths => (0 => (clk_ipd'last_event, tpd_clk_q_posedge, TRUE)), GlitchData => q_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end behave; --///////////////////////////////////////////////////////////////////////////// -- -- VHDL Simulation Model for Cyclone III CLKCTRL Atom -- --///////////////////////////////////////////////////////////////////////////// -- -- -- CYCLONEIVE_CLKCTRL Model -- -- LIBRARY IEEE; use IEEE.std_logic_1164.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; use work.cycloneive_ena_reg; entity cycloneive_clkctrl is generic ( clock_type : STRING := "Auto"; lpm_type : STRING := "cycloneive_clkctrl"; ena_register_mode : STRING := "Falling Edge"; TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; tpd_inclk_outclk : VitalDelayArrayType01(3 downto 0) := (OTHERS => DefPropDelay01); tipd_inclk : VitalDelayArrayType01(3 downto 0) := (OTHERS => DefPropDelay01); tipd_clkselect : VitalDelayArrayType01(1 downto 0) := (OTHERS => DefPropDelay01); tipd_ena : VitalDelayType01 := DefPropDelay01 ); port ( inclk : in std_logic_vector(3 downto 0) := "0000"; clkselect : in std_logic_vector(1 downto 0) := "00"; ena : in std_logic := '1'; devclrn : in std_logic := '1'; devpor : in std_logic := '1'; outclk : out std_logic ); attribute VITAL_LEVEL0 of cycloneive_clkctrl : entity is TRUE; end cycloneive_clkctrl; architecture vital_clkctrl of cycloneive_clkctrl is attribute VITAL_LEVEL0 of vital_clkctrl : architecture is TRUE; component cycloneive_ena_reg generic ( TimingChecksOn : Boolean := True; MsgOn : Boolean := DefGlitchMsgOn; XOn : Boolean := DefGlitchXOn; MsgOnChecks : Boolean := DefMsgOnChecks; XOnChecks : Boolean := DefXOnChecks; InstancePath : STRING := "*"; tsetup_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; thold_d_clk_noedge_posedge : VitalDelayType := DefSetupHoldCnst; tpd_clk_q_posedge : VitalDelayType01 := DefPropDelay01; tipd_d : VitalDelayType01 := DefPropDelay01; tipd_clk : VitalDelayType01 := DefPropDelay01 ); PORT ( clk : in std_logic; ena : in std_logic := '1'; d : in std_logic; clrn : in std_logic := '1'; prn : in std_logic := '1'; q : out std_logic ); end component; signal inclk_ipd : std_logic_vector(3 downto 0); signal clkselect_ipd : std_logic_vector(1 downto 0); signal ena_ipd : std_logic; signal clkmux_out : std_logic; signal clkmux_out_inv : std_logic; signal cereg_clr : std_logic; signal cereg1_out : std_logic; signal cereg2_out : std_logic; signal ena_out : std_logic; signal outclk_tmp : std_logic; signal vcc : std_logic := '1'; begin --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (ena_ipd, ena, tipd_ena); VitalWireDelay (inclk_ipd(0), inclk(0), tipd_inclk(0)); VitalWireDelay (inclk_ipd(1), inclk(1), tipd_inclk(1)); VitalWireDelay (inclk_ipd(2), inclk(2), tipd_inclk(2)); VitalWireDelay (inclk_ipd(3), inclk(3), tipd_inclk(3)); VitalWireDelay (clkselect_ipd(0), clkselect(0), tipd_clkselect(0)); VitalWireDelay (clkselect_ipd(1), clkselect(1), tipd_clkselect(1)); end block; process(inclk_ipd, clkselect_ipd) variable tmp : std_logic; begin if (clkselect_ipd = "11") then tmp := inclk_ipd(3); elsif (clkselect_ipd = "10") then tmp := inclk_ipd(2); elsif (clkselect_ipd = "01") then tmp := inclk_ipd(1); else tmp := inclk_ipd(0); end if; clkmux_out <= tmp; clkmux_out_inv <= NOT tmp; end process; extena0_reg : cycloneive_ena_reg port map ( clk => clkmux_out_inv, ena => vcc, d => ena_ipd, clrn => vcc, prn => devpor, q => cereg1_out ); extena1_reg : cycloneive_ena_reg port map ( clk => clkmux_out_inv, ena => vcc, d => cereg1_out, clrn => vcc, prn => devpor, q => cereg2_out ); ena_out <= cereg1_out WHEN (ena_register_mode = "falling edge") ELSE ena_ipd WHEN (ena_register_mode = "none") ELSE cereg2_out; outclk_tmp <= ena_out AND clkmux_out; -- output path process (inclk_ipd,outclk_tmp) variable outclk_VitalGlitchData : VitalGlitchDataType; begin ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => outclk, OutSignalName => "OUTCLK", OutTemp => outclk_tmp, Paths => (0 => (inclk_ipd(0)'last_event, tpd_inclk_outclk(0), TRUE), 1 => (inclk_ipd(1)'last_event, tpd_inclk_outclk(1), TRUE), 2 => (inclk_ipd(2)'last_event, tpd_inclk_outclk(2), TRUE), 3 => (inclk_ipd(3)'last_event, tpd_inclk_outclk(3), TRUE)), GlitchData => outclk_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end vital_clkctrl; -- -- -- CYCLONEIVE_RUBLOCK Model -- -- LIBRARY IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use work.cycloneive_atom_pack.all; entity cycloneive_rublock is generic ( sim_init_config : string := "factory"; sim_init_watchdog_value : integer := 0; sim_init_status : integer := 0; lpm_type : string := "cycloneive_rublock" ); port ( clk : in std_logic; shiftnld : in std_logic; captnupdt : in std_logic; regin : in std_logic; rsttimer : in std_logic; rconfig : in std_logic; regout : out std_logic ); end cycloneive_rublock; architecture architecture_rublock of cycloneive_rublock is begin end architecture_rublock; -- -- -- CYCLONEIVE_APFCONTROLLER Model -- -- LIBRARY IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use work.cycloneive_atom_pack.all; entity cycloneive_apfcontroller is generic ( lpm_type: string := "cycloneive_apfcontroller" ); port ( usermode : out std_logic; nceout : out std_logic ); end cycloneive_apfcontroller; architecture architecture_apfcontroller of cycloneive_apfcontroller is begin end architecture_apfcontroller; -------------------------------------------------------------------- -- -- Module Name : cycloneive_termination -- -- Description : Cycloneive Termination Atom VHDL simulation model -- -------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; ENTITY cycloneive_termination IS GENERIC ( pullup_control_to_core: string := "false"; power_down : string := "true"; test_mode : string := "false"; left_shift_termination_code : string := "false"; pullup_adder : integer := 0; pulldown_adder : integer := 0; clock_divide_by : integer := 32; -- 1, 4, 32 runtime_control : string := "false"; shift_vref_rup : string := "true"; shift_vref_rdn : string := "true"; shifted_vref_control : string := "true"; lpm_type : string := "cycloneive_termination"); PORT ( rup : IN std_logic := '0'; rdn : IN std_logic := '0'; terminationclock : IN std_logic := '0'; terminationclear : IN std_logic := '0'; devpor : IN std_logic := '1'; devclrn : IN std_logic := '1'; comparatorprobe : OUT std_logic; terminationcontrolprobe : OUT std_logic; calibrationdone : OUT std_logic; terminationcontrol : OUT std_logic_vector(15 DOWNTO 0)); END cycloneive_termination; ARCHITECTURE cycloneive_termination_arch OF cycloneive_termination IS SIGNAL rup_compout : std_logic := '0'; SIGNAL rdn_compout : std_logic := '1'; BEGIN calibrationdone <= '1'; -- power-up calibration status comparatorprobe <= rup_compout WHEN (pullup_control_to_core = "true") ELSE rdn_compout; rup_compout <= rup; rdn_compout <= not rdn; END cycloneive_termination_arch; ------------------------------------------------------------------- -- -- Entity Name : cycloneive_jtag -- -- Description : Cycloneive JTAG VHDL Simulation model -- ------------------------------------------------------------------- LIBRARY IEEE; use IEEE.std_logic_1164.all; use work.cycloneive_atom_pack.all; entity cycloneive_jtag is generic ( lpm_type : string := "cycloneive_jtag" ); port ( tms : in std_logic := '0'; tck : in std_logic := '0'; tdi : in std_logic := '0'; tdoutap : in std_logic := '0'; tdouser : in std_logic := '0'; tdo: out std_logic; tmsutap: out std_logic; tckutap: out std_logic; tdiutap: out std_logic; shiftuser: out std_logic; clkdruser: out std_logic; updateuser: out std_logic; runidleuser: out std_logic; usr1user: out std_logic ); end cycloneive_jtag; architecture architecture_jtag of cycloneive_jtag is begin end architecture_jtag; ------------------------------------------------------------------- -- -- Entity Name : cycloneive_crcblock -- -- Description : Cycloneive CRCBLOCK VHDL Simulation model -- ------------------------------------------------------------------- LIBRARY IEEE; use IEEE.std_logic_1164.all; use work.cycloneive_atom_pack.all; entity cycloneive_crcblock is generic ( oscillator_divider : integer := 1; lpm_type : string := "cycloneive_crcblock" ); port ( clk : in std_logic := '0'; shiftnld : in std_logic := '0'; ldsrc : in std_logic := '0'; crcerror : out std_logic; regout : out std_logic ); end cycloneive_crcblock; architecture architecture_crcblock of cycloneive_crcblock is begin crcerror <= '0'; regout <= '0'; end architecture_crcblock; -- -- -- CYCLONEIVE_OSCILLATOR Model -- -- LIBRARY IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.VITAL_Timing.all; use IEEE.VITAL_Primitives.all; use work.cycloneive_atom_pack.all; entity cycloneive_oscillator is generic ( lpm_type: string := "cycloneive_oscillator"; TimingChecksOn: Boolean := True; XOn: Boolean := DefGlitchXOn; MsgOn: Boolean := DefGlitchMsgOn; tpd_oscena_clkout_posedge : VitalDelayType01 := DefPropDelay01; tipd_oscena : VitalDelayType01 := DefPropDelay01 ); port ( oscena : in std_logic; clkout : out std_logic ); end cycloneive_oscillator; architecture architecture_oscillator of cycloneive_oscillator is signal oscena_ipd : std_logic; signal int_osc : std_logic := '0'; begin --------------------- -- INPUT PATH DELAYs --------------------- WireDelay : block begin VitalWireDelay (oscena_ipd, oscena, tipd_oscena); end block; VITAL_osc : process(oscena_ipd, int_osc) variable OSC_PW : time := 6250 ps; -- pulse width for 80MHz clock variable osc_VitalGlitchData : VitalGlitchDataType; begin if (oscena_ipd = '1') then if ((int_osc = '0') or (int_osc = '1')) then int_osc <= not int_osc after OSC_PW; else int_osc <= '0' after OSC_PW; end if; end if; ---------------------- -- Path Delay Section ---------------------- VitalPathDelay01 ( OutSignal => clkout, OutSignalName => "osc", OutTemp => int_osc, Paths => (0 => (InputChangeTime => oscena_ipd'last_event, PathDelay => tpd_oscena_clkout_posedge, PathCondition => (oscena_ipd = '1'))), GlitchData => osc_VitalGlitchData, Mode => DefGlitchMode, XOn => XOn, MsgOn => MsgOn ); end process; end architecture_oscillator;