📄 altera_mf.vhd
字号:
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 int2str (value : integer) return string;end pllpack;-- BEGINNING OF PACKAGEpackage body pllpack is-- convert std_logic_vector to integerfunction alt_conv_integer(arg : in std_logic_vector) return integer isvariable result : integer := 0;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;-- find the greatest common denominator of X and Yfunction gcd (X: integer; Y: integer) return integer isvariable 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;-- find the least common multiple of A1 to A10function 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 isvariable 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 < 10) and (M9 >= 3)) then R := 4 * M9; else R := M9 ; end if; return R;end lcm;-- find the factor of division of the output clock frequency compared to the VCOfunction output_counter_value (clk_divide: integer; clk_mult: integer ; M: integer; N: integer ) return integer isvariable R: integer := 1;begin R := (clk_divide * M)/(clk_mult * N); return R;end output_counter_value;-- find the mode of each PLL counter - bypass, even or oddfunction counter_mode (duty_cycle: integer; output_counter_value: integer) return string isvariable 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 highfunction counter_high (output_counter_value: integer := 1; duty_cycle: integer) return integer isvariable 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 lowfunction counter_low (output_counter_value: integer; duty_cycle: integer) return integer isvariable 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; return R;end;-- find the smallest time delay amongst t1 to t10function mintimedelay (t1: integer; t2: integer; t3: integer; t4: integer; t5: integer; t6: integer; t7: integer; t8: integer; t9: integer; t10: integer) return integer isvariable 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 valuefunction maxnegabs (t1: integer; t2: integer; t3: integer; t4: integer; t5: integer; t6: integer; t7: integer; t8: integer; t9: integer; t10: integer) return integer isvariable 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 isbegin return (tap_phase + ph_base);end;-- find the time delay for each PLL counterfunction counter_time_delay (clk_time_delay: integer; m_time_delay: integer; n_time_delay: integer) return integer isvariable 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 degreesfunction get_phase_degree (phase_shift: integer; clk_period: integer) return integer isvariable 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 clockfunction counter_initial (tap_phase: integer; m: integer; n: integer) return integer isvariable R: integer;variable R1: real;begin R1 := (real(abs(tap_phase)) * real(m))/(360.0 * real(n)) + 0.5; -- 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 tofunction counter_ph (tap_phase: integer; m: integer; n: integer) return integer isvariable R: integer := 0;begin -- 0.5 is added for proper rounding of the tap_phase. R := (integer(real(tap_phase * m / n)+ 0.5) REM 360)/45; return R;end;-- convert given string to length 6 by padding with spacesfunction translate_string (mode : string) return string isvariable 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;-- convert integer to stringfunction int2str( value : integer ) return string isvariable ivalue : integer := 0;variable index : integer := 1;variable digit : integer := 0;variable temp: string(10 downto 1) := "0000000000";begin ivalue := value; index := 1; while (ivalue > 0) loop digit := ivalue mod 10; ivalue := ivalue/10; case digit is when 0 => temp(index) := '0'; when 1 => temp(index) := '1'; when 2 => temp(index) := '2'; when 3 => temp(index) := '3'; when 4 => temp(index) := '4'; when 5 => temp(index) := '5'; when 6 => temp(index) := '6'; when 7 => temp(index) := '7'; when 8 => temp(index) := '8'; when 9 => temp(index) := '9'; when others => ASSERT FALSE REPORT "Illegal number!" SEVERITY ERROR; end case; index := index + 1; end loop; if (value < 0) then return ('-'& temp(index downto 1)); else return temp(index downto 1); end if;end int2str;-- convert string to integerfunction str2int (s : string) return integer isvariable 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -