-- 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 ---START_PACKAGE_HEADER----------------------------------------------------- -- -- Package Name : ALTERA_COMMON_CONVERSION -- -- Description : Common conversion functions -- ---END_PACKAGE_HEADER-------------------------------------------------------- -- BEGINING OF PRIMITIVE Library ieee; use ieee.std_logic_1164.all; entity LCELL is port( a_in : in std_logic; a_out : out std_logic); end LCELL; architecture BEHAVIOR of LCELL is begin a_out <= a_in; end BEHAVIOR; -- BEGINING OF PACKAGE Library ieee; use ieee.std_logic_1164.all; use std.textio.all; -- PACKAGE DECLARATION package ALTERA_COMMON_CONVERSION is -- FUNCTION DECLARATION function INT_TO_STR_RAM (value : in integer) return string; function INT_TO_STR_ARITH (value : in integer) return string; function HEX_STR_TO_INT (str : in string) return integer; function BIN_STR_TO_INT (str : in string) return integer; function OCT_STR_TO_INT (str : in string) return integer; function INT_STR_TO_INT (str : in string) return integer; function ALPHA_TOLOWER (given_string : in string) return string; procedure SHRINK_LINE (str_line : inout line; pos : in integer); end ALTERA_COMMON_CONVERSION; package body ALTERA_COMMON_CONVERSION is -- This function converts an integer to a string function INT_TO_STR_RAM (value : in integer) return string is variable ivalue : integer := 0; variable index : integer := 0; variable digit : integer := 0; variable line_no: string(8 downto 1) := " "; begin ivalue := value; index := 1; 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 INT_TO_STR_RAM; function INT_TO_STR_ARITH (value : in integer) return string is variable ivalue : integer := 0; variable index : integer := 0; 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 INT_TO_STR_ARITH; -- This function converts a hexadecimal number to an integer function HEX_STR_TO_INT (str : in string) return integer is variable len : integer := str'length; variable ivalue : integer := 0; variable digit : integer := 0; begin for i in len downto 1 loop case str(i) is 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 'A' => digit := 10; when 'a' => digit := 10; when 'B' => digit := 11; when 'b' => digit := 11; when 'C' => digit := 12; when 'c' => digit := 12; when 'D' => digit := 13; when 'd' => digit := 13; when 'E' => digit := 14; when 'e' => digit := 14; when 'F' => digit := 15; when 'f' => digit := 15; when others => ASSERT FALSE REPORT "Illegal hex character "& str(i) & "! " SEVERITY ERROR; end case; ivalue := ivalue * 16 + digit; end loop; return ivalue; end HEX_STR_TO_INT; -- This function converts a binary number to an integer function BIN_STR_TO_INT (str : in string) return integer is variable len : integer := str'length; variable ivalue : integer := 0; variable digit : integer := 0; begin for i in len downto 1 loop case str(i) is when '0' => digit := 0; when '1' => digit := 1; when others => ASSERT FALSE REPORT "Illegal bin character "& str(i) & "! " SEVERITY ERROR; end case; ivalue := ivalue * 2 + digit; end loop; return ivalue; end BIN_STR_TO_INT; -- This function converts a octadecimal number to an integer function OCT_STR_TO_INT (str : in string) return integer is variable len : integer := str'length; variable ivalue : integer := 0; variable digit : integer := 0; begin for i in len downto 1 loop case str(i) is 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 others => ASSERT FALSE REPORT "Illegal octadecimal character "& str(i) & "! " SEVERITY ERROR; end case; ivalue := ivalue * 8 + digit; end loop; return ivalue; end OCT_STR_TO_INT; -- This function converts a integer string to an integer function INT_STR_TO_INT (str : in string) return integer is variable len : integer := str'length; variable newdigit : integer := 0; variable sign : integer := 1; variable digit : integer := 0; begin for i in 1 to len loop case str(i) is when '-' => if i = 1 then sign := -1; else ASSERT FALSE REPORT "Illegal Character "& str(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 "& str(i) & "in string parameter! " SEVERITY ERROR; end case; newdigit := newdigit * 10 + digit; end loop; return (sign*newdigit); end; -- converts uppercase parameter values (e.g. "AUTO") to lowercase ("auto") function ALPHA_TOLOWER (given_string : in string) return string is -- VARIABLE DECLARATION variable result_string : string(given_string'low to given_string'high); begin for i in given_string'low to given_string'high loop case given_string(i) is when 'A' => result_string(i) := 'a'; when 'B' => result_string(i) := 'b'; when 'C' => result_string(i) := 'c'; when 'D' => result_string(i) := 'd'; when 'E' => result_string(i) := 'e'; when 'F' => result_string(i) := 'f'; when 'G' => result_string(i) := 'g'; when 'H' => result_string(i) := 'h'; when 'I' => result_string(i) := 'i'; when 'J' => result_string(i) := 'j'; when 'K' => result_string(i) := 'k'; when 'L' => result_string(i) := 'l'; when 'M' => result_string(i) := 'm'; when 'N' => result_string(i) := 'n'; when 'O' => result_string(i) := 'o'; when 'P' => result_string(i) := 'p'; when 'Q' => result_string(i) := 'q'; when 'R' => result_string(i) := 'r'; when 'S' => result_string(i) := 's'; when 'T' => result_string(i) := 't'; when 'U' => result_string(i) := 'u'; when 'V' => result_string(i) := 'v'; when 'W' => result_string(i) := 'w'; when 'X' => result_string(i) := 'x'; when 'Y' => result_string(i) := 'y'; when 'Z' => result_string(i) := 'z'; when others => result_string(i) := given_string(i); end case; end loop; return (result_string(given_string'low to given_string'high)); end; -- This procedure "cuts" the str_line into desired length procedure SHRINK_LINE (str_line : inout line; pos : in integer) is subtype nstring is string(1 to pos); variable str : nstring; begin if (pos >= 1) then read(str_line, str); end if; end; end ALTERA_COMMON_CONVERSION; -- END OF PACKAGE ---START_PACKAGE_HEADER----------------------------------------------------- -- -- Package Name : ALTERA_MF_HINT_EVALUATION -- -- Description : Common function to grep the value of altera specific parameters -- within the lpm_hint parameter. -- ---END_PACKAGE_HEADER-------------------------------------------------------- -- BEGINING OF PACKAGE Library ieee; use ieee.std_logic_1164.all; -- PACKAGE DECLARATION package ALTERA_MF_HINT_EVALUATION is -- FUNCTION DECLARATION function get_parameter_value( constant given_string : string; compare_param_name : string) return string; end ALTERA_MF_HINT_EVALUATION; package body ALTERA_MF_HINT_EVALUATION is -- This function will search through the string (given string) to look for a match for the -- a given parameter(compare_param_name). It will return the value for the given parameter. function get_parameter_value( constant given_string : string; compare_param_name : string) return string is variable param_name_left_index : integer := given_string'length; variable param_name_right_index : integer := given_string'length; variable param_value_left_index : integer := given_string'length; variable param_value_right_index : integer := given_string'length; variable set_right_index : boolean := true; variable extract_param_value : boolean := true; variable extract_param_name : boolean := false; variable param_found : boolean := false; begin -- checking every character of the given_string from right to left. for i in given_string'length downto 1 loop if (given_string(i) /= ' ') then if (given_string(i) = '=') then extract_param_value := false; extract_param_name := true; set_right_index := true; elsif (given_string(i) = ',') then extract_param_value := true; extract_param_name := false; set_right_index := true; if (compare_param_name = given_string(param_name_left_index to param_name_right_index)) then param_found := true; -- the compare_param_name have been found in the given_string exit; end if; else if (extract_param_value = true) then if (set_right_index = true) then param_value_right_index := i; set_right_index := false; end if; param_value_left_index := i; elsif (extract_param_name = true) then if (set_right_index = true) then param_name_right_index := i; set_right_index := false; end if; param_name_left_index := i; end if; end if; end if; end loop; -- for the case whether parameter's name is the left most part of the given_string if (extract_param_name = true) then if(compare_param_name = given_string(param_name_left_index to param_name_right_index)) then param_found := true; end if; end if; if(param_found = true) then return given_string(param_value_left_index to param_value_right_index); else return ""; -- return empty string if parameter not found end if; end get_parameter_value; end ALTERA_MF_HINT_EVALUATION; -- END OF PACKAGE ---START_PACKAGE_HEADER----------------------------------------------------- -- -- Package Name : ALTERA_DEVICE_FAMILIES -- -- Description : Common Altera device families comparison -- ---END_PACKAGE_HEADER-------------------------------------------------------- -- BEGINING OF PACKAGES Library ieee; use ieee.std_logic_1164.all; -- PACKAGE DECLARATION package ALTERA_DEVICE_FAMILIES is -- FUNCTION DECLARATION function IS_FAMILY_ARRIA10 (device : in string) return boolean; function IS_FAMILY_ARRIAGX (device : in string) return boolean; function IS_FAMILY_ARRIAIIGX (device : in string) return boolean; function IS_FAMILY_ARRIAIIGZ (device : in string) return boolean; function IS_FAMILY_ARRIAVGZ (device : in string) return boolean; function IS_FAMILY_ARRIAV (device : in string) return boolean; function IS_FAMILY_CYCLONEII (device : in string) return boolean; function IS_FAMILY_CYCLONEIIILS (device : in string) return boolean; function IS_FAMILY_CYCLONEIII (device : in string) return boolean; function IS_FAMILY_CYCLONEIVE (device : in string) return boolean; function IS_FAMILY_CYCLONEIVGX (device : in string) return boolean; function IS_FAMILY_CYCLONEV (device : in string) return boolean; function IS_FAMILY_CYCLONE (device : in string) return boolean; function IS_FAMILY_HARDCOPYII (device : in string) return boolean; function IS_FAMILY_HARDCOPYIII (device : in string) return boolean; function IS_FAMILY_HARDCOPYIV (device : in string) return boolean; function IS_FAMILY_MAX10 (device : in string) return boolean; function IS_FAMILY_MAXII (device : in string) return boolean; function IS_FAMILY_MAXV (device : in string) return boolean; function IS_FAMILY_STRATIX10 (device : in string) return boolean; function IS_FAMILY_STRATIXGX (device : in string) return boolean; function IS_FAMILY_STRATIXIIGX (device : in string) return boolean; function IS_FAMILY_STRATIXII (device : in string) return boolean; function IS_FAMILY_STRATIXIII (device : in string) return boolean; function IS_FAMILY_STRATIXIV (device : in string) return boolean; function IS_FAMILY_STRATIXV (device : in string) return boolean; function IS_FAMILY_STRATIX (device : in string) return boolean; function FEATURE_FAMILY_STRATIXGX (device : in string) return boolean; function FEATURE_FAMILY_CYCLONE (device : in string) return boolean; function FEATURE_FAMILY_STRATIXIIGX (device : in string) return boolean; function FEATURE_FAMILY_STRATIXIII (device : in string) return boolean; function FEATURE_FAMILY_ARRIAVGZ (device : in string) return boolean; function FEATURE_FAMILY_STRATIXV (device : in string) return boolean; function FEATURE_FAMILY_ARRIA10 (device : in string) return boolean; function FEATURE_FAMILY_STRATIXII (device : in string) return boolean; function FEATURE_FAMILY_CYCLONEIVGX (device : in string) return boolean; function FEATURE_FAMILY_CYCLONEIVE (device : in string) return boolean; function FEATURE_FAMILY_CYCLONEIII (device : in string) return boolean; function FEATURE_FAMILY_STRATIX_HC (device : in string) return boolean; function FEATURE_FAMILY_HARDCOPYII (device : in string) return boolean; function FEATURE_FAMILY_STRATIX (device : in string) return boolean; function FEATURE_FAMILY_MAXII (device : in string) return boolean; function FEATURE_FAMILY_MAXV (device : in string) return boolean; function FEATURE_FAMILY_CYCLONEII (device : in string) return boolean; function FEATURE_FAMILY_STRATIXIV (device : in string) return boolean; function FEATURE_FAMILY_ARRIAIIGZ (device : in string) return boolean; function FEATURE_FAMILY_ARRIAIIGX (device : in string) return boolean; function FEATURE_FAMILY_HARDCOPYIII (device : in string) return boolean; function FEATURE_FAMILY_HARDCOPYIV (device : in string) return boolean; function FEATURE_FAMILY_CYCLONEV (device : in string) return boolean; function FEATURE_FAMILY_ARRIAV (device : in string) return boolean; function FEATURE_FAMILY_MAX10 (device : in string) return boolean; function FEATURE_FAMILY_STRATIX10 (device : in string) return boolean; function FEATURE_FAMILY_BASE_STRATIXII (device : in string) return boolean; function FEATURE_FAMILY_BASE_STRATIX (device : in string) return boolean; function FEATURE_FAMILY_BASE_CYCLONEII (device : in string) return boolean; function FEATURE_FAMILY_BASE_CYCLONE (device : in string) return boolean; function FEATURE_FAMILY_BASE_CYCLONEIII (device : in string) return boolean; function FEATURE_FAMILY_BASE_STRATIXIII (device : in string) return boolean; function FEATURE_FAMILY_STRATIX_NONGX (device : in string) return boolean; function FEATURE_FAMILY_HAS_ALTERA_MULT_ADD_FLOW (device : in string) return boolean; function FEATURE_FAMILY_IS_ALTMULT_ADD_EOL (device : in string) return boolean; function FEATURE_FAMILY_HAS_STRATIXV_STYLE_RAM (device : in string) return boolean; function FEATURE_FAMILY_HAS_MEGARAM (device : in string) return boolean; function FEATURE_FAMILY_HAS_M512 (device : in string) return boolean; function FEATURE_FAMILY_HAS_LUTRAM (device : in string) return boolean; function FEATURE_FAMILY_HAS_STRATIXI_STYLE_RAM (device : in string) return boolean; function FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM (device : in string) return boolean; function FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM (device : in string) return boolean; function FEATURE_FAMILY_HAS_STRATIX_STYLE_PLL (device : in string) return boolean; function FEATURE_FAMILY_HAS_STRATIXII_STYLE_PLL (device : in string) return boolean; function FEATURE_FAMILY_USES_STRATIXIII_PLL (device : in string) return boolean; function FEATURE_FAMILY_HAS_FLEXIBLE_LVDS (device : in string) return boolean; function FEATURE_FAMILY_HAS_INVERTED_OUTPUT_DDIO (device : in string) return boolean; function IS_VALID_FAMILY (device: in string) return boolean; end ALTERA_DEVICE_FAMILIES; package body ALTERA_DEVICE_FAMILIES is function IS_FAMILY_ARRIA10 (device : in string) return boolean is variable is_arria10 : boolean := false; begin if ((device = "Arria 10") or (device = "ARRIA 10") or (device = "arria 10") or (device = "Arria10") or (device = "ARRIA10") or (device = "arria10") or (device = "Arria VI") or (device = "ARRIA VI") or (device = "arria vi") or (device = "ArriaVI") or (device = "ARRIAVI") or (device = "arriavi") or (device = "Night Fury") or (device = "NIGHT FURY") or (device = "night fury") or (device = "nightfury") or (device = "NIGHTFURY") or (device = "Arria 10 (GX/SX/GT)") or (device = "ARRIA 10 (GX/SX/GT)") or (device = "arria 10 (gx/sx/gt)") or (device = "Arria10(GX/SX/GT)") or (device = "ARRIA10(GX/SX/GT)") or (device = "arria10(gx/sx/gt)") or (device = "Arria 10 (GX)") or (device = "ARRIA 10 (GX)") or (device = "arria 10 (gx)") or (device = "Arria10(GX)") or (device = "ARRIA10(GX)") or (device = "arria10(gx)") or (device = "Arria 10 (SX)") or (device = "ARRIA 10 (SX)") or (device = "arria 10 (sx)") or (device = "Arria10(SX)") or (device = "ARRIA10(SX)") or (device = "arria10(sx)") or (device = "Arria 10 (GT)") or (device = "ARRIA 10 (GT)") or (device = "arria 10 (gt)") or (device = "Arria10(GT)") or (device = "ARRIA10(GT)") or (device = "arria10(gt)")) then is_arria10 := true; end if; return is_arria10; end IS_FAMILY_ARRIA10; function IS_FAMILY_ARRIAGX (device : in string) return boolean is variable is_arriagx : boolean := false; begin if ((device = "Arria GX") or (device = "ARRIA GX") or (device = "arria gx") or (device = "ArriaGX") or (device = "ARRIAGX") or (device = "arriagx") or (device = "Stratix II GX Lite") or (device = "STRATIX II GX LITE") or (device = "stratix ii gx lite") or (device = "StratixIIGXLite") or (device = "STRATIXIIGXLITE") or (device = "stratixiigxlite")) then is_arriagx := true; end if; return is_arriagx; end IS_FAMILY_ARRIAGX; function IS_FAMILY_ARRIAIIGX (device : in string) return boolean is variable is_arriaiigx : boolean := false; begin if ((device = "Arria II GX") or (device = "ARRIA II GX") or (device = "arria ii gx") or (device = "ArriaIIGX") or (device = "ARRIAIIGX") or (device = "arriaiigx") or (device = "Arria IIGX") or (device = "ARRIA IIGX") or (device = "arria iigx") or (device = "ArriaII GX") or (device = "ARRIAII GX") or (device = "arriaii gx") or (device = "Arria II") or (device = "ARRIA II") or (device = "arria ii") or (device = "ArriaII") or (device = "ARRIAII") or (device = "arriaii") or (device = "Arria II (GX/E)") or (device = "ARRIA II (GX/E)") or (device = "arria ii (gx/e)") or (device = "ArriaII(GX/E)") or (device = "ARRIAII(GX/E)") or (device = "arriaii(gx/e)") or (device = "PIRANHA") or (device = "piranha")) then is_arriaiigx := true; end if; return is_arriaiigx; end IS_FAMILY_ARRIAIIGX; function IS_FAMILY_ARRIAIIGZ (device : in string) return boolean is variable is_arriaiigz : boolean := false; begin if ((device = "Arria II GZ") or (device = "ARRIA II GZ") or (device = "arria ii gz") or (device = "ArriaII GZ") or (device = "ARRIAII GZ") or (device = "arriaii gz") or (device = "Arria IIGZ") or (device = "ARRIA IIGZ") or (device = "arria iigz") or (device = "ArriaIIGZ") or (device = "ARRIAIIGZ") or (device = "arriaiigz")) then is_arriaiigz := true; end if; return is_arriaiigz; end IS_FAMILY_ARRIAIIGZ; function IS_FAMILY_ARRIAVGZ (device : in string) return boolean is variable is_arriavgz : boolean := false; begin if ((device = "Arria V GZ") or (device = "ARRIA V GZ") or (device = "arria v gz") or (device = "ArriaVGZ") or (device = "ARRIAVGZ") or (device = "arriavgz")) then is_arriavgz := true; end if; return is_arriavgz; end IS_FAMILY_ARRIAVGZ; function IS_FAMILY_ARRIAV (device : in string) return boolean is variable is_arriav : boolean := false; begin if ((device = "Arria V") or (device = "ARRIA V") or (device = "arria v") or (device = "Arria V (GT/GX)") or (device = "ARRIA V (GT/GX)") or (device = "arria v (gt/gx)") or (device = "ArriaV(GT/GX)") or (device = "ARRIAV(GT/GX)") or (device = "arriav(gt/gx)") or (device = "ArriaV") or (device = "ARRIAV") or (device = "arriav") or (device = "Arria V (GT/GX/ST/SX)") or (device = "ARRIA V (GT/GX/ST/SX)") or (device = "arria v (gt/gx/st/sx)") or (device = "ArriaV(GT/GX/ST/SX)") or (device = "ARRIAV(GT/GX/ST/SX)") or (device = "arriav(gt/gx/st/sx)") or (device = "Arria V (GT)") or (device = "ARRIA V (GT)") or (device = "arria v (gt)") or (device = "ArriaV(GT)") or (device = "ARRIAV(GT)") or (device = "arriav(gt)") or (device = "Arria V (GX)") or (device = "ARRIA V (GX)") or (device = "arria v (gx)") or (device = "ArriaV(GX)") or (device = "ARRIAV(GX)") or (device = "arriav(gx)") or (device = "Arria V (ST)") or (device = "ARRIA V (ST)") or (device = "arria v (st)") or (device = "ArriaV(ST)") or (device = "ARRIAV(ST)") or (device = "arriav(st)") or (device = "Arria V (SX)") or (device = "ARRIA V (SX)") or (device = "arria v (sx)") or (device = "ArriaV(SX)") or (device = "ARRIAV(SX)") or (device = "arriav(sx)")) then is_arriav := true; end if; return is_arriav; end IS_FAMILY_ARRIAV; function IS_FAMILY_CYCLONEII (device : in string) return boolean is variable is_cycloneii : boolean := false; begin if ((device = "Cyclone II") or (device = "CYCLONE II") or (device = "cyclone ii") or (device = "Cycloneii") or (device = "CYCLONEII") or (device = "cycloneii") or (device = "Magellan") or (device = "MAGELLAN") or (device = "magellan") or (device = "CycloneII") or (device = "CYCLONEII") or (device = "cycloneii")) then is_cycloneii := true; end if; return is_cycloneii; end IS_FAMILY_CYCLONEII; function IS_FAMILY_CYCLONEIIILS (device : in string) return boolean is variable is_cycloneiiils : boolean := false; begin if ((device = "Cyclone III LS") or (device = "CYCLONE III LS") or (device = "cyclone iii ls") or (device = "CycloneIIILS") or (device = "CYCLONEIIILS") or (device = "cycloneiiils") or (device = "Cyclone III LPS") or (device = "CYCLONE III LPS") or (device = "cyclone iii lps") or (device = "Cyclone LPS") or (device = "CYCLONE LPS") or (device = "cyclone lps") or (device = "CycloneLPS") or (device = "CYCLONELPS") or (device = "cyclonelps") or (device = "Tarpon") or (device = "TARPON") or (device = "tarpon") or (device = "Cyclone IIIE") or (device = "CYCLONE IIIE") or (device = "cyclone iiie")) then is_cycloneiiils := true; end if; return is_cycloneiiils; end IS_FAMILY_CYCLONEIIILS; function IS_FAMILY_CYCLONEIII (device : in string) return boolean is variable is_cycloneiii : boolean := false; begin if ((device = "Cyclone III") or (device = "CYCLONE III") or (device = "cyclone iii") or (device = "CycloneIII") or (device = "CYCLONEIII") or (device = "cycloneiii") or (device = "Barracuda") or (device = "BARRACUDA") or (device = "barracuda") or (device = "Cuda") or (device = "CUDA") or (device = "cuda") or (device = "CIII") or (device = "ciii")) then is_cycloneiii := true; end if; return is_cycloneiii; end IS_FAMILY_CYCLONEIII; function IS_FAMILY_CYCLONEIVE (device : in string) return boolean is variable is_cycloneive : boolean := false; begin if ((device = "Cyclone IV E") or (device = "CYCLONE IV E") or (device = "cyclone iv e") or (device = "CycloneIV E") or (device = "CYCLONEIV E") or (device = "cycloneiv e") or (device = "Cyclone IVE") or (device = "CYCLONE IVE") or (device = "cyclone ive") or (device = "CycloneIVE") or (device = "CYCLONEIVE") or (device = "cycloneive")) then is_cycloneive := true; end if; return is_cycloneive; end IS_FAMILY_CYCLONEIVE; function IS_FAMILY_CYCLONEIVGX (device : in string) return boolean is variable is_cycloneivgx : boolean := false; begin if ((device = "Cyclone IV GX") or (device = "CYCLONE IV GX") or (device = "cyclone iv gx") or (device = "Cyclone IVGX") or (device = "CYCLONE IVGX") or (device = "cyclone ivgx") or (device = "CycloneIV GX") or (device = "CYCLONEIV GX") or (device = "cycloneiv gx") or (device = "CycloneIVGX") or (device = "CYCLONEIVGX") or (device = "cycloneivgx") or (device = "Cyclone IV") or (device = "CYCLONE IV") or (device = "cyclone iv") or (device = "CycloneIV") or (device = "CYCLONEIV") or (device = "cycloneiv") or (device = "Cyclone IV (GX)") or (device = "CYCLONE IV (GX)") or (device = "cyclone iv (gx)") or (device = "CycloneIV(GX)") or (device = "CYCLONEIV(GX)") or (device = "cycloneiv(gx)") or (device = "Cyclone III GX") or (device = "CYCLONE III GX") or (device = "cyclone iii gx") or (device = "CycloneIII GX") or (device = "CYCLONEIII GX") or (device = "cycloneiii gx") or (device = "Cyclone IIIGX") or (device = "CYCLONE IIIGX") or (device = "cyclone iiigx") or (device = "CycloneIIIGX") or (device = "CYCLONEIIIGX") or (device = "cycloneiiigx") or (device = "Cyclone III GL") or (device = "CYCLONE III GL") or (device = "cyclone iii gl") or (device = "CycloneIII GL") or (device = "CYCLONEIII GL") or (device = "cycloneiii gl") or (device = "Cyclone IIIGL") or (device = "CYCLONE IIIGL") or (device = "cyclone iiigl") or (device = "CycloneIIIGL") or (device = "CYCLONEIIIGL") or (device = "cycloneiiigl") or (device = "Stingray") or (device = "STINGRAY") or (device = "stingray")) then is_cycloneivgx := true; end if; return is_cycloneivgx; end IS_FAMILY_CYCLONEIVGX; function IS_FAMILY_CYCLONEV (device : in string) return boolean is variable is_cyclonev : boolean := false; begin if ((device = "Cyclone V") or (device = "CYCLONE V") or (device = "cyclone v") or (device = "CycloneV") or (device = "CYCLONEV") or (device = "cyclonev") or (device = "Cyclone V (GT/GX/E/SX)") or (device = "CYCLONE V (GT/GX/E/SX)") or (device = "cyclone v (gt/gx/e/sx)") or (device = "CycloneV(GT/GX/E/SX)") or (device = "CYCLONEV(GT/GX/E/SX)") or (device = "cyclonev(gt/gx/e/sx)") or (device = "Cyclone V (E/GX/GT/SX/SE/ST)") or (device = "CYCLONE V (E/GX/GT/SX/SE/ST)") or (device = "cyclone v (e/gx/gt/sx/se/st)") or (device = "CycloneV(E/GX/GT/SX/SE/ST)") or (device = "CYCLONEV(E/GX/GT/SX/SE/ST)") or (device = "cyclonev(e/gx/gt/sx/se/st)") or (device = "Cyclone V (E)") or (device = "CYCLONE V (E)") or (device = "cyclone v (e)") or (device = "CycloneV(E)") or (device = "CYCLONEV(E)") or (device = "cyclonev(e)") or (device = "Cyclone V (GX)") or (device = "CYCLONE V (GX)") or (device = "cyclone v (gx)") or (device = "CycloneV(GX)") or (device = "CYCLONEV(GX)") or (device = "cyclonev(gx)") or (device = "Cyclone V (GT)") or (device = "CYCLONE V (GT)") or (device = "cyclone v (gt)") or (device = "CycloneV(GT)") or (device = "CYCLONEV(GT)") or (device = "cyclonev(gt)") or (device = "Cyclone V (SX)") or (device = "CYCLONE V (SX)") or (device = "cyclone v (sx)") or (device = "CycloneV(SX)") or (device = "CYCLONEV(SX)") or (device = "cyclonev(sx)") or (device = "Cyclone V (SE)") or (device = "CYCLONE V (SE)") or (device = "cyclone v (se)") or (device = "CycloneV(SE)") or (device = "CYCLONEV(SE)") or (device = "cyclonev(se)") or (device = "Cyclone V (ST)") or (device = "CYCLONE V (ST)") or (device = "cyclone v (st)") or (device = "CycloneV(ST)") or (device = "CYCLONEV(ST)") or (device = "cyclonev(st)")) then is_cyclonev := true; end if; return is_cyclonev; end IS_FAMILY_CYCLONEV; function IS_FAMILY_CYCLONE (device : in string) return boolean is variable is_cyclone : boolean := false; begin if ((device = "Cyclone") or (device = "CYCLONE") or (device = "cyclone") or (device = "ACEX2K") or (device = "acex2k") or (device = "ACEX 2K") or (device = "acex 2k") or (device = "Tornado") or (device = "TORNADO") or (device = "tornado")) then is_cyclone := true; end if; return is_cyclone; end IS_FAMILY_CYCLONE; function IS_FAMILY_HARDCOPYII (device : in string) return boolean is variable is_hardcopyii : boolean := false; begin if ((device = "HardCopy II") or (device = "HARDCOPY II") or (device = "hardcopy ii") or (device = "HardCopyII") or (device = "HARDCOPYII") or (device = "hardcopyii") or (device = "Fusion") or (device = "FUSION") or (device = "fusion")) then is_hardcopyii := true; end if; return is_hardcopyii; end IS_FAMILY_HARDCOPYII; function IS_FAMILY_HARDCOPYIII (device : in string) return boolean is variable is_hardcopyiii : boolean := false; begin if ((device = "HardCopy III") or (device = "HARDCOPY III") or (device = "hardcopy iii") or (device = "HardCopyIII") or (device = "HARDCOPYIII") or (device = "hardcopyiii") or (device = "HCX") or (device = "hcx")) then is_hardcopyiii := true; end if; return is_hardcopyiii; end IS_FAMILY_HARDCOPYIII; function IS_FAMILY_HARDCOPYIV (device : in string) return boolean is variable is_hardcopyiv : boolean := false; begin if ((device = "HardCopy IV") or (device = "HARDCOPY IV") or (device = "hardcopy iv") or (device = "HardCopyIV") or (device = "HARDCOPYIV") or (device = "hardcopyiv") or (device = "HardCopy IV (GX)") or (device = "HARDCOPY IV (GX)") or (device = "hardcopy iv (gx)") or (device = "HardCopy IV (E)") or (device = "HARDCOPY IV (E)") or (device = "hardcopy iv (e)") or (device = "HardCopyIV(GX)") or (device = "HARDCOPYIV(GX)") or (device = "hardcopyiv(gx)") or (device = "HardCopyIV(E)") or (device = "HARDCOPYIV(E)") or (device = "hardcopyiv(e)") or (device = "HCXIV") or (device = "hcxiv") or (device = "HardCopy IV (GX/E)") or (device = "HARDCOPY IV (GX/E)") or (device = "hardcopy iv (gx/e)") or (device = "HardCopy IV (E/GX)") or (device = "HARDCOPY IV (E/GX)") or (device = "hardcopy iv (e/gx)") or (device = "HardCopyIV(GX/E)") or (device = "HARDCOPYIV(GX/E)") or (device = "hardcopyiv(gx/e)") or (device = "HardCopyIV(E/GX)") or (device = "HARDCOPYIV(E/GX)") or (device = "hardcopyiv(e/gx)")) then is_hardcopyiv := true; end if; return is_hardcopyiv; end IS_FAMILY_HARDCOPYIV; function IS_FAMILY_MAX10 (device : in string) return boolean is variable is_max10 : boolean := false; begin if ((device = "MAX 10") or (device = "max 10") or (device = "MAX 10 FPGA") or (device = "max 10 fpga") or (device = "Zippleback") or (device = "ZIPPLEBACK") or (device = "zippleback") or (device = "MAX10") or (device = "max10") or (device = "MAX 10 (DA/DF/DC/SA/SF/SC)") or (device = "max 10 (da/df/dc/sa/sf/sc)") or (device = "MAX10(DA/DF/DC/SA/SF/SC)") or (device = "max10(da/df/dc/sa/sf/sc)") or (device = "MAX 10 (DA)") or (device = "max 10 (da)") or (device = "MAX10(DA)") or (device = "max10(da)") or (device = "MAX 10 (DF)") or (device = "max 10 (df)") or (device = "MAX10(DF)") or (device = "max10(df)") or (device = "MAX 10 (DC)") or (device = "max 10 (dc)") or (device = "MAX10(DC)") or (device = "max10(dc)") or (device = "MAX 10 (SA)") or (device = "max 10 (sa)") or (device = "MAX10(SA)") or (device = "max10(sa)") or (device = "MAX 10 (SF)") or (device = "max 10 (sf)") or (device = "MAX10(SF)") or (device = "max10(sf)") or (device = "MAX 10 (SC)") or (device = "max 10 (sc)") or (device = "MAX10(SC)") or (device = "max10(sc)")) then is_max10 := true; end if; return is_max10; end IS_FAMILY_MAX10; function IS_FAMILY_MAXII (device : in string) return boolean is variable is_maxii : boolean := false; begin if ((device = "MAX II") or (device = "max ii") or (device = "MAXII") or (device = "maxii") or (device = "Tsunami") or (device = "TSUNAMI") or (device = "tsunami")) then is_maxii := true; end if; return is_maxii; end IS_FAMILY_MAXII; function IS_FAMILY_MAXV (device : in string) return boolean is variable is_maxv : boolean := false; begin if ((device = "MAX V") or (device = "max v") or (device = "MAXV") or (device = "maxv") or (device = "Jade") or (device = "JADE") or (device = "jade")) then is_maxv := true; end if; return is_maxv; end IS_FAMILY_MAXV; function IS_FAMILY_STRATIX10 (device : in string) return boolean is variable is_stratix10 : boolean := false; begin if ((device = "Stratix 10") or (device = "STRATIX 10") or (device = "stratix 10") or (device = "Stratix10") or (device = "STRATIX10") or (device = "stratix10") or (device = "nadder") or (device = "NADDER")) then is_stratix10 := true; end if; return is_stratix10; end IS_FAMILY_STRATIX10; function IS_FAMILY_STRATIXGX (device : in string) return boolean is variable is_stratixgx : boolean := false; begin if ((device = "Stratix GX") or (device = "STRATIX GX") or (device = "stratix gx") or (device = "Stratix-GX") or (device = "STRATIX-GX") or (device = "stratix-gx") or (device = "StratixGX") or (device = "STRATIXGX") or (device = "stratixgx") or (device = "Aurora") or (device = "AURORA") or (device = "aurora")) then is_stratixgx := true; end if; return is_stratixgx; end IS_FAMILY_STRATIXGX; function IS_FAMILY_STRATIXIIGX (device : in string) return boolean is variable is_stratixiigx : boolean := false; begin if ((device = "Stratix II GX") or (device = "STRATIX II GX") or (device = "stratix ii gx") or (device = "StratixIIGX") or (device = "STRATIXIIGX") or (device = "stratixiigx")) then is_stratixiigx := true; end if; return is_stratixiigx; end IS_FAMILY_STRATIXIIGX; function IS_FAMILY_STRATIXII (device : in string) return boolean is variable is_stratixii : boolean := false; begin if ((device = "Stratix II") or (device = "STRATIX II") or (device = "stratix ii") or (device = "StratixII") or (device = "STRATIXII") or (device = "stratixii") or (device = "Armstrong") or (device = "ARMSTRONG") or (device = "armstrong")) then is_stratixii := true; end if; return is_stratixii; end IS_FAMILY_STRATIXII; function IS_FAMILY_STRATIXIII (device : in string) return boolean is variable is_stratixiii : boolean := false; begin if ((device = "Stratix III") or (device = "STRATIX III") or (device = "stratix iii") or (device = "StratixIII") or (device = "STRATIXIII") or (device = "stratixiii") or (device = "Titan") or (device = "TITAN") or (device = "titan") or (device = "SIII") or (device = "siii")) then is_stratixiii := true; end if; return is_stratixiii; end IS_FAMILY_STRATIXIII; function IS_FAMILY_STRATIXIV (device : in string) return boolean is variable is_stratixiv : boolean := false; begin if ((device = "Stratix IV") or (device = "STRATIX IV") or (device = "stratix iv") or (device = "TGX") or (device = "tgx") or (device = "StratixIV") or (device = "STRATIXIV") or (device = "stratixiv") or (device = "Stratix IV (GT)") or (device = "STRATIX IV (GT)") or (device = "stratix iv (gt)") or (device = "Stratix IV (GX)") or (device = "STRATIX IV (GX)") or (device = "stratix iv (gx)") or (device = "Stratix IV (E)") or (device = "STRATIX IV (E)") or (device = "stratix iv (e)") or (device = "StratixIV(GT)") or (device = "STRATIXIV(GT)") or (device = "stratixiv(gt)") or (device = "StratixIV(GX)") or (device = "STRATIXIV(GX)") or (device = "stratixiv(gx)") or (device = "StratixIV(E)") or (device = "STRATIXIV(E)") or (device = "stratixiv(e)") or (device = "StratixIIIGX") or (device = "STRATIXIIIGX") or (device = "stratixiiigx") or (device = "Stratix IV (GT/GX/E)") or (device = "STRATIX IV (GT/GX/E)") or (device = "stratix iv (gt/gx/e)") or (device = "Stratix IV (GT/E/GX)") or (device = "STRATIX IV (GT/E/GX)") or (device = "stratix iv (gt/e/gx)") or (device = "Stratix IV (E/GT/GX)") or (device = "STRATIX IV (E/GT/GX)") or (device = "stratix iv (e/gt/gx)") or (device = "Stratix IV (E/GX/GT)") or (device = "STRATIX IV (E/GX/GT)") or (device = "stratix iv (e/gx/gt)") or (device = "StratixIV(GT/GX/E)") or (device = "STRATIXIV(GT/GX/E)") or (device = "stratixiv(gt/gx/e)") or (device = "StratixIV(GT/E/GX)") or (device = "STRATIXIV(GT/E/GX)") or (device = "stratixiv(gt/e/gx)") or (device = "StratixIV(E/GX/GT)") or (device = "STRATIXIV(E/GX/GT)") or (device = "stratixiv(e/gx/gt)") or (device = "StratixIV(E/GT/GX)") or (device = "STRATIXIV(E/GT/GX)") or (device = "stratixiv(e/gt/gx)") or (device = "Stratix IV (GX/E)") or (device = "STRATIX IV (GX/E)") or (device = "stratix iv (gx/e)") or (device = "StratixIV(GX/E)") or (device = "STRATIXIV(GX/E)") or (device = "stratixiv(gx/e)")) then is_stratixiv := true; end if; return is_stratixiv; end IS_FAMILY_STRATIXIV; function IS_FAMILY_STRATIXV (device : in string) return boolean is variable is_stratixv : boolean := false; begin if ((device = "Stratix V") or (device = "STRATIX V") or (device = "stratix v") or (device = "StratixV") or (device = "STRATIXV") or (device = "stratixv") or (device = "Stratix V (GS)") or (device = "STRATIX V (GS)") or (device = "stratix v (gs)") or (device = "StratixV(GS)") or (device = "STRATIXV(GS)") or (device = "stratixv(gs)") or (device = "Stratix V (GT)") or (device = "STRATIX V (GT)") or (device = "stratix v (gt)") or (device = "StratixV(GT)") or (device = "STRATIXV(GT)") or (device = "stratixv(gt)") or (device = "Stratix V (GX)") or (device = "STRATIX V (GX)") or (device = "stratix v (gx)") or (device = "StratixV(GX)") or (device = "STRATIXV(GX)") or (device = "stratixv(gx)") or (device = "Stratix V (GS/GX)") or (device = "STRATIX V (GS/GX)") or (device = "stratix v (gs/gx)") or (device = "StratixV(GS/GX)") or (device = "STRATIXV(GS/GX)") or (device = "stratixv(gs/gx)") or (device = "Stratix V (GS/GT)") or (device = "STRATIX V (GS/GT)") or (device = "stratix v (gs/gt)") or (device = "StratixV(GS/GT)") or (device = "STRATIXV(GS/GT)") or (device = "stratixv(gs/gt)") or (device = "Stratix V (GT/GX)") or (device = "STRATIX V (GT/GX)") or (device = "stratix v (gt/gx)") or (device = "StratixV(GT/GX)") or (device = "STRATIXV(GT/GX)") or (device = "stratixv(gt/gx)") or (device = "Stratix V (GX/GS)") or (device = "STRATIX V (GX/GS)") or (device = "stratix v (gx/gs)") or (device = "StratixV(GX/GS)") or (device = "STRATIXV(GX/GS)") or (device = "stratixv(gx/gs)") or (device = "Stratix V (GT/GS)") or (device = "STRATIX V (GT/GS)") or (device = "stratix v (gt/gs)") or (device = "StratixV(GT/GS)") or (device = "STRATIXV(GT/GS)") or (device = "stratixv(gt/gs)") or (device = "Stratix V (GX/GT)") or (device = "STRATIX V (GX/GT)") or (device = "stratix v (gx/gt)") or (device = "StratixV(GX/GT)") or (device = "STRATIXV(GX/GT)") or (device = "stratixv(gx/gt)") or (device = "Stratix V (GS/GT/GX)") or (device = "STRATIX V (GS/GT/GX)") or (device = "stratix v (gs/gt/gx)") or (device = "Stratix V (GS/GX/GT)") or (device = "STRATIX V (GS/GX/GT)") or (device = "stratix v (gs/gx/gt)") or (device = "Stratix V (GT/GS/GX)") or (device = "STRATIX V (GT/GS/GX)") or (device = "stratix v (gt/gs/gx)") or (device = "Stratix V (GT/GX/GS)") or (device = "STRATIX V (GT/GX/GS)") or (device = "stratix v (gt/gx/gs)") or (device = "Stratix V (GX/GS/GT)") or (device = "STRATIX V (GX/GS/GT)") or (device = "stratix v (gx/gs/gt)") or (device = "Stratix V (GX/GT/GS)") or (device = "STRATIX V (GX/GT/GS)") or (device = "stratix v (gx/gt/gs)") or (device = "StratixV(GS/GT/GX)") or (device = "STRATIXV(GS/GT/GX)") or (device = "stratixv(gs/gt/gx)") or (device = "StratixV(GS/GX/GT)") or (device = "STRATIXV(GS/GX/GT)") or (device = "stratixv(gs/gx/gt)") or (device = "StratixV(GT/GS/GX)") or (device = "STRATIXV(GT/GS/GX)") or (device = "stratixv(gt/gs/gx)") or (device = "StratixV(GT/GX/GS)") or (device = "STRATIXV(GT/GX/GS)") or (device = "stratixv(gt/gx/gs)") or (device = "StratixV(GX/GS/GT)") or (device = "STRATIXV(GX/GS/GT)") or (device = "stratixv(gx/gs/gt)") or (device = "StratixV(GX/GT/GS)") or (device = "STRATIXV(GX/GT/GS)") or (device = "stratixv(gx/gt/gs)") or (device = "Stratix V (GS/GT/GX/E)") or (device = "STRATIX V (GS/GT/GX/E)") or (device = "stratix v (gs/gt/gx/e)") or (device = "StratixV(GS/GT/GX/E)") or (device = "STRATIXV(GS/GT/GX/E)") or (device = "stratixv(gs/gt/gx/e)") or (device = "Stratix V (E)") or (device = "STRATIX V (E)") or (device = "stratix v (e)") or (device = "StratixV(E)") or (device = "STRATIXV(E)") or (device = "stratixv(e)")) then is_stratixv := true; end if; return is_stratixv; end IS_FAMILY_STRATIXV; function IS_FAMILY_STRATIX (device : in string) return boolean is variable is_stratix : boolean := false; begin if ((device = "Stratix") or (device = "STRATIX") or (device = "stratix") or (device = "Yeager") or (device = "YEAGER") or (device = "yeager")) then is_stratix := true; end if; return is_stratix; end IS_FAMILY_STRATIX; function FEATURE_FAMILY_STRATIXGX (device : in string) return boolean is variable var_family_stratixgx : boolean := false; begin if (IS_FAMILY_STRATIXGX(device) ) then var_family_stratixgx := true; end if; return var_family_stratixgx; end FEATURE_FAMILY_STRATIXGX; function FEATURE_FAMILY_CYCLONE (device : in string) return boolean is variable var_family_cyclone : boolean := false; begin if (IS_FAMILY_CYCLONE(device) ) then var_family_cyclone := true; end if; return var_family_cyclone; end FEATURE_FAMILY_CYCLONE; function FEATURE_FAMILY_STRATIXIIGX (device : in string) return boolean is variable var_family_stratixiigx : boolean := false; begin if (IS_FAMILY_STRATIXIIGX(device) or IS_FAMILY_ARRIAGX(device) ) then var_family_stratixiigx := true; end if; return var_family_stratixiigx; end FEATURE_FAMILY_STRATIXIIGX; function FEATURE_FAMILY_STRATIXIII (device : in string) return boolean is variable var_family_stratixiii : boolean := false; begin if (IS_FAMILY_STRATIXIII(device) or FEATURE_FAMILY_STRATIXIV(device) or FEATURE_FAMILY_HARDCOPYIII(device) ) then var_family_stratixiii := true; end if; return var_family_stratixiii; end FEATURE_FAMILY_STRATIXIII; function FEATURE_FAMILY_ARRIAVGZ (device : in string) return boolean is variable var_family_arriavgz : boolean := false; begin if (IS_FAMILY_ARRIAVGZ(device) ) then var_family_arriavgz := true; end if; return var_family_arriavgz; end FEATURE_FAMILY_ARRIAVGZ; function FEATURE_FAMILY_STRATIXV (device : in string) return boolean is variable var_family_stratixv : boolean := false; begin if (IS_FAMILY_STRATIXV(device) or FEATURE_FAMILY_ARRIAVGZ(device) ) then var_family_stratixv := true; end if; return var_family_stratixv; end FEATURE_FAMILY_STRATIXV; function FEATURE_FAMILY_ARRIA10 (device : in string) return boolean is variable var_family_arria10 : boolean := false; begin if (IS_FAMILY_ARRIA10(device) or IS_FAMILY_ARRIA10(device) ) then var_family_arria10 := true; end if; return var_family_arria10; end FEATURE_FAMILY_ARRIA10; function FEATURE_FAMILY_STRATIXII (device : in string) return boolean is variable var_family_stratixii : boolean := false; begin if (IS_FAMILY_STRATIXII(device) or IS_FAMILY_HARDCOPYII(device) or FEATURE_FAMILY_STRATIXIIGX(device) or FEATURE_FAMILY_STRATIXIII(device) ) then var_family_stratixii := true; end if; return var_family_stratixii; end FEATURE_FAMILY_STRATIXII; function FEATURE_FAMILY_CYCLONEIVGX (device : in string) return boolean is variable var_family_cycloneivgx : boolean := false; begin if (IS_FAMILY_CYCLONEIVGX(device) or IS_FAMILY_CYCLONEIVGX(device) ) then var_family_cycloneivgx := true; end if; return var_family_cycloneivgx; end FEATURE_FAMILY_CYCLONEIVGX; function FEATURE_FAMILY_CYCLONEIVE (device : in string) return boolean is variable var_family_cycloneive : boolean := false; begin if (IS_FAMILY_CYCLONEIVE(device) ) then var_family_cycloneive := true; end if; return var_family_cycloneive; end FEATURE_FAMILY_CYCLONEIVE; function FEATURE_FAMILY_CYCLONEIII (device : in string) return boolean is variable var_family_cycloneiii : boolean := false; begin if (IS_FAMILY_CYCLONEIII(device) or IS_FAMILY_CYCLONEIIILS(device) or FEATURE_FAMILY_CYCLONEIVGX(device) or FEATURE_FAMILY_CYCLONEIVE(device) or FEATURE_FAMILY_MAX10(device) ) then var_family_cycloneiii := true; end if; return var_family_cycloneiii; end FEATURE_FAMILY_CYCLONEIII; function FEATURE_FAMILY_STRATIX_HC (device : in string) return boolean is variable var_family_stratix_hc : boolean := false; begin if ((device = "StratixHC") ) then var_family_stratix_hc := true; end if; return var_family_stratix_hc; end FEATURE_FAMILY_STRATIX_HC; function FEATURE_FAMILY_HARDCOPYII (device : in string) return boolean is variable var_family_hardcopyii : boolean := false; begin if (IS_FAMILY_HARDCOPYII(device) ) then var_family_hardcopyii := true; end if; return var_family_hardcopyii; end FEATURE_FAMILY_HARDCOPYII; function FEATURE_FAMILY_STRATIX (device : in string) return boolean is variable var_family_stratix : boolean := false; begin if (IS_FAMILY_STRATIX(device) or FEATURE_FAMILY_STRATIX_HC(device) or FEATURE_FAMILY_STRATIXGX(device) or FEATURE_FAMILY_CYCLONE(device) or FEATURE_FAMILY_STRATIXII(device) or FEATURE_FAMILY_MAXII(device) or FEATURE_FAMILY_CYCLONEII(device) ) then var_family_stratix := true; end if; return var_family_stratix; end FEATURE_FAMILY_STRATIX; function FEATURE_FAMILY_MAXII (device : in string) return boolean is variable var_family_maxii : boolean := false; begin if (IS_FAMILY_MAXII(device) or FEATURE_FAMILY_MAXV(device) ) then var_family_maxii := true; end if; return var_family_maxii; end FEATURE_FAMILY_MAXII; function FEATURE_FAMILY_MAXV (device : in string) return boolean is variable var_family_maxv : boolean := false; begin if (IS_FAMILY_MAXV(device) ) then var_family_maxv := true; end if; return var_family_maxv; end FEATURE_FAMILY_MAXV; function FEATURE_FAMILY_CYCLONEII (device : in string) return boolean is variable var_family_cycloneii : boolean := false; begin if (IS_FAMILY_CYCLONEII(device) or FEATURE_FAMILY_CYCLONEIII(device) ) then var_family_cycloneii := true; end if; return var_family_cycloneii; end FEATURE_FAMILY_CYCLONEII; function FEATURE_FAMILY_STRATIXIV (device : in string) return boolean is variable var_family_stratixiv : boolean := false; begin if (IS_FAMILY_STRATIXIV(device) or IS_FAMILY_ARRIAIIGX(device) or FEATURE_FAMILY_HARDCOPYIV(device) or FEATURE_FAMILY_STRATIXV(device) or FEATURE_FAMILY_ARRIAV(device) or FEATURE_FAMILY_ARRIAIIGZ(device) or FEATURE_FAMILY_ARRIA10(device) ) then var_family_stratixiv := true; end if; return var_family_stratixiv; end FEATURE_FAMILY_STRATIXIV; function FEATURE_FAMILY_ARRIAIIGZ (device : in string) return boolean is variable var_family_arriaiigz : boolean := false; begin if (IS_FAMILY_ARRIAIIGZ(device) ) then var_family_arriaiigz := true; end if; return var_family_arriaiigz; end FEATURE_FAMILY_ARRIAIIGZ; function FEATURE_FAMILY_ARRIAIIGX (device : in string) return boolean is variable var_family_arriaiigx : boolean := false; begin if (IS_FAMILY_ARRIAIIGX(device) ) then var_family_arriaiigx := true; end if; return var_family_arriaiigx; end FEATURE_FAMILY_ARRIAIIGX; function FEATURE_FAMILY_HARDCOPYIII (device : in string) return boolean is variable var_family_hardcopyiii : boolean := false; begin if (IS_FAMILY_HARDCOPYIII(device) or IS_FAMILY_HARDCOPYIII(device) ) then var_family_hardcopyiii := true; end if; return var_family_hardcopyiii; end FEATURE_FAMILY_HARDCOPYIII; function FEATURE_FAMILY_HARDCOPYIV (device : in string) return boolean is variable var_family_hardcopyiv : boolean := false; begin if (IS_FAMILY_HARDCOPYIV(device) or IS_FAMILY_HARDCOPYIV(device) ) then var_family_hardcopyiv := true; end if; return var_family_hardcopyiv; end FEATURE_FAMILY_HARDCOPYIV; function FEATURE_FAMILY_CYCLONEV (device : in string) return boolean is variable var_family_cyclonev : boolean := false; begin if (IS_FAMILY_CYCLONEV(device) ) then var_family_cyclonev := true; end if; return var_family_cyclonev; end FEATURE_FAMILY_CYCLONEV; function FEATURE_FAMILY_ARRIAV (device : in string) return boolean is variable var_family_arriav : boolean := false; begin if (IS_FAMILY_ARRIAV(device) or FEATURE_FAMILY_CYCLONEV(device) ) then var_family_arriav := true; end if; return var_family_arriav; end FEATURE_FAMILY_ARRIAV; function FEATURE_FAMILY_MAX10 (device : in string) return boolean is variable var_family_max10 : boolean := false; begin if (IS_FAMILY_MAX10(device) ) then var_family_max10 := true; end if; return var_family_max10; end FEATURE_FAMILY_MAX10; function FEATURE_FAMILY_STRATIX10 (device : in string) return boolean is variable var_family_stratix10 : boolean := false; begin if (IS_FAMILY_STRATIX10(device) or IS_FAMILY_STRATIX10(device) ) then var_family_stratix10 := true; end if; return var_family_stratix10; end FEATURE_FAMILY_STRATIX10; function FEATURE_FAMILY_BASE_STRATIXII (device : in string) return boolean is variable var_family_base_stratixii : boolean := false; begin if (IS_FAMILY_STRATIXII(device) or IS_FAMILY_HARDCOPYII(device) or FEATURE_FAMILY_STRATIXIIGX(device) ) then var_family_base_stratixii := true; end if; return var_family_base_stratixii; end FEATURE_FAMILY_BASE_STRATIXII; function FEATURE_FAMILY_BASE_STRATIX (device : in string) return boolean is variable var_family_base_stratix : boolean := false; begin if (IS_FAMILY_STRATIX(device) or IS_FAMILY_STRATIXGX(device) ) then var_family_base_stratix := true; end if; return var_family_base_stratix; end FEATURE_FAMILY_BASE_STRATIX; function FEATURE_FAMILY_BASE_CYCLONEII (device : in string) return boolean is variable var_family_base_cycloneii : boolean := false; begin if (IS_FAMILY_CYCLONEII(device) ) then var_family_base_cycloneii := true; end if; return var_family_base_cycloneii; end FEATURE_FAMILY_BASE_CYCLONEII; function FEATURE_FAMILY_BASE_CYCLONE (device : in string) return boolean is variable var_family_base_cyclone : boolean := false; begin if (IS_FAMILY_CYCLONE(device) ) then var_family_base_cyclone := true; end if; return var_family_base_cyclone; end FEATURE_FAMILY_BASE_CYCLONE; function FEATURE_FAMILY_BASE_CYCLONEIII (device : in string) return boolean is variable var_family_base_cycloneiii : boolean := false; begin if (IS_FAMILY_CYCLONEIII(device) or IS_FAMILY_CYCLONEIIILS(device) or IS_FAMILY_CYCLONEIVGX(device) or FEATURE_FAMILY_CYCLONEIVE(device) or FEATURE_FAMILY_MAX10(device) ) then var_family_base_cycloneiii := true; end if; return var_family_base_cycloneiii; end FEATURE_FAMILY_BASE_CYCLONEIII; function FEATURE_FAMILY_BASE_STRATIXIII (device : in string) return boolean is variable var_family_base_stratixiii : boolean := false; begin if (IS_FAMILY_STRATIXIII(device) or FEATURE_FAMILY_STRATIXIV(device) or IS_FAMILY_HARDCOPYIII(device) ) then var_family_base_stratixiii := true; end if; return var_family_base_stratixiii; end FEATURE_FAMILY_BASE_STRATIXIII; function FEATURE_FAMILY_STRATIX_NONGX (device : in string) return boolean is variable var_family_stratix_nongx : boolean := false; begin if (IS_FAMILY_STRATIX(device) ) then var_family_stratix_nongx := true; end if; return var_family_stratix_nongx; end FEATURE_FAMILY_STRATIX_NONGX; function FEATURE_FAMILY_HAS_ALTERA_MULT_ADD_FLOW (device : in string) return boolean is variable var_family_has_altera_mult_add_flow : boolean := false; begin if (FEATURE_FAMILY_STRATIXV(device) or FEATURE_FAMILY_ARRIAV(device) or FEATURE_FAMILY_CYCLONEV(device) or FEATURE_FAMILY_ARRIA10(device) or FEATURE_FAMILY_STRATIX10(device) ) then var_family_has_altera_mult_add_flow := true; end if; return var_family_has_altera_mult_add_flow; end FEATURE_FAMILY_HAS_ALTERA_MULT_ADD_FLOW; function FEATURE_FAMILY_IS_ALTMULT_ADD_EOL (device : in string) return boolean is variable var_family_is_altmult_add_eol : boolean := false; begin if (FEATURE_FAMILY_ARRIA10(device) or FEATURE_FAMILY_STRATIX10(device) ) then var_family_is_altmult_add_eol := true; end if; return var_family_is_altmult_add_eol; end FEATURE_FAMILY_IS_ALTMULT_ADD_EOL; function FEATURE_FAMILY_HAS_STRATIXV_STYLE_RAM (device : in string) return boolean is variable var_family_has_stratixv_style_ram : boolean := false; begin if (FEATURE_FAMILY_STRATIXV(device) or FEATURE_FAMILY_ARRIAV(device) or FEATURE_FAMILY_ARRIA10(device) ) then var_family_has_stratixv_style_ram := true; end if; return var_family_has_stratixv_style_ram; end FEATURE_FAMILY_HAS_STRATIXV_STYLE_RAM; function FEATURE_FAMILY_HAS_MEGARAM (device : in string) return boolean is variable var_family_has_megaram : boolean := false; begin if (( ( IS_FAMILY_STRATIX(device) or FEATURE_FAMILY_STRATIX_HC(device) or IS_FAMILY_STRATIXGX(device) or FEATURE_FAMILY_STRATIXII(device) ) and NOT FEATURE_FAMILY_ARRIAIIGX(device) ) and NOT FEATURE_FAMILY_HAS_STRATIXV_STYLE_RAM(device) ) then var_family_has_megaram := true; end if; return var_family_has_megaram; end FEATURE_FAMILY_HAS_MEGARAM; function FEATURE_FAMILY_HAS_M512 (device : in string) return boolean is variable var_family_has_m512 : boolean := false; begin if (IS_FAMILY_STRATIX(device) or FEATURE_FAMILY_STRATIX_HC(device) or IS_FAMILY_STRATIXGX(device) or IS_FAMILY_STRATIXII(device) or FEATURE_FAMILY_STRATIXIIGX(device) ) then var_family_has_m512 := true; end if; return var_family_has_m512; end FEATURE_FAMILY_HAS_M512; function FEATURE_FAMILY_HAS_LUTRAM (device : in string) return boolean is variable var_family_has_lutram : boolean := false; begin if (FEATURE_FAMILY_STRATIXIII(device) or FEATURE_FAMILY_HAS_STRATIXV_STYLE_RAM(device) or FEATURE_FAMILY_STRATIX10(device) ) then var_family_has_lutram := true; end if; return var_family_has_lutram; end FEATURE_FAMILY_HAS_LUTRAM; function FEATURE_FAMILY_HAS_STRATIXI_STYLE_RAM (device : in string) return boolean is variable var_family_has_stratixi_style_ram : boolean := false; begin if (IS_FAMILY_STRATIX(device) or FEATURE_FAMILY_STRATIX_HC(device) or FEATURE_FAMILY_STRATIXGX(device) or FEATURE_FAMILY_CYCLONE(device) ) then var_family_has_stratixi_style_ram := true; end if; return var_family_has_stratixi_style_ram; end FEATURE_FAMILY_HAS_STRATIXI_STYLE_RAM; function FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM (device : in string) return boolean is variable var_family_has_stratixii_style_ram : boolean := false; begin if (FEATURE_FAMILY_STRATIXII(device) or FEATURE_FAMILY_CYCLONEII(device) ) then var_family_has_stratixii_style_ram := true; end if; return var_family_has_stratixii_style_ram; end FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM; function FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM (device : in string) return boolean is variable var_family_has_stratixiii_style_ram : boolean := false; begin if (FEATURE_FAMILY_STRATIXIII(device) or FEATURE_FAMILY_CYCLONEIII(device) ) then var_family_has_stratixiii_style_ram := true; end if; return var_family_has_stratixiii_style_ram; end FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM; function FEATURE_FAMILY_HAS_STRATIX_STYLE_PLL (device : in string) return boolean is variable var_family_has_stratix_style_pll : boolean := false; begin if (FEATURE_FAMILY_CYCLONE(device) or FEATURE_FAMILY_STRATIX_HC(device) or IS_FAMILY_STRATIX(device) or FEATURE_FAMILY_STRATIXGX(device) ) then var_family_has_stratix_style_pll := true; end if; return var_family_has_stratix_style_pll; end FEATURE_FAMILY_HAS_STRATIX_STYLE_PLL; function FEATURE_FAMILY_HAS_STRATIXII_STYLE_PLL (device : in string) return boolean is variable var_family_has_stratixii_style_pll : boolean := false; begin if (( ( FEATURE_FAMILY_STRATIXII(device) and NOT FEATURE_FAMILY_STRATIXIII(device) ) or FEATURE_FAMILY_CYCLONEII(device) ) and NOT FEATURE_FAMILY_CYCLONEIII(device) ) then var_family_has_stratixii_style_pll := true; end if; return var_family_has_stratixii_style_pll; end FEATURE_FAMILY_HAS_STRATIXII_STYLE_PLL; function FEATURE_FAMILY_USES_STRATIXIII_PLL (device : in string) return boolean is variable var_family_uses_stratixiii_pll : boolean := false; begin if (FEATURE_FAMILY_STRATIXIII(device) or FEATURE_FAMILY_CYCLONEIII(device) ) then var_family_uses_stratixiii_pll := true; end if; return var_family_uses_stratixiii_pll; end FEATURE_FAMILY_USES_STRATIXIII_PLL; function FEATURE_FAMILY_HAS_FLEXIBLE_LVDS (device : in string) return boolean is variable var_family_has_flexible_lvds : boolean := false; begin if (FEATURE_FAMILY_CYCLONE(device) or FEATURE_FAMILY_CYCLONEII(device) or FEATURE_FAMILY_MAXV(device) ) then var_family_has_flexible_lvds := true; end if; return var_family_has_flexible_lvds; end FEATURE_FAMILY_HAS_FLEXIBLE_LVDS; function FEATURE_FAMILY_HAS_INVERTED_OUTPUT_DDIO (device : in string) return boolean is variable var_family_has_inverted_output_ddio : boolean := false; begin if (FEATURE_FAMILY_CYCLONEII(device) ) then var_family_has_inverted_output_ddio := true; end if; return var_family_has_inverted_output_ddio; end FEATURE_FAMILY_HAS_INVERTED_OUTPUT_DDIO; function IS_VALID_FAMILY (device : in string) return boolean is variable is_valid : boolean := false; begin if (((device = "Arria 10") or (device = "ARRIA 10") or (device = "arria 10") or (device = "Arria10") or (device = "ARRIA10") or (device = "arria10") or (device = "Arria VI") or (device = "ARRIA VI") or (device = "arria vi") or (device = "ArriaVI") or (device = "ARRIAVI") or (device = "arriavi") or (device = "Night Fury") or (device = "NIGHT FURY") or (device = "night fury") or (device = "nightfury") or (device = "NIGHTFURY") or (device = "Arria 10 (GX/SX/GT)") or (device = "ARRIA 10 (GX/SX/GT)") or (device = "arria 10 (gx/sx/gt)") or (device = "Arria10(GX/SX/GT)") or (device = "ARRIA10(GX/SX/GT)") or (device = "arria10(gx/sx/gt)") or (device = "Arria 10 (GX)") or (device = "ARRIA 10 (GX)") or (device = "arria 10 (gx)") or (device = "Arria10(GX)") or (device = "ARRIA10(GX)") or (device = "arria10(gx)") or (device = "Arria 10 (SX)") or (device = "ARRIA 10 (SX)") or (device = "arria 10 (sx)") or (device = "Arria10(SX)") or (device = "ARRIA10(SX)") or (device = "arria10(sx)") or (device = "Arria 10 (GT)") or (device = "ARRIA 10 (GT)") or (device = "arria 10 (gt)") or (device = "Arria10(GT)") or (device = "ARRIA10(GT)") or (device = "arria10(gt)")) or ((device = "Arria GX") or (device = "ARRIA GX") or (device = "arria gx") or (device = "ArriaGX") or (device = "ARRIAGX") or (device = "arriagx") or (device = "Stratix II GX Lite") or (device = "STRATIX II GX LITE") or (device = "stratix ii gx lite") or (device = "StratixIIGXLite") or (device = "STRATIXIIGXLITE") or (device = "stratixiigxlite")) or ((device = "Arria II GX") or (device = "ARRIA II GX") or (device = "arria ii gx") or (device = "ArriaIIGX") or (device = "ARRIAIIGX") or (device = "arriaiigx") or (device = "Arria IIGX") or (device = "ARRIA IIGX") or (device = "arria iigx") or (device = "ArriaII GX") or (device = "ARRIAII GX") or (device = "arriaii gx") or (device = "Arria II") or (device = "ARRIA II") or (device = "arria ii") or (device = "ArriaII") or (device = "ARRIAII") or (device = "arriaii") or (device = "Arria II (GX/E)") or (device = "ARRIA II (GX/E)") or (device = "arria ii (gx/e)") or (device = "ArriaII(GX/E)") or (device = "ARRIAII(GX/E)") or (device = "arriaii(gx/e)") or (device = "PIRANHA") or (device = "piranha")) or ((device = "Arria II GZ") or (device = "ARRIA II GZ") or (device = "arria ii gz") or (device = "ArriaII GZ") or (device = "ARRIAII GZ") or (device = "arriaii gz") or (device = "Arria IIGZ") or (device = "ARRIA IIGZ") or (device = "arria iigz") or (device = "ArriaIIGZ") or (device = "ARRIAIIGZ") or (device = "arriaiigz")) or ((device = "Arria V GZ") or (device = "ARRIA V GZ") or (device = "arria v gz") or (device = "ArriaVGZ") or (device = "ARRIAVGZ") or (device = "arriavgz")) or ((device = "Arria V") or (device = "ARRIA V") or (device = "arria v") or (device = "Arria V (GT/GX)") or (device = "ARRIA V (GT/GX)") or (device = "arria v (gt/gx)") or (device = "ArriaV(GT/GX)") or (device = "ARRIAV(GT/GX)") or (device = "arriav(gt/gx)") or (device = "ArriaV") or (device = "ARRIAV") or (device = "arriav") or (device = "Arria V (GT/GX/ST/SX)") or (device = "ARRIA V (GT/GX/ST/SX)") or (device = "arria v (gt/gx/st/sx)") or (device = "ArriaV(GT/GX/ST/SX)") or (device = "ARRIAV(GT/GX/ST/SX)") or (device = "arriav(gt/gx/st/sx)") or (device = "Arria V (GT)") or (device = "ARRIA V (GT)") or (device = "arria v (gt)") or (device = "ArriaV(GT)") or (device = "ARRIAV(GT)") or (device = "arriav(gt)") or (device = "Arria V (GX)") or (device = "ARRIA V (GX)") or (device = "arria v (gx)") or (device = "ArriaV(GX)") or (device = "ARRIAV(GX)") or (device = "arriav(gx)") or (device = "Arria V (ST)") or (device = "ARRIA V (ST)") or (device = "arria v (st)") or (device = "ArriaV(ST)") or (device = "ARRIAV(ST)") or (device = "arriav(st)") or (device = "Arria V (SX)") or (device = "ARRIA V (SX)") or (device = "arria v (sx)") or (device = "ArriaV(SX)") or (device = "ARRIAV(SX)") or (device = "arriav(sx)")) or ((device = "BS") or (device = "bs")) or ((device = "Cyclone II") or (device = "CYCLONE II") or (device = "cyclone ii") or (device = "Cycloneii") or (device = "CYCLONEII") or (device = "cycloneii") or (device = "Magellan") or (device = "MAGELLAN") or (device = "magellan") or (device = "CycloneII") or (device = "CYCLONEII") or (device = "cycloneii")) or ((device = "Cyclone III LS") or (device = "CYCLONE III LS") or (device = "cyclone iii ls") or (device = "CycloneIIILS") or (device = "CYCLONEIIILS") or (device = "cycloneiiils") or (device = "Cyclone III LPS") or (device = "CYCLONE III LPS") or (device = "cyclone iii lps") or (device = "Cyclone LPS") or (device = "CYCLONE LPS") or (device = "cyclone lps") or (device = "CycloneLPS") or (device = "CYCLONELPS") or (device = "cyclonelps") or (device = "Tarpon") or (device = "TARPON") or (device = "tarpon") or (device = "Cyclone IIIE") or (device = "CYCLONE IIIE") or (device = "cyclone iiie")) or ((device = "Cyclone III") or (device = "CYCLONE III") or (device = "cyclone iii") or (device = "CycloneIII") or (device = "CYCLONEIII") or (device = "cycloneiii") or (device = "Barracuda") or (device = "BARRACUDA") or (device = "barracuda") or (device = "Cuda") or (device = "CUDA") or (device = "cuda") or (device = "CIII") or (device = "ciii")) or ((device = "Cyclone IV E") or (device = "CYCLONE IV E") or (device = "cyclone iv e") or (device = "CycloneIV E") or (device = "CYCLONEIV E") or (device = "cycloneiv e") or (device = "Cyclone IVE") or (device = "CYCLONE IVE") or (device = "cyclone ive") or (device = "CycloneIVE") or (device = "CYCLONEIVE") or (device = "cycloneive")) or ((device = "Cyclone IV GX") or (device = "CYCLONE IV GX") or (device = "cyclone iv gx") or (device = "Cyclone IVGX") or (device = "CYCLONE IVGX") or (device = "cyclone ivgx") or (device = "CycloneIV GX") or (device = "CYCLONEIV GX") or (device = "cycloneiv gx") or (device = "CycloneIVGX") or (device = "CYCLONEIVGX") or (device = "cycloneivgx") or (device = "Cyclone IV") or (device = "CYCLONE IV") or (device = "cyclone iv") or (device = "CycloneIV") or (device = "CYCLONEIV") or (device = "cycloneiv") or (device = "Cyclone IV (GX)") or (device = "CYCLONE IV (GX)") or (device = "cyclone iv (gx)") or (device = "CycloneIV(GX)") or (device = "CYCLONEIV(GX)") or (device = "cycloneiv(gx)") or (device = "Cyclone III GX") or (device = "CYCLONE III GX") or (device = "cyclone iii gx") or (device = "CycloneIII GX") or (device = "CYCLONEIII GX") or (device = "cycloneiii gx") or (device = "Cyclone IIIGX") or (device = "CYCLONE IIIGX") or (device = "cyclone iiigx") or (device = "CycloneIIIGX") or (device = "CYCLONEIIIGX") or (device = "cycloneiiigx") or (device = "Cyclone III GL") or (device = "CYCLONE III GL") or (device = "cyclone iii gl") or (device = "CycloneIII GL") or (device = "CYCLONEIII GL") or (device = "cycloneiii gl") or (device = "Cyclone IIIGL") or (device = "CYCLONE IIIGL") or (device = "cyclone iiigl") or (device = "CycloneIIIGL") or (device = "CYCLONEIIIGL") or (device = "cycloneiiigl") or (device = "Stingray") or (device = "STINGRAY") or (device = "stingray")) or ((device = "Cyclone V") or (device = "CYCLONE V") or (device = "cyclone v") or (device = "CycloneV") or (device = "CYCLONEV") or (device = "cyclonev") or (device = "Cyclone V (GT/GX/E/SX)") or (device = "CYCLONE V (GT/GX/E/SX)") or (device = "cyclone v (gt/gx/e/sx)") or (device = "CycloneV(GT/GX/E/SX)") or (device = "CYCLONEV(GT/GX/E/SX)") or (device = "cyclonev(gt/gx/e/sx)") or (device = "Cyclone V (E/GX/GT/SX/SE/ST)") or (device = "CYCLONE V (E/GX/GT/SX/SE/ST)") or (device = "cyclone v (e/gx/gt/sx/se/st)") or (device = "CycloneV(E/GX/GT/SX/SE/ST)") or (device = "CYCLONEV(E/GX/GT/SX/SE/ST)") or (device = "cyclonev(e/gx/gt/sx/se/st)") or (device = "Cyclone V (E)") or (device = "CYCLONE V (E)") or (device = "cyclone v (e)") or (device = "CycloneV(E)") or (device = "CYCLONEV(E)") or (device = "cyclonev(e)") or (device = "Cyclone V (GX)") or (device = "CYCLONE V (GX)") or (device = "cyclone v (gx)") or (device = "CycloneV(GX)") or (device = "CYCLONEV(GX)") or (device = "cyclonev(gx)") or (device = "Cyclone V (GT)") or (device = "CYCLONE V (GT)") or (device = "cyclone v (gt)") or (device = "CycloneV(GT)") or (device = "CYCLONEV(GT)") or (device = "cyclonev(gt)") or (device = "Cyclone V (SX)") or (device = "CYCLONE V (SX)") or (device = "cyclone v (sx)") or (device = "CycloneV(SX)") or (device = "CYCLONEV(SX)") or (device = "cyclonev(sx)") or (device = "Cyclone V (SE)") or (device = "CYCLONE V (SE)") or (device = "cyclone v (se)") or (device = "CycloneV(SE)") or (device = "CYCLONEV(SE)") or (device = "cyclonev(se)") or (device = "Cyclone V (ST)") or (device = "CYCLONE V (ST)") or (device = "cyclone v (st)") or (device = "CycloneV(ST)") or (device = "CYCLONEV(ST)") or (device = "cyclonev(st)")) or ((device = "Cyclone") or (device = "CYCLONE") or (device = "cyclone") or (device = "ACEX2K") or (device = "acex2k") or (device = "ACEX 2K") or (device = "acex 2k") or (device = "Tornado") or (device = "TORNADO") or (device = "tornado")) or ((device = "HardCopy II") or (device = "HARDCOPY II") or (device = "hardcopy ii") or (device = "HardCopyII") or (device = "HARDCOPYII") or (device = "hardcopyii") or (device = "Fusion") or (device = "FUSION") or (device = "fusion")) or ((device = "HardCopy III") or (device = "HARDCOPY III") or (device = "hardcopy iii") or (device = "HardCopyIII") or (device = "HARDCOPYIII") or (device = "hardcopyiii") or (device = "HCX") or (device = "hcx")) or ((device = "HardCopy IV") or (device = "HARDCOPY IV") or (device = "hardcopy iv") or (device = "HardCopyIV") or (device = "HARDCOPYIV") or (device = "hardcopyiv") or (device = "HardCopy IV (GX)") or (device = "HARDCOPY IV (GX)") or (device = "hardcopy iv (gx)") or (device = "HardCopy IV (E)") or (device = "HARDCOPY IV (E)") or (device = "hardcopy iv (e)") or (device = "HardCopyIV(GX)") or (device = "HARDCOPYIV(GX)") or (device = "hardcopyiv(gx)") or (device = "HardCopyIV(E)") or (device = "HARDCOPYIV(E)") or (device = "hardcopyiv(e)") or (device = "HCXIV") or (device = "hcxiv") or (device = "HardCopy IV (GX/E)") or (device = "HARDCOPY IV (GX/E)") or (device = "hardcopy iv (gx/e)") or (device = "HardCopy IV (E/GX)") or (device = "HARDCOPY IV (E/GX)") or (device = "hardcopy iv (e/gx)") or (device = "HardCopyIV(GX/E)") or (device = "HARDCOPYIV(GX/E)") or (device = "hardcopyiv(gx/e)") or (device = "HardCopyIV(E/GX)") or (device = "HARDCOPYIV(E/GX)") or (device = "hardcopyiv(e/gx)")) or ((device = "MAX 10") or (device = "max 10") or (device = "MAX 10 FPGA") or (device = "max 10 fpga") or (device = "Zippleback") or (device = "ZIPPLEBACK") or (device = "zippleback") or (device = "MAX10") or (device = "max10") or (device = "MAX 10 (DA/DF/DC/SA/SF/SC)") or (device = "max 10 (da/df/dc/sa/sf/sc)") or (device = "MAX10(DA/DF/DC/SA/SF/SC)") or (device = "max10(da/df/dc/sa/sf/sc)") or (device = "MAX 10 (DA)") or (device = "max 10 (da)") or (device = "MAX10(DA)") or (device = "max10(da)") or (device = "MAX 10 (DF)") or (device = "max 10 (df)") or (device = "MAX10(DF)") or (device = "max10(df)") or (device = "MAX 10 (DC)") or (device = "max 10 (dc)") or (device = "MAX10(DC)") or (device = "max10(dc)") or (device = "MAX 10 (SA)") or (device = "max 10 (sa)") or (device = "MAX10(SA)") or (device = "max10(sa)") or (device = "MAX 10 (SF)") or (device = "max 10 (sf)") or (device = "MAX10(SF)") or (device = "max10(sf)") or (device = "MAX 10 (SC)") or (device = "max 10 (sc)") or (device = "MAX10(SC)") or (device = "max10(sc)")) or ((device = "MAX II") or (device = "max ii") or (device = "MAXII") or (device = "maxii") or (device = "Tsunami") or (device = "TSUNAMI") or (device = "tsunami")) or ((device = "MAX V") or (device = "max v") or (device = "MAXV") or (device = "maxv") or (device = "Jade") or (device = "JADE") or (device = "jade")) or ((device = "MAX3000A") or (device = "max3000a") or (device = "MAX 3000A") or (device = "max 3000a")) or ((device = "MAX7000A") or (device = "max7000a") or (device = "MAX 7000A") or (device = "max 7000a")) or ((device = "MAX7000AE") or (device = "max7000ae") or (device = "MAX 7000AE") or (device = "max 7000ae")) or ((device = "MAX7000B") or (device = "max7000b") or (device = "MAX 7000B") or (device = "max 7000b")) or ((device = "MAX7000S") or (device = "max7000s") or (device = "MAX 7000S") or (device = "max 7000s")) or ((device = "Stratix 10") or (device = "STRATIX 10") or (device = "stratix 10") or (device = "Stratix10") or (device = "STRATIX10") or (device = "stratix10") or (device = "nadder") or (device = "NADDER")) or ((device = "Stratix GX") or (device = "STRATIX GX") or (device = "stratix gx") or (device = "Stratix-GX") or (device = "STRATIX-GX") or (device = "stratix-gx") or (device = "StratixGX") or (device = "STRATIXGX") or (device = "stratixgx") or (device = "Aurora") or (device = "AURORA") or (device = "aurora")) or ((device = "Stratix II GX") or (device = "STRATIX II GX") or (device = "stratix ii gx") or (device = "StratixIIGX") or (device = "STRATIXIIGX") or (device = "stratixiigx")) or ((device = "Stratix II") or (device = "STRATIX II") or (device = "stratix ii") or (device = "StratixII") or (device = "STRATIXII") or (device = "stratixii") or (device = "Armstrong") or (device = "ARMSTRONG") or (device = "armstrong")) or ((device = "Stratix III") or (device = "STRATIX III") or (device = "stratix iii") or (device = "StratixIII") or (device = "STRATIXIII") or (device = "stratixiii") or (device = "Titan") or (device = "TITAN") or (device = "titan") or (device = "SIII") or (device = "siii")) or ((device = "Stratix IV") or (device = "STRATIX IV") or (device = "stratix iv") or (device = "TGX") or (device = "tgx") or (device = "StratixIV") or (device = "STRATIXIV") or (device = "stratixiv") or (device = "Stratix IV (GT)") or (device = "STRATIX IV (GT)") or (device = "stratix iv (gt)") or (device = "Stratix IV (GX)") or (device = "STRATIX IV (GX)") or (device = "stratix iv (gx)") or (device = "Stratix IV (E)") or (device = "STRATIX IV (E)") or (device = "stratix iv (e)") or (device = "StratixIV(GT)") or (device = "STRATIXIV(GT)") or (device = "stratixiv(gt)") or (device = "StratixIV(GX)") or (device = "STRATIXIV(GX)") or (device = "stratixiv(gx)") or (device = "StratixIV(E)") or (device = "STRATIXIV(E)") or (device = "stratixiv(e)") or (device = "StratixIIIGX") or (device = "STRATIXIIIGX") or (device = "stratixiiigx") or (device = "Stratix IV (GT/GX/E)") or (device = "STRATIX IV (GT/GX/E)") or (device = "stratix iv (gt/gx/e)") or (device = "Stratix IV (GT/E/GX)") or (device = "STRATIX IV (GT/E/GX)") or (device = "stratix iv (gt/e/gx)") or (device = "Stratix IV (E/GT/GX)") or (device = "STRATIX IV (E/GT/GX)") or (device = "stratix iv (e/gt/gx)") or (device = "Stratix IV (E/GX/GT)") or (device = "STRATIX IV (E/GX/GT)") or (device = "stratix iv (e/gx/gt)") or (device = "StratixIV(GT/GX/E)") or (device = "STRATIXIV(GT/GX/E)") or (device = "stratixiv(gt/gx/e)") or (device = "StratixIV(GT/E/GX)") or (device = "STRATIXIV(GT/E/GX)") or (device = "stratixiv(gt/e/gx)") or (device = "StratixIV(E/GX/GT)") or (device = "STRATIXIV(E/GX/GT)") or (device = "stratixiv(e/gx/gt)") or (device = "StratixIV(E/GT/GX)") or (device = "STRATIXIV(E/GT/GX)") or (device = "stratixiv(e/gt/gx)") or (device = "Stratix IV (GX/E)") or (device = "STRATIX IV (GX/E)") or (device = "stratix iv (gx/e)") or (device = "StratixIV(GX/E)") or (device = "STRATIXIV(GX/E)") or (device = "stratixiv(gx/e)")) or ((device = "Stratix V") or (device = "STRATIX V") or (device = "stratix v") or (device = "StratixV") or (device = "STRATIXV") or (device = "stratixv") or (device = "Stratix V (GS)") or (device = "STRATIX V (GS)") or (device = "stratix v (gs)") or (device = "StratixV(GS)") or (device = "STRATIXV(GS)") or (device = "stratixv(gs)") or (device = "Stratix V (GT)") or (device = "STRATIX V (GT)") or (device = "stratix v (gt)") or (device = "StratixV(GT)") or (device = "STRATIXV(GT)") or (device = "stratixv(gt)") or (device = "Stratix V (GX)") or (device = "STRATIX V (GX)") or (device = "stratix v (gx)") or (device = "StratixV(GX)") or (device = "STRATIXV(GX)") or (device = "stratixv(gx)") or (device = "Stratix V (GS/GX)") or (device = "STRATIX V (GS/GX)") or (device = "stratix v (gs/gx)") or (device = "StratixV(GS/GX)") or (device = "STRATIXV(GS/GX)") or (device = "stratixv(gs/gx)") or (device = "Stratix V (GS/GT)") or (device = "STRATIX V (GS/GT)") or (device = "stratix v (gs/gt)") or (device = "StratixV(GS/GT)") or (device = "STRATIXV(GS/GT)") or (device = "stratixv(gs/gt)") or (device = "Stratix V (GT/GX)") or (device = "STRATIX V (GT/GX)") or (device = "stratix v (gt/gx)") or (device = "StratixV(GT/GX)") or (device = "STRATIXV(GT/GX)") or (device = "stratixv(gt/gx)") or (device = "Stratix V (GX/GS)") or (device = "STRATIX V (GX/GS)") or (device = "stratix v (gx/gs)") or (device = "StratixV(GX/GS)") or (device = "STRATIXV(GX/GS)") or (device = "stratixv(gx/gs)") or (device = "Stratix V (GT/GS)") or (device = "STRATIX V (GT/GS)") or (device = "stratix v (gt/gs)") or (device = "StratixV(GT/GS)") or (device = "STRATIXV(GT/GS)") or (device = "stratixv(gt/gs)") or (device = "Stratix V (GX/GT)") or (device = "STRATIX V (GX/GT)") or (device = "stratix v (gx/gt)") or (device = "StratixV(GX/GT)") or (device = "STRATIXV(GX/GT)") or (device = "stratixv(gx/gt)") or (device = "Stratix V (GS/GT/GX)") or (device = "STRATIX V (GS/GT/GX)") or (device = "stratix v (gs/gt/gx)") or (device = "Stratix V (GS/GX/GT)") or (device = "STRATIX V (GS/GX/GT)") or (device = "stratix v (gs/gx/gt)") or (device = "Stratix V (GT/GS/GX)") or (device = "STRATIX V (GT/GS/GX)") or (device = "stratix v (gt/gs/gx)") or (device = "Stratix V (GT/GX/GS)") or (device = "STRATIX V (GT/GX/GS)") or (device = "stratix v (gt/gx/gs)") or (device = "Stratix V (GX/GS/GT)") or (device = "STRATIX V (GX/GS/GT)") or (device = "stratix v (gx/gs/gt)") or (device = "Stratix V (GX/GT/GS)") or (device = "STRATIX V (GX/GT/GS)") or (device = "stratix v (gx/gt/gs)") or (device = "StratixV(GS/GT/GX)") or (device = "STRATIXV(GS/GT/GX)") or (device = "stratixv(gs/gt/gx)") or (device = "StratixV(GS/GX/GT)") or (device = "STRATIXV(GS/GX/GT)") or (device = "stratixv(gs/gx/gt)") or (device = "StratixV(GT/GS/GX)") or (device = "STRATIXV(GT/GS/GX)") or (device = "stratixv(gt/gs/gx)") or (device = "StratixV(GT/GX/GS)") or (device = "STRATIXV(GT/GX/GS)") or (device = "stratixv(gt/gx/gs)") or (device = "StratixV(GX/GS/GT)") or (device = "STRATIXV(GX/GS/GT)") or (device = "stratixv(gx/gs/gt)") or (device = "StratixV(GX/GT/GS)") or (device = "STRATIXV(GX/GT/GS)") or (device = "stratixv(gx/gt/gs)") or (device = "Stratix V (GS/GT/GX/E)") or (device = "STRATIX V (GS/GT/GX/E)") or (device = "stratix v (gs/gt/gx/e)") or (device = "StratixV(GS/GT/GX/E)") or (device = "STRATIXV(GS/GT/GX/E)") or (device = "stratixv(gs/gt/gx/e)") or (device = "Stratix V (E)") or (device = "STRATIX V (E)") or (device = "stratix v (e)") or (device = "StratixV(E)") or (device = "STRATIXV(E)") or (device = "stratixv(e)")) or ((device = "Stratix") or (device = "STRATIX") or (device = "stratix") or (device = "Yeager") or (device = "YEAGER") or (device = "yeager")) or ((device = "eFPGA 28 HPM") or (device = "EFPGA 28 HPM") or (device = "efpga 28 hpm") or (device = "eFPGA28HPM") or (device = "EFPGA28HPM") or (device = "efpga28hpm") or (device = "Bedrock") or (device = "BEDROCK") or (device = "bedrock"))) then is_valid := true; end if; return is_valid; end IS_VALID_FAMILY; end ALTERA_DEVICE_FAMILIES; -- END OF PACKAGE Library ieee; use ieee.std_logic_1164.all; -- START PACKAGE HEADER -------------------------------------------------------- -- -- Package Name : MF_pllpack -- -- Description : Used by altpll model to calculate required advanced parameters -- for PLL simulation. Also has functions to do string->integer, -- integer->string conversions. -- -- END PACKAGE HEADER ---------------------------------------------------------- -- PACKAGE DECLARATION package MF_pllpack is -- FUNCTION DECLARATION function int2str (value : integer) return string; function alt_conv_integer(arg : in std_logic_vector) return integer; 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; end MF_pllpack; -- BEGINNING OF PACKAGE package body MF_pllpack is -- convert integer to string function int2str( value : integer ) return string is variable 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; 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; -- 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; end MF_pllpack; -- END OF PACKAGE MF_pllpack library ieee; use ieee.std_logic_1164.all; -- DFFP entity DFFP 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 := '0' ); end DFFP; architecture behave of DFFP is begin process (clk, prn, clrn) begin if (prn = '0') then q <= '1'; elsif (clrn = '0') then q <= '0'; else if (ena = '1') then q <= d; end if; end if; end process; end behave; Library ieee; use ieee.std_logic_1164.all; entity pll_iobuf is port( i : in std_logic; oe : in std_logic; io : inout std_logic; o : out std_logic); end pll_iobuf; architecture BEHAVIOR of pll_iobuf is begin process(i, io, oe) begin if oe = '1' then io <= i; else io <= 'Z'; end if; o <= io; end process; end BEHAVIOR; --/////////////////////////////////////////////////////////////////////////// -- -- Entity Name : MF_m_cntr -- -- Description : Simulation model for the M counter. This is a -- model for the loop feedback counter of the Stratix PLL. -- --/////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; ENTITY MF_m_cntr is PORT ( clk : IN std_logic; reset : IN std_logic; cout : OUT std_logic; initial_value : IN integer; modulus : IN integer; time_delay : IN integer; ph : IN integer := 0); END MF_m_cntr; ARCHITECTURE behave of MF_m_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 : MF_n_cntr -- -- Description : Simulation model for the N counter. This is a -- model for the input counter of the Stratix PLL. -- --/////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; ENTITY MF_n_cntr is PORT ( clk : IN std_logic; reset : IN std_logic; cout : OUT std_logic; modulus : IN integer; time_delay : IN integer); END MF_n_cntr; ARCHITECTURE behave of MF_n_cntr is begin process (clk, reset) variable count : integer := 1; variable first_rising_edge : boolean := true; variable tmp_cout : std_logic; variable clk_last_valid_value : std_logic; begin if (reset = '1') then count := 1; tmp_cout := '0'; first_rising_edge := true; elsif (clk'event) then if (clk = 'X') then ASSERT FALSE REPORT "Invalid transition to 'X' detected on Stratix PLL input clk. This edge will be ignored" severity warning; elsif (clk = '1' and first_rising_edge) then first_rising_edge := false; tmp_cout := clk; elsif (not first_rising_edge and (clk_last_valid_value /= clk)) then if (count < modulus) then count := count + 1; else count := 1; tmp_cout := not tmp_cout; end if; end if; end if; if (clk /= 'X') then clk_last_valid_value := clk; end if; cout <= transport tmp_cout after time_delay * 1 ps; end process; end behave; --///////////////////////////////////////////////////////////////////////////// -- -- Entity Name : stx_scale_cntr -- -- Description : Simulation model for the output scale-down counters. -- This is a common model for the L0, L1, G0, G1, G2, G3, E0, -- E1, E2 and E3 output counters of the Stratix PLL. -- --///////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; ENTITY stx_scale_cntr is PORT ( clk : IN std_logic; reset : IN std_logic; initial : IN integer; high : IN integer; low : IN integer; mode : IN string := "bypass"; time_delay : IN integer; ph_tap : IN natural; cout : OUT std_logic); END stx_scale_cntr; ARCHITECTURE behave of stx_scale_cntr is begin process (clk, reset) variable tmp_cout : std_logic := '0'; variable count : integer := 1; variable output_shift_count : integer := 0; variable first_rising_edge : boolean := false; variable high_reg : integer := 0; variable low_reg : integer := 0; variable init : boolean := true; variable high_cnt_xfer_done : boolean := false; begin if (reset = '1') then count := 1; output_shift_count := 0; tmp_cout := '0'; first_rising_edge := false; elsif (clk'event) then if (init) then init := false; high_reg := high; low_reg := low; end if; if (mode = " off") then tmp_cout := '0'; elsif (mode = "bypass") then tmp_cout := clk; elsif (not first_rising_edge) then if (clk = '1') then output_shift_count := output_shift_count + 1; if (output_shift_count = initial) then tmp_cout := clk; first_rising_edge := true; 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_reg*2) + 1)) then tmp_cout := '0'; if (high_cnt_xfer_done) then low_reg := low; high_cnt_xfer_done := false; end if; elsif (mode = " odd" and (count = high_reg*2)) then tmp_cout := '0'; if (high_cnt_xfer_done) then low_reg := low; high_cnt_xfer_done := false; end if; elsif (count = (high_reg + low_reg)*2 + 1) then tmp_cout := '1'; count := 1; -- reset count if (high_reg /= high) then high_cnt_xfer_done := true; high_reg := high; end if; end if; end if; end if; cout <= transport tmp_cout after time_delay * 1 ps; end process; end behave; --///////////////////////////////////////////////////////////////////////////// -- -- Entity Name : MF_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 MF_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 MF_pll_reg; ARCHITECTURE behave of MF_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 : MF_stratix_pll -- -- Description : The behavioral model for Stratix PLL -- -- Limitations : Applies to the Stratix and Stratix GX device families -- No support for spread spectrum feature in the model -- -- Outputs : Up to 10 output clocks, each defined by its own set of -- parameters. Locked output (active high) indicates when the -- PLL locks. clkbad, clkloss 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; USE IEEE.std_logic_1164.all; USE STD.TEXTIO.all; USE work.MF_pllpack.all; USE work.MF_m_cntr; USE work.MF_n_cntr; USE work.stx_scale_cntr; USE work.dffp; USE work.MF_pll_reg; ENTITY MF_stratix_pll is GENERIC ( operation_mode : string := "normal"; qualify_conf_done : string := "off"; compensate_clock : string := "clk0"; pll_type : string := "auto"; -- EGPP/FAST/AUTO scan_chain : string := "long"; clk0_multiply_by : integer := 1; clk0_divide_by : integer := 1; clk0_phase_shift : string := "0"; clk0_time_delay : string := "0"; clk0_duty_cycle : integer := 50; clk1_multiply_by : integer := 1; clk1_divide_by : integer := 1; clk1_phase_shift : string := "0"; clk1_time_delay : string := "0"; clk1_duty_cycle : integer := 50; clk2_multiply_by : integer := 1; clk2_divide_by : integer := 1; clk2_phase_shift : string := "0"; clk2_time_delay : string := "0"; clk2_duty_cycle : integer := 50; clk3_multiply_by : integer := 1; clk3_divide_by : integer := 1; clk3_phase_shift : string := "0"; clk3_time_delay : string := "0"; clk3_duty_cycle : integer := 50; clk4_multiply_by : integer := 1; clk4_divide_by : integer := 1; clk4_phase_shift : string := "0"; clk4_time_delay : string := "0"; clk4_duty_cycle : integer := 50; clk5_multiply_by : integer := 1; clk5_divide_by : integer := 1; clk5_phase_shift : string := "0"; clk5_time_delay : string := "0"; clk5_duty_cycle : integer := 50; extclk0_multiply_by : integer := 1; extclk0_divide_by : integer := 1; extclk0_phase_shift : string := "0"; extclk0_time_delay : string := "0"; extclk0_duty_cycle : integer := 50; extclk1_multiply_by : integer := 1; extclk1_divide_by : integer := 1; extclk1_phase_shift : string := "0"; extclk1_time_delay : string := "0"; extclk1_duty_cycle : integer := 50; extclk2_multiply_by : integer := 1; extclk2_divide_by : integer := 1; extclk2_phase_shift : string := "0"; extclk2_time_delay : string := "0"; extclk2_duty_cycle : integer := 50; extclk3_multiply_by : integer := 1; extclk3_divide_by : integer := 1; extclk3_phase_shift : string := "0"; extclk3_time_delay : string := "0"; extclk3_duty_cycle : integer := 50; primary_clock : string := "inclk0"; inclk0_input_frequency : integer := 10000; inclk1_input_frequency : integer := 10000; gate_lock_signal : string := "no"; gate_lock_counter : integer := 1; valid_lock_multiplier : integer := 5; invalid_lock_multiplier : integer := 5; switch_over_on_lossclk : string := "off"; switch_over_on_gated_lock : string := "off"; switch_over_counter : integer := 1; enable_switch_over_counter : string := "off"; feedback_source : string := "extclk0"; bandwidth_type : string := "auto"; bandwidth : integer := 0; spread_frequency : integer := 0; down_spread : string := "0.0"; 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; m2 : integer := 1; n2 : integer := 1; ss : integer := 0; l0_high : integer := 1; l0_low : integer := 1; l0_initial : integer := 1; l0_mode : string := "bypass"; l0_ph : integer := 0; l0_time_delay : integer := 0; l1_high : integer := 1; l1_low : integer := 1; l1_initial : integer := 1; l1_mode : string := "bypass"; l1_ph : integer := 0; l1_time_delay : integer := 0; g0_high : integer := 1; g0_low : integer := 1; g0_initial : integer := 1; g0_mode : string := "bypass"; g0_ph : integer := 0; g0_time_delay : integer := 0; g1_high : integer := 1; g1_low : integer := 1; g1_initial : integer := 1; g1_mode : string := "bypass"; g1_ph : integer := 0; g1_time_delay : integer := 0; g2_high : integer := 1; g2_low : integer := 1; g2_initial : integer := 1; g2_mode : string := "bypass"; g2_ph : integer := 0; g2_time_delay : integer := 0; g3_high : integer := 1; g3_low : integer := 1; g3_initial : integer := 1; g3_mode : string := "bypass"; g3_ph : integer := 0; g3_time_delay : integer := 0; e0_high : integer := 1; e0_low : integer := 1; e0_initial : integer := 1; e0_mode : string := "bypass"; e0_ph : integer := 0; e0_time_delay : integer := 0; e1_high : integer := 1; e1_low : integer := 1; e1_initial : integer := 1; e1_mode : string := "bypass"; e1_ph : integer := 0; e1_time_delay : integer := 0; e2_high : integer := 1; e2_low : integer := 1; e2_initial : integer := 1; e2_mode : string := "bypass"; e2_ph : integer := 0; e2_time_delay : integer := 0; e3_high : integer := 1; e3_low : integer := 1; e3_initial : integer := 1; e3_mode : string := "bypass"; e3_ph : integer := 0; e3_time_delay : integer := 0; m_ph : integer := 0; m_time_delay : integer := 0; n_time_delay : integer := 0; extclk0_counter : string := "e0"; extclk1_counter : string := "e1"; extclk2_counter : string := "e2"; extclk3_counter : string := "e3"; clk0_counter : string := "g0"; clk1_counter : string := "g1"; clk2_counter : string := "g2"; clk3_counter : string := "g3"; clk4_counter : string := "l0"; clk5_counter : string := "l1"; -- LVDS mode parameters enable0_counter : string := "l0"; enable1_counter : string := "l0"; charge_pump_current : integer := 0; loop_filter_r : string := "1.0"; loop_filter_c : integer := 1; common_rx_tx : string := "off"; rx_outclock_resource : string := "auto"; use_vco_bypass : string := "false"; use_dc_coupling : string := "false"; pll_compensation_delay : integer := 0; simulation_type : string := "timing"; 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"; clk5_use_even_counter_mode : string := "off"; extclk0_use_even_counter_mode : string := "off"; extclk1_use_even_counter_mode : string := "off"; extclk2_use_even_counter_mode : string := "off"; extclk3_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"; clk5_use_even_counter_value : string := "off"; extclk0_use_even_counter_value : string := "off"; extclk1_use_even_counter_value : string := "off"; extclk2_use_even_counter_value : string := "off"; extclk3_use_even_counter_value : string := "off"; scan_chain_mif_file : string := ""; -- Simulation only generics family_name : string := "Stratix"; skip_vco : string := "off" ); PORT ( inclk : in std_logic_vector(1 downto 0); fbin : in std_logic := '0'; ena : in std_logic := '1'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; clkena : in std_logic_vector(5 downto 0) := "111111"; extclkena : in std_logic_vector(3 downto 0) := "1111"; scanaclr : in std_logic := '0'; scandata : in std_logic := '0'; scanclk : in std_logic := '0'; clk : out std_logic_vector(5 downto 0); extclk : out std_logic_vector(3 downto 0); clkbad : out std_logic_vector(1 downto 0); activeclock : out std_logic; locked : out std_logic; clkloss : out std_logic; scandataout : out std_logic; -- lvds specific ports comparator : in std_logic := '0'; enable0 : out std_logic; enable1 : out std_logic ); END MF_stratix_pll; ARCHITECTURE vital_pll of MF_stratix_pll is -- internal advanced parameter signals signal i_vco_min : natural; signal i_vco_max : natural; signal i_vco_center : natural; signal i_pfd_min : natural; signal i_pfd_max : natural; signal l0_ph_val : natural; signal l1_ph_val : natural; signal g0_ph_val : natural; signal g1_ph_val : natural; signal g2_ph_val : natural; signal g3_ph_val : natural; signal e0_ph_val : natural; signal e1_ph_val : natural; signal e2_ph_val : natural; signal e3_ph_val : natural; signal i_extclk3_counter : string(1 to 2) := "e3"; signal i_extclk2_counter : string(1 to 2) := "e2"; signal i_extclk1_counter : string(1 to 2) := "e1"; signal i_extclk0_counter : string(1 to 2) := "e0"; signal i_clk5_counter : string(1 to 2) := "l1"; signal i_clk4_counter : string(1 to 2) := "l0"; signal i_clk3_counter : string(1 to 2) := "g3"; signal i_clk2_counter : string(1 to 2) := "g2"; signal i_clk1_counter : string(1 to 2) := "g1"; signal i_clk0_counter : string(1 to 2) := "g0"; signal i_charge_pump_current : natural; signal i_loop_filter_r : natural; -- end internal advanced parameter signals -- CONSTANTS CONSTANT EGPP_SCAN_CHAIN : integer := 289; CONSTANT GPP_SCAN_CHAIN : integer := 193; CONSTANT TRST : time := 5000 ps; CONSTANT TRSTCLK : time := 5000 ps; -- signals signal vcc : std_logic := '1'; signal fbclk : std_logic; signal refclk : std_logic; signal l0_clk : std_logic; signal l1_clk : std_logic; signal g0_clk : std_logic; signal g1_clk : std_logic; signal g2_clk : std_logic; signal g3_clk : std_logic; signal e0_clk : std_logic; signal e1_clk : std_logic; signal e2_clk : std_logic; signal e3_clk : std_logic; signal vco_out : std_logic_vector(7 downto 0) := (OTHERS => '0'); -- signals to assign values to counter params signal m_val : integer := 1; signal m_val_tmp : integer := 1; signal m2_val : integer := 1; signal n_val : integer := 1; signal n_val_tmp : integer := 1; signal n2_val : integer := 1; signal m_time_delay_val, n_time_delay_val : integer := 0; signal m_ph_val : integer := 0; signal m_initial_val : integer := m_initial; signal l0_initial_val : integer := l0_initial; signal l1_initial_val : integer := l1_initial; signal l0_high_val : integer := l0_high; signal l1_high_val : integer := l1_high; signal l0_low_val : integer := l0_low; signal l1_low_val : integer := l1_low; signal l0_mode_val : string(1 to 6) := "bypass"; signal l1_mode_val : string(1 to 6) := "bypass"; signal l0_time_delay_val : integer := l0_time_delay; signal l1_time_delay_val : integer := l1_time_delay; signal g0_initial_val : integer := g0_initial; signal g1_initial_val : integer := g1_initial; signal g2_initial_val : integer := g2_initial; signal g3_initial_val : integer := g3_initial; signal g0_high_val : integer := g0_high; signal g1_high_val : integer := g1_high; signal g2_high_val : integer := g2_high; signal g3_high_val : integer := g3_high; signal g0_mode_val : string(1 to 6) := "bypass"; signal g1_mode_val : string(1 to 6) := "bypass"; signal g2_mode_val : string(1 to 6) := "bypass"; signal g3_mode_val : string(1 to 6) := "bypass"; signal g0_low_val : integer := g0_low; signal g1_low_val : integer := g1_low; signal g2_low_val : integer := g2_low; signal g3_low_val : integer := g3_low; signal g0_time_delay_val : integer := g0_time_delay; signal g1_time_delay_val : integer := g1_time_delay; signal g2_time_delay_val : integer := g2_time_delay; signal g3_time_delay_val : integer := g3_time_delay; signal e0_initial_val : integer := e0_initial; signal e1_initial_val : integer := e1_initial; signal e2_initial_val : integer := e2_initial; signal e3_initial_val : integer := e3_initial; signal e0_high_val : integer := e0_high; signal e1_high_val : integer := e1_high; signal e2_high_val : integer := e2_high; signal e3_high_val : integer := e3_high; signal e0_low_val : integer := e0_low; signal e1_low_val : integer := e1_low; signal e2_low_val : integer := e2_low; signal e3_low_val : integer := e3_low; signal e0_time_delay_val : integer := e0_time_delay; signal e1_time_delay_val : integer := e1_time_delay; signal e2_time_delay_val : integer := e2_time_delay; signal e3_time_delay_val : integer := e3_time_delay; signal e0_mode_val : string(1 to 6) := "bypass"; signal e1_mode_val : string(1 to 6) := "bypass"; signal e2_mode_val : string(1 to 6) := "bypass"; signal e3_mode_val : string(1 to 6) := "bypass"; signal m_mode_val : string(1 to 6) := " "; signal m2_mode_val : string(1 to 6) := " "; signal n_mode_val : string(1 to 6) := " "; signal n2_mode_val : string(1 to 6) := " "; signal cntr_e0_initial : integer := 1; signal cntr_e1_initial : integer := 1; signal cntr_e2_initial : integer := 1; signal cntr_e3_initial : integer := 1; signal ext_fbk_delay : integer := 0; signal cntr_e0_delay : integer := 0; signal cntr_e1_delay : integer := 0; signal cntr_e2_delay : integer := 0; signal cntr_e3_delay : integer := 0; signal transfer : std_logic := '0'; signal scan_data : std_logic_vector(288 downto 0) := (OTHERS => '0'); signal ena0 : std_logic; signal ena1 : std_logic; signal ena2 : std_logic; signal ena3 : std_logic; signal ena4 : std_logic; signal ena5 : std_logic; signal extena0 : std_logic; signal extena1 : std_logic; signal extena2 : std_logic; signal extena3 : std_logic; 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 clk5_tmp : std_logic; signal extclk0_tmp : std_logic; signal extclk1_tmp : std_logic; signal extclk2_tmp : std_logic; signal extclk3_tmp : std_logic; signal not_clk0_tmp : std_logic; signal not_clk1_tmp : std_logic; signal not_clk2_tmp : std_logic; signal not_clk3_tmp : std_logic; signal not_clk4_tmp : std_logic; signal not_clk5_tmp : std_logic; signal not_extclk0_tmp : std_logic; signal not_extclk1_tmp : std_logic; signal not_extclk2_tmp : std_logic; signal not_extclk3_tmp : std_logic; signal clkin : std_logic := '0'; signal gate_locked : std_logic := '0'; signal lock : std_logic := '0'; signal about_to_lock : boolean := false; signal quiet_period_violation : boolean := false; signal reconfig_err : boolean := false; signal scanclr_violation : boolean := false; signal scanclr_clk_violation : boolean := false; signal inclk_l0 : std_logic; signal inclk_l1 : std_logic; signal inclk_g0 : std_logic; signal inclk_g1 : std_logic; signal inclk_g2 : std_logic; signal inclk_g3 : std_logic; signal inclk_e0 : std_logic; signal inclk_e1 : std_logic; signal inclk_e2 : std_logic; signal inclk_e3 : 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 ena_ipd : std_logic; signal pfdena_ipd : std_logic; signal comparator_ipd : std_logic; signal areset_ipd : std_logic; signal fbin_ipd : std_logic; signal clkena0_ipd : std_logic; signal clkena1_ipd : std_logic; signal clkena2_ipd : std_logic; signal clkena3_ipd : std_logic; signal clkena4_ipd : std_logic; signal clkena5_ipd : std_logic; signal extclkena0_ipd : std_logic; signal extclkena1_ipd : std_logic; signal extclkena2_ipd : std_logic; signal extclkena3_ipd : std_logic; signal scanclk_ipd : std_logic; signal scanaclr_ipd : std_logic; signal scandata_ipd : std_logic; signal clkswitch_ipd : std_logic; signal lvds_dffa_clk : std_logic; signal lvds_dffb_clk : std_logic; signal lvds_dffc_clk : std_logic; signal lvds_dffd_clk : std_logic; signal dffa_out : std_logic := '0'; signal dffb_out : std_logic := '0'; signal dffc_out : std_logic := '0'; signal dffd_out : std_logic := '0'; signal nce_temp : std_logic := '0'; signal nce_l0 : std_logic := '0'; signal nce_l1 : std_logic := '0'; signal inclk_l0_dly1 : std_logic := '0'; signal inclk_l0_dly2 : std_logic := '0'; signal inclk_l0_dly3 : std_logic := '0'; signal inclk_l0_dly4 : std_logic := '0'; signal inclk_l0_dly5 : std_logic := '0'; signal inclk_l0_dly6 : std_logic := '0'; signal inclk_l1_dly1 : std_logic := '0'; signal inclk_l1_dly2 : std_logic := '0'; signal inclk_l1_dly3 : std_logic := '0'; signal inclk_l1_dly4 : std_logic := '0'; signal inclk_l1_dly5 : std_logic := '0'; signal inclk_l1_dly6 : std_logic := '0'; signal sig_offset : time := 0 ps; signal sig_refclk_time : time := 0 ps; signal sig_fbclk_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 sig_current_clock : string(1 to 6); signal m_delay : integer := 0; signal n_delay : integer := 0; signal sig_curr_clock : string(1 to 6) := primary_clock; signal scan_chain_length : integer := GPP_SCAN_CHAIN; signal ext_fbk_cntr_high : integer := 0; signal ext_fbk_cntr_low : integer := 0; signal ext_fbk_cntr_delay : integer := 0; signal ext_fbk_cntr_ph : integer := 0; signal ext_fbk_cntr_initial : integer := 1; signal ext_fbk_cntr : string(1 to 2) := "e0"; signal ext_fbk_cntr_mode : string(1 to 6) := "bypass"; signal enable0_tmp : std_logic := '0'; signal enable1_tmp : std_logic := '0'; signal reset_low : std_logic := '0'; signal scandataout_tmp : std_logic := '0'; signal sdataout_trig : std_logic := '0'; signal sdataout_rst_trig : 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 done_with_param_calc : boolean := false; COMPONENT MF_m_cntr PORT ( clk : IN std_logic; reset : IN std_logic; cout : OUT std_logic; initial_value : IN integer := 1; modulus : IN integer; time_delay : IN integer; ph : IN integer := 0 ); END COMPONENT; COMPONENT MF_n_cntr PORT ( clk : IN std_logic; reset : IN std_logic; cout : OUT std_logic; modulus : IN integer; time_delay : IN integer); END COMPONENT; COMPONENT stx_scale_cntr PORT ( clk : IN std_logic; reset : IN std_logic; cout : OUT std_logic; initial : IN integer := 1; high : IN integer := 1; low : IN integer := 1; mode : IN string := "bypass"; time_delay : IN integer := 0; ph_tap : IN natural ); END COMPONENT; COMPONENT dffp 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 MF_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 inclk0_ipd <= inclk(0); inclk1_ipd <= inclk(1); areset_ipd <= areset; ena_ipd <= ena; fbin_ipd <= fbin; pfdena_ipd <= pfdena; clkena0_ipd <= clkena(0); clkena1_ipd <= clkena(1); clkena2_ipd <= clkena(2); clkena3_ipd <= clkena(3); clkena4_ipd <= clkena(4); clkena5_ipd <= clkena(5); extclkena0_ipd <= extclkena(0); extclkena1_ipd <= extclkena(1); extclkena2_ipd <= extclkena(2); extclkena3_ipd <= extclkena(3); scanclk_ipd <= scanclk; scanaclr_ipd <= scanaclr; scandata_ipd <= scandata; comparator_ipd <= comparator; clkswitch_ipd <= clkswitch; end block; -- User to Advanced parameter conversion i_extclk3_counter <= "e3" when m=0 else extclk3_counter; i_extclk2_counter <= "e2" when m=0 else extclk2_counter; i_extclk1_counter <= "e1" when m=0 else extclk1_counter; i_extclk0_counter <= "e0" when m=0 else extclk0_counter; i_clk5_counter <= "l1" when m=0 else clk5_counter; i_clk4_counter <= "l0" when m=0 else clk4_counter; i_clk3_counter <= "g3" when m=0 else clk3_counter; i_clk2_counter <= "g2" when m=0 else clk2_counter; i_clk1_counter <= "g1" when m=0 else clk1_counter; i_clk0_counter <= "l0" when m=0 and pll_type = "lvds" else "g0" when m=0 else clk0_counter; -- end parameter conversion inclk_m <= extclk0_tmp when operation_mode = "external_feedback" and feedback_source = "extclk0" else extclk1_tmp when operation_mode = "external_feedback" and feedback_source = "extclk1" else extclk2_tmp when operation_mode = "external_feedback" and feedback_source = "extclk2" else extclk3_tmp when operation_mode = "external_feedback" and feedback_source = "extclk3" else vco_out(m_ph_val); ext_fbk_cntr <= "e0" when (feedback_source = "extclk0" and extclk0_counter = "e0") or (feedback_source = "extclk1" and extclk1_counter = "e0") or (feedback_source = "extclk2" and extclk2_counter = "e0") or (feedback_source = "extclk3" and extclk3_counter = "e0") else "e1" when (feedback_source = "extclk0" and extclk0_counter = "e1") or (feedback_source = "extclk1" and extclk1_counter = "e1") or (feedback_source = "extclk2" and extclk2_counter = "e1") or (feedback_source = "extclk3" and extclk3_counter = "e1") else "e2" when (feedback_source = "extclk0" and extclk0_counter = "e2") or (feedback_source = "extclk1" and extclk1_counter = "e2") or (feedback_source = "extclk2" and extclk2_counter = "e2") or (feedback_source = "extclk3" and extclk3_counter = "e2") else "e3" when (feedback_source = "extclk0" and extclk0_counter = "e3") or (feedback_source = "extclk1" and extclk1_counter = "e3") or (feedback_source = "extclk2" and extclk2_counter = "e3") or (feedback_source = "extclk3" and extclk3_counter = "e3") else "e0"; ext_fbk_cntr_high <= e0_high_val when ext_fbk_cntr = "e0" else e1_high_val when ext_fbk_cntr = "e1" else e2_high_val when ext_fbk_cntr = "e2" else e3_high_val when ext_fbk_cntr = "e3" else 1; ext_fbk_cntr_low <= e0_low_val when ext_fbk_cntr = "e0" else e1_low_val when ext_fbk_cntr = "e1" else e2_low_val when ext_fbk_cntr = "e2" else e3_low_val when ext_fbk_cntr = "e3" else 1; ext_fbk_cntr_delay <= e0_time_delay_val when ext_fbk_cntr = "e0" else e1_time_delay_val when ext_fbk_cntr = "e1" else e2_time_delay_val when ext_fbk_cntr = "e2" else e3_time_delay_val when ext_fbk_cntr = "e3" else 0; ext_fbk_cntr_ph <= e0_ph_val when ext_fbk_cntr = "e0" else e1_ph_val when ext_fbk_cntr = "e1" else e2_ph_val when ext_fbk_cntr = "e2" else e3_ph_val when ext_fbk_cntr = "e3" else 0; ext_fbk_cntr_initial <= e0_initial_val when ext_fbk_cntr = "e0" else e1_initial_val when ext_fbk_cntr = "e1" else e2_initial_val when ext_fbk_cntr = "e2" else e3_initial_val when ext_fbk_cntr = "e3" else 0; ext_fbk_cntr_mode <= e0_mode_val when ext_fbk_cntr = "e0" else e1_mode_val when ext_fbk_cntr = "e1" else e2_mode_val when ext_fbk_cntr = "e2" else e3_mode_val when ext_fbk_cntr = "e3" else e0_mode_val; areset_ena_sig <= areset_ipd or (not ena_ipd) or sig_stop_vco; m1 : MF_m_cntr port map ( clk => inclk_m, reset => areset_ena_sig, cout => fbclk, initial_value => m_initial_val, modulus => m_val, time_delay => m_delay, ph => m_ph_val ); -- add delta delay to inclk1 to ensure inclk0 and inclk1 are processed -- in different simulation deltas. n1 : MF_n_cntr port map ( clk => clkin, reset => areset_ipd, cout => refclk, modulus => n_val, time_delay => n_time_delay_val); inclk_l0 <= vco_out(l0_ph_val); l0 : stx_scale_cntr port map ( clk => inclk_l0, reset => areset_ena_sig, cout => l0_clk, initial => l0_initial_val, high => l0_high_val, low => l0_low_val, mode => l0_mode_val, time_delay => l0_time_delay_val, ph_tap => l0_ph_val); inclk_l1 <= vco_out(l1_ph_val); l1 : stx_scale_cntr port map ( clk => inclk_l1, reset => areset_ena_sig, cout => l1_clk, initial => l1_initial_val, high => l1_high_val, low => l1_low_val, mode => l1_mode_val, time_delay => l1_time_delay_val, ph_tap => l1_ph_val); inclk_g0 <= vco_out(g0_ph_val); g0 : stx_scale_cntr port map ( clk => inclk_g0, reset => areset_ena_sig, cout => g0_clk, initial => g0_initial_val, high => g0_high_val, low => g0_low_val, mode => g0_mode_val, time_delay => g0_time_delay_val, ph_tap => g0_ph_val); process(g0_clk, l0_clk, l1_clk) begin if (g0_clk'event and g0_clk = '1') then dffa_out <= comparator_ipd; end if; if (l0_clk'event and l0_clk = '1' and enable0_counter = "l0") then dffb_out <= dffa_out; dffc_out <= dffb_out; dffd_out <= nce_temp; end if; if (l1_clk'event and l1_clk = '1' and enable0_counter = "l1") then dffb_out <= dffa_out; dffc_out <= dffb_out; dffd_out <= nce_temp; end if; end process; nce_temp <= (not dffc_out) and dffb_out; nce_l0 <= dffd_out when enable0_counter = "l0" else '0'; nce_l1 <= dffd_out when enable0_counter = "l1" else '0'; inclk_g1 <= vco_out(g1_ph_val); g1 : stx_scale_cntr port map ( clk => inclk_g1, reset => areset_ena_sig, cout => g1_clk, initial => g1_initial_val, high => g1_high_val, low => g1_low_val, mode => g1_mode_val, time_delay => g1_time_delay_val, ph_tap => g1_ph_val); inclk_g2 <= vco_out(g2_ph_val); g2 : stx_scale_cntr port map ( clk => inclk_g2, reset => areset_ena_sig, cout => g2_clk, initial => g2_initial_val, high => g2_high_val, low => g2_low_val, mode => g2_mode_val, time_delay => g2_time_delay_val, ph_tap => g2_ph_val); inclk_g3 <= vco_out(g3_ph_val); g3 : stx_scale_cntr port map ( clk => inclk_g3, reset => areset_ena_sig, cout => g3_clk, initial => g3_initial_val, high => g3_high_val, low => g3_low_val, mode => g3_mode_val, time_delay => g3_time_delay_val, ph_tap => g3_ph_val); inclk_e0 <= vco_out(e0_ph_val); cntr_e0_initial <= 1 when operation_mode = "external_feedback" and ext_fbk_cntr = "e0" else e0_initial_val; cntr_e0_delay <= ext_fbk_delay when operation_mode = "external_feedback" and ext_fbk_cntr = "e0" else e0_time_delay_val; e0 : stx_scale_cntr port map ( clk => inclk_e0, reset => areset_ena_sig, cout => e0_clk, initial => cntr_e0_initial, high => e0_high_val, low => e0_low_val, mode => e0_mode_val, time_delay => cntr_e0_delay, ph_tap => e0_ph_val); inclk_e1 <= vco_out(e1_ph_val); cntr_e1_initial <= 1 when operation_mode = "external_feedback" and ext_fbk_cntr = "e1" else e1_initial_val; cntr_e1_delay <= ext_fbk_delay when operation_mode = "external_feedback" and ext_fbk_cntr = "e1" else e1_time_delay_val; e1 : stx_scale_cntr port map ( clk => inclk_e1, reset => areset_ena_sig, cout => e1_clk, initial => cntr_e1_initial, high => e1_high_val, low => e1_low_val, mode => e1_mode_val, time_delay => cntr_e1_delay, ph_tap => e1_ph_val); inclk_e2 <= vco_out(e2_ph_val); cntr_e2_initial <= 1 when operation_mode = "external_feedback" and ext_fbk_cntr = "e2" else e2_initial_val; cntr_e2_delay <= ext_fbk_delay when operation_mode = "external_feedback" and ext_fbk_cntr = "e2" else e2_time_delay_val; e2 : stx_scale_cntr port map ( clk => inclk_e2, reset => areset_ena_sig, cout => e2_clk, initial => cntr_e2_initial, high => e2_high_val, low => e2_low_val, mode => e2_mode_val, time_delay => cntr_e2_delay, ph_tap => e2_ph_val); inclk_e3 <= vco_out(e3_ph_val); cntr_e3_initial <= 1 when operation_mode = "external_feedback" and ext_fbk_cntr = "e3" else e3_initial_val; cntr_e3_delay <= ext_fbk_delay when operation_mode = "external_feedback" and ext_fbk_cntr = "e3" else e3_time_delay_val; e3 : stx_scale_cntr port map ( clk => inclk_e3, reset => areset_ena_sig, cout => e3_clk, initial => cntr_e3_initial, high => e3_high_val, low => e3_low_val, mode => e3_mode_val, time_delay => cntr_e3_delay, ph_tap => e3_ph_val); inclk_l0_dly1 <= inclk_l0; inclk_l0_dly2 <= inclk_l0_dly1; inclk_l0_dly3 <= inclk_l0_dly2; inclk_l0_dly4 <= inclk_l0_dly3; inclk_l0_dly5 <= inclk_l0_dly4; inclk_l0_dly6 <= inclk_l0_dly5; inclk_l1_dly1 <= inclk_l1; inclk_l1_dly2 <= inclk_l1_dly1; inclk_l1_dly3 <= inclk_l1_dly2; inclk_l1_dly4 <= inclk_l1_dly3; inclk_l1_dly5 <= inclk_l1_dly4; inclk_l1_dly6 <= inclk_l1_dly5; process(inclk_l0_dly6, inclk_l1_dly6, areset_ipd, ena_ipd, sig_stop_vco) variable l0_got_first_rising_edge : boolean := false; variable l0_count : integer := 1; variable l0_tmp, l1_tmp : std_logic := '0'; variable l1_got_first_rising_edge : boolean := false; variable l1_count : integer := 1; begin if (areset_ipd = '1' or ena_ipd = '0' or sig_stop_vco = '1') then l0_count := 1; l1_count := 1; l0_got_first_rising_edge := false; l1_got_first_rising_edge := false; else if (nce_l0 = '0') then if (not l0_got_first_rising_edge) then if (inclk_l0_dly6'event and inclk_l0_dly6 = '1') then l0_got_first_rising_edge := true; end if; elsif (inclk_l0_dly6'event) then l0_count := l0_count + 1; if (l0_count = (l0_high_val + l0_low_val) * 2) then l0_count := 1; end if; end if; end if; if (inclk_l0_dly6'event and inclk_l0_dly6 = '0') then if (l0_count = 1) then l0_tmp := '1'; l0_got_first_rising_edge := false; else l0_tmp := '0'; end if; end if; if (nce_l1 = '0') then if (not l1_got_first_rising_edge) then if (inclk_l1_dly6'event and inclk_l1_dly6 = '1') then l1_got_first_rising_edge := true; end if; elsif (inclk_l1_dly6'event) then l1_count := l1_count + 1; if (l1_count = (l1_high_val + l1_low_val) * 2) then l1_count := 1; end if; end if; end if; if (inclk_l1_dly6'event and inclk_l1_dly6 = '0') then if (l1_count = 1) then l1_tmp := '1'; l1_got_first_rising_edge := false; else l1_tmp := '0'; end if; end if; end if; if (enable0_counter = "l0") then enable0_tmp <= l0_tmp; elsif (enable0_counter = "l1") then enable0_tmp <= l1_tmp; else enable0_tmp <= '0'; end if; if (enable1_counter = "l0") then enable1_tmp <= l0_tmp; elsif (enable1_counter = "l1") then enable1_tmp <= l1_tmp; else enable1_tmp <= '0'; end if; end process; glocked_cntr : process(clkin, ena_ipd, areset_ipd) variable count : integer := 0; variable output : std_logic := '0'; begin if (areset_ipd = '1') then count := 0; output := '0'; elsif (clkin'event and clkin = '1') then if (ena_ipd = '1') then count := count + 1; if (count = gate_lock_counter) then output := '1'; end if; end if; end if; gate_locked <= output; end process; locked <= gate_locked and lock when gate_lock_signal = "yes" else lock; process (transfer) variable init : boolean := true; variable low, high : std_logic_vector(8 downto 0); variable delay_chain : std_logic_vector(3 downto 0); variable mn_delay_chain : std_logic_vector(0 to 3); variable mode : string(1 to 6) := "bypass"; variable delay_val : integer := 0; variable is_error : boolean := false; variable buf : line; -- user to advanced variables variable i_m_initial : natural; variable i_m : integer := 1; variable i_n : natural := 1; variable i_m2 : natural; variable i_n2 : natural; variable i_ss : natural; variable i_l0_high : natural; variable i_l1_high : natural; variable i_g0_high : natural; variable i_g1_high : natural; variable i_g2_high : natural; variable i_g3_high : natural; variable i_e0_high : natural; variable i_e1_high : natural; variable i_e2_high : natural; variable i_e3_high : natural; variable i_l0_low : natural; variable i_l1_low : natural; variable i_g0_low : natural; variable i_g1_low : natural; variable i_g2_low : natural; variable i_g3_low : natural; variable i_e0_low : natural; variable i_e1_low : natural; variable i_e2_low : natural; variable i_e3_low : natural; variable i_l0_initial : natural; variable i_l1_initial : natural; variable i_g0_initial : natural; variable i_g1_initial : natural; variable i_g2_initial : natural; variable i_g3_initial : natural; variable i_e0_initial : natural; variable i_e1_initial : natural; variable i_e2_initial : natural; variable i_e3_initial : natural; variable i_l0_mode : string(1 to 6); variable i_l1_mode : string(1 to 6); variable i_g0_mode : string(1 to 6); variable i_g1_mode : string(1 to 6); variable i_g2_mode : string(1 to 6); variable i_g3_mode : string(1 to 6); variable i_e0_mode : string(1 to 6); variable i_e1_mode : string(1 to 6); variable i_e2_mode : string(1 to 6); variable i_e3_mode : string(1 to 6); variable max_neg_abs : integer := 0; variable i_l0_time_delay : natural; variable i_l1_time_delay : natural; variable i_g0_time_delay : natural; variable i_g1_time_delay : natural; variable i_g2_time_delay : natural; variable i_g3_time_delay : natural; variable i_e0_time_delay : natural; variable i_e1_time_delay : natural; variable i_e2_time_delay : natural; variable i_e3_time_delay : natural; variable i_m_time_delay : natural; variable i_n_time_delay : natural; variable i_l0_ph : natural; variable i_l1_ph : natural; variable i_g0_ph : natural; variable i_g1_ph : natural; variable i_g2_ph : natural; variable i_g3_ph : natural; variable i_e0_ph : natural; variable i_e1_ph : natural; variable i_e2_ph : natural; variable i_e3_ph : natural; variable i_m_ph : natural; variable output_count : natural; variable new_divisor : natural; -- 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 i_clk5_mult_by : integer := 1; variable i_clk5_div_by : integer := 1; variable i_extclk0_mult_by : integer := 1; variable i_extclk0_div_by : integer := 1; variable i_extclk1_mult_by : integer := 1; variable i_extclk1_div_by : integer := 1; variable i_extclk2_mult_by : integer := 1; variable i_extclk2_div_by : integer := 1; variable i_extclk3_mult_by : integer := 1; variable i_extclk3_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; begin if (init) then 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 := 500; -- 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); find_simple_integer_fraction(clk5_multiply_by, clk5_divide_by, max_d_value, i_clk5_mult_by, i_clk5_div_by); find_simple_integer_fraction(extclk0_multiply_by, extclk0_divide_by, max_d_value, i_extclk0_mult_by, i_extclk0_div_by); find_simple_integer_fraction(extclk1_multiply_by, extclk1_divide_by, max_d_value, i_extclk1_mult_by, i_extclk1_div_by); find_simple_integer_fraction(extclk2_multiply_by, extclk2_divide_by, max_d_value, i_extclk2_mult_by, i_extclk2_div_by); find_simple_integer_fraction(extclk3_multiply_by, extclk3_divide_by, max_d_value, i_extclk3_mult_by, i_extclk3_div_by); i_n := 1; if (pll_type = "lvds") then i_m := clk0_multiply_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, i_clk5_mult_by, i_extclk0_mult_by, i_extclk1_mult_by, i_extclk2_mult_by, i_extclk3_mult_by, inclk0_input_frequency); end if; i_m_time_delay := maxnegabs ( str2int(clk0_time_delay), str2int(clk1_time_delay), str2int(clk2_time_delay), str2int(clk3_time_delay), str2int(clk4_time_delay), str2int(clk5_time_delay), str2int(extclk0_time_delay), str2int(extclk1_time_delay), str2int(extclk2_time_delay), str2int(extclk3_time_delay)); i_n_time_delay := mintimedelay(str2int(clk0_time_delay), str2int(clk1_time_delay), str2int(clk2_time_delay), str2int(clk3_time_delay), str2int(clk4_time_delay), str2int(clk5_time_delay), str2int(extclk0_time_delay), str2int(extclk1_time_delay), str2int(extclk2_time_delay), str2int(extclk3_time_delay)); if (pll_type = "lvds") then i_g0_time_delay := counter_time_delay ( str2int(clk2_time_delay), i_m_time_delay, i_n_time_delay); else i_g0_time_delay := counter_time_delay ( str2int(clk0_time_delay), i_m_time_delay,i_n_time_delay); end if; i_g1_time_delay := counter_time_delay ( str2int(clk1_time_delay), i_m_time_delay, i_n_time_delay); i_g2_time_delay := counter_time_delay ( str2int(clk2_time_delay), i_m_time_delay, i_n_time_delay); i_g3_time_delay := counter_time_delay ( str2int(clk3_time_delay), i_m_time_delay, i_n_time_delay); if (pll_type = "lvds") then i_l0_time_delay := i_g0_time_delay; i_l1_time_delay := i_g0_time_delay; else i_l0_time_delay := counter_time_delay ( str2int(clk4_time_delay), i_m_time_delay, i_n_time_delay); i_l1_time_delay := counter_time_delay ( str2int(clk5_time_delay), i_m_time_delay, i_n_time_delay); end if; i_e0_time_delay := counter_time_delay ( str2int(extclk0_time_delay), i_m_time_delay, i_n_time_delay); i_e1_time_delay := counter_time_delay ( str2int(extclk1_time_delay), i_m_time_delay, i_n_time_delay); i_e2_time_delay := counter_time_delay ( str2int(extclk2_time_delay), i_m_time_delay, i_n_time_delay); i_e3_time_delay := counter_time_delay ( str2int(extclk3_time_delay), i_m_time_delay, i_n_time_delay); 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), str2int(clk5_phase_shift), str2int(extclk0_phase_shift), str2int(extclk1_phase_shift), str2int(extclk2_phase_shift), str2int(extclk3_phase_shift)); i_m_ph := counter_ph(get_phase_degree(max_neg_abs,inclk0_input_frequency), i_m, i_n); if (pll_type = "lvds") then i_g0_ph := counter_ph(get_phase_degree(ph_adjust(i_clk2_phase_shift, max_neg_abs),inclk0_input_frequency), i_m, i_n); else i_g0_ph := counter_ph(get_phase_degree(ph_adjust(i_clk0_phase_shift, max_neg_abs),inclk0_input_frequency), i_m, i_n); end if; i_g1_ph := counter_ph(get_phase_degree(ph_adjust(i_clk1_phase_shift, max_neg_abs),inclk0_input_frequency), i_m, i_n); i_g2_ph := counter_ph(get_phase_degree(ph_adjust(i_clk2_phase_shift, max_neg_abs),inclk0_input_frequency), i_m, i_n); i_g3_ph := counter_ph(get_phase_degree(ph_adjust(str2int(clk3_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); if (pll_type = "lvds") then i_l0_ph := i_g0_ph; i_l1_ph := i_g0_ph; else i_l0_ph := counter_ph(get_phase_degree(ph_adjust(str2int(clk4_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); i_l1_ph := counter_ph(get_phase_degree(ph_adjust(str2int(clk5_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); end if; i_e0_ph := counter_ph(get_phase_degree(ph_adjust(str2int(extclk0_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); i_e1_ph := counter_ph(get_phase_degree(ph_adjust(str2int(extclk1_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); i_e2_ph := counter_ph(get_phase_degree(ph_adjust(str2int(extclk2_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); i_e3_ph := counter_ph(get_phase_degree(ph_adjust(str2int(extclk3_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); if (pll_type = "lvds") then i_g0_high := counter_high ( output_counter_value(i_clk2_div_by, i_clk2_mult_by, i_m, i_n), clk2_duty_cycle); else i_g0_high := counter_high ( output_counter_value(i_clk0_div_by, i_clk0_mult_by, i_m, i_n), clk0_duty_cycle); end if; i_g1_high := counter_high ( output_counter_value(i_clk1_div_by, i_clk1_mult_by, i_m, i_n), clk1_duty_cycle); i_g2_high := counter_high ( output_counter_value(i_clk2_div_by, i_clk2_mult_by, i_m, i_n), clk2_duty_cycle); i_g3_high := counter_high ( output_counter_value(i_clk3_div_by, i_clk3_mult_by, i_m, i_n), clk3_duty_cycle); if (pll_type = "lvds") then i_l0_high := i_g0_high; i_l1_high := i_g0_high; else i_l0_high := counter_high ( output_counter_value(i_clk4_div_by, i_clk4_mult_by, i_m, i_n), clk4_duty_cycle); i_l1_high := counter_high ( output_counter_value(i_clk5_div_by, i_clk5_mult_by, i_m, i_n), clk5_duty_cycle); end if; i_e0_high := counter_high ( output_counter_value(i_extclk0_div_by, i_extclk0_mult_by, i_m, i_n), extclk0_duty_cycle); i_e1_high := counter_high ( output_counter_value(i_extclk1_div_by, i_extclk1_mult_by, i_m, i_n), extclk1_duty_cycle); i_e2_high := counter_high ( output_counter_value(i_extclk2_div_by, i_extclk2_mult_by, i_m, i_n), extclk2_duty_cycle); i_e3_high := counter_high ( output_counter_value(i_extclk3_div_by, i_extclk3_mult_by, i_m, i_n), extclk3_duty_cycle); if (pll_type = "lvds") then i_g0_low := counter_low ( output_counter_value(i_clk2_div_by, i_clk2_mult_by, i_m, i_n), clk2_duty_cycle); else i_g0_low := counter_low ( output_counter_value(i_clk0_div_by, i_clk0_mult_by, i_m, i_n), clk0_duty_cycle); end if; i_g1_low := counter_low ( output_counter_value(i_clk1_div_by, i_clk1_mult_by, i_m, i_n), clk1_duty_cycle); i_g2_low := counter_low ( output_counter_value(i_clk2_div_by, i_clk2_mult_by, i_m, i_n), clk2_duty_cycle); i_g3_low := counter_low ( output_counter_value(i_clk3_div_by, i_clk3_mult_by, i_m, i_n), clk3_duty_cycle); if (pll_type = "lvds") then i_l0_low := i_g0_low; i_l1_low := i_g0_low; else i_l0_low := counter_low ( output_counter_value(i_clk4_div_by, i_clk4_mult_by, i_m, i_n), clk4_duty_cycle); i_l1_low := counter_low ( output_counter_value(i_clk5_div_by, i_clk5_mult_by, i_m, i_n), clk5_duty_cycle); end if; i_e0_low := counter_low ( output_counter_value(i_extclk0_div_by, i_extclk0_mult_by, i_m, i_n), extclk0_duty_cycle); i_e1_low := counter_low ( output_counter_value(i_extclk1_div_by, i_extclk1_mult_by, i_m, i_n), extclk1_duty_cycle); i_e2_low := counter_low ( output_counter_value(i_extclk2_div_by, i_extclk2_mult_by, i_m, i_n), extclk2_duty_cycle); i_e3_low := counter_low ( output_counter_value(i_extclk3_div_by, i_extclk3_mult_by, i_m, i_n), extclk3_duty_cycle); i_m_initial := counter_initial(get_phase_degree(max_neg_abs, inclk0_input_frequency), i_m,i_n); if (pll_type = "lvds") then i_g0_initial := counter_initial(get_phase_degree(ph_adjust(i_clk2_phase_shift, max_neg_abs), inclk0_input_frequency), i_m, i_n); else i_g0_initial := counter_initial(get_phase_degree(ph_adjust(i_clk0_phase_shift, max_neg_abs), inclk0_input_frequency), i_m, i_n); end if; i_g1_initial := counter_initial(get_phase_degree(ph_adjust(i_clk1_phase_shift, max_neg_abs), inclk0_input_frequency), i_m, i_n); i_g2_initial := counter_initial(get_phase_degree(ph_adjust(i_clk2_phase_shift, max_neg_abs), inclk0_input_frequency), i_m, i_n); i_g3_initial := counter_initial(get_phase_degree(ph_adjust(str2int(clk3_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); if (pll_type = "lvds") then i_l0_initial := i_g0_initial; i_l1_initial := i_g0_initial; else i_l0_initial := counter_initial(get_phase_degree(ph_adjust(str2int(clk4_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); i_l1_initial := counter_initial(get_phase_degree(ph_adjust(str2int(clk5_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); end if; i_e0_initial := counter_initial(get_phase_degree(ph_adjust(str2int(extclk0_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); i_e1_initial := counter_initial(get_phase_degree(ph_adjust(str2int(extclk1_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); i_e2_initial := counter_initial(get_phase_degree(ph_adjust(str2int(extclk2_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); i_e3_initial := counter_initial(get_phase_degree(ph_adjust(str2int(extclk3_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); if (pll_type = "lvds") then i_g0_mode := counter_mode(clk2_duty_cycle, output_counter_value(i_clk2_div_by, i_clk2_mult_by, i_m, i_n)); else i_g0_mode := counter_mode(clk0_duty_cycle, output_counter_value(i_clk0_div_by, i_clk0_mult_by, i_m, i_n)); end if; i_g1_mode := counter_mode(clk1_duty_cycle, output_counter_value(i_clk1_div_by, i_clk1_mult_by, i_m, i_n)); i_g2_mode := counter_mode(clk2_duty_cycle, output_counter_value(i_clk2_div_by, i_clk2_mult_by, i_m, i_n)); i_g3_mode := counter_mode(clk3_duty_cycle, output_counter_value(i_clk3_div_by, i_clk3_mult_by, i_m, i_n)); if (pll_type = "lvds") then i_l0_mode := "bypass"; i_l1_mode := "bypass"; else i_l0_mode := counter_mode(clk4_duty_cycle, output_counter_value(i_clk4_div_by, i_clk4_mult_by, i_m, i_n)); i_l1_mode := counter_mode(clk5_duty_cycle, output_counter_value(i_clk5_div_by, i_clk5_mult_by, i_m, i_n)); end if; i_e0_mode := counter_mode(extclk0_duty_cycle, output_counter_value(i_extclk0_div_by, i_extclk0_mult_by, i_m, i_n)); i_e1_mode := counter_mode(extclk1_duty_cycle, output_counter_value(i_extclk1_div_by, i_extclk1_mult_by, i_m, i_n)); i_e2_mode := counter_mode(extclk2_duty_cycle, output_counter_value(i_extclk2_div_by, i_extclk2_mult_by, i_m, i_n)); i_e3_mode := counter_mode(extclk3_duty_cycle, output_counter_value(i_extclk3_div_by, i_extclk3_mult_by, i_m, i_n)); -- in external feedback mode, need to adjust M value to take -- into consideration the external feedback counter value if(operation_mode = "external_feedback") then -- if there is a negative phase shift, m_initial can -- only be 1 if (max_neg_abs > 0) then i_m_initial := 1; end if; -- calculate the feedback counter multiplier if (feedback_source = "extclk0") then if (i_e0_mode = "bypass") then output_count := 1; else output_count := i_e0_high + i_e0_low; end if; elsif (feedback_source = "extclk1") then if (i_e1_mode = "bypass") then output_count := 1; else output_count := i_e1_high + i_e1_low; end if; elsif (feedback_source = "extclk2") then if (i_e2_mode = "bypass") then output_count := 1; else output_count := i_e2_high + i_e2_low; end if; elsif (feedback_source = "extclk3") then if (i_e3_mode = "bypass") then output_count := 1; else output_count := i_e3_high + i_e3_low; end if; else -- default to e0 if (i_e0_mode = "bypass") then output_count := 1; else output_count := i_e0_high + i_e0_low; end if; end if; new_divisor := gcd(i_m, output_count); i_m := i_m / new_divisor; i_n := output_count / new_divisor; end if; else -- m /= 0 i_n := n; i_m := m; i_m_initial := m_initial; i_m_time_delay := m_time_delay; i_n_time_delay := n_time_delay; i_l0_time_delay := l0_time_delay; i_l1_time_delay := l1_time_delay; i_g0_time_delay := g0_time_delay; i_g1_time_delay := g1_time_delay; i_g2_time_delay := g2_time_delay; i_g3_time_delay := g3_time_delay; i_e0_time_delay := e0_time_delay; i_e1_time_delay := e1_time_delay; i_e2_time_delay := e2_time_delay; i_e3_time_delay := e3_time_delay; i_m_ph := m_ph; i_l0_ph := l0_ph; i_l1_ph := l1_ph; i_g0_ph := g0_ph; i_g1_ph := g1_ph; i_g2_ph := g2_ph; i_g3_ph := g3_ph; i_e0_ph := e0_ph; i_e1_ph := e1_ph; i_e2_ph := e2_ph; i_e3_ph := e3_ph; i_l0_high := l0_high; i_l1_high := l1_high; i_g0_high := g0_high; i_g1_high := g1_high; i_g2_high := g2_high; i_g3_high := g3_high; i_e0_high := e0_high; i_e1_high := e1_high; i_e2_high := e2_high; i_e3_high := e3_high; i_l0_low := l0_low; i_l1_low := l1_low; i_g0_low := g0_low; i_g1_low := g1_low; i_g2_low := g2_low; i_g3_low := g3_low; i_e0_low := e0_low; i_e1_low := e1_low; i_e2_low := e2_low; i_e3_low := e3_low; i_l0_initial := l0_initial; i_l1_initial := l1_initial; i_g0_initial := g0_initial; i_g1_initial := g1_initial; i_g2_initial := g2_initial; i_g3_initial := g3_initial; i_e0_initial := e0_initial; i_e1_initial := e1_initial; i_e2_initial := e2_initial; i_e3_initial := e3_initial; i_l0_mode := translate_string(l0_mode); i_l1_mode := translate_string(l1_mode); i_g0_mode := translate_string(g0_mode); i_g1_mode := translate_string(g1_mode); i_g2_mode := translate_string(g2_mode); i_g3_mode := translate_string(g3_mode); i_e0_mode := translate_string(e0_mode); i_e1_mode := translate_string(e1_mode); i_e2_mode := translate_string(e2_mode); i_e3_mode := translate_string(e3_mode); end if; -- user to advanced conversion. m_initial_val <= i_m_initial; n_val_tmp <= i_n; m_val_tmp <= i_m; if (i_m = 1) then m_mode_val <= "bypass"; end if; if (i_n = 1) then n_mode_val <= "bypass"; end if; -- NOTE: m_time_delay (vco time delay) not supported for external -- feedback mode -- in feedback mode, m_time_delay = delay of feedback loop tap m_time_delay_val <= i_m_time_delay; n_time_delay_val <= i_n_time_delay; m_ph_val <= i_m_ph; m2_val <= m2; n2_val <= n2; if (m2 = 1) then m2_mode_val <= "bypass"; end if; if (n2 = 1) then n2_mode_val <= "bypass"; end if; if (skip_vco = "on") then m_val_tmp <= 1; m_initial_val <= 1; m_time_delay_val <= 0; m_ph_val <= 0; end if; l0_ph_val <= i_l0_ph; l1_ph_val <= i_l1_ph; g0_ph_val <= i_g0_ph; g1_ph_val <= i_g1_ph; g2_ph_val <= i_g2_ph; g3_ph_val <= i_g3_ph; e0_ph_val <= i_e0_ph; e1_ph_val <= i_e1_ph; e2_ph_val <= i_e2_ph; e3_ph_val <= i_e3_ph; l0_initial_val <= i_l0_initial; l0_high_val <= i_l0_high; l0_low_val <= i_l0_low; l0_mode_val <= i_l0_mode; l0_time_delay_val <= i_l0_time_delay; l1_initial_val <= i_l1_initial; l1_high_val <= i_l1_high; l1_low_val <= i_l1_low; l1_mode_val <= i_l1_mode; l1_time_delay_val <= i_l1_time_delay; g0_initial_val <= i_g0_initial; g0_high_val <= i_g0_high; g0_low_val <= i_g0_low; g0_mode_val <= i_g0_mode; g0_time_delay_val <= i_g0_time_delay; g1_initial_val <= i_g1_initial; g1_high_val <= i_g1_high; g1_low_val <= i_g1_low; g1_mode_val <= i_g1_mode; g1_time_delay_val <= i_g1_time_delay; g2_initial_val <= i_g2_initial; g2_high_val <= i_g2_high; g2_low_val <= i_g2_low; g2_mode_val <= i_g2_mode; g2_time_delay_val <= i_g2_time_delay; g3_initial_val <= i_g3_initial; g3_high_val <= i_g3_high; g3_low_val <= i_g3_low; g3_mode_val <= i_g3_mode; g3_time_delay_val <= i_g3_time_delay; if (scan_chain = "long") then e0_initial_val <= i_e0_initial; e0_high_val <= i_e0_high; e0_low_val <= i_e0_low; e0_mode_val <= i_e0_mode; e0_time_delay_val <= i_e0_time_delay; e1_initial_val <= i_e1_initial; e1_high_val <= i_e1_high; e1_low_val <= i_e1_low; e1_mode_val <= i_e1_mode; e1_time_delay_val <= i_e1_time_delay; e2_initial_val <= i_e2_initial; e2_high_val <= i_e2_high; e2_low_val <= i_e2_low; e2_mode_val <= i_e2_mode; e2_time_delay_val <= i_e2_time_delay; e3_initial_val <= i_e3_initial; e3_high_val <= i_e3_high; e3_low_val <= i_e3_low; e3_mode_val <= i_e3_mode; e3_time_delay_val <= i_e3_time_delay; scan_chain_length <= EGPP_SCAN_CHAIN; end if; init := false; done_with_param_calc <= true; elsif (transfer'event and transfer = '1') then reconfig_err <= false; ASSERT false REPORT "Reconfiguring PLL" severity note; if (scan_chain = "long") then -- cntr e3 delay_chain := scan_data(287 downto 284); if (scan_data(273) = '1') then e3_mode_val <= "bypass"; if (scan_data(283) = '1') then e3_mode_val <= " off"; ASSERT false REPORT "The specified bit settings will turn OFF the E3 counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (scan_data(283) = '1') then e3_mode_val <= " odd"; else e3_mode_val <= " even"; end if; high := scan_data(272 downto 264); low := scan_data(282 downto 274); e3_low_val <= alt_conv_integer(low); e3_high_val <= alt_conv_integer(high); -- count value of 0 is actually 512 if (alt_conv_integer(high) = 0) then e3_high_val <= 512; end if; if (alt_conv_integer(low) = 0) then e3_low_val <= 512; end if; delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; e3_time_delay_val <= delay_val; -- cntr e2 delay_chain := scan_data(263 downto 260); if (scan_data(249) = '1') then e2_mode_val <= "bypass"; if (scan_data(259) = '1') then e2_mode_val <= " off"; ASSERT false REPORT "The specified bit settings will turn OFF the E2 counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (scan_data(259) = '1') then e2_mode_val <= " odd"; else e2_mode_val <= " even"; end if; high := scan_data(248 downto 240); low := scan_data(258 downto 250); e2_low_val <= alt_conv_integer(low); e2_high_val <= alt_conv_integer(high); if (alt_conv_integer(high) = 0) then e2_high_val <= 512; end if; if (alt_conv_integer(low) = 0) then e2_low_val <= 512; end if; delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; e2_time_delay_val <= delay_val; -- cntr e1 delay_chain := scan_data(239 downto 236); if (scan_data(225) = '1') then e1_mode_val <= "bypass"; if (scan_data(235) = '1') then e1_mode_val <= " off"; ASSERT false REPORT "The specified bit settings will turn OFF the E1 counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (scan_data(235) = '1') then e1_mode_val <= " odd"; else e1_mode_val <= " even"; end if; high := scan_data(224 downto 216); low := scan_data(234 downto 226); e1_low_val <= alt_conv_integer(low); e1_high_val <= alt_conv_integer(high); if (alt_conv_integer(high) = 0) then e1_high_val <= 512; end if; if (alt_conv_integer(low) = 0) then e1_low_val <= 512; end if; delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; e1_time_delay_val <= delay_val; -- cntr e0 delay_chain := scan_data(215 downto 212); if (scan_data(201) = '1') then e0_mode_val <= "bypass"; if (scan_data(211) = '1') then e0_mode_val <= " off"; ASSERT false REPORT "The specified bit settings will turn OFF the E0 counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (scan_data(211) = '1') then e0_mode_val <= " odd"; else e0_mode_val <= " even"; end if; high := scan_data(200 downto 192); low := scan_data(210 downto 202); e0_low_val <= alt_conv_integer(low); e0_high_val <= alt_conv_integer(high); if (alt_conv_integer(high) = 0) then e0_high_val <= 512; end if; if (alt_conv_integer(low) = 0) then e0_low_val <= 512; end if; delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; e0_time_delay_val <= delay_val; end if; -- cntr l1 delay_chain := scan_data(191 downto 188); if (scan_data(177) = '1') then l1_mode_val <= "bypass"; if (scan_data(187) = '1') then l1_mode_val <= " off"; ASSERT false REPORT "The specified bit settings will turn OFF the L1 counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (scan_data(187) = '1') then l1_mode_val <= " odd"; else l1_mode_val <= " even"; end if; high := scan_data(176 downto 168); low := scan_data(186 downto 178); l1_low_val <= alt_conv_integer(low); l1_high_val <= alt_conv_integer(high); if (alt_conv_integer(high) = 0) then l1_high_val <= 512; end if; if (alt_conv_integer(low) = 0) then l1_low_val <= 512; end if; delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; l1_time_delay_val <= delay_val; -- cntr l0 delay_chain := scan_data(167 downto 164); if (scan_data(153) = '1') then l0_mode_val <= "bypass"; if (scan_data(163) = '1') then l0_mode_val <= " off"; ASSERT false REPORT "The specified bit settings will turn OFF the L0 counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (scan_data(163) = '1') then l0_mode_val <= " odd"; else l0_mode_val <= " even"; end if; high := scan_data(152 downto 144); low := scan_data(162 downto 154); l0_low_val <= alt_conv_integer(low); l0_high_val <= alt_conv_integer(high); if (alt_conv_integer(high) = 0) then l0_high_val <= 512; end if; if (alt_conv_integer(low) = 0) then l0_low_val <= 512; end if; delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; l0_time_delay_val <= delay_val; -- cntr g3 delay_chain := scan_data(143 downto 140); if (scan_data(129) = '1') then g3_mode_val <= "bypass"; if (scan_data(139) = '1') then g3_mode_val <= " off"; ASSERT false REPORT "The specified bit settings will turn OFF the G3 counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (scan_data(139) = '1') then g3_mode_val <= " odd"; else g3_mode_val <= " even"; end if; high := scan_data(128 downto 120); low := scan_data(138 downto 130); g3_low_val <= alt_conv_integer(low); g3_high_val <= alt_conv_integer(high); if (alt_conv_integer(high) = 0) then g3_high_val <= 512; end if; if (alt_conv_integer(low) = 0) then g3_low_val <= 512; end if; delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; g3_time_delay_val <= delay_val; -- cntr g2 delay_chain := scan_data(119 downto 116); if (scan_data(105) = '1') then g2_mode_val <= "bypass"; if (scan_data(115) = '1') then g2_mode_val <= " off"; ASSERT false REPORT "The specified bit settings will turn OFF the G2 counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (scan_data(115) = '1') then g2_mode_val <= " odd"; else g2_mode_val <= " even"; end if; high := scan_data(104 downto 96); low := scan_data(114 downto 106); g2_low_val <= alt_conv_integer(low); g2_high_val <= alt_conv_integer(high); if (alt_conv_integer(high) = 0) then g2_high_val <= 512; end if; if (alt_conv_integer(low) = 0) then g2_low_val <= 512; end if; delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; g2_time_delay_val <= delay_val; -- cntr g1 delay_chain := scan_data(95 downto 92); if (scan_data(81) = '1') then g1_mode_val <= "bypass"; if (scan_data(91) = '1') then g1_mode_val <= " off"; ASSERT false REPORT "The specified bit settings will turn OFF the G1 counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (scan_data(91) = '1') then g1_mode_val <= " odd"; else g1_mode_val <= " even"; end if; high := scan_data(80 downto 72); low := scan_data(90 downto 82); g1_low_val <= alt_conv_integer(low); g1_high_val <= alt_conv_integer(high); if (alt_conv_integer(high) = 0) then g1_high_val <= 512; end if; if (alt_conv_integer(low) = 0) then g1_low_val <= 512; end if; delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; g1_time_delay_val <= delay_val; -- cntr g0 delay_chain := scan_data(71 downto 68); if (scan_data(57) = '1') then g0_mode_val <= "bypass"; if (scan_data(67) = '1') then g0_mode_val <= " off"; ASSERT false REPORT "The specified bit settings will turn OFF the G0 counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (scan_data(67) = '1') then g0_mode_val <= " odd"; else g0_mode_val <= " even"; end if; high := scan_data(56 downto 48); low := scan_data(66 downto 58); g0_low_val <= alt_conv_integer(low); g0_high_val <= alt_conv_integer(high); if (alt_conv_integer(high) = 0) then g0_high_val <= 512; end if; if (alt_conv_integer(low) = 0) then g0_low_val <= 512; end if; delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; g0_time_delay_val <= delay_val; -- cntr M is_error := false; -- 'low' contains modulus for m_cntr(spread_spectrum disabled) low := scan_data(32 downto 24); m_val_tmp <= alt_conv_integer(low); if (scan_data(33) /= '1') then if (alt_conv_integer(low) = 1) then is_error := true; reconfig_err <= true; ASSERT false REPORT "Illegal 1 value for M counter. Instead, M counter should be BYPASSED. Reconfiguration may not work." severity warning; elsif (alt_conv_integer(low) = 0) then m_val_tmp <= 512; end if; if (not is_error) then if (m_mode_val = "bypass") then ASSERT false REPORT "M counter switched from BYPASS mode to enabled (M modulus = " &int2str(alt_conv_integer(low))& "). PLL may lose lock." severity warning; else write (buf, string'(" M modulus = ")); write (buf, alt_conv_integer(low)); writeline (output, buf); end if; m_mode_val <= " "; end if; elsif (scan_data(33) = '1') then if (scan_data(24) /= '0') then is_error := true; reconfig_err <= true; ASSERT false REPORT "Illegal value for M counter in BYPASS mode. The LSB of the counter should be set to 0 in order to operate the counter in BYPASS mode. Reconfiguration may not work." severity warning; else if (m_mode_val /= "bypass") then ASSERT false REPORT "M counter switched from enabled to BYPASS mode. PLL may lose lock." severity warning; end if; write (buf, string'(" M modulus = ")); write (buf, 1); writeline (output, buf); m_val_tmp <= 1; m_mode_val <= "bypass"; end if; end if; if (skip_vco = "on") then m_val_tmp <= 1; ASSERT FALSE REPORT "VCO is bypassed, setting M modulus = 1, M time delay = 0" severity note; end if; -- cntr M2 if (ss > 0) then is_error := false; low := scan_data(42 downto 34); m2_val <= alt_conv_integer(low); if (scan_data(43) /= '1') then if (alt_conv_integer(low) = 1) then is_error := true; reconfig_err <= true; ASSERT false REPORT "Illegal 1 value for M2 counter. Instead, M counter should be BYPASSED. Reconfiguration may not work." severity warning; elsif (alt_conv_integer(low) = 0) then m2_val <= 512; end if; if (not is_error) then if (m2_mode_val = "bypass") then ASSERT false REPORT "M2 counter switched from BYPASS mode to enabled (M2 modulus = " &int2str(alt_conv_integer(low))& "). PLL may lose lock." severity warning; else write (buf, string'(" M2 modulus = ")); write (buf, alt_conv_integer(low)); writeline (output, buf); end if; m2_mode_val <= " "; end if; elsif (scan_data(43) = '1') then if (scan_data(34) /= '0') then is_error := true; reconfig_err <= true; ASSERT false REPORT "Illegal value for M2 counter in BYPASS mode. The LSB of the counter should be set to 0 in order to operate the counter in BYPASS mode. Reconfiguration may not work." severity warning; else if (m2_mode_val /= "bypass") then ASSERT false REPORT "M2 counter switched from enabled to BYPASS mode. PLL may lose lock." severity warning; end if; write (buf, string'(" M2 modulus = ")); write (buf, 1); writeline (output, buf); m2_val <= 1; m2_mode_val <= "bypass"; end if; end if; if (m_mode_val /= m2_mode_val) then is_error := true; reconfig_err <= true; ASSERT false REPORT "Incompatible modes for M1/M2 counters. Either both should be BYPASSED or both NON-BYPASSED. Reconfiguration may not work." severity warning; end if; end if; delay_chain := scan_data(47 downto 44); delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; m_time_delay_val <= delay_val; if (skip_vco = "on") then m_time_delay_val <= 0; delay_val := 0; end if; write (buf, string'(" M time delay = ")); write (buf, delay_val); writeline (output, buf); -- cntr N is_error := false; -- 'low' contains modulus for n_cntr(spread_spectrum disabled) low := scan_data(8 downto 0); n_val_tmp <= alt_conv_integer(low); if (scan_data(9) /= '1') then if (alt_conv_integer(low) = 1) then is_error := true; reconfig_err <= true; ASSERT false REPORT "Illegal 1 value for N counter. Instead, N counter should be BYPASSED. Reconfiguration may not work." severity warning; elsif (alt_conv_integer(low) = 0) then n_val_tmp <= 512; write (buf, string'(" N modulus = ")); write (buf, 512); writeline (output, buf); else write (buf, string'(" N modulus = ")); write (buf, alt_conv_integer(low)); writeline (output, buf); end if; if (not is_error) then if (n_mode_val = "bypass") then ASSERT false REPORT "N Counter switched from BYPASS mode to enabled (N modulus = " &int2str(alt_conv_integer(low))& "). PLL may lose lock." severity warning; else write (buf, string'(" N modulus = ")); write (buf, alt_conv_integer(low)); writeline (output, buf); end if; n_mode_val <= " "; end if; elsif (scan_data(9) = '1') then if (scan_data(0) /= '0') then is_error := true; reconfig_err <= true; ASSERT false REPORT "Illegal value for N counter in BYPASS mode. The LSB of the counter should be set to 0 in order to operate the counter in BYPASS mode. Reconfiguration may not work." severity warning; else if (n_mode_val /= "bypass") then ASSERT false REPORT "N counter switched from enabled to BYPASS mode. PLL may lose lock." severity warning; end if; write (buf, string'(" N modulus = ")); write (buf, 1); writeline (output, buf); n_val_tmp <= 1; n_mode_val <= "bypass"; end if; end if; -- cntr N2 if (ss > 0) then is_error := false; low := scan_data(18 downto 10); n2_val <= alt_conv_integer(low); if (scan_data(19) /= '1') then if (alt_conv_integer(low) = 1) then is_error := true; reconfig_err <= true; ASSERT false REPORT "Illegal 1 value for N2 counter. Instead, N counter should be BYPASSED. Reconfiguration may not work." severity warning; elsif (alt_conv_integer(low) = 0) then n2_val <= 512; end if; if (not is_error) then if (n2_mode_val = "bypass") then ASSERT false REPORT "N2 counter switched from BYPASS mode to enabled (N2 modulus = " &int2str(alt_conv_integer(low))& "). PLL may lose lock." severity warning; else write (buf, string'(" N2 modulus = ")); write (buf, alt_conv_integer(low)); writeline (output, buf); end if; n2_mode_val <= " "; end if; elsif (scan_data(19) = '1') then if (scan_data(10) /= '0') then is_error := true; reconfig_err <= true; ASSERT false REPORT "Illegal value for N2 counter in BYPASS mode. The LSB of the counter should be set to 0 in order to operate the counter in BYPASS mode. Reconfiguration may not work." severity warning; else if (n2_mode_val /= "bypass") then ASSERT false REPORT "N2 counter switched from enabled to BYPASS mode. PLL may lose lock." severity warning; end if; write (buf, string'(" N2 modulus = ")); write (buf, 1); writeline (output, buf); n2_val <= 1; n2_mode_val <= "bypass"; end if; end if; if (n_mode_val /= n2_mode_val) then is_error := true; reconfig_err <= true; ASSERT false REPORT "Incompatible modes for N1/N2 counters. Either both should be BYPASSED or both NON-BYPASSED. Reconfiguration may not work." severity warning; end if; end if; delay_chain := scan_data(23 downto 20); delay_val := alt_conv_integer(delay_chain); delay_val := delay_val * 250; if (delay_val > 3000) then delay_val := 3000; end if; n_time_delay_val <= delay_val; write (buf, string'(" N time delay = ")); write (buf, delay_val); writeline (output, buf); else if (scan_chain = "long") then write (buf, string'(" E3 high = ")); write (buf, e3_high_val); write (buf, string'(" , E3 low = ")); write (buf, e3_low_val); write (buf, string'(" , E3 mode = ")); write (buf, e3_mode_val); write (buf, string'(" , E3 time delay = ")); write (buf, e3_time_delay_val); writeline(output, buf); write (buf, string'(" E2 high = ")); write (buf, e2_high_val); write (buf, string'(" , E2 low = ")); write (buf, e2_low_val); write (buf, string'(" , E2 mode = ")); write (buf, e2_mode_val); write (buf, string'(" , E2 time delay = ")); write (buf, e2_time_delay_val); writeline(output, buf); write (buf, string'(" E1 high = ")); write (buf, e1_high_val); write (buf, string'(" , E1 low = ")); write (buf, e1_low_val); write (buf, string'(" , E1 mode = ")); write (buf, e1_mode_val); write (buf, string'(" , E1 time delay = ")); write (buf, e1_time_delay_val); writeline(output, buf); write (buf, string'(" E0 high = ")); write (buf, e0_high_val); write (buf, string'(" , E0 low = ")); write (buf, e0_low_val); write (buf, string'(" , E0 mode = ")); write (buf, e0_mode_val); write (buf, string'(" , E0 time delay = ")); write (buf, e0_time_delay_val); writeline(output, buf); end if; write (buf, string'(" L1 high = ")); write (buf, l1_high_val); write (buf, string'(" , L1 low = ")); write (buf, l1_low_val); write (buf, string'(" , L1 mode = ")); write (buf, l1_mode_val); write (buf, string'(" , L1 time delay = ")); write (buf, l1_time_delay_val); writeline(output, buf); write (buf, string'(" L0 high = ")); write (buf, l0_high_val); write (buf, string'(" , L0 low = ")); write (buf, l0_low_val); write (buf, string'(" , L0 mode = ")); write (buf, l0_mode_val); write (buf, string'(" , L0 time delay = ")); write (buf, l0_time_delay_val); writeline(output, buf); write (buf, string'(" G3 high = ")); write (buf, g3_high_val); write (buf, string'(" , G3 low = ")); write (buf, g3_low_val); write (buf, string'(" , G3 mode = ")); write (buf, g3_mode_val); write (buf, string'(" , G3 time delay = ")); write (buf, g3_time_delay_val); writeline(output, buf); write (buf, string'(" G2 high = ")); write (buf, g2_high_val); write (buf, string'(" , G2 low = ")); write (buf, g2_low_val); write (buf, string'(" , G2 mode = ")); write (buf, g2_mode_val); write (buf, string'(" , G2 time delay = ")); write (buf, g2_time_delay_val); writeline(output, buf); write (buf, string'(" G1 high = ")); write (buf, g1_high_val); write (buf, string'(" , G1 low = ")); write (buf, g1_low_val); write (buf, string'(" , G1 mode = ")); write (buf, g1_mode_val); write (buf, string'(" , G1 time delay = ")); write (buf, g1_time_delay_val); writeline(output, buf); write (buf, string'(" G0 high = ")); write (buf, g0_high_val); write (buf, string'(" , G0 low = ")); write (buf, g0_low_val); write (buf, string'(" , G0 mode = ")); write (buf, g0_mode_val); write (buf, string'(" , G0 time delay = ")); write (buf, g0_time_delay_val); writeline(output, buf); end if; end process; process (schedule_vco, areset_ipd, ena_ipd, pfdena_ipd, refclk, fbclk, inclk0_ipd, inclk1_ipd, clkswitch_ipd, done_with_param_calc) 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 primary_clock_frequency : 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 pll_about_to_lock : boolean := false; 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 schedule_offset : 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_ext_fbk_cntr : 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 init_clks : boolean := true; variable ext_fbk_cntr_modulus : integer := 1; variable pll_is_in_reset : boolean := false; -- clkswitch variables variable other_clock_value : std_logic := '0'; variable other_clock_last_value : std_logic; variable current_clock : string(1 to 6) := primary_clock; 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; begin if (init and done_with_param_calc) then if (pll_type = "fast") then locked_tmp := '1'; end if; m_val <= m_val_tmp; n_val <= n_val_tmp; -- 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; -- merged from separate process if (now = 0 ps) then if (current_clock = "inclk1") then active_clock := '1'; end if; end if; if (clkswitch_ipd'event and clkswitch_ipd = '1') then external_switch := true; end if; -- save the current inclk event value if (inclk0_ipd'event) then if (current_clock /= "inclk0") then other_clock_value := inclk0_ipd; end if; end if; if (inclk1_ipd'event) then if (current_clock /= "inclk1") then other_clock_value := inclk1_ipd; end if; 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'; if (current_clock = "inclk0") then current_clk_is_bad := false; end if; clk1_count := 0; if (clk0_count > 2) then -- no event on other clk for 2 cycles clk1_is_bad := '1'; if (current_clock = "inclk1") then current_clk_is_bad := true; end if; end if; end if; if (inclk1_ipd'event and inclk1_ipd = '1') then clk1_count := clk1_count + 1; clk1_is_bad := '0'; if (current_clock = "inclk1") then current_clk_is_bad := false; end if; clk0_count := 0; if (clk1_count > 2) then -- no event on other clk for 2 cycles clk0_is_bad := '1'; if (current_clock = "inclk0") then current_clk_is_bad := true; end if; end if; end if; -- check if the bad clk is the primary clock if ((primary_clock = "inclk0" and clk0_is_bad = '1') or (primary_clock = "inclk1" and clk1_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 = "inclk0") 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; end if; if (inclk1_ipd'event and current_clock = "inclk1") then if (external_switch) then if (not got_curr_clk_falling_edge_after_clkswitch) then if (inclk1_ipd = '0') then got_curr_clk_falling_edge_after_clkswitch := true; end if; clkin <= transport inclk1_ipd; end if; else clkin <= transport inclk1_ipd; end if; end if; if (inclk0_ipd'event or inclk1_ipd'event) then if ( (other_clock_value = '1') and (other_clock_value /= other_clock_last_value) and (switch_over_on_lossclk = "on") and (enable_switch_over_counter = "on") and (primary_clk_is_bad) ) then switch_over_count := switch_over_count + 1; end if; if ((other_clock_value = '0') and (other_clock_value /= other_clock_last_value)) then if (external_switch and (got_curr_clk_falling_edge_after_clkswitch or current_clk_is_bad)) or (switch_over_on_lossclk = "on" and primary_clk_is_bad and (enable_switch_over_counter = "off" or switch_over_count = switch_over_counter)) then got_curr_clk_falling_edge_after_clkswitch := false; if (current_clock = "inclk0") then current_clock := "inclk1"; else current_clock := "inclk0"; end if; active_clock := not active_clock; switch_over_count := 0; external_switch := false; current_clk_is_bad := false; end if; end if; other_clock_last_value := other_clock_value; end if; -- schedule outputs clkbad(0) <= clk0_is_bad; clkbad(1) <= clk1_is_bad; if (switch_over_on_lossclk = "on" and clkswitch_ipd /= '1') then if (primary_clk_is_bad) then -- assert clkloss clkloss <= '1'; else clkloss <= '0'; end if; else clkloss <= clkswitch_ipd; end if; activeclock <= active_clock; -- end -- clkswitch if (schedule_vco'event) then if (init_clks) then if (primary_clock = "inclk0") then refclk_period := inclk0_input_frequency * n_val * 1 ps; primary_clock_frequency := inclk0_input_frequency * 1 ps; elsif (primary_clock = "inclk1") then refclk_period := inclk1_input_frequency * n_val * 1 ps; primary_clock_frequency := inclk1_input_frequency * 1 ps; end if; 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; end if; -- areset deasserted if (areset_ipd'event and areset_ipd = '0') then if (scandataout_tmp = '1') then sdataout_rst_trig <= transport not sdataout_rst_trig; end if; end if; -- ena was deasserted if (ena_ipd'event and ena_ipd = '0') then assert false report family_name & " PLL was disabled" severity note; end if; if (schedule_vco'event and (areset_ipd = '1' or ena_ipd = '0' or stop_vco)) then if (areset_ipd = '1') then pll_is_in_reset := true; end if; -- 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 locked_tmp := '0'; if (pll_type = "fast") then locked_tmp := '1'; end if; pll_is_locked := false; pll_about_to_lock := 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; schedule_offset := true; vco_val := '0'; vco_period_was_phase_adjusted := false; phase_adjust_was_scheduled := false; elsif ((schedule_vco'event or ena_ipd'event or areset_ipd'event) and areset_ipd = '0' and ena_ipd = '1' 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; pll_is_in_reset := false; end if; -- 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; loop_time_delay := m_time_delay_val; if (operation_mode = "external_feedback") then if (ext_fbk_cntr_mode = "bypass") then ext_fbk_cntr_modulus := 1; else ext_fbk_cntr_modulus := ext_fbk_cntr_high + ext_fbk_cntr_low; end if; loop_xplier := m_val * (ext_fbk_cntr_modulus); loop_ph := ext_fbk_cntr_ph; loop_initial := ext_fbk_cntr_initial - 1 + ((m_initial_val - 1) * (ext_fbk_cntr_modulus)); loop_time_delay := m_time_delay_val + ext_fbk_cntr_delay; end if; -- 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; if (operation_mode = "external_feedback") then pull_back_ext_fbk_cntr := ext_fbk_cntr_delay + (ext_fbk_cntr_initial - 1) * (m_times_vco_period/loop_xplier)/1 ps + fbk_phase; while (pull_back_ext_fbk_cntr > refclk_period/1 ps) loop pull_back_ext_fbk_cntr := pull_back_ext_fbk_cntr - refclk_period/ 1 ps; end loop; pull_back_M := m_time_delay_val + (m_initial_val - 1) * (ext_fbk_cntr_modulus) * ((refclk_period/loop_xplier)/1 ps); while (pull_back_M > refclk_period/1 ps) loop pull_back_M := pull_back_M - refclk_period/ 1 ps; end loop; else pull_back_ext_fbk_cntr := 0; pull_back_M := initial_delay/1 ps + m_time_delay_val + fbk_phase; end if; total_pull_back := pull_back_M + pull_back_ext_fbk_cntr; 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; if (operation_mode = "external_feedback") then fbk_delay := pull_back_M; if (simulation_type = "timing") then fbk_delay := fbk_delay + pll_compensation_delay; end if; ext_fbk_delay <= transport (pull_back_ext_fbk_cntr - fbk_phase) after 1 ps; else 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; 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; -- add offset if (schedule_offset) then sched_time := sched_time + offset; schedule_offset := false; 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; if (sched_time > 0 ps) then schedule_vco <= transport not schedule_vco after sched_time; end if; 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; if (refclk'event and refclk = '1' and areset_ipd = '0') then n_val <= n_val_tmp; 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 ((vco_max /= 0 and vco_min /= 0 and skip_vco = "off" and pfdena_ipd = '1') and (((refclk_period/1 ps)/loop_xplier > vco_max) or ((refclk_period/1 ps)/loop_xplier < vco_min)) ) then if (pll_is_locked) then assert false report " Input clock freq. is not within VCO range : " & family_name & " PLL may lose lock" severity warning; if (inclk_out_of_range) then -- unlock pll_is_locked := false; locked_tmp := '0'; if (pll_type = "fast") then locked_tmp := '1'; end if; pll_about_to_lock := false; cycles_to_lock := 0; assert false report family_name & " PLL lost lock" severity note; first_schedule := true; schedule_offset := true; vco_period_was_phase_adjusted := false; phase_adjust_was_scheduled := false; end if; elsif (not no_warn) then assert false report " Input clock freq. is not within VCO range : " & family_name & " PLL may not lock." severity warning; no_warn := true; end if; inclk_out_of_range := true; else inclk_out_of_range := false; 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; if (fbclk'event and fbclk = '1') then m_val <= transport m_val_tmp after 1 ps; 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') ) 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'; if (pll_type = "fast") then locked_tmp := '1'; end if; assert false report family_name & " PLL lost lock due to loss of input clock" severity note; end if; pll_about_to_lock := false; 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 = valid_lock_multiplier - 1) then pll_about_to_lock := true; end if; if (cycles_to_lock = valid_lock_multiplier) then if (not pll_is_locked) then assert (quiet_period_violation) report family_name & " PLL locked to incoming clock" severity note; end if; pll_is_locked := true; locked_tmp := '1'; if (pll_type = "fast") then locked_tmp := '0'; end if; 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)) <= 5 ps)) 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 = invalid_lock_multiplier) then pll_is_locked := false; locked_tmp := '0'; if (pll_type = "fast") then locked_tmp := '1'; end if; pll_about_to_lock := false; cycles_to_lock := 0; assert (quiet_period_violation) report family_name & " PLL lost lock" severity note; first_schedule := true; schedule_offset := true; vco_period_was_phase_adjusted := false; phase_adjust_was_scheduled := 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 if ( abs(fbclk_time - refclk_time) > 1.5 * refclk_period) then -- input clock may have stopped; do nothing else new_m_times_vco_period := m_times_vco_period + (refclk_period - abs(fbclk_time - refclk_time)); vco_period_was_phase_adjusted := true; end if; 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 locked_tmp := 'X'; 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 (quiet_period_violation or reconfig_err or scanclr_violation or scanclr_clk_violation) then lock <= '0'; if (pll_type = "fast") then lock <= '1'; end if; else lock <= locked_tmp; end if; about_to_lock <= pll_about_to_lock after 1 ps; -- signal to calculate quiet_time sig_refclk_period <= refclk_period; sig_current_clock <= current_clock; -- signals for debugging sig_offset <= offset; sig_refclk_time <= refclk_time; sig_fbclk_time <= fbclk_time; sig_fbclk_period <= fbclk_period; sig_vco_period_was_phase_adjusted <= vco_period_was_phase_adjusted; sig_phase_adjust_was_scheduled <= phase_adjust_was_scheduled; if (stop_vco = true) then sig_stop_vco <= '1'; else sig_stop_vco <= '0'; end if; sig_m_times_vco_period <= m_times_vco_period; sig_new_m_times_vco_period <= new_m_times_vco_period; sig_got_refclk_posedge <= got_refclk_posedge; sig_got_fbclk_posedge <= got_fbclk_posedge; sig_got_second_refclk <= got_second_refclk; end process; process (scanclk_ipd, scanaclr_ipd, scan_data, transfer, sdataout_trig, sdataout_rst_trig) variable j : integer := 0; variable pll_in_quiet_period : boolean := false; variable start_quiet_time : time := 0 ps; variable quiet_time : time := 0 ps; variable scanclr_rising_time : time := 0 ps; variable scanclr_falling_time : time := 0 ps; variable got_first_scanclk_after_scanclr_inactive_edge : boolean := false; variable scan_chain_being_reset : boolean := false; function slowest_clk ( L0 : integer; L0_mode : string(1 to 6); L1 : integer; L1_mode : string(1 to 6); G0 : integer; G0_mode : string(1 to 6); G1 : integer; G1_mode : string(1 to 6); G2 : integer; G2_mode : string(1 to 6); G3 : integer; G3_mode : string(1 to 6); E0 : integer; E0_mode : string(1 to 6); E1 : integer; E1_mode : string(1 to 6); E2 : integer; E2_mode : string(1 to 6); E3 : integer; E3_mode : string(1 to 6); scan_chain : string; 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 (L0_mode /= "bypass" and L0_mode /= " off") then max_modulus := L0; end if; if (L1 > max_modulus and L1_mode /= "bypass" and L1_mode /= " off") then max_modulus := L1; end if; if (G0 > max_modulus and G0_mode /= "bypass" and G0_mode /= " off") then max_modulus := G0; end if; if (G1 > max_modulus and G1_mode /= "bypass" and G1_mode /= " off") then max_modulus := G1; end if; if (G2 > max_modulus and G2_mode /= "bypass" and G2_mode /= " off") then max_modulus := G2; end if; if (G3 > max_modulus and G3_mode /= "bypass" and G3_mode /= " off") then max_modulus := G3; end if; if (scan_chain = "long") then if (E0 > max_modulus and E0_mode /= "bypass" and E0_mode /= " off") then max_modulus := E0; end if; if (E1 > max_modulus and E1_mode /= "bypass" and E1_mode /= " off") then max_modulus := E1; end if; if (E2 > max_modulus and E2_mode /= "bypass" and E2_mode /= " off") then max_modulus := E2; end if; if (E3 > max_modulus and E3_mode /= "bypass" and E3_mode /= " off") then max_modulus := E3; end if; end if; refclk_int := refclk / 1 ps; if (m_mod /= 0) then q_period := ((refclk_int/m_mod) * max_modulus) * 1 ps; end if; return (2*q_period); end slowest_clk; begin if (transfer'event) then if (transfer = '0') then -- clear the chain for i in scan_data'range loop scan_data(i) <= '0'; end loop; end if; elsif (scanaclr_ipd'event and scanaclr_ipd = '1') then -- scanaclr rising scanclr_rising_time := now; scan_chain_being_reset := true; elsif (scanaclr_ipd'event and scanaclr_ipd = '0') then -- scanaclr falling scanclr_falling_time := now; if (scan_chain_being_reset and (now - scanclr_rising_time < TRST)) then scanclr_violation <= true; ASSERT false REPORT "Detected SCANACLR ACTIVE pulse width violation. Required is 5000 ps, actual is "& int2str((now - scanclr_rising_time) / 1 ps) &". The PLL may not function correctly." severity warning; else scanclr_violation <= false; for i in scan_data'range loop scan_data(i) <= '0'; end loop; end if; scan_chain_being_reset := false; got_first_scanclk_after_scanclr_inactive_edge := false; elsif (scanclk_ipd'event and scanclk_ipd = '1' and not got_first_scanclk_after_scanclr_inactive_edge and (now - scanclr_falling_time < TRSTCLK)) then scanclr_clk_violation <= true; got_first_scanclk_after_scanclr_inactive_edge := true; ASSERT false REPORT "Detected SCANACLR INACTIVE time violation before rising edge of SCANCLK. Required is 5000 ps, actual is "& int2str((now - scanclr_falling_time) / 1 ps) &". Reconfiguration may not work." severity warning; elsif (scanclk_ipd'event and scanclk_ipd = '1' and scanaclr_ipd = '0') then if (pll_in_quiet_period and (now - start_quiet_time < quiet_time)) then ASSERT false REPORT "Detected transition on SCANCLK during quiet period. The PLL may not function correctly." severity warning; quiet_period_violation <= true; else pll_in_quiet_period := false; for j in scan_chain_length-1 downto 1 loop scan_data(j) <= scan_data(j-1); end loop; scan_data(0) <= scandata_ipd; end if; if (not got_first_scanclk_after_scanclr_inactive_edge) then got_first_scanclk_after_scanclr_inactive_edge := true; scanclr_clk_violation <= false; end if; elsif (scanclk_ipd'event and scanclk_ipd = '0' and scanaclr_ipd = '0') then if (pll_in_quiet_period and (now - start_quiet_time < quiet_time)) then ASSERT false REPORT "Detected transition on SCANCLK during quiet period. The PLL may not function correctly." severity warning; quiet_period_violation <= true; elsif (scan_data(scan_chain_length-1) = '1') then -- reset violation flag only after another reconfig seq. quiet_period_violation <= false; -- initiate transfer transfer <= '1'; transfer <= transport '0' after 1 ps; scandataout_tmp <= '1'; pll_in_quiet_period := true; start_quiet_time := now; quiet_time := slowest_clk ( l0_high_val+l0_low_val, l0_mode_val, l1_high_val+l1_low_val, l1_mode_val, g0_high_val+g0_low_val, g0_mode_val, g1_high_val+g1_low_val, g1_mode_val, g2_high_val+g2_low_val, g2_mode_val, g3_high_val+g3_low_val, g3_mode_val, e0_high_val+e0_low_val, e0_mode_val, e1_high_val+e1_low_val, e1_mode_val, e2_high_val+e2_low_val, e2_mode_val, e3_high_val+e3_low_val, e3_mode_val, scan_chain, sig_refclk_period, m_val); sdataout_trig <= transport not sdataout_trig after quiet_time; end if; elsif (sdataout_trig'event) then if (areset_ipd = '0') then scandataout_tmp <= transport '0'; end if; elsif (sdataout_rst_trig'event) then scandataout_tmp <= transport '0' after quiet_time; end if; end process; clk0_tmp <= l0_clk when i_clk0_counter = "l0" else l1_clk when i_clk0_counter = "l1" else g0_clk when i_clk0_counter = "g0" else g1_clk when i_clk0_counter = "g1" else g2_clk when i_clk0_counter = "g2" else g3_clk when i_clk0_counter = "g3" else '0'; not_clk0_tmp <= not clk0_tmp; ena0_reg : dffp port map ( D => clkena(0), CLRN => vcc, PRN => vcc, ENA => vcc, CLK => not_clk0_tmp, Q => ena0 ); clk(0) <= ena0 and clk0_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else ena0 and 'X'; clk1_tmp <= l0_clk when i_clk1_counter = "l0" else l1_clk when i_clk1_counter = "l1" else g0_clk when i_clk1_counter = "g0" else g1_clk when i_clk1_counter = "g1" else g2_clk when i_clk1_counter = "g2" else g3_clk when i_clk1_counter = "g3" else '0'; not_clk1_tmp <= not clk1_tmp; ena1_reg : dffp port map ( D => clkena(1), CLRN => vcc, PRN => vcc, ENA => vcc, CLK => not_clk1_tmp, Q => ena1 ); clk(1) <= ena1 and clk1_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else ena1 and 'X'; clk2_tmp <= l0_clk when i_clk2_counter = "l0" else l1_clk when i_clk2_counter = "l1" else g0_clk when i_clk2_counter = "g0" else g1_clk when i_clk2_counter = "g1" else g2_clk when i_clk2_counter = "g2" else g3_clk when i_clk2_counter = "g3" else '0'; not_clk2_tmp <= not clk2_tmp; ena2_reg : dffp port map ( D => clkena(2), CLRN => vcc, PRN => vcc, ENA => vcc, CLK => not_clk2_tmp, Q => ena2 ); clk(2) <= ena2 and clk2_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else ena2 and 'X'; clk3_tmp <= l0_clk when i_clk3_counter = "l0" else l1_clk when i_clk3_counter = "l1" else g0_clk when i_clk3_counter = "g0" else g1_clk when i_clk3_counter = "g1" else g2_clk when i_clk3_counter = "g2" else g3_clk when i_clk3_counter = "g3" else '0'; not_clk3_tmp <= not clk3_tmp; ena3_reg : dffp port map ( D => clkena(3), CLRN => vcc, PRN => vcc, ENA => vcc, CLK => not_clk3_tmp, Q => ena3 ); clk(3) <= ena3 and clk3_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else ena3 and 'X'; clk4_tmp <= l0_clk when i_clk4_counter = "l0" else l1_clk when i_clk4_counter = "l1" else g0_clk when i_clk4_counter = "g0" else g1_clk when i_clk4_counter = "g1" else g2_clk when i_clk4_counter = "g2" else g3_clk when i_clk4_counter = "g3" else '0'; not_clk4_tmp <= not clk4_tmp; ena4_reg : dffp port map ( D => clkena(4), CLRN => vcc, PRN => vcc, ENA => vcc, CLK => not_clk4_tmp, Q => ena4 ); clk(4) <= ena4 and clk4_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else ena4 and 'X'; clk5_tmp <= l0_clk when i_clk5_counter = "l0" else l1_clk when i_clk5_counter = "l1" else g0_clk when i_clk5_counter = "g0" else g1_clk when i_clk5_counter = "g1" else g2_clk when i_clk5_counter = "g2" else g3_clk when i_clk5_counter = "g3" else '0'; not_clk5_tmp <= not clk5_tmp; ena5_reg : dffp port map ( D => clkena(5), CLRN => vcc, PRN => vcc, ENA => vcc, CLK => not_clk5_tmp, Q => ena5 ); clk(5) <= ena5 and clk5_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else ena5 and 'X'; extclk0_tmp <= e0_clk when i_extclk0_counter = "e0" else e1_clk when i_extclk0_counter = "e1" else e2_clk when i_extclk0_counter = "e2" else e3_clk when i_extclk0_counter = "e3" else g0_clk when i_extclk0_counter = "g0" else '0'; not_extclk0_tmp <= not extclk0_tmp; extena0_reg : dffp port map ( D => extclkena(0), CLRN => vcc, PRN => vcc, ENA => vcc, CLK => not_extclk0_tmp, Q => extena0 ); extclk(0) <= extena0 and extclk0_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else extena0 and 'X'; extclk1_tmp <= e0_clk when i_extclk1_counter = "e0" else e1_clk when i_extclk1_counter = "e1" else e2_clk when i_extclk1_counter = "e2" else e3_clk when i_extclk1_counter = "e3" else g0_clk when i_extclk1_counter = "g0" else '0'; not_extclk1_tmp <= not extclk1_tmp; extena1_reg : dffp port map ( D => extclkena(1), CLRN => vcc, PRN => vcc, ENA => vcc, CLK => not_extclk1_tmp, Q => extena1 ); extclk(1) <= extena1 and extclk1_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else extena1 and 'X'; extclk2_tmp <= e0_clk when i_extclk2_counter = "e0" else e1_clk when i_extclk2_counter = "e1" else e2_clk when i_extclk2_counter = "e2" else e3_clk when i_extclk2_counter = "e3" else g0_clk when i_extclk2_counter = "g0" else '0'; not_extclk2_tmp <= not extclk2_tmp; extena2_reg : dffp port map ( D => extclkena(2), CLRN => vcc, PRN => vcc, ENA => vcc, CLK => not_extclk2_tmp, Q => extena2 ); extclk(2) <= extena2 and extclk2_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else extena2 and 'X'; extclk3_tmp <= e0_clk when i_extclk3_counter = "e0" else e1_clk when i_extclk3_counter = "e1" else e2_clk when i_extclk3_counter = "e2" else e3_clk when i_extclk3_counter = "e3" else g0_clk when i_extclk3_counter = "g0" else '0'; not_extclk3_tmp <= not extclk3_tmp; extena3_reg : dffp port map ( D => extclkena(3), CLRN => vcc, PRN => vcc, ENA => vcc, CLK => not_extclk3_tmp, Q => extena3 ); extclk(3) <= extena3 and extclk3_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else extena3 and 'X'; enable0 <= enable0_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else 'X'; enable1 <= enable1_tmp when (areset_ipd = '1' or ena_ipd = '0') or (about_to_lock and (not quiet_period_violation) and (not reconfig_err) and (not scanclr_violation) and (not scanclr_clk_violation)) else 'X'; scandataout <= scandataout_tmp; end vital_pll; -- END ARCHITECTURE VITAL_PLL --/////////////////////////////////////////////////////////////////////////// -- -- Entity Name : arm_m_cntr -- -- Description : Simulation model for the M counter. M is the loop -- feedback counter of the StratixII PLL. -- --/////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; ENTITY arm_m_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 arm_m_cntr; ARCHITECTURE behave of arm_m_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 : arm_n_cntr -- -- Description : Simulation model for the N counter. N is the -- input counter of the StratixII PLL. -- --/////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; ENTITY arm_n_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 arm_n_cntr; ARCHITECTURE behave of arm_n_cntr is begin process (clk, reset) variable count : integer := 1; variable first_rising_edge : boolean := true; variable tmp_cout : std_logic; variable clk_last_valid_value : std_logic; begin if (reset = '1') then count := 1; tmp_cout := '0'; first_rising_edge := true; elsif (clk'event) then if (clk = 'X') then ASSERT FALSE REPORT "Invalid transition to 'X' detected on PLL input clk. This edge will be ignored." severity warning; elsif (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; if (clk /= 'X') then clk_last_valid_value := clk; end if; cout <= transport tmp_cout after time_delay * 1 ps; end process; end behave; --///////////////////////////////////////////////////////////////////////////// -- -- Entity Name : arm_scale_cntr -- -- Description : 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 StratixII PLL. -- --///////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; ENTITY arm_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 arm_scale_cntr; ARCHITECTURE behave of arm_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 : MF_stratixii_pll -- -- Description : Simulation model for the StratixII 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 6 output clocks, each defined by its own set of -- parameters. Locked output (active high) indicates when the -- PLL locks. clkbad, clkloss 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 STD.TEXTIO.all; USE work.MF_pllpack.all; USE work.arm_m_cntr; USE work.arm_n_cntr; USE work.arm_scale_cntr; USE work.dffp; USE work.MF_pll_reg; ENTITY MF_stratixii_pll is GENERIC ( operation_mode : string := "normal"; pll_type : string := "auto"; -- EGPP/FAST/AUTO compensate_clock : string := "clk0"; feedback_source : string := "clk0"; qualify_conf_done : string := "off"; test_input_comp_delay : integer := 0; test_feedback_comp_delay : integer := 0; inclk0_input_frequency : integer := 10000; inclk1_input_frequency : integer := 10000; gate_lock_signal : string := "no"; gate_lock_counter : integer := 1; self_reset_on_gated_loss_lock : string := "off"; valid_lock_multiplier : integer := 1; invalid_lock_multiplier : integer := 5; sim_gate_lock_device_behavior : string := "off"; switch_over_type : string := "auto"; switch_over_on_lossclk : string := "off"; switch_over_on_gated_lock : string := "off"; switch_over_counter : integer := 1; enable_switch_over_counter : string := "on"; bandwidth : integer := 0; bandwidth_type : string := "auto"; down_spread : string := "0.0"; spread_frequency : integer := 0; clk0_output_frequency : integer := 0; clk0_multiply_by : integer := 1; clk0_divide_by : integer := 1; clk0_phase_shift : string := "0"; clk0_duty_cycle : integer := 50; clk1_output_frequency : integer := 0; clk1_multiply_by : integer := 1; clk1_divide_by : integer := 1; clk1_phase_shift : string := "0"; clk1_duty_cycle : integer := 50; clk2_output_frequency : integer := 0; clk2_multiply_by : integer := 1; clk2_divide_by : integer := 1; clk2_phase_shift : string := "0"; clk2_duty_cycle : integer := 50; clk3_output_frequency : integer := 0; clk3_multiply_by : integer := 1; clk3_divide_by : integer := 1; clk3_phase_shift : string := "0"; clk3_duty_cycle : integer := 50; clk4_output_frequency : integer := 0; clk4_multiply_by : integer := 1; clk4_divide_by : integer := 1; clk4_phase_shift : string := "0"; clk4_duty_cycle : integer := 50; clk5_output_frequency : integer := 0; clk5_multiply_by : integer := 1; clk5_divide_by : integer := 1; clk5_phase_shift : string := "0"; clk5_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; m2 : integer := 1; n2 : integer := 1; ss : integer := 0; 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; c5_high : integer := 1; c5_low : integer := 1; c5_initial : integer := 1; c5_mode : string := "bypass"; c5_ph : integer := 0; m_ph : integer := 0; clk0_counter : string := "c0"; clk1_counter : string := "c1"; clk2_counter : string := "c2"; clk3_counter : string := "c3"; clk4_counter : string := "c4"; clk5_counter : string := "c5"; c1_use_casc_in : string := "off"; c2_use_casc_in : string := "off"; c3_use_casc_in : string := "off"; c4_use_casc_in : string := "off"; c5_use_casc_in : string := "off"; m_test_source : integer := 5; c0_test_source : integer := 5; c1_test_source : integer := 5; c2_test_source : integer := 5; c3_test_source : integer := 5; c4_test_source : integer := 5; c5_test_source : integer := 5; -- LVDS mode parameters enable0_counter : string := "c0"; enable1_counter : string := "c1"; sclkout0_phase_shift : string := "0"; sclkout1_phase_shift : string := "0"; charge_pump_current : integer := 52; loop_filter_r : string := " 1.000000"; loop_filter_c : integer := 16; common_rx_tx : string := "off"; use_vco_bypass : string := "false"; use_dc_coupling : string := "false"; pll_compensation_delay : integer := 0; simulation_type : string := "functional"; -- Simulation only generics family_name : string := "StratixII"; 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"; clk5_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"; clk5_use_even_counter_value : string := "off"; vco_multiply_by : integer := 0; vco_divide_by : integer := 0; scan_chain_mif_file : string := ""; vco_post_scale : integer := 1 ); PORT ( inclk : in std_logic_vector(1 downto 0); fbin : in std_logic := '0'; ena : in std_logic := '1'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; scanread : in std_logic := '0'; scanwrite : in std_logic := '0'; scandata : in std_logic := '0'; scanclk : in std_logic := '0'; testin : in std_logic_vector(3 downto 0) := "0000"; clk : out std_logic_vector(5 downto 0); clkbad : out std_logic_vector(1 downto 0); activeclock : out std_logic; locked : out std_logic; clkloss : out std_logic; scandataout : out std_logic; scandone : out std_logic; testupout : out std_logic; testdownout : out std_logic; -- lvds specific ports enable0 : out std_logic; enable1 : out std_logic; sclkout : out std_logic_vector(1 downto 0) ); END MF_stratixii_pll; ARCHITECTURE vital_pll of MF_stratixii_pll is 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; -- internal advanced parameter signals signal i_vco_min : integer; signal i_vco_max : integer; signal i_vco_center : integer; signal i_pfd_min : integer; signal i_pfd_max : integer; signal c_ph_val : int_array(0 to 5) := (OTHERS => 0); signal c_high_val : int_array(0 to 5) := (OTHERS => 1); signal c_low_val : int_array(0 to 5) := (OTHERS => 1); signal c_initial_val : int_array(0 to 5) := (OTHERS => 1); signal c_mode_val : str_array(0 to 5); -- old values signal c_high_val_old : int_array(0 to 5) := (OTHERS => 1); signal c_low_val_old : int_array(0 to 5) := (OTHERS => 1); signal c_ph_val_old : int_array(0 to 5) := (OTHERS => 0); signal c_mode_val_old : str_array(0 to 5); -- hold registers signal c_high_val_hold : int_array(0 to 5) := (OTHERS => 1); signal c_low_val_hold : int_array(0 to 5) := (OTHERS => 1); signal c_ph_val_hold : int_array(0 to 5) := (OTHERS => 0); signal c_mode_val_hold : str_array(0 to 5); -- temp registers signal sig_c_ph_val_tmp : int_array(0 to 5) := (OTHERS => 0); signal sig_c_low_val_tmp : int_array(0 to 5) := (OTHERS => 1); signal sig_c_hi_val_tmp : int_array(0 to 5) := (OTHERS => 1); signal c_ph_val_orig : int_array(0 to 5) := (OTHERS => 0); --signal i_clk5_counter : string(1 to 2) := "c5"; --signal i_clk4_counter : string(1 to 2) := "c4"; --signal i_clk3_counter : string(1 to 2) := "c3"; --signal i_clk2_counter : string(1 to 2) := "c2"; --signal i_clk1_counter : string(1 to 2) := "c1"; --signal i_clk0_counter : string(1 to 2) := "c0"; signal i_clk5_counter : integer := 5; 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 GPP_SCAN_CHAIN : integer := 174; CONSTANT FAST_SCAN_CHAIN : integer := 75; CONSTANT GATE_LOCK_CYCLES : integer := 7; CONSTANT cntrs : str_array(5 downto 0) := (" C5", " 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) := (57, 16, 36, 5); CONSTANT fpll_loop_filter_c_arr : int_array(0 to 3) := (18, 13, 8, 2); CONSTANT charge_pump_curr_arr : int_array(0 to 15) := (6, 12, 30, 36, 52, 57, 72, 77, 92, 96, 110, 114, 127, 131, 144, 148); CONSTANT loop_filter_r_arr : str_array1(0 to 39) := (" 1.000000", " 1.500000", " 2.000000", " 2.500000", " 3.000000", " 3.500000", " 4.000000", " 4.500000", " 5.000000", " 5.500000", " 6.000000", " 6.500000", " 7.000000", " 7.500000", " 8.000000", " 8.500000", " 9.000000", " 9.500000", "10.000000", "10.500000", "11.000000", "11.500000", "12.000000", "12.500000", "13.000000", "13.500000", "14.000000", "14.500000", "15.000000", "15.500000", "16.000000", "16.500000", "17.000000", "17.500000", "18.000000", "18.500000", "19.000000", "19.500000", "20.000000", "20.500000"); -- signals signal vcc : std_logic := '1'; signal fbclk : std_logic; signal refclk : std_logic; signal c_clk : std_logic_array(0 to 5); signal vco_out : std_logic_vector(7 downto 0) := (OTHERS => '0'); signal vco_tap : std_logic_vector(7 downto 0) := (OTHERS => '0'); signal vco_out_last_value : std_logic_vector(7 downto 0); signal vco_tap_last_value : std_logic_vector(7 downto 0); -- signals to assign values to counter params signal m_val : int_array(0 to 1) := (OTHERS => 1); signal n_val : int_array(0 to 1) := (OTHERS => 1); signal m_ph_val : integer := 0; signal m_initial_val : integer := m_initial; signal m_mode_val : str_array(0 to 1) := (OTHERS => " "); signal n_mode_val : str_array(0 to 1) := (OTHERS => " "); signal lfc_val : integer := 0; signal cp_curr_val : integer := 0; signal lfr_val : string(1 to 9) := " "; -- old values signal m_val_old : int_array(0 to 1) := (OTHERS => 1); signal n_val_old : int_array(0 to 1) := (OTHERS => 1); signal m_mode_val_old : str_array(0 to 1) := (OTHERS => " "); signal n_mode_val_old : str_array(0 to 1) := (OTHERS => " "); signal m_ph_val_old : integer := 0; signal lfc_old : integer := 0; signal cp_curr_old : integer := 0; signal lfr_old : string(1 to 9) := " "; signal num_output_cntrs : integer := 6; signal scan_data : std_logic_vector(173 downto 0) := (OTHERS => '0'); 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 clk5_tmp : std_logic; signal sclkout0_tmp : std_logic; signal sclkout1_tmp : std_logic; signal clkin : std_logic := '0'; signal gate_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_c5 : 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 ena_ipd : std_logic; signal pfdena_ipd : std_logic; signal areset_ipd : std_logic; signal fbin_ipd : std_logic; signal scanclk_ipd : std_logic; signal scanread_ipd : std_logic; signal scanwrite_ipd : std_logic; signal scandata_ipd : std_logic; signal clkswitch_ipd : std_logic; -- registered signals signal scanread_reg : std_logic := '0'; signal scanwrite_reg : std_logic := '0'; signal scanwrite_enabled : std_logic := '0'; signal gated_scanclk : std_logic := '1'; signal inclk_c0_dly1 : std_logic := '0'; signal inclk_c0_dly2 : std_logic := '0'; signal inclk_c0_dly3 : std_logic := '0'; signal inclk_c0_dly4 : std_logic := '0'; signal inclk_c0_dly5 : std_logic := '0'; signal inclk_c0_dly6 : std_logic := '0'; signal inclk_c1_dly1 : std_logic := '0'; signal inclk_c1_dly2 : std_logic := '0'; signal inclk_c1_dly3 : std_logic := '0'; signal inclk_c1_dly4 : std_logic := '0'; signal inclk_c1_dly5 : std_logic := '0'; signal inclk_c1_dly6 : std_logic := '0'; 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 ext_fbk_cntr_high : integer := 0; signal ext_fbk_cntr_low : integer := 0; signal ext_fbk_cntr_ph : integer := 0; signal ext_fbk_cntr_initial : integer := 1; signal ext_fbk_cntr : string(1 to 2) := "c0"; signal ext_fbk_cntr_mode : string(1 to 6) := "bypass"; signal ext_fbk_cntr_index : integer := 0; signal enable0_tmp : std_logic := '0'; signal enable1_tmp : std_logic := '0'; signal reset_low : std_logic := '0'; signal scandataout_tmp : std_logic := '0'; signal scandone_tmp : 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 inclk_c_from_vco : std_logic_array(0 to 5); signal inclk_m_from_vco : std_logic; signal inclk_sclkout0_from_vco : std_logic; signal inclk_sclkout1_from_vco : std_logic; --signal tap0_is_active : boolean := true; signal sig_quiet_time : time := 0 ps; signal sig_slowest_clk_old : time := 0 ps; signal sig_slowest_clk_new : time := 0 ps; signal sig_m_val_tmp : int_array(0 to 1) := (OTHERS => 1); COMPONENT arm_m_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 arm_n_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 arm_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 dffp 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 MF_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 inclk0_ipd <= inclk(0); inclk1_ipd <= inclk(1); areset_ipd <= areset; ena_ipd <= ena; fbin_ipd <= fbin; pfdena_ipd <= pfdena; scanclk_ipd <= scanclk; scanread_ipd <= scanread; scandata_ipd <= scandata; scanwrite_ipd <= scanwrite; clkswitch_ipd <= clkswitch; end block; inclk_m <= clkin when m_test_source = 0 else clk0_tmp when operation_mode = "external_feedback" and feedback_source = "clk0" else clk1_tmp when operation_mode = "external_feedback" and feedback_source = "clk1" else clk2_tmp when operation_mode = "external_feedback" and feedback_source = "clk2" else clk3_tmp when operation_mode = "external_feedback" and feedback_source = "clk3" else clk4_tmp when operation_mode = "external_feedback" and feedback_source = "clk4" else clk5_tmp when operation_mode = "external_feedback" and feedback_source = "clk5" else inclk_m_from_vco; ext_fbk_cntr_high <= c_high_val(ext_fbk_cntr_index); ext_fbk_cntr_low <= c_low_val(ext_fbk_cntr_index); ext_fbk_cntr_ph <= c_ph_val(ext_fbk_cntr_index); ext_fbk_cntr_initial <= c_initial_val(ext_fbk_cntr_index); ext_fbk_cntr_mode <= c_mode_val(ext_fbk_cntr_index); areset_ena_sig <= areset_ipd or (not ena_ipd) or sig_stop_vco; pll_in_test_mode <= true when m_test_source /= 5 or c0_test_source /= 5 or c1_test_source /= 5 or c2_test_source /= 5 or c3_test_source /= 5 or c4_test_source /= 5 or c5_test_source /= 5 else false; m1 : arm_m_cntr port map ( clk => inclk_m, reset => areset_ena_sig, cout => fbclk, initial_value => m_initial_val, modulus => m_val(0), time_delay => m_delay ); -- add delta delay to inclk1 to ensure inclk0 and inclk1 are processed -- in different simulation deltas. inclk1_tmp <= inclk1_ipd; 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; 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 current_clock := 1; active_clock := '1'; clkin <= transport inclk1_tmp; elsif (clkswitch_ipd'event and clkswitch_ipd = '0') then current_clock := 0; active_clock := '0'; clkin <= transport inclk0_ipd; 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 switch_over_on_lossclk = "on" 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 (switch_over_on_lossclk = "on" and 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 (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; end if; end if; end if; -- schedule outputs clkbad(0) <= clk0_is_bad; clkbad(1) <= clk1_is_bad; if (switch_over_on_lossclk = "on" and clkswitch_ipd /= '1') then if (primary_clk_is_bad) then -- assert clkloss clkloss <= '1'; else clkloss <= '0'; end if; else clkloss <= clkswitch_ipd; end if; activeclock <= active_clock; end process; process (inclk_sclkout0_from_vco) begin sclkout0_tmp <= inclk_sclkout0_from_vco; end process; process (inclk_sclkout1_from_vco) begin sclkout1_tmp <= inclk_sclkout1_from_vco; end process; n1 : arm_n_cntr port map ( clk => clkin, reset => areset_ipd, cout => refclk, initial_value => n_val(0), modulus => n_val(0)); inclk_c0 <= clkin when c0_test_source = 0 else refclk when c0_test_source = 1 else inclk_c_from_vco(0); c0 : arm_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 <= clkin when c1_test_source = 0 else fbclk when c1_test_source = 2 else c_clk(0) when c1_use_casc_in = "on" else inclk_c_from_vco(1); c1 : arm_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 <= clkin when c2_test_source = 0 else c_clk(1) when c2_use_casc_in = "on" else inclk_c_from_vco(2); c2 : arm_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 <= clkin when c3_test_source = 0 else c_clk(2) when c3_use_casc_in = "on" else inclk_c_from_vco(3); c3 : arm_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 <= '0' when (pll_type = "fast") else clkin when (c4_test_source = 0) else c_clk(3) when (c4_use_casc_in = "on") else inclk_c_from_vco(4); c4 : arm_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)); inclk_c5 <= '0' when (pll_type = "fast") else clkin when c5_test_source = 0 else c_clk(4) when c5_use_casc_in = "on" else inclk_c_from_vco(5); c5 : arm_scale_cntr port map ( clk => inclk_c5, reset => areset_ena_sig, cout => c_clk(5), initial => c_initial_val(5), high => c_high_val(5), low => c_low_val(5), mode => c_mode_val(5), ph_tap => c_ph_val(5)); inclk_c0_dly1 <= inclk_c0 when (pll_type = "fast" or pll_type = "lvds") else '0'; inclk_c0_dly2 <= inclk_c0_dly1; inclk_c0_dly3 <= inclk_c0_dly2; inclk_c0_dly4 <= inclk_c0_dly3; inclk_c0_dly5 <= inclk_c0_dly4; inclk_c0_dly6 <= inclk_c0_dly5; inclk_c1_dly1 <= inclk_c1 when (pll_type = "fast" or pll_type = "lvds") else '0'; inclk_c1_dly2 <= inclk_c1_dly1; inclk_c1_dly3 <= inclk_c1_dly2; inclk_c1_dly4 <= inclk_c1_dly3; inclk_c1_dly5 <= inclk_c1_dly4; inclk_c1_dly6 <= inclk_c1_dly5; process(inclk_c0_dly6, inclk_c1_dly6, areset_ipd, ena_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 ena_ipd = '0' 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_dly6'event and inclk_c0_dly6 = '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_dly6'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_dly6'event and inclk_c0_dly6 = '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_dly6'event and inclk_c1_dly6 = '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_dly6'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_dly6'event and inclk_c1_dly6 = '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; if (enable0_counter = "c0") then enable0_tmp <= c0_tmp; elsif (enable0_counter = "c1") then enable0_tmp <= c1_tmp; else enable0_tmp <= '0'; end if; if (enable1_counter = "c0") then enable1_tmp <= c0_tmp; elsif (enable1_counter = "c1") then enable1_tmp <= c1_tmp; else enable1_tmp <= '0'; end if; end process; glocked_cntr : process(clkin, ena_ipd, areset_ipd) variable count : integer := 0; variable output : std_logic := '0'; begin if (areset_ipd = '1') then count := 0; output := '0'; elsif (clkin'event and clkin = '1') then if (ena_ipd = '1') then count := count + 1; if (sim_gate_lock_device_behavior = "on") then if (count = gate_lock_counter) then output := '1'; end if; elsif (count = GATE_LOCK_CYCLES) then output := '1'; end if; end if; end if; gate_locked <= output; end process; locked <= gate_locked and lock when gate_lock_signal = "yes" 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 family_name & " 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(0)); write (buf, string'(" ( ")); write (buf, n_val_old(0)); write (buf, string'(" )")); writeline (output, buf); write (buf, string'(" M modulus = ")); write (buf, m_val(0)); write (buf, string'(" ( ")); write (buf, m_val_old(0)); 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); if (ss > 0) then write (buf, string'(" M2 modulus = ")); write (buf, m_val(1)); write (buf, string'(" ( ")); write (buf, m_val_old(1)); write (buf, string'(" )")); writeline (output, buf); write (buf, string'(" N2 modulus = ")); write (buf, n_val(1)); write (buf, string'(" ( ")); write (buf, n_val_old(1)); write (buf, string'(" )")); writeline (output, buf); end if; for i in 0 to (num_output_cntrs-1) loop 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, sig_c_low_val_tmp(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; 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); 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; process (scanwrite_enabled, c_clk(0), c_clk(1), c_clk(2), c_clk(3), c_clk(4), c_clk(5), vco_tap, fbclk, scanclk_ipd, gated_scanclk) 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 n_fast : std_logic_vector(1 downto 0); variable c_high_val_tmp : int_array(0 to 5) := (OTHERS => 1); variable c_low_val_tmp : int_array(0 to 5) := (OTHERS => 1); variable c_ph_val_tmp : int_array(0 to 5) := (OTHERS => 0); variable c_mode_val_tmp : str_array(0 to 5); variable m_ph_val_tmp : integer := 0; variable m_val_tmp : int_array(0 to 1) := (OTHERS => 1); 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; variable c5_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 i_clk5_mult_by : integer := 1; variable i_clk5_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_m2 : integer; variable i_n2 : integer; variable i_ss : integer; variable i_c_high : int_array(0 to 5); variable i_c_low : int_array(0 to 5); variable i_c_initial : int_array(0 to 5); variable i_c_ph : int_array(0 to 5); variable i_c_mode : str_array(0 to 5); variable i_m_ph : integer; variable output_count : integer; variable new_divisor : integer; variable clk0_cntr : string(1 to 2) := "c0"; variable clk1_cntr : string(1 to 2) := "c1"; variable clk2_cntr : string(1 to 2) := "c2"; variable clk3_cntr : string(1 to 2) := "c3"; variable clk4_cntr : string(1 to 2) := "c4"; variable clk5_cntr : string(1 to 2) := "c5"; 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 tmp_scan_data : std_logic_vector(173 downto 0) := (OTHERS => '0'); variable m_lo, m_hi : std_logic_vector(4 downto 0); variable j : integer := 0; variable scanread_active_edge : time := 0 ps; variable got_first_scanclk : boolean := false; variable got_first_gated_scanclk : boolean := false; variable scanclk_last_rising_edge : time := 0 ps; variable scanclk_period : time := 0 ps; variable current_scan_data : std_logic_vector(173 downto 0) := (OTHERS => '0'); variable index : integer := 0; 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; 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); 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; refclk_int := refclk / 1 ps; if (m_mod /= 0) then if (refclk_int > (refclk_int * max_modulus / m_mod)) then q_period := refclk_int * 1 ps; else q_period := (refclk_int * max_modulus / m_mod) * 1 ps; end if; 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_index (arg:string) return integer is variable index : integer := 0; begin if (arg(2) = '0') then index := 0; elsif (arg(2) = '1') then index := 1; elsif (arg(2) = '2') then index := 2; elsif (arg(2) = '3') then index := 3; elsif (arg(2) = '4') then index := 4; else index := 5; end if; return index; end extract_cntr_index; begin if (init) then if (m = 0) then clk5_cntr := "c5"; clk4_cntr := "c4"; clk3_cntr := "c3"; clk2_cntr := "c2"; clk1_cntr := "c1"; clk0_cntr := "c0"; else clk5_cntr := clk5_counter; clk4_cntr := clk4_counter; clk3_cntr := clk3_counter; clk2_cntr := clk2_counter; clk1_cntr := clk1_counter; clk0_cntr := clk0_counter; end if; if (operation_mode = "external_feedback") then if (feedback_source = "clk0") then fbk_cntr := clk0_cntr; elsif (feedback_source = "clk1") then fbk_cntr := clk1_cntr; elsif (feedback_source = "clk2") then fbk_cntr := clk2_cntr; elsif (feedback_source = "clk3") then fbk_cntr := clk3_cntr; elsif (feedback_source = "clk4") then fbk_cntr := clk4_cntr; elsif (feedback_source = "clk5") then fbk_cntr := clk5_cntr; else fbk_cntr := "c0"; end if; if (fbk_cntr = "c0") then fbk_cntr_index := 0; elsif (fbk_cntr = "c1") then fbk_cntr_index := 1; elsif (fbk_cntr = "c2") then fbk_cntr_index := 2; elsif (fbk_cntr = "c3") then fbk_cntr_index := 3; elsif (fbk_cntr = "c4") then fbk_cntr_index := 4; elsif (fbk_cntr = "c5") then fbk_cntr_index := 5; end if; ext_fbk_cntr <= fbk_cntr; ext_fbk_cntr_index <= fbk_cntr_index; end if; 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); i_clk5_counter <= extract_cntr_index(clk5_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 := 500; -- 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); find_simple_integer_fraction(clk5_multiply_by, clk5_divide_by, max_d_value, i_clk5_mult_by, i_clk5_div_by); if (((pll_type = "fast") or (pll_type = "lvds")) 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; i_m := lcm (i_clk0_mult_by, i_clk1_mult_by, i_clk2_mult_by, i_clk3_mult_by, i_clk4_mult_by, i_clk5_mult_by, 1, 1, 1, 1, inclk0_input_frequency); 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), str2int(clk5_phase_shift), 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_ph(5) := counter_ph(get_phase_degree(ph_adjust(str2int(clk5_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_high(5) := counter_high(output_counter_value(i_clk5_div_by, i_clk5_mult_by, i_m, i_n), clk5_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_c_low(5) := counter_low(output_counter_value(i_clk5_div_by, i_clk5_mult_by, i_m, i_n), clk5_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_initial(5) := counter_initial(get_phase_degree(ph_adjust(str2int(clk5_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)); i_c_mode(5) := counter_mode(clk5_duty_cycle, output_counter_value(i_clk5_div_by, i_clk5_mult_by, i_m, i_n)); -- in external feedback mode, need to adjust M value to take -- into consideration the external feedback counter value if(operation_mode = "external_feedback") then -- if there is a negative phase shift, m_initial can -- only be 1 if (max_neg_abs > 0) then i_m_initial := 1; end if; -- calculate the feedback counter multiplier if (i_c_mode(fbk_cntr_index) = "bypass") then output_count := 1; else output_count := i_c_high(fbk_cntr_index) + i_c_low(fbk_cntr_index); end if; new_divisor := gcd(i_m, output_count); i_m := i_m / new_divisor; i_n := output_count / new_divisor; end if; 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_ph(5) := c5_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_high(5) := c5_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_low(5) := c5_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_initial(5) := c5_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); i_c_mode(5) := translate_string(c5_mode); end if; -- user to advanced conversion. m_initial_val <= i_m_initial; n_val(0) <= i_n; m_val(0) <= i_m; m_val(1) <= m2; n_val(1) <= n2; if (i_m = 1) then m_mode_val(0) <= "bypass"; else m_mode_val(0) <= " "; end if; if (m2 = 1) then m_mode_val(1) <= "bypass"; end if; if (i_n = 1) then n_mode_val(0) <= "bypass"; end if; if (n2 = 1) then n_mode_val(1) <= "bypass"; end if; m_ph_val <= i_m_ph; m_ph_val_tmp := i_m_ph; m_val_tmp := m_val; for i in 0 to 5 loop if (i_c_mode(i) = "bypass") then if (pll_type = "fast" or pll_type = "lvds") 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_low_val_tmp(i) := i_c_low(i); c_mode_val_tmp(i) := i_c_mode(i); c_ph_val_tmp(i) := i_c_ph(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; lfc_val <= loop_filter_c; lfr_val <= loop_filter_r; cp_curr_val <= charge_pump_current; if (pll_type = "fast") then scan_chain_length := FAST_SCAN_CHAIN; end if; -- initialize the scan_chain contents -- CP/LF bits scan_data(11 downto 0) <= "000000000000"; for i in 0 to 3 loop if (pll_type = "fast" or pll_type = "lvds") then if (fpll_loop_filter_c_arr(i) = loop_filter_c) then scan_data(11 downto 10) <= int2bin(i, 2); end if; else if (loop_filter_c_arr(i) = loop_filter_c) then scan_data(11 downto 10) <= int2bin(i, 2); end if; end if; end loop; for i in 0 to 15 loop if (charge_pump_curr_arr(i) = charge_pump_current) then scan_data(3 downto 0) <= int2bin(i, 4); end if; end loop; for i in 0 to 39 loop if (loop_filter_r_arr(i) = loop_filter_r) then if (i >= 16 and i <= 23) then scan_data(9 downto 4) <= int2bin((i+8), 6); elsif (i >= 24 and i <= 31) then scan_data(9 downto 4) <= int2bin((i+16), 6); elsif (i >= 32) then scan_data(9 downto 4) <= int2bin((i+24), 6); else scan_data(9 downto 4) <= int2bin(i, 6); end if; end if; end loop; if (pll_type = "fast" or pll_type = "lvds") then scan_data(21 downto 12) <= "0000000000"; -- M, C3-C0 ph -- C0-C3 high scan_data(25 downto 22) <= int2bin(i_c_high(0), 4); scan_data(35 downto 32) <= int2bin(i_c_high(1), 4); scan_data(45 downto 42) <= int2bin(i_c_high(2), 4); scan_data(55 downto 52) <= int2bin(i_c_high(3), 4); -- C0-C3 low scan_data(30 downto 27) <= int2bin(i_c_low(0), 4); scan_data(40 downto 37) <= int2bin(i_c_low(1), 4); scan_data(50 downto 47) <= int2bin(i_c_low(2), 4); scan_data(60 downto 57) <= int2bin(i_c_low(3), 4); -- C0-C3 mode for i in 0 to 3 loop if (i_c_mode(i) = " off" or i_c_mode(i) = "bypass") then scan_data(26 + (10*i)) <= '1'; if (i_c_mode(i) = " off") then scan_data(31 + (10*i)) <= '1'; else scan_data(31 + (10*i)) <= '0'; end if; else scan_data(26 + (10*i)) <= '0'; if (i_c_mode(i) = " odd") then scan_data(31 + (10*i)) <= '1'; else scan_data(31 + (10*i)) <= '0'; end if; end if; end loop; -- M if (i_m = 1) then scan_data(66) <= '1'; scan_data(71) <= '0'; scan_data(65 downto 62) <= "0000"; scan_data(70 downto 67) <= "0000"; else scan_data(66) <= '0'; -- set BYPASS bit to 0 scan_data(70 downto 67) <= int2bin(i_m/2, 4); -- set M low if (i_m rem 2 = 0) then -- M is an even no. : set M high = low, -- set odd/even bit to 0 scan_data(65 downto 62) <= int2bin(i_m/2, 4); scan_data(71) <= '0'; else -- M is odd : M high = low + 1 scan_data(65 downto 62) <= int2bin((i_m/2) + 1, 4); scan_data(71) <= '1'; end if; end if; -- N scan_data(73 downto 72) <= int2bin(i_n, 2); if (i_n = 1) then scan_data(74) <= '1'; scan_data(73 downto 72) <= "00"; end if; else -- PLL type is auto or enhanced scan_data(25 downto 12) <= "00000000000000"; -- M, C5-C0 ph -- C0-C5 high scan_data(123 downto 116) <= int2bin(i_c_high(0), 8); scan_data(105 downto 98) <= int2bin(i_c_high(1), 8); scan_data(87 downto 80) <= int2bin(i_c_high(2), 8); scan_data(69 downto 62) <= int2bin(i_c_high(3), 8); scan_data(51 downto 44) <= int2bin(i_c_high(4), 8); scan_data(33 downto 26) <= int2bin(i_c_high(5), 8); -- C0-C5 low scan_data(132 downto 125) <= int2bin(i_c_low(0), 8); scan_data(114 downto 107) <= int2bin(i_c_low(1), 8); scan_data(96 downto 89) <= int2bin(i_c_low(2), 8); scan_data(78 downto 71) <= int2bin(i_c_low(3), 8); scan_data(60 downto 53) <= int2bin(i_c_low(4), 8); scan_data(42 downto 35) <= int2bin(i_c_low(5), 8); -- C0-C5 mode for i in 0 to 5 loop if (i_c_mode(i) = " off" or i_c_mode(i) = "bypass") then scan_data(124 - (18*i)) <= '1'; if (i_c_mode(i) = " off") then scan_data(133 - (18*i)) <= '1'; else scan_data(133 - (18*i)) <= '0'; end if; else scan_data(124 - (18*i)) <= '0'; if (i_c_mode(i) = " odd") then scan_data(133 - (18*i)) <= '1'; else scan_data(133 - (18*i)) <= '0'; end if; end if; end loop; -- M/M2 scan_data(142 downto 134) <= int2bin(i_m, 9); scan_data(143) <= '0'; scan_data(152 downto 144) <= int2bin(m2, 9); scan_data(153) <= '0'; if (i_m = 1) then scan_data(143) <= '1'; scan_data(142 downto 134) <= "000000000"; end if; if (m2 = 1) then scan_data(153) <= '1'; scan_data(152 downto 144) <= "000000000"; end if; -- N/N2 scan_data(162 downto 154) <= int2bin(i_n, 9); scan_data(172 downto 164) <= int2bin(n2, 9); if (i_n = 1) then scan_data(163) <= '1'; scan_data(162 downto 154) <= "000000000"; end if; if (n2 = 1) then scan_data(173) <= '1'; scan_data(172 downto 164) <= "000000000"; end if; end if; if (pll_type = "fast" or pll_type = "lvds") then num_output_cntrs <= 4; else num_output_cntrs <= 6; end if; init := false; elsif (scanwrite_enabled'event and scanwrite_enabled = '0') then -- falling edge : deassert scandone scandone_tmp <= transport '0' after (1.5 * scanclk_period); 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; c5_rising_edge_transfer_done := false; elsif (scanwrite_enabled'event and scanwrite_enabled = '1') then ASSERT false REPORT "PLL Reprogramming Initiated" severity note; reconfig_err <= false; -- make temporary copy of scan_data for processing tmp_scan_data := scan_data; -- save old values lfc_old <= lfc_val; lfr_old <= lfr_val; cp_curr_old <= cp_curr_val; -- CP -- Bits 0-3 : all values are legal cp_curr_val <= charge_pump_curr_arr(alt_conv_integer(scan_data(3 downto 0))); -- LF Resistance : bits 4-9 -- values from 010000 - 010111, 100000 - 100111, -- 110000 - 110111 are illegal lfr_tmp := tmp_scan_data(9 downto 4); lfr_int := alt_conv_integer(lfr_tmp); if (((lfr_int >= 16) and (lfr_int <= 23)) or ((lfr_int >= 32) and (lfr_int <= 39)) or ((lfr_int >= 48) and (lfr_int <= 55))) then reconfig_err <= true; ASSERT false REPORT "Illegal bit settings for Loop Filter Resistance. Legal bit values range from 000000-001111, 011000-011111, 101000-101111 and 111000-111111. Reconfiguration may not work." severity warning; else if (lfr_int >= 56) then lfr_int := lfr_int - 24; elsif ((lfr_int >= 40) and (lfr_int <= 47)) then lfr_int := lfr_int - 16; elsif ((lfr_int >= 24) and (lfr_int <= 31)) then lfr_int := lfr_int - 8; end if; lfr_val <= loop_filter_r_arr(lfr_int); end if; -- LF Capacitance : bits 10,11 : all values are legal lfc_tmp := scan_data(11 downto 10); if (pll_type = "fast" or pll_type = "lvds") then lfc_val <= fpll_loop_filter_c_arr(alt_conv_integer(lfc_tmp)); else lfc_val <= loop_filter_c_arr(alt_conv_integer(lfc_tmp)); end if; -- cntrs c0-c5 -- save old values for display info. m_val_old <= m_val; n_val_old <= n_val; m_mode_val_old <= m_mode_val; n_mode_val_old <= n_mode_val; m_ph_val_old <= m_ph_val; c_high_val_old <= c_high_val; c_low_val_old <= c_low_val; c_ph_val_old <= c_ph_val; c_mode_val_old <= c_mode_val; -- first the M counter phase : bit order same for fast and GPP if (scan_data(12) = '0') then -- do nothing elsif (scan_data(12) = '1' and scan_data(13) = '1') then m_ph_val_tmp := m_ph_val_tmp + 1; if (m_ph_val_tmp > 7) then m_ph_val_tmp := 0; end if; elsif (scan_data(12) = '1' and scan_data(13) = '0') then m_ph_val_tmp := m_ph_val_tmp - 1; if (m_ph_val_tmp < 0) then m_ph_val_tmp := 7; end if; else reconfig_err <= true; ASSERT false REPORT "Illegal values for M counter phase tap. Reconfiguration may not work." severity warning; end if; -- read the fast PLL bits if (pll_type = "fast" or pll_type = "lvds") then -- C3-C0 phase bits for i in 3 downto 0 loop start_bit := 14 + ((3-i)*2); if (tmp_scan_data(start_bit) = '0') then -- do nothing elsif (tmp_scan_data(start_bit) = '1') then if (tmp_scan_data(start_bit + 1) = '1') then c_ph_val_tmp(i) := c_ph_val_tmp(i) + 1; if (c_ph_val_tmp(i) > 7) then c_ph_val_tmp(i) := 0; end if; elsif (tmp_scan_data(start_bit + 1) = '0') then c_ph_val_tmp(i) := c_ph_val_tmp(i) - 1; if (c_ph_val_tmp(i) < 0) then c_ph_val_tmp(i) := 7; end if; end if; end if; end loop; -- C0-C3 counter moduli for i in 0 to 3 loop start_bit := 22 + (i*10); if (tmp_scan_data(start_bit + 4) = '1') then c_mode_val_tmp(i) := "bypass"; if (tmp_scan_data(start_bit + 9) = '1') then c_mode_val_tmp(i) := " off"; ASSERT false REPORT "The specified bit settings will turn OFF the " &cntrs(i)& "counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (tmp_scan_data(start_bit + 9) = '1') then c_mode_val_tmp(i) := " odd"; else c_mode_val_tmp(i) := " even"; end if; high_fast := tmp_scan_data(start_bit+3 downto start_bit); low_fast := tmp_scan_data(start_bit+8 downto start_bit+5); if (tmp_scan_data(start_bit+3 downto start_bit) = "0000") then c_high_val_tmp(i) := 16; else c_high_val_tmp(i) := alt_conv_integer(high_fast); end if; if (tmp_scan_data(start_bit+8 downto start_bit+5) = "0000") then c_low_val_tmp(i) := 16; else c_low_val_tmp(i) := alt_conv_integer(low_fast); end if; end loop; sig_c_ph_val_tmp <= c_ph_val_tmp; sig_c_low_val_tmp <= c_low_val_tmp; sig_c_hi_val_tmp <= c_high_val_tmp; -- M -- some temporary storage if (tmp_scan_data(65 downto 62) = "0000") then m_hi := "10000"; else m_hi := "0" & tmp_scan_data(65 downto 62); end if; if (tmp_scan_data(70 downto 67) = "0000") then m_lo := "10000"; else m_lo := "0" & tmp_scan_data(70 downto 67); end if; m_val_tmp(0) := alt_conv_integer(m_hi) + alt_conv_integer(m_lo); if (tmp_scan_data(66) = '1') then if (tmp_scan_data(71) = '1') then -- this will turn off the M counter : error reconfig_err <= true; is_error := true; ASSERT false REPORT "The specified bit settings will turn OFF the M counter. This is illegal. Reconfiguration may not work." severity warning; else -- M counter is being bypassed if (m_mode_val(0) /= "bypass") then -- mode is switched : give warning ASSERT false REPORT "M counter switched from enabled to BYPASS mode. PLL may lose lock." severity warning; end if; m_val_tmp(0) := 1; m_mode_val(0) <= "bypass"; end if; else if (m_mode_val(0) = "bypass") then -- mode is switched : give warning ASSERT false REPORT "M counter switched BYPASS mode to enabled. PLL may lose lock." severity warning; end if; m_mode_val(0) <= " "; if (tmp_scan_data(71) = '1') then -- odd : check for duty cycle, if not 50% -- error if (alt_conv_integer(m_hi) - alt_conv_integer(m_lo) /= 1) then reconfig_err <= true; ASSERT FALSE REPORT "The M counter of the " & family_name & " FAST PLL can 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." severity warning; end if; else -- even if (alt_conv_integer(m_hi) /= alt_conv_integer(m_lo)) then reconfig_err <= true; ASSERT FALSE REPORT "The M counter of the " & family_name & " FAST PLL can 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." severity warning; end if; end if; end if; -- N is_error := false; n_fast := tmp_scan_data(73 downto 72); n_val(0) <= alt_conv_integer(n_fast); if (tmp_scan_data(74) /= '1') then if (alt_conv_integer(n_fast) = 1) then is_error := true; reconfig_err <= true; -- cntr value is illegal : give warning ASSERT false REPORT "Illegal 1 value for N counter. Instead the counter should be BYPASSED. Reconfiguration may not work." severity warning; elsif (alt_conv_integer(n_fast) = 0) then n_val(0) <= 4; ASSERT FALSE REPORT "N Modulus = " &int2str(4)& " " severity note; end if; if (not is_error) then if (n_mode_val(0) = "bypass") then ASSERT false REPORT "N Counter switched from BYPASS mode to enabled (N modulus = " &int2str(alt_conv_integer(n_fast))& "). PLL may lose lock." severity warning; else ASSERT FALSE REPORT "N modulus = " &int2str(alt_conv_integer(n_fast))& " "severity note; end if; n_mode_val(0) <= " "; end if; elsif (tmp_scan_data(74) = '1') then if (tmp_scan_data(72) /= '0') then is_error := true; reconfig_err <= true; ASSERT false report "Illegal value for N counter in BYPASS mode. The LSB of the counter should be set to 0 in order to operate the counter in BYPASS mode. Reconfiguration may not work." severity warning; else if (n_mode_val(0) /= "bypass") then ASSERT false REPORT "N Counter switched from enabled to BYPASS mode. PLL may lose lock." severity warning; end if; n_val(0) <= 1; n_mode_val(0) <= "bypass"; end if; end if; else -- GENERAL PURPOSE PLL for i in 0 to 5 loop start_bit := 116 - (i*18); if (tmp_scan_data(start_bit + 8) = '1') then c_mode_val_tmp(i) := "bypass"; if (tmp_scan_data(start_bit + 17) = '1') then c_mode_val_tmp(i) := " off"; ASSERT false REPORT "The specified bit settings will turn OFF the " &cntrs(i)& "counter. It cannot be turned on unless the part is re-initialized." severity warning; end if; elsif (tmp_scan_data(start_bit + 17) = '1') then c_mode_val_tmp(i) := " odd"; else c_mode_val_tmp(i) := " even"; end if; high := tmp_scan_data(start_bit + 7 downto start_bit); low := tmp_scan_data(start_bit+16 downto start_bit+9); if (tmp_scan_data(start_bit+7 downto start_bit) = "00000000") then c_high_val_tmp(i) := 256; else c_high_val_tmp(i) := alt_conv_integer(high); end if; if (tmp_scan_data(start_bit+16 downto start_bit+9) = "00000000") then c_low_val_tmp(i) := 256; else c_low_val_tmp(i) := alt_conv_integer(low); end if; end loop; -- the phase taps for i in 0 to 5 loop start_bit := 14 + (i*2); if (tmp_scan_data(start_bit) = '0') then -- do nothing elsif (tmp_scan_data(start_bit) = '1') then if (tmp_scan_data(start_bit + 1) = '1') then c_ph_val_tmp(i) := c_ph_val_tmp(i) + 1; if (c_ph_val_tmp(i) > 7) then c_ph_val_tmp(i) := 0; end if; elsif (tmp_scan_data(start_bit + 1) = '0') then c_ph_val_tmp(i) := c_ph_val_tmp(i) - 1; if (c_ph_val_tmp(i) < 0) then c_ph_val_tmp(i) := 7; end if; end if; end if; end loop; sig_c_ph_val_tmp <= c_ph_val_tmp; sig_c_low_val_tmp <= c_low_val_tmp; sig_c_hi_val_tmp <= c_high_val_tmp; -- cntrs M/M2 for i in 0 to 1 loop start_bit := 134 + (i*10); if ( i = 0 or (i = 1 and ss > 0) ) then is_error := false; m_tmp := tmp_scan_data(start_bit+8 downto start_bit); m_val_tmp(i) := alt_conv_integer(m_tmp); if (tmp_scan_data(start_bit+9) /= '1') then if (alt_conv_integer(m_tmp) = 1) then is_error := true; reconfig_err <= true; -- cntr value is illegal : give warning ASSERT false REPORT "Illegal 1 value for " &ss_cntrs(i)& "counter. Instead " &ss_cntrs(i)& "should be BYPASSED. Reconfiguration may not work." severity warning; elsif (tmp_scan_data(start_bit+8 downto start_bit) = "000000000") then m_val_tmp(i) := 512; end if; if (not is_error) then if (m_mode_val(i) = "bypass") then -- Mode is switched : give warning ASSERT false REPORT "M Counter switched from BYPASS mode to enabled (M modulus = " &int2str(alt_conv_integer(m_tmp))& "). PLL may lose lock." severity warning; else end if; m_mode_val(i) <= " "; end if; elsif (tmp_scan_data(start_bit+9) = '1') then if (tmp_scan_data(start_bit) /= '0') then is_error := true; reconfig_err <= true; ASSERT false report "Illegal value for counter " &ss_cntrs(i)& "in BYPASS mode. The LSB of the counter should be set to 0 in order to operate the counter in BYPASS mode. Reconfiguration may not work." severity warning; else if (m_mode_val(i) /= "bypass") then -- Mode is switched : give warning ASSERT false REPORT "M Counter switched from enabled to BYPASS mode. PLL may lose lock." severity warning; end if; m_val_tmp(i) := 1; m_mode_val(i) <= "bypass"; end if; end if; end if; end loop; if (ss > 0) then if (m_mode_val(0) /= m_mode_val(1)) then reconfig_err <= true; is_error := true; ASSERT false REPORT "Incompatible modes for M/M2 counters. Either both should be BYPASSED or both NON-BYPASSED. Reconfiguration may not work." severity warning; end if; end if; sig_m_val_tmp <= m_val_tmp; -- cntrs N/N2 for i in 0 to 1 loop start_bit := 154 + i*10; if ( i = 0 or (i = 1 and ss > 0) ) then is_error := false; n_tmp := tmp_scan_data(start_bit+8 downto start_bit); n_val(i) <= alt_conv_integer(n_tmp); if (tmp_scan_data(start_bit+9) /= '1') then if (alt_conv_integer(n_tmp) = 1) then is_error := true; reconfig_err <= true; -- cntr value is illegal : give warning ASSERT false REPORT "Illegal 1 value for " &ss_cntrs(2+i)& "counter. Instead " &ss_cntrs(2+i)& "should be BYPASSED. Reconfiguration may not work." severity warning; elsif (alt_conv_integer(n_tmp) = 0) then n_val(i) <= 512; end if; if (not is_error) then if (n_mode_val(i) = "bypass") then ASSERT false REPORT "N Counter switched from BYPASS mode to enabled (N modulus = " &int2str(alt_conv_integer(n_tmp))& "). PLL may lose lock." severity warning; else end if; n_mode_val(i) <= " "; end if; elsif (tmp_scan_data(start_bit+9) = '1') then if (tmp_scan_data(start_bit) /= '0') then is_error := true; reconfig_err <= true; ASSERT false report "Illegal value for counter " &ss_cntrs(2+i)& "in BYPASS mode. The LSB of the counter should be set to 0 in order to operate the counter in BYPASS mode. Reconfiguration may not work." severity warning; else if (n_mode_val(i) /= "bypass") then ASSERT false REPORT "N Counter switched from enabled to BYPASS mode. PLL may lose lock." severity warning; end if; n_val(i) <= 1; n_mode_val(i) <= "bypass"; end if; end if; end if; end loop; if (ss > 0) then if (n_mode_val(0) /= n_mode_val(1)) then reconfig_err <= true; is_error := true; ASSERT false REPORT "Incompatible modes for N/N2 counters. Either both should be BYPASSED or both NON-BYPASSED. Reconfiguration may not work." severity warning; end if; end if; end if; slowest_clk_old := slowest_clk(c_high_val(0)+c_low_val(0), c_mode_val(0), c_high_val(1)+c_low_val(1), c_mode_val(1), c_high_val(2)+c_low_val(2), c_mode_val(2), c_high_val(3)+c_low_val(3), c_mode_val(3), c_high_val(4)+c_low_val(4), c_mode_val(4), c_high_val(5)+c_low_val(5), c_mode_val(5), sig_refclk_period, m_val(0)); slowest_clk_new := slowest_clk(c_high_val_tmp(0)+c_low_val_tmp(0), c_mode_val_tmp(0), c_high_val_tmp(1)+c_low_val_tmp(1), c_mode_val_tmp(1), c_high_val_tmp(2)+c_low_val_tmp(2), c_mode_val_tmp(2), c_high_val_tmp(3)+c_low_val_tmp(3), c_mode_val_tmp(3), c_high_val_tmp(4)+c_low_val_tmp(4), c_mode_val_tmp(4), c_high_val_tmp(5)+c_low_val_tmp(5), c_mode_val_tmp(5), sig_refclk_period, m_val_tmp(0)); if (slowest_clk_new > slowest_clk_old) then quiet_time := slowest_clk_new; else quiet_time := slowest_clk_old; end if; sig_quiet_time <= quiet_time; sig_slowest_clk_old <= slowest_clk_old; sig_slowest_clk_new <= slowest_clk_new; tmp_rem := (quiet_time/1 ps) rem (scanclk_period/ 1 ps); scanclk_cycles := (quiet_time/1 ps) / (scanclk_period/1 ps); if (tmp_rem /= 0) then scanclk_cycles := scanclk_cycles + 1; end if; scandone_tmp <= transport '1' after ((scanclk_cycles+1)*scanclk_period - (scanclk_period/2)); end if; if (scanwrite_enabled = '1') then if (fbclk'event and fbclk = '1') then m_val <= m_val_tmp; end if; if (c_clk(0)'event and c_clk(0) = '1') then c_high_val(0) <= c_high_val_tmp(0); c_mode_val(0) <= c_mode_val_tmp(0); c0_rising_edge_transfer_done := true; end if; if (c_clk(1)'event and c_clk(1) = '1') then c_high_val(1) <= c_high_val_tmp(1); c_mode_val(1) <= c_mode_val_tmp(1); c1_rising_edge_transfer_done := true; end if; if (c_clk(2)'event and c_clk(2) = '1') then c_high_val(2) <= c_high_val_tmp(2); c_mode_val(2) <= c_mode_val_tmp(2); c2_rising_edge_transfer_done := true; end if; if (c_clk(3)'event and c_clk(3) = '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 (c_clk(4)'event and c_clk(4) = '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; if (c_clk(5)'event and c_clk(5) = '1') then c_high_val(5) <= c_high_val_tmp(5); c_mode_val(5) <= c_mode_val_tmp(5); c5_rising_edge_transfer_done := true; end if; end if; if (c_clk(0)'event and c_clk(0) = '0' and c0_rising_edge_transfer_done) then c_low_val(0) <= c_low_val_tmp(0); end if; if (c_clk(1)'event and c_clk(1) = '0' and c1_rising_edge_transfer_done) then c_low_val(1) <= c_low_val_tmp(1); end if; if (c_clk(2)'event and c_clk(2) = '0' and c2_rising_edge_transfer_done) then c_low_val(2) <= c_low_val_tmp(2); end if; if (c_clk(3)'event and c_clk(3) = '0' and c3_rising_edge_transfer_done) then c_low_val(3) <= c_low_val_tmp(3); end if; if (c_clk(4)'event and c_clk(4) = '0' and c4_rising_edge_transfer_done) then c_low_val(4) <= c_low_val_tmp(4); end if; if (c_clk(5)'event and c_clk(5) = '0' and c5_rising_edge_transfer_done) then c_low_val(5) <= c_low_val_tmp(5); end if; if (scanwrite_enabled = '1') then for x in 0 to 7 loop if (vco_tap(x) /= vco_tap_last_value(x) and vco_tap(x) = '0') then -- TAP X has event for i in 0 to 5 loop if (c_ph_val(i) = x) then c_ph_val(i) <= c_ph_val_tmp(i); end if; end loop; if (m_ph_val = x) then m_ph_val <= m_ph_val_tmp; end if; end if; end loop; end if; -- revert counter phase tap values to POF programmed values -- if PLL is reset if (areset_ipd = '1') then c_ph_val <= i_c_ph; c_ph_val_tmp := i_c_ph; m_ph_val <= i_m_ph; m_ph_val_tmp := i_m_ph; end if; for x in 0 to 7 loop if (vco_tap(x) /= vco_tap_last_value(x)) then -- TAP X has event for i in 0 to 5 loop if (c_ph_val(i) = x) then inclk_c_from_vco(i) <= vco_tap(x); if (i = 0 and enable0_counter = "c0") then inclk_sclkout0_from_vco <= vco_tap(x); end if; if (i = 0 and enable1_counter = "c0") then inclk_sclkout1_from_vco <= vco_tap(x); end if; if (i = 1 and enable0_counter = "c1") then inclk_sclkout0_from_vco <= vco_tap(x); end if; if (i = 1 and enable1_counter = "c1") then inclk_sclkout1_from_vco <= vco_tap(x); end if; end if; end loop; if (m_ph_val = x) then inclk_m_from_vco <= vco_tap(x); end if; vco_tap_last_value(x) <= vco_tap(x); end if; end loop; if (scanclk_ipd'event and scanclk_ipd = '0') then -- enable scanwrite on falling edge scanwrite_enabled <= scanwrite_reg; end if; if (scanread_reg = '1') then gated_scanclk <= transport scanclk_ipd and scanread_reg; else gated_scanclk <= transport '1'; end if; if (scanclk_ipd'event and scanclk_ipd = '1') then -- register scanread and scanwrite scanread_reg <= scanread_ipd; scanwrite_reg <= scanwrite_ipd; if (got_first_scanclk) then scanclk_period := now - scanclk_last_rising_edge; else got_first_scanclk := true; end if; -- reset got_first_scanclk on falling edge of scanread_reg if (scanread_ipd = '0' and scanread_reg = '1') then got_first_scanclk := false; got_first_gated_scanclk := false; end if; scanclk_last_rising_edge := now; end if; if (gated_scanclk'event and gated_scanclk = '1' and now > 0 ps) then if (not got_first_gated_scanclk) then got_first_gated_scanclk := true; end if; for j in scan_chain_length - 1 downto 1 loop scan_data(j) <= scan_data(j-1); end loop; scan_data(0) <= scandata_ipd; end if; end process; scandataout_tmp <= scan_data(FAST_SCAN_CHAIN-1) when (pll_type = "fast" or pll_type = "lvds") else scan_data(GPP_SCAN_CHAIN-1); SCHEDULE : process (schedule_vco, areset_ipd, ena_ipd, pfdena_ipd, refclk, fbclk, vco_out) 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 pll_about_to_lock : boolean := false; 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 pll_is_disabled : boolean := false; variable next_vco_sched_time : time := 0 ps; variable tap0_is_active : boolean := true; 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(0) * 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 locked_tmp := '0'; pll_is_locked := false; pll_about_to_lock := false; cycles_to_lock := 0; cycles_to_unlock := 0; pll_is_in_reset := true; tap0_is_active := false; for x in 0 to 7 loop vco_tap(x) <= '0'; end loop; end if; -- 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; pll_is_in_reset := false; if (ena_ipd = '1' and not stop_vco and next_vco_sched_time <= now) then schedule_vco <= not schedule_vco; end if; end if; -- ena was deasserted if (ena_ipd'event and ena_ipd = '0') then assert false report family_name & " PLL was disabled" severity note; pll_is_disabled := true; tap0_is_active := false; for x in 0 to 7 loop vco_tap(x) <= '0'; end loop; end if; if (ena_ipd'event and ena_ipd = '1') then assert false report family_name & " PLL is enabled" severity note; pll_is_disabled := false; if (areset_ipd /= '1' and not stop_vco and next_vco_sched_time < now) then schedule_vco <= not schedule_vco; end if; end if; -- illegal value on areset_ipd if (areset_ipd'event and areset_ipd = 'X') then assert false report "Illegal value 'X' detected on ARESET input" severity warning; end if; if (areset_ipd = '1' or ena_ipd = '0' or stop_vco) then -- reset lock parameters locked_tmp := '0'; pll_is_locked := false; pll_about_to_lock := 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; -- reset all counter phase taps to POF programmed values end if; if (schedule_vco'event and areset_ipd /= '1' and ena_ipd /= '0' and (not stop_vco) and now > 0 ps) then -- calculate loop_xplier : this will be different from m_val -- in external_feedback_mode loop_xplier := m_val(0); loop_initial := m_initial_val - 1; loop_ph := m_ph_val; if (operation_mode = "external_feedback") then if (ext_fbk_cntr_mode = "bypass") then ext_fbk_cntr_modulus := 1; else ext_fbk_cntr_modulus := ext_fbk_cntr_high + ext_fbk_cntr_low; end if; loop_xplier := m_val(0) * (ext_fbk_cntr_modulus); loop_ph := ext_fbk_cntr_ph; loop_initial := ext_fbk_cntr_initial - 1 + ((m_initial_val - 1) * ext_fbk_cntr_modulus); end if; -- 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; if (operation_mode = "external_feedback") then pull_back_M := (m_initial_val - 1) * ext_fbk_cntr_modulus * ((refclk_period/loop_xplier)/1 ps); while (pull_back_M > refclk_period/1 ps) loop pull_back_M := pull_back_M - refclk_period/ 1 ps; end loop; else pull_back_M := initial_delay/1 ps + fbk_phase; end if; 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; if (operation_mode = "external_feedback") then fbk_delay := pull_back_M; if (simulation_type = "timing") then fbk_delay := fbk_delay + pll_compensation_delay; end if; else 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; 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 tap0 vco_out(0) <= transport vco_val after sched_time; 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 tap 0 vco_out(0) <= transport vco_val after sched_time; first_schedule := false; end if; schedule_vco <= transport not schedule_vco after sched_time; next_vco_sched_time := now + 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; -- now schedule the other taps with the appropriate phase-shift if (vco_out(0)'event) then for k in 1 to 7 loop phase_shift(k) := (k * vco_per)/8; vco_out(k) <= transport vco_out(0) after phase_shift(k); end loop; 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 ( (vco_max /= 0 and vco_min /= 0 and pfdena_ipd = '1') and (((refclk_period/1 ps)/loop_xplier > vco_max) or ((refclk_period/1 ps)/loop_xplier < vco_min)) ) then if (pll_is_locked) then assert false report " Input clock freq. is not within VCO range : " & family_name & " PLL may lose lock" severity warning; if (inclk_out_of_range) then pll_is_locked := false; locked_tmp := '0'; pll_about_to_lock := false; 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 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 inclk_out_of_range := false; 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; 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') ) 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" severity note; end if; pll_about_to_lock := false; cycles_to_lock := 0; cycles_to_unlock := 0; first_schedule := true; vco_period_was_phase_adjusted := false; phase_adjust_was_scheduled := false; tap0_is_active := false; for x in 0 to 7 loop vco_tap(x) <= '0'; end loop; 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 = valid_lock_multiplier - 1) then pll_about_to_lock := true; end if; if (cycles_to_lock = valid_lock_multiplier) 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)) <= 5 ps)) 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 = invalid_lock_multiplier) then pll_is_locked := false; locked_tmp := '0'; pll_about_to_lock := false; 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; 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 if ( abs(fbclk_time - refclk_time) > 1.5 * refclk_period) then -- input clock may have stopped : do nothing else new_m_times_vco_period := m_times_vco_period + (refclk_period - abs(fbclk_time - refclk_time)); vco_period_was_phase_adjusted := true; end if; 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; -- check which vco_tap has event for x in 0 to 7 loop if (vco_out(x) /= vco_out_last_value(x)) then -- TAP X has event if (x = 0 and areset_ipd = '0' and ena_ipd = '1' and sig_stop_vco = '0') then if (vco_out(0) = '1') then tap0_is_active := true; end if; if (tap0_is_active) then vco_tap(0) <= vco_out(0); end if; elsif (tap0_is_active) then vco_tap(x) <= vco_out(x); end if; if (sig_stop_vco = '1') then vco_tap(x) <= '0'; end if; vco_out_last_value(x) <= vco_out(x); end if; end loop; 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; about_to_lock <= pll_about_to_lock after 1 ps; -- 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; end process SCHEDULE; clk0_tmp <= c_clk(i_clk0_counter); clk(0) <= clk0_tmp when (areset_ipd = '1' or ena_ipd = '0' or pll_in_test_mode) or (about_to_lock and (not reconfig_err)) else 'X'; clk1_tmp <= c_clk(i_clk1_counter); clk(1) <= clk1_tmp when (areset_ipd = '1' or ena_ipd = '0' or pll_in_test_mode) or (about_to_lock and (not reconfig_err)) else 'X'; clk2_tmp <= c_clk(i_clk2_counter); clk(2) <= clk2_tmp when (areset_ipd = '1' or ena_ipd = '0' or pll_in_test_mode) or (about_to_lock and (not reconfig_err)) else 'X'; clk3_tmp <= c_clk(i_clk3_counter); clk(3) <= clk3_tmp when (areset_ipd = '1' or ena_ipd = '0' or pll_in_test_mode) or (about_to_lock and (not reconfig_err)) else 'X'; clk4_tmp <= c_clk(i_clk4_counter); clk(4) <= clk4_tmp when (areset_ipd = '1' or ena_ipd = '0' or pll_in_test_mode) or (about_to_lock and (not reconfig_err)) else 'X'; clk5_tmp <= c_clk(i_clk5_counter); clk(5) <= clk5_tmp when (areset_ipd = '1' or ena_ipd = '0' or pll_in_test_mode) or (about_to_lock and (not reconfig_err)) else 'X'; sclkout(0) <= sclkout0_tmp when (areset_ipd = '1' or ena_ipd = '0' or pll_in_test_mode) or (about_to_lock and (not reconfig_err)) else 'X'; sclkout(1) <= sclkout1_tmp when (areset_ipd = '1' or ena_ipd = '0' or pll_in_test_mode) or (about_to_lock and (not reconfig_err)) else 'X'; enable0 <= enable0_tmp when (areset_ipd = '1' or ena_ipd = '0' or pll_in_test_mode) or (about_to_lock and (not reconfig_err)) else 'X'; enable1 <= enable1_tmp when (areset_ipd = '1' or ena_ipd = '0' or pll_in_test_mode) or (about_to_lock and (not reconfig_err)) else 'X'; scandataout <= scandataout_tmp; scandone <= scandone_tmp; end vital_pll; -- END ARCHITECTURE VITAL_PLL --/////////////////////////////////////////////////////////////////////////// -- -- Entity Name : MF_ttn_mn_cntr -- -- Description : Simulation model for the M and N counter. This is a -- common model for the input counter and the loop feedback -- counter of the StratixIII PLL. -- --/////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; USE IEEE.std_logic_unsigned.all; ENTITY MF_ttn_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 MF_ttn_mn_cntr; ARCHITECTURE behave of MF_ttn_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 : MF_ttn_scale_cntr -- -- Description : 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 StratixII PLL. -- --///////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; ENTITY MF_ttn_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 MF_ttn_scale_cntr; ARCHITECTURE behave of MF_ttn_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 : MF_stratixiii_pll -- -- Description : Simulation model for the StratixII 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 STD.TEXTIO.all; USE work.MF_pllpack.all; USE work.MF_ttn_mn_cntr; USE work.MF_ttn_scale_cntr; USE work.dffp; USE work.MF_pll_reg; -- New Features : The list below outlines key new features in TITAN: -- 1. Dynamic Phase Reconfiguration -- 2. Dynamic PLL Reconfiguration (different protocol) -- 3. More output counters ENTITY MF_stratixiii_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"; dpa_multiply_by : integer := 0; dpa_divide_by : integer := 0; dpa_divider : integer := 0; 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; clk5_output_frequency : integer := 0; clk5_multiply_by : integer := 0; clk5_divide_by : integer := 0; clk5_phase_shift : string := "0"; clk5_duty_cycle : integer := 50; clk6_output_frequency : integer := 0; clk6_multiply_by : integer := 0; clk6_divide_by : integer := 0; clk6_phase_shift : string := "0"; clk6_duty_cycle : integer := 50; clk7_output_frequency : integer := 0; clk7_multiply_by : integer := 0; clk7_divide_by : integer := 0; clk7_phase_shift : string := "0"; clk7_duty_cycle : integer := 50; clk8_output_frequency : integer := 0; clk8_multiply_by : integer := 0; clk8_divide_by : integer := 0; clk8_phase_shift : string := "0"; clk8_duty_cycle : integer := 50; clk9_output_frequency : integer := 0; clk9_multiply_by : integer := 0; clk9_divide_by : integer := 0; clk9_phase_shift : string := "0"; clk9_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; c5_high : integer := 1; c5_low : integer := 1; c5_initial : integer := 1; c5_mode : string := "bypass"; c5_ph : integer := 0; c6_high : integer := 1; c6_low : integer := 1; c6_initial : integer := 1; c6_mode : string := "bypass"; c6_ph : integer := 0; c7_high : integer := 1; c7_low : integer := 1; c7_initial : integer := 1; c7_mode : string := "bypass"; c7_ph : integer := 0; c8_high : integer := 1; c8_low : integer := 1; c8_initial : integer := 1; c8_mode : string := "bypass"; c8_ph : integer := 0; c9_high : integer := 1; c9_low : integer := 1; c9_initial : integer := 1; c9_mode : string := "bypass"; c9_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"; clk5_counter : string := "unused"; clk6_counter : string := "unused"; clk7_counter : string := "unused"; clk8_counter : string := "unused"; clk9_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"; c5_use_casc_in : string := "off"; c6_use_casc_in : string := "off"; c7_use_casc_in : string := "off"; c8_use_casc_in : string := "off"; c9_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; c5_test_source : integer := -1; c6_test_source : integer := -1; c7_test_source : integer := -1; c8_test_source : integer := -1; c9_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"; 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"; clk5_use_even_counter_mode : string := "off"; clk6_use_even_counter_mode : string := "off"; clk7_use_even_counter_mode : string := "off"; clk8_use_even_counter_mode : string := "off"; clk9_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"; clk5_use_even_counter_value : string := "off"; clk6_use_even_counter_value : string := "off"; clk7_use_even_counter_value : string := "off"; clk8_use_even_counter_value : string := "off"; clk9_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_c6_delay_chain_bits : integer := 0; test_counter_c7_delay_chain_bits : integer := 0; test_counter_c8_delay_chain_bits : integer := 0; test_counter_c9_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 := ""; dpa_output_clock_phase_shift : integer := 0; test_counter_c3_sclk_delay_chain_bits : integer := -1; test_counter_c4_sclk_delay_chain_bits : integer := -1; test_counter_c5_lden_delay_chain_bits : integer := -1; test_counter_c6_lden_delay_chain_bits : integer := -1; auto_settings : string := "true"; -- Simulation only generics family_name : string := "StratixIII"; 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(9 downto 0); phasecounterselect : in std_logic_vector(3 downto 0) := "0000"; 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 MF_stratixiii_pll; ARCHITECTURE vital_pll of MF_stratixiii_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 9) := (OTHERS => 0); signal c_ph_val_tmp : int_array(0 to 9) := (OTHERS => 0); signal c_high_val : int_array(0 to 9) := (OTHERS => 1); signal c_low_val : int_array(0 to 9) := (OTHERS => 1); signal c_initial_val : int_array(0 to 9) := (OTHERS => 1); signal c_mode_val : str_array(0 to 9); signal clk_num : str_array(0 to 9); -- old values signal c_high_val_old : int_array(0 to 9) := (OTHERS => 1); signal c_low_val_old : int_array(0 to 9) := (OTHERS => 1); signal c_ph_val_old : int_array(0 to 9) := (OTHERS => 0); signal c_mode_val_old : str_array(0 to 9); -- hold registers signal c_high_val_hold : int_array(0 to 9) := (OTHERS => 1); signal c_low_val_hold : int_array(0 to 9) := (OTHERS => 1); signal c_ph_val_hold : int_array(0 to 9) := (OTHERS => 0); signal c_mode_val_hold : str_array(0 to 9); -- temp registers signal sig_c_ph_val_tmp : int_array(0 to 9) := (OTHERS => 0); signal c_ph_val_orig : int_array(0 to 9) := (OTHERS => 0); signal i_clk9_counter : integer := 9; signal i_clk8_counter : integer := 8; signal i_clk7_counter : integer := 7; signal i_clk6_counter : integer := 6; signal i_clk5_counter : integer := 5; 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(9 downto 0) := (" C9", " C8", " C7", " C6", " C5", " 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 9); 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 := 10; signal scanclk_period : time := 1 ps; signal scan_data : std_logic_vector(0 to 233) := (OTHERS => '0'); signal clk_pfd : std_logic_vector(0 to 9); 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 clk5_tmp : std_logic; signal clk6_tmp : std_logic; signal clk7_tmp : std_logic; signal clk8_tmp : std_logic; signal clk9_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_c5 : std_logic; signal inclk_c6 : std_logic; signal inclk_c7 : std_logic; signal inclk_c8 : std_logic; signal inclk_c9 : 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(3 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(3 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 9); 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 MF_ttn_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 MF_ttn_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 dffp 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 MF_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 inclk0_ipd <= inclk(0); inclk1_ipd <= inclk(1); areset_ipd <= areset; fbin_ipd <= fbin; pfdena_ipd <= pfdena; scanclk_ipd <= scanclk; scanclkena_ipd <= scanclkena; scandata_ipd <= scandata; configupdate_ipd <= configupdate; clkswitch_ipd <= clkswitch; phaseupdown_ipd <= phaseupdown; phasestep_ipd <= phasestep; phasecounterselect_ipd(0) <= phasecounterselect(0); phasecounterselect_ipd(1) <= phasecounterselect(1); phasecounterselect_ipd(2) <= phasecounterselect(2); phasecounterselect_ipd(3) <= phasecounterselect(3); 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 or c5_test_source /= -1 or c6_test_source /= -1 or c7_test_source /= -1 or c8_test_source /= -1 or c9_test_source /= -1) else false; real_lock_high <= lock_high WHEN (sim_gate_lock_device_behavior = "on") ELSE 0; m1 : MF_ttn_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 : MF_ttn_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 : MF_ttn_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 : MF_ttn_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 : MF_ttn_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 : MF_ttn_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 : MF_ttn_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)); inclk_c5 <= refclk when c5_test_source = 1 else fbclk when c5_test_source = 0 else c_clk(4) when c5_use_casc_in = "on" else inclk_c_from_vco(5); c5 : MF_ttn_scale_cntr port map ( clk => inclk_c5, reset => areset_ena_sig, cout => c_clk(5), initial => c_initial_val(5), high => c_high_val(5), low => c_low_val(5), mode => c_mode_val(5), ph_tap => c_ph_val(5)); inclk_c6 <= refclk when c6_test_source = 1 else fbclk when c6_test_source = 0 else c_clk(5) when c6_use_casc_in = "on" else inclk_c_from_vco(6); c6 : MF_ttn_scale_cntr port map ( clk => inclk_c6, reset => areset_ena_sig, cout => c_clk(6), initial => c_initial_val(6), high => c_high_val(6), low => c_low_val(6), mode => c_mode_val(6), ph_tap => c_ph_val(6)); inclk_c7 <= refclk when c7_test_source = 1 else fbclk when c7_test_source = 0 else c_clk(6) when c7_use_casc_in = "on" else inclk_c_from_vco(7); c7 : MF_ttn_scale_cntr port map ( clk => inclk_c7, reset => areset_ena_sig, cout => c_clk(7), initial => c_initial_val(7), high => c_high_val(7), low => c_low_val(7), mode => c_mode_val(7), ph_tap => c_ph_val(7)); inclk_c8 <= refclk when c8_test_source = 1 else fbclk when c8_test_source = 0 else c_clk(7) when c8_use_casc_in = "on" else inclk_c_from_vco(8); c8 : MF_ttn_scale_cntr port map ( clk => inclk_c8, reset => areset_ena_sig, cout => c_clk(8), initial => c_initial_val(8), high => c_high_val(8), low => c_low_val(8), mode => c_mode_val(8), ph_tap => c_ph_val(8)); inclk_c9 <= refclk when c9_test_source = 1 else fbclk when c9_test_source = 0 else c_clk(8) when c9_use_casc_in = "on" else inclk_c_from_vco(9); c9 : MF_ttn_scale_cntr port map ( clk => inclk_c9, reset => areset_ena_sig, cout => c_clk(9), initial => c_initial_val(9), high => c_high_val(9), low => c_low_val(9), mode => c_mode_val(9), ph_tap => c_ph_val(9)); 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), c_clk(5), c_clk(6), c_clk(7), c_clk(8), c_clk(9), 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 9) := (OTHERS => 1); variable c_low_val_tmp,c_lval : int_array(0 to 9) := (OTHERS => 1); variable c_mode_val_tmp : str_array(0 to 9); 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; variable c5_rising_edge_transfer_done : boolean := false; variable c6_rising_edge_transfer_done : boolean := false; variable c7_rising_edge_transfer_done : boolean := false; variable c8_rising_edge_transfer_done : boolean := false; variable c9_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 i_clk5_mult_by : integer := 1; variable i_clk5_div_by : integer := 1; variable i_clk6_mult_by : integer := 1; variable i_clk6_div_by : integer := 1; variable i_clk7_mult_by : integer := 1; variable i_clk7_div_by : integer := 1; variable i_clk8_mult_by : integer := 1; variable i_clk8_div_by : integer := 1; variable i_clk9_mult_by : integer := 1; variable i_clk9_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 9); variable i_c_low : int_array(0 to 9); variable i_c_initial : int_array(0 to 9); variable i_c_ph : int_array(0 to 9); variable i_c_mode : str_array(0 to 9); 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 clk5_cntr : string(1 to 6) := " c5"; variable clk6_cntr : string(1 to 6) := " c6"; variable clk7_cntr : string(1 to 6) := " c7"; variable clk8_cntr : string(1 to 6) := " c8"; variable clk9_cntr : string(1 to 6) := " c9"; 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 233) := (OTHERS => '0'); variable index : integer := 0; 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 clk9_cntr := " c9"; clk8_cntr := " c8"; clk7_cntr := " c7"; clk6_cntr := " c6"; clk5_cntr := " c5"; clk4_cntr := " c4"; clk3_cntr := " c3"; clk2_cntr := " c2"; clk1_cntr := " c1"; clk0_cntr := " c0"; else clk9_cntr := extract_cntr_string(clk9_counter); clk8_cntr := extract_cntr_string(clk8_counter); clk7_cntr := extract_cntr_string(clk7_counter); clk6_cntr := extract_cntr_string(clk6_counter); clk5_cntr := extract_cntr_string(clk5_counter); 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(9) <= output_cntr_num(clk9_counter); clk_num(8) <= output_cntr_num(clk8_counter); clk_num(7) <= output_cntr_num(clk7_counter); clk_num(6) <= output_cntr_num(clk6_counter); clk_num(5) <= output_cntr_num(clk5_counter); 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); i_clk5_counter <= extract_cntr_index(clk5_cntr); i_clk6_counter <= extract_cntr_index(clk6_cntr); i_clk7_counter <= extract_cntr_index(clk7_cntr); i_clk8_counter <= extract_cntr_index(clk8_cntr); i_clk9_counter <= extract_cntr_index(clk9_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); find_simple_integer_fraction(clk5_multiply_by, clk5_divide_by, max_d_value, i_clk5_mult_by, i_clk5_div_by); find_simple_integer_fraction(clk6_multiply_by, clk6_divide_by, max_d_value, i_clk6_mult_by, i_clk6_div_by); find_simple_integer_fraction(clk7_multiply_by, clk7_divide_by, max_d_value, i_clk7_mult_by, i_clk7_div_by); find_simple_integer_fraction(clk8_multiply_by, clk8_divide_by, max_d_value, i_clk8_mult_by, i_clk8_div_by); find_simple_integer_fraction(clk9_multiply_by, clk9_divide_by, max_d_value, i_clk9_mult_by, i_clk9_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, i_clk5_mult_by,i_clk6_mult_by, i_clk7_mult_by,i_clk8_mult_by,i_clk9_mult_by, i_clk0_div_by, i_clk1_div_by, i_clk2_div_by, i_clk3_div_by, i_clk4_div_by, i_clk5_div_by,i_clk6_div_by, i_clk7_div_by,i_clk8_div_by,i_clk9_div_by, clk0_counter, clk1_counter, clk2_counter, clk3_counter, clk4_counter, clk5_counter,clk6_counter, clk7_counter,clk8_counter,clk9_counter, 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, i_clk5_mult_by,i_clk6_mult_by, i_clk7_mult_by,i_clk8_mult_by,i_clk9_mult_by, 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), str2int(clk5_phase_shift), str2int(clk6_phase_shift), str2int(clk7_phase_shift), str2int(clk8_phase_shift), str2int(clk9_phase_shift) ); 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_ph(5) := counter_ph(get_phase_degree(ph_adjust(str2int(clk5_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); i_c_ph(6) := counter_ph(get_phase_degree(ph_adjust(str2int(clk6_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); i_c_ph(7) := counter_ph(get_phase_degree(ph_adjust(str2int(clk7_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); i_c_ph(8) := counter_ph(get_phase_degree(ph_adjust(str2int(clk8_phase_shift),max_neg_abs),inclk0_input_frequency), i_m, i_n); i_c_ph(9) := counter_ph(get_phase_degree(ph_adjust(str2int(clk9_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_high(5) := counter_high(output_counter_value(i_clk5_div_by, i_clk5_mult_by, i_m, i_n), clk5_duty_cycle); i_c_high(6) := counter_high(output_counter_value(i_clk6_div_by, i_clk6_mult_by, i_m, i_n), clk6_duty_cycle); i_c_high(7) := counter_high(output_counter_value(i_clk7_div_by, i_clk7_mult_by, i_m, i_n), clk7_duty_cycle); i_c_high(8) := counter_high(output_counter_value(i_clk8_div_by, i_clk8_mult_by, i_m, i_n), clk8_duty_cycle); i_c_high(9) := counter_high(output_counter_value(i_clk9_div_by, i_clk9_mult_by, i_m, i_n), clk9_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_c_low(5) := counter_low(output_counter_value(i_clk5_div_by, i_clk5_mult_by, i_m, i_n), clk5_duty_cycle); i_c_low(6) := counter_low(output_counter_value(i_clk6_div_by, i_clk6_mult_by, i_m, i_n), clk6_duty_cycle); i_c_low(7) := counter_low(output_counter_value(i_clk7_div_by, i_clk7_mult_by, i_m, i_n), clk7_duty_cycle); i_c_low(8) := counter_low(output_counter_value(i_clk8_div_by, i_clk8_mult_by, i_m, i_n), clk8_duty_cycle); i_c_low(9) := counter_low(output_counter_value(i_clk9_div_by, i_clk9_mult_by, i_m, i_n), clk9_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_initial(5) := counter_initial(get_phase_degree(ph_adjust(str2int(clk5_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); i_c_initial(6) := counter_initial(get_phase_degree(ph_adjust(str2int(clk6_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); i_c_initial(7) := counter_initial(get_phase_degree(ph_adjust(str2int(clk7_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); i_c_initial(8) := counter_initial(get_phase_degree(ph_adjust(str2int(clk8_phase_shift), max_neg_abs), inclk0_input_frequency), i_m, i_n); i_c_initial(9) := counter_initial(get_phase_degree(ph_adjust(str2int(clk9_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)); i_c_mode(5) := counter_mode(clk5_duty_cycle, output_counter_value(i_clk5_div_by, i_clk5_mult_by, i_m, i_n)); i_c_mode(6) := counter_mode(clk6_duty_cycle, output_counter_value(i_clk6_div_by, i_clk6_mult_by, i_m, i_n)); i_c_mode(7) := counter_mode(clk7_duty_cycle, output_counter_value(i_clk7_div_by, i_clk7_mult_by, i_m, i_n)); i_c_mode(8) := counter_mode(clk8_duty_cycle, output_counter_value(i_clk8_div_by, i_clk8_mult_by, i_m, i_n)); i_c_mode(9) := counter_mode(clk9_duty_cycle, output_counter_value(i_clk9_div_by, i_clk9_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_ph(5) := c5_ph; i_c_ph(6) := c6_ph; i_c_ph(7) := c7_ph; i_c_ph(8) := c8_ph; i_c_ph(9) := c9_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_high(5) := c5_high; i_c_high(6) := c6_high; i_c_high(7) := c7_high; i_c_high(8) := c8_high; i_c_high(9) := c9_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_low(5) := c5_low; i_c_low(6) := c6_low; i_c_low(7) := c7_low; i_c_low(8) := c8_low; i_c_low(9) := c9_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_initial(5) := c5_initial; i_c_initial(6) := c6_initial; i_c_initial(7) := c7_initial; i_c_initial(8) := c8_initial; i_c_initial(9) := c9_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); i_c_mode(5) := translate_string(c5_mode); i_c_mode(6) := translate_string(c6_mode); i_c_mode(7) := translate_string(c7_mode); i_c_mode(8) := translate_string(c8_mode); i_c_mode(9) := translate_string(c9_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 9 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; if (pll_type = "fast" OR (pll_type = "left_right")) then scan_chain_length := FAST_SCAN_CHAIN; else scan_chain_length := GPP_SCAN_CHAIN; end if; if (pll_type = "fast" or pll_type = "lvds" OR (pll_type = "left_right")) then num_output_cntrs <= 7; else num_output_cntrs <= 10; end if; 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; c5_rising_edge_transfer_done := false; c6_rising_edge_transfer_done := false; c7_rising_edge_transfer_done := false; c8_rising_edge_transfer_done := false; c9_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 m_mode_val <= "bypass"; -- 3. Mode - odd/even (bit 27) ELSIF (scan_data(27) = '1') THEN m_mode_val <= " odd"; ELSE m_mode_val <= " even"; END IF; -- 2. High (bit 19-26) m_hi := scan_data(19 TO 26); -- 4. Low (bit 28-35) m_lo := scan_data(28 TO 35); -- N counter -- 1. Mode - bypass (bit 36) IF (scan_data(36) = '1') THEN n_mode_val <= "bypass"; -- 3. Mode - odd/even (bit 45) ELSIF (scan_data(45) = '1') THEN n_mode_val <= " odd"; ELSE n_mode_val <= " even"; END IF; -- 2. High (bit 37-44) n_hi := scan_data(37 TO 44); -- 4. Low (bit 46-53) n_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(18) /= '1') THEN IF ((m_hi /= m_lo) and (scan_data(27) /= '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(36) /= '1') THEN IF ((n_hi /= n_lo)and (scan_data(45) /= '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; if (scanclk_ipd'event and scanclk_ipd = '1') then c_high_val(5) <= c_high_val_tmp(5); c_mode_val(5) <= c_mode_val_tmp(5); c5_rising_edge_transfer_done := true; end if; if (scanclk_ipd'event and scanclk_ipd = '1') then c_high_val(6) <= c_high_val_tmp(6); c_mode_val(6) <= c_mode_val_tmp(6); c6_rising_edge_transfer_done := true; end if; if (scanclk_ipd'event and scanclk_ipd = '1') then c_high_val(7) <= c_high_val_tmp(7); c_mode_val(7) <= c_mode_val_tmp(7); c7_rising_edge_transfer_done := true; end if; if (scanclk_ipd'event and scanclk_ipd = '1') then c_high_val(8) <= c_high_val_tmp(8); c_mode_val(8) <= c_mode_val_tmp(8); c8_rising_edge_transfer_done := true; end if; if (scanclk_ipd'event and scanclk_ipd = '1') then c_high_val(9) <= c_high_val_tmp(9); c_mode_val(9) <= c_mode_val_tmp(9); c9_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 (scanclk_ipd'event and scanclk_ipd = '0' and c5_rising_edge_transfer_done) then c_low_val(5) <= c_low_val_tmp(5); end if; if (scanclk_ipd'event and scanclk_ipd = '0' and c6_rising_edge_transfer_done) then c_low_val(6) <= c_low_val_tmp(6); end if; if (scanclk_ipd'event and scanclk_ipd = '0' and c7_rising_edge_transfer_done) then c_low_val(7) <= c_low_val_tmp(7); end if; if (scanclk_ipd'event and scanclk_ipd = '0' and c8_rising_edge_transfer_done) then c_low_val(8) <= c_low_val_tmp(8); end if; if (scanclk_ipd'event and scanclk_ipd = '0' and c9_rising_edge_transfer_done) then c_low_val(9) <= c_low_val_tmp(9); end if; if (update_phase = '1') then if (vco_out(0)'event and vco_out(0) = '0') then for i in 0 to 9 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 9 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 9 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 9 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 9 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 9 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 9 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 9 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 9 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 9 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 9 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 9 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 9 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 9 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 9 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 9 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; 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 < "1100") THEN -- no counters selected IF (phasecounterselect_ipd = "0000") 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 = "0001") 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(FAST_SCAN_CHAIN-2) when (pll_type = "fast" or pll_type = "lvds" or pll_type = "left_right") else scan_data(GPP_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'; clk5_tmp <= c_clk(i_clk5_counter); clk_pfd(5) <= clk5_tmp WHEN (pfd_locked = '1') ELSE 'X'; clk(5) <= clk_pfd(5) WHEN (test_bypass_lock_detect = "on") ELSE clk5_tmp when (areset_ipd = '1' or pll_in_test_mode) or (pll_locked and (not reconfig_err)) else 'X'; clk6_tmp <= c_clk(i_clk6_counter); clk_pfd(6) <= clk6_tmp WHEN (pfd_locked = '1') ELSE 'X'; clk(6) <= clk_pfd(6) WHEN (test_bypass_lock_detect = "on") ELSE clk6_tmp when (areset_ipd = '1' or pll_in_test_mode) or (pll_locked and (not reconfig_err)) else 'X'; clk7_tmp <= c_clk(i_clk7_counter); clk_pfd(7) <= clk7_tmp WHEN (pfd_locked = '1') ELSE 'X'; clk(7) <= clk_pfd(7) WHEN (test_bypass_lock_detect = "on") ELSE clk7_tmp when (areset_ipd = '1' or pll_in_test_mode) or (pll_locked and (not reconfig_err)) else 'X'; clk8_tmp <= c_clk(i_clk8_counter); clk_pfd(8) <= clk8_tmp WHEN (pfd_locked = '1') ELSE 'X'; clk(8) <= clk_pfd(8) WHEN (test_bypass_lock_detect = "on") ELSE clk8_tmp when (areset_ipd = '1' or pll_in_test_mode) or (pll_locked and (not reconfig_err)) else 'X'; clk9_tmp <= c_clk(i_clk9_counter); clk_pfd(9) <= clk9_tmp WHEN (pfd_locked = '1') ELSE 'X'; clk(9) <= clk_pfd(9) WHEN (test_bypass_lock_detect = "on") ELSE clk9_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 -- cycloneiii_msg --/////////////////////////////////////////////////////////////////////////// -- -- Entity Name : MF_cda_mn_cntr -- -- Description : Simulation model for the M and N counter. This is a -- common model for the input counter and the loop feedback -- counter of the CycloneIII PLL. -- --/////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; USE IEEE.std_logic_unsigned.all; ENTITY MF_cda_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 MF_cda_mn_cntr; ARCHITECTURE behave of MF_cda_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 : MF_cda_scale_cntr -- -- Description : 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 StratixII PLL. -- --///////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; ENTITY MF_cda_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 MF_cda_scale_cntr; ARCHITECTURE behave of MF_cda_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 : MF_cycloneiii_pll -- -- Description : Simulation model for the StratixII 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 STD.TEXTIO.all; USE work.MF_pllpack.all; USE work.MF_cda_mn_cntr; USE work.MF_cda_scale_cntr; USE work.dffp; USE work.MF_pll_reg; -- New Features : The list below outlines key new features in TITAN: -- 1. Dynamic Phase Reconfiguration -- 2. Dynamic PLL Reconfiguration (different protocol) -- 3. More output counters ENTITY MF_cycloneiii_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"; 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 := "StratixIII"; 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 MF_cycloneiii_pll; ARCHITECTURE vital_pll of MF_cycloneiii_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 MF_cda_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 MF_cda_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 dffp 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 MF_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 inclk0_ipd <= inclk(0); inclk1_ipd <= inclk(1); areset_ipd <= areset; pfdena_ipd <= pfdena; scanclk_ipd <= scanclk; scanclkena_ipd <= scanclkena; scandata_ipd <= scandata; configupdate_ipd <= configupdate; clkswitch_ipd <= clkswitch; phaseupdown_ipd <= phaseupdown; phasestep_ipd <= phasestep; phasecounterselect_ipd(0) <= phasecounterselect(0); phasecounterselect_ipd(1) <= phasecounterselect(1); phasecounterselect_ipd(2) <= 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 : MF_cda_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 : MF_cda_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 : MF_cda_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 : MF_cda_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 : MF_cda_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 : MF_cda_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 : MF_cda_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 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; 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 -- cycloneiii_msg --/////////////////////////////////////////////////////////////////////////// -- -- Entity Name : MF_stingray_mn_cntr -- -- Description : Simulation model for the M and N counter. This is a -- common model for the input counter and the loop feedback -- counter of the CycloneIIIGL PLL. -- --/////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; USE IEEE.std_logic_unsigned.all; ENTITY MF_stingray_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 MF_stingray_mn_cntr; ARCHITECTURE behave of MF_stingray_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 : MF_stingray_post_divider -- -- Description : Simulation model that models the icdrclk output. -- --/////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; USE IEEE.std_logic_unsigned.all; ENTITY MF_stingray_post_divider is GENERIC ( dpa_divider : integer := 1 ); PORT( clk : IN std_logic; reset : IN std_logic := '0'; cout : OUT std_logic ); END MF_stingray_post_divider; ARCHITECTURE behave of MF_stingray_post_divider is begin process (clk, reset) variable count : integer := 1; variable first_rising_edge : boolean := true; variable tmp_cout : std_logic; variable modules : integer := 0; variable init : boolean := true; begin if (init = true) then if (dpa_divider = 0) then modules := 1; else modules := dpa_divider; end if; init := false; end if; 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 < modules) then count := count + 1; else count := 1; tmp_cout := not tmp_cout; end if; end if; end if; cout <= transport tmp_cout; end process; end behave; --///////////////////////////////////////////////////////////////////////////// -- -- Entity Name : MF_stingray_scale_cntr -- -- Description : 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 Stingray PLL. -- --///////////////////////////////////////////////////////////////////////////// LIBRARY IEEE; USE IEEE.std_logic_1164.all; ENTITY MF_stingray_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 MF_stingray_scale_cntr; ARCHITECTURE behave of MF_stingray_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 : MF_cycloneiiigl_pll -- -- Description : Simulation model for the Stingray 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 STD.TEXTIO.all; USE work.MF_pllpack.all; USE work.MF_stingray_mn_cntr; USE work.MF_stingray_scale_cntr; USE work.dffp; USE work.MF_pll_reg; ENTITY MF_cycloneiiigl_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; feedback_source : integer := 0; feedback_external_loop_divider : string := "false"; -- 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; dpa_multiply_by : integer := 0; dpa_divide_by : integer := 0; dpa_divider : integer := 1; 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_hint : string := "unused"; 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_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 := "Stingray"; 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; fref : out std_logic; icdrclk : out std_logic ); END MF_cycloneiiigl_pll; ARCHITECTURE vital_pll of MF_cycloneiiigl_pll is 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; -- internal advanced parameter signals signal i_vco_min : integer := vco_min * (vco_post_scale/2); signal i_vco_max : integer := vco_max * (vco_post_scale/2); 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 icdr_clk : 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 MF_stingray_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 MF_stingray_post_divider GENERIC ( dpa_divider : integer := 0 ); PORT ( clk : IN std_logic; reset : IN std_logic := '0'; cout : OUT std_logic ); END COMPONENT; COMPONENT MF_stingray_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 dffp 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 MF_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 inclk0_ipd <= inclk(0); inclk1_ipd <= inclk(1); areset_ipd <= areset; pfdena_ipd <= pfdena; scanclk_ipd <= scanclk; scanclkena_ipd <= scanclkena; scandata_ipd <= scandata; configupdate_ipd <= configupdate; clkswitch_ipd <= clkswitch; phaseupdown_ipd <= phaseupdown; phasestep_ipd <= phasestep; phasecounterselect_ipd(0) <= phasecounterselect(0); phasecounterselect_ipd(1) <= phasecounterselect(1); phasecounterselect_ipd(2) <= 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 : MF_stingray_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 : MF_stingray_mn_cntr port map ( clk => clkin, reset => areset_ipd, cout => refclk, initial_value => n_val, modulus => n_val); d1 : MF_stingray_post_divider generic map ( dpa_divider => dpa_divider) port map ( clk => inclk_m_from_vco, reset => areset_ipd, cout => icdr_clk); inclk_c0 <= refclk when c0_test_source = 1 else fbclk when c0_test_source = 0 else inclk_c_from_vco(0); c0 : MF_stingray_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 : MF_stingray_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 : MF_stingray_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 : MF_stingray_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 : MF_stingray_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 i_clk4_cntr : integer := 4; variable i_clk3_cntr : integer := 3; variable i_clk2_cntr : integer := 2; variable i_clk1_cntr : integer := 1; variable i_clk0_cntr : integer := 0; 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 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'); variable clk_index : integer := 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); i_clk0_cntr := extract_cntr_index(clk0_cntr); i_clk1_cntr := extract_cntr_index(clk1_cntr); i_clk2_cntr := extract_cntr_index(clk2_cntr); i_clk3_cntr := extract_cntr_index(clk3_cntr); i_clk4_cntr := 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 := 500; -- 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; elsif ((dpa_multiply_by /= 0) and (dpa_divide_by /= 0)) then i_n := dpa_divide_by; i_m := dpa_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; if ((compensate_clock = "iqtxrxclk") and (m /= 0)) then case feedback_source is when 0 => clk_index := i_clk0_cntr; when 1 => clk_index := i_clk1_cntr; when 2 => clk_index := i_clk2_cntr; when 3 => clk_index := i_clk3_cntr; when 4 => clk_index := i_clk4_cntr; when others => ASSERT FALSE REPORT "Invalid feedback_source value (" & int2str(feedback_source) & ")!" SEVERITY ERROR; end case; if(feedback_external_loop_divider = "true") then m_val <= i_m * (i_c_high(clk_index) + i_c_low(clk_index)) * 2; m_val_tmp := i_m * (i_c_high(clk_index) + i_c_low(clk_index)) * 2; else m_val <= i_m * (i_c_high(clk_index) + i_c_low(clk_index)); m_val_tmp := i_m * (i_c_high(clk_index) + i_c_low(clk_index)); end if; else m_val <= i_m; m_val_tmp := i_m; end if; n_val <= i_n; 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; 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' ; 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' AFTER scanclk_period; 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/2; i_vco_min <= vco_min/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; 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 time_resolution : 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 if (lpm_hint = "time_resolution=100fs") then time_resolution := 100 fs; elsif (lpm_hint = "time_resolution=10fs") then time_resolution := 10 fs; elsif (lpm_hint = "time_resolution=fs") then time_resolution := 1 fs; else time_resolution := 1 ps; end if; -- 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 locked_tmp := '0'; pll_is_locked := false; cycles_to_lock := 0; cycles_to_unlock := 0; end if; if (schedule_vco'event and (areset_ipd = '1' or stop_vco)) then if (areset_ipd = '1') then pll_is_in_reset := true; got_first_refclk := false; got_second_refclk := false; end if; -- 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 locked_tmp := '0'; 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; pll_is_in_reset := false; locked_tmp := '0'; end if; -- 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/time_resolution) rem loop_xplier; tmp_vco_per := (m_times_vco_period/time_resolution) / 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/time_resolution + 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/time_resolution) loop total_pull_back := total_pull_back - refclk_period/time_resolution; end loop; if (total_pull_back > 0) then offset := refclk_period - (total_pull_back * time_resolution); end if; fbk_delay := total_pull_back - fbk_phase; if (fbk_delay < 0) then offset := offset - (fbk_phase * time_resolution); fbk_delay := total_pull_back; end if; -- assign m_delay m_delay <= transport fbk_delay after time_resolution; my_rem := (m_times_vco_period/time_resolution) rem loop_xplier; for i in 1 to loop_xplier loop -- adjust cycles tmp_vco_per := (m_times_vco_period/time_resolution)/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 * time_resolution; high_time := (tmp_vco_per/2) * time_resolution; if (tmp_vco_per rem 2 /= 0) then high_time := high_time + time_resolution; 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; fref <= refclk; icdrclk <= icdr_clk; end vital_pll; -- END ARCHITECTURE VITAL_PLL -- START ENTITY HEADER --------------------------------------------------------- -- -- Entity Name : ALTPLL -- -- Description : Phase-Locked Loop (PLL) behavioral model. Model supports -- basic PLL features such as clock division and -- multiplication, programmable duty cycle and phase shifts, -- various feedback modes and clock delays. Also supports -- real-time reconfiguration of PLL "parameters" and clock -- switchover between the 2 input reference clocks. -- Up to 10 clock outputs may be used. -- -- Limitations : Applicable to Stratix, Stratix-GX, Stratix II and Cyclone II -- device families only. There is no support in the model for -- spread-spectrum feature. -- -- Expected results : Up to 10 different output clocks, each defined by its own -- parameters. Locked output (active high) indicates when -- the PLL locks. clkbad, clkloss and activeclock highlights -- which clock has gone bad, when clock switchover initiates, -- and which input clock (0 or 1) is the reference clock, -- respectively. scandataout is the data output of the serial -- scan chain. -- -- END ENTITY HEADER ----------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.ALTERA_DEVICE_FAMILIES.all; use work.MF_stratix_pll; use work.MF_stratixii_pll; use work.MF_stratixiii_pll; use work.MF_cycloneiii_pll; use work.MF_cycloneiiigl_pll; use work.pll_iobuf; -- ENTITY DECLARATION entity altpll is generic ( intended_device_family : string := "Stratix" ; operation_mode : string := "NORMAL" ; pll_type : string := "AUTO" ; qualify_conf_done : string := "OFF" ; compensate_clock : string := "CLK0" ; scan_chain : string := "LONG"; primary_clock : string := "inclk0" ; inclk0_input_frequency : natural; -- required parameter inclk1_input_frequency : natural := 0; gate_lock_signal : string := "NO"; gate_lock_counter : integer := 0; lock_high : natural := 1; lock_low : natural := 0; valid_lock_multiplier : natural := 1; invalid_lock_multiplier : natural := 5; switch_over_type : string := "AUTO" ; switch_over_on_lossclk : string := "OFF" ; switch_over_on_gated_lock : string := "OFF" ; enable_switch_over_counter : string := "OFF"; switch_over_counter : natural := 0; feedback_source : string := "EXTCLK0" ; bandwidth : natural := 0; bandwidth_type : string := "UNUSED"; lpm_hint : string := "UNUSED"; spread_frequency : natural := 0; down_spread : string := "0.0"; self_reset_on_gated_loss_lock : string := "OFF"; self_reset_on_loss_lock : string := "OFF"; lock_window_ui : string := "0.05"; width_clock : natural := 6; width_phasecounterselect : natural := 4; using_fbmimicbidir_port : string := "ON"; charge_pump_current_bits : natural := 9999; loop_filter_c_bits : natural := 9999; loop_filter_r_bits : natural := 9999; scan_chain_mif_file : string := "UNUSED"; -- simulation-only parameters simulation_type : string := "functional"; source_is_pll : string := "off"; skip_vco : string := "off"; -- internal clock (i.e. clock that feeds the core) specifications clk9_multiply_by : natural := 1; clk8_multiply_by : natural := 1; clk7_multiply_by : natural := 1; clk6_multiply_by : natural := 1; clk5_multiply_by : natural := 1; clk4_multiply_by : natural := 1; clk3_multiply_by : natural := 1; clk2_multiply_by : natural := 1; clk1_multiply_by : natural := 1; clk0_multiply_by : natural := 1; clk9_divide_by : natural := 1; clk8_divide_by : natural := 1; clk7_divide_by : natural := 1; clk6_divide_by : natural := 1; clk5_divide_by : natural := 1; clk4_divide_by : natural := 1; clk3_divide_by : natural := 1; clk2_divide_by : natural := 1; clk1_divide_by : natural := 1; clk0_divide_by : natural := 1; clk9_phase_shift : string := "0"; clk8_phase_shift : string := "0"; clk7_phase_shift : string := "0"; clk6_phase_shift : string := "0"; clk5_phase_shift : string := "0"; clk4_phase_shift : string := "0"; clk3_phase_shift : string := "0"; clk2_phase_shift : string := "0"; clk1_phase_shift : string := "0"; clk0_phase_shift : string := "0"; clk5_time_delay : string := "0"; clk4_time_delay : string := "0"; clk3_time_delay : string := "0"; clk2_time_delay : string := "0"; clk1_time_delay : string := "0"; clk0_time_delay : string := "0"; clk9_duty_cycle : natural := 50; clk8_duty_cycle : natural := 50; clk7_duty_cycle : natural := 50; clk6_duty_cycle : natural := 50; clk5_duty_cycle : natural := 50; clk4_duty_cycle : natural := 50; clk3_duty_cycle : natural := 50; clk2_duty_cycle : natural := 50; clk1_duty_cycle : natural := 50; clk0_duty_cycle : natural := 50; clk9_use_even_counter_mode : string := "OFF"; clk8_use_even_counter_mode : string := "OFF"; clk7_use_even_counter_mode : string := "OFF"; clk6_use_even_counter_mode : string := "OFF"; clk5_use_even_counter_mode : string := "OFF"; clk4_use_even_counter_mode : string := "OFF"; clk3_use_even_counter_mode : string := "OFF"; clk2_use_even_counter_mode : string := "OFF"; clk1_use_even_counter_mode : string := "OFF"; clk0_use_even_counter_mode : string := "OFF"; clk9_use_even_counter_value : string := "OFF"; clk8_use_even_counter_value : string := "OFF"; clk7_use_even_counter_value : string := "OFF"; clk6_use_even_counter_value : string := "OFF"; clk5_use_even_counter_value : string := "OFF"; clk4_use_even_counter_value : string := "OFF"; clk3_use_even_counter_value : string := "OFF"; clk2_use_even_counter_value : string := "OFF"; clk1_use_even_counter_value : string := "OFF"; clk0_use_even_counter_value : string := "OFF"; clk2_output_frequency : natural := 0; clk1_output_frequency : natural := 0; clk0_output_frequency : natural := 0; -- external clock (i.e. clock that feeds pins) specifications extclk3_multiply_by : natural := 1; extclk2_multiply_by : natural := 1; extclk1_multiply_by : natural := 1; extclk0_multiply_by : natural := 1; extclk3_divide_by : natural := 1; extclk2_divide_by : natural := 1; extclk1_divide_by : natural := 1; extclk0_divide_by : natural := 1; extclk3_phase_shift : string := "0"; extclk2_phase_shift : string := "0"; extclk1_phase_shift : string := "0"; extclk0_phase_shift : string := "0"; extclk3_time_delay : string := "0"; extclk2_time_delay : string := "0"; extclk1_time_delay : string := "0"; extclk0_time_delay : string := "0"; extclk3_duty_cycle : natural := 50; extclk2_duty_cycle : natural := 50; extclk1_duty_cycle : natural := 50; extclk0_duty_cycle : natural := 50; -- The following 4 parameters are for Stratix II pll in lvds mode only vco_multiply_by : integer := 0; vco_divide_by : integer := 0; sclkout0_phase_shift : string := "0"; sclkout1_phase_shift : string := "0"; dpa_multiply_by : integer := 0; dpa_divide_by : integer := 0; dpa_divider : integer := 0; -- advanced user parameters vco_min : natural := 0; vco_max : natural := 0; vco_center : natural := 0; pfd_min : natural := 0; pfd_max : natural := 0; m_initial : natural := 1; m : natural := 0; -- m must default to 0 to force altpll to calculate the internal parameters for itself n : natural := 1; m2 : natural := 1; n2 : natural := 1; ss : natural := 0; c0_high : natural := 1; c1_high : natural := 1; c2_high : natural := 1; c3_high : natural := 1; c4_high : natural := 1; c5_high : natural := 1; c6_high : natural := 1; c7_high : natural := 1; c8_high : natural := 1; c9_high : natural := 1; l0_high : natural := 1; l1_high : natural := 1; g0_high : natural := 1; g1_high : natural := 1; g2_high : natural := 1; g3_high : natural := 1; e0_high : natural := 1; e1_high : natural := 1; e2_high : natural := 1; e3_high : natural := 1; c0_low : natural := 1; c1_low : natural := 1; c2_low : natural := 1; c3_low : natural := 1; c4_low : natural := 1; c5_low : natural := 1; c6_low : natural := 1; c7_low : natural := 1; c8_low : natural := 1; c9_low : natural := 1; l0_low : natural := 1; l1_low : natural := 1; g0_low : natural := 1; g1_low : natural := 1; g2_low : natural := 1; g3_low : natural := 1; e0_low : natural := 1; e1_low : natural := 1; e2_low : natural := 1; e3_low : natural := 1; c0_initial : natural := 1; c1_initial : natural := 1; c2_initial : natural := 1; c3_initial : natural := 1; c4_initial : natural := 1; c5_initial : natural := 1; c6_initial : natural := 1; c7_initial : natural := 1; c8_initial : natural := 1; c9_initial : natural := 1; l0_initial : natural := 1; l1_initial : natural := 1; g0_initial : natural := 1; g1_initial : natural := 1; g2_initial : natural := 1; g3_initial : natural := 1; e0_initial : natural := 1; e1_initial : natural := 1; e2_initial : natural := 1; e3_initial : natural := 1; c0_mode : string := "bypass" ; c1_mode : string := "bypass" ; c2_mode : string := "bypass" ; c3_mode : string := "bypass" ; c4_mode : string := "bypass" ; c5_mode : string := "bypass" ; c6_mode : string := "bypass" ; c7_mode : string := "bypass" ; c8_mode : string := "bypass" ; c9_mode : string := "bypass" ; l0_mode : string := "bypass" ; l1_mode : string := "bypass" ; g0_mode : string := "bypass" ; g1_mode : string := "bypass" ; g2_mode : string := "bypass" ; g3_mode : string := "bypass" ; e0_mode : string := "bypass" ; e1_mode : string := "bypass" ; e2_mode : string := "bypass" ; e3_mode : string := "bypass" ; c0_ph : natural := 0; c1_ph : natural := 0; c2_ph : natural := 0; c3_ph : natural := 0; c4_ph : natural := 0; c5_ph : natural := 0; c6_ph : natural := 0; c7_ph : natural := 0; c8_ph : natural := 0; c9_ph : natural := 0; l0_ph : natural := 0; l1_ph : natural := 0; g0_ph : natural := 0; g1_ph : natural := 0; g2_ph : natural := 0; g3_ph : natural := 0; e0_ph : natural := 0; e1_ph : natural := 0; e2_ph : natural := 0; e3_ph : natural := 0; m_ph : natural := 0; l0_time_delay : natural := 0; l1_time_delay : natural := 0; g0_time_delay : natural := 0; g1_time_delay : natural := 0; g2_time_delay : natural := 0; g3_time_delay : natural := 0; e0_time_delay : natural := 0; e1_time_delay : natural := 0; e2_time_delay : natural := 0; e3_time_delay : natural := 0; m_time_delay : natural := 0; n_time_delay : natural := 0; c1_use_casc_in : string := "off"; c2_use_casc_in : string := "off"; c3_use_casc_in : string := "off"; c4_use_casc_in : string := "off"; c5_use_casc_in : string := "off"; c6_use_casc_in : string := "off"; c7_use_casc_in : string := "off"; c8_use_casc_in : string := "off"; c9_use_casc_in : string := "off"; extclk3_counter : string := "e3" ; extclk2_counter : string := "e2" ; extclk1_counter : string := "e1" ; extclk0_counter : string := "e0" ; clk9_counter : string := "c9" ; clk8_counter : string := "c8" ; clk7_counter : string := "c7" ; clk6_counter : string := "c6" ; clk5_counter : string := "l1" ; clk4_counter : string := "l0" ; clk3_counter : string := "g3" ; clk2_counter : string := "g2" ; clk1_counter : string := "g1" ; clk0_counter : string := "g0" ; enable0_counter : string := "l0"; enable1_counter : string := "l0"; charge_pump_current : natural := 2; loop_filter_r : string := " 1.000000"; loop_filter_c : natural := 5; vco_post_scale : natural := 0; vco_frequency_control : string := "AUTO"; vco_phase_shift_step : natural := 0; m_test_source : integer := 5; c0_test_source : integer := 5; c1_test_source : integer := 5; c2_test_source : integer := 5; c3_test_source : integer := 5; c4_test_source : integer := 5; c5_test_source : integer := 5; c6_test_source : integer := 5; c7_test_source : integer := 5; c8_test_source : integer := 5; c9_test_source : integer := 5; sim_gate_lock_device_behavior : string := "OFF"; lpm_type : string := "altpll"; -- The following parameter are used to define the connectivity for some -- of the input and output ports. port_clkena0 : string := "PORT_CONNECTIVITY"; port_clkena1 : string := "PORT_CONNECTIVITY"; port_clkena2 : string := "PORT_CONNECTIVITY"; port_clkena3 : string := "PORT_CONNECTIVITY"; port_clkena4 : string := "PORT_CONNECTIVITY"; port_clkena5 : string := "PORT_CONNECTIVITY"; port_extclkena0 : string := "PORT_CONNECTIVITY"; port_extclkena1 : string := "PORT_CONNECTIVITY"; port_extclkena2 : string := "PORT_CONNECTIVITY"; port_extclkena3 : string := "PORT_CONNECTIVITY"; port_extclk0 : string := "PORT_CONNECTIVITY"; port_extclk1 : string := "PORT_CONNECTIVITY"; port_extclk2 : string := "PORT_CONNECTIVITY"; port_extclk3 : string := "PORT_CONNECTIVITY"; port_clk0 : string := "PORT_CONNECTIVITY"; port_clk1 : string := "PORT_CONNECTIVITY"; port_clk2 : string := "PORT_CONNECTIVITY"; port_clk3 : string := "PORT_CONNECTIVITY"; port_clk4 : string := "PORT_CONNECTIVITY"; port_clk5 : string := "PORT_CONNECTIVITY"; port_clk6 : string := "PORT_CONNECTIVITY"; port_clk7 : string := "PORT_CONNECTIVITY"; port_clk8 : string := "PORT_CONNECTIVITY"; port_clk9 : string := "PORT_CONNECTIVITY"; port_scandata : string := "PORT_CONNECTIVITY"; port_scandataout : string := "PORT_CONNECTIVITY"; port_scandone : string := "PORT_CONNECTIVITY"; port_sclkout1 : string := "PORT_CONNECTIVITY"; port_sclkout0 : string := "PORT_CONNECTIVITY"; port_clkbad0 : string := "PORT_CONNECTIVITY"; port_clkbad1 : string := "PORT_CONNECTIVITY"; port_activeclock : string := "PORT_CONNECTIVITY"; port_clkloss : string := "PORT_CONNECTIVITY"; port_inclk1 : string := "PORT_CONNECTIVITY"; port_inclk0 : string := "PORT_CONNECTIVITY"; port_fbin : string := "PORT_CONNECTIVITY"; port_fbout : string := "PORT_CONNECTIVITY"; port_pllena : string := "PORT_CONNECTIVITY"; port_clkswitch : string := "PORT_CONNECTIVITY"; port_areset : string := "PORT_CONNECTIVITY"; port_pfdena : string := "PORT_CONNECTIVITY"; port_scanclk : string := "PORT_CONNECTIVITY"; port_scanaclr : string := "PORT_CONNECTIVITY"; port_scanread : string := "PORT_CONNECTIVITY"; port_scanwrite : string := "PORT_CONNECTIVITY"; port_enable0 : string := "PORT_CONNECTIVITY"; port_enable1 : string := "PORT_CONNECTIVITY"; port_locked : string := "PORT_CONNECTIVITY"; port_configupdate : string := "PORT_CONNECTIVITY"; port_phasecounterselect : string := "PORT_CONNECTIVITY"; port_phasedone : string := "PORT_CONNECTIVITY"; port_phasestep : string := "PORT_CONNECTIVITY"; port_phaseupdown : string := "PORT_CONNECTIVITY"; port_vcooverrange : string := "PORT_CONNECTIVITY"; port_vcounderrange : string := "PORT_CONNECTIVITY"; port_scanclkena : string := "PORT_CONNECTIVITY" ); port ( inclk : in std_logic_vector(1 downto 0) := (others => '0'); -- input clocks, up to 2 can be used fbin : in std_logic := '0'; -- external feedback port pllena : in std_logic := '1'; -- PLL enable signal clkswitch : in std_logic := '0'; -- switch between inclk0 and inclk1 areset : in std_logic := '0'; -- asynchronous reset pfdena : in std_logic := '1'; -- enable Phase Frequency Detector (PFD) clkena : in std_logic_vector(5 downto 0) := (others => '1'); -- enable clk0-clk5 outputs extclkena : in std_logic_vector(3 downto 0) := (others => '1'); -- enable extclk0-extclk3 outputs scanclk : in std_logic := '0'; -- clock for scan chain scanclkena : in std_logic := '1'; scanaclr : in std_logic := '0'; -- asynchronous clear for the scan chain scanread : in std_logic := '0'; -- determines when the scan chain can read in data from the scandata port scanwrite : in std_logic := '0'; -- determines when the scan chain can write out data into pll scandata : in std_logic := '0'; -- data for the scan chain comparator : in std_logic := '0'; -- control the enable0 pulse generation to achieve data realignment in lvds. phasecounterselect : in std_logic_vector(width_phasecounterselect-1 downto 0) := (others => '0'); phaseupdown : in std_logic := '0'; phasestep : in std_logic := '0'; configupdate : in std_logic := '0'; fbmimicbidir : inout std_logic := '1'; clk : out std_logic_vector(width_clock-1 downto 0); -- internal clock outputs (feeds the core) extclk : out std_logic_vector(3 downto 0); -- external clock outputs (feeds pins) clkbad : out std_logic_vector(1 downto 0); -- indicates if inclk0/inclk1 has gone bad enable0 : out std_logic; -- load enable pulse 0 for lvds enable1 : out std_logic; -- load enable pulse 1 for lvds activeclock : out std_logic; -- indicates which input clock is being used clkloss : out std_logic; -- indicates when clock switchover initiates locked : out std_logic; -- indicates when the PLL locks scandataout : out std_logic; -- data output from the scan chain scandone : out std_logic; -- indicates when pll reconfiguration is complete sclkout0 : out std_logic; -- serial clock output 0 for lvds sclkout1 : out std_logic; -- serial clock output 1 for lvds phasedone : out std_logic; vcooverrange : out std_logic; vcounderrange : out std_logic; fbout : out std_logic; fref : out std_logic; icdrclk : out std_logic ); end altpll; -- BEGINNING OF ARCHITECURE BEHAVIOR architecture behavior of altpll is ----------------------- -- CONSTANT DECLARATION ----------------------- constant IS_STRATIXII : boolean := FEATURE_FAMILY_STRATIXII(intended_device_family); constant IS_STRATIXIII : boolean := FEATURE_FAMILY_STRATIXIII(intended_device_family); constant IS_CYCLONEII : boolean := FEATURE_FAMILY_CYCLONEII(intended_device_family); constant IS_CYCLONEIII : boolean := FEATURE_FAMILY_CYCLONEIII(intended_device_family) or FEATURE_FAMILY_MAX10(intended_device_family); constant IS_PIRANHA : boolean := FEATURE_FAMILY_ARRIAIIGX(intended_device_family); constant IS_STINGRAY : boolean := FEATURE_FAMILY_CYCLONEIVGX(intended_device_family); -- converts uppercase parameter values (e.g. "AUTO") to lowercase ("auto") -- as expected by stratix_pll model function alpha_tolower (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin for i in 1 to string_length loop case given_string(i) is when 'A' => result_string(i) := 'a'; when 'B' => result_string(i) := 'b'; when 'C' => result_string(i) := 'c'; when 'D' => result_string(i) := 'd'; when 'E' => result_string(i) := 'e'; when 'F' => result_string(i) := 'f'; when 'G' => result_string(i) := 'g'; when 'H' => result_string(i) := 'h'; when 'I' => result_string(i) := 'i'; when 'J' => result_string(i) := 'j'; when 'K' => result_string(i) := 'k'; when 'L' => result_string(i) := 'l'; when 'M' => result_string(i) := 'm'; when 'N' => result_string(i) := 'n'; when 'O' => result_string(i) := 'o'; when 'P' => result_string(i) := 'p'; when 'Q' => result_string(i) := 'q'; when 'R' => result_string(i) := 'r'; when 'S' => result_string(i) := 's'; when 'T' => result_string(i) := 't'; when 'U' => result_string(i) := 'u'; when 'V' => result_string(i) := 'v'; when 'W' => result_string(i) := 'w'; when 'X' => result_string(i) := 'x'; when 'Y' => result_string(i) := 'y'; when 'Z' => result_string(i) := 'z'; when others => result_string(i) := given_string(i); end case; end loop; return (result_string(1 to string_length)); end; -- The following functions are used to set the default parameters' values for -- Stratix II if user do not specify these parameters' values. function get_clk0_counter (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin if (given_string = "g0") then return "c0"; else result_string(1 to string_length) := alpha_tolower(given_string); return (result_string(1 to string_length)); end if; end; -- get feedback source for stratixii function get_clk1_counter (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin if (given_string = "g1") then return "c1"; else result_string(1 to string_length) := alpha_tolower(given_string); return (result_string(1 to string_length)); end if; end; function get_clk2_counter (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin if (given_string = "g2") then return "c2"; else result_string(1 to string_length) := alpha_tolower(given_string); return (result_string(1 to string_length)); end if; end; function get_clk3_counter (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin if (given_string = "g3") then return "c3"; else result_string(1 to string_length) := alpha_tolower(given_string); return (result_string(1 to string_length)); end if; end; function get_clk4_counter (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin if (given_string = "l0") then return "c4"; else result_string(1 to string_length) := alpha_tolower(given_string); return (result_string(1 to string_length)); end if; end; function get_clk5_counter (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin if (given_string = "l1") then return "c5"; else result_string(1 to string_length) := alpha_tolower(given_string); return (result_string(1 to string_length)); end if; end; function get_clk_counter (counter_value : string; port_usage : string) return string is -- VARIABLE DECLARATION variable string_length : integer := counter_value'length; variable result_string : string(1 to 20) := " "; begin if (port_usage /= "PORT_USED") then return "unused"; else result_string(1 to string_length) := alpha_tolower(counter_value); return (result_string(1 to string_length)); end if; end; function get_enable0_counter (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin if (given_string = "l0") then return "c0"; else result_string(1 to string_length) := alpha_tolower(given_string); return (result_string(1 to string_length)); end if; end; function get_enable1_counter (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin if (given_string = "l0") then return "c1"; else result_string(1 to string_length) := alpha_tolower(given_string); return (result_string(1 to string_length)); end if; end; -- get feedback source for stratixii function get_feedback_source (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin if (given_string = "extclk0") then return "clk0"; else result_string(1 to string_length) := alpha_tolower(given_string); return (result_string(1 to string_length)); end if; end; -- get charge_pump_current for stratixii function get_charge_pump_current (m_value : integer; charge_pump_current : integer) return integer is begin if (m_value = 0) then return 52; else return charge_pump_current; end if; end; -- get loop_filter_c for stratixii function get_loop_filter_c (m_value : integer; loop_filter_c : integer) return integer is begin if (m_value = 0) then return 16; else return loop_filter_c; end if; end; function get_test_source (test_source : integer) return integer is begin if (test_source = 5) then return -1; else return test_source; end if; end; function get_vco_min_s (vco_min : integer) return integer is begin if (vco_min = 0 AND m /= 0 ) then return 1000; else return vco_min; end if; end; function get_vco_min_s2 (vco_min : integer) return integer is begin if (vco_min = 0 AND m /= 0) then return 700; else return vco_min; end if; end; function get_vco_min_c2 (vco_min : integer) return integer is begin if (vco_min = 0 AND m /= 0) then return 300; else return vco_min; end if; end; function get_vco_min_s3 (vco_min : integer) return integer is begin if (vco_min = 0 AND m /= 0) then return 100; else return vco_min; end if; end; function get_vco_min_c3 (vco_min : integer) return integer is begin if (vco_min = 0 AND m /= 0) then return 200; else return vco_min; end if; end; function get_vco_max (vco_max : integer) return integer is begin if (vco_max = 0 AND m /= 0) then return 3600; else return vco_max; end if; end; -- COMPONENT DECLARATION component MF_stratix_pll generic ( operation_mode : string := "normal"; pll_type : string := "auto"; qualify_conf_done : string := "off"; compensate_clock : string := "clk0"; scan_chain : string := "long"; primary_clock : string := "inclk0"; inclk0_input_frequency : integer := 1000; inclk1_input_frequency : integer := 1000; gate_lock_signal : string := "no"; gate_lock_counter : integer := 0; valid_lock_multiplier : integer := 1; invalid_lock_multiplier : integer := 5; switch_over_on_lossclk : string := "off"; switch_over_on_gated_lock : string := "off"; enable_switch_over_counter : string := "off"; switch_over_counter : integer := 0; feedback_source : string := "extclk0"; bandwidth : integer := 0; bandwidth_type : string := "auto"; spread_frequency : integer := 0; down_spread : string := "0.0"; simulation_type : string := "functional"; skip_vco : string := "off"; family_name : string := "Stratix"; clk0_multiply_by : integer := 1; clk0_divide_by : integer := 1; clk0_phase_shift : string := "0"; clk0_time_delay : string := "0"; clk0_duty_cycle : integer := 50; clk1_multiply_by : integer := 1; clk1_divide_by : integer := 1; clk1_phase_shift : string := "0"; clk1_time_delay : string := "0"; clk1_duty_cycle : integer := 50; clk2_multiply_by : integer := 1; clk2_divide_by : integer := 1; clk2_phase_shift : string := "0"; clk2_time_delay : string := "0"; clk2_duty_cycle : integer := 50; clk3_multiply_by : integer := 1; clk3_divide_by : integer := 1; clk3_phase_shift : string := "0"; clk3_time_delay : string := "0"; clk3_duty_cycle : integer := 50; clk4_multiply_by : integer := 1; clk4_divide_by : integer := 1; clk4_phase_shift : string := "0"; clk4_time_delay : string := "0"; clk4_duty_cycle : integer := 50; clk5_multiply_by : integer := 1; clk5_divide_by : integer := 1; clk5_phase_shift : string := "0"; clk5_time_delay : string := "0"; clk5_duty_cycle : integer := 50; extclk0_multiply_by : integer := 1; extclk0_divide_by : integer := 1; extclk0_phase_shift : string := "0"; extclk0_time_delay : string := "0"; extclk0_duty_cycle : integer := 50; extclk1_multiply_by : integer := 1; extclk1_divide_by : integer := 1; extclk1_phase_shift : string := "0"; extclk1_time_delay : string := "0"; extclk1_duty_cycle : integer := 50; extclk2_multiply_by : integer := 1; extclk2_divide_by : integer := 1; extclk2_phase_shift : string := "0"; extclk2_time_delay : string := "0"; extclk2_duty_cycle : integer := 50; extclk3_multiply_by : integer := 1; extclk3_divide_by : integer := 1; extclk3_phase_shift : string := "0"; extclk3_time_delay : string := "0"; extclk3_duty_cycle : integer := 50; vco_min : integer := 0; vco_max : integer := 0; vco_center : integer := 0; pfd_min : integer := 0; pfd_max : integer := 0; -- ADVANCED USER PARAMETERS m_initial : integer := 1; -- 1-1024 m : integer := 1; -- 1-1024 n : integer := 1; -- 1-1024 m2 : integer := 1; -- 1-1024 n2 : integer := 1; -- 1-1024 ss : integer := 0; l0_high : integer := 1; -- 1-512 l0_low : integer := 1; -- 1-512 l0_initial : integer := 1; -- 1-512 l0_mode : string := "bypass"; -- bypass,odd,even l0_ph : integer := 0; l0_time_delay : integer := 0; l1_high : integer := 1; l1_low : integer := 1; l1_initial : integer := 1; l1_mode : string := "bypass"; l1_ph : integer := 0; l1_time_delay : integer := 0; g0_high : integer := 1; g0_low : integer := 1; g0_initial : integer := 1; g0_mode : string := "bypass"; g0_ph : integer := 0; g0_time_delay : integer := 0; g1_high : integer := 1; g1_low : integer := 1; g1_initial : integer := 1; g1_mode : string := "bypass"; g1_ph : integer := 0; g1_time_delay : integer := 0; g2_high : integer := 1; g2_low : integer := 1; g2_initial : integer := 1; g2_mode : string := "bypass"; g2_ph : integer := 0; g2_time_delay : integer := 0; g3_high : integer := 1; g3_low : integer := 1; g3_initial : integer := 1; g3_mode : string := "bypass"; g3_ph : integer := 0; g3_time_delay : integer := 0; e0_high : integer := 1; e0_low : integer := 1; e0_initial : integer := 1; e0_mode : string := "bypass"; e0_ph : integer := 0; e0_time_delay : integer := 0; e1_high : integer := 1; e1_low : integer := 1; e1_initial : integer := 1; e1_mode : string := "bypass"; e1_ph : integer := 0; e1_time_delay : integer := 0; e2_high : integer := 1; e2_low : integer := 1; e2_initial : integer := 1; e2_mode : string := "bypass"; e2_ph : integer := 0; e2_time_delay : integer := 0; e3_high : integer := 1; e3_low : integer := 1; e3_initial : integer := 1; e3_mode : string := "bypass"; e3_ph : integer := 0; e3_time_delay : integer := 0; m_ph : integer := 0; m_time_delay : integer := 0; n_time_delay : integer := 0; extclk0_counter : string := "e0"; extclk1_counter : string := "e1"; extclk2_counter : string := "e2"; extclk3_counter : string := "e3"; clk0_counter : string := "g0"; clk1_counter : string := "g1"; clk2_counter : string := "g2"; clk3_counter : string := "g3"; clk4_counter : string := "l0"; clk5_counter : string := "l1"; enable0_counter : string := "l0"; enable1_counter : string := "l0"; charge_pump_current : integer := 2; loop_filter_r : string := "1.0"; loop_filter_c : natural := 5 ); port ( inclk : in std_logic_vector(1 downto 0) := (OTHERS=>'0'); fbin : in std_logic := '0'; ena : in std_logic := '1'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; clkena : in std_logic_vector(5 downto 0) := (OTHERS=>'1'); extclkena : in std_logic_vector(3 downto 0) := (OTHERS=>'1'); scanclk : in std_logic := '0'; scanaclr : in std_logic := '0'; scandata : in std_logic := '0'; clk : out std_logic_vector(5 downto 0); extclk : out std_logic_vector(3 downto 0); clkbad : out std_logic_vector(1 downto 0); activeclock : out std_logic; clkloss : out std_logic; locked : out std_logic; scandataout : out std_logic; -- lvds specific ports comparator : in std_logic := '0'; enable0 : out std_logic; enable1 : out std_logic ); end component; component MF_stratixii_pll generic ( operation_mode : string := "normal"; pll_type : string := "auto"; qualify_conf_done : string := "off"; compensate_clock : string := "clk0"; inclk0_input_frequency : integer := 1000; inclk1_input_frequency : integer := 1000; gate_lock_signal : string := "no"; gate_lock_counter : integer := 0; valid_lock_multiplier : integer := 1; invalid_lock_multiplier : integer := 5; switch_over_type : string := "auto"; switch_over_on_lossclk : string := "off"; switch_over_on_gated_lock : string := "off"; enable_switch_over_counter : string := "off"; switch_over_counter : integer := 0; feedback_source : string := "extclk0"; bandwidth : integer := 0; bandwidth_type : string := "auto"; spread_frequency : integer := 0; down_spread : string := "0.0"; self_reset_on_gated_loss_lock : string := "OFF"; simulation_type : string := "functional"; family_name : string := "StratixII"; clk0_output_frequency : natural := 0; clk0_multiply_by : integer := 1; clk0_divide_by : integer := 1; clk0_phase_shift : string := "0"; clk0_duty_cycle : integer := 50; clk1_output_frequency : natural := 0; clk1_multiply_by : integer := 1; clk1_divide_by : integer := 1; clk1_phase_shift : string := "0"; clk1_duty_cycle : integer := 50; clk2_output_frequency : natural := 0; clk2_multiply_by : integer := 1; clk2_divide_by : integer := 1; clk2_phase_shift : string := "0"; clk2_duty_cycle : integer := 50; clk3_multiply_by : integer := 1; clk3_divide_by : integer := 1; clk3_phase_shift : string := "0"; clk3_duty_cycle : integer := 50; clk4_multiply_by : integer := 1; clk4_divide_by : integer := 1; clk4_phase_shift : string := "0"; clk4_duty_cycle : integer := 50; clk5_multiply_by : integer := 1; clk5_divide_by : integer := 1; clk5_phase_shift : string := "0"; clk5_duty_cycle : integer := 50; vco_min : integer := 0; vco_max : integer := 0; vco_center : integer := 0; pfd_min : integer := 0; pfd_max : integer := 0; -- ADVANCED USER PARAMETERS m_initial : integer := 1; -- 1-1024 m : integer := 1; -- 1-1024 n : integer := 1; -- 1-1024 m2 : integer := 1; -- 1-1024 n2 : integer := 1; -- 1-1024 ss : integer := 0; c0_high : integer := 1; -- 1-512 c0_low : integer := 1; -- 1-512 c0_initial : integer := 1; -- 1-512 c0_mode : string := "bypass"; -- bypass,odd,even 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; c5_high : integer := 1; c5_low : integer := 1; c5_initial : integer := 1; c5_mode : string := "bypass"; c5_ph : integer := 0; m_ph : integer := 0; c1_use_casc_in : string := "off"; c2_use_casc_in : string := "off"; c3_use_casc_in : string := "off"; c4_use_casc_in : string := "off"; c5_use_casc_in : string := "off"; m_test_source : integer := 5; c0_test_source : integer := 5; c1_test_source : integer := 5; c2_test_source : integer := 5; c3_test_source : integer := 5; c4_test_source : integer := 5; c5_test_source : integer := 5; clk0_counter : string := "c0"; clk1_counter : string := "c1"; clk2_counter : string := "c2"; clk3_counter : string := "c3"; clk4_counter : string := "c4"; clk5_counter : string := "c5"; enable0_counter : string := "c0"; enable1_counter : string := "c0"; sclkout0_phase_shift : string := "0"; sclkout1_phase_shift : string := "0"; vco_multiply_by : integer := 0; vco_divide_by : integer := 0; charge_pump_current : integer := 2; loop_filter_r : string := "1.0"; loop_filter_c : natural := 5; sim_gate_lock_device_behavior : string := "OFF" ); port ( inclk : in std_logic_vector(1 downto 0) := (OTHERS=>'0'); fbin : in std_logic := '0'; ena : in std_logic := '1'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; scanclk : in std_logic := '1'; scanread : in std_logic := '1'; scanwrite : in std_logic := '1'; scandata : in std_logic := '1'; testin : in std_logic_vector(3 downto 0) := (OTHERS=>'0'); clk : out std_logic_vector(5 downto 0); clkbad : out std_logic_vector(1 downto 0); activeclock : out std_logic; clkloss : out std_logic; locked : out std_logic; scandataout : out std_logic; scandone : out std_logic; -- lvds specific ports enable0 : out std_logic; enable1 : out std_logic; sclkout : out std_logic_vector(1 downto 0) ); end component; component MF_stratixiii_pll generic ( operation_mode : string := "normal"; pll_type : string := "auto"; compensate_clock : string := "clk0"; inclk0_input_frequency : integer := 1000; inclk1_input_frequency : integer := 1000; self_reset_on_loss_lock : string := "off"; switch_over_type : string := "auto"; enable_switch_over_counter : string := "off"; switch_over_counter : integer := 0; bandwidth : integer := 0; bandwidth_type : string := "auto"; lock_high : integer := 0; lock_low : integer := 0; lock_window_ui : string := " 0.05"; lock_c : integer := 4; simulation_type : string := "functional"; family_name : string := "StratixIII"; clk0_output_frequency : natural := 0; clk0_multiply_by : integer := 1; clk0_divide_by : integer := 1; clk0_phase_shift : string := "0"; clk0_duty_cycle : integer := 50; clk0_use_even_counter_mode : string := "OFF"; clk0_use_even_counter_value : string := "OFF"; clk1_output_frequency : natural := 0; clk1_multiply_by : integer := 1; clk1_divide_by : integer := 1; clk1_phase_shift : string := "0"; clk1_duty_cycle : integer := 50; clk1_use_even_counter_mode : string := "OFF"; clk1_use_even_counter_value : string := "OFF"; clk2_output_frequency : natural := 0; clk2_multiply_by : integer := 1; clk2_divide_by : integer := 1; clk2_phase_shift : string := "0"; clk2_duty_cycle : integer := 50; clk2_use_even_counter_mode : string := "OFF"; clk2_use_even_counter_value : string := "OFF"; clk3_multiply_by : integer := 1; clk3_divide_by : integer := 1; clk3_phase_shift : string := "0"; clk3_duty_cycle : integer := 50; clk3_use_even_counter_mode : string := "OFF"; clk3_use_even_counter_value : string := "OFF"; clk4_multiply_by : integer := 1; clk4_divide_by : integer := 1; clk4_phase_shift : string := "0"; clk4_duty_cycle : integer := 50; clk4_use_even_counter_mode : string := "OFF"; clk4_use_even_counter_value : string := "OFF"; clk5_multiply_by : integer := 1; clk5_divide_by : integer := 1; clk5_phase_shift : string := "0"; clk5_duty_cycle : integer := 50; clk5_use_even_counter_mode : string := "OFF"; clk5_use_even_counter_value : string := "OFF"; clk6_multiply_by : integer := 1; clk6_divide_by : integer := 1; clk6_phase_shift : string := "0"; clk6_duty_cycle : integer := 50; clk6_use_even_counter_mode : string := "OFF"; clk6_use_even_counter_value : string := "OFF"; clk7_multiply_by : integer := 1; clk7_divide_by : integer := 1; clk7_phase_shift : string := "0"; clk7_duty_cycle : integer := 50; clk7_use_even_counter_mode : string := "OFF"; clk7_use_even_counter_value : string := "OFF"; clk8_multiply_by : integer := 1; clk8_divide_by : integer := 1; clk8_phase_shift : string := "0"; clk8_duty_cycle : integer := 50; clk8_use_even_counter_mode : string := "OFF"; clk8_use_even_counter_value : string := "OFF"; clk9_multiply_by : integer := 1; clk9_divide_by : integer := 1; clk9_phase_shift : string := "0"; clk9_duty_cycle : integer := 50; clk9_use_even_counter_mode : string := "OFF"; clk9_use_even_counter_value : string := "OFF"; vco_min : integer := 0; vco_max : integer := 0; vco_center : integer := 0; pfd_min : integer := 0; pfd_max : integer := 0; -- ADVANCED USER PARAMETERS m_initial : integer := 1; -- 1-1024 m : integer := 1; -- 1-1024 n : integer := 1; -- 1-1024 c0_high : integer := 1; -- 1-512 c0_low : integer := 1; -- 1-512 c0_initial : integer := 1; -- 1-512 c0_mode : string := "bypass"; -- bypass,odd,even 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; c5_high : integer := 1; c5_low : integer := 1; c5_initial : integer := 1; c5_mode : string := "bypass"; c5_ph : integer := 0; c6_high : integer := 1; c6_low : integer := 1; c6_initial : integer := 1; c6_mode : string := "bypass"; c6_ph : integer := 0; c7_high : integer := 1; c7_low : integer := 1; c7_initial : integer := 1; c7_mode : string := "bypass"; c7_ph : integer := 0; c8_high : integer := 1; c8_low : integer := 1; c8_initial : integer := 1; c8_mode : string := "bypass"; c8_ph : integer := 0; c9_high : integer := 1; c9_low : integer := 1; c9_initial : integer := 1; c9_mode : string := "bypass"; c9_ph : integer := 0; m_ph : integer := 0; c1_use_casc_in : string := "off"; c2_use_casc_in : string := "off"; c3_use_casc_in : string := "off"; c4_use_casc_in : string := "off"; c5_use_casc_in : string := "off"; c6_use_casc_in : string := "off"; c7_use_casc_in : string := "off"; c8_use_casc_in : string := "off"; c9_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; c5_test_source : integer := -1; c6_test_source : integer := -1; c7_test_source : integer := -1; c8_test_source : integer := -1; c9_test_source : integer := -1; clk0_counter : string := "c0"; clk1_counter : string := "c1"; clk2_counter : string := "c2"; clk3_counter : string := "c3"; clk4_counter : string := "c4"; clk5_counter : string := "c5"; clk6_counter : string := "c6"; clk7_counter : string := "c7"; clk8_counter : string := "c8"; clk9_counter : string := "c9"; vco_multiply_by : integer := 0; vco_divide_by : integer := 0; dpa_multiply_by : integer := 0; dpa_divide_by : integer := 0; dpa_divider : integer := 0; vco_frequency_control : string := "AUTO"; vco_phase_shift_step : natural := 0; charge_pump_current_bits : natural := 9999; loop_filter_c_bits : natural := 9999; loop_filter_r_bits : natural := 9999; charge_pump_current : integer := 2; loop_filter_r : string := "1.0"; loop_filter_c : natural := 5 ); port ( inclk : in std_logic_vector(1 downto 0) := (OTHERS=>'0'); fbin : in std_logic := '0'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; scanclk : in std_logic := '1'; scandata : in std_logic := '1'; scanclkena : in std_logic := '1'; configupdate : in std_logic := '0'; phasecounterselect : in std_logic_vector(3 downto 0) := (OTHERS=>'0'); phaseupdown : in std_logic := '0'; phasestep : in std_logic := '0'; clk : out std_logic_vector(9 downto 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; fbout : out std_logic ); end component; component MF_cycloneiii_pll generic ( operation_mode : string := "normal"; pll_type : string := "auto"; compensate_clock : string := "clk0"; inclk0_input_frequency : integer := 1000; inclk1_input_frequency : integer := 1000; self_reset_on_loss_lock : string := "off"; switch_over_type : string := "auto"; enable_switch_over_counter : string := "off"; switch_over_counter : integer := 0; bandwidth : integer := 0; bandwidth_type : string := "auto"; lock_high : integer := 0; lock_low : integer := 0; lock_window_ui : string := "0.05"; lock_c : integer := 4; simulation_type : string := "functional"; family_name : string := "CycloneIII"; clk0_output_frequency : natural := 0; clk0_multiply_by : integer := 1; clk0_divide_by : integer := 1; clk0_phase_shift : string := "0"; clk0_duty_cycle : integer := 50; clk0_use_even_counter_mode : string := "OFF"; clk0_use_even_counter_value : string := "OFF"; clk1_output_frequency : natural := 0; clk1_multiply_by : integer := 1; clk1_divide_by : integer := 1; clk1_phase_shift : string := "0"; clk1_duty_cycle : integer := 50; clk1_use_even_counter_mode : string := "OFF"; clk1_use_even_counter_value : string := "OFF"; clk2_output_frequency : natural := 0; clk2_multiply_by : integer := 1; clk2_divide_by : integer := 1; clk2_phase_shift : string := "0"; clk2_duty_cycle : integer := 50; clk2_use_even_counter_mode : string := "OFF"; clk2_use_even_counter_value : string := "OFF"; clk3_multiply_by : integer := 1; clk3_divide_by : integer := 1; clk3_phase_shift : string := "0"; clk3_duty_cycle : integer := 50; clk3_use_even_counter_mode : string := "OFF"; clk3_use_even_counter_value : string := "OFF"; clk4_multiply_by : integer := 1; clk4_divide_by : integer := 1; clk4_phase_shift : string := "0"; clk4_duty_cycle : integer := 50; clk4_use_even_counter_mode : string := "OFF"; clk4_use_even_counter_value : string := "OFF"; vco_min : integer := 0; vco_max : integer := 0; vco_center : integer := 0; pfd_min : integer := 0; pfd_max : integer := 0; -- ADVANCED USER PARAMETERS m_initial : integer := 1; -- 1-1024 m : integer := 1; -- 1-1024 n : integer := 1; -- 1-1024 c0_high : integer := 1; -- 1-512 c0_low : integer := 1; -- 1-512 c0_initial : integer := 1; -- 1-512 c0_mode : string := "bypass"; -- bypass,odd,even 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; 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; clk0_counter : string := "c0"; clk1_counter : string := "c1"; clk2_counter : string := "c2"; clk3_counter : string := "c3"; clk4_counter : string := "c4"; vco_multiply_by : integer := 0; vco_divide_by : integer := 0; vco_frequency_control : string := "AUTO"; vco_phase_shift_step : natural := 0; charge_pump_current_bits : natural := 9999; loop_filter_c_bits : natural := 9999; loop_filter_r_bits : natural := 9999; charge_pump_current : integer := 2; loop_filter_r : string := "1.0"; loop_filter_c : natural := 5 ); port ( inclk : in std_logic_vector(1 downto 0) := (OTHERS=>'0'); fbin : in std_logic := '0'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; scanclk : in std_logic := '1'; scandata : in std_logic := '1'; scanclkena : in std_logic := '1'; configupdate : in std_logic := '0'; phasecounterselect : in std_logic_vector(2 downto 0) := (OTHERS=>'0'); phaseupdown : in std_logic := '0'; phasestep : in std_logic := '0'; clk : out std_logic_vector(4 downto 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; fbout : out std_logic ); end component; component MF_cycloneiiigl_pll generic ( operation_mode : string := "normal"; pll_type : string := "auto"; compensate_clock : string := "clk0"; inclk0_input_frequency : integer := 1000; inclk1_input_frequency : integer := 1000; self_reset_on_loss_lock : string := "off"; switch_over_type : string := "auto"; enable_switch_over_counter : string := "off"; switch_over_counter : integer := 0; bandwidth : integer := 0; bandwidth_type : string := "auto"; lock_high : integer := 0; lock_low : integer := 0; lock_window_ui : string := "0.05"; lock_c : integer := 4; simulation_type : string := "functional"; family_name : string := "CycloneIIIGL"; lpm_hint : string := "unused"; clk0_output_frequency : natural := 0; clk0_multiply_by : integer := 1; clk0_divide_by : integer := 1; clk0_phase_shift : string := "0"; clk0_duty_cycle : integer := 50; clk0_use_even_counter_mode : string := "OFF"; clk0_use_even_counter_value : string := "OFF"; clk1_output_frequency : natural := 0; clk1_multiply_by : integer := 1; clk1_divide_by : integer := 1; clk1_phase_shift : string := "0"; clk1_duty_cycle : integer := 50; clk1_use_even_counter_mode : string := "OFF"; clk1_use_even_counter_value : string := "OFF"; clk2_output_frequency : natural := 0; clk2_multiply_by : integer := 1; clk2_divide_by : integer := 1; clk2_phase_shift : string := "0"; clk2_duty_cycle : integer := 50; clk2_use_even_counter_mode : string := "OFF"; clk2_use_even_counter_value : string := "OFF"; clk3_multiply_by : integer := 1; clk3_divide_by : integer := 1; clk3_phase_shift : string := "0"; clk3_duty_cycle : integer := 50; clk3_use_even_counter_mode : string := "OFF"; clk3_use_even_counter_value : string := "OFF"; clk4_multiply_by : integer := 1; clk4_divide_by : integer := 1; clk4_phase_shift : string := "0"; clk4_duty_cycle : integer := 50; clk4_use_even_counter_mode : string := "OFF"; clk4_use_even_counter_value : string := "OFF"; vco_min : integer := 0; vco_max : integer := 0; vco_center : integer := 0; dpa_multiply_by : integer := 0; dpa_divide_by : integer := 0; dpa_divider : integer := 0; pfd_min : integer := 0; pfd_max : integer := 0; -- ADVANCED USER PARAMETERS m_initial : integer := 1; -- 1-1024 m : integer := 1; -- 1-1024 n : integer := 1; -- 1-1024 c0_high : integer := 1; -- 1-512 c0_low : integer := 1; -- 1-512 c0_initial : integer := 1; -- 1-512 c0_mode : string := "bypass"; -- bypass,odd,even 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; 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; clk0_counter : string := "c0"; clk1_counter : string := "c1"; clk2_counter : string := "c2"; clk3_counter : string := "c3"; clk4_counter : string := "c4"; vco_multiply_by : integer := 0; vco_divide_by : integer := 0; vco_frequency_control : string := "AUTO"; vco_phase_shift_step : natural := 0; charge_pump_current_bits : natural := 9999; loop_filter_c_bits : natural := 9999; loop_filter_r_bits : natural := 9999; charge_pump_current : integer := 2; loop_filter_r : string := "1.0"; loop_filter_c : natural := 5 ); port ( inclk : in std_logic_vector(1 downto 0) := (OTHERS=>'0'); fbin : in std_logic := '0'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; scanclk : in std_logic := '1'; scandata : in std_logic := '1'; scanclkena : in std_logic := '1'; configupdate : in std_logic := '0'; phasecounterselect : in std_logic_vector(2 downto 0) := (OTHERS=>'0'); phaseupdown : in std_logic := '0'; phasestep : in std_logic := '0'; clk : out std_logic_vector(4 downto 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; fbout : out std_logic; fref : out std_logic; icdrclk : out std_logic ); end component; component pll_iobuf port ( i : in std_logic; oe : in std_logic; io : inout std_logic; o : out std_logic ); end component; signal locked_tmp : std_logic; signal clk_tmp : std_logic_vector(6 downto 0); signal fbin_wire : std_logic; signal pllena_wire : std_logic; signal clkswitch_wire : std_logic; signal areset_wire : std_logic; signal pfdena_wire : std_logic; signal scanclk_wire : std_logic; signal scanaclr_wire : std_logic; signal scanread_wire : std_logic; signal scanwrite_wire : std_logic; signal scandata_wire : std_logic; signal clkena_wire : std_logic_vector(5 downto 0); signal extclkena_wire : std_logic_vector(3 downto 0); signal clk_wire : std_logic_vector(9 downto 0); signal extclk_wire : std_logic_vector(3 downto 0); signal clkbad_wire : std_logic_vector(1 downto 0); signal activeclock_wire : std_logic; signal clkloss_wire : std_logic; signal scandataout_wire : std_logic; signal scandone_wire : std_logic; signal sclkout0_wire : std_logic; signal sclkout1_wire : std_logic; signal locked_wire : std_logic; signal configupdate_wire : std_logic; signal phasecounterselect_wire : std_logic_vector(3 downto 0); signal phasestep_wire : std_logic; signal phaseupdown_wire : std_logic; signal scanclkena_wire : std_logic; signal phasedone_wire : std_logic; signal vcooverrange_wire : std_logic; signal vcounderrange_wire : std_logic; signal fbout_wire : std_logic; signal iobuf_o : std_logic; signal stratix3_fbin : std_logic; signal oe_wire : std_logic; signal pll_lock_sync : std_logic := '1'; signal fref_wire : std_logic; signal icdrclk_wire : std_logic; begin -- checking for invalid parameters MSG: process begin if (clk5_multiply_by <= 0) then ASSERT FALSE REPORT "The clk5_multiply_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk4_multiply_by <= 0) then ASSERT FALSE REPORT "The clk4_multiply_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk3_multiply_by <= 0) then ASSERT FALSE REPORT "The clk3_multiply_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk2_multiply_by <= 0) then ASSERT FALSE REPORT "The clk2_multiply_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk1_multiply_by <= 0) then ASSERT FALSE REPORT "The clk1_multiply_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk0_multiply_by <= 0) then ASSERT FALSE REPORT "The clk0_multiply_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk5_divide_by <= 0) then ASSERT FALSE REPORT "The clk5_divide_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk4_divide_by <= 0) then ASSERT FALSE REPORT "The clk4_divide_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk3_divide_by <= 0) then ASSERT FALSE REPORT "The clk3_divide_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk2_divide_by <= 0) then ASSERT FALSE REPORT "The clk2_divide_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk1_divide_by <= 0) then ASSERT FALSE REPORT "The clk1_divide_by parameter must be greater than 0" SEVERITY ERROR; end if; if (clk0_divide_by <= 0) then ASSERT FALSE REPORT "The clk0_divide_by parameter must be greater than 0" SEVERITY ERROR; end if; if (extclk3_multiply_by <= 0) then ASSERT FALSE REPORT "The extclk3_multiply_by parameter must be greater than 0" SEVERITY ERROR; end if; if (extclk2_multiply_by <= 0) then ASSERT FALSE REPORT "The extclk2_multiply_by parameter must be greater than 0" SEVERITY ERROR; end if; if (extclk1_multiply_by <= 0) then ASSERT FALSE REPORT "The extclk1_multiply_by parameter must be greater than 0" SEVERITY ERROR; end if; if (extclk0_multiply_by <= 0) then ASSERT FALSE REPORT "The extclk0_multiply_by parameter must be greater than 0" SEVERITY ERROR; end if; if (extclk3_divide_by <= 0) then ASSERT FALSE REPORT "The extclk3_divide_by parameter must be greater than 0" SEVERITY ERROR; end if; if (extclk2_divide_by <= 0) then ASSERT FALSE REPORT "The extclk2_divide_by parameter must be greater than 0" SEVERITY ERROR; end if; if (extclk1_divide_by <= 0) then ASSERT FALSE REPORT "The extclk1_divide_by parameter must be greater than 0" SEVERITY ERROR; end if; if (extclk0_divide_by <= 0) then ASSERT FALSE REPORT "The extclk0_divide_by parameter must be greater than 0" SEVERITY ERROR; end if; if not ((alpha_tolower(primary_clock) = "inclk0") or (alpha_tolower(primary_clock) = "inclk1")) then ASSERT FALSE REPORT "The primary clock is set to an illegal value" SEVERITY ERROR; end if; if ((IS_PIRANHA) and (alpha_tolower(operation_mode) = "external_feedback")) then ASSERT FALSE REPORT "The external feedback mode is not supported for the ARRIA II family." SEVERITY ERROR; end if; if((IS_PIRANHA) and (alpha_tolower(pll_type) = "top_bottom")) then ASSERT FALSE REPORT "A pll_type specification is not supported for the ARRIA II family. It will be ignored." SEVERITY WARNING; end if; if((IS_PIRANHA) and ((port_clk7 /= "PORT_UNUSED") or (port_clk8 /= "PORT_UNUSED") or (port_clk9 /= "PORT_UNUSED"))) then ASSERT FALSE REPORT "One or more clock outputs used in the design are not supported in ARRIA II family." SEVERITY ERROR; end if; wait; end process MSG; -- For fast mode, the stratix pll atom model will give active low signal on locked output. -- Therefore, need to invert the lock signal for fast mode as in user view, locked signal is -- always active high. locked_wire <= (not locked_tmp) when ((not IS_STRATIXII) and (not IS_CYCLONEII) and alpha_tolower(pll_type) = "fast") else (locked_tmp and pll_lock_sync) when (IS_STRATIXIII) or (IS_CYCLONEIII) else locked_tmp; clkena_wire(0) <= clkena(0) when ((alpha_tolower(pll_type) /= "fast") or (port_clkena0 = "PORT_USED")) and (port_clkena0 /= "PORT_UNUSED") else '1'; clkena_wire(1) <= clkena(1) when ((alpha_tolower(pll_type) /= "fast") or (port_clkena1 = "PORT_USED")) and (port_clkena1 /= "PORT_UNUSED") else '1'; clkena_wire(2) <= clkena(2) when ((alpha_tolower(pll_type) /= "fast") or (port_clkena2 = "PORT_USED")) and (port_clkena2 /= "PORT_UNUSED") else '1'; clkena_wire(3) <= clkena(3) when ((alpha_tolower(pll_type) /= "fast") or (port_clkena3 = "PORT_USED")) and (port_clkena3 /= "PORT_UNUSED") else '1'; clkena_wire(4) <= clkena(4) when ((alpha_tolower(pll_type) /= "fast") or (port_clkena4 = "PORT_USED")) and (port_clkena4 /= "PORT_UNUSED") else '1'; clkena_wire(5) <= clkena(5) when ((alpha_tolower(pll_type) /= "fast") or (port_clkena5 = "PORT_USED")) and (port_clkena5 /= "PORT_UNUSED") else '1'; extclkena_wire(0) <= extclkena(0) when ((alpha_tolower(pll_type) /= "fast") or (port_extclkena0 = "PORT_USED")) and (port_extclkena0 /= "PORT_UNUSED") else '1'; extclkena_wire(1) <= extclkena(1) when ((alpha_tolower(pll_type) /= "fast") or (port_extclkena1 = "PORT_USED")) and (port_extclkena1 /= "PORT_UNUSED") else '1'; extclkena_wire(2) <= extclkena(2) when ((alpha_tolower(pll_type) /= "fast") or (port_extclkena2 = "PORT_USED")) and (port_extclkena2 /= "PORT_UNUSED") else '1'; extclkena_wire(3) <= extclkena(3) when ((alpha_tolower(pll_type) /= "fast") or (port_extclkena3 = "PORT_USED")) and (port_extclkena3 /= "PORT_UNUSED") else '1'; fbin_wire <= fbin when ((port_fbin = "PORT_CONNECTIVITY") or (port_fbin = "PORT_USED")) else '0'; pllena_wire <= pllena when ((port_pllena = "PORT_CONNECTIVITY") or (port_pllena = "PORT_USED")) else '1'; clkswitch_wire <= clkswitch when ((port_clkswitch = "PORT_CONNECTIVITY") or (port_clkswitch = "PORT_USED")) else '0'; areset_wire <= areset when ((port_areset = "PORT_CONNECTIVITY") or (port_areset = "PORT_USED")) else '0'; pfdena_wire <= pfdena when ((port_pfdena = "PORT_CONNECTIVITY") or (port_pfdena = "PORT_USED")) else '1'; scanclk_wire <= scanclk when (port_scanclk /= "PORT_UNUSED") else '0'; scandata_wire <= scandata when (port_scandata /= "PORT_UNUSED") else '0'; scanaclr_wire <= scanaclr when (port_scanaclr /= "PORT_UNUSED") else '0'; scanread_wire <= scanread when (port_scanread /= "PORT_UNUSED") else '0'; scanwrite_wire <= scanwrite when (port_scanwrite /= "PORT_UNUSED") else '0'; configupdate_wire <= configupdate when (port_configupdate /= "PORT_UNUSED") else '0'; phasecounterselect_wire(width_phasecounterselect-1 downto 0) <= phasecounterselect(width_phasecounterselect-1 downto 0) when (port_phasecounterselect /= "PORT_UNUSED") else (others => '0'); phasecounterselect3 : if (width_phasecounterselect < 3) generate phasecounterselect_wire(3) <= '0'; end generate phasecounterselect3; phasestep_wire <= phasestep when (port_phasestep /= "PORT_UNUSED") else '0'; phaseupdown_wire <= phaseupdown when (port_phaseupdown /= "PORT_UNUSED") else '0'; scanclkena_wire <= scanclkena when (port_scanclkena /= "PORT_UNUSED") else '1'; clk(0) <= clk_wire(0) when (port_clk0 /= "PORT_UNUSED") else '0'; clk(1) <= clk_wire(1) when (port_clk1 /= "PORT_UNUSED") else '0'; clk(2) <= clk_wire(2) when (port_clk2 /= "PORT_UNUSED") else '0'; clk(3) <= clk_wire(3) when (port_clk3 /= "PORT_UNUSED") else '0'; clk(4) <= clk_wire(4) when (port_clk4 /= "PORT_UNUSED") else '0'; CLK5 : if (width_clock = 6) generate clk(5) <= clk_wire(5) when (port_clk5 /= "PORT_UNUSED") else '0'; end generate CLK5; CLK5TO6: if (width_clock = 7) generate clk(5) <= clk_wire(5) when (port_clk5 /= "PORT_UNUSED") else '0'; clk(6) <= clk_wire(6) when (port_clk6 /= "PORT_UNUSED") else '0'; end generate CLK5TO6; CLK5TO9: if (width_clock = 10) generate clk(5) <= clk_wire(5) when (port_clk5 /= "PORT_UNUSED") else '0'; clk(6) <= clk_wire(6) when (port_clk6 /= "PORT_UNUSED") else '0'; clk(7) <= clk_wire(7) when (port_clk7 /= "PORT_UNUSED") else '0'; clk(8) <= clk_wire(8) when (port_clk8 /= "PORT_UNUSED") else '0'; clk(9) <= clk_wire(9) when (port_clk9 /= "PORT_UNUSED") else '0'; end generate CLK5TO9; extclk(0) <= extclk_wire(0) when (port_extclk0 /= "PORT_UNUSED") else '0'; extclk(1) <= extclk_wire(1) when (port_extclk1 /= "PORT_UNUSED") else '0'; extclk(2) <= extclk_wire(2) when (port_extclk2 /= "PORT_UNUSED") else '0'; extclk(3) <= extclk_wire(3) when (port_extclk3 /= "PORT_UNUSED") else '0'; clkbad(0) <= clkbad_wire(0) when (port_clkbad0 /= "PORT_UNUSED") else '0'; clkbad(1) <= clkbad_wire(1) when (port_clkbad1 /= "PORT_UNUSED") else '0'; activeclock <= activeclock_wire when (port_activeclock /= "PORT_UNUSED") else '0'; clkloss <= clkloss_wire when (port_clkloss /= "PORT_UNUSED") else '0'; scandataout <= scandataout_wire when (port_scandataout /= "PORT_UNUSED") else '0'; scandone <= scandone_wire when (port_scandone /= "PORT_UNUSED") else '0'; sclkout0 <= sclkout0_wire when (port_sclkout0 /= "PORT_UNUSED") else '0'; sclkout1 <= sclkout1_wire when (port_sclkout1 /= "PORT_UNUSED") else '0'; locked <= locked_wire when (port_locked /= "PORT_UNUSED") else '0'; phasedone <= phasedone_wire when (port_phasedone /= "PORT_UNUSED") else '0'; vcooverrange <= vcooverrange_wire when (port_vcooverrange /= "PORT_UNUSED") else '0'; vcounderrange <= vcounderrange_wire when (port_vcounderrange /= "PORT_UNUSED") else '0'; fbout <= fbout_wire when (port_fbout /= "PORT_UNUSED") else '0'; stratix3_fbin <= iobuf_o when ((using_fbmimicbidir_port = "ON") and (alpha_tolower(operation_mode) = "zero_delay_buffer") and (IS_STRATIXIII) and (not IS_PIRANHA)) else fbout_wire when ((alpha_tolower(operation_mode) = "zero_delay_buffer") and (IS_PIRANHA)) else fbin; oe_wire <= '1'; fref <= fref_wire; icdrclk <= icdrclk_wire; -- Instantiate stratix_pll STRATIX_ALTPLL: if (FEATURE_FAMILY_HAS_STRATIX_STYLE_PLL(intended_device_family) = true) generate M0: MF_stratix_pll generic map( operation_mode => alpha_tolower(operation_mode), pll_type => alpha_tolower(pll_type), qualify_conf_done => alpha_tolower(qualify_conf_done), compensate_clock => alpha_tolower(compensate_clock), scan_chain => alpha_tolower(scan_chain), primary_clock => alpha_tolower(primary_clock), inclk0_input_frequency => inclk0_input_frequency, inclk1_input_frequency => inclk1_input_frequency, gate_lock_signal => alpha_tolower(gate_lock_signal), gate_lock_counter => gate_lock_counter, valid_lock_multiplier => valid_lock_multiplier, invalid_lock_multiplier => invalid_lock_multiplier, switch_over_on_lossclk => alpha_tolower(switch_over_on_lossclk), switch_over_on_gated_lock => alpha_tolower(switch_over_on_gated_lock), enable_switch_over_counter => alpha_tolower(enable_switch_over_counter), switch_over_counter => switch_over_counter, feedback_source => alpha_tolower(feedback_source), bandwidth => bandwidth, bandwidth_type => alpha_tolower(bandwidth_type), spread_frequency => spread_frequency, down_spread => down_spread, simulation_type => alpha_tolower(simulation_type), skip_vco => alpha_tolower(skip_vco), family_name => intended_device_family, -- internal clock specifications clk5_multiply_by => clk5_multiply_by, clk4_multiply_by => clk4_multiply_by, clk3_multiply_by => clk3_multiply_by, clk2_multiply_by => clk2_multiply_by, clk1_multiply_by => clk1_multiply_by, clk0_multiply_by => clk0_multiply_by, clk5_divide_by => clk5_divide_by, clk4_divide_by => clk4_divide_by, clk3_divide_by => clk3_divide_by, clk2_divide_by => clk2_divide_by, clk1_divide_by => clk1_divide_by, clk0_divide_by => clk0_divide_by, clk5_phase_shift => clk5_phase_shift, clk4_phase_shift => clk4_phase_shift, clk3_phase_shift => clk3_phase_shift, clk2_phase_shift => clk2_phase_shift, clk1_phase_shift => clk1_phase_shift, clk0_phase_shift => clk0_phase_shift, clk5_time_delay => clk5_time_delay, clk4_time_delay => clk4_time_delay, clk3_time_delay => clk3_time_delay, clk2_time_delay => clk2_time_delay, clk1_time_delay => clk1_time_delay, clk0_time_delay => clk0_time_delay, clk5_duty_cycle => clk5_duty_cycle, clk4_duty_cycle => clk4_duty_cycle, clk3_duty_cycle => clk3_duty_cycle, clk2_duty_cycle => clk2_duty_cycle, clk1_duty_cycle => clk1_duty_cycle, clk0_duty_cycle => clk0_duty_cycle, -- external clock specifications extclk3_multiply_by => extclk3_multiply_by, extclk2_multiply_by => extclk2_multiply_by, extclk1_multiply_by => extclk1_multiply_by, extclk0_multiply_by => extclk0_multiply_by, extclk3_divide_by => extclk3_divide_by, extclk2_divide_by => extclk2_divide_by, extclk1_divide_by => extclk1_divide_by, extclk0_divide_by => extclk0_divide_by, extclk3_phase_shift => extclk3_phase_shift, extclk2_phase_shift => extclk2_phase_shift, extclk1_phase_shift => extclk1_phase_shift, extclk0_phase_shift => extclk0_phase_shift, extclk3_time_delay => extclk3_time_delay, extclk2_time_delay => extclk2_time_delay, extclk1_time_delay => extclk1_time_delay, extclk0_time_delay => extclk0_time_delay, extclk3_duty_cycle => extclk3_duty_cycle, extclk2_duty_cycle => extclk2_duty_cycle, extclk1_duty_cycle => extclk1_duty_cycle, extclk0_duty_cycle => extclk0_duty_cycle, -- advanced user parameters vco_min => get_vco_min_s(vco_min), vco_max => get_vco_max(vco_max), vco_center => vco_center, pfd_min => pfd_min, pfd_max => pfd_max, m_initial => m_initial, m => m, n => n, m2 => m2, n2 => n2, ss => ss, l0_high => l0_high, l1_high => l1_high, g0_high => g0_high, g1_high => g1_high, g2_high => g2_high, g3_high => g3_high, e0_high => e0_high, e1_high => e1_high, e2_high => e2_high, e3_high => e3_high, l0_low => l0_low, l1_low => l1_low, g0_low => g0_low, g1_low => g1_low, g2_low => g2_low, g3_low => g3_low, e0_low => e0_low, e1_low => e1_low, e2_low => e2_low, e3_low => e3_low, l0_initial => l0_initial, l1_initial => l1_initial, g0_initial => g0_initial, g1_initial => g1_initial, g2_initial => g2_initial, g3_initial => g3_initial, e0_initial => e0_initial, e1_initial => e1_initial, e2_initial => e2_initial, e3_initial => e3_initial, l0_mode => alpha_tolower(l0_mode), l1_mode => alpha_tolower(l1_mode), g0_mode => alpha_tolower(g0_mode), g1_mode => alpha_tolower(g1_mode), g2_mode => alpha_tolower(g2_mode), g3_mode => alpha_tolower(g3_mode), e0_mode => alpha_tolower(e0_mode), e1_mode => alpha_tolower(e1_mode), e2_mode => alpha_tolower(e2_mode), e3_mode => alpha_tolower(e3_mode), l0_ph => l0_ph, l1_ph => l1_ph, g0_ph => g0_ph, g1_ph => g1_ph, g2_ph => g2_ph, g3_ph => g3_ph, e0_ph => e0_ph, e1_ph => e1_ph, e2_ph => e2_ph, e3_ph => e3_ph, m_ph => m_ph, l0_time_delay => l0_time_delay, l1_time_delay => l1_time_delay, g0_time_delay => g0_time_delay, g1_time_delay => g1_time_delay, g2_time_delay => g2_time_delay, g3_time_delay => g3_time_delay, e0_time_delay => e0_time_delay, e1_time_delay => e1_time_delay, e2_time_delay => e2_time_delay, e3_time_delay => e3_time_delay, m_time_delay => m_time_delay, n_time_delay => n_time_delay, extclk3_counter => alpha_tolower(extclk3_counter), extclk2_counter => alpha_tolower(extclk2_counter), extclk1_counter => alpha_tolower(extclk1_counter), extclk0_counter => alpha_tolower(extclk0_counter), clk5_counter => alpha_tolower(clk5_counter), clk4_counter => alpha_tolower(clk4_counter), clk3_counter => alpha_tolower(clk3_counter), clk2_counter => alpha_tolower(clk2_counter), clk1_counter => alpha_tolower(clk1_counter), clk0_counter => alpha_tolower(clk0_counter), enable0_counter => alpha_tolower(enable0_counter), enable1_counter => alpha_tolower(enable1_counter), charge_pump_current => charge_pump_current, loop_filter_r => loop_filter_r, loop_filter_c => loop_filter_c ) port map ( inclk => inclk, fbin => fbin_wire, ena => pllena_wire, clkswitch => clkswitch_wire, areset => areset_wire, pfdena => pfdena_wire, clkena => clkena_wire, extclkena => extclkena_wire, scanclk => scanclk_wire, scanaclr => scanaclr_wire, scandata => scandata_wire, comparator => comparator, clk(0) => clk_wire(0), clk(1) => clk_wire(1), clk(2) => clk_wire(2), clk(3) => clk_wire(3), clk(4) => clk_wire(4), clk(5) => clk_wire(5), extclk => extclk_wire, clkbad => clkbad_wire, enable0 => enable0, enable1 => enable1, activeclock => activeclock_wire, clkloss => clkloss_wire, locked => locked_tmp, scandataout => scandataout_wire ); end generate STRATIX_ALTPLL; -- Instantiate stratixii_pll STRATIXII_ALTPLL: if ((FEATURE_FAMILY_HAS_STRATIXII_STYLE_PLL(intended_device_family) = true) and (FEATURE_FAMILY_BASE_CYCLONEII(intended_device_family) = false)) generate M1 : MF_stratixii_pll generic map( operation_mode => alpha_tolower(operation_mode), pll_type => alpha_tolower(pll_type), qualify_conf_done => alpha_tolower(qualify_conf_done), compensate_clock => alpha_tolower(compensate_clock), inclk0_input_frequency => inclk0_input_frequency, inclk1_input_frequency => inclk1_input_frequency, gate_lock_signal => alpha_tolower(gate_lock_signal), gate_lock_counter => gate_lock_counter, valid_lock_multiplier => valid_lock_multiplier, invalid_lock_multiplier => invalid_lock_multiplier, switch_over_type => alpha_tolower(switch_over_type), switch_over_on_lossclk => alpha_tolower(switch_over_on_lossclk), switch_over_on_gated_lock => alpha_tolower(switch_over_on_gated_lock), enable_switch_over_counter => alpha_tolower(enable_switch_over_counter), switch_over_counter => switch_over_counter, feedback_source => get_feedback_source(feedback_source), bandwidth => bandwidth, bandwidth_type => alpha_tolower(bandwidth_type), spread_frequency => spread_frequency, down_spread => down_spread, self_reset_on_gated_loss_lock => self_reset_on_gated_loss_lock, simulation_type => alpha_tolower(simulation_type), family_name => intended_device_family, -- internal clock specifications clk5_multiply_by => clk5_multiply_by, clk4_multiply_by => clk4_multiply_by, clk3_multiply_by => clk3_multiply_by, clk2_multiply_by => clk2_multiply_by, clk1_multiply_by => clk1_multiply_by, clk0_multiply_by => clk0_multiply_by, clk5_divide_by => clk5_divide_by, clk4_divide_by => clk4_divide_by, clk3_divide_by => clk3_divide_by, clk2_divide_by => clk2_divide_by, clk1_divide_by => clk1_divide_by, clk0_divide_by => clk0_divide_by, clk5_phase_shift => clk5_phase_shift, clk4_phase_shift => clk4_phase_shift, clk3_phase_shift => clk3_phase_shift, clk2_phase_shift => clk2_phase_shift, clk1_phase_shift => clk1_phase_shift, clk0_phase_shift => clk0_phase_shift, clk5_duty_cycle => clk5_duty_cycle, clk4_duty_cycle => clk4_duty_cycle, clk3_duty_cycle => clk3_duty_cycle, clk2_duty_cycle => clk2_duty_cycle, clk1_duty_cycle => clk1_duty_cycle, clk0_duty_cycle => clk0_duty_cycle, -- advanced user parameters vco_min => get_vco_min_s2(vco_min), vco_max => get_vco_max(vco_max), vco_center => vco_center, pfd_min => pfd_min, pfd_max => pfd_max, m_initial => m_initial, m => m, n => n, m2 => m2, n2 => n2, ss => ss, c0_high => c0_high, c1_high => c1_high, c2_high => c2_high, c3_high => c3_high, c4_high => c4_high, c5_high => c5_high, c0_low => c0_low, c1_low => c1_low, c2_low => c2_low, c3_low => c3_low, c4_low => c4_low, c5_low => c5_low, c0_initial => c0_initial, c1_initial => c1_initial, c2_initial => c2_initial, c3_initial => c3_initial, c4_initial => c4_initial, c5_initial => c5_initial, c0_mode => alpha_tolower(c0_mode), c1_mode => alpha_tolower(c1_mode), c2_mode => alpha_tolower(c2_mode), c3_mode => alpha_tolower(c3_mode), c4_mode => alpha_tolower(c4_mode), c5_mode => alpha_tolower(c5_mode), c0_ph => c0_ph, c1_ph => c1_ph, c2_ph => c2_ph, c3_ph => c3_ph, c4_ph => c4_ph, c5_ph => c5_ph, m_ph => m_ph, c1_use_casc_in => c1_use_casc_in, c2_use_casc_in => c2_use_casc_in, c3_use_casc_in => c3_use_casc_in, c4_use_casc_in => c4_use_casc_in, c5_use_casc_in => c5_use_casc_in, m_test_source => m_test_source, c0_test_source => c0_test_source, c1_test_source => c1_test_source, c2_test_source => c2_test_source, c3_test_source => c3_test_source, c4_test_source => c4_test_source, c5_test_source => c5_test_source, clk5_counter => get_clk5_counter(clk5_counter), clk4_counter => get_clk4_counter(clk4_counter), clk3_counter => get_clk3_counter(clk3_counter), clk2_counter => get_clk2_counter(clk2_counter), clk1_counter => get_clk1_counter(clk1_counter), clk0_counter => get_clk0_counter(clk0_counter), enable0_counter => get_enable0_counter(enable0_counter), enable1_counter => get_enable1_counter(enable1_counter), sclkout0_phase_shift => sclkout0_phase_shift, sclkout1_phase_shift => sclkout1_phase_shift, vco_multiply_by => vco_multiply_by, vco_divide_by => vco_divide_by, charge_pump_current => get_charge_pump_current(m, charge_pump_current), loop_filter_r => loop_filter_r, loop_filter_c => get_loop_filter_c(m, loop_filter_c), sim_gate_lock_device_behavior => alpha_tolower(sim_gate_lock_device_behavior) ) port map ( inclk => inclk, fbin => fbin_wire, ena => pllena_wire, clkswitch => clkswitch_wire, areset => areset_wire, pfdena => pfdena_wire, scanclk => scanclk_wire, scanread => scanread_wire, scanwrite => scanwrite_wire, scandata => scandata_wire, clk(0) => clk_wire(0), clk(1) => clk_wire(1), clk(2) => clk_wire(2), clk(3) => clk_wire(3), clk(4) => clk_wire(4), clk(5) => clk_wire(5), clkbad => clkbad_wire, enable0 => enable0, enable1 => enable1, activeclock => activeclock_wire, clkloss => clkloss_wire, locked => locked_tmp, scandataout => scandataout_wire, scandone => scandone_wire, sclkout(0) => sclkout0_wire, sclkout(1) => sclkout1_wire ); end generate STRATIXII_ALTPLL; -- Instantiate cycloneii_pll CYCLONEII_ALTPLL: if (FEATURE_FAMILY_BASE_CYCLONEII(intended_device_family) = true) generate M3 : MF_stratixii_pll generic map( operation_mode => alpha_tolower(operation_mode), pll_type => alpha_tolower(pll_type), qualify_conf_done => alpha_tolower(qualify_conf_done), compensate_clock => alpha_tolower(compensate_clock), inclk0_input_frequency => inclk0_input_frequency, inclk1_input_frequency => inclk1_input_frequency, gate_lock_signal => alpha_tolower(gate_lock_signal), gate_lock_counter => gate_lock_counter, valid_lock_multiplier => valid_lock_multiplier, invalid_lock_multiplier => invalid_lock_multiplier, switch_over_type => "manual", switch_over_on_lossclk => alpha_tolower(switch_over_on_lossclk), switch_over_on_gated_lock => alpha_tolower(switch_over_on_gated_lock), enable_switch_over_counter => alpha_tolower(enable_switch_over_counter), switch_over_counter => switch_over_counter, feedback_source => get_feedback_source(feedback_source), bandwidth => bandwidth, bandwidth_type => alpha_tolower(bandwidth_type), spread_frequency => spread_frequency, down_spread => down_spread, simulation_type => alpha_tolower(simulation_type), family_name => intended_device_family, -- internal clock specifications clk5_multiply_by => clk5_multiply_by, clk4_multiply_by => clk4_multiply_by, clk3_multiply_by => clk3_multiply_by, clk2_multiply_by => clk2_multiply_by, clk1_multiply_by => clk1_multiply_by, clk0_multiply_by => clk0_multiply_by, clk5_divide_by => clk5_divide_by, clk4_divide_by => clk4_divide_by, clk3_divide_by => clk3_divide_by, clk2_divide_by => clk2_divide_by, clk1_divide_by => clk1_divide_by, clk0_divide_by => clk0_divide_by, clk5_phase_shift => clk5_phase_shift, clk4_phase_shift => clk4_phase_shift, clk3_phase_shift => clk3_phase_shift, clk2_phase_shift => clk2_phase_shift, clk1_phase_shift => clk1_phase_shift, clk0_phase_shift => clk0_phase_shift, clk5_duty_cycle => clk5_duty_cycle, clk4_duty_cycle => clk4_duty_cycle, clk3_duty_cycle => clk3_duty_cycle, clk2_duty_cycle => clk2_duty_cycle, clk1_duty_cycle => clk1_duty_cycle, clk0_duty_cycle => clk0_duty_cycle, clk2_output_frequency => clk2_output_frequency, clk1_output_frequency => clk1_output_frequency, clk0_output_frequency => clk0_output_frequency, -- advanced user parameters vco_min => get_vco_min_c2(vco_min), vco_max => get_vco_max(vco_max), vco_center => vco_center, pfd_min => pfd_min, pfd_max => pfd_max, m_initial => m_initial, m => m, n => n, m2 => m2, n2 => n2, ss => ss, c0_high => c0_high, c1_high => c1_high, c2_high => c2_high, c3_high => c3_high, c4_high => c4_high, c5_high => c5_high, c0_low => c0_low, c1_low => c1_low, c2_low => c2_low, c3_low => c3_low, c4_low => c4_low, c5_low => c5_low, c0_initial => c0_initial, c1_initial => c1_initial, c2_initial => c2_initial, c3_initial => c3_initial, c4_initial => c4_initial, c5_initial => c5_initial, c0_mode => alpha_tolower(c0_mode), c1_mode => alpha_tolower(c1_mode), c2_mode => alpha_tolower(c2_mode), c3_mode => alpha_tolower(c3_mode), c4_mode => alpha_tolower(c4_mode), c5_mode => alpha_tolower(c5_mode), c0_ph => c0_ph, c1_ph => c1_ph, c2_ph => c2_ph, c3_ph => c3_ph, c4_ph => c4_ph, c5_ph => c5_ph, m_ph => m_ph, c1_use_casc_in => c1_use_casc_in, c2_use_casc_in => c2_use_casc_in, c3_use_casc_in => c3_use_casc_in, c4_use_casc_in => c4_use_casc_in, c5_use_casc_in => c5_use_casc_in, clk5_counter => get_clk5_counter(clk5_counter), clk4_counter => get_clk4_counter(clk4_counter), clk3_counter => get_clk3_counter(clk3_counter), clk2_counter => get_clk2_counter(clk2_counter), clk1_counter => get_clk1_counter(clk1_counter), clk0_counter => get_clk0_counter(clk0_counter), enable0_counter => get_enable0_counter(enable0_counter), enable1_counter => get_enable1_counter(enable1_counter), sclkout0_phase_shift => sclkout0_phase_shift, sclkout1_phase_shift => sclkout1_phase_shift, vco_multiply_by => vco_multiply_by, vco_divide_by => vco_divide_by, charge_pump_current => get_charge_pump_current(m, charge_pump_current), loop_filter_r => loop_filter_r, loop_filter_c => get_loop_filter_c(m, loop_filter_c), sim_gate_lock_device_behavior => alpha_tolower(sim_gate_lock_device_behavior) ) port map ( inclk => inclk, fbin => open, ena => pllena_wire, clkswitch => clkswitch_wire, areset => areset_wire, pfdena => pfdena_wire, scanclk => open, scanread => open, scanwrite => open, scandata => open, clk(0) => clk_wire(0), clk(1) => clk_wire(1), clk(2) => clk_wire(2), clk(3) => clk_tmp(0), clk(4) => clk_tmp(1), clk(5) => clk_tmp(2), clkbad => open, enable0 => open, enable1 => open, activeclock => open, clkloss => open, locked => locked_tmp, scandataout => open, scandone => open, sclkout => open ); end generate CYCLONEII_ALTPLL; -- Instantiate stratixiii_pll STRATIXIII_ALTPLL: if (IS_STRATIXIII) generate M4 : MF_stratixiii_pll generic map( operation_mode => alpha_tolower(operation_mode), pll_type => alpha_tolower(pll_type), compensate_clock => alpha_tolower(compensate_clock), inclk0_input_frequency => inclk0_input_frequency, inclk1_input_frequency => inclk1_input_frequency, self_reset_on_loss_lock => alpha_tolower(self_reset_on_loss_lock), switch_over_type => alpha_tolower(switch_over_type), enable_switch_over_counter => alpha_tolower(enable_switch_over_counter), switch_over_counter => switch_over_counter, bandwidth => bandwidth, bandwidth_type => alpha_tolower(bandwidth_type), lock_high => lock_high, lock_low => lock_low, lock_window_ui => lock_window_ui, simulation_type => alpha_tolower(simulation_type), family_name => intended_device_family, -- internal clock specifications clk9_multiply_by => clk9_multiply_by, clk8_multiply_by => clk8_multiply_by, clk7_multiply_by => clk7_multiply_by, clk6_multiply_by => clk6_multiply_by, clk5_multiply_by => clk5_multiply_by, clk4_multiply_by => clk4_multiply_by, clk3_multiply_by => clk3_multiply_by, clk2_multiply_by => clk2_multiply_by, clk1_multiply_by => clk1_multiply_by, clk0_multiply_by => clk0_multiply_by, clk9_divide_by => clk9_divide_by, clk8_divide_by => clk8_divide_by, clk7_divide_by => clk7_divide_by, clk6_divide_by => clk6_divide_by, clk5_divide_by => clk5_divide_by, clk4_divide_by => clk4_divide_by, clk3_divide_by => clk3_divide_by, clk2_divide_by => clk2_divide_by, clk1_divide_by => clk1_divide_by, clk0_divide_by => clk0_divide_by, clk9_phase_shift => clk9_phase_shift, clk8_phase_shift => clk8_phase_shift, clk7_phase_shift => clk7_phase_shift, clk6_phase_shift => clk6_phase_shift, clk5_phase_shift => clk5_phase_shift, clk4_phase_shift => clk4_phase_shift, clk3_phase_shift => clk3_phase_shift, clk2_phase_shift => clk2_phase_shift, clk1_phase_shift => clk1_phase_shift, clk0_phase_shift => clk0_phase_shift, clk9_duty_cycle => clk9_duty_cycle, clk8_duty_cycle => clk8_duty_cycle, clk7_duty_cycle => clk7_duty_cycle, clk6_duty_cycle => clk6_duty_cycle, clk5_duty_cycle => clk5_duty_cycle, clk4_duty_cycle => clk4_duty_cycle, clk3_duty_cycle => clk3_duty_cycle, clk2_duty_cycle => clk2_duty_cycle, clk1_duty_cycle => clk1_duty_cycle, clk0_duty_cycle => clk0_duty_cycle, -- advanced user parameters vco_min => get_vco_min_s3(vco_min), vco_max => get_vco_max(vco_max), vco_center => vco_center, pfd_min => pfd_min, pfd_max => pfd_max, m_initial => m_initial, m => m, n => n, c0_high => c0_high, c1_high => c1_high, c2_high => c2_high, c3_high => c3_high, c4_high => c4_high, c5_high => c5_high, c6_high => c6_high, c7_high => c7_high, c8_high => c8_high, c9_high => c9_high, c0_low => c0_low, c1_low => c1_low, c2_low => c2_low, c3_low => c3_low, c4_low => c4_low, c5_low => c5_low, c6_low => c6_low, c7_low => c7_low, c8_low => c8_low, c9_low => c9_low, c0_initial => c0_initial, c1_initial => c1_initial, c2_initial => c2_initial, c3_initial => c3_initial, c4_initial => c4_initial, c5_initial => c5_initial, c6_initial => c6_initial, c7_initial => c7_initial, c8_initial => c8_initial, c9_initial => c9_initial, c0_mode => alpha_tolower(c0_mode), c1_mode => alpha_tolower(c1_mode), c2_mode => alpha_tolower(c2_mode), c3_mode => alpha_tolower(c3_mode), c4_mode => alpha_tolower(c4_mode), c5_mode => alpha_tolower(c5_mode), c6_mode => alpha_tolower(c6_mode), c7_mode => alpha_tolower(c7_mode), c8_mode => alpha_tolower(c8_mode), c9_mode => alpha_tolower(c9_mode), c0_ph => c0_ph, c1_ph => c1_ph, c2_ph => c2_ph, c3_ph => c3_ph, c4_ph => c4_ph, c5_ph => c5_ph, c6_ph => c6_ph, c7_ph => c7_ph, c8_ph => c8_ph, c9_ph => c9_ph, m_ph => m_ph, c1_use_casc_in => c1_use_casc_in, c2_use_casc_in => c2_use_casc_in, c3_use_casc_in => c3_use_casc_in, c4_use_casc_in => c4_use_casc_in, c5_use_casc_in => c5_use_casc_in, c6_use_casc_in => c6_use_casc_in, c7_use_casc_in => c7_use_casc_in, c8_use_casc_in => c8_use_casc_in, c9_use_casc_in => c9_use_casc_in, m_test_source => get_test_source(m_test_source), c0_test_source => get_test_source(c0_test_source), c1_test_source => get_test_source(c1_test_source), c2_test_source => get_test_source(c2_test_source), c3_test_source => get_test_source(c3_test_source), c4_test_source => get_test_source(c4_test_source), c5_test_source => get_test_source(c5_test_source), c6_test_source => get_test_source(c6_test_source), c7_test_source => get_test_source(c7_test_source), c8_test_source => get_test_source(c8_test_source), c9_test_source => get_test_source(c9_test_source), clk9_counter => get_clk_counter(clk9_counter, port_clk9), clk8_counter => get_clk_counter(clk8_counter, port_clk8), clk7_counter => get_clk_counter(clk7_counter, port_clk7), clk6_counter => get_clk_counter(clk6_counter, port_clk6), clk5_counter => get_clk_counter(get_clk5_counter(clk5_counter), port_clk5), clk4_counter => get_clk_counter(get_clk4_counter(clk4_counter), port_clk4), clk3_counter => get_clk_counter(get_clk3_counter(clk3_counter), port_clk3), clk2_counter => get_clk_counter(get_clk2_counter(clk2_counter), port_clk2), clk1_counter => get_clk_counter(get_clk1_counter(clk1_counter), port_clk1), clk0_counter => get_clk_counter(get_clk0_counter(clk0_counter), port_clk0), dpa_multiply_by => dpa_multiply_by, dpa_divide_by => dpa_divide_by, dpa_divider => dpa_divider, vco_multiply_by => vco_multiply_by, vco_divide_by => vco_divide_by, vco_frequency_control => alpha_tolower(vco_frequency_control), vco_phase_shift_step => vco_phase_shift_step, charge_pump_current => charge_pump_current, loop_filter_r => loop_filter_r, loop_filter_c => loop_filter_c, charge_pump_current_bits => charge_pump_current_bits, loop_filter_c_bits => loop_filter_c_bits, loop_filter_r_bits => loop_filter_r_bits, clk9_use_even_counter_mode => alpha_tolower(clk0_use_even_counter_mode), clk8_use_even_counter_mode => alpha_tolower(clk1_use_even_counter_mode), clk7_use_even_counter_mode => alpha_tolower(clk2_use_even_counter_mode), clk6_use_even_counter_mode => alpha_tolower(clk3_use_even_counter_mode), clk5_use_even_counter_mode => alpha_tolower(clk4_use_even_counter_mode), clk4_use_even_counter_mode => alpha_tolower(clk5_use_even_counter_mode), clk3_use_even_counter_mode => alpha_tolower(clk6_use_even_counter_mode), clk2_use_even_counter_mode => alpha_tolower(clk7_use_even_counter_mode), clk1_use_even_counter_mode => alpha_tolower(clk8_use_even_counter_mode), clk0_use_even_counter_mode => alpha_tolower(clk9_use_even_counter_mode), clk9_use_even_counter_value => alpha_tolower(clk9_use_even_counter_value), clk8_use_even_counter_value => alpha_tolower(clk8_use_even_counter_value), clk7_use_even_counter_value => alpha_tolower(clk7_use_even_counter_value), clk6_use_even_counter_value => alpha_tolower(clk6_use_even_counter_value), clk5_use_even_counter_value => alpha_tolower(clk5_use_even_counter_value), clk4_use_even_counter_value => alpha_tolower(clk4_use_even_counter_value), clk3_use_even_counter_value => alpha_tolower(clk3_use_even_counter_value), clk2_use_even_counter_value => alpha_tolower(clk2_use_even_counter_value), clk1_use_even_counter_value => alpha_tolower(clk1_use_even_counter_value), clk0_use_even_counter_value => alpha_tolower(clk0_use_even_counter_value) ) port map ( inclk => inclk, fbin => stratix3_fbin, clkswitch => clkswitch_wire, areset => areset_wire, pfdena => pfdena_wire, scanclk => scanclk_wire, scandata => scandata_wire, scanclkena => scanclkena_wire, phasecounterselect => phasecounterselect_wire, phaseupdown => phaseupdown_wire, phasestep => phasestep_wire, configupdate => configupdate_wire, clk(0) => clk_wire(0), clk(1) => clk_wire(1), clk(2) => clk_wire(2), clk(3) => clk_wire(3), clk(4) => clk_wire(4), clk(5) => clk_wire(5), clk(6) => clk_wire(6), clk(7) => clk_wire(7), clk(8) => clk_wire(8), clk(9) => clk_wire(9), clkbad => clkbad_wire, activeclock => activeclock_wire, locked => locked_tmp, scandataout => scandataout_wire, scandone => scandone_wire, phasedone => phasedone_wire, vcooverrange => vcooverrange_wire, vcounderrange => vcounderrange_wire, fbout => fbout_wire ); end generate STRATIXIII_ALTPLL; -- Instantiate cycloneiii_pll CYCLONEIII_ALTPLL: if ((not IS_STINGRAY) and (IS_CYCLONEIII)) generate M5 : MF_cycloneiii_pll generic map( operation_mode => alpha_tolower(operation_mode), pll_type => alpha_tolower(pll_type), compensate_clock => alpha_tolower(compensate_clock), inclk0_input_frequency => inclk0_input_frequency, inclk1_input_frequency => inclk1_input_frequency, self_reset_on_loss_lock => alpha_tolower(self_reset_on_loss_lock), switch_over_type => alpha_tolower(switch_over_type), enable_switch_over_counter => alpha_tolower(enable_switch_over_counter), switch_over_counter => switch_over_counter, bandwidth => bandwidth, bandwidth_type => alpha_tolower(bandwidth_type), lock_high => lock_high, lock_low => lock_low, lock_window_ui => lock_window_ui, simulation_type => alpha_tolower(simulation_type), family_name => intended_device_family, -- internal clock specifications clk4_multiply_by => clk4_multiply_by, clk3_multiply_by => clk3_multiply_by, clk2_multiply_by => clk2_multiply_by, clk1_multiply_by => clk1_multiply_by, clk0_multiply_by => clk0_multiply_by, clk4_divide_by => clk4_divide_by, clk3_divide_by => clk3_divide_by, clk2_divide_by => clk2_divide_by, clk1_divide_by => clk1_divide_by, clk0_divide_by => clk0_divide_by, clk4_phase_shift => clk4_phase_shift, clk3_phase_shift => clk3_phase_shift, clk2_phase_shift => clk2_phase_shift, clk1_phase_shift => clk1_phase_shift, clk0_phase_shift => clk0_phase_shift, clk4_duty_cycle => clk4_duty_cycle, clk3_duty_cycle => clk3_duty_cycle, clk2_duty_cycle => clk2_duty_cycle, clk1_duty_cycle => clk1_duty_cycle, clk0_duty_cycle => clk0_duty_cycle, -- advanced user parameters vco_min => get_vco_min_c3(vco_min), vco_max => get_vco_max(vco_max), vco_center => vco_center, pfd_min => pfd_min, pfd_max => pfd_max, m_initial => m_initial, m => m, n => n, c0_high => c0_high, c1_high => c1_high, c2_high => c2_high, c3_high => c3_high, c4_high => c4_high, c0_low => c0_low, c1_low => c1_low, c2_low => c2_low, c3_low => c3_low, c4_low => c4_low, c0_initial => c0_initial, c1_initial => c1_initial, c2_initial => c2_initial, c3_initial => c3_initial, c4_initial => c4_initial, c0_mode => alpha_tolower(c0_mode), c1_mode => alpha_tolower(c1_mode), c2_mode => alpha_tolower(c2_mode), c3_mode => alpha_tolower(c3_mode), c4_mode => alpha_tolower(c4_mode), c0_ph => c0_ph, c1_ph => c1_ph, c2_ph => c2_ph, c3_ph => c3_ph, c4_ph => c4_ph, m_ph => m_ph, c1_use_casc_in => c1_use_casc_in, c2_use_casc_in => c2_use_casc_in, c3_use_casc_in => c3_use_casc_in, c4_use_casc_in => c4_use_casc_in, m_test_source => get_test_source(m_test_source), c0_test_source => get_test_source(c0_test_source), c1_test_source => get_test_source(c1_test_source), c2_test_source => get_test_source(c2_test_source), c3_test_source => get_test_source(c3_test_source), c4_test_source => get_test_source(c4_test_source), clk4_counter => get_clk_counter(get_clk4_counter(clk4_counter), port_clk4), clk3_counter => get_clk_counter(get_clk3_counter(clk3_counter), port_clk3), clk2_counter => get_clk_counter(get_clk2_counter(clk2_counter), port_clk2), clk1_counter => get_clk_counter(get_clk1_counter(clk1_counter), port_clk1), clk0_counter => get_clk_counter(get_clk0_counter(clk0_counter), port_clk0), vco_multiply_by => vco_multiply_by, vco_divide_by => vco_divide_by, vco_frequency_control => alpha_tolower(vco_frequency_control), vco_phase_shift_step => vco_phase_shift_step, charge_pump_current => charge_pump_current, loop_filter_r => loop_filter_r, loop_filter_c => loop_filter_c, charge_pump_current_bits => charge_pump_current_bits, loop_filter_c_bits => loop_filter_c_bits, loop_filter_r_bits => loop_filter_r_bits, clk4_use_even_counter_mode => alpha_tolower(clk5_use_even_counter_mode), clk3_use_even_counter_mode => alpha_tolower(clk6_use_even_counter_mode), clk2_use_even_counter_mode => alpha_tolower(clk7_use_even_counter_mode), clk1_use_even_counter_mode => alpha_tolower(clk8_use_even_counter_mode), clk0_use_even_counter_mode => alpha_tolower(clk9_use_even_counter_mode), clk4_use_even_counter_value => alpha_tolower(clk4_use_even_counter_value), clk3_use_even_counter_value => alpha_tolower(clk3_use_even_counter_value), clk2_use_even_counter_value => alpha_tolower(clk2_use_even_counter_value), clk1_use_even_counter_value => alpha_tolower(clk1_use_even_counter_value), clk0_use_even_counter_value => alpha_tolower(clk0_use_even_counter_value) ) port map ( inclk => inclk, fbin => fbin_wire, clkswitch => clkswitch_wire, areset => areset_wire, pfdena => pfdena_wire, scanclk => scanclk, scandata => scandata, scanclkena => scanclkena_wire, configupdate => configupdate_wire, phasecounterselect => phasecounterselect_wire(2 downto 0), phaseupdown => phaseupdown_wire, phasestep => phasestep_wire, clk(0) => clk_wire(0), clk(1) => clk_wire(1), clk(2) => clk_wire(2), clk(3) => clk_wire(3), clk(4) => clk_wire(4), clkbad => clkbad_wire, activeclock => activeclock_wire, locked => locked_tmp, scandataout => scandataout_wire, scandone => scandone_wire, phasedone => phasedone_wire, vcooverrange => vcooverrange_wire, vcounderrange => vcounderrange_wire, fbout => fbout_wire ); end generate CYCLONEIII_ALTPLL; -- Instantiate cycloneiiigx_pll CYCLONEIIIGL_ALTPLL: if (IS_STINGRAY) generate M6 : MF_cycloneiiigl_pll generic map( operation_mode => alpha_tolower(operation_mode), pll_type => alpha_tolower(pll_type), compensate_clock => alpha_tolower(compensate_clock), inclk0_input_frequency => inclk0_input_frequency, inclk1_input_frequency => inclk1_input_frequency, self_reset_on_loss_lock => alpha_tolower(self_reset_on_loss_lock), switch_over_type => alpha_tolower(switch_over_type), enable_switch_over_counter => alpha_tolower(enable_switch_over_counter), switch_over_counter => switch_over_counter, bandwidth => bandwidth, bandwidth_type => alpha_tolower(bandwidth_type), lock_high => lock_high, lock_low => lock_low, lock_window_ui => lock_window_ui, simulation_type => alpha_tolower(simulation_type), family_name => intended_device_family, lpm_hint => lpm_hint, -- internal clock specifications clk4_multiply_by => clk4_multiply_by, clk3_multiply_by => clk3_multiply_by, clk2_multiply_by => clk2_multiply_by, clk1_multiply_by => clk1_multiply_by, clk0_multiply_by => clk0_multiply_by, clk4_divide_by => clk4_divide_by, clk3_divide_by => clk3_divide_by, clk2_divide_by => clk2_divide_by, clk1_divide_by => clk1_divide_by, clk0_divide_by => clk0_divide_by, clk4_phase_shift => clk4_phase_shift, clk3_phase_shift => clk3_phase_shift, clk2_phase_shift => clk2_phase_shift, clk1_phase_shift => clk1_phase_shift, clk0_phase_shift => clk0_phase_shift, clk4_duty_cycle => clk4_duty_cycle, clk3_duty_cycle => clk3_duty_cycle, clk2_duty_cycle => clk2_duty_cycle, clk1_duty_cycle => clk1_duty_cycle, clk0_duty_cycle => clk0_duty_cycle, -- advanced user parameters vco_min => get_vco_min_c3(vco_min), vco_max => get_vco_max(vco_max), vco_center => vco_center, dpa_multiply_by => dpa_multiply_by, dpa_divide_by => dpa_divide_by, dpa_divider => dpa_divider, pfd_min => pfd_min, pfd_max => pfd_max, m_initial => m_initial, m => m, n => n, c0_high => c0_high, c1_high => c1_high, c2_high => c2_high, c3_high => c3_high, c4_high => c4_high, c0_low => c0_low, c1_low => c1_low, c2_low => c2_low, c3_low => c3_low, c4_low => c4_low, c0_initial => c0_initial, c1_initial => c1_initial, c2_initial => c2_initial, c3_initial => c3_initial, c4_initial => c4_initial, c0_mode => alpha_tolower(c0_mode), c1_mode => alpha_tolower(c1_mode), c2_mode => alpha_tolower(c2_mode), c3_mode => alpha_tolower(c3_mode), c4_mode => alpha_tolower(c4_mode), c0_ph => c0_ph, c1_ph => c1_ph, c2_ph => c2_ph, c3_ph => c3_ph, c4_ph => c4_ph, m_ph => m_ph, c1_use_casc_in => c1_use_casc_in, c2_use_casc_in => c2_use_casc_in, c3_use_casc_in => c3_use_casc_in, c4_use_casc_in => c4_use_casc_in, m_test_source => get_test_source(m_test_source), c0_test_source => get_test_source(c0_test_source), c1_test_source => get_test_source(c1_test_source), c2_test_source => get_test_source(c2_test_source), c3_test_source => get_test_source(c3_test_source), c4_test_source => get_test_source(c4_test_source), clk4_counter => get_clk_counter(get_clk4_counter(clk4_counter), port_clk4), clk3_counter => get_clk_counter(get_clk3_counter(clk3_counter), port_clk3), clk2_counter => get_clk_counter(get_clk2_counter(clk2_counter), port_clk2), clk1_counter => get_clk_counter(get_clk1_counter(clk1_counter), port_clk1), clk0_counter => get_clk_counter(get_clk0_counter(clk0_counter), port_clk0), vco_multiply_by => vco_multiply_by, vco_divide_by => vco_divide_by, vco_frequency_control => alpha_tolower(vco_frequency_control), vco_phase_shift_step => vco_phase_shift_step, charge_pump_current => charge_pump_current, loop_filter_r => loop_filter_r, loop_filter_c => loop_filter_c, charge_pump_current_bits => charge_pump_current_bits, loop_filter_c_bits => loop_filter_c_bits, loop_filter_r_bits => loop_filter_r_bits, clk4_use_even_counter_mode => alpha_tolower(clk5_use_even_counter_mode), clk3_use_even_counter_mode => alpha_tolower(clk6_use_even_counter_mode), clk2_use_even_counter_mode => alpha_tolower(clk7_use_even_counter_mode), clk1_use_even_counter_mode => alpha_tolower(clk8_use_even_counter_mode), clk0_use_even_counter_mode => alpha_tolower(clk9_use_even_counter_mode), clk4_use_even_counter_value => alpha_tolower(clk4_use_even_counter_value), clk3_use_even_counter_value => alpha_tolower(clk3_use_even_counter_value), clk2_use_even_counter_value => alpha_tolower(clk2_use_even_counter_value), clk1_use_even_counter_value => alpha_tolower(clk1_use_even_counter_value), clk0_use_even_counter_value => alpha_tolower(clk0_use_even_counter_value) ) port map ( inclk => inclk, fbin => fbin_wire, clkswitch => clkswitch_wire, areset => areset_wire, pfdena => pfdena_wire, scanclk => scanclk, scandata => scandata, scanclkena => scanclkena_wire, configupdate => configupdate_wire, phasecounterselect => phasecounterselect_wire(2 downto 0), phaseupdown => phaseupdown_wire, phasestep => phasestep_wire, clk(0) => clk_wire(0), clk(1) => clk_wire(1), clk(2) => clk_wire(2), clk(3) => clk_wire(3), clk(4) => clk_wire(4), clkbad => clkbad_wire, activeclock => activeclock_wire, locked => locked_tmp, scandataout => scandataout_wire, scandone => scandone_wire, phasedone => phasedone_wire, vcooverrange => vcooverrange_wire, vcounderrange => vcounderrange_wire, fbout => fbout_wire, fref => fref_wire, icdrclk => icdrclk_wire ); end generate CYCLONEIIIGL_ALTPLL; -- Instantiate pll_iobuf STRATIXIIIPLL_IOBUF: if ((IS_STRATIXIII) and (not IS_PIRANHA) and (alpha_tolower(operation_mode) = "zero_delay_buffer") and (using_fbmimicbidir_port = "ON")) generate iobuf1 : pll_iobuf port map ( i => fbout_wire, oe => oe_wire, o => iobuf_o, io => fbmimicbidir ); end generate STRATIXIIIPLL_IOBUF; process (locked_tmp, areset) begin if (areset = '1') then pll_lock_sync <= '0'; elsif (locked_tmp = '1' and locked_tmp'event) then pll_lock_sync <= '1'; end if; end process; end behavior; -- END ARCHITECTURE BEHAVIOR ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : altaccumulate -- -- Description : Parameterized accumulator megafunction. The accumulator -- performs an add function or a subtract function based on the add_sub -- parameter. The input data can be signed or unsigned. -- -- Limitation : n/a -- -- Results expected: result - The results of add or subtract operation. Output -- port [width_out-1 .. 0] wide. -- cout - The cout port has a physical interpretation as -- the carry-out (borrow-in) of the MSB. The cout -- port is most meaningful for detecting overflow -- in unsigned operations. The cout port operates -- in the same manner for signed and unsigned -- operations. -- overflow - Indicates the accumulator is overflow. -- ---END_ENTITY_HEADER----------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; -- BEGINNING OF ENTITY entity altaccumulate is -- GENERIC DECLARATION generic ( width_in : natural := 4; -- Required width_out : natural := 8; -- Required lpm_representation : string := "UNSIGNED"; extra_latency : integer := 0; use_wys : string := "ON"; lpm_hint : string := "UNUSED"; lpm_type : string := "altaccumulate" ); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION cin : in std_logic := 'Z'; data : in std_logic_vector(width_in -1 downto 0); -- Required port add_sub : in std_logic := '1'; clock : in std_logic; -- Required port sload : in std_logic := '0'; clken : in std_logic := '1'; sign_data : in std_logic := '0'; aclr : in std_logic := '0'; -- OUTPUT PORT DECLARATION result : out std_logic_vector(width_out -1 downto 0) := (others => '0'); -- Required port cout : out std_logic := '0'; overflow : out std_logic := '0' ); end altaccumulate; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE architecture behaviour of altaccumulate is -- TYPE DECLARATION type pipeline is array (extra_latency-1 downto 0) of std_logic_vector (width_out+1 downto 0); -- SIGNAL DECLARATION signal temp_sum : std_logic_vector (width_out downto 0) := (others => '0'); signal cout_int : std_logic := '0'; signal overflow_int : std_logic := '0'; signal result_int : std_logic_vector (width_out+1 downto 0) := (others => '0'); signal result_pipe : pipeline := (others => (others => '0')); begin MSG: process begin if( width_in <= 0 ) then ASSERT FALSE REPORT "Error! Value of width_in parameter must be greater than 0." SEVERITY ERROR; end if; if( width_out <= 0 ) then ASSERT FALSE REPORT "Error! Value of width_out parameter must be greater than 0." SEVERITY ERROR; end if; if( extra_latency > width_out ) then ASSERT FALSE REPORT "Info: Value of extra_latency parameter should be lower than width_out parameter for better performance/utilization." SEVERITY NOTE; end if; if( width_in > width_out ) then ASSERT FALSE REPORT "Error! Value of width_in parameter should be lower than or equal to width_out." SEVERITY ERROR; end if; wait; end process MSG; -- PROCESS DECLARATION ADDSUB : process (data, add_sub, sload, cin, sign_data, result_int (width_out-1 downto 0)) -- VARIABLE DECLARATIOM variable fb_int : std_logic_vector (width_out downto 0) := (others => '0'); variable data_int : std_logic_vector (width_out-1 downto 0) := (others => '0'); variable zeropad : std_logic_vector ((width_out - width_in)-1 downto 0) := (others => '0'); variable temp_sum_int : std_logic_vector (width_out downto 0) := (others => '0'); variable cout_temp, borrow : std_logic; variable result_full : std_logic_vector (width_out downto 0); variable temp_sum_zero : std_logic_vector (width_out downto 0) := (others => '0'); variable cin_int : std_logic; begin if ((LPM_REPRESENTATION = "SIGNED") or (sign_data = '1')) then zeropad := (others => data (width_in-1)); else zeropad := (others => '0'); end if; if (sload = '1') then fb_int := (others => '0'); else fb_int := ('0' & result_int (width_out-1 downto 0)); end if; if ((data (0) = '1') or (data (0) = '0')) then data_int := (zeropad & data); end if; -- If cin is omitted (i.e. cin = 'z'), cin default is 0 for add operation -- and 1 for subtract operation. if ((cin /= '0') and (cin /= '1')) then cin_int := not add_sub; else cin_int := cin; end if; if (sload = '1') then temp_sum_int := unsigned(temp_sum_zero) + unsigned(data_int); else if (add_sub = '1') then temp_sum_int := unsigned(temp_sum_zero) + unsigned(fb_int) + unsigned(data_int) + cin_int; cout_temp := temp_sum_int(width_out); else borrow := not cin_int; if ((borrow /= '1') and (borrow /= '0')) then borrow := '0'; end if; temp_sum_int := unsigned(temp_sum_zero) + unsigned (fb_int) - unsigned (data_int) - borrow; result_full := unsigned(temp_sum_zero) + unsigned(data_int) + borrow; if (fb_int >= result_full) then cout_temp :='1'; else cout_temp :='0'; end if; end if; end if; if (sload = '0') then if ((LPM_REPRESENTATION = "SIGNED") or (sign_data = '1')) then overflow_int <= ((not (data (width_in-1) xor result_int (width_out -1))) xor (not (add_sub))) and (result_int (width_out -1) xor temp_sum_int (width_out -1)); else overflow_int <= not (add_sub xor cout_temp); end if; else overflow_int <= '0'; cout_temp := not add_sub; end if; cout_int <= cout_temp; temp_sum <= temp_sum_int; end process ADDSUB; ACC: process (clock, aclr, cout_int) -- VARIABLE DECLARATIOM variable head_pipe : integer; variable head : integer := 0; variable full_res: std_logic_vector (width_out+1 downto 0); begin head_pipe := head; if ((aclr /= '1') and (extra_latency = 0)) then cout <= cout_int; end if; if (aclr = '1') then result <= (others => '0'); result_int <= (others => '0'); if (extra_latency > 0) then cout <= '0'; else cout <= cout_int; end if; overflow <= '0'; result_pipe <= (others => (others => '0')); elsif rising_edge(clock) then if (clken = '1') then if (extra_latency > 0) then result_pipe (head_pipe) <= (result_int (width_out+1) & cout_int & result_int (width_out-1 downto 0)); head_pipe := (head_pipe + 1) mod (extra_latency); if (head_pipe = head) then full_res := (result_int (width_out+1) & cout_int & result_int (width_out-1 downto 0)); else full_res := result_pipe (head_pipe); end if; cout <= full_res (width_out); result <= full_res (width_out-1 downto 0); overflow <= full_res (width_out+1); else overflow <= overflow_int; result <= temp_sum (width_out-1 downto 0); end if; result_int <= (overflow_int & cout_int & temp_sum (width_out-1 downto 0)); end if; end if; head := head_pipe; end process ACC; end behaviour; -- End behaviour of altaccumulate -- END OF ARCHITECTURE -- -------------------------------------------------------------------------- -- Module Name : altmult_accum -- -- Description : a*b + x (MAC) -- -- Limitation : Stratix DSP block -- -- Results expected : signed & unsigned, maximum of 3 pipelines(latency) each. -- -- -------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use work.ALTERA_DEVICE_FAMILIES.all; entity altmult_accum is generic ( -- --------------------- -- PARAMETER DECLARATION -- --------------------- width_a : natural := 1; width_b : natural := 1; width_c : natural := 1; width_result : natural := 2; width_upper_data : natural := 1; input_source_a : string := "DATAA"; input_source_b : string := "DATAB"; input_reg_a : string := "CLOCK0"; input_aclr_a : string := "ACLR3"; input_reg_b : string := "CLOCK0"; input_aclr_b : string := "ACLR3"; port_addnsub : string := "PORT_CONNECTIVITY"; addnsub_reg : string := "CLOCK0"; addnsub_aclr : string := "ACLR3"; addnsub_pipeline_reg : string := "CLOCK0"; addnsub_pipeline_aclr : string := "ACLR3"; accum_direction : string := "ADD"; accum_sload_reg : string := "CLOCK0"; accum_sload_aclr : string := "ACLR3"; accum_sload_pipeline_reg : string := "CLOCK0"; accum_sload_pipeline_aclr : string := "ACLR3"; representation_a : string := "UNSIGNED"; port_signa : string := "PORT_CONNECTIVITY"; sign_reg_a : string := "CLOCK0"; sign_aclr_a : string := "ACLR3"; sign_pipeline_reg_a : string := "CLOCK0"; sign_pipeline_aclr_a : string := "ACLR3"; representation_b : string := "UNSIGNED"; port_signb : string := "PORT_CONNECTIVITY"; sign_reg_b : string := "CLOCK0"; sign_aclr_b : string := "ACLR3"; sign_pipeline_reg_b : string := "CLOCK0"; sign_pipeline_aclr_b : string := "ACLR3"; multiplier_reg : string := "CLOCK0"; multiplier_aclr : string := "ACLR3"; output_reg : string := "CLOCK0"; output_aclr : string := "ACLR3"; extra_multiplier_latency : integer := 0; extra_accumulator_latency : integer := 0; dedicated_multiplier_circuitry : string := "AUTO"; dsp_block_balancing : string := "AUTO"; lpm_hint : string := "UNUSED"; lpm_type : string := "altmult_accum"; intended_device_family : string := "Stratix"; multiplier_rounding : string := "NO"; mult_round_aclr : string := "ACLR3"; mult_round_reg : string := "CLOCK0"; multiplier_saturation : string := "NO"; mult_saturation_aclr : string := "ACLR3"; mult_saturation_reg : string := "CLOCK0"; accumulator_rounding : string := "NO"; accum_round_aclr : string := "ACLR3"; accum_round_reg : string := "CLOCK0"; accum_round_pipeline_aclr : string := "ACLR3"; accum_round_pipeline_reg : string := "CLOCK0"; accumulator_saturation : string := "NO"; accum_saturation_aclr : string := "ACLR3"; accum_saturation_reg : string := "CLOCK0"; accum_saturation_pipeline_aclr : string := "ACLR3"; accum_saturation_pipeline_reg : string := "CLOCK0"; accum_sload_upper_data_aclr : string := "ACLR3"; accum_sload_upper_data_pipeline_aclr : string := "ACLR3"; accum_sload_upper_data_pipeline_reg : string := "CLOCK0"; accum_sload_upper_data_reg : string := "CLOCK0"; port_mult_is_saturated : string := "UNUSED"; port_accum_is_saturated : string := "UNUSED"; -- StratixV parameters preadder_mode : string := "SIMPLE"; loadconst_value : integer := 0; width_coef : integer := 0; loadconst_control_register : string := "CLOCK0"; loadconst_control_aclr : string := "ACLR0"; coefsel0_register : string := "CLOCK0"; coefsel1_register : string := "CLOCK0"; coefsel2_register : string := "CLOCK0"; coefsel3_register : string := "CLOCK0"; coefsel0_aclr : string := "ACLR0"; coefsel1_aclr : string := "ACLR0"; coefsel2_aclr : string := "ACLR0"; coefsel3_aclr : string := "ACLR0"; preadder_direction_0 : string := "ADD"; preadder_direction_1 : string := "ADD"; preadder_direction_2 : string := "ADD"; preadder_direction_3 : string := "ADD"; systolic_delay1 : string := "UNREGISTERED"; systolic_delay3 : string := "UNREGISTERED"; systolic_aclr1 : string := "NONE"; systolic_aclr3 : string := "NONE"; -- coefficient storage coef0_0 : integer := 0; coef0_1 : integer := 0; coef0_2 : integer := 0; coef0_3 : integer := 0; coef0_4 : integer := 0; coef0_5 : integer := 0; coef0_6 : integer := 0; coef0_7 : integer := 0; coef1_0 : integer := 0; coef1_1 : integer := 0; coef1_2 : integer := 0; coef1_3 : integer := 0; coef1_4 : integer := 0; coef1_5 : integer := 0; coef1_6 : integer := 0; coef1_7 : integer := 0; coef2_0 : integer := 0; coef2_1 : integer := 0; coef2_2 : integer := 0; coef2_3 : integer := 0; coef2_4 : integer := 0; coef2_5 : integer := 0; coef2_6 : integer := 0; coef2_7 : integer := 0; coef3_0 : integer := 0; coef3_1 : integer := 0; coef3_2 : integer := 0; coef3_3 : integer := 0; coef3_4 : integer := 0; coef3_5 : integer := 0; coef3_6 : integer := 0; coef3_7 : integer := 0 ); port ( -- ---------------- -- PORT DECLARATION -- ---------------- -- input data ports dataa : in std_logic_vector(width_a -1 downto 0) := (others => '0'); datab : in std_logic_vector(width_b -1 downto 0) := (others => '0'); datac : in std_logic_vector(width_c -1 downto 0) := (others => '0'); scanina : in std_logic_vector(width_a -1 downto 0) := (others => 'Z'); scaninb : in std_logic_vector(width_b -1 downto 0) := (others => 'Z'); accum_sload_upper_data : in std_logic_vector(width_upper_data - 1 downto 0) := (others => '0'); sourcea : in std_logic := '0'; sourceb : in std_logic := '0'; -- control signals addnsub : in std_logic := 'Z'; accum_sload : in std_logic := '0'; signa : in std_logic := 'Z'; signb : in std_logic := 'Z'; -- clock ports clock0 : in std_logic := '1'; clock1 : in std_logic := '1'; clock2 : in std_logic := '1'; clock3 : in std_logic := '1'; -- clock enable ports ena0 : in std_logic := '1'; ena1 : in std_logic := '1'; ena2 : in std_logic := '1'; ena3 : in std_logic := '1'; -- clear ports aclr0 : in std_logic := '0'; aclr1 : in std_logic := '0'; aclr2 : in std_logic := '0'; aclr3 : in std_logic := '0'; -- round and saturation ports mult_round : in std_logic := '0'; mult_saturation : in std_logic := '0'; accum_round : in std_logic := '0'; accum_saturation : in std_logic := '0'; -- StratixV only input ports coefsel0 : in std_logic_vector(2 downto 0) := (others => '0'); coefsel1 : in std_logic_vector(2 downto 0) := (others => '0'); coefsel2 : in std_logic_vector(2 downto 0) := (others => '0'); coefsel3 : in std_logic_vector(2 downto 0) := (others => '0'); -- output ports result : out std_logic_vector(width_result -1 downto 0) := (others => '0'); overflow : out std_logic :='0'; scanouta : out std_logic_vector (width_a -1 downto 0) := (others => '0'); scanoutb : out std_logic_vector (width_b -1 downto 0) := (others => '0'); mult_is_saturated : out std_logic := '0'; accum_is_saturated : out std_logic := '0' ); end altmult_accum; architecture behaviour of altmult_accum is -- ------------------------------------- -- INTERNAL SIGNALS AND TYPE DECLARATION -- ------------------------------------- -- CONSTANT DECLARATION constant IS_STRATIXV : boolean := FEATURE_FAMILY_STRATIXV(intended_device_family); constant IS_STRATIXIII : boolean := FEATURE_FAMILY_STRATIXIII(intended_device_family); constant IS_STRATIXII : boolean := FEATURE_FAMILY_STRATIXII(intended_device_family); constant IS_CYCLONEII : boolean := FEATURE_FAMILY_CYCLONEII(intended_device_family); constant altera_mult_add_block : boolean := FEATURE_FAMILY_HAS_ALTERA_MULT_ADD_FLOW(intended_device_family); constant altmult_add_eol_block : boolean := FEATURE_FAMILY_IS_ALTMULT_ADD_EOL(intended_device_family); function resolve_internal_width (ARG : integer;ARG2 : integer) return integer is variable changed_width:integer := 0; begin if (multiplier_saturation = "NO" and multiplier_rounding = "NO" and accumulator_saturation = "NO" and accumulator_rounding = "NO") then if (ARG2 = 0) then changed_width := width_a; else changed_width := width_b; end if; else changed_width := 18; end if; return changed_width; end resolve_internal_width; -- This constant int_width_a would be used internally in this model -- to represent width_a constant int_width_a : natural := resolve_internal_width(width_a, 0); -- This constant int_width_b woudl be used internally in this model -- to represent width_b constant int_width_b : natural := resolve_internal_width(width_b, 1); function resolve_internal_extra_width return integer is variable changed_value :integer := 0; begin if (multiplier_saturation = "NO" and multiplier_rounding = "NO" and accumulator_saturation = "NO" and accumulator_rounding = "NO") then changed_value := 0; else changed_value := int_width_a + int_width_b - width_a - width_b; end if; return changed_value; end resolve_internal_extra_width; constant int_extra_width : integer := resolve_internal_extra_width; function resolve_internal_width_result return integer is variable changed_width_result:integer := 0; begin if (multiplier_saturation = "NO" and multiplier_rounding = "NO" and accumulator_saturation = "NO" and accumulator_rounding = "NO") then if ((int_width_a + int_width_b - 1) > width_result) then changed_width_result := int_width_a + int_width_b - 1; else changed_width_result := width_result; end if; else if ((int_width_a + int_width_b - 1) > 52) then changed_width_result := int_width_a + int_width_b - 1; else changed_width_result := 52; end if; end if; return changed_width_result; end resolve_internal_width_result; constant int_width_result : natural := resolve_internal_width_result; -- ------------------------------------- -- INTERNAL TEMPLATE DECLARATION -- ------------------------------------- type pipeline_accum is array (extra_accumulator_latency downto 0) of std_logic_vector (int_width_result downto 0); type pipeline_multi is array (extra_multiplier_latency downto 0) of std_logic_vector (int_width_a + int_width_b + 4 downto 0); type pipeline_sload is array (extra_multiplier_latency downto 0) of std_logic_vector (width_upper_data - 1 downto 0); signal mult_a : std_logic_vector (width_a - 1 downto 0):= (others => '0'); signal mult_b : std_logic_vector (width_b - 1 downto 0):= (others => '0'); signal mult_res : std_logic_vector (int_width_a + int_width_b - 1 downto 0):= (others => '0'); signal acc_sload_reg : std_logic := '0'; signal accum_sload_pipe : std_logic := '0'; signal sign_a_reg : std_logic := '0'; signal sign_a_pipe : std_logic := '0'; signal sign_a_latent : std_logic := '0'; signal sign_b_reg : std_logic := '0'; signal sign_b_pipe : std_logic := '0'; signal sign_b_latent : std_logic := '0'; signal addsub_reg : std_logic := '0'; signal addsub_pipe : std_logic := '0'; signal addsub_latent : std_logic := '0'; signal accum_sload_latent : std_logic := '0'; signal mult_pipe : pipeline_multi := (others => (others => '0')); signal sload_upper_data_pipe : pipeline_sload := (others => (others => '0')); signal mult_out_latent : std_logic_vector (int_width_a + int_width_b - 1 downto 0):= (others => '0'); signal result_int : std_logic_vector (int_width_result - 1 downto 0):= (others => '0'); signal temp_mult_zero : std_logic_vector (int_width_a + int_width_b downto 0):= (others => '0'); signal mult_full : std_logic_vector (int_width_a + int_width_b + 4 downto 0):= (others => '0'); signal mult_signed : std_logic := '0'; signal do_add : std_logic := '0'; signal temp_mult_signed : std_logic := '0'; signal head_result : natural := 0; signal head_mult : natural := 0; signal lower_bits : std_logic_vector (width_result + width_upper_data - 1 downto 0) := (others => '0'); signal sload_upper_data_reg : std_logic_vector (width_upper_data - 1 downto 0) := (others => '0'); signal sload_upper_data_latent : std_logic_vector (width_upper_data - 1 downto 0) := (others => '0'); signal sload_upper_data_wire : std_logic_vector (width_upper_data - 1 downto 0) := (others => '0'); signal sload_upper_data_full : std_logic_vector (width_upper_data - 1 downto 0) := (others => '0'); signal mult_is_saturated_wire : std_logic := '0'; signal mult_is_saturated_reg : std_logic := '0'; signal mult_is_saturated_out : std_logic := '0'; signal accum_is_saturated_out : std_logic := '0'; signal mult_round_wire : std_logic := '0'; signal mult_saturate_wire : std_logic := '0'; signal mult_final_out : std_logic_vector (int_width_a + int_width_b - 1 downto 0) := (others => '0'); signal accum_round_pipe_wire : std_logic := '0'; signal accum_round_wire : std_logic := '0'; signal accum_saturation_pipe_wire : std_logic := '0'; signal accum_saturate_wire : std_logic := '0'; begin scanouta <= mult_a; scanoutb <= mult_b; sign_a_latent <= mult_full (int_width_a + int_width_b + 4) when extra_multiplier_latency >0 else sign_a_reg; sign_b_latent <= mult_full (int_width_a + int_width_b + 3) when extra_multiplier_latency >0 else sign_b_reg; accum_sload_latent <= mult_full (int_width_a + int_width_b + 2) when extra_multiplier_latency >0 else acc_sload_reg; addsub_latent <= mult_full (int_width_a + int_width_b + 1) when extra_multiplier_latency >0 else addsub_reg; mult_signed <= mult_full (int_width_a + int_width_b + 0) when extra_multiplier_latency >0 else temp_mult_signed; mult_out_latent <= mult_full (int_width_a + int_width_b - 1 downto 0) when extra_multiplier_latency >0 else mult_final_out; sload_upper_data_latent <= sload_upper_data_full when extra_multiplier_latency >0 else sload_upper_data_reg; mult_is_saturated <= mult_is_saturated_out when (port_mult_is_saturated = "USED") else '0'; accum_is_saturated <= accum_is_saturated_out when (port_accum_is_saturated = "USED") else '0'; -- Parameter Checking process begin -- Legality check, family from Night Fury and moving forwards is officially EOL if (altmult_add_eol_block) then assert false report "ALTMULT_ACCUM is EOL for "& intended_device_family &" device family" severity failure; end if; -- Legality check, block unsupported family from running pre_layout simulation using altera_mf (family with altera_mult_add flow) if (altera_mult_add_block or altmult_add_eol_block) then assert false report "ALTMULT_ACCUM is not supported for "& intended_device_family &" device family" severity failure; end if; if ((dedicated_multiplier_circuitry /= "AUTO") and (dedicated_multiplier_circuitry /= "YES") and (dedicated_multiplier_circuitry /= "NO")) then assert false report "Error: The DEDICATED_MULTIPLIER_CIRCUITRY parameter is set to an illegal value." severity error; end if; if (width_a <= 0) then assert false report "Error: width_a must be greater than 0." severity error; end if; if (width_b <= 0) then assert false report "Error: width_b must be greater than 0." severity error; end if; if (width_result <= 0) then assert false report "Error: width_result must be greater than 0." severity error; end if; if ((not IS_STRATIXII) and (not IS_CYCLONEII) and (input_source_a /= "DATAA")) then assert false report "Error: The input source for port A are limited to input dataa." severity error; end if; if ((not IS_STRATIXII) and (not IS_CYCLONEII) and (input_source_b /= "DATAB")) then assert false report "Error: The input source for port B are limited to input datab." severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and (multiplier_rounding /= "NO")) then assert false report "Error: There is no rounding feature for " & intended_device_family & " device." severity error; end if; if ((not IS_STRATIXII) and (accumulator_rounding /= "NO")) then assert false report "Error: There is no rounding feature for "& intended_device_family &" device." severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and (multiplier_saturation /= "NO")) then assert false report "Error: There is no saturation feature for "& intended_device_family &" device." severity error; end if; if ((not IS_STRATIXII) and (accumulator_saturation /= "NO")) then assert false report "Error: There is no saturation feature for "& intended_device_family &" device." severity error; end if; if ((IS_STRATIXIII) and (port_addnsub /= "PORT_UNUSED")) then assert false report "Error: The addnsub port is not available for "& intended_device_family &" device." severity error; end if; if ((IS_STRATIXIII) and (accum_direction /= "ADD") and (accum_direction /= "SUB")) then assert false report "Error: Invalid value for ACCUM_DIRECTION parameter for "& intended_device_family &" device." severity error; end if; if ((IS_STRATIXIII) and not(IS_STRATIXV) and (input_source_a = "VARIABLE")) then assert false report "Error: Invalid value for INPUT_SOURCE_A parameter for "& intended_device_family &" device." severity error; end if; wait; end process; G1:if (input_reg_a = "UNREGISTERED") generate process (dataa, scanina, sourcea) begin if (input_source_a = "DATAA") then mult_a <= dataa; elsif (input_source_a = "SCANA") then mult_a <= scanina; elsif (input_source_a = "VARIABLE") then if (sourcea = '1') then mult_a <= dataa; else mult_a <= scanina; end if; end if; end process; end generate G1; G2:if (input_reg_b = "UNREGISTERED") generate process (datab, scaninb, sourceb) begin if (input_source_b = "DATAB") then mult_b <= datab; elsif (input_source_b = "SCANB") then mult_b <= scaninb; elsif (input_source_b = "VARIABLE") then if (sourceb = '1') then mult_b <= datab; else mult_b <= scaninb; end if; end if; end process; end generate G2; G3: if (addnsub_reg = "UNREGISTERED") generate addsub_reg <= addnsub; end generate G3; G4: if (addnsub_pipeline_reg = "UNREGISTERED") generate addsub_pipe <= addsub_latent; end generate G4; G5: if (accum_sload_reg = "UNREGISTERED") generate acc_sload_reg <= accum_sload; end generate G5; G6: if (accum_sload_pipeline_reg = "UNREGISTERED") generate accum_sload_pipe <= accum_sload_latent; end generate G6; G7: if (sign_reg_a = "UNREGISTERED") generate sign_a_reg <= signa; end generate G7; G8: if sign_reg_b= "UNREGISTERED" generate sign_b_reg <= signb; end generate G8; G9: if (sign_pipeline_reg_a = "UNREGISTERED") generate sign_a_pipe <= sign_a_latent; end generate G9; G10: if (sign_pipeline_reg_b = "UNREGISTERED") generate sign_b_pipe <= sign_b_latent; end generate G10; G11: if (accum_round_reg = "UNREGISTERED") generate process (accum_round, accum_sload) begin if (IS_STRATIXIII) then accum_round_pipe_wire <= accum_sload; else accum_round_pipe_wire <= accum_round; end if; end process; end generate G11; G12: if (accum_round_pipeline_reg = "UNREGISTERED") generate accum_round_wire <= accum_round_pipe_wire; end generate G12; G12b: if (accum_saturation_reg = "UNREGISTERED") generate accum_saturation_pipe_wire <= accum_saturation; end generate G12b; G14: if (accum_saturation_pipeline_reg = "UNREGISTERED") generate accum_saturate_wire <= accum_saturation_pipe_wire; end generate G14; G15: if (mult_round_reg = "UNREGISTERED") generate mult_round_wire <= mult_round; end generate G15; G16: if (mult_saturation_reg = "UNREGISTERED") generate mult_saturate_wire <= mult_saturation; end generate G16; G17: if (accum_sload_upper_data_reg = "UNREGISTERED") generate sload_upper_data_reg <= accum_sload_upper_data; end generate G17; G18: if (accum_sload_upper_data_pipeline_reg = "UNREGISTERED") generate sload_upper_data_wire <= sload_upper_data_latent; end generate G18; G19: if (multiplier_reg = "UNREGISTERED") generate mult_res <= mult_out_latent; mult_is_saturated_reg <= mult_is_saturated_wire; end generate G19; -- ---------------------------------------------------------------------------- -- This process contains 1 register and a combinatorial block (to set mult_a) -- The signal registered is dataa -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if input_reg_a is unregistered and -- dataa changes value -- --------------------------------------------------------------------------- IFG1: if (input_reg_a = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, dataa, scanina, sourcea) begin if (((input_aclr_a= "ACLR0") and (aclr0 = '1')) or ((input_aclr_a= "ACLR1") and (aclr1 = '1')) or ((input_aclr_a= "ACLR2") and (aclr2 = '1')) or ((input_aclr_a= "ACLR3") and (aclr3 = '1'))) then mult_a <= (others => '0'); elsif rising_edge(clock0) then if ((ena0 ='1')) then if (input_source_a = "DATAA") then mult_a <= dataa; elsif (input_source_a = "SCANA") then mult_a <= scanina; elsif (input_source_a = "VARIABLE") then if (sourcea = '1') then mult_a <= dataa; else mult_a <= scanina; end if; end if; end if; end if; end process; end generate IFG1; IFG2: if (input_reg_a = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, dataa, scanina, sourcea) begin if (((input_aclr_a= "ACLR0") and (aclr0 = '1')) or ((input_aclr_a= "ACLR1") and (aclr1 = '1')) or ((input_aclr_a= "ACLR2") and (aclr2 = '1')) or ((input_aclr_a= "ACLR3") and (aclr3 = '1'))) then mult_a <= (others => '0'); elsif rising_edge(clock1) then if ((ena1 ='1')) then if (input_source_a = "DATAA") then mult_a <= dataa; elsif (input_source_a = "SCANA") then mult_a <= scanina; elsif (input_source_a = "VARIABLE") then if (sourcea = '1') then mult_a <= dataa; else mult_a <= scanina; end if; end if; end if; end if; end process; end generate IFG2; IFG3: if (input_reg_a = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, dataa, scanina, sourcea) begin if (((input_aclr_a= "ACLR0") and (aclr0 = '1')) or ((input_aclr_a= "ACLR1") and (aclr1 = '1')) or ((input_aclr_a= "ACLR2") and (aclr2 = '1')) or ((input_aclr_a= "ACLR3") and (aclr3 = '1'))) then mult_a <= (others => '0'); elsif rising_edge(clock2) then if ((ena2 ='1'))then if (input_source_a = "DATAA") then mult_a <= dataa; elsif (input_source_a = "SCANA") then mult_a <= scanina; elsif (input_source_a = "VARIABLE") then if (sourcea = '1') then mult_a <= dataa; else mult_a <= scanina; end if; end if; end if; end if; end process; end generate IFG3; IFG4: if (input_reg_a = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, dataa, scanina, sourcea) begin if (((input_aclr_a= "ACLR0") and (aclr0 = '1')) or ((input_aclr_a= "ACLR1") and (aclr1 = '1')) or ((input_aclr_a= "ACLR2") and (aclr2 = '1')) or ((input_aclr_a= "ACLR3") and (aclr3 = '1'))) then mult_a <= (others => '0'); elsif rising_edge(clock3) then if ((ena3 ='1')) then if (input_source_a = "DATAA") then mult_a <= dataa; elsif (input_source_a = "SCANA") then mult_a <= scanina; elsif (input_source_a = "VARIABLE") then if (sourcea = '1') then mult_a <= dataa; else mult_a <= scanina; end if; end if; end if; end if; end process; end generate IFG4; -- ---------------------------------------------------------------------------- -- This process contains 1 register and a combinatorial block (to set mult_b) -- The signal registered is datab -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if input_reg_b is unregistered and -- datab changes value -- --------------------------------------------------------------------------- IFG5: if (input_reg_b = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, datab, scaninb, sourceb) begin if (((input_aclr_b= "ACLR0") and (aclr0 = '1')) or ((input_aclr_b= "ACLR1") and (aclr1 = '1')) or ((input_aclr_b= "ACLR2") and (aclr2 = '1')) or ((input_aclr_b= "ACLR3") and (aclr3 = '1'))) then mult_b <= (others => '0'); elsif rising_edge(clock0) then if ((ena0 ='1')) then if (input_source_b = "DATAB") then mult_b <= datab; elsif (input_source_b = "SCANB") then mult_b <= scaninb; elsif (input_source_b = "VARIABLE") then if (sourceb = '1') then mult_b <= datab; else mult_b <= scaninb; end if; end if; end if; end if; end process; end generate IFG5; IFG6: if (input_reg_b = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, datab, scaninb, sourceb) begin if (((input_aclr_b= "ACLR0") and (aclr0 = '1')) or ((input_aclr_b= "ACLR1") and (aclr1 = '1')) or ((input_aclr_b= "ACLR2") and (aclr2 = '1')) or ((input_aclr_b= "ACLR3") and (aclr3 = '1'))) then mult_b <= (others => '0'); elsif rising_edge(clock1) then if ((ena1 ='1')) then if (input_source_b = "DATAB") then mult_b <= datab; elsif (input_source_b = "SCANB") then mult_b <= scaninb; elsif (input_source_b = "VARIABLE") then if (sourceb = '1') then mult_b <= datab; else mult_b <= scaninb; end if; end if; end if; end if; end process; end generate IFG6; IFG7: if (input_reg_b = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, datab, scaninb, sourceb) begin if (((input_aclr_b= "ACLR0") and (aclr0 = '1')) or ((input_aclr_b= "ACLR1") and (aclr1 = '1')) or ((input_aclr_b= "ACLR2") and (aclr2 = '1')) or ((input_aclr_b= "ACLR3") and (aclr3 = '1'))) then mult_b <= (others => '0'); elsif rising_edge(clock2) then if ((ena2 ='1')) then if (input_source_b = "DATAB") then mult_b <= datab; elsif (input_source_b = "SCANB") then mult_b <= scaninb; elsif (input_source_b = "VARIABLE") then if (sourceb = '1') then mult_b <= datab; else mult_b <= scaninb; end if; end if; end if; end if; end process; end generate IFG7; IFG8: if (input_reg_b = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, datab, scaninb, sourceb) begin if (((input_aclr_b= "ACLR0") and (aclr0 = '1')) or ((input_aclr_b= "ACLR1") and (aclr1 = '1')) or ((input_aclr_b= "ACLR2") and (aclr2 = '1')) or ((input_aclr_b= "ACLR3") and (aclr3 = '1'))) then mult_b <= (others => '0'); elsif rising_edge(clock3) then if ((ena3 ='1')) then if (input_source_b = "DATAB") then mult_b <= datab; elsif (input_source_b = "SCANB") then mult_b <= scaninb; elsif (input_source_b = "VARIABLE") then if (sourceb = '1') then mult_b <= datab; else mult_b <= scaninb; end if; end if; end if; end if; end process; end generate IFG8; -- ------------------------------------------------------------------------------ -- This process contains 1 register and a combinatorial block (to set addsub_reg) -- The signal registered is addnsub -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if addnsub_reg is unregistered and -- addnsub changes value -- ------------------------------------------------------------------------------ IFG9: if (addnsub_reg = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, addnsub) begin if (((addnsub_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub_aclr= "ACLR3") and (aclr3 = '1'))) then addsub_reg <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then addsub_reg <= addnsub; end if; end if; end process; end generate IFG9; IFG10: if (addnsub_reg = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, addnsub) begin if (((addnsub_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub_aclr= "ACLR3") and (aclr3 = '1'))) then addsub_reg <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then addsub_reg <= addnsub; end if; end if; end process; end generate IFG10; IFG11: if (addnsub_reg = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, addnsub) begin if (((addnsub_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub_aclr= "ACLR3") and (aclr3 = '1'))) then addsub_reg <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then addsub_reg <= addnsub; end if; end if; end process; end generate IFG11; IFG12: if (addnsub_reg = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, addnsub) begin if (((addnsub_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub_aclr= "ACLR3") and (aclr3 = '1'))) then addsub_reg <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then addsub_reg <= addnsub; end if; end if; end process; end generate IFG12; -- ------------------------------------------------------------------------------------ -- This process contains 1 register and a combinatorial block (to set addsub_pipe) -- The signal registered is addnsub_latent -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if addnsub_pipeline_reg is unregistered and -- addsub_latent changes value -- ------------------------------------------------------------------------------------ IFG12b: if (addnsub_pipeline_reg = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, addsub_latent) begin if (((addnsub_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then addsub_pipe <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then addsub_pipe <= addsub_latent; end if; end if; end process; end generate IFG12b; IFG14: if (addnsub_pipeline_reg = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, addsub_latent) begin if (((addnsub_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then addsub_pipe <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then addsub_pipe <= addsub_latent; end if; end if; end process; end generate IFG14; IFG15: if (addnsub_pipeline_reg = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, addsub_latent) begin if (((addnsub_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then addsub_pipe <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then addsub_pipe <= addsub_latent; end if; end if; end process; end generate IFG15; IFG16: if (addnsub_pipeline_reg = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, addsub_latent) begin if (((addnsub_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then addsub_pipe <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then addsub_pipe <= addsub_latent; end if; end if; end process; end generate IFG16; -- --------------------------------------------------------------------------------- -- This process contains 1 register and a combinatorial block (to set acc_sload_reg) -- The signal registered is accum_sload -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if accum_sload_reg is unregistered and -- accum_sload changes value -- --------------------------------------------------------------------------------- IFG17: if (accum_sload_reg = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, accum_sload) begin if (((accum_sload_aclr= "ACLR0") and (aclr0 = '1')) or ((accum_sload_aclr= "ACLR1") and (aclr1 = '1')) or ((accum_sload_aclr= "ACLR2") and (aclr2 = '1')) or ((accum_sload_aclr= "ACLR3") and (aclr3 = '1'))) then acc_sload_reg <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then acc_sload_reg <= accum_sload; end if; end if; end process; end generate IFG17; IFG18: if (accum_sload_reg = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, accum_sload) begin if (((accum_sload_aclr= "ACLR0") and (aclr0 = '1')) or ((accum_sload_aclr= "ACLR1") and (aclr1 = '1')) or ((accum_sload_aclr= "ACLR2") and (aclr2 = '1')) or ((accum_sload_aclr= "ACLR3") and (aclr3 = '1'))) then acc_sload_reg <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then acc_sload_reg <= accum_sload; end if; end if; end process; end generate IFG18; IFG19: if (accum_sload_reg = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, accum_sload) begin if (((accum_sload_aclr= "ACLR0") and (aclr0 = '1')) or ((accum_sload_aclr= "ACLR1") and (aclr1 = '1')) or ((accum_sload_aclr= "ACLR2") and (aclr2 = '1')) or ((accum_sload_aclr= "ACLR3") and (aclr3 = '1'))) then acc_sload_reg <= '0'; elsif rising_edge(clock2) then if((ena2 ='1')) then acc_sload_reg <= accum_sload; end if; end if; end process; end generate IFG19; IFG20: if (accum_sload_reg = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, accum_sload) begin if (((accum_sload_aclr= "ACLR0") and (aclr0 = '1')) or ((accum_sload_aclr= "ACLR1") and (aclr1 = '1')) or ((accum_sload_aclr= "ACLR2") and (aclr2 = '1')) or ((accum_sload_aclr= "ACLR3") and (aclr3 = '1'))) then acc_sload_reg <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then acc_sload_reg <= accum_sload; end if; end if; end process; end generate IFG20; -- ------------------------------------------------------------------------------------ -- This process contains 1 register and a combinatorial block (to set accum_sload_pipe) -- The signal registered is accum_sload_latent -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if accum_sload_pipeline_reg -- is unregistered and accum_sload_latent changes value -- ------------------------------------------------------------------------------------ IFG21: if (accum_sload_pipeline_reg = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, accum_sload_latent) begin if (((accum_sload_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_sload_pipe <= '0'; elsif rising_edge(clock0) then if ((ena0 = '1')) then accum_sload_pipe <= accum_sload_latent; end if; end if; end process; end generate IFG21; IFG22: if (accum_sload_pipeline_reg = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, accum_sload_latent) begin if (((accum_sload_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_sload_pipe <= '0'; elsif rising_edge(clock1) then if ((ena1 = '1')) then accum_sload_pipe <= accum_sload_latent; end if; end if; end process; end generate IFG22; IFG23: if (accum_sload_pipeline_reg = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, accum_sload_latent) begin if (((accum_sload_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_sload_pipe <= '0'; elsif rising_edge(clock2) then if ((ena2 = '1')) then accum_sload_pipe <= accum_sload_latent; end if; end if; end process; end generate IFG23; IFG24: if (accum_sload_pipeline_reg = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, accum_sload_latent) begin if (((accum_sload_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_sload_pipe <= '0'; elsif rising_edge(clock3) then if ((ena3 = '1')) then accum_sload_pipe <= accum_sload_latent; end if; end if; end process; end generate IFG24; -- ------------------------------------------------------------------------------ -- This process contains 1 register and a combinatorial block (to set sign_a_reg) -- The signal registered is signa -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if sign_reg_a is unregistered and -- signa changes value -- ------------------------------------------------------------------------------ IFG25: if (sign_reg_a = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, signa) begin if (((sign_aclr_a= "ACLR0") and (aclr0 = '1')) or ((sign_aclr_a= "ACLR1") and (aclr1 = '1')) or ((sign_aclr_a= "ACLR2") and (aclr2 = '1')) or ((sign_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_reg <= '0'; elsif (rising_edge(clock0)) then if (ena0 ='1') then sign_a_reg <= signa; end if; end if; end process; end generate IFG25; IFG26: if (sign_reg_a = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, signa) begin if (((sign_aclr_a= "ACLR0") and (aclr0 = '1')) or ((sign_aclr_a= "ACLR1") and (aclr1 = '1')) or ((sign_aclr_a= "ACLR2") and (aclr2 = '1')) or ((sign_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_reg <= '0'; elsif (rising_edge(clock1) and (ena1 ='1')) then sign_a_reg <= signa; end if; end process; end generate IFG26; IFG27: if (sign_reg_a = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, signa) begin if (((sign_aclr_a= "ACLR0") and (aclr0 = '1')) or ((sign_aclr_a= "ACLR1") and (aclr1 = '1')) or ((sign_aclr_a= "ACLR2") and (aclr2 = '1')) or ((sign_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_reg <= '0'; elsif (rising_edge(clock2) and (ena2 ='1')) then sign_a_reg <= signa; end if; end process; end generate IFG27; IFG28: if (sign_reg_a = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, signa) begin if (((sign_aclr_a= "ACLR0") and (aclr0 = '1')) or ((sign_aclr_a= "ACLR1") and (aclr1 = '1')) or ((sign_aclr_a= "ACLR2") and (aclr2 = '1')) or ((sign_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_reg <= '0'; elsif (rising_edge(clock3) and (ena3 ='1')) then sign_a_reg <= signa; end if; end process; end generate IFG28; -- ------------------------------------------------------------------------------ -- This process contains 1 register and a combinatorial block (to set sign_b_reg) -- The signal registered is signb -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if sign_reg_b is unregistered and -- signb changes value -- ------------------------------------------------------------------------------ IFG29: if (sign_reg_b = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, signb) begin if (((sign_aclr_b= "ACLR0") and (aclr0 = '1')) or ((sign_aclr_b= "ACLR1") and (aclr1 = '1')) or ((sign_aclr_b= "ACLR2") and (aclr2 = '1')) or ((sign_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_reg <= '0'; elsif (rising_edge(clock0)) then if (ena0 ='1') then sign_b_reg <= signb; end if; end if; end process; end generate IFG29; IFG30: if (sign_reg_b = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, signb) begin if (((sign_aclr_b= "ACLR0") and (aclr0 = '1')) or ((sign_aclr_b= "ACLR1") and (aclr1 = '1')) or ((sign_aclr_b= "ACLR2") and (aclr2 = '1')) or ((sign_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_reg <= '0'; elsif (rising_edge(clock1) and (ena1 ='1')) then sign_b_reg <= signb; end if; end process; end generate IFG30; IFG31: if (sign_reg_b = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, signb) begin if (((sign_aclr_b= "ACLR0") and (aclr0 = '1')) or ((sign_aclr_b= "ACLR1") and (aclr1 = '1')) or ((sign_aclr_b= "ACLR2") and (aclr2 = '1')) or ((sign_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_reg <= '0'; elsif (rising_edge(clock2) and (ena2 ='1')) then sign_b_reg <= signb; end if; end process; end generate IFG31; IFG32: if (sign_reg_b = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, signb) begin if (((sign_aclr_b= "ACLR0") and (aclr0 = '1')) or ((sign_aclr_b= "ACLR1") and (aclr1 = '1')) or ((sign_aclr_b= "ACLR2") and (aclr2 = '1')) or ((sign_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_reg <= '0'; elsif (rising_edge(clock3) and (ena3 ='1'))then sign_b_reg <= signb; end if; end process; end generate IFG32; -- ------------------------------------------------------------------------------- -- This process contains 1 register and a combinatorial block (to set sign_a_pipe) -- The signal registered is sign_a_latent -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if sign_pipeline_reg_a -- is unregistered and sign_a_latent changes value -- ------------------------------------------------------------------------------- IFG33: if (sign_pipeline_reg_a = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, sign_a_latent) begin if (((sign_pipeline_aclr_a= "ACLR0") and (aclr0 = '1')) or ((sign_pipeline_aclr_a= "ACLR1") and (aclr1 = '1')) or ((sign_pipeline_aclr_a= "ACLR2") and (aclr2 = '1')) or ((sign_pipeline_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_pipe <= '0'; elsif (rising_edge(clock0)) then if (ena0 ='1') then sign_a_pipe <= sign_a_latent; end if; end if; end process; end generate IFG33; IFG34: if (sign_pipeline_reg_a = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, sign_a_latent) begin if (((sign_pipeline_aclr_a= "ACLR0") and (aclr0 = '1')) or ((sign_pipeline_aclr_a= "ACLR1") and (aclr1 = '1')) or ((sign_pipeline_aclr_a= "ACLR2") and (aclr2 = '1')) or ((sign_pipeline_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_pipe <= '0'; elsif (rising_edge(clock1) and (ena1 ='1')) then sign_a_pipe <= sign_a_latent; end if; end process; end generate IFG34; IFG35: if (sign_pipeline_reg_a = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, sign_a_latent) begin if (((sign_pipeline_aclr_a= "ACLR0") and (aclr0 = '1')) or ((sign_pipeline_aclr_a= "ACLR1") and (aclr1 = '1')) or ((sign_pipeline_aclr_a= "ACLR2") and (aclr2 = '1')) or ((sign_pipeline_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_pipe <= '0'; elsif (rising_edge(clock2) and (ena2 ='1')) then sign_a_pipe <= sign_a_latent; end if; end process; end generate IFG35; IFG36: if (sign_pipeline_reg_a = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, sign_a_latent) begin if (((sign_pipeline_aclr_a= "ACLR0") and (aclr0 = '1')) or ((sign_pipeline_aclr_a= "ACLR1") and (aclr1 = '1')) or ((sign_pipeline_aclr_a= "ACLR2") and (aclr2 = '1')) or ((sign_pipeline_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_pipe <= '0'; elsif (rising_edge(clock3) and (ena3 ='1')) then sign_a_pipe <= sign_a_latent; end if; end process; end generate IFG36; -- ------------------------------------------------------------------------------- -- This process contains 1 register and a combinatorial block (to set sign_b_pipe) -- The signal registered is sign_b_latent -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if sign_pipeline_reg_b -- is unregistered and sign_b_latent changes value -- ------------------------------------------------------------------------------- IFG37: if (sign_pipeline_reg_b = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, sign_b_latent) begin if (((sign_pipeline_aclr_b= "ACLR0") and (aclr0 = '1')) or ((sign_pipeline_aclr_b= "ACLR1") and (aclr1 = '1')) or ((sign_pipeline_aclr_b= "ACLR2") and (aclr2 = '1')) or ((sign_pipeline_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_pipe <= '0'; elsif (rising_edge(clock0)) then if (ena0 ='1') then sign_b_pipe <= sign_b_latent; end if; end if; end process; end generate IFG37; IFG38: if (sign_pipeline_reg_b = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, sign_b_latent) begin if (((sign_pipeline_aclr_b= "ACLR0") and (aclr0 = '1')) or ((sign_pipeline_aclr_b= "ACLR1") and (aclr1 = '1')) or ((sign_pipeline_aclr_b= "ACLR2") and (aclr2 = '1')) or ((sign_pipeline_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_pipe <= '0'; elsif (rising_edge(clock1) and (ena1 ='1')) then sign_b_pipe <= sign_b_latent; end if; end process; end generate IFG38; IFG39: if (sign_pipeline_reg_b = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, sign_b_latent) begin if (((sign_pipeline_aclr_b= "ACLR0") and (aclr0 = '1')) or ((sign_pipeline_aclr_b= "ACLR1") and (aclr1 = '1')) or ((sign_pipeline_aclr_b= "ACLR2") and (aclr2 = '1')) or ((sign_pipeline_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_pipe <= '0'; elsif (rising_edge(clock2) and (ena2 ='1')) then sign_b_pipe <= sign_b_latent; end if; end process; end generate IFG39; IFG40: if (sign_pipeline_reg_b = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, sign_b_latent) begin if (((sign_pipeline_aclr_b= "ACLR0") and (aclr0 = '1')) or ((sign_pipeline_aclr_b= "ACLR1") and (aclr1 = '1')) or ((sign_pipeline_aclr_b= "ACLR2") and (aclr2 = '1')) or ((sign_pipeline_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_pipe <= '0'; elsif (rising_edge(clock3) and (ena3 ='1')) then sign_b_pipe <= sign_b_latent; end if; end process; end generate IFG40; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set accum_round_pipe_wire) -- The signal registered is accum_round -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if accum_round_reg -- is unregistered and accum_round changes value ------------------------------------------------------------------------------------- IFG41: if (accum_round_reg = "CLOCK0") generate process (clock0, accum_round, aclr0, aclr1, aclr2, aclr3) begin if (((accum_round_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_round_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_round_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_round_aclr = "ACLR3") and (aclr3 = '1'))) then accum_round_pipe_wire <= '0'; elsif (rising_edge(clock0)) then if (ena0 = '1') then if (IS_STRATIXIII) then accum_round_pipe_wire <= accum_sload; else accum_round_pipe_wire <= accum_round; end if; end if; end if; end process; end generate IFG41; IFG42: if (accum_round_reg = "CLOCK1") generate process (clock1, accum_round, aclr0, aclr1, aclr2, aclr3) begin if (((accum_round_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_round_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_round_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_round_aclr = "ACLR3") and (aclr3 = '1'))) then accum_round_pipe_wire <= '0'; elsif (rising_edge(clock1) and (ena1 = '1')) then if (IS_STRATIXIII) then accum_round_pipe_wire <= accum_sload; else accum_round_pipe_wire <= accum_round; end if; end if; end process; end generate IFG42; IFG43: if (accum_round_reg = "CLOCK2") generate process (clock2, accum_round, aclr0, aclr1, aclr2, aclr3) begin if (((accum_round_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_round_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_round_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_round_aclr = "ACLR3") and (aclr3 = '1'))) then accum_round_pipe_wire <= '0'; elsif (rising_edge(clock2) and (ena2 = '1')) then if (IS_STRATIXIII) then accum_round_pipe_wire <= accum_sload; else accum_round_pipe_wire <= accum_round; end if; end if; end process; end generate IFG43; IFG44: if (accum_round_reg = "CLOCK3") generate process (clock3, accum_round, aclr0, aclr1, aclr2, aclr3) begin if (((accum_round_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_round_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_round_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_round_aclr = "ACLR3") and (aclr3 = '1'))) then accum_round_pipe_wire <= '0'; elsif (rising_edge(clock3) and (ena3 = '1')) then if (IS_STRATIXIII) then accum_round_pipe_wire <= accum_sload; else accum_round_pipe_wire <= accum_round; end if; end if; end process; end generate IFG44; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set accum_round_wire) -- The signal registered is accum_round_pipe_wire -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if accum_round_pipeline_reg -- is unregistered and accum_round_pipe_wire changes value ------------------------------------------------------------------------------------- IFG45: if (accum_round_pipeline_reg = "CLOCK0") generate process (clock0, accum_round_pipe_wire, aclr0, aclr1, aclr2, aclr3) begin if (((accum_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_round_wire <= '0'; elsif (rising_edge(clock0)) then if (ena0 = '1') then accum_round_wire <= accum_round_pipe_wire; end if; end if; end process; end generate IFG45; IFG46: if (accum_round_pipeline_reg = "CLOCK1") generate process (clock1, accum_round_pipe_wire, aclr0, aclr1, aclr2, aclr3) begin if (((accum_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_round_wire <= '0'; elsif (rising_edge(clock1) and (ena1 = '1')) then accum_round_wire <= accum_round_pipe_wire; end if; end process; end generate IFG46; IFG47: if (accum_round_pipeline_reg = "CLOCK2") generate process (clock2, accum_round_pipe_wire, aclr0, aclr1, aclr2, aclr3) begin if (((accum_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_round_wire <= '0'; elsif (rising_edge(clock2) and (ena2 = '1')) then accum_round_wire <= accum_round_pipe_wire; end if; end process; end generate IFG47; IFG48: if (accum_round_pipeline_reg = "CLOCK3") generate process (clock3, accum_round_pipe_wire, aclr0, aclr1, aclr2, aclr3) begin if (((accum_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_round_wire <= '0'; elsif (rising_edge(clock3) and (ena3 = '1')) then accum_round_wire <= accum_round_pipe_wire; end if; end process; end generate IFG48; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set accum_saturation_pipe_wire) -- The signal registered is accum_saturation -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if accum_saturation_reg -- is unregistered and accum_saturation changes value -- --------------------------------------------------------------------------------- IFG49: if (accum_saturation_reg = "CLOCK0") generate process (clock0, accum_saturation, aclr0, aclr1, aclr2, aclr3) begin if (((accum_saturation_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_saturation_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_saturation_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_saturation_aclr = "ACLR3") and (aclr3 = '1'))) then accum_saturation_pipe_wire <= '0'; elsif (rising_edge(clock0)) then if (ena0 = '1')then accum_saturation_pipe_wire <= accum_saturation; end if; end if; end process; end generate IFG49; IFG50: if (accum_saturation_reg = "CLOCK1") generate process (clock1, accum_saturation, aclr0, aclr1, aclr2, aclr3) begin if (((accum_saturation_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_saturation_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_saturation_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_saturation_aclr = "ACLR3") and (aclr3 = '1'))) then accum_saturation_pipe_wire <= '0'; elsif (rising_edge(clock1) and (ena1 = '1')) then accum_saturation_pipe_wire <= accum_saturation; end if; end process; end generate IFG50; IFG51: if (accum_saturation_reg = "CLOCK2") generate process (clock2, accum_saturation, aclr0, aclr1, aclr2, aclr3) begin if (((accum_saturation_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_saturation_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_saturation_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_saturation_aclr = "ACLR3") and (aclr3 = '1'))) then accum_saturation_pipe_wire <= '0'; elsif (rising_edge(clock2) and (ena2 = '1')) then accum_saturation_pipe_wire <= accum_saturation; end if; end process; end generate IFG51; IFG52: if (accum_saturation_reg = "CLOCK3") generate process (clock3, accum_saturation, aclr0, aclr1, aclr2, aclr3) begin if (((accum_saturation_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_saturation_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_saturation_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_saturation_aclr = "ACLR3") and (aclr3 = '1'))) then accum_saturation_pipe_wire <= '0'; elsif (rising_edge(clock3) and (ena3 = '1')) then accum_saturation_pipe_wire <= accum_saturation; end if; end process; end generate IFG52; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set accum_saturate_wire) -- The signal registered is accum_saturation_pipe_wire -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if accum_saturation_pipeline_reg -- is unregistered and accum_saturation_pipe_wire changes value -- --------------------------------------------------------------------------------- IFG53: if (accum_saturation_pipeline_reg = "CLOCK0") generate process (clock0, accum_saturation_pipe_wire, aclr0, aclr1, aclr2, aclr3) begin if (((accum_saturation_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_saturate_wire <= '0'; elsif (rising_edge(clock0)) then if (ena0 = '1') then accum_saturate_wire <= accum_saturation_pipe_wire; end if; end if; end process; end generate IFG53; IFG54: if (accum_saturation_pipeline_reg = "CLOCK1") generate process (clock1, accum_saturation_pipe_wire, aclr0, aclr1, aclr2, aclr3) begin if (((accum_saturation_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_saturate_wire <= '0'; elsif (rising_edge(clock1) and (ena1 = '1')) then accum_saturate_wire <= accum_saturation_pipe_wire; end if; end process; end generate IFG54; IFG55: if (accum_saturation_pipeline_reg = "CLOCK2") generate process (clock2, accum_saturation_pipe_wire, aclr0, aclr1, aclr2, aclr3) begin if (((accum_saturation_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_saturate_wire <= '0'; elsif (rising_edge(clock2) and (ena2 = '1')) then accum_saturate_wire <= accum_saturation_pipe_wire; end if; end process; end generate IFG55; IFG56: if (accum_saturation_pipeline_reg = "CLOCK3") generate process (clock3, accum_saturation_pipe_wire, aclr0, aclr1, aclr2, aclr3) begin if (((accum_saturation_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_saturation_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accum_saturate_wire <= '0'; elsif (rising_edge(clock3) and (ena3 = '1')) then accum_saturate_wire <= accum_saturation_pipe_wire; end if; end process; end generate IFG56; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set mult_round_wire) -- The signal registered is mult_round -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if mult_round_reg -- is unregistered and mult_round changes value -- --------------------------------------------------------------------------------- IFG57: if (mult_round_reg = "CLOCK0") generate process (clock0, mult_round, aclr0, aclr1, aclr2, aclr3) begin if (((mult_round_aclr = "ACLR0") and (aclr0 = '1')) or ((mult_round_aclr = "ACLR1") and (aclr1 = '1')) or ((mult_round_aclr = "ACLR2") and (aclr2 = '1')) or ((mult_round_aclr = "ACLR3") and (aclr3 = '1'))) then mult_round_wire <= '0'; elsif (rising_edge(clock0)) then if (ena0 = '1') then mult_round_wire <= mult_round; end if; end if; end process; end generate IFG57; IFG58: if (mult_round_reg = "CLOCK1") generate process (clock1, mult_round, aclr0, aclr1, aclr2, aclr3) begin if (((mult_round_aclr = "ACLR0") and (aclr0 = '1')) or ((mult_round_aclr = "ACLR1") and (aclr1 = '1')) or ((mult_round_aclr = "ACLR2") and (aclr2 = '1')) or ((mult_round_aclr = "ACLR3") and (aclr3 = '1'))) then mult_round_wire <= '0'; elsif (rising_edge(clock1) and (ena1 = '1')) then mult_round_wire <= mult_round; end if; end process; end generate IFG58; IFG59: if (mult_round_reg = "CLOCK2") generate process (clock2, mult_round, aclr0, aclr1, aclr2, aclr3) begin if (((mult_round_aclr = "ACLR0") and (aclr0 = '1')) or ((mult_round_aclr = "ACLR1") and (aclr1 = '1')) or ((mult_round_aclr = "ACLR2") and (aclr2 = '1')) or ((mult_round_aclr = "ACLR3") and (aclr3 = '1'))) then mult_round_wire <= '0'; elsif (rising_edge(clock2) and (ena2 = '1')) then mult_round_wire <= mult_round; end if; end process; end generate IFG59; IFG60: if (mult_round_reg = "CLOCK3") generate process (clock3, mult_round, aclr0, aclr1, aclr2, aclr3) begin if (((mult_round_aclr = "ACLR0") and (aclr0 = '1')) or ((mult_round_aclr = "ACLR1") and (aclr1 = '1')) or ((mult_round_aclr = "ACLR2") and (aclr2 = '1')) or ((mult_round_aclr = "ACLR3") and (aclr3 = '1'))) then mult_round_wire <= '0'; elsif (rising_edge(clock3) and (ena3 = '1')) then mult_round_wire <= mult_round; end if; end process; end generate IFG60; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set mult_saturation_wire) -- The signal registered is mult_saturation -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if mult_saturation_reg -- is unregistered and mult_saturation changes value -- --------------------------------------------------------------------------------- IFG61: if (mult_saturation_reg = "CLOCK0") generate process (clock0, mult_saturation, aclr0, aclr1, aclr2, aclr3) begin if (((mult_saturation_aclr = "ACLR0") and (aclr0 = '1')) or ((mult_saturation_aclr = "ACLR1") and (aclr1 = '1')) or ((mult_saturation_aclr = "ACLR2") and (aclr2 = '1')) or ((mult_saturation_aclr = "ACLR3") and (aclr3 = '1'))) then mult_saturate_wire <= '0'; elsif (rising_edge(clock0)) then if (ena0 = '1') then mult_saturate_wire <= mult_saturation; end if; end if; end process; end generate IFG61; IFG62: if (mult_saturation_reg = "CLOCK1") generate process (clock1, mult_saturation, aclr0, aclr1, aclr2, aclr3) begin if (((mult_saturation_aclr = "ACLR0") and (aclr0 = '1')) or ((mult_saturation_aclr = "ACLR1") and (aclr1 = '1')) or ((mult_saturation_aclr = "ACLR2") and (aclr2 = '1')) or ((mult_saturation_aclr = "ACLR3") and (aclr3 = '1'))) then mult_saturate_wire <= '0'; elsif (rising_edge(clock1) and (ena1 = '1')) then mult_saturate_wire <= mult_saturation; end if; end process; end generate IFG62; IFG63: if (mult_saturation_reg = "CLOCK2") generate process (clock2, mult_saturation, aclr0, aclr1, aclr2, aclr3) begin if (((mult_saturation_aclr = "ACLR0") and (aclr0 = '1')) or ((mult_saturation_aclr = "ACLR1") and (aclr1 = '1')) or ((mult_saturation_aclr = "ACLR2") and (aclr2 = '1')) or ((mult_saturation_aclr = "ACLR3") and (aclr3 = '1'))) then mult_saturate_wire <= '0'; elsif (rising_edge(clock2) and (ena2 = '1')) then mult_saturate_wire <= mult_saturation; end if; end process; end generate IFG63; IFG64: if (mult_saturation_reg = "CLOCK3") generate process (clock3, mult_saturation, aclr0, aclr1, aclr2, aclr3) begin if (((mult_saturation_aclr = "ACLR0") and (aclr0 = '1')) or ((mult_saturation_aclr = "ACLR1") and (aclr1 = '1')) or ((mult_saturation_aclr = "ACLR2") and (aclr2 = '1')) or ((mult_saturation_aclr = "ACLR3") and (aclr3 = '1'))) then mult_saturate_wire <= '0'; elsif (rising_edge(clock3) and (ena3 = '1')) then mult_saturate_wire <= mult_saturation; end if; end process; end generate IFG64; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set sload_upper_data_reg) -- The signal registered is accum_sload_upper_data -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if accum_sload_upper_data_reg -- is unregistered and accum_sload_upper_data changes value -- --------------------------------------------------------------------------------- IFG65: if (accum_sload_upper_data_reg = "CLOCK0") generate process (clock0, accum_sload_upper_data, aclr0, aclr1, aclr2, aclr3) begin if (((accum_sload_upper_data_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_upper_data_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_upper_data_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_upper_data_aclr = "ACLR3") and (aclr3 = '1'))) then sload_upper_data_reg <= (others => '0'); elsif (rising_edge(clock0)) then if (ena0 = '1') then sload_upper_data_reg <= accum_sload_upper_data; end if; end if; end process; end generate IFG65; IFG66: if (accum_sload_upper_data_reg = "CLOCK1") generate process (clock1, accum_sload_upper_data, aclr0, aclr1, aclr2, aclr3) begin if (((accum_sload_upper_data_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_upper_data_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_upper_data_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_upper_data_aclr = "ACLR3") and (aclr3 = '1'))) then sload_upper_data_reg <= (others => '0'); elsif (rising_edge(clock1) and (ena1 = '1')) then sload_upper_data_reg <= accum_sload_upper_data; end if; end process; end generate IFG66; IFG67: if (accum_sload_upper_data_reg = "CLOCK2") generate process (clock2, accum_sload_upper_data, aclr0, aclr1, aclr2, aclr3) begin if (((accum_sload_upper_data_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_upper_data_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_upper_data_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_upper_data_aclr = "ACLR3") and (aclr3 = '1'))) then sload_upper_data_reg <= (others => '0'); elsif (rising_edge(clock2) and (ena2 = '1')) then sload_upper_data_reg <= accum_sload_upper_data; end if; end process; end generate IFG67; IFG68: if (accum_sload_upper_data_reg = "CLOCK3") generate process (clock3, accum_sload_upper_data, aclr0, aclr1, aclr2, aclr3) begin if (((accum_sload_upper_data_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_upper_data_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_upper_data_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_upper_data_aclr = "ACLR3") and (aclr3 = '1'))) then sload_upper_data_reg <= (others => '0'); elsif (rising_edge(clock3) and (ena3 = '1')) then sload_upper_data_reg <= accum_sload_upper_data; end if; end process; end generate IFG68; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set sload_upper_data_wire) -- The signal registered is sload_upper_data_latent -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if accum_sload_upper_data_pipeline_reg -- is unregistered and sload_upper_data_latent changes value -- --------------------------------------------------------------------------------- IFG69: if (accum_sload_upper_data_pipeline_reg = "CLOCK0") generate process (clock0, sload_upper_data_latent, aclr0, aclr1, aclr2, aclr3) begin if (((accum_sload_upper_data_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then sload_upper_data_wire <= (others => '0'); elsif (rising_edge(clock0)) then if (ena0 = '1') then sload_upper_data_wire <= sload_upper_data_latent; end if; end if; end process; end generate IFG69; IFG70: if (accum_sload_upper_data_pipeline_reg = "CLOCK1") generate process (clock1, sload_upper_data_latent, aclr0, aclr1, aclr2, aclr3) begin if (((accum_sload_upper_data_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then sload_upper_data_wire <= (others => '0'); elsif (rising_edge(clock1) and (ena1 = '1')) then sload_upper_data_wire <= sload_upper_data_latent; end if; end process; end generate IFG70; IFG71: if (accum_sload_upper_data_pipeline_reg = "CLOCK2") generate process (clock2, sload_upper_data_latent, aclr0, aclr1, aclr2, aclr3) begin if (((accum_sload_upper_data_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then sload_upper_data_wire <= (others => '0'); elsif (rising_edge(clock2) and (ena2 = '1')) then sload_upper_data_wire <= sload_upper_data_latent; end if; end process; end generate IFG71; IFG72: if (accum_sload_upper_data_pipeline_reg = "CLOCK3") generate process (clock3, sload_upper_data_latent, aclr0, aclr1, aclr2, aclr3) begin if (((accum_sload_upper_data_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_upper_data_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then sload_upper_data_wire <= (others => '0'); elsif (rising_edge(clock3) and (ena3 = '1')) then sload_upper_data_wire <= sload_upper_data_latent; end if; end process; end generate IFG72; -- ---------------------------------------------------------------------------- -- This block multiplies the two input numbers and sets the result to mult_final_out -- ---------------------------------------------------------------------------- process (mult_a, mult_b, sign_a_reg, sign_b_reg, mult_round_wire, mult_saturate_wire, signa, signb, temp_mult_zero) variable temp_mult_int : std_logic_vector (int_width_a + int_width_b downto 0); variable temp_mult : std_logic_vector (int_width_a + int_width_b -1 downto 0):= (others => '0'); variable neg_a, neg_b, is_signed : std_logic; variable mult_round_out : std_logic_vector (int_width_a + int_width_b - 1 downto 0) := (others => '0'); variable mult_saturate_overflow : std_logic := '0'; variable mult_saturate_out : std_logic_vector (int_width_a + int_width_b - 1 downto 0) := (others => '0'); variable mult_result : std_logic_vector (int_width_a + int_width_b - 1 downto 0) := (others => '0'); variable int_mult_a : std_logic_vector (int_width_a - 1 downto 0); variable int_mult_b : std_logic_vector (int_width_b - 1 downto 0); variable mult_a_zero_bits_pad : std_logic_vector (int_width_a - width_a - 1 downto 0) := (others => '0'); variable mult_b_zero_bits_pad : std_logic_vector (int_width_b - width_b - 1 downto 0) := (others => '0'); begin is_signed := '0'; if (port_signa = "PORT_CONNECTIVITY") then if (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_reg = '1')) then neg_a := mult_a (width_a-1); is_signed :='1'; end if; else if (((representation_a = "SIGNED") and (port_signa = "PORT_UNUSED")) or (sign_a_reg = '1')) then neg_a := mult_a (width_a-1); is_signed :='1'; end if; end if; if (port_signb = "PORT_CONNECTIVITY") then if (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_reg = '1')) then neg_b := mult_b (width_b-1); is_signed :='1'; end if; else if (((representation_b = "SIGNED") and (port_signb = "PORT_UNUSED")) or (sign_b_reg = '1')) then neg_b := mult_b (width_b-1); is_signed :='1'; end if; end if; if(int_width_a > width_a) then int_mult_a := mult_a & mult_a_zero_bits_pad; else int_mult_a := mult_a; end if; if(int_width_b > width_b) then int_mult_b := mult_b & mult_b_zero_bits_pad; else int_mult_b := mult_b; end if; if (port_signa = "PORT_CONNECTIVITY" and port_signb ="PORT_CONNECTIVITY") then if (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_reg = '1')) then if (((representation_b = "SIGNED") and( signb = 'Z')) or (sign_b_reg = '1')) then temp_mult_int := signed (temp_mult_zero) + (signed (int_mult_a) * signed (int_mult_b)); else temp_mult_int := signed (temp_mult_zero) + (signed (int_mult_a) * unsigned (int_mult_b)); end if; else if (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_reg = '1')) then temp_mult_int := signed (temp_mult_zero) + (unsigned (int_mult_a) * signed (int_mult_b)); else temp_mult_int := signed (temp_mult_zero) + (unsigned (int_mult_a) * unsigned (int_mult_b)); end if; end if; else if (((representation_a = "SIGNED") and (port_signa = "PORT_UNUSED")) or (sign_a_reg = '1')) then if (((representation_b = "SIGNED") and(port_signb = "PORT_UNUSED")) or (sign_b_reg = '1')) then temp_mult_int := signed (temp_mult_zero) + (signed (int_mult_a) * signed (int_mult_b)); else temp_mult_int := signed (temp_mult_zero) + (signed (int_mult_a) * unsigned (int_mult_b)); end if; else if (((representation_b = "SIGNED") and (port_signb = "PORT_UNUSED")) or (sign_b_reg = '1')) then temp_mult_int := signed (temp_mult_zero) + (unsigned (int_mult_a) * signed (int_mult_b)); else temp_mult_int := signed (temp_mult_zero) + (unsigned (int_mult_a) * unsigned (int_mult_b)); end if; end if; end if; temp_mult := temp_mult_int (int_width_a + int_width_b -1 downto 0); if (FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) then -- StratixII rounding support -- This is based on both input is in Q1.15 format with assumption -- width_a = 16 and width_b = 16 if ((multiplier_rounding = "YES") or ((multiplier_rounding = "VARIABLE") and (mult_round_wire = '1'))) then mult_round_out := unsigned (temp_mult) + ( 2 ** (int_width_a + int_width_b - 18)); else mult_round_out := temp_mult; end if; -- StratixII saturation support if ((multiplier_saturation = "YES") or (( multiplier_saturation = "VARIABLE") and (mult_saturate_wire = '1'))) then if((mult_round_out(int_width_a + int_width_b - 1) = '0') and (mult_round_out(int_width_a + int_width_b - 2) = '1')) then mult_saturate_overflow := '1'; else mult_saturate_overflow := '0'; end if; if (mult_saturate_overflow = '0') then mult_saturate_out := mult_round_out; else for i in (int_width_a + int_width_b - 1) downto (int_width_a + int_width_b - 2) loop mult_saturate_out(i) := mult_round_out(int_width_a + int_width_b - 1); end loop; for i in (int_width_a + int_width_b - 3) downto 0 loop mult_saturate_out(i) := not mult_round_out(int_width_a + int_width_b - 1); end loop; for i in (int_width_a + int_width_b - 34) downto 0 loop mult_saturate_out(i) := '0'; end loop; end if; else mult_saturate_out := mult_round_out; mult_saturate_overflow := '0'; end if; if ((multiplier_rounding = "YES") or ((multiplier_rounding = "VARIABLE") and (mult_round_wire = '1'))) then mult_result := mult_saturate_out; for i in (int_width_a + int_width_b - 18) downto 0 loop mult_result(i) := '0'; end loop; else mult_result := mult_saturate_out; end if; mult_is_saturated_wire <= mult_saturate_overflow; end if; if (not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) then mult_final_out <= temp_mult; else mult_final_out <= mult_result; end if; end process; -- ---------------------------------------------------------------------------- -- This process contains 1 register and a combinatorial block (to set mult_res) -- The signal registered is mult_out_latent -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if multiplier_reg -- is unregistered and mult_out_latent changes value -- ---------------------------------------------------------------------------- IFG73: if (multiplier_reg = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, mult_out_latent) begin if (((multiplier_aclr= "ACLR0") and (aclr0 = '1')) or ((multiplier_aclr= "ACLR1") and (aclr1 = '1')) or ((multiplier_aclr= "ACLR2") and (aclr2 = '1')) or ((multiplier_aclr= "ACLR3") and (aclr3 = '1'))) then mult_res <= (others =>'0'); elsif (rising_edge(clock0)) then if (ena0 ='1') then mult_res <= mult_out_latent; end if; end if; end process; end generate IFG73; IFG74: if (multiplier_reg = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, mult_out_latent) begin if (((multiplier_aclr= "ACLR0") and (aclr0 = '1')) or ((multiplier_aclr= "ACLR1") and (aclr1 = '1')) or ((multiplier_aclr= "ACLR2") and (aclr2 = '1')) or ((multiplier_aclr= "ACLR3") and (aclr3 = '1'))) then mult_res <= (others =>'0'); elsif (rising_edge(clock1) and (ena1 ='1')) then mult_res <= mult_out_latent; end if; end process; end generate IFG74; IFG75: if (multiplier_reg = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, mult_out_latent) begin if (((multiplier_aclr= "ACLR0") and (aclr0 = '1')) or ((multiplier_aclr= "ACLR1") and (aclr1 = '1')) or ((multiplier_aclr= "ACLR2") and (aclr2 = '1')) or ((multiplier_aclr= "ACLR3") and (aclr3 = '1'))) then mult_res <= (others =>'0'); elsif (rising_edge(clock2) and (ena2 ='1')) then mult_res <= mult_out_latent; end if; end process; end generate IFG75; IFG76: if (multiplier_reg = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, mult_out_latent) begin if (((multiplier_aclr= "ACLR0") and (aclr0 = '1')) or ((multiplier_aclr= "ACLR1") and (aclr1 = '1')) or ((multiplier_aclr= "ACLR2") and (aclr2 = '1')) or ((multiplier_aclr= "ACLR3") and (aclr3 = '1'))) then mult_res <= (others =>'0'); elsif (rising_edge(clock3) and (ena3 ='1')) then mult_res <= mult_out_latent; end if; end process; end generate IFG76; -- ---------------------------------------------------------------------------- -- This process contains 1 register and a combinatorial block (to set mult_is_saturated_reg) -- The signal registered is mult_is_saturated_wire -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if multiplier_reg -- is unregistered and mult_is_saturated_wire changes value -- ---------------------------------------------------------------------------- IFG77: if (multiplier_reg = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, mult_is_saturated_wire) begin if (((multiplier_aclr= "ACLR0") and (aclr0 = '1')) or ((multiplier_aclr= "ACLR1") and (aclr1 = '1')) or ((multiplier_aclr= "ACLR2") and (aclr2 = '1')) or ((multiplier_aclr= "ACLR3") and (aclr3 = '1'))) then mult_is_saturated_reg <= '0'; elsif (rising_edge(clock0)) then if (ena0 ='1') then mult_is_saturated_reg <= mult_is_saturated_wire; end if; end if; end process; end generate IFG77; IFG78: if (multiplier_reg = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, mult_is_saturated_wire) begin if (((multiplier_aclr= "ACLR0") and (aclr0 = '1')) or ((multiplier_aclr= "ACLR1") and (aclr1 = '1')) or ((multiplier_aclr= "ACLR2") and (aclr2 = '1')) or ((multiplier_aclr= "ACLR3") and (aclr3 = '1'))) then mult_is_saturated_reg <= '0'; elsif (rising_edge(clock1) and (ena1 ='1')) then mult_is_saturated_reg <= mult_is_saturated_wire; end if; end process; end generate IFG78; IFG79: if (multiplier_reg = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, mult_is_saturated_wire) begin if (((multiplier_aclr= "ACLR0") and (aclr0 = '1')) or ((multiplier_aclr= "ACLR1") and (aclr1 = '1')) or ((multiplier_aclr= "ACLR2") and (aclr2 = '1')) or ((multiplier_aclr= "ACLR3") and (aclr3 = '1'))) then mult_is_saturated_reg <= '0'; elsif (rising_edge(clock2) and (ena2 ='1')) then mult_is_saturated_reg <= mult_is_saturated_wire; end if; end process; end generate IFG79; IFG80: if (multiplier_reg = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, mult_is_saturated_wire) begin if (((multiplier_aclr= "ACLR0") and (aclr0 = '1')) or ((multiplier_aclr= "ACLR1") and (aclr1 = '1')) or ((multiplier_aclr= "ACLR2") and (aclr2 = '1')) or ((multiplier_aclr= "ACLR3") and (aclr3 = '1'))) then mult_is_saturated_reg <= '0'; elsif (rising_edge(clock3) and (ena3 ='1')) then mult_is_saturated_reg <= mult_is_saturated_wire; end if; end process; end generate IFG80; IFG81: if (extra_multiplier_latency >0) generate process (clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3) -- ------------------------------------------------------------------------ -- This process is only valid if extra_multiplier_latency is greater then 0 -- ------------------------------------------------------------------------ variable head_mult_int: integer := 0; begin -- ------------------------------------------------------------------------ -- This process is only valid if extra_multiplier_latency is greater then 0 -- ------------------------------------------------------------------------ if ( (((multiplier_aclr= "ACLR0") or (multiplier_reg = "UNREGISTERED")) and (aclr0 = '1')) or ((multiplier_reg /= "UNREGISTERED") and ( ((multiplier_aclr= "ACLR1") and (aclr1 = '1')) or ((multiplier_aclr= "ACLR2") and (aclr2 = '1')) or ((multiplier_aclr= "ACLR3") and (aclr3 = '1')) )) ) then mult_pipe <= (others => (others => '0')); mult_full <= (others => '0'); sload_upper_data_full <= (others => '0'); sload_upper_data_pipe <= (others => (others => '0')); elsif ( (rising_edge(clock0) and ((multiplier_reg = "CLOCK0") or (multiplier_reg = "UNREGISTERED"))) or (rising_edge(clock1) and (multiplier_reg = "CLOCK1")) or (rising_edge(clock2) and (multiplier_reg = "CLOCK2")) or (rising_edge(clock3) and (multiplier_reg = "CLOCK3")) ) then if ((((multiplier_reg = "CLOCK0") or (multiplier_reg = "UNREGISTERED")) and (ena0 ='1')) or ((multiplier_reg = "CLOCK1") and (ena1 ='1')) or ((multiplier_reg = "CLOCK2") and (ena2 ='1')) or ((multiplier_reg = "CLOCK3") and (ena3 ='1')) ) then if (extra_multiplier_latency >0) then head_mult_int := head_mult; mult_pipe (head_mult_int) <= sign_a_reg & sign_b_reg & acc_sload_reg & addsub_reg & '0' & mult_final_out; sload_upper_data_pipe (head_mult_int) <= sload_upper_data_reg; head_mult_int := (head_mult_int +1) mod (extra_multiplier_latency); if (extra_multiplier_latency = 1) then mult_full <= sign_a_reg & sign_b_reg & acc_sload_reg & addsub_reg & '0' & mult_final_out; sload_upper_data_full <= sload_upper_data_reg; else mult_full <= (mult_pipe(head_mult_int)); sload_upper_data_full <= (sload_upper_data_pipe(head_mult_int)); end if; head_mult <= head_mult_int; end if; end if; end if; end process; end generate IFG81; process (clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3) -- ------------------------------------------------------------- -- This is the main process block that performs the accumulation -- ------------------------------------------------------------- variable head_result_int : integer := 0; variable temp_sum : std_logic_vector (int_width_result downto 0) := (others => '0'); variable result_full : std_logic_vector (int_width_result downto 0) := (others => '0'); variable cout_int, overflow_int :std_logic; variable temp_sum_zero : std_logic_vector (int_width_result downto 0) := (others => '0'); variable accum_int, addsub_int, signed_int : std_logic; variable result_temp : std_logic_vector (int_width_result -1 downto 0); variable sign_extend : std_logic_vector (int_width_result - int_width_a - int_width_b - 1 downto 0) := (others => '0'); variable mult_res_temp : std_logic_vector (int_width_result -1 downto 0) := (others => '0'); variable accum_final_out : std_logic_vector (int_width_result - 1 downto 0) := (others => '0'); variable accum_round_out : std_logic_vector (int_width_result - 1 downto 0) := (others => '0'); variable accum_saturate_overflow : std_logic := '0'; variable accum_saturate_out : std_logic_vector (int_width_result - 1 downto 0) := (others => '0'); variable accum_result_sign_bits : std_logic_vector (int_width_result - int_width_a - int_width_b + 2 - 1 downto 0) := (others => '0'); variable accum_result_sign_bits_ones : std_logic_vector (int_width_result - int_width_a - int_width_b + 2 - 1 downto 0) := (others => '1'); variable accum_result_sign_bits_zeros : std_logic_vector (int_width_result - int_width_a - int_width_b + 2 - 1 downto 0) := (others => '0'); variable accum_result : std_logic_vector (int_width_result - 1 downto 0) := (others => '0'); variable upper_data_sign_extend : std_logic := '0'; variable upper_data_sign_bit : std_logic := '0'; variable result_pipe : pipeline_accum := (others => (others => '0')); variable sat_for_ini : integer := int_width_a + int_width_b - 34; variable bits_to_round : integer := int_width_a + int_width_b - 18; variable accum_sat_for_limit : integer := int_width_a + int_width_b - 33; begin -- ------------------------------------------------------------- -- This is the main process block that performs the accumulation -- ------------------------------------------------------------- if (((output_aclr= "ACLR0") and (aclr0 = '1')) or ((output_aclr= "ACLR1") and (aclr1 = '1')) or ((output_aclr= "ACLR2") and (aclr2 = '1')) or ((output_aclr= "ACLR3") and (aclr3 = '1'))) then temp_sum := (others => '0'); result_pipe := (others => (others => '0')); result <= (others => '0'); result_int <= (others => '0'); overflow_int := '0'; overflow <= '0'; accum_is_saturated_out <= '0'; mult_is_saturated_out <= '0'; elsif ( (rising_edge(clock0) and (output_reg = "CLOCK0")) or (rising_edge(clock1) and (output_reg = "CLOCK1")) or (rising_edge(clock2) and (output_reg = "CLOCK2")) or (rising_edge(clock3) and (output_reg = "CLOCK3")) ) then if (((output_reg = "CLOCK0") and (ena0 ='1')) or ((output_reg = "CLOCK1") and (ena1 ='1')) or ((output_reg = "CLOCK2") and (ena2 ='1')) or ((output_reg = "CLOCK3") and (ena3 ='1')) ) then if (accum_sload = 'Z') then accum_int := '0'; else accum_int := accum_sload_pipe; end if; -- check if addition flag is to be set if (port_addnsub = "PORT_CONNECTIVITY") then if (((addnsub = 'Z') and (accum_direction = "ADD")) or (addsub_pipe = '1')) then addsub_int := '1'; else addsub_int := '0'; end if; else if (((port_addnsub = "PORT_UNUSED") and (accum_direction = "ADD")) or (addsub_pipe = '1')) then addsub_int := '1'; else addsub_int := '0'; end if; end if; -- check if signed flag is to be set if (port_signa = "PORT_CONNECTIVITY" and port_signb = "PORT_CONNECTIVITY") then if ((((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_pipe = '1')) or (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_pipe = '1'))) then signed_int := '1'; else signed_int := '0'; end if; else if ((((representation_b = "SIGNED") and (port_signb = "PORT_UNUSED")) or (sign_b_pipe = '1')) or (((representation_a = "SIGNED") and (port_signa = "PORT_UNUSED")) or (sign_a_pipe = '1'))) then signed_int := '1'; else signed_int := '0'; end if; end if; sign_extend := (others => (signed_int and mult_res (int_width_a + int_width_b -1))); if (int_width_result >= (int_width_a + int_width_b)) then mult_res_temp := sign_extend & mult_res; else mult_res_temp := sign_extend & mult_res(int_width_result -1 downto 0); end if; if (int_width_result > width_result) then upper_data_sign_extend := '1'; else upper_data_sign_extend := '0'; end if; if (accum_int ='1') then if ((not IS_STRATIXII) and (not IS_CYCLONEII)) then result_temp := (others => '0'); else upper_data_sign_bit := (signed_int and sload_upper_data_wire(width_upper_data - 1)); result_temp := (others => '0'); if(upper_data_sign_extend = '1') then for i in (int_width_result - 1) downto (int_extra_width + width_result) loop result_temp(i) := upper_data_sign_bit; end loop; end if; if(width_upper_data > width_result) then result_temp(int_extra_width + width_result - 1 downto int_extra_width) := sload_upper_data_wire(width_result - 1 downto 0); else result_temp(int_extra_width + width_result - 1 downto int_extra_width + width_result - width_upper_data) := sload_upper_data_wire; end if; end if; else result_temp := result_int; end if; if (addsub_int = '1') then -- add the numbers if the add flag is turned on temp_sum := unsigned(temp_sum_zero)+ unsigned (result_temp) + unsigned (mult_res_temp); cout_int := temp_sum (int_width_result); else -- subtract the numbers if the add flag is turned off temp_sum := unsigned(temp_sum_zero)+ unsigned (result_temp) - unsigned (mult_res_temp); if (unsigned (result_temp) >= unsigned (mult_res_temp)) then cout_int := '1'; else cout_int := '0'; end if; end if; if (signed_int = '1' and (not (mult_res = temp_mult_zero))) then overflow_int := (((not (mult_res (int_width_a + int_width_b-1) xor result_temp (int_width_result -1))) xor (not (addsub_int))) and (result_temp (int_width_result -1) xor temp_sum (int_width_result -1))); else overflow_int := not (addsub_int xor cout_int); end if; if (IS_STRATIXII) then -- StratixII rounding support -- This is based on both input is in Q1.15 format with assumption -- width_a = 16 and width_b = 16 -- result_width = widht_a + width_b if ((accumulator_rounding = "YES") or ((accumulator_rounding = "VARIABLE") and (accum_round_wire = '1'))) then accum_round_out := temp_sum(int_width_result -1 downto 0); accum_round_out := signed (accum_round_out) + ( 2 ** bits_to_round); else accum_round_out := temp_sum(int_width_result -1 downto 0); end if; -- StratixII saturation support if ((accumulator_saturation = "YES") or ((accumulator_saturation = "VARIABLE") and (accum_saturate_wire = '1'))) then accum_result_sign_bits := accum_round_out(int_width_result - 1 downto int_width_a + int_width_b - 2); if ((accum_result_sign_bits = accum_result_sign_bits_ones) or (accum_result_sign_bits = accum_result_sign_bits_zeros)) then accum_saturate_overflow := '0'; else accum_saturate_overflow := '1'; end if; if (accum_saturate_overflow = '0') then accum_saturate_out := accum_round_out; accum_saturate_out(sat_for_ini) := '0'; else for i in (int_width_result - 1) downto (int_width_a + int_width_b - 2) loop accum_saturate_out(i) := accum_round_out(int_width_result - 1); end loop; for i in (int_width_a + int_width_b - 3) downto (accum_sat_for_limit) loop accum_saturate_out(i) := not accum_round_out(int_width_result - 1); end loop; for i in (sat_for_ini) downto 0 loop accum_saturate_out(i) := '0'; end loop; end if; else accum_saturate_out := accum_round_out; accum_saturate_overflow := '0'; end if; if ((accumulator_rounding = "YES") or ((accumulator_rounding = "VARIABLE") and (accum_round_wire = '1'))) then accum_result := accum_saturate_out; for i in (bits_to_round) downto 0 loop accum_result(i) := '0'; end loop; else accum_result := accum_saturate_out; end if; accum_is_saturated_out <= accum_saturate_overflow; mult_is_saturated_out <= mult_is_saturated_reg; end if; if (not IS_STRATIXII) then accum_final_out := temp_sum(int_width_result -1 downto 0); else accum_final_out := accum_result; end if; if (extra_accumulator_latency = 0) then result <= accum_final_out(width_result - 1 + int_extra_width downto int_extra_width); overflow <= overflow_int; else head_result_int := head_result; result_pipe (head_result_int) := (overflow_int & accum_final_out); head_result_int := (head_result_int +1) mod (extra_accumulator_latency + 1); result_full := result_pipe(head_result_int); result <= result_full (width_result - 1 + int_extra_width downto int_extra_width); overflow <= result_full (int_width_result); head_result <= head_result_int; end if; result_int <= accum_final_out; end if; end if; end process; end behaviour; -- end of ALT_MULT_ACCUM ---------------------------------------------------------------------------- -- Module Name : altmult_add -- -- Description : a*b + c*d -- -- Limitation : Stratix DSP block -- -- Results expected : signed & unsigned, maximum of 3 pipelines(latency) each. -- possible of zero pipeline. -- ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use work.ALTERA_DEVICE_FAMILIES.all; entity altmult_add is generic ( -- --------------------- -- PARAMETER DECLARATION -- --------------------- width_a : natural := 1; width_b : natural := 1; width_result : natural := 1; number_of_multipliers : natural := 1; -- A inputs input_register_a0 : string := "CLOCK0"; input_aclr_a0 : string := "ACLR3"; input_source_a0 : string := "DATAA"; input_register_a1 : string := "CLOCK0"; input_aclr_a1 : string := "ACLR3"; input_source_a1 : string := "DATAA"; input_register_a2 : string := "CLOCK0"; input_aclr_a2 : string := "ACLR3"; input_source_a2 : string := "DATAA"; input_register_a3 : string := "CLOCK0"; input_aclr_a3 : string := "ACLR3"; input_source_a3 : string := "DATAA"; port_signa : string := "PORT_CONNECTIVITY"; representation_a : string := "UNSIGNED"; signed_register_a : string := "CLOCK0"; signed_aclr_a : string := "ACLR3"; signed_pipeline_register_a : string := "CLOCK0"; signed_pipeline_aclr_a : string := "ACLR3"; scanouta_register : string := "UNREGISTERED"; scanouta_aclr : string := "NONE"; -- B inputs input_register_b0 : string := "CLOCK0"; input_aclr_b0 : string := "ACLR3"; input_source_b0 : string := "DATAB"; input_register_b1 : string := "CLOCK0"; input_aclr_b1 : string := "ACLR3"; input_source_b1 : string := "DATAB"; input_register_b2 : string := "CLOCK0"; input_aclr_b2 : string := "ACLR3"; input_source_b2 : string := "DATAB"; input_register_b3 : string := "CLOCK0"; input_aclr_b3 : string := "ACLR3"; input_source_b3 : string := "DATAB"; port_signb : string := "PORT_CONNECTIVITY"; representation_b : string := "UNSIGNED"; signed_register_b : string := "CLOCK0"; signed_aclr_b : string := "ACLR3"; signed_pipeline_register_b : string := "CLOCK0"; signed_pipeline_aclr_b : string := "ACLR3"; -- Multiplier parameter multiplier_register0 : string := "CLOCK0"; multiplier_aclr0 : string := "ACLR3"; multiplier_register1 : string := "CLOCK0"; multiplier_aclr1 : string := "ACLR3"; multiplier_register2 : string := "CLOCK0"; multiplier_aclr2 : string := "ACLR3"; multiplier_register3 : string := "CLOCK0"; multiplier_aclr3 : string := "ACLR3"; port_addnsub1 : string := "PORT_CONNECTIVITY"; addnsub_multiplier_register1 : string := "CLOCK0"; addnsub_multiplier_aclr1 : string := "ACLR3"; addnsub_multiplier_pipeline_register1 : string := "CLOCK0"; addnsub_multiplier_pipeline_aclr1 : string := "ACLR3"; port_addnsub3 : string := "PORT_CONNECTIVITY"; addnsub_multiplier_register3 : string := "CLOCK0"; addnsub_multiplier_aclr3 : string := "ACLR3"; addnsub_multiplier_pipeline_register3 : string := "CLOCK0"; addnsub_multiplier_pipeline_aclr3 : string := "ACLR3"; multiplier1_direction : string := "ADD"; multiplier3_direction : string := "ADD"; -- output parameters output_register : string := "CLOCK0"; output_aclr : string := "ACLR3"; -- StratixII parameters multiplier01_rounding : string := "NO"; multiplier01_saturation : string := "NO"; mult01_round_aclr : string := "ACLR3"; mult01_round_register : string := "CLOCK0"; mult01_saturation_register : string := "CLOCK0"; mult01_saturation_aclr : string := "ACLR3"; multiplier23_rounding : string := "NO"; multiplier23_saturation : string := "NO"; mult23_round_aclr : string := "ACLR3"; mult23_round_register : string := "CLOCK0"; mult23_saturation_register : string := "CLOCK0"; mult23_saturation_aclr : string := "ACLR3"; adder1_rounding : string := "NO"; adder3_rounding : string := "NO"; addnsub1_round_aclr : string := "ACLR3"; addnsub1_round_pipeline_aclr : string := "ACLR3"; addnsub1_round_register : string := "CLOCK0"; addnsub1_round_pipeline_register : string := "CLOCK0"; addnsub3_round_aclr : string := "ACLR3"; addnsub3_round_pipeline_aclr : string := "ACLR3"; addnsub3_round_register : string := "CLOCK0"; addnsub3_round_pipeline_register : string := "CLOCK0"; port_mult0_is_saturated : string := "UNUSED"; port_mult1_is_saturated : string := "UNUSED"; port_mult2_is_saturated : string := "UNUSED"; port_mult3_is_saturated : string := "UNUSED"; -- Stratix III parameters -- Rounding parameters output_rounding : string := "NO"; output_round_type : string := "NEAREST_INTEGER"; width_msb : integer := 17; output_round_register : string := "UNREGISTERED"; output_round_aclr : string := "NONE"; output_round_pipeline_register : string := "UNREGISTERED"; output_round_pipeline_aclr : string := "NONE"; chainout_rounding : string := "NO"; chainout_round_register : string := "UNREGISTERED"; chainout_round_aclr : string := "NONE"; chainout_round_pipeline_register : string := "UNREGISTERED"; chainout_round_pipeline_aclr : string := "NONE"; chainout_round_output_register : string := "UNREGISTERED"; chainout_round_output_aclr : string := "NONE"; -- saturation parameters port_output_is_overflow : string := "PORT_UNUSED"; port_chainout_sat_is_overflow : string := "PORT_UNUSED"; output_saturation : string := "NO"; output_saturate_type : string := "ASYMMETRIC"; width_saturate_sign : integer := 1; output_saturate_register : string := "UNREGISTERED"; output_saturate_aclr : string := "NONE"; output_saturate_pipeline_register : string := "UNREGISTERED"; output_saturate_pipeline_aclr : string := "NONE"; chainout_saturation : string := "NO"; chainout_saturate_register : string := "UNREGISTERED"; chainout_saturate_aclr : string := "NONE"; chainout_saturate_pipeline_register : string := "UNREGISTERED"; chainout_saturate_pipeline_aclr : string := "NONE"; chainout_saturate_output_register : string := "UNREGISTERED"; chainout_saturate_output_aclr : string := "NONE"; -- chainout parameters chainout_adder : string := "NO"; chainout_register : string := "UNREGISTERED"; chainout_aclr : string := "ACLR3"; width_chainin : integer := 1; zero_chainout_output_register : string := "UNREGISTERED"; zero_chainout_output_aclr : string := "NONE"; -- rotate & shift parameters shift_mode : string := "NO"; rotate_aclr : string := "NONE"; rotate_register : string := "UNREGISTERED"; rotate_pipeline_register : string := "UNREGISTERED"; rotate_pipeline_aclr : string := "NONE"; rotate_output_register : string := "UNREGISTERED"; rotate_output_aclr : string := "NONE"; shift_right_register : string := "UNREGISTERED"; shift_right_aclr : string := "NONE"; shift_right_pipeline_register : string := "UNREGISTERED"; shift_right_pipeline_aclr : string := "NONE"; shift_right_output_register : string := "UNREGISTERED"; shift_right_output_aclr : string := "NONE"; -- loopback parameters zero_loopback_register : string := "UNREGISTERED"; zero_loopback_aclr : string := "NONE"; zero_loopback_pipeline_register : string := "UNREGISTERED"; zero_loopback_pipeline_aclr : string := "NONE"; zero_loopback_output_register : string := "UNREGISTERED"; zero_loopback_output_aclr : string := "NONE"; -- accumulator parameters accum_sload_register : string := "UNREGISTERED"; accum_sload_aclr : string := "NONE"; accum_sload_pipeline_register : string := "UNREGISTERED"; accum_sload_pipeline_aclr : string := "NONE"; accum_direction : string := "ADD"; accumulator : string := "NO"; -- Stratix V parameters width_c : integer := 22; loadconst_value : integer := 64; preadder_mode : string := "SIMPLE"; preadder_direction_0 : string := "ADD"; preadder_direction_1 : string := "ADD"; preadder_direction_2 : string := "ADD"; preadder_direction_3 : string := "ADD"; input_register_c0 : string := "CLOCK0"; input_aclr_c0 : string := "ACLR0"; coefsel0_register : string := "CLOCK0"; coefsel1_register : string := "CLOCK0"; coefsel2_register : string := "CLOCK0"; coefsel3_register : string := "CLOCK0"; coefsel0_aclr : string := "ACLR0"; coefsel1_aclr : string := "ACLR0"; coefsel2_aclr : string := "ACLR0"; coefsel3_aclr : string := "ACLR0"; systolic_delay1 : string := "UNREGISTERED"; systolic_delay3 : string := "UNREGISTERED"; systolic_aclr1 : string := "NONE"; systolic_aclr3 : string := "NONE"; coef0_0 : integer := 0; coef0_1 : integer := 0; coef0_2 : integer := 0; coef0_3 : integer := 0; coef0_4 : integer := 0; coef0_5 : integer := 0; coef0_6 : integer := 0; coef0_7 : integer := 0; coef1_0 : integer := 0; coef1_1 : integer := 0; coef1_2 : integer := 0; coef1_3 : integer := 0; coef1_4 : integer := 0; coef1_5 : integer := 0; coef1_6 : integer := 0; coef1_7 : integer := 0; coef2_0 : integer := 0; coef2_1 : integer := 0; coef2_2 : integer := 0; coef2_3 : integer := 0; coef2_4 : integer := 0; coef2_5 : integer := 0; coef2_6 : integer := 0; coef2_7 : integer := 0; coef3_0 : integer := 0; coef3_1 : integer := 0; coef3_2 : integer := 0; coef3_3 : integer := 0; coef3_4 : integer := 0; coef3_5 : integer := 0; coef3_6 : integer := 0; coef3_7 : integer := 0; width_coef : integer := 18; -- General setting parameters extra_latency : integer := 0; dedicated_multiplier_circuitry : string := "AUTO"; dsp_block_balancing : string := "AUTO"; lpm_hint : string := "UNUSED"; lpm_type : string := "altmult_add"; intended_device_family : string := "Stratix" ); port ( -- ---------------- -- PORT DECLARATION -- ---------------- -- data input ports dataa : in std_logic_vector(number_of_multipliers * width_a -1 downto 0); datab : in std_logic_vector(number_of_multipliers * width_b -1 downto 0); scanina : in std_logic_vector(width_a -1 downto 0) := (others => '0'); scaninb : in std_logic_vector(width_b -1 downto 0) := (others => '0'); sourcea : in std_logic_vector((number_of_multipliers -1) downto 0) := (others => '0'); sourceb : in std_logic_vector((number_of_multipliers -1) downto 0) := (others => '0'); -- clock ports clock3 : in std_logic := '1'; clock2 : in std_logic := '1'; clock1 : in std_logic := '1'; clock0 : in std_logic := '1'; -- clear ports aclr3 : in std_logic := '0'; aclr2 : in std_logic := '0'; aclr1 : in std_logic := '0'; aclr0 : in std_logic := '0'; -- clock enable signals ena3 : in std_logic := '1'; ena2 : in std_logic := '1'; ena1 : in std_logic := '1'; ena0 : in std_logic := '1'; -- control signals signa : in std_logic := 'Z'; signb : in std_logic := 'Z'; addnsub1 : in std_logic := 'Z'; addnsub3 : in std_logic := 'Z'; -- StratixII only input ports mult01_round : in std_logic := '0'; mult23_round : in std_logic := '0'; mult01_saturation : in std_logic := '0'; mult23_saturation : in std_logic := '0'; addnsub1_round : in std_logic := '0'; addnsub3_round : in std_logic := '0'; -- Stratix III only input ports output_round : in std_logic := '0'; chainout_round : in std_logic := '0'; output_saturate : in std_logic := '0'; chainout_saturate : in std_logic := '0'; chainin : in std_logic_vector (width_chainin - 1 downto 0) := (others => '0'); zero_chainout : in std_logic := '0'; rotate : in std_logic := '0'; shift_right : in std_logic := '0'; zero_loopback : in std_logic := '0'; accum_sload : in std_logic := '0'; -- Stratix V only input ports coefsel0 : in std_logic_vector (2 downto 0) := (others => '0'); coefsel1 : in std_logic_vector (2 downto 0) := (others => '0'); coefsel2 : in std_logic_vector (2 downto 0) := (others => '0'); coefsel3 : in std_logic_vector (2 downto 0) := (others => '0'); datac : in std_logic_vector (number_of_multipliers * width_c -1 downto 0) := (others => '0'); -- output ports result : out std_logic_vector(width_result -1 downto 0) := (others => '0'); scanouta : out std_logic_vector (width_a -1 downto 0) := (others => '0'); scanoutb : out std_logic_vector (width_b -1 downto 0) := (others => '0'); -- StratixII only output ports mult0_is_saturated : out std_logic := '0'; mult1_is_saturated : out std_logic := '0'; mult2_is_saturated : out std_logic := '0'; mult3_is_saturated : out std_logic := '0'; -- Stratix III only output ports overflow : out std_logic := '0'; chainout_sat_overflow : out std_logic := '0' ); end altmult_add; architecture behaviour of altmult_add is -- --------------------------- -- SIGNAL AND TYPE DECLARATION -- --------------------------- function resolve_internal_width (ARG : integer;ARG2 : integer) return integer is variable changed_width:integer := 0; begin if (multiplier01_saturation = "NO" and multiplier23_saturation = "NO" and multiplier01_rounding = "NO" and multiplier23_rounding = "NO" and output_saturation = "NO" and output_rounding = "NO" and chainout_adder = "NO" and input_source_b0 /= "LOOPBACK" ) then if (ARG2 = 0) then changed_width := width_a; else changed_width := width_b; end if; else if (ARG < 18) then changed_width := 18; else if (ARG2 = 0) then changed_width := width_a; else changed_width := width_b; end if; end if; end if; return changed_width; end resolve_internal_width; -- This constant int_width_a would be used internally in this model -- to represent width_a constant int_width_a : natural := resolve_internal_width(width_a, 0); -- This constant int_width_b woudl be used internally in this model -- to represent width_b constant int_width_b : natural := resolve_internal_width(width_b, 1); function resolve_internal_mult_diff return integer is variable changed_value :integer := 0; begin if (multiplier01_saturation = "NO" and multiplier23_saturation = "NO" and multiplier01_rounding = "NO" and multiplier23_rounding = "NO" and output_rounding = "NO" and output_saturation = "NO" and chainout_adder = "NO") then changed_value := 0; else if (chainout_adder = "YES") then if (width_result > width_a + width_b + 8) then changed_value := 0; else changed_value := int_width_a - width_a + int_width_b - width_b; end if; else changed_value := int_width_a - width_a + int_width_b - width_b; end if; end if; return changed_value; end resolve_internal_mult_diff; constant int_mult_diff_bit : integer := resolve_internal_mult_diff; function resolve_internal_width_result return integer is variable changed_width_result:integer := 0; begin if (multiplier01_saturation = "NO" and multiplier23_saturation = "NO" and multiplier01_rounding = "NO" and multiplier23_rounding = "NO" and output_rounding = "NO" and output_saturation = "NO" and chainout_rounding = "NO" and chainout_saturation = "NO" and chainout_adder = "NO" and shift_mode = "NO") then changed_width_result := width_result; else if (shift_mode /= "NO") then changed_width_result := 64; elsif (chainout_adder = "YES") then changed_width_result := 44; elsif (width_result > (int_width_a + int_width_b)) then changed_width_result := width_result + (width_result - int_width_a - int_width_b); else changed_width_result := int_width_a + int_width_b; end if; end if; return changed_width_result; end resolve_internal_width_result; constant int_width_result : natural := resolve_internal_width_result; function resolve_result_width return integer is variable width_value :integer := 0; begin width_value := 44; return width_value; end resolve_result_width; constant result_width : integer := resolve_result_width; function resolve_saturation_position return integer is variable saturation_value :integer := 0; begin if (output_saturation /= "NO" and chainout_saturation = "NO") then if (((width_a + width_b )> width_result) and (width_result >= width_saturate_sign)) then saturation_value := (int_width_a + int_width_b - width_saturate_sign - (width_a + width_b - width_result)); elsif (((width_a + width_b) = width_result) and (width_result >= width_saturate_sign)) then saturation_value:= (int_width_a + int_width_b - width_saturate_sign); elsif (width_result >= width_saturate_sign) then saturation_value := (int_width_a + int_width_b - width_saturate_sign + (width_result - width_saturate_sign) + (width_saturate_sign - width_a - width_b)); end if; elsif (chainout_saturation /= "NO") then if ((width_result >= int_width_result) and (width_result > width_saturate_sign)) then saturation_value := width_result - width_saturate_sign; elsif (width_result > width_saturate_sign) then saturation_value := width_result + int_mult_diff_bit - width_saturate_sign; end if; else saturation_value:= 2; end if; return saturation_value; end resolve_saturation_position; constant saturation_position : natural := resolve_saturation_position; function resolve_chainout_saturation_position return integer is variable saturation_value :integer := 0; begin if (chainout_saturation /= "NO") then if ((width_result >= int_width_result) and (width_result > width_saturate_sign)) then saturation_value := width_result - width_saturate_sign; elsif (width_result > width_saturate_sign) then saturation_value := width_result + int_mult_diff_bit - width_saturate_sign; end if; else saturation_value := 2; end if; if (saturation_value < 0) then saturation_value:= 2; elsif (saturation_value > int_width_result) then saturation_value:= (int_width_a + int_width_b - width_saturate_sign); end if; return saturation_value; end resolve_chainout_saturation_position; constant chainout_saturation_position : natural := resolve_chainout_saturation_position; function resolve_round_position return integer is variable round_value :integer := 2; begin if (output_rounding /= "NO" or output_saturate_type = "SYMMETRIC") then if (input_source_b0 = "LOOPBACK") then round_value := 18; elsif (((width_a + width_b )> width_result) and (width_msb < width_result)) then round_value := (int_width_a + int_width_b - width_msb - (width_a + width_b - width_result)); elsif (((width_a + width_b) = width_result) and (width_msb < width_result)) then round_value:= (int_width_a + int_width_b - width_msb); elsif (width_msb < width_result) then round_value := (int_width_a + int_width_b - width_msb + (width_result - width_a - width_b)); end if; else round_value := 2; end if; if (output_rounding /= "NO" or output_saturate_type = "SYMMETRIC") then if (round_value < 0) then round_value := 2; elsif (round_value > int_width_result) then round_value := int_width_result - width_msb; end if; end if; return round_value; end resolve_round_position; constant round_position : natural := resolve_round_position; function resolve_chainout_round_position return integer is variable round_value :integer := 2; begin if (chainout_rounding /= "NO" or output_saturate_type = "SYMMETRIC") then if ((width_result >= int_width_result) and (width_msb < width_result)) then round_value := width_result - width_msb; elsif (width_msb < width_result) then round_value := width_result + int_mult_diff_bit - width_msb; end if; else round_value := 2; end if; if (chainout_rounding /= "NO" or output_saturate_type = "SYMMETRIC") then if (round_value < 0) then round_value := 2; elsif (round_value > int_width_result) then round_value := int_width_result - width_msb; end if; end if; return round_value; end resolve_chainout_round_position; constant chainout_round_position : natural := resolve_chainout_round_position; function resolve_chainout_input_a return integer is variable input_a_value :integer := 0; begin if (chainout_adder = "YES") then if (width_a < 18) then input_a_value := 18 - width_a; else input_a_value := 1; end if; end if; return input_a_value; end resolve_chainout_input_a; constant chainout_input_a : natural := resolve_chainout_input_a; function resolve_chainout_input_b return integer is variable input_b_value :integer := 0; begin if (chainout_adder = "YES") then if (width_b < 18) then input_b_value := 18 - width_b; else input_b_value := 1; end if; end if; return input_b_value; end resolve_chainout_input_b; constant chainout_input_b : natural := resolve_chainout_input_b; function resolve_accum_width return integer is variable accum_value :integer := 0; begin if((int_width_a + int_width_b) < 44) then accum_value := 44; else accum_value := int_width_a + int_width_b; end if; return accum_value; end resolve_accum_width; constant accum_width : natural := resolve_accum_width; function resolve_loopback_width return integer is variable loopback_value :integer := 0; begin loopback_value := 17; return loopback_value; end resolve_loopback_width; constant loopback_width : natural := resolve_loopback_width; function resolve_lsb_position return integer is variable lsb_position_value :integer := 0; begin lsb_position_value := 36 - width_a - width_b; if(lsb_position_value < 0) then lsb_position_value := 0; end if; return lsb_position_value; end resolve_lsb_position; constant lsb_position : natural := resolve_lsb_position; function resolve_extra_sign_bit_width return integer is variable extra_sign_bit_width_value :integer :=0; begin if(port_signa = "PORT_USED" or port_signb = "PORT_USED") then extra_sign_bit_width_value := accum_width - width_result - lsb_position; elsif(representation_a = "UNSIGNED" and representation_b = "UNSIGNED") then extra_sign_bit_width_value := accum_width - width_result - lsb_position; else extra_sign_bit_width_value := accum_width - width_result + 1 - lsb_position; end if; if(extra_sign_bit_width_value < 0) then extra_sign_bit_width_value := 0; end if; return extra_sign_bit_width_value; end resolve_extra_sign_bit_width; constant extra_sign_bit_width : natural := resolve_extra_sign_bit_width; function resolve_bit_position return integer is variable bit_position_value :integer := 0; begin bit_position_value := accum_width - lsb_position - extra_sign_bit_width - 1; return bit_position_value; end resolve_bit_position; constant bit_position : natural := resolve_bit_position; type pipeline_accum is array (extra_latency downto 0) of std_logic_vector (width_result - 1 downto 0); signal mult_a : std_logic_vector ((4 * int_width_a) -1 downto 0) := (others => '0'); signal mult_b : std_logic_vector ((4 * int_width_b) -1 downto 0) := (others => '0'); signal mult_res : std_logic_vector ((number_of_multipliers * (int_width_a + int_width_b)) + number_of_multipliers downto 0) := (others => '0'); signal tmp_mult_a : std_logic_vector ((4 * int_width_a) -1 downto 0) := (others => '0'); signal tmp_mult_b : std_logic_vector ((4 * int_width_b) -1 downto 0) := (others => '0'); signal sign_a_reg : std_logic := '0'; signal sign_a_pipe : std_logic := '0'; signal sign_b_reg : std_logic := '0'; signal sign_b_pipe : std_logic := '0'; signal addsub_reg1 : std_logic := '0'; signal addsub_pipe1 : std_logic := '0'; signal addsub_reg3 : std_logic := '0'; signal addsub_pipe3 : std_logic := '0'; signal mult_clock : std_logic_vector (3 downto 0) := (others => '0'); signal mult_ena : std_logic_vector (3 downto 0) := (others => '0'); signal mult_aclr : std_logic_vector (3 downto 0) := (others => '0'); signal clock_vector : std_logic_vector (3 downto 0) := (others => '0'); signal ena_vector : std_logic_vector (3 downto 0) := (others => '0'); signal aclr_vector : std_logic_vector (3 downto 0) := (others => '0'); signal dataa_int : std_logic_vector (4 * int_width_a -1 downto 0) := (others => '0'); signal dataa_int1 : std_logic_vector (int_width_a -1 downto 0) := (others => '0'); signal dataa_int2 : std_logic_vector (int_width_a -1 downto 0) := (others => '0'); signal dataa_int3 : std_logic_vector (int_width_a -1 downto 0) := (others => '0'); signal dataa_int4 : std_logic_vector (int_width_a -1 downto 0) := (others => '0'); signal datab_int : std_logic_vector (4 * int_width_b -1 downto 0) := (others => '0'); signal datab_int1 : std_logic_vector (int_width_b -1 downto 0) := (others => '0'); signal datab_int2 : std_logic_vector (int_width_b -1 downto 0) := (others => '0'); signal datab_int3 : std_logic_vector (int_width_b -1 downto 0) := (others => '0'); signal datab_int4 : std_logic_vector (int_width_b -1 downto 0) := (others => '0'); signal is_reg : std_logic_vector (3 downto 0) := (others => '0'); signal temp_mult_zero : std_logic_vector ((int_width_a + int_width_b) -1 downto 0) := (others => '0'); signal head_result : natural := 0; signal head_result_siii : natural := 0; signal head_overflow : natural := 0; signal mult01_round_wire : std_logic := '0'; signal mult01_saturate_wire : std_logic := '0'; signal mult23_round_wire : std_logic := '0'; signal mult23_saturate_wire : std_logic := '0'; signal mult_is_saturated : std_logic_vector ((number_of_multipliers - 1) downto 0) := (others => '0'); signal mult_is_saturated_pipe : std_logic_vector ((number_of_multipliers - 1) downto 0) := (others => '0'); signal sourcea_wire : std_logic_vector (3 downto 0) := (others => '0'); signal sourceb_wire : std_logic_vector (3 downto 0) := (others => '0'); signal addnsub1_round_wire : std_logic := '0'; signal addnsub1_round_pipe_wire : std_logic := '0'; signal addnsub3_round_wire : std_logic := '0'; signal addnsub3_round_pipe_wire : std_logic := '0'; signal outround_reg : std_logic := '0'; signal outround_pipe : std_logic := '0'; signal chainout_round_reg : std_logic := '0'; signal chainout_round_pipe : std_logic := '0'; signal chainout_round_out_reg : std_logic := '0'; signal outsat_reg : std_logic := '0'; signal outsat_pipe : std_logic := '0'; signal chainout_sat_reg : std_logic := '0'; signal chainout_sat_pipe : std_logic := '0'; signal chainout_sat_out : std_logic := '0'; signal scanouta_reg : std_logic_vector (width_a - 1 downto 0) := (others => '0'); signal zerochainout_reg : std_logic := '0'; signal rotate_reg : std_logic := '0'; signal rotate_pipe : std_logic := '0'; signal rotate_out : std_logic := '0'; signal shiftr_reg : std_logic := '0'; signal shiftr_pipe : std_logic := '0'; signal shiftr_out : std_logic := '0'; signal zeroloopback_reg : std_logic := '0'; signal zeroloopback_pipe : std_logic := '0'; signal zeroloopback_out : std_logic := '0'; signal accumsload_reg : std_logic := '0'; signal accumsload_pipe : std_logic := '0'; signal acc_feedback : std_logic_vector (int_width_result + int_width_a + int_width_b downto 0) := (others => '0'); signal loopback_wire : std_logic_vector (int_width_result downto 0) := (others => '0'); signal shift_rot_result : std_logic_vector ((int_width_result/2) - 1 downto 0) := (others => '0'); signal chainout_output : std_logic_vector (int_width_result downto 0) := (others => '0'); signal output_result : std_logic_vector (int_width_result + int_width_a + int_width_b downto 0) := (others => '0'); signal overflow_int : std_logic := '0'; signal chainout_overflow_int : std_logic := '0'; signal adder1_reg : std_logic_vector (int_width_result + int_width_a + int_width_b downto 0) := (others => '0'); signal adder3_reg : std_logic_vector (int_width_result + int_width_a + int_width_b downto 0) := (others => '0'); signal chainout_sat_block_res_wire : std_logic_vector (int_width_result downto 0) := (others => '0'); signal acc_feedback_temp : std_logic_vector (accum_width downto 0) := (others => '0'); signal accum_res : std_logic_vector (accum_width downto 0) := (others => '0'); signal feedback : std_logic_vector (loopback_width downto 0) := (others => '0'); signal unsigned_sub1_overflow_reg : std_logic := '0'; signal unsigned_sub3_overflow_reg : std_logic := '0'; signal unsigned_sub1_overflow_mult_reg : std_logic := '0'; signal unsigned_sub3_overflow_mult_reg : std_logic := '0'; constant stratixii_block : boolean := FEATURE_FAMILY_BASE_STRATIXII(intended_device_family) or (FEATURE_FAMILY_STRATIXIII(intended_device_family) and (dedicated_multiplier_circuitry = "NO")); constant stratixiii_block : boolean := FEATURE_FAMILY_STRATIXIII(intended_device_family) and (dedicated_multiplier_circuitry /= "NO"); constant stratixv_block : boolean := FEATURE_FAMILY_STRATIXV(intended_device_family); constant altera_mult_add_block : boolean := FEATURE_FAMILY_HAS_ALTERA_MULT_ADD_FLOW(intended_device_family); constant altmult_add_eol_block : boolean := FEATURE_FAMILY_IS_ALTMULT_ADD_EOL(intended_device_family); -- ------------------------------------------------------------------- -- This function takes in a string that describes the clock name -- and returns the correct number that corresponds to that particular -- clock signal -- ------------------------------------------------------------------- function resolve_clock (ARG : string) return integer is variable clock_num:integer := 0; begin if (ARG = "CLOCK0") then clock_num := 0; elsif ARG = "CLOCK1" then clock_num := 1; elsif ARG = "CLOCK2" then clock_num := 2; elsif ARG = "CLOCK3" then clock_num := 3; end if; return clock_num; end resolve_clock; -- ------------------------------------------------------------------- -- This function takes in a string that describes the clear name -- and returns the correct number that corresponds to that particular -- clear signal -- ------------------------------------------------------------------- function resolve_aclr (ARG : string) return integer is variable aclr_num:integer := 0; begin if (ARG = "ACLR0") then aclr_num := 0; elsif ARG = "ACLR1" then aclr_num := 1; elsif ARG = "ACLR2" then aclr_num := 2; elsif ARG = "ACLR3" then aclr_num := 3; end if; return aclr_num; end resolve_aclr; -- ------------------------------------------------------------------- -- This function takes in a integer that describes the particular -- clock signal returns the correct string -- ------------------------------------------------------------------- function check_clock (arg: integer) return string is variable ret_val:string (1 to 6); begin if (arg = 0) then ret_val := multiplier_register0 (1 to 6); elsif arg =1 then ret_val := multiplier_register1 (1 to 6); elsif arg=2 then ret_val := multiplier_register2 (1 to 6); elsif arg=3 then ret_val := multiplier_register3 (1 to 6); else ret_val := "CLOCK0"; end if; return ret_val; end check_clock; begin process(mult_b) begin if (altera_mult_add_block) then scanoutb <= (others => 'Z'); elsif (chainout_adder = "YES" and (width_result > width_a + width_b + 8)) then scanoutb <= mult_b((number_of_multipliers * int_width_b) - 1 - (int_width_b - width_b) downto ((number_of_multipliers-1) * int_width_b)); else scanoutb <= mult_b ((number_of_multipliers * int_width_b) -1 downto ((number_of_multipliers -1 ) * int_width_b) + int_width_b - width_b); end if; end process; clock_vector (0) <= clock0; clock_vector (1) <= clock1; clock_vector (2) <= clock2; clock_vector (3) <= clock3; ena_vector (0) <= ena0; ena_vector (1) <= ena1; ena_vector (2) <= ena2; ena_vector (3) <= ena3; aclr_vector (0) <= aclr0; aclr_vector (1) <= aclr1; aclr_vector (2) <= aclr2; aclr_vector (3) <= aclr3; sourcea_wire ( number_of_multipliers - 1 downto 0) <= sourcea (number_of_multipliers -1 downto 0); sourceb_wire ( number_of_multipliers - 1 downto 0) <= sourceb (number_of_multipliers - 1 downto 0); tmp_mult_a <= mult_a; tmp_mult_b <= mult_b; -- Parameter Checking process begin -- Legality check, family from Night Fury and moving forwards is officially EOL if (altmult_add_eol_block) then assert false report "ALTMULT_ADD is EOL for "& intended_device_family &" device family" severity failure; end if; -- Legality check, block new family from running pre_layout simulation using altera_mf (family with altera_mult_add flow) if (altera_mult_add_block) then if(accumulator /= "NO") then assert false report "Accumulator mode is not supported in altera_mf for "& intended_device_family &" device family" severity failure; end if; if (port_addnsub1 /= "PORT_UNUSED" or port_addnsub3 /= "PORT_UNUSED") then assert false report "Dynamic adder is not supported in altera_mf for "& intended_device_family &" device family" severity failure; end if; if (chainout_adder /= "NO") then assert false report "Chain adder is not supported in altera_mf for "& intended_device_family &" device family" severity failure; end if; if (systolic_delay1 /= "UNREGISTERED" or systolic_delay3 /= "UNREGISTERED") then assert false report "Systolic mode is not supported in altera_mf for "& intended_device_family &" device family" severity failure; end if; if (input_source_a0 /= "DATAA" or input_source_a1 /= "DATAA" or input_source_a2 /= "DATAA" or input_source_a3 /= "DATAA") then assert false report "The INPUT_SOURCE_A parameter is set to an unsupported value. Only DATAA input is supported in altera_mf for "& intended_device_family &" device family" severity failure; end if; if (input_source_b0 /= "DATAB" or input_source_b1 /= "DATAB" or input_source_b2 /= "DATAB" or input_source_b3 /= "DATAB") then assert false report "The INPUT_SOURCE_B parameter is set to an unsupported value. Only DATAB input is supported in altera_mf for "& intended_device_family &" device family" severity failure; end if; if (preadder_mode /= "SIMPLE") then assert false report "The PREADDER_MODE parameter is set to an unsupported value. Only SIMPLE mode is supported in altera_mf for "& intended_device_family &" device family" severity failure; end if; if (output_rounding /= "NO" or chainout_rounding /= "NO" or adder1_rounding /= "NO" or adder3_rounding /= "NO" or multiplier01_rounding /= "NO" or multiplier23_rounding /= "NO") then assert false report "Rounding is not supported in altera_mf for "& intended_device_family &" device family" severity failure; end if; if (output_saturation /= "NO" or chainout_saturation /= "NO" or port_mult0_is_saturated /= "UNUSED" or port_mult1_is_saturated /= "UNUSED" or port_mult2_is_saturated /= "UNUSED" or port_mult3_is_saturated /= "UNUSED" or multiplier01_saturation /= "NO" or multiplier23_saturation /= "NO" or port_output_is_overflow /= "PORT_UNUSED") then assert false report "Saturation is not supported in altera_mf for "& intended_device_family &" device family" severity failure; end if; if (shift_mode /= "NO") then assert false report "Shift is not supported in altera_mf for "& intended_device_family &" device family" severity failure; end if; if (signed_pipeline_register_a /= "UNREGISTERED" or signed_pipeline_register_b /= "UNREGISTERED" or addnsub_multiplier_pipeline_register1 /= "UNREGISTERED" or addnsub_multiplier_pipeline_register3 /= "UNREGISTERED" or accum_sload_pipeline_register /= "UNREGISTERED") then assert false report "Pipeline register is not supported in altera_mf for "& intended_device_family &" device family" severity warning; end if; end if; -- Checking for invalid parameters, in case Wizard is bypassed (hand-modified). if (number_of_multipliers > 4) then assert false report "Altmult_add does not currently support NUMBER_OF_MULTIPLIERS > 4" severity error; end if; if (number_of_multipliers <= 0) then assert false report "NUMBER_OF_MULTIPLIERS must be greater than 0." severity error; end if; if (width_a <= 0) then assert false report "Error: width_a must be greater than 0." severity error; end if; if (width_b <= 0) then assert false report "Error: width_b must be greater than 0." severity error; end if; if (width_result <= 0) then assert false report "Error: width_result must be greater than 0." severity error; end if; if ((dedicated_multiplier_circuitry /= "AUTO") and (dedicated_multiplier_circuitry /= "YES") and (dedicated_multiplier_circuitry /= "NO")) then assert false report "Error: The DEDICATED_MULTIPLIER_CIRCUITRY parameter is set to an illegal value." severity error; end if; if ((input_source_a0 /= "DATAA") and (input_source_a0 /= "SCANA") and (input_source_a0 /= "VARIABLE")) then assert false report "Error: The INPUT_SOURCE_A0 parameter is set to an illegal value." severity error; end if; if ((input_source_a1 /= "DATAA") and (input_source_a1 /= "SCANA") and (input_source_a1 /= "VARIABLE")) then assert false report "Error: The INPUT_SOURCE_A1 parameter is set to an illegal value." severity error; end if; if ((input_source_a2 /= "DATAA") and (input_source_a2 /= "SCANA") and (input_source_a2 /= "VARIABLE")) then assert false report "Error: The INPUT_SOURCE_A2 parameter is set to an illegal value." severity error; end if; if ((input_source_a3 /= "DATAA") and (input_source_a3 /= "SCANA") and (input_source_a3 /= "VARIABLE")) then assert false report "Error: The INPUT_SOURCE_A3 parameter is set to an illegal value." severity error; end if; if ((input_source_b0 /= "DATAB") and (input_source_b0 /= "SCANB") and (input_source_b0 /= "VARIABLE") and (input_source_b0 /= "LOOPBACK")) then assert false report "Error: The INPUT_SOURCE_B0 parameter is set to an illegal value." severity error; end if; if ((input_source_b1 /= "DATAB") and (input_source_b1 /= "SCANB") and (input_source_b1 /= "VARIABLE")) then assert false report "Error: The INPUT_SOURCE_B1 parameter is set to an illegal value." severity error; end if; if ((input_source_b2 /= "DATAB") and (input_source_b2 /= "SCANB") and (input_source_b2 /= "VARIABLE")) then assert false report "Error: The INPUT_SOURCE_B2 parameter is set to an illegal value." severity error; end if; if ((input_source_b3 /= "DATAB") and (input_source_b3 /= "SCANB") and (input_source_b3 /= "VARIABLE")) then assert false report "Error: The INPUT_SOURCE_B3 parameter is set to an illegal value." severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and (not FEATURE_FAMILY_CYCLONEII(intended_device_family)) and (input_source_a0 = "VARIABLE")) then assert false report "Error: Input source as VARIABLE is not supported in "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and (not FEATURE_FAMILY_CYCLONEII(intended_device_family)) and (input_source_a1 = "VARIABLE")) then assert false report "Error: Input source as VARIABLE is not supported in "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and (not FEATURE_FAMILY_CYCLONEII(intended_device_family)) and (input_source_a2 = "VARIABLE")) then assert false report "Error: Input source as VARIABLE is not supported in "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and (not FEATURE_FAMILY_CYCLONEII(intended_device_family)) and (input_source_a3 = "VARIABLE")) then assert false report "Error: Input source as VARIABLE is not supported in "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and (not FEATURE_FAMILY_CYCLONEII(intended_device_family)) and (input_source_b0 = "VARIABLE")) then assert false report "Error: Input source as VARIABLE is not supported in "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and (not FEATURE_FAMILY_CYCLONEII(intended_device_family)) and (input_source_b1 = "VARIABLE")) then assert false report "Error: Input source as VARIABLE is not supported in "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and (not FEATURE_FAMILY_CYCLONEII(intended_device_family)) and (input_source_b2 = "VARIABLE")) then assert false report "Error: Input source as VARIABLE is not supported in "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and (not FEATURE_FAMILY_CYCLONEII(intended_device_family)) and (input_source_b3 = "VARIABLE")) then assert false report "Error: Input source as VARIABLE is not supported in "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and ((multiplier01_rounding = "YES") or (multiplier01_rounding = "VARIABLE") or (multiplier23_rounding = "YES") or (multiplier23_rounding = "VARIABLE"))) then assert false report "Error: Rounding for multiplier is not supported in "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and ((multiplier01_saturation = "YES") or (multiplier01_saturation = "VARIABLE") or (multiplier23_saturation = "YES") or (multiplier23_saturation = "VARIABLE"))) then assert false report "Error: Saturation for multiplier is not supported in "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_BASE_STRATIXII(intended_device_family)) and ((adder1_rounding = "YES") or (adder1_rounding = "VARIABLE") or (adder3_rounding = "YES") or (adder3_rounding = "VARIABLE"))) then assert false report "Error: Rounding for adder is not supported in "& intended_device_family &" device family" severity error; end if; if ((multiplier01_saturation = "NO") and (multiplier23_saturation = "NO") and (multiplier01_rounding = "NO") and (multiplier23_rounding = "NO") and (output_rounding = "NO") and (output_saturation = "NO") and (shift_mode ="NO") and (chainout_adder = "NO")) then if (int_width_result /= width_result) then assert false report "Error: Internal parameter setting of int_width_result is illegal" severity error; end if; if (int_mult_diff_bit /= 0) then assert false report "Error: Internal parameter setting of int_mult_diff_bit is illegal" severity error; end if; else if (((width_a < 18) and (int_width_a /= 18)) or ((width_a >= 18) and (int_width_a /= width_a))) then assert false report "Error: Internal parameter setting of int_width_a is illegal" severity error; end if; if (((width_b < 18) and (int_width_b /= 18)) or ((width_b >= 18) and (int_width_b /= width_b))) then assert false report "Error: Internal parameter setting of int_width_b is illegal" severity error; end if; if ((chainout_adder = "NO") and (shift_mode = "NO")) then if ((int_width_result > (int_width_a + int_width_b))) then if (int_width_result /= (width_result + width_result - int_width_a - int_width_b)) then assert false report "Error: Internal parameter setting of int_width_result is illegal" severity error; end if; elsif ((int_width_result /= (int_width_a + int_width_b))) then assert false report "Error: Internal parameter setting of int_width_result is illegal" severity error; end if; if ((int_mult_diff_bit /= (int_width_a - width_a + int_width_b - width_b))) then assert false report "Error: Internal parameter setting of int_mult_diff_bit is illegal" severity error; end if; end if; end if; -- Stratix III parameter checking if ((not FEATURE_FAMILY_STRATIXIII(intended_device_family)) and ((output_rounding = "YES") or (output_rounding = "VARIABLE") or (chainout_rounding = "YES") or (chainout_rounding = "VARIABLE"))) then assert false report "Error: Output rounding and/or Chainout rounding are not supported for "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_STRATIXIII(intended_device_family)) and ((output_saturation = "YES") or (output_saturation = "VARIABLE") or (chainout_saturation = "YES") or (chainout_saturation = "VARIABLE"))) then assert false report "Error: Output saturation and/or Chainout saturation are not supported for "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_STRATIXIII(intended_device_family)) and (input_source_b0 = "LOOPBACK")) then assert false report "Error: Loopback mode is not supported for "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_STRATIXIII(intended_device_family)) and (chainout_adder = "YES")) then assert false report "Error: Chainout mode is not supported for "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_STRATIXIII(intended_device_family)) and (shift_mode /= "NO")) then assert false report "Error: shift and rotate modes are not supported for "& intended_device_family &" device family" severity error; end if; if ((not FEATURE_FAMILY_STRATIXIII(intended_device_family)) and (accumulator = "YES")) then assert false report "Error: Accumulator mode is not supported for "& intended_device_family &" device family" severity error; end if; if ((output_rounding /= "YES") and (output_rounding /= "NO") and (output_rounding /= "VARIABLE")) then assert false report "Error: The OUTPUT_ROUNDING parameter is set to an invalid value" severity error; end if; if ((chainout_rounding /= "YES") and (chainout_rounding /= "NO") and (chainout_rounding /= "VARIABLE")) then assert false report "Error: The CHAINOUT_ROUNDING parameter is set to an invalid value" severity error; end if; if ((output_saturation /= "YES") and (output_saturation /= "NO") and (output_saturation /= "VARIABLE")) then assert false report "Error: The OUTPUT_SATURATION parameter is set to an invalid value" severity error; end if; if ((chainout_saturation /= "YES") and (chainout_saturation /= "NO") and (chainout_saturation /= "VARIABLE")) then assert false report "Error: The CHAINOUT_SATURATION parameter is set to an invalid value" severity error; end if; if ((output_rounding /= "NO") and ((output_round_type /= "NEAREST_INTEGER") and (output_round_type /= "NEAREST_EVEN"))) then assert false report "Error: The OUTPUT_ROUND_TYPE parameter is set to an invalid value" severity error; end if; if ((output_saturation /= "NO") and ((output_saturate_type /= "ASYMMETRIC") and (output_saturate_type /= "SYMMETRIC"))) then assert false report "Error: The OUTPUT_SATURATE_TYPE parameter is set to an invalid value" severity error; end if; if ((shift_mode /= "NO") and (shift_mode /= "LEFT") and (shift_mode /= "RIGHT") and (shift_mode /= "ROTATION") and (shift_mode /= "VARIABLE")) then assert false report "Error: The SHIFT_MODE parameter is set to an inavlid value" severity error; end if; if ((accumulator = "YES") and (accum_direction /= "ADD") and (accum_direction /= "SUB")) then assert false report "Error: The ACCUM_DIRECTION parameter is set to an invalid value" severity error; end if; if (FEATURE_FAMILY_STRATIXIII(intended_device_family)) then if ((output_rounding = "YES") and (accumulator = "YES")) then assert false report "Error: In accumulator mode, the OUTPUT_ROUNDING parameter has to be set to VARIABLE if used" severity error; end if; if ((chainout_adder = "YES") and (output_rounding /= "NO")) then assert false report "Error: In chainout mode, output rounding cannot be turned on" severity error; end if; end if; wait; end process; -- ---------------------------------------------------------------- -- This process updates the dataa_int everytime dataa changes value -- ---------------------------------------------------------------- IFG01: if (number_of_multipliers >= 1) generate process (dataa, signa, sign_a_reg, sign_a_pipe) variable dataa1_cnt : integer := 0; variable dataa_word_temp : std_logic_vector (int_width_a -1 downto 0) := (others=>'0'); variable asign : boolean; variable is_rep_a_sign : boolean; variable is_rep_a_pipe_sign : boolean; begin is_rep_a_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_reg = '1'))) or ((port_signa = "PORT_USED") and (sign_a_reg = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); is_rep_a_pipe_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_pipe = '1'))) or ((port_signa = "PORT_USED") and (sign_a_pipe = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); -- Use sign_a_reg instead of sign_a_pipe when signed_pipeline_register_a is unregistered -- to set the asign flag if (signed_pipeline_register_a = "UNREGISTERED") then if (is_rep_a_sign) then asign := true; else asign := false; end if; else if (is_rep_a_pipe_sign) then asign := true; else asign := false; end if; end if; dataa_word_temp := (others => '0'); if ((chainout_adder = "YES") and (stratixiii_block)) then if ((width_result > width_a + width_b + 8) and (width_a < 18)) then if (asign = true) then -- signed number, extend MSB with sign bit for dataa1_cnt in 1 to (chainout_input_a) loop dataa_word_temp(int_width_a - dataa1_cnt) := dataa(width_a - 1); end loop; else -- unsigned number, extend MSB with "0" for dataa1_cnt in 1 to (chainout_input_a) loop dataa_word_temp(int_width_a - dataa1_cnt) := '0'; end loop; end if; for dataa1_cnt in 0 to (width_a - 1) loop dataa_word_temp(dataa1_cnt) := dataa(dataa1_cnt); end loop; dataa_int1 <= dataa_word_temp(int_width_a -1 downto 0); else dataa_int1((int_width_a) - 1 downto ((int_width_a) - width_a)) <= dataa(width_a - 1 downto 0); end if; else dataa_int1((int_width_a) - 1 downto ((int_width_a) - width_a)) <= dataa(width_a - 1 downto 0); end if; end process; end generate IFG01; IFG02: if (number_of_multipliers >= 2) generate process (dataa, signa, sign_a_reg, sign_a_pipe) variable dataa2_cnt : integer := 0; variable dataa2_word_temp : std_logic_vector (int_width_a -1 downto 0) := (others=>'0'); variable asign : boolean; variable is_rep_a_sign : boolean; variable is_rep_a_pipe_sign : boolean; begin is_rep_a_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_reg = '1'))) or ((port_signa = "PORT_USED") and (sign_a_reg = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); is_rep_a_pipe_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_pipe = '1'))) or ((port_signa = "PORT_USED") and (sign_a_pipe = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); -- Use sign_a_reg instead of sign_a_pipe when signed_pipeline_register_a is unregistered -- to set the asign flag if (signed_pipeline_register_a = "UNREGISTERED") then if (is_rep_a_sign) then asign := true; else asign := false; end if; else if (is_rep_a_pipe_sign) then asign := true; else asign := false; end if; end if; dataa2_word_temp := (others => '0'); if ((chainout_adder = "YES") and (stratixiii_block)) then if ((width_result > width_a + width_b + 8) and (width_a < 18)) then if (asign = true) then -- signed number, extend MSB with sign bit for dataa2_cnt in 1 to (chainout_input_a) loop dataa2_word_temp(int_width_a - dataa2_cnt) := dataa((2*width_a) - 1); end loop; else -- unsigned number, extend MSB with "0" for dataa2_cnt in 1 to (chainout_input_a) loop dataa2_word_temp(int_width_a - dataa2_cnt) := '0'; end loop; end if; for dataa2_cnt in 0 to (width_a - 1) loop dataa2_word_temp(dataa2_cnt) := dataa(width_a + dataa2_cnt); end loop; dataa_int2 <= dataa2_word_temp(int_width_a -1 downto 0); else dataa_int2((int_width_a) - 1 downto ((int_width_a) - width_a)) <= dataa((2*width_a) - 1 downto width_a); end if; else dataa_int2((int_width_a) - 1 downto ((int_width_a) - width_a)) <= dataa((2 * width_a) - 1 downto width_a); end if; end process; end generate IFG02; IFG03: if (number_of_multipliers >= 3) generate process (dataa, signa, sign_a_reg, sign_a_pipe) variable dataa3_cnt : integer := 0; variable dataa3_word_temp : std_logic_vector (int_width_a -1 downto 0) := (others=>'0'); variable asign : boolean; variable is_rep_a_sign : boolean; variable is_rep_a_pipe_sign : boolean; begin is_rep_a_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_reg = '1'))) or ((port_signa = "PORT_USED") and (sign_a_reg = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); is_rep_a_pipe_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_pipe = '1'))) or ((port_signa = "PORT_USED") and (sign_a_pipe = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); -- Use sign_a_reg instead of sign_a_pipe when signed_pipeline_register_a is unregistered -- to set the asign flag if (signed_pipeline_register_a = "UNREGISTERED") then if (is_rep_a_sign) then asign := true; else asign := false; end if; else if (is_rep_a_pipe_sign) then asign := true; else asign := false; end if; end if; dataa3_word_temp := (others => '0'); if ((chainout_adder = "YES") and (stratixiii_block)) then if ((width_result > width_a + width_b + 8) and (width_a < 18)) then if (asign = true) then -- signed number, extend MSB with sign bit for dataa3_cnt in 1 to (chainout_input_a) loop dataa3_word_temp(int_width_a - dataa3_cnt) := dataa((3*width_a) - 1); end loop; else -- unsigned number, extend MSB with "0" for dataa3_cnt in 1 to (chainout_input_a) loop dataa3_word_temp(int_width_a - dataa3_cnt) := '0'; end loop; end if; for dataa3_cnt in 0 to (width_a - 1) loop dataa3_word_temp (dataa3_cnt) := dataa((2*width_a) + dataa3_cnt); end loop; dataa_int3 <= dataa3_word_temp(int_width_a -1 downto 0); else dataa_int3((int_width_a) - 1 downto ((int_width_a) - width_a)) <= dataa((3*width_a) - 1 downto (2*width_a)); end if; else dataa_int3((int_width_a) - 1 downto (int_width_a) - width_a) <= dataa((3 * width_a) - 1 downto (2 * width_a)); end if; end process; end generate IFG03; IFG04: if (number_of_multipliers >= 4) generate process (dataa, signa, sign_a_reg, sign_a_pipe) variable dataa4_cnt : integer := 0; variable dataa4_word_temp : std_logic_vector (int_width_a -1 downto 0) := (others=>'0'); variable asign : boolean; variable is_rep_a_sign : boolean; variable is_rep_a_pipe_sign : boolean; begin is_rep_a_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_reg = '1'))) or ((port_signa = "PORT_USED") and (sign_a_reg = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); is_rep_a_pipe_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_pipe = '1'))) or ((port_signa = "PORT_USED") and (sign_a_pipe = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); -- Use sign_a_reg instead of sign_a_pipe when signed_pipeline_register_a is unregistered -- to set the asign flag if (signed_pipeline_register_a = "UNREGISTERED") then if (is_rep_a_sign) then asign := true; else asign := false; end if; else if (is_rep_a_pipe_sign) then asign := true; else asign := false; end if; end if; dataa4_word_temp := (others => '0'); if ((chainout_adder = "YES") and (stratixiii_block)) then if ((width_result > width_a + width_b + 8) and (width_a < 18)) then if (asign = true) then -- signed number, extend MSB with sign bit for dataa4_cnt in 1 to (chainout_input_a) loop dataa4_word_temp(int_width_a - dataa4_cnt) := dataa((4*width_a) - 1); end loop; else -- unsigned number, extend MSB with "0" for dataa4_cnt in 1 to (chainout_input_a) loop dataa4_word_temp(int_width_a - dataa4_cnt) := '0'; end loop; end if; for dataa4_cnt in 0 to (width_a - 1) loop dataa4_word_temp(dataa4_cnt) := dataa((3*width_a) + dataa4_cnt); end loop; dataa_int4 <= dataa4_word_temp(int_width_a -1 downto 0); else dataa_int4((int_width_a) - 1 downto ((int_width_a) - width_a)) <= dataa((4*width_a) - 1 downto (3*width_a)); end if; else dataa_int4((int_width_a) - 1 downto (int_width_a) - width_a) <= dataa((4 * width_a) - 1 downto (3 * width_a)); end if; end process; end generate IFG04; -- ---------------------------------------------------------------- -- This process updates the datab_int everytime datab changes value -- ---------------------------------------------------------------- IFG05: if (number_of_multipliers >= 1) generate process (datab, signb, sign_b_reg, sign_b_pipe) variable datab1_cnt : integer := 0; variable datab_word_temp : std_logic_vector(int_width_b -1 downto 0) := (others => '0'); variable bsign : boolean; variable is_rep_b_sign : boolean; variable is_rep_b_pipe_sign : boolean; begin is_rep_b_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_reg = '1'))) or ((port_signb = "PORT_USED") and (sign_b_reg = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); is_rep_b_pipe_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_pipe = '1'))) or ((port_signb = "PORT_USED") and (sign_b_pipe = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); -- Use sign_b_reg instead of sign_b_pipe when -- signed_pipeline_register_b is unregistered -- to set the bsign flag if (signed_pipeline_register_b = "UNREGISTERED") then if (is_rep_b_sign) then bsign := true; else bsign := false; end if; else if (is_rep_b_pipe_sign) then bsign := true; else bsign := false; end if; end if; datab_word_temp := (others => '0'); if ((chainout_adder = "YES") and (stratixiii_block)) then if ((width_result > width_a + width_b + 8) and (width_b < 18))then if (bsign = true) then -- signed number, extend MSB with sign bit for datab1_cnt in 1 to (chainout_input_b) loop datab_word_temp(int_width_b - datab1_cnt) := datab(width_b - 1); end loop; else -- unsigned number, extend MSB with "0" for datab1_cnt in 1 to (chainout_input_b) loop datab_word_temp(int_width_b - datab1_cnt) := '0'; end loop; end if; for datab1_cnt in 0 to (width_b - 1) loop datab_word_temp(datab1_cnt) := datab(datab1_cnt); end loop; datab_int1 <= datab_word_temp(int_width_b - 1 downto 0); else datab_int1((int_width_b) - 1 downto ((int_width_b) - width_b)) <= datab(width_b - 1 downto 0); end if; else datab_int1((int_width_b) - 1 downto ((int_width_b) - width_b)) <= datab(width_b - 1 downto 0); end if; end process; end generate IFG05; IFG06: if (number_of_multipliers >= 2) generate process (datab, signb, sign_b_reg, sign_b_pipe) variable datab2_cnt : integer := 0; variable datab2_word_temp : std_logic_vector(int_width_b -1 downto 0) := (others => '0'); variable bsign : boolean; variable is_rep_b_sign : boolean; variable is_rep_b_pipe_sign : boolean; begin is_rep_b_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_reg = '1'))) or ((port_signb = "PORT_USED") and (sign_b_reg = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); is_rep_b_pipe_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_pipe = '1'))) or ((port_signb = "PORT_USED") and (sign_b_pipe = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); -- Use sign_b_reg instead of sign_b_pipe when -- signed_pipeline_register_b is unregistered -- to set the bsign flag if (signed_pipeline_register_b = "UNREGISTERED") then if (is_rep_b_sign) then bsign := true; else bsign := false; end if; else if (is_rep_b_pipe_sign) then bsign := true; else bsign := false; end if; end if; datab2_word_temp := (others => '0'); if ((chainout_adder = "YES") and (stratixiii_block)) then if ((width_result > width_a + width_b + 8) and (width_b < 18)) then if (bsign = true) then -- signed number, extend MSB with sign bit for datab2_cnt in 1 to (chainout_input_b) loop datab2_word_temp(int_width_b - datab2_cnt) := datab((2*width_b) - 1); end loop; else -- unsigned number, extend MSB with "0" for datab2_cnt in 1 to (chainout_input_b) loop datab2_word_temp(int_width_b - datab2_cnt) := '0'; end loop; end if; for datab2_cnt in 0 to (width_b - 1) loop datab2_word_temp(datab2_cnt) := datab(width_b + datab2_cnt); end loop; datab_int2 <= datab2_word_temp(int_width_b -1 downto 0); else datab_int2((int_width_b) - 1 downto ((int_width_b) - width_b)) <= datab((2*width_b) - 1 downto width_b); end if; else datab_int2((int_width_b) - 1 downto ((int_width_b) - width_b)) <= datab((2 * width_b) - 1 downto width_b); end if; end process; end generate IFG06; IFG07: if (number_of_multipliers >= 3) generate process (datab, signb, sign_b_reg, sign_b_pipe) variable datab3_cnt : integer := 0; variable datab3_word_temp : std_logic_vector(int_width_b -1 downto 0) := (others => '0'); variable bsign : boolean; variable is_rep_b_sign : boolean; variable is_rep_b_pipe_sign : boolean; begin is_rep_b_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_reg = '1'))) or ((port_signb = "PORT_USED") and (sign_b_reg = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); is_rep_b_pipe_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_pipe = '1'))) or ((port_signb = "PORT_USED") and (sign_b_pipe = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); -- Use sign_b_reg instead of sign_b_pipe when -- signed_pipeline_register_b is unregistered -- to set the bsign flag if (signed_pipeline_register_b = "UNREGISTERED") then if (is_rep_b_sign) then bsign := true; else bsign := false; end if; else if (is_rep_b_pipe_sign) then bsign := true; else bsign := false; end if; end if; datab3_word_temp := (others => '0'); if ((chainout_adder = "YES") and (stratixiii_block)) then if ((width_result > width_a + width_b + 8) and (width_b < 18)) then if (bsign = true) then -- signed number, extend MSB with sign bit for datab3_cnt in 1 to (chainout_input_b) loop datab3_word_temp(int_width_b - datab3_cnt) := datab((3*width_b) - 1); end loop; else -- unsigned number, extend MSB with "0" for datab3_cnt in 1 to (chainout_input_b) loop datab3_word_temp(int_width_b - datab3_cnt) := '0'; end loop; end if; for datab3_cnt in 0 to (width_b - 1) loop datab3_word_temp(datab3_cnt) := datab((2*width_b) + datab3_cnt); end loop; datab_int3 <= datab3_word_temp(int_width_b - 1 downto 0); else datab_int3((int_width_b) - 1 downto ((int_width_b) - width_b)) <= datab((3*width_b) - 1 downto (2*width_b)); end if; else datab_int3((int_width_b) - 1 downto ((int_width_b) - width_b)) <= datab((3 * width_b) - 1 downto (2 * width_b)); end if; end process; end generate IFG07; IFG08: if (number_of_multipliers >= 4) generate process (datab, signb, sign_b_reg, sign_b_pipe) variable datab4_cnt : integer := 0; variable datab4_word_temp : std_logic_vector(int_width_b -1 downto 0) := (others => '0'); variable bsign : boolean; variable is_rep_b_sign : boolean; variable is_rep_b_pipe_sign : boolean; begin is_rep_b_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_reg = '1'))) or ((port_signb = "PORT_USED") and (sign_b_reg = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); is_rep_b_pipe_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_pipe = '1'))) or ((port_signb = "PORT_USED") and (sign_b_pipe = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); -- Use sign_b_reg instead of sign_b_pipe when -- signed_pipeline_register_b is unregistered -- to set the bsign flag if (signed_pipeline_register_b = "UNREGISTERED") then if (is_rep_b_sign) then bsign := true; else bsign := false; end if; else if (is_rep_b_pipe_sign) then bsign := true; else bsign := false; end if; end if; datab4_word_temp := (others => '0'); if ((chainout_adder = "YES") and (stratixiii_block)) then if ((width_result > width_a + width_b + 8) and (width_b < 18)) then if (bsign = true) then -- signed number, extend MSB with sign bit for datab4_cnt in 1 to (chainout_input_b) loop datab4_word_temp(int_width_b - datab4_cnt) := datab((4*width_b) - 1); end loop; else -- unsigned number, extend MSB with "0" for datab4_cnt in 1 to (chainout_input_b) loop datab4_word_temp(int_width_b - datab4_cnt) := '0'; end loop; end if; for datab4_cnt in 0 to (width_b - 1) loop datab4_word_temp(datab4_cnt) := datab((3*width_b) + datab4_cnt); end loop; datab_int4 <= datab4_word_temp(int_width_b - 1 downto 0); else datab_int4((int_width_b) - 1 downto ((int_width_b) - width_b)) <= datab((4*width_b) - 1 downto (3*width_b)); end if; else datab_int4((int_width_b) - 1 downto ((int_width_b) - width_b)) <= datab((4 * width_b) - 1 downto (3 * width_b)); end if; end process; end generate IFG08; -- This process updates scanouta depending on which family is being used process (mult_a, scanouta_reg) begin if (altera_mult_add_block) then scanouta <= (others => 'Z'); elsif (stratixiii_block) then scanouta <= scanouta_reg (width_a - 1 downto 0); else scanouta <= mult_a ((number_of_multipliers * int_width_a) - 1 downto ((number_of_multipliers -1 ) * int_width_a) + int_width_a - width_a) ; end if; end process; -- This process updates dataa_int and datab_int process (dataa_int1, dataa_int2, dataa_int3, dataa_int4, datab_int1, datab_int2, datab_int3, datab_int4) begin dataa_int <= dataa_int4 & dataa_int3 & dataa_int2 & dataa_int1; datab_int <= datab_int4 & datab_int3 & datab_int2 & datab_int1; end process; -- ------------------------------------------------------------------------------------ -- This process sets up all the clock, clock enable and clear signals for all registers -- ------------------------------------------------------------------------------------ -- --------------------------------------- -- SETTING UP THE CONTROL SIGNAL REGISTERS -- --------------------------------------- -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set addsub_reg1) -- The signal registered is addnsub1 -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if addnsub_multiplier_register1 -- is unregistered and addnsub1 changes value -- --------------------------------------------------------------------------------- G1: if (addnsub_multiplier_register1 = "UNREGISTERED") generate addsub_reg1 <= addnsub1; end generate G1; IFG9: if (addnsub_multiplier_register1 = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, addnsub1) begin if (((addnsub_multiplier_aclr1= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_aclr1= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_aclr1= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_aclr1= "ACLR3") and (aclr3 = '1'))) then addsub_reg1 <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then addsub_reg1 <= addnsub1; end if; end if; end process; end generate IFG9; IFG10: if (addnsub_multiplier_register1 = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, addnsub1) begin if (((addnsub_multiplier_aclr1= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_aclr1= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_aclr1= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_aclr1= "ACLR3") and (aclr3 = '1'))) then addsub_reg1 <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then addsub_reg1 <= addnsub1; end if; end if; end process; end generate IFG10; IFG11: if (addnsub_multiplier_register1 = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, addnsub1) begin if (((addnsub_multiplier_aclr1= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_aclr1= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_aclr1= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_aclr1= "ACLR3") and (aclr3 = '1'))) then addsub_reg1 <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then addsub_reg1 <= addnsub1; end if; end if; end process; end generate IFG11; IFG12: if (addnsub_multiplier_register1 = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, addnsub1) begin if (((addnsub_multiplier_aclr1= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_aclr1= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_aclr1= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_aclr1= "ACLR3") and (aclr3 = '1'))) then addsub_reg1 <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then addsub_reg1 <= addnsub1; end if; end if; end process; end generate IFG12; -- ---------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set addsub_pipe1) -- The signal registered is addsub_reg1 -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if addnsub_multiplier_pipeline_register1 -- is unregistered and addsub_reg1 changes value -- ---------------------------------------------------------------------------------- G2: if (addnsub_multiplier_pipeline_register1 = "UNREGISTERED") generate addsub_pipe1 <= addsub_reg1; end generate G2; IFG14: if (addnsub_multiplier_pipeline_register1 = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, addsub_reg1) begin if (((addnsub_multiplier_pipeline_aclr1= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR3") and (aclr3 = '1'))) then addsub_pipe1<= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then addsub_pipe1 <= addsub_reg1; end if; end if; end process; end generate IFG14; IFG14a: if (addnsub_multiplier_pipeline_register1 = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, addsub_reg1) begin if (((addnsub_multiplier_pipeline_aclr1= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR3") and (aclr3 = '1'))) then addsub_pipe1<= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then addsub_pipe1 <= addsub_reg1; end if; end if; end process; end generate IFG14a; IFG15: if (addnsub_multiplier_pipeline_register1 = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, addsub_reg1) begin if (((addnsub_multiplier_pipeline_aclr1= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR3") and (aclr3 = '1'))) then addsub_pipe1<= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then addsub_pipe1 <= addsub_reg1; end if; end if; end process; end generate IFG15; IFG16: if (addnsub_multiplier_pipeline_register1 = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, addsub_reg1) begin if (((addnsub_multiplier_pipeline_aclr1= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_pipeline_aclr1= "ACLR3") and (aclr3 = '1'))) then addsub_pipe1<= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then addsub_pipe1 <= addsub_reg1; end if; end if; end process; end generate IFG16; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set addsub_reg3) -- The signal registered is addsub3 -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if addnsub_multiplier_register3 -- is unregistered and addnsub3 changes value -- --------------------------------------------------------------------------------- G3: if (addnsub_multiplier_register3 = "UNREGISTERED") generate addsub_reg3 <= addnsub3; end generate G3; IFG17: if (addnsub_multiplier_register3 = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, addnsub3) begin if (((addnsub_multiplier_aclr3= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_aclr3= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_aclr3= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_aclr3= "ACLR3") and (aclr3 = '1'))) then addsub_reg3 <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then addsub_reg3 <= addnsub3; end if; end if; end process; end generate IFG17; IFG18: if (addnsub_multiplier_register3 = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, addnsub3) begin if (((addnsub_multiplier_aclr3= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_aclr3= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_aclr3= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_aclr3= "ACLR3") and (aclr3 = '1'))) then addsub_reg3 <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then addsub_reg3 <= addnsub3; end if; end if; end process; end generate IFG18; IFG19: if (addnsub_multiplier_register3 = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, addnsub3) begin if (((addnsub_multiplier_aclr3= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_aclr3= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_aclr3= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_aclr3= "ACLR3") and (aclr3 = '1'))) then addsub_reg3 <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then addsub_reg3 <= addnsub3; end if; end if; end process; end generate IFG19; IFG20: if (addnsub_multiplier_register3 = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, addnsub3) begin if (((addnsub_multiplier_aclr3= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_aclr3= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_aclr3= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_aclr3= "ACLR3") and (aclr3 = '1'))) then addsub_reg3 <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then addsub_reg3 <= addnsub3; end if; end if; end process; end generate IFG20; -- ---------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set addsub_pipe3) -- The signal registered is addsub_reg3 -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if addnsub_multiplier_pipeline_register3 -- is unregistered and addsub_reg3 changes value -- ---------------------------------------------------------------------------------- G4: if (addnsub_multiplier_pipeline_register3 = "UNREGISTERED") generate addsub_pipe3 <= addsub_reg3; end generate G4; IFG21: if (addnsub_multiplier_pipeline_register3 = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, addsub_reg3) begin if (((addnsub_multiplier_pipeline_aclr3= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR3") and (aclr3 = '1'))) then addsub_pipe3<= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then addsub_pipe3 <= addsub_reg3; end if; end if; end process; end generate IFG21; IFG22: if (addnsub_multiplier_pipeline_register3 = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, addsub_reg3) begin if (((addnsub_multiplier_pipeline_aclr3= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR3") and (aclr3 = '1'))) then addsub_pipe3<= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then addsub_pipe3 <= addsub_reg3; end if; end if; end process; end generate IFG22; IFG23: if (addnsub_multiplier_pipeline_register3 = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, addsub_reg3) begin if (((addnsub_multiplier_pipeline_aclr3= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR3") and (aclr3 = '1'))) then addsub_pipe3<= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then addsub_pipe3 <= addsub_reg3; end if; end if; end process; end generate IFG23; IFG24: if (addnsub_multiplier_pipeline_register3 = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, addsub_reg3) begin if (((addnsub_multiplier_pipeline_aclr3= "ACLR0") and (aclr0 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR1") and (aclr1 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR2") and (aclr2 = '1')) or ((addnsub_multiplier_pipeline_aclr3= "ACLR3") and (aclr3 = '1'))) then addsub_pipe3<= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then addsub_pipe3 <= addsub_reg3; end if; end if; end process; end generate IFG24; -- -------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set sign_a_reg) -- The signal registered is signa -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if signed_register_a -- is unregistered and signa changes value -- -------------------------------------------------------------------------------- G5: if (signed_register_a = "UNREGISTERED") generate sign_a_reg <= signa; end generate G5; IFG25: if (signed_register_a = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, signa) begin if (((signed_aclr_a= "ACLR0") and (aclr0 = '1')) or ((signed_aclr_a= "ACLR1") and (aclr1 = '1')) or ((signed_aclr_a= "ACLR2") and (aclr2 = '1')) or ((signed_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_reg <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then sign_a_reg <= signa; end if; end if; end process; end generate IFG25; IFG26: if (signed_register_a = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, signa) begin if (((signed_aclr_a= "ACLR0") and (aclr0 = '1')) or ((signed_aclr_a= "ACLR1") and (aclr1 = '1')) or ((signed_aclr_a= "ACLR2") and (aclr2 = '1')) or ((signed_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_reg <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then sign_a_reg <= signa; end if; end if; end process; end generate IFG26; IFG27: if (signed_register_a = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, signa) begin if (((signed_aclr_a= "ACLR0") and (aclr0 = '1')) or ((signed_aclr_a= "ACLR1") and (aclr1 = '1')) or ((signed_aclr_a= "ACLR2") and (aclr2 = '1')) or ((signed_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_reg <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then sign_a_reg <= signa; end if; end if; end process; end generate IFG27; IFG28: if (signed_register_a = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, signa) begin if (((signed_aclr_a= "ACLR0") and (aclr0 = '1')) or ((signed_aclr_a= "ACLR1") and (aclr1 = '1')) or ((signed_aclr_a= "ACLR2") and (aclr2 = '1')) or ((signed_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_reg <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then sign_a_reg <= signa; end if; end if; end process; end generate IFG28; -- -------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set sign_b_reg) -- The signal registered is signb -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if signed_register_b -- is unregistered and signb changes value -- -------------------------------------------------------------------------------- G6: if (signed_register_b = "UNREGISTERED") generate sign_b_reg <= signb; end generate G6; IFG29: if (signed_register_b = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, signb) begin if (((signed_aclr_b= "ACLR0") and (aclr0 = '1')) or ((signed_aclr_b= "ACLR1") and (aclr1 = '1')) or ((signed_aclr_b= "ACLR2") and (aclr2 = '1')) or ((signed_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_reg <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then sign_b_reg <= signb; end if; end if; end process; end generate IFG29; IFG30: if (signed_register_b = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, signb) begin if (((signed_aclr_b= "ACLR0") and (aclr0 = '1')) or ((signed_aclr_b= "ACLR1") and (aclr1 = '1')) or ((signed_aclr_b= "ACLR2") and (aclr2 = '1')) or ((signed_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_reg <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then sign_b_reg <= signb; end if; end if; end process; end generate IFG30; IFG31: if (signed_register_b = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, signb) begin if (((signed_aclr_b= "ACLR0") and (aclr0 = '1')) or ((signed_aclr_b= "ACLR1") and (aclr1 = '1')) or ((signed_aclr_b= "ACLR2") and (aclr2 = '1')) or ((signed_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_reg <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then sign_b_reg <= signb; end if; end if; end process; end generate IFG31; IFG32: if (signed_register_b = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, signb) begin if (((signed_aclr_b= "ACLR0") and (aclr0 = '1')) or ((signed_aclr_b= "ACLR1") and (aclr1 = '1')) or ((signed_aclr_b= "ACLR2") and (aclr2 = '1')) or ((signed_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_reg <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then sign_b_reg <= signb; end if; end if; end process; end generate IFG32; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set sign_a_pipe) -- The signal registered is sign_a_reg -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if signed_pipeline_register_a -- is unregistered and sign_a_reg changes value -- --------------------------------------------------------------------------------- G7: if (signed_pipeline_register_a = "UNREGISTERED") generate sign_a_pipe <= sign_a_reg; end generate G7; IFG33: if (signed_pipeline_register_a = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, sign_a_reg) begin if (((signed_pipeline_aclr_a= "ACLR0") and (aclr0 = '1')) or ((signed_pipeline_aclr_a= "ACLR1") and (aclr1 = '1')) or ((signed_pipeline_aclr_a= "ACLR2") and (aclr2 = '1')) or ((signed_pipeline_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_pipe <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then sign_a_pipe <= sign_a_reg; end if; end if; end process; end generate IFG33; IFG34: if (signed_pipeline_register_a = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, sign_a_reg) begin if (((signed_pipeline_aclr_a= "ACLR0") and (aclr0 = '1')) or ((signed_pipeline_aclr_a= "ACLR1") and (aclr1 = '1')) or ((signed_pipeline_aclr_a= "ACLR2") and (aclr2 = '1')) or ((signed_pipeline_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_pipe <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then sign_a_pipe <= sign_a_reg; end if; end if; end process; end generate IFG34; IFG35: if (signed_pipeline_register_a = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, sign_a_reg) begin if (((signed_pipeline_aclr_a= "ACLR0") and (aclr0 = '1')) or ((signed_pipeline_aclr_a= "ACLR1") and (aclr1 = '1')) or ((signed_pipeline_aclr_a= "ACLR2") and (aclr2 = '1')) or ((signed_pipeline_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_pipe <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then sign_a_pipe <= sign_a_reg; end if; end if; end process; end generate IFG35; IFG36: if (signed_pipeline_register_a = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, sign_a_reg) begin if (((signed_pipeline_aclr_a= "ACLR0") and (aclr0 = '1')) or ((signed_pipeline_aclr_a= "ACLR1") and (aclr1 = '1')) or ((signed_pipeline_aclr_a= "ACLR2") and (aclr2 = '1')) or ((signed_pipeline_aclr_a= "ACLR3") and (aclr3 = '1'))) then sign_a_pipe <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then sign_a_pipe <= sign_a_reg; end if; end if; end process; end generate IFG36; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set sign_b_pipe) -- The signal registered is sign_b_reg -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if signed_pipeline_register_b -- is unregistered and sign_b_reg changes value -- --------------------------------------------------------------------------------- G8: if (signed_pipeline_register_b = "UNREGISTERED") generate sign_b_pipe <= sign_b_reg; end generate G8; IFG37: if (signed_pipeline_register_b = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, sign_b_reg) begin if (((signed_pipeline_aclr_b= "ACLR0") and (aclr0 = '1')) or ((signed_pipeline_aclr_b= "ACLR1") and (aclr1 = '1')) or ((signed_pipeline_aclr_b= "ACLR2") and (aclr2 = '1')) or ((signed_pipeline_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_pipe <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then sign_b_pipe <= sign_b_reg; end if; end if; end process; end generate IFG37; IFG38: if (signed_pipeline_register_b = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, sign_b_reg) begin if (((signed_pipeline_aclr_b= "ACLR0") and (aclr0 = '1')) or ((signed_pipeline_aclr_b= "ACLR1") and (aclr1 = '1')) or ((signed_pipeline_aclr_b= "ACLR2") and (aclr2 = '1')) or ((signed_pipeline_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_pipe <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then sign_b_pipe <= sign_b_reg; end if; end if; end process; end generate IFG38; IFG39: if (signed_pipeline_register_b = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, sign_b_reg) begin if (((signed_pipeline_aclr_b= "ACLR0") and (aclr0 = '1')) or ((signed_pipeline_aclr_b= "ACLR1") and (aclr1 = '1')) or ((signed_pipeline_aclr_b= "ACLR2") and (aclr2 = '1')) or ((signed_pipeline_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_pipe <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then sign_b_pipe <= sign_b_reg; end if; end if; end process; end generate IFG39; IFG40: if (signed_pipeline_register_b = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, sign_b_reg) begin if (((signed_pipeline_aclr_b= "ACLR0") and (aclr0 = '1')) or ((signed_pipeline_aclr_b= "ACLR1") and (aclr1 = '1')) or ((signed_pipeline_aclr_b= "ACLR2") and (aclr2 = '1')) or ((signed_pipeline_aclr_b= "ACLR3") and (aclr3 = '1'))) then sign_b_pipe <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then sign_b_pipe <= sign_b_reg; end if; end if; end process; end generate IFG40; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set outround_reg) -- The signal registered is output_round -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if output_round_register -- is unregistered and output_round changes value -- --------------------------------------------------------------------------------- G17 : if (output_round_register = "UNREGISTERED") generate outround_reg <= output_round; end generate G17; IFG73: if (output_round_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, output_round) begin if (((output_round_aclr = "ACLR0") and (aclr0 = '1')) or ((output_round_aclr = "ACLR1") and (aclr1 = '1')) or ((output_round_aclr = "ACLR2") and (aclr2 = '1')) or ((output_round_aclr = "ACLR3") and (aclr3 = '1'))) then outround_reg <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then outround_reg <= output_round; end if; end if; end process; end generate IFG73; IFG74: if (output_round_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, output_round) begin if (((output_round_aclr = "ACLR0") and (aclr0 = '1')) or ((output_round_aclr = "ACLR1") and (aclr1 = '1')) or ((output_round_aclr = "ACLR2") and (aclr2 = '1')) or ((output_round_aclr = "ACLR3") and (aclr3 = '1'))) then outround_reg <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then outround_reg <= output_round; end if; end if; end process; end generate IFG74; IFG75: if (output_round_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, output_round) begin if (((output_round_aclr = "ACLR0") and (aclr0 = '1')) or ((output_round_aclr = "ACLR1") and (aclr1 = '1')) or ((output_round_aclr = "ACLR2") and (aclr2 = '1')) or ((output_round_aclr = "ACLR3") and (aclr3 = '1'))) then outround_reg <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then outround_reg <= output_round; end if; end if; end process; end generate IFG75; IFG76: if (output_round_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, output_round) begin if (((output_round_aclr = "ACLR0") and (aclr0 = '1')) or ((output_round_aclr = "ACLR1") and (aclr1 = '1')) or ((output_round_aclr = "ACLR2") and (aclr2 = '1')) or ((output_round_aclr = "ACLR3") and (aclr3 = '1'))) then outround_reg <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then outround_reg <= output_round; end if; end if; end process; end generate IFG76; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set outround_pipe) -- The signal registered is outround_reg -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if output_round_pipeline_register -- is unregistered and outround_reg changes value -- --------------------------------------------------------------------------------- G18 : if (output_round_pipeline_register = "UNREGISTERED") generate outround_pipe <= outround_reg; end generate G18; IFG77: if (output_round_pipeline_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, outround_reg) begin if (((output_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((output_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((output_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((output_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then outround_pipe <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then outround_pipe <= outround_reg; end if; end if; end process; end generate IFG77; IFG78: if (output_round_pipeline_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, outround_reg) begin if (((output_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((output_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((output_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((output_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then outround_pipe <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then outround_pipe <= outround_reg; end if; end if; end process; end generate IFG78; IFG79: if (output_round_pipeline_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, outround_reg) begin if (((output_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((output_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((output_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((output_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then outround_pipe <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then outround_pipe <= outround_reg; end if; end if; end process; end generate IFG79; IFG80: if (output_round_pipeline_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, outround_reg) begin if (((output_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((output_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((output_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((output_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then outround_pipe <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then outround_pipe <= outround_reg; end if; end if; end process; end generate IFG80; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set chainout_round_reg) -- The signal registered is chainout_round -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if chainout_round_register -- is unregistered and chainout_round changes value -- --------------------------------------------------------------------------------- G19 : if (chainout_round_register = "UNREGISTERED") generate chainout_round_reg <= chainout_round; end generate G19; IFG81: if (chainout_round_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, chainout_round) begin if (((chainout_round_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_reg <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then chainout_round_reg <= chainout_round; end if; end if; end process; end generate IFG81; IFG82: if (chainout_round_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, chainout_round) begin if (((chainout_round_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_reg <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then chainout_round_reg <= chainout_round; end if; end if; end process; end generate IFG82; IFG83: if (chainout_round_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, chainout_round) begin if (((chainout_round_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_reg <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then chainout_round_reg <= chainout_round; end if; end if; end process; end generate IFG83; IFG84: if (chainout_round_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, chainout_round) begin if (((chainout_round_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_reg <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then chainout_round_reg <= chainout_round; end if; end if; end process; end generate IFG84; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set chainout_round_pipe) -- The signal registered is chainout_round_reg -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if chainout_round_pipeline_register -- is unregistered and chainout_round_reg changes value -- --------------------------------------------------------------------------------- G20 : if (chainout_round_pipeline_register = "UNREGISTERED") generate chainout_round_pipe <= chainout_round_reg; end generate G20; IFG85: if (chainout_round_pipeline_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, chainout_round_reg) begin if (((chainout_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_pipe <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then chainout_round_pipe <= chainout_round_reg; end if; end if; end process; end generate IFG85; IFG86: if (chainout_round_pipeline_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, chainout_round_reg) begin if (((chainout_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_pipe <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then chainout_round_pipe <= chainout_round_reg; end if; end if; end process; end generate IFG86; IFG87: if (chainout_round_pipeline_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, chainout_round_reg) begin if (((chainout_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_pipe <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then chainout_round_pipe <= chainout_round_reg; end if; end if; end process; end generate IFG87; IFG88: if (chainout_round_pipeline_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, chainout_round_reg) begin if (((chainout_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_pipe <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then chainout_round_pipe <= chainout_round_reg; end if; end if; end process; end generate IFG88; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set chainout_round_out_reg) -- The signal registered is chainout_round_pipe -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if chainout_round_output_register -- is unregistered and chainout_round_pipe changes value -- --------------------------------------------------------------------------------- G21 : if (chainout_round_output_register = "UNREGISTERED") generate chainout_round_out_reg <= chainout_round_pipe; end generate G21; IFG89: if (chainout_round_output_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, chainout_round_pipe) begin if (((chainout_round_output_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_output_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_output_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_output_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_out_reg <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then chainout_round_out_reg <= chainout_round_pipe; end if; end if; end process; end generate IFG89; IFG90: if (chainout_round_output_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, chainout_round_pipe) begin if (((chainout_round_output_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_output_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_output_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_output_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_out_reg <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then chainout_round_out_reg <= chainout_round_pipe; end if; end if; end process; end generate IFG90; IFG91: if (chainout_round_output_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, chainout_round_pipe) begin if (((chainout_round_output_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_output_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_output_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_output_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_out_reg <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then chainout_round_out_reg <= chainout_round_pipe; end if; end if; end process; end generate IFG91; IFG92: if (chainout_round_output_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, chainout_round_pipe) begin if (((chainout_round_output_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_round_output_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_round_output_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_round_output_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_round_out_reg <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then chainout_round_out_reg <= chainout_round_pipe; end if; end if; end process; end generate IFG92; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set outsat_reg) -- The signal registered is output_saturate -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if output_saturate_register -- is unregistered and output_saturate changes value -- --------------------------------------------------------------------------------- G22 : if (output_saturate_register = "UNREGISTERED") generate outsat_reg <= output_saturate; end generate G22; IFG93: if (output_saturate_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, output_saturate) begin if (((output_saturate_aclr = "ACLR0") and (aclr0 = '1')) or ((output_saturate_aclr = "ACLR1") and (aclr1 = '1')) or ((output_saturate_aclr = "ACLR2") and (aclr2 = '1')) or ((output_saturate_aclr = "ACLR3") and (aclr3 = '1'))) then outsat_reg <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then outsat_reg <= output_saturate; end if; end if; end process; end generate IFG93; IFG94: if (output_saturate_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, output_saturate) begin if (((output_saturate_aclr = "ACLR0") and (aclr0 = '1')) or ((output_saturate_aclr = "ACLR1") and (aclr1 = '1')) or ((output_saturate_aclr = "ACLR2") and (aclr2 = '1')) or ((output_saturate_aclr = "ACLR3") and (aclr3 = '1'))) then outsat_reg <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then outsat_reg <= output_saturate; end if; end if; end process; end generate IFG94; IFG95: if (output_saturate_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, output_saturate) begin if (((output_saturate_aclr = "ACLR0") and (aclr0 = '1')) or ((output_saturate_aclr = "ACLR1") and (aclr1 = '1')) or ((output_saturate_aclr = "ACLR2") and (aclr2 = '1')) or ((output_saturate_aclr = "ACLR3") and (aclr3 = '1'))) then outsat_reg <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then outsat_reg <= output_saturate; end if; end if; end process; end generate IFG95; IFG96: if (output_saturate_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, output_saturate) begin if (((output_saturate_aclr = "ACLR0") and (aclr0 = '1')) or ((output_saturate_aclr = "ACLR1") and (aclr1 = '1')) or ((output_saturate_aclr = "ACLR2") and (aclr2 = '1')) or ((output_saturate_aclr = "ACLR3") and (aclr3 = '1'))) then outsat_reg <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then outsat_reg <= output_saturate; end if; end if; end process; end generate IFG96; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set outsat_pipe) -- The signal registered is outsat_reg -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if output_saturate_pipeline_register -- is unregistered and outsat_reg changes value -- --------------------------------------------------------------------------------- G23 : if (output_saturate_pipeline_register = "UNREGISTERED") generate outsat_pipe <= outsat_reg; end generate G23; IFG97: if (output_saturate_pipeline_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, outsat_reg) begin if (((output_saturate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((output_saturate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((output_saturate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((output_saturate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then outsat_pipe <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then outsat_pipe <= outsat_reg; end if; end if; end process; end generate IFG97; IFG98: if (output_saturate_pipeline_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, outsat_reg) begin if (((output_saturate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((output_saturate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((output_saturate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((output_saturate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then outsat_pipe <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then outsat_pipe <= outsat_reg; end if; end if; end process; end generate IFG98; IFG99: if (output_saturate_pipeline_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, outsat_reg) begin if (((output_saturate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((output_saturate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((output_saturate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((output_saturate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then outsat_pipe <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then outsat_pipe <= outsat_reg; end if; end if; end process; end generate IFG99; IFG100: if (output_saturate_pipeline_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, outsat_reg) begin if (((output_saturate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((output_saturate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((output_saturate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((output_saturate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then outsat_pipe <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then outsat_pipe <= outsat_reg; end if; end if; end process; end generate IFG100; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set chainout_sat_reg) -- The signal registered is chainout_saturate -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if chainout_saturate_register -- is unregistered and chainout_saturate changes value -- --------------------------------------------------------------------------------- G24 : if (chainout_saturate_register = "UNREGISTERED") generate chainout_sat_reg <= chainout_saturate; end generate G24; IFG101: if (chainout_saturate_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, chainout_saturate) begin if (((chainout_saturate_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_reg <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then chainout_sat_reg <= chainout_saturate; end if; end if; end process; end generate IFG101; IFG102: if (chainout_saturate_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, chainout_saturate) begin if (((chainout_saturate_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_reg <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then chainout_sat_reg <= chainout_saturate; end if; end if; end process; end generate IFG102; IFG103: if (chainout_saturate_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, chainout_saturate) begin if (((chainout_saturate_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_reg <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then chainout_sat_reg <= chainout_saturate; end if; end if; end process; end generate IFG103; IFG104: if (chainout_saturate_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, chainout_saturate) begin if (((chainout_saturate_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_reg <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then chainout_sat_reg <= chainout_saturate; end if; end if; end process; end generate IFG104; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set chainout_sat_pipe) -- The signal registered is chainout_sat_reg -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if chainout_saturate_pipeline_register -- is unregistered and chainout_sat_reg changes value -- --------------------------------------------------------------------------------- G25 : if (chainout_saturate_pipeline_register = "UNREGISTERED") generate chainout_sat_pipe <= chainout_sat_reg; end generate G25; IFG105: if (chainout_saturate_pipeline_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, chainout_sat_reg) begin if (((chainout_saturate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_pipe <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then chainout_sat_pipe <= chainout_sat_reg; end if; end if; end process; end generate IFG105; IFG106: if (chainout_saturate_pipeline_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, chainout_sat_reg) begin if (((chainout_saturate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_pipe <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then chainout_sat_pipe <= chainout_sat_reg; end if; end if; end process; end generate IFG106; IFG107: if (chainout_saturate_pipeline_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, chainout_sat_reg) begin if (((chainout_saturate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_pipe <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then chainout_sat_pipe <= chainout_sat_reg; end if; end if; end process; end generate IFG107; IFG108: if (chainout_saturate_pipeline_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, chainout_sat_reg) begin if (((chainout_saturate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_pipe <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then chainout_sat_pipe <= chainout_sat_reg; end if; end if; end process; end generate IFG108; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set chainout_sat_out) -- The signal registered is chainout_sat_pipe -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if chainout_saturate_output_register -- is unregistered and chainout_sat_pipe changes value -- --------------------------------------------------------------------------------- G26 : if (chainout_saturate_output_register = "UNREGISTERED") generate chainout_sat_out <= chainout_sat_pipe; end generate G26; IFG109: if (chainout_saturate_output_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, chainout_sat_pipe) begin if (((chainout_saturate_output_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_output_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_output_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_output_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_out <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then chainout_sat_out <= chainout_sat_pipe; end if; end if; end process; end generate IFG109; IFG110: if (chainout_saturate_output_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, chainout_sat_pipe) begin if (((chainout_saturate_output_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_output_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_output_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_output_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_out <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then chainout_sat_out <= chainout_sat_pipe; end if; end if; end process; end generate IFG110; IFG111: if (chainout_saturate_output_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, chainout_sat_pipe) begin if (((chainout_saturate_output_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_output_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_output_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_output_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_out <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then chainout_sat_out <= chainout_sat_pipe; end if; end if; end process; end generate IFG111; IFG112: if (chainout_saturate_output_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, chainout_sat_pipe) begin if (((chainout_saturate_output_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_saturate_output_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_saturate_output_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_saturate_output_aclr = "ACLR3") and (aclr3 = '1'))) then chainout_sat_out <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then chainout_sat_out <= chainout_sat_pipe; end if; end if; end process; end generate IFG112; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set scanouta_reg) -- The signal registered is mult_a -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if scanouta_register -- is unregistered and mult_a changes value -- --------------------------------------------------------------------------------- G27 : if ((scanouta_register = "UNREGISTERED" and chainout_adder = "YES") and (width_result > width_a + width_b + 8))generate scanouta_reg <= mult_a((number_of_multipliers * int_width_a) - 1 - (int_width_a - width_a) downto ((number_of_multipliers-1) * int_width_a)); end generate G27; G27_1: if (scanouta_register = "UNREGISTERED" and chainout_adder /= "YES") generate scanouta_reg <= mult_a ((number_of_multipliers * int_width_a) - 1 downto ((number_of_multipliers -1 ) * int_width_a) + int_width_a - width_a) ; end generate G27_1; G27_2: if ((scanouta_register = "UNREGISTERED" and chainout_adder = "YES") and (width_result <= width_a + width_b + 8))generate scanouta_reg <= mult_a ((number_of_multipliers * int_width_a) - 1 downto ((number_of_multipliers -1 ) * int_width_a) + int_width_a - width_a) ; end generate G27_2; IFG113: if (scanouta_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, mult_a) begin if (((scanouta_aclr = "ACLR0") and (aclr0 = '1')) or ((scanouta_aclr = "ACLR1") and (aclr1 = '1')) or ((scanouta_aclr = "ACLR2") and (aclr2 = '1')) or ((scanouta_aclr = "ACLR3") and (aclr3 = '1'))) then scanouta_reg <= (others => '0'); elsif rising_edge(clock0) then if (ena0 = '1') then if (chainout_adder = "YES" and (width_result > width_a + width_b + 8)) then scanouta_reg <= mult_a((number_of_multipliers * int_width_a) - 1 - (int_width_a - width_a) downto ((number_of_multipliers-1) * int_width_a)); else scanouta_reg <= mult_a ((number_of_multipliers * int_width_a) - 1 downto ((number_of_multipliers -1 ) * int_width_a) + int_width_a - width_a) ; end if; end if; end if; end process; end generate IFG113; IFG114: if (scanouta_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, mult_a) begin if (((scanouta_aclr = "ACLR0") and (aclr0 = '1')) or ((scanouta_aclr = "ACLR1") and (aclr1 = '1')) or ((scanouta_aclr = "ACLR2") and (aclr2 = '1')) or ((scanouta_aclr = "ACLR3") and (aclr3 = '1'))) then scanouta_reg <= (others => '0'); elsif rising_edge(clock1) then if (ena1 = '1') then if (chainout_adder = "YES" and (width_result > width_a + width_b + 8)) then scanouta_reg <= mult_a((number_of_multipliers * int_width_a) - 1 - (int_width_a - width_a) downto ((number_of_multipliers-1) * int_width_a)); else scanouta_reg <= mult_a ((number_of_multipliers * int_width_a) - 1 downto ((number_of_multipliers -1 ) * int_width_a) + int_width_a - width_a) ; end if; end if; end if; end process; end generate IFG114; IFG115: if (scanouta_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, mult_a) begin if (((scanouta_aclr = "ACLR0") and (aclr0 = '1')) or ((scanouta_aclr = "ACLR1") and (aclr1 = '1')) or ((scanouta_aclr = "ACLR2") and (aclr2 = '1')) or ((scanouta_aclr = "ACLR3") and (aclr3 = '1'))) then scanouta_reg <= (others => '0'); elsif rising_edge(clock2) then if (ena2 = '1') then if (chainout_adder = "YES" and (width_result > width_a + width_b + 8)) then scanouta_reg <= mult_a((number_of_multipliers * int_width_a) - 1 - (int_width_a - width_a) downto ((number_of_multipliers-1) * int_width_a)); else scanouta_reg <= mult_a ((number_of_multipliers * int_width_a) - 1 downto ((number_of_multipliers -1 ) * int_width_a) + int_width_a - width_a) ; end if; end if; end if; end process; end generate IFG115; IFG116: if (scanouta_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, mult_a) begin if (((scanouta_aclr = "ACLR0") and (aclr0 = '1')) or ((scanouta_aclr = "ACLR1") and (aclr1 = '1')) or ((scanouta_aclr = "ACLR2") and (aclr2 = '1')) or ((scanouta_aclr = "ACLR3") and (aclr3 = '1'))) then scanouta_reg <= (others => '0'); elsif rising_edge(clock3) then if (ena3 = '1') then if (chainout_adder = "YES" and (width_result > width_a + width_b + 8)) then scanouta_reg <= mult_a((number_of_multipliers * int_width_a) - 1 - (int_width_a - width_a) downto ((number_of_multipliers-1) * int_width_a)); else scanouta_reg <= mult_a ((number_of_multipliers * int_width_a) - 1 downto ((number_of_multipliers -1 ) * int_width_a) + int_width_a - width_a) ; end if; end if; end if; end process; end generate IFG116; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set zerochainout_reg) -- The signal registered is zero_chainout -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if zero_chainout_output_register -- is unregistered and zero_chainout changes value -- --------------------------------------------------------------------------------- G28 : if (zero_chainout_output_register = "UNREGISTERED") generate zerochainout_reg <= zero_chainout; end generate G28; IFG117: if (zero_chainout_output_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, zero_chainout) begin if (((zero_chainout_output_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_chainout_output_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_chainout_output_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_chainout_output_aclr = "ACLR3") and (aclr3 = '1'))) then zerochainout_reg <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then zerochainout_reg <= zero_chainout; end if; end if; end process; end generate IFG117; IFG118: if (zero_chainout_output_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, zero_chainout) begin if (((zero_chainout_output_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_chainout_output_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_chainout_output_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_chainout_output_aclr = "ACLR3") and (aclr3 = '1'))) then zerochainout_reg <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then zerochainout_reg <= zero_chainout; end if; end if; end process; end generate IFG118; IFG119: if (zero_chainout_output_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, zero_chainout) begin if (((zero_chainout_output_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_chainout_output_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_chainout_output_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_chainout_output_aclr = "ACLR3") and (aclr3 = '1'))) then zerochainout_reg <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then zerochainout_reg <= zero_chainout; end if; end if; end process; end generate IFG119; IFG120: if (zero_chainout_output_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, zero_chainout) begin if (((zero_chainout_output_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_chainout_output_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_chainout_output_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_chainout_output_aclr = "ACLR3") and (aclr3 = '1'))) then zerochainout_reg <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then zerochainout_reg <= zero_chainout; end if; end if; end process; end generate IFG120; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set rotate_reg) -- The signal registered is rotate -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if rotate_register -- is unregistered and rotate changes value -- --------------------------------------------------------------------------------- G29 : if (rotate_register = "UNREGISTERED") generate rotate_reg <= rotate; end generate G29; IFG121: if (rotate_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, rotate) begin if (((rotate_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_reg <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then rotate_reg <= rotate; end if; end if; end process; end generate IFG121; IFG122: if (rotate_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, rotate) begin if (((rotate_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_reg <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then rotate_reg <= rotate; end if; end if; end process; end generate IFG122; IFG123: if (rotate_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, rotate) begin if (((rotate_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_reg <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then rotate_reg <= rotate; end if; end if; end process; end generate IFG123; IFG124: if (rotate_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, rotate) begin if (((rotate_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_reg <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then rotate_reg <= rotate; end if; end if; end process; end generate IFG124; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set rotate_pipe) -- The signal registered is rotate_reg -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if rotate_pipeline_register -- is unregistered and rotate_reg changes value -- --------------------------------------------------------------------------------- G30 : if (rotate_pipeline_register = "UNREGISTERED") generate rotate_pipe <= rotate_reg; end generate G30; IFG125: if (rotate_pipeline_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, rotate_reg) begin if (((rotate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_pipe <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then rotate_pipe <= rotate_reg; end if; end if; end process; end generate IFG125; IFG126: if (rotate_pipeline_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, rotate_reg) begin if (((rotate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_pipe <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then rotate_pipe <= rotate_reg; end if; end if; end process; end generate IFG126; IFG127: if (rotate_pipeline_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, rotate_reg) begin if (((rotate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_pipe <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then rotate_pipe <= rotate_reg; end if; end if; end process; end generate IFG127; IFG128: if (rotate_pipeline_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, rotate_reg) begin if (((rotate_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_pipe <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then rotate_pipe <= rotate_reg; end if; end if; end process; end generate IFG128; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set rotate_out) -- The signal registered is rotate_pipe -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if rotate_output_register -- is unregistered and rotate_pipe changes value -- --------------------------------------------------------------------------------- G31 : if (rotate_output_register = "UNREGISTERED") generate rotate_out <= rotate_pipe; end generate G31; IFG129: if (rotate_output_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, rotate_out) begin if (((rotate_output_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_output_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_output_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_output_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_out <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then rotate_out <= rotate_pipe; end if; end if; end process; end generate IFG129; IFG130: if (rotate_output_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, rotate_out) begin if (((rotate_output_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_output_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_output_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_output_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_out <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then rotate_out <= rotate_pipe; end if; end if; end process; end generate IFG130; IFG131: if (rotate_output_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, rotate_out) begin if (((rotate_output_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_output_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_output_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_output_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_out <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then rotate_out <= rotate_pipe; end if; end if; end process; end generate IFG131; IFG132: if (rotate_output_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, rotate_out) begin if (((rotate_output_aclr = "ACLR0") and (aclr0 = '1')) or ((rotate_output_aclr = "ACLR1") and (aclr1 = '1')) or ((rotate_output_aclr = "ACLR2") and (aclr2 = '1')) or ((rotate_output_aclr = "ACLR3") and (aclr3 = '1'))) then rotate_out <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then rotate_out <= rotate_pipe; end if; end if; end process; end generate IFG132; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set shiftr_reg) -- The signal registered is shift_right -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if shift_right_register -- is unregistered and shift_right changes value -- --------------------------------------------------------------------------------- G32 : if (shift_right_register = "UNREGISTERED") generate shiftr_reg <= shift_right; end generate G32; IFG133: if (shift_right_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, shift_right) begin if (((shift_right_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_reg <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then shiftr_reg <= shift_right; end if; end if; end process; end generate IFG133; IFG134: if (shift_right_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, shift_right) begin if (((shift_right_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_reg <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then shiftr_reg <= shift_right; end if; end if; end process; end generate IFG134; IFG135: if (shift_right_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, shift_right) begin if (((shift_right_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_reg <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then shiftr_reg <= shift_right; end if; end if; end process; end generate IFG135; IFG136: if (shift_right_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, shift_right) begin if (((shift_right_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_reg <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then shiftr_reg <= shift_right; end if; end if; end process; end generate IFG136; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set shiftr_pipe) -- The signal registered is shiftr_reg -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if shift_right_pipeline_register -- is unregistered and shiftr_reg changes value -- --------------------------------------------------------------------------------- G33 : if (shift_right_pipeline_register = "UNREGISTERED") generate shiftr_pipe <= shiftr_reg; end generate G33; IFG137: if (shift_right_pipeline_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, shiftr_reg) begin if (((shift_right_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_pipe <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then shiftr_pipe <= shiftr_reg; end if; end if; end process; end generate IFG137; IFG138: if (shift_right_pipeline_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, shiftr_reg) begin if (((shift_right_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_pipe <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then shiftr_pipe <= shiftr_reg; end if; end if; end process; end generate IFG138; IFG139: if (shift_right_pipeline_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, shiftr_reg) begin if (((shift_right_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_pipe <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then shiftr_pipe <= shiftr_reg; end if; end if; end process; end generate IFG139; IFG140: if (shift_right_pipeline_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, shiftr_reg) begin if (((shift_right_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_pipe <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then shiftr_pipe <= shiftr_reg; end if; end if; end process; end generate IFG140; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set shiftr_out) -- The signal registered is shiftr_pipe -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if shift_right_output_register -- is unregistered and shiftr_pipe changes value -- --------------------------------------------------------------------------------- G34 : if (shift_right_output_register = "UNREGISTERED") generate shiftr_out <= shiftr_pipe; end generate G34; IFG141: if (shift_right_output_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, shiftr_pipe) begin if (((shift_right_output_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_output_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_output_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_output_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_out <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then shiftr_out <= shiftr_pipe; end if; end if; end process; end generate IFG141; IFG142: if (shift_right_output_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, shiftr_pipe) begin if (((shift_right_output_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_output_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_output_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_output_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_out <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then shiftr_out <= shiftr_pipe; end if; end if; end process; end generate IFG142; IFG143: if (shift_right_output_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, shiftr_pipe) begin if (((shift_right_output_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_output_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_output_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_output_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_out <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then shiftr_out <= shiftr_pipe; end if; end if; end process; end generate IFG143; IFG144: if (shift_right_output_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, shiftr_pipe) begin if (((shift_right_output_aclr = "ACLR0") and (aclr0 = '1')) or ((shift_right_output_aclr = "ACLR1") and (aclr1 = '1')) or ((shift_right_output_aclr = "ACLR2") and (aclr2 = '1')) or ((shift_right_output_aclr = "ACLR3") and (aclr3 = '1'))) then shiftr_out <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then shiftr_out <= shiftr_pipe; end if; end if; end process; end generate IFG144; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set zeroloopback_reg) -- The signal registered is zero_loopback -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if zero_loopback_register -- is unregistered and zero_loopback changes value -- --------------------------------------------------------------------------------- G35 : if (zero_loopback_register = "UNREGISTERED") generate zeroloopback_reg <= zero_loopback; end generate G35; IFG145: if (zero_loopback_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, zero_loopback) begin if (((zero_loopback_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_reg <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then zeroloopback_reg <= zero_loopback; end if; end if; end process; end generate IFG145; IFG146: if (zero_loopback_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, zero_loopback) begin if (((zero_loopback_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_reg <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then zeroloopback_reg <= zero_loopback; end if; end if; end process; end generate IFG146; IFG147: if (zero_loopback_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, zero_loopback) begin if (((zero_loopback_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_reg <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then zeroloopback_reg <= zero_loopback; end if; end if; end process; end generate IFG147; IFG148: if (zero_loopback_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, zero_loopback) begin if (((zero_loopback_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_reg <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then zeroloopback_reg <= zero_loopback; end if; end if; end process; end generate IFG148; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set zeroloopback_pipe) -- The signal registered is zeroloopback_reg -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if zero_loopback_pipeline_register -- is unregistered and zeroloopback_reg changes value -- --------------------------------------------------------------------------------- G36 : if (zero_loopback_pipeline_register = "UNREGISTERED") generate zeroloopback_pipe <= zeroloopback_reg; end generate G36; IFG149: if (zero_loopback_pipeline_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, zeroloopback_reg) begin if (((zero_loopback_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_pipe <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then zeroloopback_pipe <= zeroloopback_reg; end if; end if; end process; end generate IFG149; IFG150: if (zero_loopback_pipeline_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, zeroloopback_reg) begin if (((zero_loopback_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_pipe <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then zeroloopback_pipe <= zeroloopback_reg; end if; end if; end process; end generate IFG150; IFG151: if (zero_loopback_pipeline_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, zeroloopback_reg) begin if (((zero_loopback_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_pipe <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then zeroloopback_pipe <= zeroloopback_reg; end if; end if; end process; end generate IFG151; IFG152: if (zero_loopback_pipeline_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, zeroloopback_reg) begin if (((zero_loopback_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_pipe <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then zeroloopback_pipe <= zeroloopback_reg; end if; end if; end process; end generate IFG152; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set zeroloopback_out) -- The signal registered is zeroloopback_pipe -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if zero_loopback_output_register -- is unregistered and zeroloopback_pipe changes value -- --------------------------------------------------------------------------------- G37 : if (zero_loopback_output_register = "UNREGISTERED") generate zeroloopback_out <= zeroloopback_pipe; end generate G37; IFG153: if (zero_loopback_output_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, zeroloopback_pipe) begin if (((zero_loopback_output_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_output_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_output_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_output_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_out <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then zeroloopback_out <= zeroloopback_pipe; end if; end if; end process; end generate IFG153; IFG154: if (zero_loopback_output_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, zeroloopback_pipe) begin if (((zero_loopback_output_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_output_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_output_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_output_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_out <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then zeroloopback_out <= zeroloopback_pipe; end if; end if; end process; end generate IFG154; IFG155: if (zero_loopback_output_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, zeroloopback_pipe) begin if (((zero_loopback_output_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_output_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_output_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_output_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_out <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then zeroloopback_out <= zeroloopback_pipe; end if; end if; end process; end generate IFG155; IFG156: if (zero_loopback_output_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, zeroloopback_pipe) begin if (((zero_loopback_output_aclr = "ACLR0") and (aclr0 = '1')) or ((zero_loopback_output_aclr = "ACLR1") and (aclr1 = '1')) or ((zero_loopback_output_aclr = "ACLR2") and (aclr2 = '1')) or ((zero_loopback_output_aclr = "ACLR3") and (aclr3 = '1'))) then zeroloopback_out <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then zeroloopback_out <= zeroloopback_pipe; end if; end if; end process; end generate IFG156; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set accumsload_reg) -- The signal registered is accum_sload -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if accum_sload_register -- is unregistered and accum_sload changes value -- --------------------------------------------------------------------------------- G38 : if (accum_sload_register = "UNREGISTERED") generate process (accum_sload, output_round) begin if ((accumulator = "YES") and (output_rounding = "VARIABLE") and (chainout_adder = "NO")) then accumsload_reg <= output_round; else accumsload_reg <= accum_sload; end if; end process; end generate G38; IFG157: if (accum_sload_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, accum_sload) begin if (((accum_sload_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_aclr = "ACLR3") and (aclr3 = '1'))) then accumsload_reg <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then if ((accumulator = "YES") and (output_rounding = "VARIABLE") and (chainout_adder = "NO")) then accumsload_reg <= output_round; else accumsload_reg <= accum_sload; end if; end if; end if; end process; end generate IFG157; IFG158: if (accum_sload_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, accum_sload) begin if (((accum_sload_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_aclr = "ACLR3") and (aclr3 = '1'))) then accumsload_reg <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then if ((accumulator = "YES") and (output_rounding = "VARIABLE") and (chainout_adder = "NO")) then accumsload_reg <= output_round; else accumsload_reg <= accum_sload; end if; end if; end if; end process; end generate IFG158; IFG159: if (accum_sload_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, accum_sload) begin if (((accum_sload_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_aclr = "ACLR3") and (aclr3 = '1'))) then accumsload_reg <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then if ((accumulator = "YES") and (output_rounding = "VARIABLE") and (chainout_adder = "NO")) then accumsload_reg <= output_round; else accumsload_reg <= accum_sload; end if; end if; end if; end process; end generate IFG159; IFG160: if (accum_sload_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, accum_sload) begin if (((accum_sload_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_aclr = "ACLR3") and (aclr3 = '1'))) then accumsload_reg <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then if ((accumulator = "YES") and (output_rounding = "VARIABLE") and (chainout_adder = "NO")) then accumsload_reg <= output_round; else accumsload_reg <= accum_sload; end if; end if; end if; end process; end generate IFG160; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set accumsload_pipe) -- The signal registered is accumsload_reg -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if accum_sload_pipeline_register -- is unregistered and accumsload_reg changes value -- --------------------------------------------------------------------------------- G39 : if (accum_sload_pipeline_register = "UNREGISTERED") generate accumsload_pipe <= accumsload_reg; end generate G39; IFG161: if (accum_sload_pipeline_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, accumsload_reg) begin if (((accum_sload_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accumsload_pipe <= '0'; elsif rising_edge(clock0) then if (ena0 = '1') then accumsload_pipe <= accumsload_reg; end if; end if; end process; end generate IFG161; IFG162: if (accum_sload_pipeline_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, accumsload_reg) begin if (((accum_sload_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accumsload_pipe <= '0'; elsif rising_edge(clock1) then if (ena1 = '1') then accumsload_pipe <= accumsload_reg; end if; end if; end process; end generate IFG162; IFG163: if (accum_sload_pipeline_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, accumsload_reg) begin if (((accum_sload_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accumsload_pipe <= '0'; elsif rising_edge(clock2) then if (ena2 = '1') then accumsload_pipe <= accumsload_reg; end if; end if; end process; end generate IFG163; IFG164: if (accum_sload_pipeline_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, accumsload_reg) begin if (((accum_sload_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((accum_sload_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((accum_sload_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((accum_sload_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then accumsload_pipe <= '0'; elsif rising_edge(clock3) then if (ena3 = '1') then accumsload_pipe <= accumsload_reg; end if; end if; end process; end generate IFG164; --------------------------------------------------------------------------- process (clock0, clock1, clock2, clock3, aclr_vector, dataa_int, datab_int, scanina, scaninb, clock_vector, ena_vector, aclr0, aclr1, aclr2, aclr3, sourcea_wire, sourceb_wire, tmp_mult_a, tmp_mult_b, feedback) variable temp_clock : integer := 0; variable temp_aclr : integer := 0; variable x : integer := 0; variable scanina_var : std_logic_vector (int_width_a -1 downto 0):= (others => '0'); variable scaninb_var : std_logic_vector (int_width_b -1 downto 0):= (others => '0'); variable mult_a_pre0 : std_logic_vector (4 * int_width_a -1 downto 0):= (others => '0'); variable mult_a_pre1 : std_logic_vector (4 * int_width_a -1 downto 0):= (others => '0'); variable mult_a_pre2 : std_logic_vector (4 * int_width_a -1 downto 0):= (others => '0'); variable mult_a_pre3 : std_logic_vector (4 * int_width_a -1 downto 0):= (others => '0'); variable mult_b_pre0 : std_logic_vector (4 * int_width_b -1 downto 0):= (others => '0'); variable mult_b_pre1 : std_logic_vector (4 * int_width_b -1 downto 0):= (others => '0'); variable mult_b_pre2 : std_logic_vector (4 * int_width_b -1 downto 0):= (others => '0'); variable mult_b_pre3 : std_logic_vector (4 * int_width_b -1 downto 0):= (others => '0'); variable mult1_source_scanin_en : std_logic := '0'; variable mult2_source_scanin_en : std_logic := '0'; variable mult3_source_scanin_en : std_logic := '0'; begin scanina_var(int_width_a - 1 downto (int_width_a - width_a)) := scanina (width_a - 1 downto 0); scaninb_var(int_width_b - 1 downto (int_width_b - width_b)) := scaninb (width_b - 1 downto 0); --sets up all the clock, clock enable and clear signals for multiplier0 if not (multiplier_register0 = "UNREGISTERED") then temp_clock := resolve_clock (multiplier_register0); mult_clock(0) <= clock_vector (temp_clock); mult_ena(0) <= ena_vector (temp_clock); temp_aclr := resolve_aclr (multiplier_aclr0); mult_aclr(0) <= aclr_vector (temp_aclr); is_reg(0) <= '1'; end if; --sets up all the clock, clock enable and clear signals for multiplier1 if not (multiplier_register1 = "UNREGISTERED") then temp_clock := resolve_clock (multiplier_register1); mult_clock(1) <= clock_vector (temp_clock); mult_ena(1) <= ena_vector (temp_clock); temp_aclr := resolve_aclr (multiplier_aclr1); mult_aclr(1) <= aclr_vector (temp_aclr); is_reg(1) <= '1'; end if; --sets up all the clock, clock enable and clear signals for multiplier2 if not (multiplier_register2 = "UNREGISTERED") then temp_clock := resolve_clock (multiplier_register2); mult_clock(2) <= clock_vector (temp_clock); mult_ena(2) <= ena_vector (temp_clock); temp_aclr := resolve_aclr (multiplier_aclr2); mult_aclr(2) <= aclr_vector (temp_aclr); is_reg(2) <= '1'; end if; --sets up all the clock, clock enable and clear signals for multiplier3 if not (multiplier_register3 = "UNREGISTERED") then temp_clock := resolve_clock (multiplier_register3); mult_clock(3) <= clock_vector (temp_clock); mult_ena(3) <= ena_vector (temp_clock); temp_aclr := resolve_aclr (multiplier_aclr3); mult_aclr(3) <= aclr_vector (temp_aclr); is_reg(3) <= '1'; end if; -- --------------------------------------------- -- SETTING UP THE DATA INPUT REGISTERS OF PORT A -- --------------------------------------------- -- ----------------- -- INPUT_REGISTER_A0 -- ----------------- -- set the initial value for mult_a_pre0 from dataa_int if (input_source_a0 = "DATAA") then mult_a_pre0 (int_width_a-1 downto 0) := dataa_int (int_width_a-1 downto 0); elsif (input_source_a0 = "SCANA") then if (stratixii_block) then mult_a_pre0 (int_width_a-1 downto 0) := scanina_var; else mult_a_pre0 (int_width_a-1 downto 0) := dataa_int (int_width_a-1 downto 0); end if; else if (sourcea_wire(0) = '1') then mult_a_pre0 (int_width_a-1 downto 0) := scanina_var; else mult_a_pre0 (int_width_a-1 downto 0) := dataa_int (int_width_a-1 downto 0); end if; end if; -- ----------------------------------------------------------------------------------- -- Clears mult_a and mult_a_pre1 (this is the next variable to be used by register_a1) -- whenever clear signal is triggered -- -- If clock is triggered or register is not used, assign mult_a to mult_a_pre0 -- -- Check make sure that register_a1 doesnt use the same clock as register_a0, -- or if register_a0 is unregistered -- If so, then update mult_a_pre1 with mult_a_pre0 to be used for register_a1 -- -- if nothing happens (ie. clock/clear is not triggered), -- then update mult_a_pre1 with the current value of mult_a -- ----------------------------------------------------------------------------------- if ((((input_aclr_a0 = "ACLR0") and (aclr0 = '1')) or ((input_aclr_a0 = "ACLR1") and (aclr1 = '1')) or ((input_aclr_a0 = "ACLR2") and (aclr2 = '1')) or ((input_aclr_a0 = "ACLR3") and (aclr3 = '1'))) and (not (input_register_a0 = "UNREGISTERED"))) then mult_a(int_width_a-1 downto 0) <= (others => '0'); mult_a_pre1(int_width_a-1 downto 0) := (others => '0'); elsif (((input_register_a0 = "CLOCK0") and rising_edge(clock0)) or ((input_register_a0 = "CLOCK1") and rising_edge(clock1)) or ((input_register_a0 = "CLOCK2") and rising_edge(clock2)) or ((input_register_a0 = "CLOCK3") and rising_edge(clock3)) or (input_register_a0 = "UNREGISTERED")) then if (((input_register_a0 = "CLOCK0") and (ena0 = '1')) or ((input_register_a0 = "CLOCK1") and (ena1 = '1')) or ((input_register_a0 = "CLOCK2") and (ena2 = '1')) or ((input_register_a0 = "CLOCK3") and (ena3 = '1')) or (input_register_a0 = "UNREGISTERED")) then mult_a (int_width_a-1 downto 0) <= mult_a_pre0 (int_width_a-1 downto 0); if ((not(input_register_a0 = input_register_a1)) or (input_register_a0 = "UNREGISTERED")) then mult_a_pre1 (int_width_a-1 downto 0) := mult_a_pre0 (int_width_a-1 downto 0); end if; end if; else mult_a_pre1 (int_width_a-1 downto 0) := tmp_mult_a (int_width_a-1 downto 0); end if; -- ----------------- -- INPUT_REGISTER_A1 -- ----------------- -- set the initial value for mult_a_pre1 from dataa_int if input source is from dataa -- otherwise, load it from the mult_a_pre1 that stored the previous value from register_a0 if (input_source_a1 = "DATAA") then if (mult1_source_scanin_en = '1') then mult_a_pre1 ((2)*int_width_a-1 downto (int_width_a)) := mult_a_pre1(int_width_a-1 downto 0); else mult_a_pre1 ((2)*int_width_a-1 downto (int_width_a)) := dataa_int ((2)*int_width_a-1 downto (int_width_a)); end if; elsif (input_source_a1 = "SCANA") then mult_a_pre1 ((2)*int_width_a-1 downto (int_width_a)) := mult_a_pre1(int_width_a-1 downto 0); else if (sourcea_wire(1) = '1') then mult_a_pre1 ((2)*int_width_a-1 downto (int_width_a)) := mult_a_pre1(int_width_a-1 downto 0); else mult_a_pre1 ((2)*int_width_a-1 downto (int_width_a)) := dataa_int ((2)*int_width_a-1 downto (int_width_a)); end if; end if; -- ----------------------------------------------------------------------------------- -- Clears mult_a and mult_a_pre2 (this is the next variable to be used by register_a2) -- whenever clear signal is triggered -- -- If clock is triggered or register is not used, assign mult_a to mult_a_pre1 -- -- Check make sure that register_a1 doesnt use the same clock as register_a2, -- or if register_a1 is unregistered -- If so, then update mult_a_pre2 with mult_a_pre1 to be used for register_a2 -- -- if nothing happens (ie. clock/clear is not triggered), -- then update mult_a_pre2 with the current value of mult_a -- ----------------------------------------------------------------------------------- if ((((input_aclr_a1 = "ACLR0") and (aclr0 = '1')) or ((input_aclr_a1 = "ACLR1") and (aclr1 = '1')) or ((input_aclr_a1 = "ACLR2") and (aclr2 = '1')) or ((input_aclr_a1 = "ACLR3") and (aclr3 = '1'))) and (not (input_register_a1 = "UNREGISTERED"))) then mult_a ((2)*int_width_a-1 downto (int_width_a)) <= (others => '0'); mult_a_pre2 ((2)*int_width_a-1 downto (int_width_a)) := (others => '0'); elsif (((input_register_a1 = "CLOCK0") and rising_edge(clock0)) or ((input_register_a1 = "CLOCK1") and rising_edge(clock1)) or ((input_register_a1 = "CLOCK2") and rising_edge(clock2)) or ((input_register_a1 = "CLOCK3") and rising_edge(clock3)) or (input_register_a1 = "UNREGISTERED")) then if (((input_register_a1 = "CLOCK0") and (ena0 = '1')) or ((input_register_a1 = "CLOCK1") and (ena1 = '1')) or ((input_register_a1 = "CLOCK2") and (ena2 = '1')) or ((input_register_a1 = "CLOCK3") and (ena3 = '1')) or (input_register_a1 = "UNREGISTERED")) then mult_a ((2)*int_width_a-1 downto (int_width_a)) <= mult_a_pre1 ((2)*int_width_a-1 downto int_width_a); if ((not(input_register_a1 = input_register_a2)) or (input_register_a1 = "UNREGISTERED")) then mult_a_pre2 ((2)*int_width_a-1 downto (int_width_a)) := mult_a_pre1 ((2)*int_width_a-1 downto int_width_a); end if; end if; else mult_a_pre2 ((2)*int_width_a-1 downto (int_width_a)) := tmp_mult_a ((2)*int_width_a-1 downto (int_width_a)); end if; -- ----------------- -- INPUT_REGISTER_A2 -- ----------------- -- set the initial value for mult_a_pre2 from dataa_int if input source is from dataa -- otherwise, load it from the mult_a_pre2 that stored the previous value from register_a1 if (input_source_a2 = "DATAA") then if (mult2_source_scanin_en = '1') then mult_a_pre2 ((3)*int_width_a-1 downto (2*int_width_a)) := mult_a_pre2((2)*int_width_a-1 downto (int_width_a)); else mult_a_pre2 ((3)*int_width_a-1 downto (2*int_width_a)) := dataa_int ((3)*int_width_a-1 downto (2*int_width_a)); end if; elsif (input_source_a2 = "SCANA") then mult_a_pre2 ((3)*int_width_a-1 downto (2*int_width_a)) := mult_a_pre2((2)*int_width_a-1 downto (int_width_a)); else if (sourcea_wire(2) = '1') then mult_a_pre2 ((3)*int_width_a-1 downto (2*int_width_a)) := mult_a_pre2((2)*int_width_a-1 downto (int_width_a)); else mult_a_pre2 ((3)*int_width_a-1 downto (2*int_width_a)) := dataa_int ((3)*int_width_a-1 downto (2*int_width_a)); end if; end if; -- ----------------------------------------------------------------------------------- -- Clears mult_a and mult_a_pre3 (this is the next variable to be used by register_a3) -- whenever clear signal is triggered -- -- If clock is triggered or register is not used, assign mult_a to mult_a_pre2 -- -- Check make sure that register_a2 doesnt use the same clock as register_a3, -- or if register_a2 is unregistered -- If so, then update mult_a_pre3 with mult_a_pre2 to be used for register_a3 -- -- if nothing happens (ie. clock/clear is not triggered), -- then update mult_a_pre3 with the current value of mult_a -- ----------------------------------------------------------------------------------- if ((((input_aclr_a2 = "ACLR0") and (aclr0 = '1')) or ((input_aclr_a2 = "ACLR1") and (aclr1 = '1')) or ((input_aclr_a2 = "ACLR2") and (aclr2 = '1')) or ((input_aclr_a2 = "ACLR3") and (aclr3 = '1'))) and (not (input_register_a2 = "UNREGISTERED"))) then mult_a ((3)*int_width_a-1 downto (2*int_width_a)) <= (others => '0'); mult_a_pre3 ((3)*int_width_a-1 downto (2*int_width_a)) := (others => '0'); elsif (((input_register_a2 = "CLOCK0") and rising_edge(clock0)) or ((input_register_a2 = "CLOCK1") and rising_edge(clock1)) or ((input_register_a2 = "CLOCK2") and rising_edge(clock2)) or ((input_register_a2 = "CLOCK3") and rising_edge(clock3)) or (input_register_a2 = "UNREGISTERED")) then if (((input_register_a2 = "CLOCK0") and (ena0 = '1')) or ((input_register_a2 = "CLOCK1") and (ena1 = '1')) or ((input_register_a2 = "CLOCK2") and (ena2 = '1')) or ((input_register_a2 = "CLOCK3") and (ena3 = '1')) or (input_register_a2 = "UNREGISTERED")) then mult_a ((3)*int_width_a-1 downto (2*int_width_a)) <= mult_a_pre2 ((3)*int_width_a-1 downto (2*int_width_a)); if ((not(input_register_a2 = input_register_a3)) or (input_register_a2 = "UNREGISTERED")) then mult_a_pre3 ((3)*int_width_a-1 downto (2*int_width_a)) := mult_a_pre2 ((3)*int_width_a-1 downto (2*int_width_a)); end if; end if; else mult_a_pre3 ((3)*int_width_a-1 downto (2*int_width_a)) := tmp_mult_a ((3)*int_width_a-1 downto (2*int_width_a)); end if; -- ----------------- -- INPUT_REGISTER_A3 -- ----------------- -- set the initial value for mult_a_pre3 from dataa_int if input source is from dataa -- otherwise, load it from the mult_a_pre3 that stored the previous value from register_a2 if (input_source_a3 = "DATAA") then if (mult3_source_scanin_en = '1') then mult_a_pre3 ((4)*int_width_a-1 downto (3*int_width_a)) := mult_a_pre3 ((3)*int_width_a-1 downto (2*int_width_a)); else mult_a_pre3 ((4)*int_width_a-1 downto (3*int_width_a)) := dataa_int ((4)*int_width_a-1 downto (3*int_width_a)); end if; elsif (input_source_a3 = "SCANA") then mult_a_pre3 ((4)*int_width_a-1 downto (3*int_width_a)) := mult_a_pre3 ((3)*int_width_a-1 downto (2*int_width_a)); else if (sourcea_wire(3) = '1') then mult_a_pre3 ((4)*int_width_a-1 downto (3*int_width_a)) := mult_a_pre3 ((3)*int_width_a-1 downto (2*int_width_a)); else mult_a_pre3 ((4)*int_width_a-1 downto (3*int_width_a)) := dataa_int ((4)*int_width_a-1 downto (3*int_width_a)); end if; end if; -- ----------------------------------------------------------------------------------- -- Clears mult_a whenever clear signal is triggered -- If clock is triggered or register is not used, assign mult_a to mult_a_pre3 -- ----------------------------------------------------------------------------------- if ((((input_aclr_a3 = "ACLR0") and (aclr0 = '1')) or ((input_aclr_a3 = "ACLR1") and (aclr1 = '1')) or ((input_aclr_a3 = "ACLR2") and (aclr2 = '1')) or ((input_aclr_a3 = "ACLR3") and (aclr3 = '1'))) and (not (input_register_a3 = "UNREGISTERED"))) then mult_a ((4)*int_width_a-1 downto (3*int_width_a)) <= (others => '0'); elsif (((input_register_a3 = "CLOCK0") and rising_edge(clock0)) or ((input_register_a3 = "CLOCK1") and rising_edge(clock1)) or ((input_register_a3 = "CLOCK2") and rising_edge(clock2)) or ((input_register_a3 = "CLOCK3") and rising_edge(clock3)) or (input_register_a3 = "UNREGISTERED")) then if (((input_register_a3 = "CLOCK0") and (ena0 = '1')) or ((input_register_a3 = "CLOCK1") and (ena1 = '1')) or ((input_register_a3 = "CLOCK2") and (ena2 = '1')) or ((input_register_a3 = "CLOCK3") and (ena3 = '1')) or (input_register_a3 = "UNREGISTERED")) then mult_a ((4)*int_width_a-1 downto (3*int_width_a)) <= mult_a_pre3 ((4)*int_width_a-1 downto (3*int_width_a)); end if; end if; -- --------------------------------------------- -- SETTING UP THE DATA INPUT REGISTERS OF PORT B -- --------------------------------------------- -- ----------------- -- INPUT_REGISTER_B0 -- ----------------- -- set the initial value for mult_b_pre0 from datab_int if (input_source_b0 = "DATAB") then mult_b_pre0 (int_width_b-1 downto 0) := datab_int (int_width_b-1 downto 0); elsif (input_source_b0 = "SCANB") then if (stratixii_block) then mult_b_pre0 (int_width_b-1 downto 0) := scaninb_var; else mult_b_pre0 (int_width_b-1 downto 0) := datab_int (int_width_b-1 downto 0); end if; elsif (stratixiii_block and (input_source_b0 = "LOOPBACK")) then mult_b_pre0 (int_width_b - 1 downto 0) := feedback; else if (sourceb_wire(0) = '1') then mult_b_pre0 (int_width_b-1 downto 0) := scaninb_var; else mult_b_pre0 (int_width_b-1 downto 0) := datab_int (int_width_b-1 downto 0); end if; end if; -- ----------------------------------------------------------------------------------- -- Clears mult_b and mult_b_pre1 (this is the next variable to be used by register_b1) -- whenever clear signal is triggered -- -- If clock is triggered or register is not used, assign mult_b to mult_b_pre0 -- -- Check make sure that register_b1 doesnt use the same clock as register_b0, -- or if register_b0 is unregistered -- If so, then update mult_b_pre1 with mult_b_pre0 to be used for register_b1 -- -- if nothing happens (ie. clock/clear is not triggered), -- then update mult_b_pre1 with the current value of mult_b -- ----------------------------------------------------------------------------------- if ((((input_aclr_b0 = "ACLR0") and (aclr0 = '1')) or ((input_aclr_b0 = "ACLR1") and (aclr1 = '1')) or ((input_aclr_b0 = "ACLR2") and (aclr2 = '1')) or ((input_aclr_b0 = "ACLR3") and (aclr3 = '1'))) and (not (input_register_b0 = "UNREGISTERED"))) then mult_b (int_width_b-1 downto 0) <= (others => '0'); mult_b_pre1 (int_width_b-1 downto 0) := (others => '0'); elsif (((input_register_b0 = "CLOCK0") and rising_edge(clock0)) or ((input_register_b0 = "CLOCK1") and rising_edge(clock1)) or ((input_register_b0 = "CLOCK2") and rising_edge(clock2)) or ((input_register_b0 = "CLOCK3") and rising_edge(clock3)) or (input_register_b0 = "UNREGISTERED")) then if (((input_register_b0 = "CLOCK0") and (ena0 = '1')) or ((input_register_b0 = "CLOCK1") and (ena1 = '1')) or ((input_register_b0 = "CLOCK2") and (ena2 = '1')) or ((input_register_b0 = "CLOCK3") and (ena3 = '1')) or (input_register_b0 = "UNREGISTERED")) then mult_b (int_width_b-1 downto 0) <= mult_b_pre0 (int_width_b-1 downto 0); if ((not(input_register_b0 = input_register_b1)) or (input_register_b0 = "UNREGISTERED")) then mult_b_pre1 (int_width_b-1 downto 0) := mult_b_pre0 (int_width_b-1 downto 0); end if; end if; else mult_b_pre1 (int_width_b-1 downto 0) := tmp_mult_b (int_width_b-1 downto 0); end if; -- ----------------- -- INPUT_REGISTER_B1 -- ----------------- -- set the initial value for mult_b_pre1 from datab_int if input source is from datab -- otherwise, load it from the mult_b_pre1 that stored the previous value from register_b0 if (input_source_b1 = "DATAB") then -- if loopback mode is used, the data input for b1 comes from datab[width_b-1 to 0] if (input_source_b0 = "LOOPBACK") then mult_b_pre1 ((2)*int_width_b-1 downto (int_width_b)) := datab_int (int_width_b-1 downto 0); else mult_b_pre1 ((2)*int_width_b-1 downto (int_width_b)) := datab_int ((2)*int_width_b-1 downto (int_width_b)); end if; elsif (input_source_b1 = "SCANB") then if (mult1_source_scanin_en = '1') then mult_b_pre1 ((2)*int_width_b-1 downto (int_width_b)) := datab_int ((2)*int_width_b-1 downto (int_width_b)); else mult_b_pre1 ((2)*int_width_b-1 downto (int_width_b)) := mult_b_pre1 (int_width_b-1 downto 0); end if; else if (sourceb_wire(1) = '1') then mult_b_pre1 ((2)*int_width_b-1 downto (int_width_b)) := mult_b_pre1 (int_width_b-1 downto 0); else mult_b_pre1 ((2)*int_width_b-1 downto (int_width_b)) := datab_int ((2)*int_width_b-1 downto (int_width_b)); end if; end if; -- ----------------------------------------------------------------------------------- -- Clears mult_b and mult_b_pre2 (this is the next variable to be used by register_b2) -- whenever clear signal is triggered -- -- If clock is triggered or register is not used, assign mult_b to mult_b_pre1 -- -- Check make sure that register_a1 doesnt use the same clock as register_b2, -- or if register_b1 is unregistered -- If so, then update mult_b_pre2 with mult_b_pre1 to be used for register_b2 -- -- if nothing happens (ie. clock/clear is not triggered), -- then update mult_b_pre2 with the current value of mult_b -- ----------------------------------------------------------------------------------- if ((((input_aclr_b1 = "ACLR0") and (aclr0 = '1')) or ((input_aclr_b1 = "ACLR1") and (aclr1 = '1')) or ((input_aclr_b1 = "ACLR2") and (aclr2 = '1')) or ((input_aclr_b1 = "ACLR3") and (aclr3 = '1'))) and (not (input_register_b1 = "UNREGISTERED"))) then mult_b ((2)*int_width_b-1 downto (int_width_b)) <= (others => '0'); mult_b_pre2 ((2)*int_width_b-1 downto (int_width_b)) := (others => '0'); elsif (((input_register_b1 = "CLOCK0") and rising_edge(clock0)) or ((input_register_b1 = "CLOCK1") and rising_edge(clock1)) or ((input_register_b1 = "CLOCK2") and rising_edge(clock2)) or ((input_register_b1 = "CLOCK3") and rising_edge(clock3)) or (input_register_b1 = "UNREGISTERED")) then if (((input_register_b1 = "CLOCK0") and (ena0 = '1')) or ((input_register_b1 = "CLOCK1") and (ena1 = '1')) or ((input_register_b1 = "CLOCK2") and (ena2 = '1')) or ((input_register_b1 = "CLOCK3") and (ena3 = '1')) or (input_register_b1 = "UNREGISTERED")) then mult_b ((2)*int_width_b-1 downto (int_width_b)) <= mult_b_pre1 ((2)*int_width_b-1 downto int_width_b); if ((not(input_register_b1 = input_register_b2)) or (input_register_b1 = "UNREGISTERED")) then mult_b_pre2 ((2)*int_width_b-1 downto (int_width_b)) := mult_b_pre1 ((2)*int_width_b-1 downto int_width_b); end if; end if; else mult_b_pre2 ((2)*int_width_b-1 downto (int_width_b)) := tmp_mult_b ((2)*int_width_b-1 downto (int_width_b)); end if; -- ----------------- -- INPUT_REGISTER_B2 -- ----------------- -- set the initial value for mult_b_pre2 from datab_int if input source is from datab -- otherwise, load it from the mult_b_pre2 that stored the previous value from register_b1 if (input_source_b2 = "DATAB") then if (input_source_b0 = "LOOPBACK") then mult_b_pre2 ((3)*int_width_b-1 downto (2*int_width_b)) := datab_int ((2*int_width_b) -1 downto int_width_b); else mult_b_pre2 ((3)*int_width_b-1 downto (2*int_width_b)) := datab_int ((3)*int_width_b-1 downto (2*int_width_b)); end if; elsif (input_source_b2 = "SCANB") then if (mult2_source_scanin_en = '1') then mult_b_pre2 ((3)*int_width_b-1 downto (2*int_width_b)) := datab_int ((3)*int_width_b-1 downto (2*int_width_b)); else mult_b_pre2 ((3)*int_width_b-1 downto (2*int_width_b)) := mult_b_pre2 ((2)*int_width_b-1 downto (int_width_b)); end if; else if (sourceb_wire(2) = '1') then mult_b_pre2 ((3)*int_width_b-1 downto (2*int_width_b)) := mult_b_pre2 ((2)*int_width_b-1 downto (int_width_b)); else mult_b_pre2 ((3)*int_width_b-1 downto (2*int_width_b)) := datab_int ((3)*int_width_b-1 downto (2*int_width_b)); end if; end if; -- ----------------------------------------------------------------------------------- -- Clears mult_b and mult_b_pre3 (this is the next variable to be used by register_b3) -- whenever clear signal is triggered -- -- If clock is triggered or register is not used, assign mult_b to mult_b_pre2 -- -- Check make sure that register_b2 doesnt use the same clock as register_b3, -- or if register_b2 is unregistered -- If so, then update mult_b_pre3 with mult_b_pre2 to be used for register_b3 -- -- if nothing happens (ie. clock/clear is not triggered), -- then update mult_b_pre3 with the current value of mult_b -- ----------------------------------------------------------------------------------- if ((((input_aclr_b2 = "ACLR0") and (aclr0 = '1')) or ((input_aclr_b2 = "ACLR1") and (aclr1 = '1')) or ((input_aclr_b2 = "ACLR2") and (aclr2 = '1')) or ((input_aclr_b2 = "ACLR3") and (aclr3 = '1'))) and (not (input_register_b2 = "UNREGISTERED"))) then mult_b ((3)*int_width_b-1 downto (2*int_width_b)) <= (others => '0'); mult_b_pre3 ((3)*int_width_b-1 downto (2*int_width_b)) := (others => '0'); elsif (((input_register_b2 = "CLOCK0") and rising_edge(clock0)) or ((input_register_b2 = "CLOCK1") and rising_edge(clock1)) or ((input_register_b2 = "CLOCK2") and rising_edge(clock2)) or ((input_register_b2 = "CLOCK3") and rising_edge(clock3)) or (input_register_b2 = "UNREGISTERED")) then if (((input_register_b2 = "CLOCK0") and (ena0 = '1')) or ((input_register_b2 = "CLOCK1") and (ena1 = '1')) or ((input_register_b2 = "CLOCK2") and (ena2 = '1')) or ((input_register_b2 = "CLOCK3") and (ena3 = '1')) or (input_register_b2 = "UNREGISTERED")) then mult_b ((3)*int_width_b-1 downto (2*int_width_b)) <= mult_b_pre2 ((3)*int_width_b-1 downto (2*int_width_b)); if ((not(input_register_b2 = input_register_b3)) or (input_register_b2 = "UNREGISTERED")) then mult_b_pre3 ((3)*int_width_b-1 downto (2*int_width_b)) := mult_b_pre2 ((3)*int_width_b-1 downto (2*int_width_b)); end if; end if; else mult_b_pre3 ((3)*int_width_b-1 downto (2*int_width_b)) := tmp_mult_b ((3)*int_width_b-1 downto (2*int_width_b)); end if; -- ----------------- -- INPUT_REGISTER_B3 -- ----------------- -- set the initial value for mult_b_pre3 from datab_int if input source is from datab -- otherwise, load it from the mult_b_pre3 that stored the previous value from register_b2 if (input_source_b3 = "DATAB") then if (input_source_b0 = "LOOPBACK") then mult_b_pre3 ((4)*int_width_b-1 downto (3*int_width_b)) := datab_int ((3)*int_width_b-1 downto (2*int_width_b)); else mult_b_pre3 ((4)*int_width_b-1 downto (3*int_width_b)) := datab_int ((4)*int_width_b-1 downto (3*int_width_b)); end if; elsif (input_source_b3 = "SCANB") then if (mult3_source_scanin_en = '1') then mult_b_pre3 ((4)*int_width_b-1 downto (3*int_width_b)) := datab_int ((4)*int_width_b-1 downto (3*int_width_b)); else mult_b_pre3 ((4)*int_width_b-1 downto (3*int_width_b)) := mult_b_pre3 ((3)*int_width_b-1 downto (2*int_width_b)); end if; else if (sourceb_wire(3) = '1') then mult_b_pre3 ((4)*int_width_b-1 downto (3*int_width_b)) := mult_b_pre3 ((3)*int_width_b-1 downto (2*int_width_b)); else mult_b_pre3 ((4)*int_width_b-1 downto (3*int_width_b)) := datab_int ((4)*int_width_b-1 downto (3*int_width_b)); end if; end if; -- ----------------------------------------------------------------------------------- -- Clears mult_b whenever clear signal is triggered -- If clock is triggered or register is not used, assign mult_b to mult_b_pre3 -- ----------------------------------------------------------------------------------- if ((((input_aclr_b3 = "ACLR0") and (aclr0 = '1')) or ((input_aclr_b3 = "ACLR1") and (aclr1 = '1')) or ((input_aclr_b3 = "ACLR2") and (aclr2 = '1')) or ((input_aclr_b3 = "ACLR3") and (aclr3 = '1'))) and (not (input_register_b3 = "UNREGISTERED"))) then mult_b ((4)*int_width_b-1 downto (3*int_width_b)) <= (others => '0'); elsif (((input_register_b3 = "CLOCK0") and rising_edge(clock0)) or ((input_register_b3 = "CLOCK1") and rising_edge(clock1)) or ((input_register_b3 = "CLOCK2") and rising_edge(clock2)) or ((input_register_b3 = "CLOCK3") and rising_edge(clock3)) or (input_register_b3 = "UNREGISTERED")) then if (((input_register_b3 = "CLOCK0") and (ena0 = '1')) or ((input_register_b3 = "CLOCK1") and (ena1 = '1')) or ((input_register_b3 = "CLOCK2") and (ena2 = '1')) or ((input_register_b3 = "CLOCK3") and (ena3 = '1')) or (input_register_b3 = "UNREGISTERED")) then mult_b ((4)*int_width_b-1 downto (3*int_width_b)) <= mult_b_pre3 ((4)*int_width_b-1 downto (3*int_width_b)); end if; end if; end process; -- ----------------------------------------------------------------------- -- This process block performs the rounding and saturation control signal -- setting -- ----------------------------------------------------------------------- -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set mult01_round_wire) -- The signal registered is mult01_round -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if mult01_round_register -- is unregistered and mult01_round changes value -- --------------------------------------------------------------------------------- G9: if (mult01_round_register = "UNREGISTERED") generate mult01_round_wire <= mult01_round; end generate G9; IFG41: if (mult01_round_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, mult01_round) begin if (((mult01_round_aclr= "ACLR0") and (aclr0 = '1')) or ((mult01_round_aclr= "ACLR1") and (aclr1 = '1')) or ((mult01_round_aclr= "ACLR2") and (aclr2 = '1')) or ((mult01_round_aclr= "ACLR3") and (aclr3 = '1'))) then mult01_round_wire <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then mult01_round_wire <= mult01_round; end if; end if; end process; end generate IFG41; IFG42: if (mult01_round_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, mult01_round) begin if (((mult01_round_aclr= "ACLR0") and (aclr0 = '1')) or ((mult01_round_aclr= "ACLR1") and (aclr1 = '1')) or ((mult01_round_aclr= "ACLR2") and (aclr2 = '1')) or ((mult01_round_aclr= "ACLR3") and (aclr3 = '1'))) then mult01_round_wire <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then mult01_round_wire <= mult01_round; end if; end if; end process; end generate IFG42; IFG43: if (mult01_round_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, mult01_round) begin if (((mult01_round_aclr= "ACLR0") and (aclr0 = '1')) or ((mult01_round_aclr= "ACLR1") and (aclr1 = '1')) or ((mult01_round_aclr= "ACLR2") and (aclr2 = '1')) or ((mult01_round_aclr= "ACLR3") and (aclr3 = '1'))) then mult01_round_wire <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then mult01_round_wire <= mult01_round; end if; end if; end process; end generate IFG43; IFG44: if (mult01_round_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, mult01_round) begin if (((mult01_round_aclr = "ACLR0") and (aclr0 = '1')) or ((mult01_round_aclr = "ACLR1") and (aclr1 = '1')) or ((mult01_round_aclr = "ACLR2") and (aclr2 = '1')) or ((mult01_round_aclr = "ACLR3") and (aclr3 = '1'))) then mult01_round_wire <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then mult01_round_wire <= mult01_round; end if; end if; end process; end generate IFG44; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set mult01_saturate_wire) -- The signal registered is mult01_saturation -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if mult01_saturate_register -- is unregistered and mult01_saturation changes value -- --------------------------------------------------------------------------------- G10: if (mult01_saturation_register = "UNREGISTERED") generate mult01_saturate_wire <= mult01_saturation; end generate G10; IFG45: if (mult01_saturation_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, mult01_saturation) begin if (((mult01_saturation_aclr= "ACLR0") and (aclr0 = '1')) or ((mult01_saturation_aclr= "ACLR1") and (aclr1 = '1')) or ((mult01_saturation_aclr= "ACLR2") and (aclr2 = '1')) or ((mult01_saturation_aclr= "ACLR3") and (aclr3 = '1'))) then mult01_saturate_wire <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then mult01_saturate_wire <= mult01_saturation; end if; end if; end process; end generate IFG45; IFG46: if (mult01_saturation_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, mult01_saturation) begin if (((mult01_saturation_aclr= "ACLR0") and (aclr0 = '1')) or ((mult01_saturation_aclr= "ACLR1") and (aclr1 = '1')) or ((mult01_saturation_aclr= "ACLR2") and (aclr2 = '1')) or ((mult01_saturation_aclr= "ACLR3") and (aclr3 = '1'))) then mult01_saturate_wire <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then mult01_saturate_wire <= mult01_saturation; end if; end if; end process; end generate IFG46; IFG47: if (mult01_saturation_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, mult01_saturation) begin if (((mult01_saturation_aclr= "ACLR0") and (aclr0 = '1')) or ((mult01_saturation_aclr= "ACLR1") and (aclr1 = '1')) or ((mult01_saturation_aclr= "ACLR2") and (aclr2 = '1')) or ((mult01_saturation_aclr= "ACLR3") and (aclr3 = '1'))) then mult01_saturate_wire <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then mult01_saturate_wire <= mult01_saturation; end if; end if; end process; end generate IFG47; IFG48: if (mult01_saturation_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, mult01_saturation) begin if (((mult01_saturation_aclr = "ACLR0") and (aclr0 = '1')) or ((mult01_saturation_aclr = "ACLR1") and (aclr1 = '1')) or ((mult01_saturation_aclr = "ACLR2") and (aclr2 = '1')) or ((mult01_saturation_aclr = "ACLR3") and (aclr3 = '1'))) then mult01_saturate_wire <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then mult01_saturate_wire <= mult01_saturation; end if; end if; end process; end generate IFG48; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set mult23_round_wire) -- The signal registered is mult23_round -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if mult23_round_register -- is unregistered and mult23_round changes value -- --------------------------------------------------------------------------------- G11: if (mult23_round_register = "UNREGISTERED") generate mult23_round_wire <= mult23_round; end generate G11; IFG49: if (mult23_round_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, mult23_round) begin if (((mult23_round_aclr= "ACLR0") and (aclr0 = '1')) or ((mult23_round_aclr= "ACLR1") and (aclr1 = '1')) or ((mult23_round_aclr= "ACLR2") and (aclr2 = '1')) or ((mult23_round_aclr= "ACLR3") and (aclr3 = '1'))) then mult23_round_wire <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then mult23_round_wire <= mult23_round; end if; end if; end process; end generate IFG49; IFG50: if (mult23_round_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, mult23_round) begin if (((mult23_round_aclr= "ACLR0") and (aclr0 = '1')) or ((mult23_round_aclr= "ACLR1") and (aclr1 = '1')) or ((mult23_round_aclr= "ACLR2") and (aclr2 = '1')) or ((mult23_round_aclr= "ACLR3") and (aclr3 = '1'))) then mult23_round_wire <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then mult23_round_wire <= mult23_round; end if; end if; end process; end generate IFG50; IFG51: if (mult23_round_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, mult23_round) begin if (((mult23_round_aclr= "ACLR0") and (aclr0 = '1')) or ((mult23_round_aclr= "ACLR1") and (aclr1 = '1')) or ((mult23_round_aclr= "ACLR2") and (aclr2 = '1')) or ((mult23_round_aclr= "ACLR3") and (aclr3 = '1'))) then mult23_round_wire <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then mult23_round_wire <= mult23_round; end if; end if; end process; end generate IFG51; IFG52: if (mult23_round_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, mult23_round) begin if (((mult23_round_aclr = "ACLR0") and (aclr0 = '1')) or ((mult23_round_aclr = "ACLR1") and (aclr1 = '1')) or ((mult23_round_aclr = "ACLR2") and (aclr2 = '1')) or ((mult23_round_aclr = "ACLR3") and (aclr3 = '1'))) then mult23_round_wire <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then mult23_round_wire <= mult23_round; end if; end if; end process; end generate IFG52; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set mult23_saturate_wire) -- The signal registered is mult23_saturation -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if mult23_saturate_register -- is unregistered and mult23_saturation changes value -- --------------------------------------------------------------------------------- G12: if (mult23_saturation_register = "UNREGISTERED") generate mult23_saturate_wire <= mult23_saturation; end generate G12; IFG53: if (mult23_saturation_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, mult23_saturation) begin if (((mult23_saturation_aclr= "ACLR0") and (aclr0 = '1')) or ((mult23_saturation_aclr= "ACLR1") and (aclr1 = '1')) or ((mult23_saturation_aclr= "ACLR2") and (aclr2 = '1')) or ((mult23_saturation_aclr= "ACLR3") and (aclr3 = '1'))) then mult23_saturate_wire <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then mult23_saturate_wire <= mult23_saturation; end if; end if; end process; end generate IFG53; IFG54: if (mult23_saturation_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, mult23_saturation) begin if (((mult23_saturation_aclr= "ACLR0") and (aclr0 = '1')) or ((mult23_saturation_aclr= "ACLR1") and (aclr1 = '1')) or ((mult23_saturation_aclr= "ACLR2") and (aclr2 = '1')) or ((mult23_saturation_aclr= "ACLR3") and (aclr3 = '1'))) then mult23_saturate_wire <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then mult23_saturate_wire <= mult23_saturation; end if; end if; end process; end generate IFG54; IFG55: if (mult23_saturation_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, mult23_saturation) begin if (((mult23_saturation_aclr= "ACLR0") and (aclr0 = '1')) or ((mult23_saturation_aclr= "ACLR1") and (aclr1 = '1')) or ((mult23_saturation_aclr= "ACLR2") and (aclr2 = '1')) or ((mult23_saturation_aclr= "ACLR3") and (aclr3 = '1'))) then mult23_saturate_wire <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then mult23_saturate_wire <= mult23_saturation; end if; end if; end process; end generate IFG55; IFG56: if (mult23_saturation_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, mult23_saturation) begin if (((mult23_saturation_aclr = "ACLR0") and (aclr0 = '1')) or ((mult23_saturation_aclr = "ACLR1") and (aclr1 = '1')) or ((mult23_saturation_aclr = "ACLR2") and (aclr2 = '1')) or ((mult23_saturation_aclr = "ACLR3") and (aclr3 = '1'))) then mult23_saturate_wire <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then mult23_saturate_wire <= mult23_saturation; end if; end if; end process; end generate IFG56; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set addnsub1_round_wire) -- The signal registered is addnsub1_round -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if addnsub1_round_register -- is unregistered and addnsub1_round changes value -- --------------------------------------------------------------------------------- G13: if (addnsub1_round_register = "UNREGISTERED") generate addnsub1_round_wire <= addnsub1_round; end generate G13; IFG57: if (addnsub1_round_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, addnsub1_round) begin if (((addnsub1_round_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub1_round_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub1_round_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub1_round_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub1_round_wire <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then addnsub1_round_wire <= addnsub1_round; end if; end if; end process; end generate IFG57; IFG58: if (addnsub1_round_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, addnsub1_round) begin if (((addnsub1_round_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub1_round_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub1_round_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub1_round_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub1_round_wire <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then addnsub1_round_wire <= addnsub1_round; end if; end if; end process; end generate IFG58; IFG59: if (addnsub1_round_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, addnsub1_round) begin if (((addnsub1_round_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub1_round_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub1_round_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub1_round_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub1_round_wire <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then addnsub1_round_wire <= addnsub1_round; end if; end if; end process; end generate IFG59; IFG60: if (addnsub1_round_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, addnsub1_round) begin if (((addnsub1_round_aclr = "ACLR0") and (aclr0 = '1')) or ((addnsub1_round_aclr = "ACLR1") and (aclr1 = '1')) or ((addnsub1_round_aclr = "ACLR2") and (aclr2 = '1')) or ((addnsub1_round_aclr = "ACLR3") and (aclr3 = '1'))) then addnsub1_round_wire <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then addnsub1_round_wire <= addnsub1_round; end if; end if; end process; end generate IFG60; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set addnsub1_round_pipe_wire) -- The signal registered is addnsub1_round_wire -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if addnsub1_round_pipe_register -- is unregistered and addnsub1_round_wire changes value -- --------------------------------------------------------------------------------- G14: if (addnsub1_round_pipeline_register = "UNREGISTERED") generate addnsub1_round_pipe_wire <= addnsub1_round_wire; end generate G14; IFG61: if (addnsub1_round_pipeline_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, addnsub1_round_wire) begin if (((addnsub1_round_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub1_round_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub1_round_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub1_round_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub1_round_pipe_wire <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then addnsub1_round_pipe_wire <= addnsub1_round_wire; end if; end if; end process; end generate IFG61; IFG62: if (addnsub1_round_pipeline_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, addnsub1_round_wire) begin if (((addnsub1_round_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub1_round_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub1_round_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub1_round_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub1_round_pipe_wire <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then addnsub1_round_pipe_wire <= addnsub1_round_wire; end if; end if; end process; end generate IFG62; IFG63: if (addnsub1_round_pipeline_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, addnsub1_round_wire) begin if (((addnsub1_round_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub1_round_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub1_round_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub1_round_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub1_round_pipe_wire <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then addnsub1_round_pipe_wire <= addnsub1_round_wire; end if; end if; end process; end generate IFG63; IFG64: if (addnsub1_round_pipeline_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, addnsub1_round_wire) begin if (((addnsub1_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((addnsub1_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((addnsub1_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((addnsub1_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then addnsub1_round_pipe_wire <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then addnsub1_round_pipe_wire <= addnsub1_round_wire; end if; end if; end process; end generate IFG64; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set addnsub3_round_wire) -- The signal registered is addnsub3_round -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if addnsub3_round_register -- is unregistered and addnsub3_round changes value -- --------------------------------------------------------------------------------- G15: if (addnsub3_round_register = "UNREGISTERED") generate addnsub3_round_wire <= addnsub3_round; end generate G15; IFG65: if (addnsub3_round_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, addnsub3_round) begin if (((addnsub3_round_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub3_round_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub3_round_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub3_round_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub3_round_wire <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then addnsub3_round_wire <= addnsub3_round; end if; end if; end process; end generate IFG65; IFG66: if (addnsub3_round_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, addnsub3_round) begin if (((addnsub3_round_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub3_round_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub3_round_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub3_round_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub3_round_wire <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then addnsub3_round_wire <= addnsub3_round; end if; end if; end process; end generate IFG66; IFG67: if (addnsub3_round_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, addnsub3_round) begin if (((addnsub3_round_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub3_round_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub3_round_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub3_round_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub3_round_wire <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then addnsub3_round_wire <= addnsub3_round; end if; end if; end process; end generate IFG67; IFG68: if (addnsub3_round_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, addnsub3_round) begin if (((addnsub3_round_aclr = "ACLR0") and (aclr0 = '1')) or ((addnsub3_round_aclr = "ACLR1") and (aclr1 = '1')) or ((addnsub3_round_aclr = "ACLR2") and (aclr2 = '1')) or ((addnsub3_round_aclr = "ACLR3") and (aclr3 = '1'))) then addnsub3_round_wire <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then addnsub3_round_wire <= addnsub3_round; end if; end if; end process; end generate IFG68; -- --------------------------------------------------------------------------------- -- This statement contains 1 register and a combinatorial block (to set addnsub3_round_pipe_wire) -- The signal registered is addnsub3_round_wire -- -- The register has an asynchronous clear and a clock enable signal -- NOTE: the combinatorial block is trigged if addnsub3_round_pipeline_register -- is unregistered and addnsub3_round_wire changes value -- --------------------------------------------------------------------------------- G16: if (addnsub3_round_pipeline_register = "UNREGISTERED") generate addnsub3_round_pipe_wire <= addnsub3_round_wire; end generate G16; IFG69: if (addnsub3_round_pipeline_register = "CLOCK0") generate process (clock0, aclr0, aclr1, aclr2, aclr3, addnsub3_round_wire) begin if (((addnsub3_round_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub3_round_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub3_round_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub3_round_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub3_round_pipe_wire <= '0'; elsif rising_edge(clock0) then if ((ena0 ='1')) then addnsub3_round_pipe_wire <= addnsub3_round_wire; end if; end if; end process; end generate IFG69; IFG70: if (addnsub3_round_pipeline_register = "CLOCK1") generate process (clock1, aclr0, aclr1, aclr2, aclr3, addnsub3_round_wire) begin if (((addnsub3_round_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub3_round_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub3_round_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub3_round_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub3_round_pipe_wire <= '0'; elsif rising_edge(clock1) then if ((ena1 ='1')) then addnsub3_round_pipe_wire <= addnsub3_round_wire; end if; end if; end process; end generate IFG70; IFG71: if (addnsub3_round_pipeline_register = "CLOCK2") generate process (clock2, aclr0, aclr1, aclr2, aclr3, addnsub3_round_wire) begin if (((addnsub3_round_pipeline_aclr = "ACLR0") and (aclr0 = '1')) or ((addnsub3_round_pipeline_aclr = "ACLR1") and (aclr1 = '1')) or ((addnsub3_round_pipeline_aclr = "ACLR2") and (aclr2 = '1')) or ((addnsub3_round_pipeline_aclr = "ACLR3") and (aclr3 = '1'))) then addnsub3_round_pipe_wire <= '0'; elsif rising_edge(clock2) then if ((ena2 ='1')) then addnsub3_round_pipe_wire <= addnsub3_round_wire; end if; end if; end process; end generate IFG71; IFG72: if (addnsub3_round_pipeline_register = "CLOCK3") generate process (clock3, aclr0, aclr1, aclr2, aclr3, addnsub3_round_wire) begin if (((addnsub3_round_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or ((addnsub3_round_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or ((addnsub3_round_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or ((addnsub3_round_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then addnsub3_round_pipe_wire <= '0'; elsif rising_edge(clock3) then if ((ena3 ='1')) then addnsub3_round_pipe_wire <= addnsub3_round_wire; end if; end if; end process; end generate IFG72; -- ----------------------------------------------------------------------- -- This process block performs the multiplication of the two input numbers -- ----------------------------------------------------------------------- process (clock0, clock1, clock2, clock3, mult_aclr, mult_a, mult_b, sign_a_reg, sign_b_reg, mult01_round_wire, mult01_saturate_wire, mult23_round_wire, mult23_saturate_wire, mult_clock, is_reg, signa, signb) variable mult_a_int : std_logic_vector (int_width_a -1 downto 0); variable mult_b_int : std_logic_vector (int_width_b -1 downto 0); variable mult_round_out : std_logic_vector (int_width_a + int_width_b - 1 downto 0) := (others => '0'); variable mult_result : std_logic_vector (int_width_a + int_width_b - 1 downto 0) := (others => '0'); variable mult_saturate_overflow : std_logic := '0'; variable mult_saturate_out : std_logic_vector (int_width_a + int_width_b - 1 downto 0) := (others => '0'); variable neg_a : std_logic := '0'; variable neg_b : std_logic := '0'; variable temp_mult_int : std_logic_vector ((int_width_a + int_width_b)-1 downto 0); variable mux_clock : std_logic; variable check_clock_out : string (1 to 6); variable x : integer; variable mult_round_bits : integer; variable zero_pad : std_logic := '0'; variable is_rep_a_sign : std_logic := '1'; variable is_rep_b_sign : std_logic := '1'; begin if (((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_reg = '1'))) or ((port_signa = "PORT_USED") and (sign_a_reg = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED"))) then is_rep_a_sign := '1'; else is_rep_a_sign := '0'; end if; if (((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_reg = '1'))) or ((port_signb = "PORT_USED") and (sign_b_reg = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED"))) then is_rep_b_sign := '1'; else is_rep_b_sign := '0'; end if; for i in 0 to (number_of_multipliers -1) loop x := i; if (i > 3) then x := 3; end if; mux_clock := mult_clock (x); check_clock_out := check_clock (x); if ((not stratixiii_block) and ((is_reg (x) = '1') and (mult_aclr (x) = '1'))) then mult_res ( ((i+1)*(int_width_a + int_width_b)) - 1 downto (i*(int_width_a + int_width_b))) <= (others => '0'); mult_is_saturated(x) <= '0'; elsif ((not stratixiii_block) and (((check_clock_out = "CLOCK0") and rising_edge(clock0)) or ((check_clock_out = "CLOCK1") and rising_edge(clock1)) or ((check_clock_out = "CLOCK2") and rising_edge(clock2)) or ((check_clock_out = "CLOCK3") and rising_edge(clock3)) or (is_reg (x) = '0'))) or (stratixiii_block) then if ((not stratixiii_block) and (((check_clock_out = "CLOCK0") and (ena0 = '1')) or ((check_clock_out = "CLOCK1") and (ena1 = '1')) or ((check_clock_out = "CLOCK2") and (ena2 = '1')) or ((check_clock_out = "CLOCK3") and (ena3 = '1')) or is_reg (x) = '0')) or (stratixiii_block) then neg_a := '0'; neg_b := '0'; -- check if mult_a is to be interpreted as negative if (is_rep_a_sign = '1') then neg_a := mult_a ( (i+1)*int_width_a-1); end if; -- check if mult_b is to be interpreted as negative if (is_rep_b_sign = '1') then if (input_source_b0 = "LOOPBACK" and i=1) then neg_b := mult_b ( (i+1)*int_width_b-1 );-- + (int_width_b - width_b)); else neg_b := mult_b ( (i+1)*int_width_b-1); end if; end if; -- perform 2's complement if mult_a is negative if (neg_a ='1') then mult_a_int := unsigned (not mult_a ( (i+1)*int_width_a-1 downto (i*int_width_a))) + 1; else mult_a_int := mult_a ( (i+1)*int_width_a-1 downto (i*int_width_a)); end if; -- perform 2's complement if mult_b is negative if (neg_b ='1') then if(input_source_b0 = "LOOPBACK" and i=1) then mult_b_int(width_b - 1 downto 0) := unsigned (not mult_b ( (i+1)*int_width_b-1 downto (i*int_width_b + (int_width_b - width_b)))) + 1; else mult_b_int := unsigned (not mult_b ( (i+1)*int_width_b-1 downto (i*int_width_b))) + 1; end if; else if(input_source_b0 = "LOOPBACK" and i=1) then mult_b_int := mult_b ( (i+1)*int_width_b-1 + (int_width_b - width_b) downto (i*int_width_b + (int_width_b - width_b))); else mult_b_int := mult_b ( (i+1)*int_width_b-1 downto (i*int_width_b)); end if; end if; -- perform multiplication temp_mult_int := unsigned (temp_mult_zero) + unsigned(mult_a_int) * unsigned(mult_b_int); -- determining if the result should be a negative number -- based on the 2 input numbers if ((neg_a xor neg_b) = '1') then temp_mult_int := unsigned(temp_mult_zero) - unsigned(temp_mult_int); end if; if (stratixii_block) then -- ------------------------------------------------------- -- Stratix II Rounding support -- This block basically carries out the rounding for the -- temp_mult_int. The equation to get the mult_round_out is -- obtained from the Stratix II Mac FFD which is below: -- round_adder_constant = (1 << (wfraction - wfraction_round - 1)) -- roundout[] = datain[] + round_adder_constant -- For Stratix II rounding, we round up the bits to 15 bits -- or in another word wfraction_round = 15. The sign bits would be 2 bits -- -------------------------------------------------------- if ((((x = 0) or (x = 1)) and ((multiplier01_rounding = "YES") or ((multiplier01_rounding = "VARIABLE") and (mult01_round_wire = '1')))) or (((x = 2) or (x = 3)) and ((multiplier23_rounding = "YES") or ((multiplier23_rounding = "VARIABLE") and (mult23_round_wire = '1'))))) then -- Here the value 17 is from the 2 bits of sign and the rounding for 15 bits mult_round_bits := (int_width_a + int_width_b) - 17; mult_round_out := unsigned (temp_mult_int) + ( 2 ** (mult_round_bits - 1)); else mult_round_out := temp_mult_int; end if; -- ------------------------------------------------------- -- Stratix II Saturation support -- This carries out the saturation for mult_round_out. -- The equation to get the saturated result is obtained -- from Stratix II MAC FFD which is below: -- satoverflow = 1 if sign bit is different -- satvalue[wtotal-1 : wfraction] = roundout[wtotal-1] -- satvalue[wfraction-1 : 0] = !roundout[wtotal-1] -- ------------------------------------------------------- if ((((x = 0) or (x = 1)) and ((multiplier01_saturation = "YES") or (( multiplier01_saturation = "VARIABLE") and (mult01_saturate_wire = '1')))) or (((x = 2) or (x = 3)) and ((multiplier23_saturation = "YES") or (( multiplier23_saturation = "VARIABLE") and (mult23_saturate_wire = '1'))))) then mult_saturate_overflow := (not mult_round_out(int_width_a + int_width_b - 1)) and (mult_round_out(int_width_a + int_width_b - 2)); if (mult_saturate_overflow = '0') then mult_saturate_out := mult_round_out; mult_is_saturated(x) <= mult_round_out(0); else -- We are doing the Q2.31 saturation, thus there is a bit -- insertion over here for i in (int_width_a + int_width_b - 1) downto (int_width_a + int_width_b - 2) loop mult_saturate_out(i) := mult_round_out(int_width_a + int_width_b - 1); end loop; for i in (int_width_a + int_width_b - 3) downto 3 loop mult_saturate_out(i) := not mult_round_out(int_width_a + int_width_b - 1); end loop; mult_saturate_out(2 downto 0) := mult_round_out(2 downto 0); mult_is_saturated(x) <= mult_saturate_overflow; end if; else mult_is_saturated(x) <= mult_saturate_overflow; mult_saturate_out := mult_round_out; end if; if ((((x = 0) or (x = 1)) and ((multiplier01_rounding = "YES") or (( multiplier01_rounding = "VARIABLE") and (mult01_round_wire = '1')))) or (((x = 2) or (x = 3)) and ((multiplier23_rounding = "YES") or (( multiplier23_rounding = "VARIABLE") and (mult23_round_wire = '1'))))) then mult_result := mult_saturate_out; for i in (mult_round_bits - 1) downto 0 loop mult_result(i) := '0'; end loop; else mult_result := mult_saturate_out; end if; else mult_result := temp_mult_int; end if; mult_res ( ((i+1)*(int_width_a + int_width_b)) - 1 downto (i*(int_width_a + int_width_b)) ) <= mult_result; end if; end if; end loop; end process; -- ----------------------------------------------------------------- -- This is the main block that performs the addition and subtraction -- ----------------------------------------------------------------- IFGFAM0: if (not stratixiii_block) generate process (clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3, mult_res, sign_a_reg, sign_b_reg, sign_a_pipe, sign_b_pipe, addsub_pipe1, addsub_pipe3, addsub_reg1, addsub_reg3, addnsub1_round_pipe_wire, addnsub3_round_pipe_wire, mult_is_saturated) variable head_result_int : integer := 0; variable do_add : boolean; variable asign : boolean; variable bsign : boolean; variable temp_sum : std_logic_vector (int_width_a + int_width_b + int_width_result downto 0) := (others => '0'); variable mult_res_temp : std_logic_vector ((int_width_a + int_width_b - 1) downto 0); variable mult_res_ext : std_logic_vector (int_width_result-1 downto 0); variable adder_round_bits: integer; variable adder_result : std_logic_vector (int_width_result downto 0) := (others => '0'); variable adder1_result : std_logic_vector (int_width_result downto 0) := (others => '0'); variable adder3_result : std_logic_vector (int_width_result downto 0) := (others => '0'); variable adder_final_out : std_logic_vector (2*int_width_result - 1 downto 0) := (others => '0'); variable adder_round_out : std_logic_vector (int_width_result downto 0) := (others => '0'); variable is_rep_a_sign : boolean; variable is_rep_b_sign : boolean; variable is_rep_a_pipe_sign : boolean; variable is_rep_b_pipe_sign : boolean; variable is_adder1_add : boolean; variable is_adder3_add : boolean; variable is_adder1_pipe_add : boolean; variable is_adder3_pipe_add : boolean; variable result_temp : std_logic_vector (width_result - 1 downto 0) := (others => '0'); variable result_ext : std_logic_vector (width_result - 1 downto 0) := (others => '0'); variable result_pipe : pipeline_accum := (others => (others => '0')); begin if ((((output_aclr = "ACLR0") and (aclr0 = '1')) or ((output_aclr = "ACLR1") and (aclr1 = '1')) or ((output_aclr = "ACLR2") and (aclr2 = '1')) or ((output_aclr = "ACLR3") and (aclr3 = '1'))) and (not (output_register = "UNREGISTERED"))) then temp_sum := (others => '0'); result_pipe := (others => (others => '0')); result <= (others => '0'); mult_is_saturated_pipe <= (others => '0'); elsif (((output_register = "CLOCK0") and rising_edge(clock0) and (ena0 = '1')) or ((output_register = "CLOCK1") and rising_edge(clock1) and (ena1 = '1')) or ((output_register = "CLOCK2") and rising_edge(clock2) and (ena2 = '1')) or ((output_register = "CLOCK3") and rising_edge(clock3) and (ena3 = '1')) or (output_register = "UNREGISTERED")) then if (((output_register = "CLOCK0") and (ena0 = '1')) or ((output_register = "CLOCK1") and (ena1 = '1')) or ((output_register = "CLOCK2") and (ena2 = '1')) or ((output_register = "CLOCK3") and (ena3 = '1')) or (output_register = "UNREGISTERED")) then temp_sum := (others => '0'); is_rep_a_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_reg = '1'))) or ((port_signa = "PORT_USED") and (sign_a_reg = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); is_rep_b_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_reg = '1'))) or ((port_signb = "PORT_USED") and (sign_b_reg = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); is_rep_a_pipe_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_pipe = '1'))) or ((port_signa = "PORT_USED") and (sign_a_pipe = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); is_rep_b_pipe_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_pipe = '1'))) or ((port_signb = "PORT_USED") and (sign_b_pipe = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); is_adder1_add := ((port_addnsub1 = "PORT_CONNECTIVITY") and (((multiplier1_direction = "ADD") and (addnsub1 = 'Z')) or (addsub_reg1 = '1'))) or ((port_addnsub1 = "PORT_USED") and (addsub_reg1 = '1')) or ((port_addnsub1 = "PORT_UNUSED") and (multiplier1_direction = "ADD")); is_adder3_add := ((port_addnsub3 = "PORT_CONNECTIVITY") and (((multiplier3_direction = "ADD") and (addnsub3 = 'Z')) or (addsub_reg3 = '1'))) or ((port_addnsub3 = "PORT_USED") and (addsub_reg3 = '1')) or ((port_addnsub3 = "PORT_UNUSED") and (multiplier3_direction = "ADD")); is_adder1_pipe_add := ((port_addnsub1 = "PORT_CONNECTIVITY") and (((multiplier1_direction = "ADD") and (addnsub1 = 'Z')) or (addsub_pipe1 = '1'))) or ((port_addnsub1 = "PORT_USED") and (addsub_pipe1 = '1')) or ((port_addnsub1 = "PORT_UNUSED") and (multiplier1_direction = "ADD")); is_adder3_pipe_add := ((port_addnsub3 = "PORT_CONNECTIVITY") and (((multiplier3_direction = "ADD") and (addnsub3 = 'Z')) or (addsub_pipe3 = '1'))) or ((port_addnsub3 = "PORT_USED") and (addsub_pipe3 = '1')) or ((port_addnsub3 = "PORT_UNUSED") and (multiplier3_direction = "ADD")); for i in 0 to (number_of_multipliers -1) loop -- use addsub_reg instead of addsub_pipe if -- addnsub_multiplier_pipeline_register is unregistered -- to determine the do_add flag if ((addnsub_multiplier_pipeline_register1 = "UNREGISTERED") and (addnsub_multiplier_pipeline_register3 = "UNREGISTERED"))then if (((i = 1) and (is_adder1_add)) or ((i = 3) and (is_adder3_add)) or (i = 0) or (i = 2) or (i > 3)) then do_add := true; else do_add := false; end if; elsif ((addnsub_multiplier_pipeline_register1 = "UNREGISTERED") and (not (addnsub_multiplier_pipeline_register3 = "UNREGISTERED")))then if (((i = 1) and (is_adder1_add)) or ((i = 3) and (is_adder3_pipe_add)) or (i = 0) or (i = 2) or (i > 3)) then do_add := true; else do_add := false; end if; elsif ((not (addnsub_multiplier_pipeline_register1 = "UNREGISTERED")) and (addnsub_multiplier_pipeline_register3 = "UNREGISTERED")) then if (((i = 1) and (is_adder1_pipe_add)) or ((i = 3) and (is_adder3_add)) or (i = 0) or (i = 2) or (i > 3)) then do_add := true; else do_add := false; end if; else if (((i = 1) and (is_adder1_pipe_add)) or ((i = 3) and (is_adder3_pipe_add)) or (i = 0) or (i = 2) or (i > 3)) then do_add := true; else do_add := false; end if; end if; mult_res_temp := mult_res( ((i+1)*(int_width_a + int_width_b) - 1) downto (i*(int_width_a + int_width_b))); -- Use sign_a_reg instead of sign_a_pipe when -- signed_pipeline_register_a is unregistered -- to set the asign flag if (signed_pipeline_register_a = "UNREGISTERED") then if (is_rep_a_sign) then asign := true; else asign := false; end if; else if (is_rep_a_pipe_sign) then asign := true; else asign := false; end if; end if; -- Use sign_b_reg instead of sign_b_pipe when -- signed_pipeline_register_b is unregistered -- to set the bsign flag if (signed_pipeline_register_b = "UNREGISTERED") then if (is_rep_b_sign) then bsign := true; else bsign := false; end if; else if (is_rep_b_pipe_sign) then bsign := true; else bsign := false; end if; end if; -- perform addition/subrtaction based on the do_add flag if (do_add = true) then if ((asign = true) or (bsign = true)) then temp_sum := signed (temp_sum) + signed(mult_res_temp); else temp_sum := unsigned (temp_sum) + unsigned(mult_res_temp); end if; else if ((asign = true) or (bsign = true)) then temp_sum := signed (temp_sum) - signed(mult_res_temp); else temp_sum := unsigned (temp_sum) - unsigned(mult_res_temp); end if; end if; if (stratixii_block) then -- ------------------------------------------------------- -- Stratix II Rounding support -- This block basically carries out the rounding for the -- temp_sum. The equation to get the adder_round_out is -- obtained from the Stratix II Mac FFD which is below: -- round_adder_constant = (1 << (wfraction - wfraction_round - 1)) -- roundout[] = datain[] + round_adder_constant -- For Stratix II rounding, we round up the bits to 15 bits -- or in another word wfraction_round = 15. -- -------------------------------------------------------- if (((i = 1) and ((adder1_rounding = "YES") or ((adder1_rounding = "VARIABLE") and (addnsub1_round_pipe_wire = '1')))) or ((i = 2) and (number_of_multipliers = 3) and ((adder3_rounding = "YES") or ((adder3_rounding = "VARIABLE") and (addnsub3_round_pipe_wire = '1')))) or ((i = 3) and ((adder3_rounding = "YES") or ((adder3_rounding = "VARIABLE") and (addnsub3_round_pipe_wire = '1'))))) then -- Here the value 17 is from the 2 bits of sign and the rounding for 15 bits adder_round_bits := (int_width_a + int_width_b) - 17; adder_round_out := signed (temp_sum(int_width_result downto 0)) + ( 2 ** (adder_round_bits - 1)); for j in (adder_round_bits - 1) downto 0 loop adder_round_out(j) := '0'; end loop; --adder_result := adder_round_out; if ((i=2) or (i=3)) then for j in (int_width_result - 1) downto 0 loop temp_sum(j) := adder_round_out(j); end loop; end if; else adder_round_out := temp_sum(int_width_result downto 0); end if; if (i = 0) then adder_result := adder_round_out; end if; if (i = 1) then adder1_result := adder_round_out; adder_result := adder1_result; temp_sum := (others => '0'); end if; if ((i=2) or (i=3))then adder3_result := adder_round_out; if ((asign = true) or (bsign = true)) then adder_result := signed (adder3_result) + signed(adder1_result); else adder_result := unsigned (adder3_result) + unsigned(adder1_result); end if; end if; end if; if (not stratixii_block) then adder_final_out(int_width_result - 1 downto 0) := temp_sum(int_width_result - 1 downto 0); adder_final_out(2*int_width_result - 1 downto int_width_result) := (others => temp_sum(int_width_result -1)); else adder_final_out(int_width_result - 1 downto 0) := adder_result(int_width_result - 1 downto 0); adder_final_out(2*int_width_result - 1 downto int_width_result) := (others => adder_result(int_width_result)); end if; end loop; -- for i in 0 to (number_of_multipliers -1) loop mult_is_saturated_pipe <= mult_is_saturated; if (extra_latency = 0) then result_temp := adder_final_out((width_result - 1 + int_mult_diff_bit) downto int_mult_diff_bit); -- need to extend the MSB for cases where width_result is larger than width_a + width_b if ((number_of_multipliers = 1) and (width_result > width_a + width_b)) then if ((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) then for res_cnt in 1 to (width_result - width_a - width_b) loop result_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - width_a - width_b) loop result_ext(width_result - res_cnt) := result_temp(width_a + width_b - 1); end loop; end if; result_ext(width_a + width_b - 1 downto 0) := result_temp(width_a + width_b - 1 downto 0); elsif ((number_of_multipliers = 2) and (width_result > width_a + width_b + 1)) then if ((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) then for res_cnt in 1 to (width_result - width_a - width_b - 1) loop result_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - width_a - width_b - 1) loop result_ext(width_result - res_cnt) := result_temp(width_a + width_b); end loop; end if; result_ext(width_a + width_b downto 0) := result_temp(width_a + width_b downto 0); elsif ((number_of_multipliers > 2) and (width_result > width_a + width_b + 2)) then if ((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) then for res_cnt in 1 to (width_result - width_a - width_b - 2) loop result_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - width_a - width_b - 2) loop result_ext(width_result - res_cnt) := result_temp(width_a + width_b + 1); end loop; end if; result_ext(width_a + width_b + 1 downto 0) := result_temp(width_a + width_b + 1 downto 0); else result_ext(width_result - 1 downto 0) := result_temp(width_result - 1 downto 0); end if; result <= result_ext; else result_temp := adder_final_out((width_result - 1 + int_mult_diff_bit) downto int_mult_diff_bit); if ((number_of_multipliers = 1) and (width_result > width_a + width_b)) then if ((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) then for res_cnt in 1 to (width_result - width_a - width_b) loop result_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - width_a - width_b) loop result_ext(width_result - res_cnt) := result_temp(width_a + width_b - 1); end loop; end if; result_ext(width_a + width_b - 1 downto 0) := result_temp(width_a + width_b - 1 downto 0); elsif ((number_of_multipliers = 2) and (width_result > width_a + width_b + 1)) then if ((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) then for res_cnt in 1 to (width_result - width_a - width_b - 1) loop result_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - width_a - width_b - 1) loop result_ext(width_result - res_cnt) := result_temp(width_a + width_b); end loop; end if; result_ext(width_a + width_b downto 0) := result_temp(width_a + width_b downto 0); elsif ((number_of_multipliers > 2) and (width_result > width_a + width_b + 2)) then if ((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) then for res_cnt in 1 to (width_result - width_a - width_b - 2) loop result_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - width_a - width_b - 2) loop result_ext(width_result - res_cnt) := result_temp(width_a + width_b + 1); end loop; end if; result_ext(width_a + width_b + 1 downto 0) := result_temp(width_a + width_b + 1 downto 0); else result_ext(width_result - 1 downto 0) := result_temp(width_result - 1 downto 0); end if; head_result_int := head_result; result_pipe (head_result_int) := adder_final_out(width_result - 1 downto 0); head_result_int := (head_result_int +1) mod (extra_latency + 1); result <= result_pipe(head_result_int); head_result <= head_result_int; end if; end if; end if; end process; end generate IFGFAM0; process (mult_is_saturated_pipe) begin -- We also need to update the multpilier saturated port. The reason we update it here -- is that the signal whether the multiplier is saturated or not can appear the same -- time as the adder result for num_mult in 0 to (number_of_multipliers -1) loop if (num_mult = 0) then if (port_mult0_is_saturated = "USED") then mult0_is_saturated <= mult_is_saturated_pipe(num_mult); end if; elsif (num_mult = 1) then if (port_mult1_is_saturated = "USED") then mult1_is_saturated <= mult_is_saturated_pipe(num_mult); end if; elsif (num_mult = 2) then if (port_mult2_is_saturated = "USED") then mult2_is_saturated <= mult_is_saturated_pipe(num_mult); end if; elsif (num_mult = 3) then if (port_mult3_is_saturated = "USED") then mult3_is_saturated <= mult_is_saturated_pipe(num_mult); end if; else assert false report "Error: Not supported number of multipliers in saturation"; end if; end loop; -- for i in 0 to (number_of_multipliers -1) loop end process; -- The addition, subtraction and other functionality for Stratix III IFGFAM1: if (stratixiii_block) generate process (clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3, adder1_reg, adder3_reg, acc_feedback, acc_feedback_temp, outround_pipe, outsat_pipe, mult_res) variable asign : boolean; variable bsign : boolean; variable is_rep_a_sign : boolean; variable is_rep_b_sign : boolean; variable is_rep_a_pipe_sign : boolean; variable is_rep_b_pipe_sign : boolean; variable round_happen : boolean; variable adder1_sum : std_logic_vector (int_width_a + int_width_b + int_width_result downto 0) := (others => '0'); variable adder3_sum : std_logic_vector (int_width_a + int_width_b + int_width_result downto 0) := (others => '0'); variable mult_res_temp : std_logic_vector ((int_width_a + int_width_b - 1) downto 0); variable mult_res_temp_int : std_logic_vector ((int_width_a + int_width_b + int_width_result) downto 0) := (others => '0'); variable stckbit_cnt : integer := 0; variable rndbit_cnt : integer := 0; variable sat_bit_cnt : integer := 0; variable leadsat_bit_cnt : integer := 0; variable trailsat_bit_cnt : integer := 0; variable allsat_bit_cnt : integer := 0; variable satbit_or_cnt : integer := 0; variable overflow_status_bit_pos : integer :=0; variable i : integer := 0; variable stick_bits_or : std_logic := '0'; variable overflow_status : std_logic := '0'; variable sat_bits_or : std_logic := '0'; variable round_sat_in_result : std_logic_vector (int_width_result + int_width_a + int_width_b downto 0) := (others => '0'); variable round_block_result : std_logic_vector (int_width_result + int_width_a + int_width_b downto 0) := (others => '0'); variable sat_block_result : std_logic_vector (int_width_result + int_width_a + int_width_b downto 0) := (others => '0'); variable output_result_temp : std_logic_vector (int_width_result downto 0) := (others => '0'); variable adder1_reg_temp : std_logic_vector (accum_width downto 0) := (others => '0'); variable adder3_reg_temp : std_logic_vector (accum_width downto 0) := (others => '0'); variable accum_res_temp : std_logic_vector (accum_width downto 0) := (others => '0'); variable accum_overflow : std_logic := '0'; variable acc_feedback_int : std_logic_vector (accum_width downto 0) := (others => '0'); variable accum_res_int : std_logic_vector (accum_width downto 0) := (others => '0'); variable and_sign_wire : std_logic := '0'; variable or_sign_wire : std_logic := '0'; variable accum_overflow_int : std_logic := '0'; variable msb : std_logic := '0'; variable unsigned_sub1_overflow : std_logic := '0'; variable unsigned_sub3_overflow : std_logic := '0'; begin -- determine whether dataa and datab are signed or unsigned numbers is_rep_a_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_reg = '1'))) or ((port_signa = "PORT_USED") and (sign_a_reg = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); is_rep_b_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_reg = '1'))) or ((port_signb = "PORT_USED") and (sign_b_reg = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); is_rep_a_pipe_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_pipe = '1'))) or ((port_signa = "PORT_USED") and (sign_a_pipe = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); is_rep_b_pipe_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_pipe = '1'))) or ((port_signb = "PORT_USED") and (sign_b_pipe = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); -- Use sign_a_reg instead of sign_a_pipe when -- signed_pipeline_register_a is unregistered -- to set the asign flag if (signed_pipeline_register_a = "UNREGISTERED") then if (is_rep_a_sign) then asign := true; else asign := false; end if; else if (is_rep_a_pipe_sign) then asign := true; else asign := false; end if; end if; -- Use sign_b_reg instead of sign_b_pipe when -- signed_pipeline_register_b is unregistered -- to set the bsign flag if (signed_pipeline_register_b = "UNREGISTERED") then if (is_rep_b_sign) then bsign := true; else bsign := false; end if; else if (is_rep_b_pipe_sign) then bsign := true; else bsign := false; end if; end if; acc_feedback_int(accum_width - 1 downto 0) := acc_feedback_temp(accum_width - 1 downto 0); if ((((output_aclr = "ACLR0") and (aclr0 = '1')) or ((output_aclr = "ACLR1") and (aclr1 = '1')) or ((output_aclr = "ACLR2") and (aclr2 = '1')) or ((output_aclr = "ACLR3") and (aclr3 = '1'))) and (not (output_register = "UNREGISTERED"))) then accum_res <= (others => '0'); accum_res_temp := (others => '0'); acc_feedback_int := (others => '0'); elsif (((output_register = "CLOCK0") and rising_edge (clock0) and (ena0 = '1')) or ((output_register = "CLOCK1") and rising_edge (clock1) and (ena1 = '1')) or ((output_register = "CLOCK2") and rising_edge (clock2) and (ena2 = '1')) or ((output_register = "CLOCK3") and rising_edge (clock3) and (ena3 = '1')) or (output_register = "UNREGISTERED")) then end if; -- model the registering of the 1st-level adder/subtractor results -- note: For Stratix III, multiplier_register0 should be the same setting as -- multiplier_register1, multiplier_register2 and multiplier_register3, so just use 1 parameter will do if ((((multiplier_aclr0 = "ACLR0") and (aclr0 = '1')) or ((multiplier_aclr0 = "ACLR1") and (aclr1 = '1')) or ((multiplier_aclr0 = "ACLR2") and (aclr2 = '1')) or ((multiplier_aclr0 = "ACLR3") and (aclr3 = '1'))) and (not (multiplier_register0 = "UNREGISTERED"))) then adder1_sum := (others => '0'); adder3_sum := (others => '0'); adder1_reg <= (others => '0'); adder3_reg <= (others => '0'); elsif (((multiplier_register0 = "CLOCK0") and rising_edge (clock0)) or ((multiplier_register0 = "CLOCK1") and rising_edge (clock1)) or ((multiplier_register0 = "CLOCK2") and rising_edge (clock2)) or ((multiplier_register0 = "CLOCK3") and rising_edge (clock3)) or (multiplier_register0 = "UNREGISTERED")) then if (((multiplier_register0 = "CLOCK0") and (ena0 = '1')) or ((multiplier_register0 = "CLOCK1") and (ena1 = '1')) or ((multiplier_register0 = "CLOCK2") and (ena2 = '1')) or ((multiplier_register0 = "CLOCK3") and (ena3 = '1')) or (multiplier_register0 = "UNREGISTERED")) then adder1_sum := (others => '0'); adder3_sum := (others => '0'); -- model the first level adder/subtractor for i in 0 to (number_of_multipliers - 1) loop mult_res_temp := mult_res( ((i+1)*(int_width_a + int_width_b) - 1) downto (i*(int_width_a + int_width_b))); mult_res_temp_int(int_width_a + int_width_b - 1 downto 0) := mult_res_temp; if ((is_rep_a_sign) or (is_rep_b_sign))then mult_res_temp_int(int_width_result + int_width_a + int_width_b downto int_width_a + int_width_b) := (others => mult_res_temp_int(int_width_a + int_width_b - 1)); else mult_res_temp_int(int_width_result + int_width_a + int_width_b downto int_width_a + int_width_b) := (others => '0'); end if; -- perform 1st level addition/subtraction if ((i= 0) or (i = 1)) then if ((multiplier1_direction = "ADD") or (i=0)) then if ((asign = true) or (bsign = true)) then adder1_sum := signed (adder1_sum) + signed(mult_res_temp_int); else adder1_sum := unsigned (adder1_sum) + unsigned(mult_res_temp_int); end if; else -- subtract if ((asign = true) or (bsign = true)) then adder1_sum := signed (adder1_sum) - signed(mult_res_temp_int); else adder1_sum := unsigned (adder1_sum) - unsigned(mult_res_temp_int); if(adder1_sum(int_width_a + int_width_b + int_width_result) = '1') then unsigned_sub1_overflow := '1'; else unsigned_sub1_overflow := '0'; end if; end if; end if; else -- 3rd and 4th multiplier if ((multiplier3_direction = "ADD") or (i=2)) then if ((asign = true) or (bsign = true)) then adder3_sum := signed (adder3_sum) + signed(mult_res_temp_int); else adder3_sum := unsigned (adder3_sum) + unsigned(mult_res_temp_int); end if; else -- subtract if ((asign = true) or (bsign = true)) then adder3_sum := signed (adder3_sum) - signed(mult_res_temp_int); else adder3_sum := unsigned (adder3_sum) - unsigned(mult_res_temp_int); if(adder3_sum(int_width_a + int_width_b + int_width_result) = '1') then unsigned_sub3_overflow := '1'; else unsigned_sub3_overflow := '0'; end if; end if; end if; end if; end loop; -- assign the results to signals adder1_reg <= adder1_sum (int_width_result + int_width_a + int_width_b downto 0); adder3_reg <= adder3_sum (int_width_result + int_width_a + int_width_b downto 0); unsigned_sub1_overflow_mult_reg <= unsigned_sub1_overflow; unsigned_sub3_overflow_mult_reg <= unsigned_sub3_overflow; end if; end if; -- end 1st adder register stage -- extend width for adder1_reg, adder2_reg and acc_feedback to set accumulator overflow bit if(accum_width < int_width_result + int_width_a + int_width_b + 1) then adder1_reg_temp(accum_width - 1 downto 0) := adder1_reg(accum_width - 1 downto 0); adder3_reg_temp(accum_width - 1 downto 0) := adder3_reg(accum_width - 1 downto 0); else adder1_reg_temp(int_width_result + int_width_a + int_width_b downto 0) := adder1_reg(int_width_result + int_width_a + int_width_b downto 0); adder3_reg_temp(int_width_result + int_width_a + int_width_b downto 0) := adder3_reg(int_width_result + int_width_a + int_width_b downto 0); if ((asign = true) or (bsign = true)) then adder1_reg_temp(accum_width - 1 downto int_width_result + int_width_a + int_width_b + 1) := (others => adder1_reg(int_width_result + int_width_a + int_width_b)); adder3_reg_temp(accum_width - 1 downto int_width_result + int_width_a + int_width_b + 1) := (others => adder3_reg(int_width_result + int_width_a + int_width_b)); else adder1_reg_temp(accum_width - 1 downto int_width_result + int_width_a + int_width_b + 1) := (others => '0'); adder3_reg_temp(accum_width - 1 downto int_width_result + int_width_a + int_width_b + 1) := (others => '0'); end if; end if; if ((asign = true) or (bsign = true)) then if(acc_feedback_int(accum_width - 1) = '1') then acc_feedback_int(accum_width) := '1'; else acc_feedback_int(accum_width) := '0'; end if; if((adder1_reg_temp(accum_width - 1) = '1') and (accum_direction = "SUB")) then adder1_reg_temp(accum_width) := '1'; else adder1_reg_temp(accum_width) := '0'; end if; else acc_feedback_int(accum_width) := '0'; end if; adder1_reg_temp(accum_width) := '0'; adder3_reg_temp(accum_width) := '0'; -- model the output register if ((((output_aclr = "ACLR0") and (aclr0 = '1')) or ((output_aclr = "ACLR1") and (aclr1 = '1')) or ((output_aclr = "ACLR2") and (aclr2 = '1')) or ((output_aclr = "ACLR3") and (aclr3 = '1'))) and (not (output_register = "UNREGISTERED"))) then output_result <= (others => '0'); overflow_int <= '0'; unsigned_sub1_overflow_reg <= '0'; unsigned_sub3_overflow_reg <= '0'; elsif (((output_register = "CLOCK0") and rising_edge (clock0)) or ((output_register = "CLOCK1") and rising_edge (clock1)) or ((output_register = "CLOCK2") and rising_edge (clock2)) or ((output_register = "CLOCK3") and rising_edge (clock3)) or (output_register = "UNREGISTERED")) then if (((output_register = "CLOCK0") and (ena0 = '1')) or ((output_register = "CLOCK1") and (ena1 = '1')) or ((output_register = "CLOCK2") and (ena2 = '1')) or ((output_register = "CLOCK3") and (ena3 = '1')) or (output_register = "UNREGISTERED")) then unsigned_sub1_overflow_reg <= unsigned_sub1_overflow_mult_reg; unsigned_sub3_overflow_reg <= unsigned_sub3_overflow_mult_reg; if ((asign = true) or (bsign = true)) then if(accum_direction = "ADD") then accum_res_temp := signed (adder3_reg_temp) + signed (adder1_reg_temp); else accum_res_temp := signed (acc_feedback_int) - signed (adder1_reg_temp); end if; else if(accum_direction = "ADD") then accum_res_temp := unsigned (adder3_reg_temp) + unsigned (adder1_reg_temp); else accum_res_temp := unsigned (acc_feedback_int) - unsigned (adder1_reg_temp); end if; end if; if ((asign = true) or (bsign = true)) then if(accum_res_temp(accum_width - 1) = '1') then accum_res_temp(accum_width) := '1'; else accum_res_temp(accum_width) := '0'; end if; if(adder3_reg_temp(accum_width - 1) = '1') then adder3_reg_temp(accum_width) := '1'; else adder3_reg_temp(accum_width) := '0'; end if; --else -- accum_res_temp(accum_width) := '0'; end if; if ((asign = true) or (bsign = true)) then if(accum_direction = "ADD") then accum_res_int := signed (acc_feedback_int) + signed (accum_res_temp); else accum_res_int := signed(accum_res_temp) - signed(adder3_reg_temp); end if; else if(accum_direction = "ADD") then accum_res_int := unsigned (acc_feedback_int) + unsigned (accum_res_temp); else accum_res_int := unsigned (accum_res_temp) - unsigned (adder3_reg_temp); end if; end if; or_sign_wire := '0'; and_sign_wire := '0'; if(extra_sign_bit_width >= 1) then and_sign_wire := '1'; for i in (accum_width -lsb_position - extra_sign_bit_width) to (accum_width -lsb_position - 1) loop if(accum_res_int(i) = '1') then or_sign_wire := '1'; end if; if(accum_res_int(i) = '0') then and_sign_wire := '0'; end if; end loop; end if; if(port_signa = "PORT_USED" or port_signb = "PORT_USED") then if ((asign = true) or (bsign = true)) then --signed data if(accum_res_int(44) /= accum_res_int(43)) then accum_overflow_int := '1'; else accum_overflow_int := '0'; end if; else -- unsigned data if(accum_direction = "ADD") then -- addition if(accum_res_int(44) = '1') then accum_overflow_int := '1'; else accum_overflow_int := '0'; end if; else -- subtraction if(accum_res_int(44) = '0') then accum_overflow_int := '0'; else accum_overflow_int := '0'; end if; end if; end if; -- dynamic sign input if(accum_res_int(bit_position) = '1') then msb := '1'; else msb := '0'; end if; if(extra_sign_bit_width >= 1) then if((and_sign_wire = '1') and ((not(asign = true or bsign = true)) or ((asign = true or bsign = true) and (msb = '1')))) then and_sign_wire := '1'; else and_sign_wire := '0'; end if; if ((asign = true or bsign = true) and (msb = '1')) then or_sign_wire := '1'; end if; end if; --operation XOR if ((or_sign_wire /= and_sign_wire) or accum_overflow_int = '1') then accum_overflow := '1'; else accum_overflow := '0'; end if; elsif(representation_a = "SIGNED" or representation_b = "SIGNED") then --signed data if (accum_res_int(44) /= accum_res_int(43)) then accum_overflow_int := '1'; else accum_overflow_int := '0'; end if; --operation XOR if ((or_sign_wire /= and_sign_wire) or accum_overflow_int = '1') then accum_overflow := '1'; else accum_overflow := '0'; end if; else -- unsigned data if(accum_direction = "ADD") then -- addition if ((accum_res_int(44) = '1') or ((adder1_reg_temp(43) = '1') and (adder3_reg_temp(43) = '1')))then accum_overflow_int := '1'; else accum_overflow_int := '0'; end if; else -- subtraction if (accum_res_int(44) = '0') then accum_overflow_int := '1'; else accum_overflow_int := '0'; end if; end if; if(or_sign_wire = '1' or accum_overflow_int = '1') then accum_overflow := '1'; else accum_overflow := '0'; end if; end if; accum_res <= accum_res_int; -- model the 2nd stage adder or accumulator if (accumulator = "NO") then if ((asign = true) or (bsign = true)) then round_sat_in_result := signed (adder1_reg) + signed (adder3_reg); else round_sat_in_result := unsigned (adder1_reg) + unsigned (adder3_reg); end if; elsif (accum_direction = "ADD") then if ((asign = true) or (bsign = true)) then round_sat_in_result := signed (acc_feedback) + signed (adder1_reg) + signed (adder3_reg); else round_sat_in_result := unsigned (acc_feedback) + unsigned (adder1_reg) + unsigned (adder3_reg); end if; elsif (accum_direction = "SUB") then if ((asign = true) or (bsign = true)) then round_sat_in_result := signed (acc_feedback) - signed (adder1_reg) - signed (adder3_reg); else round_sat_in_result := unsigned (acc_feedback) - unsigned (adder1_reg) - unsigned (adder3_reg); end if; end if; round_happen := false; -- 1st rounding block if (output_rounding = "NO") then round_block_result := round_sat_in_result; else if (((output_rounding = "VARIABLE") and (outround_pipe = '1')) or (output_rounding = "YES")) then -- guard bit is '1' if (round_sat_in_result(round_position - 1) = '1') then if (output_round_type = "NEAREST_INTEGER") then -- round to nearest integer round_block_result := unsigned(round_sat_in_result) + (2 ** (round_position)); else -- round to nearest even stick_bits_or := '0'; -- determine if any sticky bit is '1' for stckbit_cnt in 0 to (round_position - 2) loop stick_bits_or := stick_bits_or or round_sat_in_result(stckbit_cnt); end loop; if (stick_bits_or = '1') then -- if sticky bits = 1, do rounding round_block_result := unsigned(round_sat_in_result) + (2 ** (round_position)); else -- all sticky bits are 0, look at the LSB to determine to round or not if (round_sat_in_result (round_position) = '1') then -- LSB is odd, so do rounding round_block_result := unsigned(round_sat_in_result) + (2 ** (round_position)); else round_block_result := round_sat_in_result; end if; end if; end if; else -- guard bit is 0, so no need to round round_block_result := round_sat_in_result; end if; -- if unsigned numbers enter into the rounding & saturation block, "X" the entire data -- since unsigned numbers are illegal if (((asign = false) and (bsign = false)) and (((port_signa = "PORT_USED") and (port_signb = "PORT_USED")) or ((representation_a /= "UNUSED") and (representation_b /= "UNUSED")))) then round_block_result := (others => 'X'); end if; -- force the LSBs beyond the rounding position to "X" if(input_source_b0 /= "LOOPBACK") then for rndbit_cnt in 0 to (round_position - 1) loop round_block_result(rndbit_cnt) := 'X'; end loop; end if; round_happen := true; else round_block_result := round_sat_in_result; end if; end if; -- prevent the previous overflow_status being taken into consideration when determining the overflow if ((overflow_status = '0') and (port_output_is_overflow = "PORT_UNUSED") and (chainout_adder = "NO")) then overflow_status_bit_pos := int_width_result + int_mult_diff_bit - 1; else overflow_status_bit_pos := int_width_result + 1; end if; -- 1st saturation block if (output_saturation = "NO") then sat_block_result := round_block_result; else overflow_status := '0'; if (((output_saturation = "VARIABLE") and (outsat_pipe = '1')) or (output_saturation = "YES")) then if (round_block_result (int_width_result) = '0') then -- carry bit is 0, positive number for sat_bit_cnt in (saturation_position) to (int_width_result) loop if (sat_bit_cnt /= overflow_status_bit_pos) then overflow_status := overflow_status or round_block_result (sat_bit_cnt); end if; end loop; else -- carry bit is 1, negative number for sat_bit_cnt in (saturation_position) to (int_width_result) loop if (sat_bit_cnt /= overflow_status_bit_pos) then overflow_status := overflow_status or (not round_block_result (sat_bit_cnt)); end if; end loop; if ((output_saturate_type = "SYMMETRIC") and (overflow_status = '0')) then overflow_status := '1'; if (round_happen) then for sat_bit_cnt in (round_position) to (saturation_position - 1) loop overflow_status := overflow_status and not(round_block_result (sat_bit_cnt)); end loop; else for sat_bit_cnt in (0) to (saturation_position - 1) loop overflow_status := overflow_status and not(round_block_result (sat_bit_cnt)); end loop; end if; end if; end if; if (overflow_status = '1') then if (round_block_result (int_width_result) = '0') then -- positive number if (port_output_is_overflow = "PORT_UNUSED") then sat_block_result (int_width_a + int_width_b - 1) := overflow_status; elsif (accumulator = "NO") then sat_block_result (int_width_a + int_width_b - 1) := 'X'; end if; for leadsat_bit_cnt in (saturation_position) to (int_width_a + int_width_b) loop sat_block_result (leadsat_bit_cnt) := '0'; end loop; if (round_happen) then for trailsat_bit_cnt in (round_position) to (saturation_position - 1) loop sat_block_result (trailsat_bit_cnt) := '1'; end loop; else for trailsat_bit_cnt in 0 to (saturation_position - 1) loop sat_block_result (trailsat_bit_cnt) := '1'; end loop; end if; sat_block_result(int_width_result + int_width_a + int_width_b - 1 downto int_width_a + int_width_b + 1) := (others => '0'); else -- negative number if (port_output_is_overflow = "PORT_UNUSED") then sat_block_result (int_width_a + int_width_b - 1) := overflow_status; elsif (accumulator = "NO") then sat_block_result (int_width_a + int_width_b - 1) := 'X'; end if; for allsat_bit_cnt in (saturation_position) to (int_width_a + int_width_b) loop sat_block_result (allsat_bit_cnt) := '1'; -- set all sign bits to '1' end loop; if ((output_rounding /= "NO") and (output_saturate_type = "SYMMETRIC")) then for allsat_bit_cnt in (round_position) to (saturation_position - 1) loop sat_block_result (allsat_bit_cnt) := '0'; -- set all bits to "0" end loop; if(accumulator = "NO") then for allsat_bit_cnt in 0 to (round_position - 1) loop sat_block_result (allsat_bit_cnt) := 'X'; -- set LSBs to "X" end loop; else for allsat_bit_cnt in 0 to (round_position - 1) loop sat_block_result (allsat_bit_cnt) := '0'; -- set LSBs to "X" end loop; end if; else for allsat_bit_cnt in 0 to (saturation_position - 1) loop sat_block_result (allsat_bit_cnt) := '0'; -- set all bits to "0" end loop; end if; if ((output_rounding /= "NO") and (output_saturate_type = "SYMMETRIC")) then sat_block_result (round_position) := '1'; elsif (output_saturate_type = "SYMMETRIC") then sat_block_result (int_mult_diff_bit) := '1'; end if; sat_block_result(int_width_result + int_width_a + int_width_b - 1 downto int_width_a + int_width_b + 1) := (others => '1'); end if; else -- if not overflow sat_block_result := round_block_result; if (port_output_is_overflow = "PORT_UNUSED" and chainout_adder = "NO" and ((output_saturation = "VARIABLE") and (outsat_pipe = '1'))) then sat_block_result (int_width_result + int_mult_diff_bit - 1) := overflow_status; end if; -- if negative number & output_saturate_type is symmetric, need to check for special case if (sat_block_result (int_width_a + int_width_b - 1) = '1') then if (output_saturate_type = "SYMMETRIC") then for satbit_or_cnt in (round_position) to (int_width_a + int_width_b - 2) loop sat_bits_or := sat_bits_or or sat_block_result (satbit_or_cnt); end loop; end if; end if; end if; -- if unsigned numbers enter into the rounding & saturation block, "X" the entire data -- since unsigned numbers are illegal if (((asign = false) and (bsign = false)) and (((port_signa = "PORT_USED") and (port_signb = "PORT_USED")) or ((representation_a /= "UNUSED") and (representation_b /= "UNUSED")))) then sat_block_result := (others => 'X'); end if; elsif ((output_saturation = "VARIABLE") and (outsat_pipe = '0')) then sat_block_result := round_block_result; overflow_status := '0'; else sat_block_result := round_block_result; end if; end if; -- assign the saturation block output to a signal output_result <= sat_block_result; -- assign the overflow status to the overflow port if (port_output_is_overflow = "PORT_USED") then if(output_saturation = "NO" and accumulator = "YES") then overflow_int <= accum_overflow; elsif(output_saturation /= "NO") then overflow_int <= overflow_status; end if; end if; end if; end if; -- end of output_register block end process; end generate IFGFAM1; IFGFAM10: if (stratixiii_block) generate process (clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3, chainout_round_out_reg, chainout_sat_out, zerochainout_reg, chainin, output_result) variable asign : boolean; variable bsign : boolean; variable is_rep_a_sign : boolean; variable is_rep_b_sign : boolean; variable is_rep_a_pipe_sign : boolean; variable is_rep_b_pipe_sign : boolean; variable cho_round_happen : boolean; variable cho_rndbit_cnt : integer := 0; variable cho_stckbit_cnt : integer := 0; variable cho_sat_bit_cnt : integer := 0; variable cho_leadsat_bit_cnt : integer := 0; variable cho_trailsat_bit_cnt : integer := 0; variable cho_allsat_bit_cnt : integer := 0; variable cho_satbit_or_cnt : integer := 0; variable cho_stick_bits_or : std_logic := '0'; variable cho_sat_bits_or : std_logic := '0'; variable chainout_overflow_status : std_logic := '0'; variable chainout_round_block_result : std_logic_vector (int_width_result downto 0) := (others => '0'); variable chainout_add_result : std_logic_vector (int_width_result downto 0) := (others => '0'); variable chainout_sat_block_result : std_logic_vector (int_width_result downto 0) := (others => '0'); variable overflow_checking : std_logic; variable round_checking : std_logic; begin -- determine whether dataa and datab are signed or unsigned numbers is_rep_a_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_reg = '1'))) or ((port_signa = "PORT_USED") and (sign_a_reg = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); is_rep_b_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_reg = '1'))) or ((port_signb = "PORT_USED") and (sign_b_reg = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); is_rep_a_pipe_sign := ((port_signa = "PORT_CONNECTIVITY") and (((representation_a = "SIGNED") and (signa = 'Z')) or (sign_a_pipe = '1'))) or ((port_signa = "PORT_USED") and (sign_a_pipe = '1')) or ((port_signa = "PORT_UNUSED") and (representation_a = "SIGNED")); is_rep_b_pipe_sign := ((port_signb = "PORT_CONNECTIVITY") and (((representation_b = "SIGNED") and (signb = 'Z')) or (sign_b_pipe = '1'))) or ((port_signb = "PORT_USED") and (sign_b_pipe = '1')) or ((port_signb = "PORT_UNUSED") and (representation_b = "SIGNED")); -- Use sign_a_reg instead of sign_a_pipe when -- signed_pipeline_register_a is unregistered -- to set the asign flag if (signed_pipeline_register_a = "UNREGISTERED") then if (is_rep_a_sign) then asign := true; else asign := false; end if; else if (is_rep_a_pipe_sign) then asign := true; else asign := false; end if; end if; -- Use sign_b_reg instead of sign_b_pipe when -- signed_pipeline_register_b is unregistered -- to set the bsign flag if (signed_pipeline_register_b = "UNREGISTERED") then if (is_rep_b_sign) then bsign := true; else bsign := false; end if; else if (is_rep_b_pipe_sign) then bsign := true; else bsign := false; end if; end if; -- model the chainout stage if ((((chainout_aclr = "ACLR0") and (aclr0 = '1')) or ((chainout_aclr = "ACLR1") and (aclr1 = '1')) or ((chainout_aclr = "ACLR2") and (aclr2 = '1')) or ((chainout_aclr = "ACLR3") and (aclr3 = '1'))) and (not (chainout_register = "UNREGISTERED"))) then chainout_sat_block_res_wire <= (others => '0'); chainout_sat_overflow <= '0'; chainout_overflow_int <= '0'; elsif (((chainout_register = "CLOCK0") and rising_edge (clock0)) or ((chainout_register = "CLOCK1") and rising_edge (clock1)) or ((chainout_register = "CLOCK2") and rising_edge (clock2)) or ((chainout_register = "CLOCK3") and rising_edge (clock3)) or (chainout_register = "UNREGISTERED")) then if (((chainout_register = "CLOCK0") and (ena0 = '1')) or ((chainout_register = "CLOCK1") and (ena1 = '1')) or ((chainout_register = "CLOCK2") and (ena2 = '1')) or ((chainout_register = "CLOCK3") and (ena3 = '1')) or (chainout_register = "UNREGISTERED")) then -- model the chainout adder if (chainout_adder = "YES") then if ((asign = true) or (bsign = true)) then chainout_add_result := signed (output_result(int_width_result downto 0)) + signed (chainin); else chainout_add_result := unsigned (output_result(int_width_result downto 0)) + unsigned (chainin); end if; cho_round_happen := false; -- model the chainout stage rounding block if (chainout_rounding = "NO") then chainout_round_block_result := chainout_add_result; else if (((chainout_rounding = "VARIABLE") and (chainout_round_out_reg = '1')) or (chainout_rounding = "YES")) then overflow_checking := chainout_add_result(int_width_result - 1); -- guard bit is '1' if (chainout_add_result(chainout_round_position - 1) = '1') then if (output_round_type = "NEAREST_INTEGER") then -- round to nearest integer round_checking := '1'; chainout_round_block_result := unsigned(chainout_add_result) + (2 ** (chainout_round_position)); else -- round to nearest even -- determine if any sticky bit is '1' cho_stick_bits_or := '0'; for cho_stckbit_cnt in 0 to (chainout_round_position - 2) loop cho_stick_bits_or := cho_stick_bits_or or chainout_add_result(cho_stckbit_cnt); end loop; if (cho_stick_bits_or = '1') then -- if sticky bits = 1, do rounding chainout_round_block_result := unsigned(chainout_add_result) + (2 ** (chainout_round_position)); else -- all sticky bits are 0, look at the LSB to determine to round or not if (chainout_add_result (chainout_round_position) = '1') then -- LSB is odd, so do rounding chainout_round_block_result := unsigned(chainout_add_result) + (2 ** (chainout_round_position)); else chainout_round_block_result := chainout_add_result; end if; end if; end if; else -- guard bit is 0, so no need to round chainout_round_block_result := chainout_add_result; end if; -- if unsigned numbers enter into the rounding & saturation block, "X" the entire data -- since unsigned numbers are illegal if (((asign = false) and (bsign = false)) and (((port_signa = "PORT_USED") and (port_signb = "PORT_USED")) or ((representation_a /= "UNUSED") and (representation_b /= "UNUSED")))) then chainout_round_block_result := (others => 'X'); end if; cho_round_happen := true; else chainout_round_block_result := chainout_add_result; end if; end if; chainout_overflow_status := '0'; if (chainout_saturation = "NO") then chainout_sat_block_result := chainout_round_block_result; else if (((chainout_saturation = "VARIABLE") and (chainout_sat_out = '1')) or (chainout_saturation = "YES")) then if ((((chainout_rounding = "VARIABLE") and (chainout_round_out_reg = '1')) or (chainout_rounding = "YES")) and round_checking = '1' and width_saturate_sign = 1 and width_result = result_width) then if (chainout_round_block_result(int_width_result - 1) /= overflow_checking) then chainout_overflow_status := '1'; else chainout_overflow_status := '0'; end if; elsif (chainout_round_block_result (int_width_result - 1) = '0') then -- carry bit is 0, positive number for cho_sat_bit_cnt in (chainout_saturation_position) to (int_width_result - 1) loop chainout_overflow_status := chainout_overflow_status or chainout_round_block_result (cho_sat_bit_cnt); end loop; else -- carry bit is 1, negative number for cho_sat_bit_cnt in (chainout_saturation_position) to (int_width_result - 1) loop chainout_overflow_status := chainout_overflow_status or (not chainout_round_block_result (cho_sat_bit_cnt)); end loop; if ((output_saturate_type = "SYMMETRIC") and (chainout_overflow_status = '0')) then chainout_overflow_status := '1'; if (cho_round_happen) then for cho_sat_bit_cnt in (chainout_round_position) to (chainout_saturation_position - 1) loop chainout_overflow_status := chainout_overflow_status and not(chainout_round_block_result (cho_sat_bit_cnt)); end loop; else for cho_sat_bit_cnt in (0) to (chainout_saturation_position - 1) loop chainout_overflow_status := chainout_overflow_status and not(chainout_round_block_result (cho_sat_bit_cnt)); end loop; end if; end if; end if; if (chainout_overflow_status = '1') then if ((((chainout_rounding = "VARIABLE") and (chainout_round_out_reg = '1')) or (chainout_rounding = "YES")) and round_checking = '1' and width_saturate_sign = 1 and width_result = result_width) then if (chainout_round_block_result (int_width_result - 1) = '1') then -- positive number if (port_chainout_sat_is_overflow = "PORT_UNUSED") then chainout_sat_block_result (int_width_result - 1) := chainout_overflow_status; else chainout_sat_block_result (int_width_result - 1) := chainout_overflow_status; end if; for cho_leadsat_bit_cnt in (chainout_saturation_position) to (int_width_result - 1) loop chainout_sat_block_result (cho_leadsat_bit_cnt) := '0'; end loop; if (cho_round_happen) then for cho_trailsat_bit_cnt in (0) to (chainout_saturation_position - 1) loop chainout_sat_block_result (cho_trailsat_bit_cnt) := '1'; end loop; else for cho_trailsat_bit_cnt in 0 to (chainout_saturation_position - 1) loop chainout_sat_block_result (cho_trailsat_bit_cnt) := '1'; end loop; end if; else -- negative number if (port_chainout_sat_is_overflow = "PORT_UNUSED") then chainout_sat_block_result (int_width_result - 1) := chainout_overflow_status; else chainout_sat_block_result (int_width_result - 1) := chainout_overflow_status; end if; for cho_allsat_bit_cnt in (chainout_saturation_position) to (int_width_result - 1) loop chainout_sat_block_result (cho_allsat_bit_cnt) := '1'; -- set all sign bits to '1' end loop; if ((chainout_rounding /= "NO") and (output_saturate_type = "SYMMETRIC")) then for cho_allsat_bit_cnt in (chainout_round_position) to (chainout_saturation_position - 1) loop chainout_sat_block_result (cho_allsat_bit_cnt) := '0'; -- set all bits to '0' end loop; for cho_allsat_bit_cnt in 0 to (chainout_round_position - 1) loop chainout_sat_block_result (cho_allsat_bit_cnt) := '0'; -- set LSBs to '0' end loop; else for cho_allsat_bit_cnt in 0 to (chainout_saturation_position - 1) loop chainout_sat_block_result (cho_allsat_bit_cnt) := '0'; -- set all bits to '0' end loop; end if; if ((chainout_rounding /= "NO") and (output_saturate_type = "SYMMETRIC")) then chainout_sat_block_result (chainout_round_position) := '1'; elsif (output_saturate_type = "SYMMETRIC") then chainout_sat_block_result (int_mult_diff_bit) := '1'; end if; end if; else if (chainout_round_block_result (int_width_result - 1) = '0') then -- positive number if (port_chainout_sat_is_overflow = "PORT_UNUSED") then chainout_sat_block_result (int_width_result - 1) := chainout_overflow_status; else chainout_sat_block_result (int_width_result - 1) := chainout_overflow_status; end if; for cho_leadsat_bit_cnt in (chainout_saturation_position) to (int_width_result - 1) loop chainout_sat_block_result (cho_leadsat_bit_cnt) := '0'; end loop; if (cho_round_happen) then for cho_trailsat_bit_cnt in (0) to (chainout_saturation_position - 1) loop chainout_sat_block_result (cho_trailsat_bit_cnt) := '1'; end loop; else for cho_trailsat_bit_cnt in 0 to (chainout_saturation_position - 1) loop chainout_sat_block_result (cho_trailsat_bit_cnt) := '1'; end loop; end if; else -- negative number if (port_chainout_sat_is_overflow = "PORT_UNUSED") then chainout_sat_block_result (int_width_result - 1) := chainout_overflow_status; else chainout_sat_block_result (int_width_result - 1) := chainout_overflow_status; end if; for cho_allsat_bit_cnt in (chainout_saturation_position) to (int_width_result - 1) loop chainout_sat_block_result (cho_allsat_bit_cnt) := '1'; -- set all sign bits to '1' end loop; if ((chainout_rounding /= "NO") or (output_saturate_type = "SYMMETRIC")) then for cho_allsat_bit_cnt in (chainout_round_position) to (chainout_saturation_position - 1) loop chainout_sat_block_result (cho_allsat_bit_cnt) := '0'; -- set all bits to '0' end loop; for cho_allsat_bit_cnt in 0 to (chainout_round_position - 1) loop chainout_sat_block_result (cho_allsat_bit_cnt) := '0'; -- set LSBs to 'X' end loop; else for cho_allsat_bit_cnt in 0 to (chainout_saturation_position - 1) loop chainout_sat_block_result (cho_allsat_bit_cnt) := '0'; -- set all bits to '0' end loop; end if; if ((chainout_rounding /= "NO") and (output_saturate_type = "SYMMETRIC")) then chainout_sat_block_result (chainout_round_position) := '1'; elsif (output_saturate_type = "SYMMETRIC") then chainout_sat_block_result (int_mult_diff_bit) := '1'; end if; end if; end if; else -- if not overflow chainout_sat_block_result := chainout_round_block_result; -- if negative number & output_saturate_type is symmetric, need to check for special case if (chainout_sat_block_result (int_width_result) = '1') then if (output_saturate_type = "SYMMETRIC") then for cho_satbit_or_cnt in (chainout_round_position) to (int_width_result - 2) loop cho_sat_bits_or := cho_sat_bits_or or chainout_sat_block_result (cho_satbit_or_cnt); end loop; if ((cho_sat_bits_or = '0') and (chainout_sat_block_result (int_width_result - 1) = '1')) then chainout_sat_block_result (chainout_round_position) := '1'; end if; end if; end if; end if; -- if unsigned numbers enter into the rounding & saturation block, "X" the entire data -- since unsigned numbers are illegal if (((asign = false) and (bsign = false)) and (((port_signa = "PORT_USED") and (port_signb = "PORT_USED")) or ((representation_a /= "UNUSED") and (representation_b /= "UNUSED")))) then chainout_sat_block_result := (others => 'X'); end if; else chainout_sat_block_result := chainout_round_block_result; end if; end if; end if; -- assign the chainout overflow status to the chainout_sat_overflow port if (port_chainout_sat_is_overflow = "PORT_USED") then chainout_sat_overflow <= chainout_overflow_status; chainout_overflow_int <= chainout_overflow_status; end if; chainout_sat_block_res_wire <= chainout_sat_block_result; end if; end if; -- end of chainout register stage end process; end generate IFGFAM10; IFGFAM11: if (stratixiii_block) generate process (chainout_sat_block_res_wire, zerochainout_reg) variable cho_cnt : integer := 0; variable chainout_out_temp : std_logic_vector (int_width_result downto 0) := (others => '0'); begin chainout_out_temp := (others => '0'); -- the chainout output after factoring in zero_chainout for cho_cnt in 0 to int_width_result loop chainout_out_temp(cho_cnt) := (not zerochainout_reg) and (chainout_sat_block_res_wire(cho_cnt)); end loop; chainout_output(int_width_result downto 0) <= chainout_out_temp(int_width_result downto 0); end process; end generate IFGFAM11; -- model the shift & rotate blocks for Stratix III IFGFAM2: if (stratixiii_block) generate process (output_result, shiftr_out, rotate_out) begin if (not (shift_mode = "NO")) then if ((shift_mode = "LEFT") or ((shift_mode = "VARIABLE") and (shiftr_out = '0') and (rotate_out = '0'))) then shift_rot_result <= output_result((int_width_result / 2) - 1 downto 0); elsif ((shift_mode = "RIGHT") or ((shift_mode = "VARIABLE") and (shiftr_out = '1') and (rotate_out = '0'))) then shift_rot_result <= output_result(int_width_result - 1 downto (int_width_result / 2)); elsif ((shift_mode = "ROTATION") or ((shift_mode = "VARIABLE") and (shiftr_out = '0') and (rotate_out = '1'))) then shift_rot_result <= (output_result(int_width_result - 1 downto (int_width_result / 2))) or (output_result((int_width_result / 2) - 1 downto 0)); end if; end if; end process; end generate IFGFAM2; IFGFAM3: if (stratixiii_block) generate process (output_result, zeroloopback_out) variable lpbk_cnt : integer := 0; begin if (input_source_b0 = "LOOPBACK") then for lpbk_cnt in 0 to (int_width_result - 1) loop loopback_wire(lpbk_cnt) <= output_result(lpbk_cnt + (int_width_b - width_b)) and (not zeroloopback_out); end loop; end if; end process; end generate IFGFAM3; IFLOOPBACK: if (stratixiii_block) generate process (loopback_wire) begin if(input_source_b0 = "LOOPBACK") then feedback <= loopback_wire(width_a + 18 - 1 downto width_a); end if; end process; end generate IFLOOPBACK; IFGFAM4: if (stratixiii_block) generate process (output_result, accumsload_pipe) variable acfdbk_cnt : integer := 0; begin if (accumulator = "YES") then for acfdbk_cnt in 0 to (int_width_result + int_width_a + int_width_b) loop acc_feedback(acfdbk_cnt) <= output_result(acfdbk_cnt) and (not accumsload_pipe); end loop; end if; end process; end generate IFGFAM4; IFACCUM: if (stratixiii_block) generate process (accum_res, accumsload_pipe) variable acfdbk_cnt : integer := 0; begin if (accumulator = "YES") then for acfdbk_cnt in 0 to (accum_width) loop acc_feedback_temp(acfdbk_cnt) <= accum_res(acfdbk_cnt) and (not accumsload_pipe); end loop; end if; end process; end generate IFACCUM; IFGFAM5: if (stratixiii_block) generate process (output_result, overflow_int, chainout_overflow_int, shift_rot_result, chainout_output, clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3, unsigned_sub1_overflow_reg, unsigned_sub3_overflow_reg) variable head_result_int : integer := 0; variable res_cnt : integer := 0; variable result_pipe : pipeline_accum := (others => (others => '0')); variable result_stxiii : std_logic_vector (width_result - 1 downto 0) := (others => '0'); variable result_stxiii_ext : std_logic_vector (width_result - 1 downto 0) := (others => '0'); variable count : integer := 0; variable overflow_stat_pipe_reg : std_logic_vector (extra_latency downto 0) := (others => '0'); variable head_overflow_int : integer := 0; begin if (extra_latency = 0) then if (not (shift_mode = "NO")) then result_stxiii := shift_rot_result((width_result - 1 + int_mult_diff_bit) downto int_mult_diff_bit); elsif (chainout_adder = "YES") then result_stxiii := chainout_output((width_result - 1 + int_mult_diff_bit) downto int_mult_diff_bit); elsif (input_source_b0 = "LOOPBACK") then result_stxiii := output_result((width_result - 1 + (int_width_b - width_b)) downto int_width_b - width_b); else result_stxiii := output_result((width_result - 1 + int_mult_diff_bit) downto int_mult_diff_bit); end if; -- need to extend the MSB for cases where width_result is larger than width_a + width_b if ((chainout_adder = "YES") or (accumulator = "YES")) then result_stxiii_ext(width_result - 1 downto 0) := result_stxiii(width_result - 1 downto 0); elsif ((number_of_multipliers = 1) and (width_result > width_a + width_b)) then if (((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) and (unsigned_sub1_overflow_reg = '0' and unsigned_sub3_overflow_reg = '0')) then for res_cnt in 1 to (width_result - width_a - width_b) loop result_stxiii_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - width_a - width_b) loop result_stxiii_ext(width_result - res_cnt) := result_stxiii(width_a + width_b - 1); end loop; end if; result_stxiii_ext(width_a + width_b - 1 downto 0) := result_stxiii(width_a + width_b - 1 downto 0); elsif (((number_of_multipliers = 2) or (input_source_b0 = "LOOPBACK")) and (width_result > width_a + width_b + 1)) then if (((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) and (unsigned_sub1_overflow_reg = '0' and unsigned_sub3_overflow_reg = '0')) then for res_cnt in 1 to (width_result - width_a - width_b - 1) loop result_stxiii_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - width_a - width_b - 1) loop result_stxiii_ext(width_result - res_cnt) := result_stxiii(width_a + width_b); end loop; end if; result_stxiii_ext(width_a + width_b downto 0) := result_stxiii(width_a + width_b downto 0); elsif ((number_of_multipliers > 2) and (width_result > width_a + width_b + 2)) then if (((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) and (unsigned_sub1_overflow_reg = '0' and unsigned_sub3_overflow_reg = '0')) then for res_cnt in 1 to (width_result - width_a - width_b - 2) loop result_stxiii_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - width_a - width_b - 2) loop result_stxiii_ext(width_result - res_cnt) := result_stxiii(width_a + width_b + 1); end loop; end if; result_stxiii_ext(width_a + width_b + 1 downto 0) := result_stxiii(width_a + width_b + 1 downto 0); else result_stxiii_ext(width_result - 1 downto 0) := result_stxiii(width_result - 1 downto 0); end if; result <= result_stxiii_ext; if(chainout_saturation /= "NO") then overflow <= chainout_overflow_int ; else overflow <= overflow_int; end if; else if (input_source_b0 = "LOOPBACK") then result_stxiii := output_result((width_result - 1 + (int_width_b - width_b)) downto int_width_b - width_b); else result_stxiii := output_result((width_result - 1 + int_mult_diff_bit) downto int_mult_diff_bit); end if; if ((chainout_adder = "YES") or (accumulator = "YES")) then result_stxiii_ext(width_result - 1 downto 0) := result_stxiii(width_result - 1 downto 0); elsif ((number_of_multipliers = 1) and (width_result > int_width_a + int_width_b)) then if (((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) and (unsigned_sub1_overflow_reg = '0' and unsigned_sub3_overflow_reg = '0')) then for res_cnt in 1 to (width_result - int_width_a - int_width_b) loop result_stxiii_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - int_width_a - int_width_b) loop result_stxiii_ext(width_result - res_cnt) := result_stxiii(int_width_a + int_width_b - 1); end loop; end if; result_stxiii_ext(int_width_a + int_width_b - 1 downto 0) := result_stxiii(int_width_a + int_width_b - 1 downto 0); elsif (((number_of_multipliers = 2) or (input_source_b0 = "LOOPBACK")) and (width_result > int_width_a + int_width_b + 1)) then if (((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) and (unsigned_sub1_overflow_reg = '0' and unsigned_sub3_overflow_reg = '0')) then for res_cnt in 1 to (width_result - int_width_a - int_width_b - 1) loop result_stxiii_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - int_width_a - int_width_b - 1) loop result_stxiii_ext(width_result - res_cnt) := result_stxiii(int_width_a + int_width_b); end loop; end if; result_stxiii_ext(int_width_a + int_width_b downto 0) := result_stxiii(int_width_a + int_width_b downto 0); elsif ((number_of_multipliers > 2) and (width_result > int_width_a + int_width_b + 2)) then if (((representation_a = "UNSIGNED") and (representation_b = "UNSIGNED")) and (unsigned_sub1_overflow_reg = '0' and unsigned_sub3_overflow_reg = '0')) then for res_cnt in 1 to (width_result - int_width_a - int_width_b - 2) loop result_stxiii_ext(width_result - res_cnt) := '0'; end loop; else for res_cnt in 1 to (width_result - int_width_a - int_width_b - 2) loop result_stxiii_ext(width_result - res_cnt) := result_stxiii(int_width_a + int_width_b + 1); end loop; end if; result_stxiii_ext(int_width_a + int_width_b + 1 downto 0) := result_stxiii(int_width_a + int_width_b + 1 downto 0); else result_stxiii_ext(width_result - 1 downto 0) := result_stxiii(width_result - 1 downto 0); end if; if(output_aclr = "ACLR0" and aclr0 = '1') then for count in 0 to extra_latency loop result_pipe(count) := (others => '0'); overflow_stat_pipe_reg (count) := '0'; head_result_siii <= 0; head_overflow <= 0; result <= (others => '0'); overflow <= '0'; end loop; elsif(output_aclr = "ACLR1" and aclr1 = '1') then for count in 0 to extra_latency loop result_pipe(count) := (others => '0'); overflow_stat_pipe_reg (count) := '0'; head_result_siii <= 0; head_overflow <= 0; result <= (others => '0'); overflow <= '0'; end loop; elsif(output_aclr = "ACLR2" and aclr2 = '1') then for count in 0 to extra_latency loop result_pipe(count) := (others => '0'); overflow_stat_pipe_reg (count) := '0'; head_result_siii <= 0; head_overflow <= 0; result <= (others => '0'); overflow <= '0'; end loop; elsif(output_aclr = "ACLR3" and aclr3 = '1') then for count in 0 to extra_latency loop result_pipe(count) := (others => '0'); overflow_stat_pipe_reg (count) := '0'; head_result_siii <= 0; head_overflow <= 0; result <= (others => '0'); overflow <= '0'; end loop; end if; if ((output_register = "CLOCK0") and (rising_edge(clock0) and ena0 = '1')) then head_result_int := head_result_siii; head_overflow_int := head_overflow; result_pipe(head_result_int) := result_stxiii_ext; if(chainout_saturation /= "NO") then overflow_stat_pipe_reg (head_overflow_int) := chainout_overflow_int; else overflow_stat_pipe_reg (head_overflow_int) := overflow_int; end if; head_result_int := (head_result_int +1) mod (extra_latency); head_overflow_int := (head_overflow_int +1) mod (extra_latency); overflow <= overflow_stat_pipe_reg(head_overflow_int); result <= result_pipe(head_result_int); head_result_siii <= head_result_int; head_overflow <= head_overflow_int; elsif ((output_register = "CLOCK1") and (rising_edge(clock1) and ena1 = '1')) then head_result_int := head_result_siii; head_overflow_int := head_overflow; result_pipe(head_result_int) := result_stxiii_ext; if(chainout_saturation /= "NO") then overflow_stat_pipe_reg (head_overflow_int) := chainout_overflow_int; else overflow_stat_pipe_reg (head_overflow_int) := overflow_int; end if; head_result_int := (head_result_int +1) mod (extra_latency); head_overflow_int := (head_overflow_int +1) mod (extra_latency); overflow <= overflow_stat_pipe_reg(head_overflow_int); result <= result_pipe(head_result_int); head_result_siii <= head_result_int; head_overflow <= head_overflow_int; elsif ((output_register = "CLOCK2") and (rising_edge(clock2) and ena2 = '1')) then head_result_int := head_result_siii; head_overflow_int := head_overflow; result_pipe(head_result_int) := result_stxiii_ext; if(chainout_saturation /= "NO") then overflow_stat_pipe_reg (head_overflow_int) := chainout_overflow_int; else overflow_stat_pipe_reg (head_overflow_int) := overflow_int; end if; head_result_int := (head_result_int +1) mod (extra_latency); head_overflow_int := (head_overflow_int +1) mod (extra_latency); overflow <= overflow_stat_pipe_reg(head_overflow_int); result <= result_pipe(head_result_int); head_result_siii <= head_result_int; head_overflow <= head_overflow_int; elsif ((output_register = "CLOCK3") and (rising_edge(clock3) and ena3 = '1')) then head_result_int := head_result_siii; head_overflow_int := head_overflow; result_pipe(head_result_int) := result_stxiii_ext; if(chainout_saturation /= "NO") then overflow_stat_pipe_reg (head_overflow_int) := chainout_overflow_int; else overflow_stat_pipe_reg (head_overflow_int) := overflow_int; end if; head_result_int := (head_result_int +1) mod (extra_latency); head_overflow_int := (head_overflow_int +1) mod (extra_latency); overflow <= overflow_stat_pipe_reg(head_overflow_int); result <= result_pipe(head_result_int); head_result_siii <= head_result_int; head_overflow <= head_overflow_int; end if; if((width_a > 36) or (width_b > 36)) then if (rising_edge(clock0) or rising_edge(clock1) or rising_edge(clock2) or rising_edge(clock3)) then head_result_int := head_result_siii; head_overflow_int := head_overflow; result_pipe(head_result_int) := result_stxiii_ext; overflow_stat_pipe_reg (head_overflow) := overflow_int; head_result_int := (head_result_int +1) mod (extra_latency); head_overflow_int := (head_overflow_int +1) mod (extra_latency); overflow <= overflow_stat_pipe_reg(head_overflow_int); result <= result_pipe(head_result_int); head_result_siii <= head_result_int; head_overflow <= head_overflow_int; end if; end if; if((width_a > 36) or (width_b > 36)) then if (rising_edge(aclr0) or rising_edge(aclr1) or rising_edge(aclr2) or rising_edge(aclr3)) then for count in 0 to extra_latency loop result_pipe(count) := (others => '0'); head_result_siii <= 0; head_overflow <= 0; result <= (others => '0'); overflow <= '0'; end loop; end if; end if; if((output_register = "UNREGISTERED") and (width_a < 36 and width_b < 36)) then head_result_int := head_result_siii; result_pipe(head_result_int) := result_stxiii_ext; result <= result_pipe(head_result_int); if(chainout_saturation /= "NO") then overflow_stat_pipe_reg (head_overflow_int) := chainout_overflow_int; else overflow_stat_pipe_reg (head_overflow_int) := overflow_int; end if; overflow <= overflow_stat_pipe_reg(head_overflow_int); head_result_siii <= head_result_int; head_overflow <= head_overflow_int; end if; end if; end process; end generate IFGFAM5; IFGFAM6: if (stratixv_block and not(preadder_mode = "SIMPLE")) generate assert false report "Error: Stratix V simulation model not support other mode beside simple mode in the current Quartus II Version"; end generate IFGFAM6; end behaviour; -- end of ALTMULT_ADD -- START ENTITY HEADER --------------------------------------------------------- -- -- Entity Name : altfp_mult -- -- Description : Parameterized floating point multiplier megafunction. -- This module implements IEEE-754 Compliant Floating Poing -- Multiplier. The module supports Single Precision, Single -- Extended Precision, and Double Precision floating point -- multiplication. -- -- Limitations : Fixed clock latency with 4 clock cycle delay. -- --Results expected : result of multiplication and the result's status bits -- END ENTITY HEADER ----------------------------------------------------------- -- LIBRARY USED----------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use work.ALTERA_COMMON_CONVERSION.all; -- ENTITY DECLARATION entity altfp_mult is -- GENERIC DECLARATION generic ( -- exponent width, Minimum = 8, Maximum = 31 width_exp : natural := 8; -- mantissa width, Minimum = 23, Maximum = 52 width_man : natural := 23; -- Specifies whether to use dedicated multiplier circuitry. dedicated_multiplier_circuitry : string := "AUTO"; reduced_functionality : string := "NO"; pipeline : natural := 5; denormal_support : string := "YES"; exception_handling : string := "YES"; lpm_hint : string := "UNUSED"; lpm_type : string := "altfp_mult" ); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION -- Clock input to the multiplier.(Required) clock : in std_logic; -- Clock enable for the multiplier. clk_en : in std_logic := '1'; -- Asynchronous clear for the multiplier. aclr : in std_logic := '0'; -- Data input to the multiplier.(Required) dataa : in std_logic_vector(width_exp + width_man downto 0); datab : in std_logic_vector(width_exp + width_man downto 0); -- OUTPUT PORT DECLARATION -- Multiplier output port.(Required) result : out std_logic_vector(width_exp + width_man downto 0); overflow : out std_logic ; underflow : out std_logic ; zero : out std_logic; denormal : out std_logic ; indefinite : out std_logic; nan : out std_logic ); end altfp_mult; -- END OF ENTITY -- BEGINNING OF ACHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of altfp_mult is -- CONSTANT DECLARATION constant LATENCY : integer := pipeline -1; constant WIDTH_MAN_EXP : integer := width_exp + width_man; -- TYPE DECLARATION type PIPELINE_MULT is array (LATENCY downto 0) of std_logic_vector(WIDTH_MAN_EXP + 6 downto 0); -- FUNCTION DECLARATION -- Bitwise left shift procedure shift_left ( val : inout std_logic_vector) is variable temp : std_logic_vector((val'length - 1) downto 0); begin temp := val; if (val'length > 1) then for i in temp'high downto 1 loop temp(i) := temp(i-1); end loop; end if; temp(0) :='0'; val := temp; end shift_left; -- Bitwise right shift procedure shift_right ( cout: in std_logic; val : inout std_logic_vector ) is variable temp : std_logic_vector(val'length-1 downto 0); begin temp := val; if (val'length > 1) then for i in 0 to temp'high - 1 loop temp(i) := temp(i+1); end loop; end if; temp(temp'high) := cout; val := temp; end shift_right; -- Check whether all the bits is '0' or not function bit_all_0 ( val : std_logic_vector ) return boolean is variable all_0 : boolean := true; begin for i in val'range loop if (val(i) = '1') then all_0 := false; exit; end if; end loop; return all_0; end bit_all_0; -- Check whether all the bits is '0' or not (with specific range) function bit_all_0 (val : std_logic_vector; index1 : integer; index2 : integer ) return boolean is variable all_0 : boolean := true; begin for i in index1 to index2 loop if (val(i) = '1') then all_0 := false; exit; end if; end loop; return all_0; end bit_all_0; -- add val1 to temporary result procedure add_bits( val1 : in std_logic_vector; result : inout std_logic_vector; cout : out std_logic) is variable co : std_logic; variable i : integer := 0; begin co := '0'; for i in 0 to val1'high loop if (co = '0') then if (val1(i) /= result(i + width_man + 1)) then result(i + width_man + 1) := '1'; else co := val1(i) and result(i + width_man + 1); result(i + width_man + 1) := '0'; end if; else co := val1(i) or result(i + width_man + 1); if (val1(i) /= result(i + width_man + 1)) then result(i + width_man + 1) := '0'; else result(i + width_man + 1) := '1'; end if; end if; end loop; cout := co; end add_bits; begin -- basic error checking for invalid deserialization factors MSG: process begin -- Check for illegal mode setting if ((width_exp + width_man) >= 64) then ASSERT FALSE REPORT "The sum of width_exp (" & INT_TO_STR_ARITH(width_exp) & ") and width_man (" & INT_TO_STR_ARITH(width_man) & ") must be less than 64" SEVERITY ERROR; end if; if (width_exp < 8) then ASSERT FALSE REPORT "width_exp (" & INT_TO_STR_ARITH(width_exp) & ") must be at least 8" SEVERITY ERROR; end if; if (width_man < 23) then ASSERT FALSE REPORT "width_man (" & INT_TO_STR_ARITH(width_man) & ") must be at least 23" SEVERITY ERROR; end if; if not ((width_exp >= 11) or ((width_exp = 8) and (width_man = 23))) then ASSERT FALSE REPORT "Found width_exp (" & INT_TO_STR_ARITH(width_exp) & ") inside the range of Single Precision. width_exp must be 8" & " and width_man must be 23 for Single Precision" SEVERITY ERROR; end if; if not ((width_man >= 31) or ((width_exp = 8) and (width_man = 23))) then ASSERT FALSE REPORT "Found width_man (" & INT_TO_STR_ARITH(width_man) & ") inside the range of Single Precision. width_exp must be 8" & " and width_man must be 23 for Single Precision" SEVERITY ERROR; end if; if (width_exp >= width_man) then ASSERT FALSE REPORT "width_exp (" & INT_TO_STR_ARITH(width_exp) & ") must be less than width_man (" & INT_TO_STR_ARITH(width_man) & ")" SEVERITY ERROR; end if; if ((pipeline /= 5) and (pipeline /= 6) and (pipeline /= 10) and (pipeline /= 11)) then ASSERT FALSE REPORT "The legal value for pipeline is 5, 6, 10 or 11." SEVERITY ERROR; end if; if ((reduced_functionality /= "NO") and (reduced_functionality /= "YES")) then ASSERT FALSE REPORT "reduced_functionality value must be ""YES"" or ""NO""." SEVERITY ERROR; end if; if ((denormal_support /= "NO") and (denormal_support /= "YES")) then ASSERT FALSE REPORT "denormal_support value must be ""YES"" or ""NO""." SEVERITY ERROR; end if; if (reduced_functionality /= "NO") then ASSERT FALSE REPORT "The Clearbox support is available for reduced functionality Floating Point Multiplier." SEVERITY WARNING; end if; wait; end process; -- MSG process MULTIPLY_FP: process(clock, aclr) variable exp_dataa : integer := 0; variable exp_datab : integer := 0; variable exp_result : integer := 0; variable mant_dataa : std_logic_vector (width_man downto 0) := (others => '0'); variable mant_datab : std_logic_vector (width_man downto 0) := (others => '0'); variable mant_result : std_logic_vector ((2 * (width_man + 1)) - 1 downto 0) := (others => '0'); variable cout : std_logic := '0'; variable zero_mant_dataa : boolean := false; variable zero_mant_datab : boolean := false; variable zero_dataa : boolean := false; variable zero_datab : boolean := false; variable inf_dataa : boolean := false; variable inf_datab : boolean := false; variable nan_dataa : boolean := false; variable nan_datab : boolean := false; variable den_dataa : boolean := false; variable den_datab : boolean := false; variable no_multiply : boolean := false; variable no_rounding : boolean := false; variable mant_result_msb : std_logic := '0'; variable sticky_bit : std_logic := '0'; variable round_bit : std_logic := '0'; variable guard_bit : std_logic := '0'; variable carry : boolean := false; variable temp_result : PIPELINE_MULT := (others => (others => '0')); begin if (aclr = '1') then --clear the output ports temp_result := (others => (others => '0')); for i in LATENCY downto 0 loop temp_result(i)(WIDTH_MAN_EXP + 3) := '1'; -- set zero status end loop; result <= (others => '0'); overflow <= '0'; underflow <= '0'; zero <= '1'; denormal <= '0'; indefinite <= '0'; nan <= '0'; elsif (clock = '1') and clock'event and (clock'last_value = '0') then if (clk_en = '1') then -- Create latency for the output result for i in LATENCY downto 1 loop temp_result(i) := temp_result(i - 1); end loop; temp_result(0) := (others => '0'); mant_result := (others => '0'); --convert exponent of dataa[] to integer exp_dataa := 0; for i in 0 to width_exp -1 loop if (dataa(width_man + i) = '1') then exp_dataa := (2**i) + exp_dataa; end if; end loop; --convert exponent of datab[] to integer exp_datab := 0; for i in 0 to width_exp -1 loop if (datab(width_man + i) = '1') then exp_datab := (2**i) + exp_datab; end if; end loop; --check whether all the bits in mantissa of dataa[] is '0' zero_mant_dataa := true; for i in 0 to width_man -1 loop if (dataa(i) = '1') then zero_mant_dataa := false; exit; end if; end loop; --check whether all the bits in mantissa of datab[] is '0' zero_mant_datab := true; for i in 0 to width_man -1 loop if (datab(i) = '1') then zero_mant_datab := false; exit; end if; end loop; --check whether dataa is special input zero_dataa := false; den_dataa := false; inf_dataa := false; nan_dataa := false; if (exp_dataa = 0) then if ((zero_mant_dataa = true) or (reduced_functionality /= "NO")) then zero_dataa := true; else if (denormal_support = "YES") then den_dataa := true; else zero_dataa := true; end if; end if; elsif (exp_dataa = (2**width_exp) -1) then if (zero_mant_dataa = true) then inf_dataa := true; else nan_dataa := true; end if; end if; --check whether datab is special input zero_datab := false; den_datab := false; inf_datab := false; nan_datab := false; if (exp_datab = 0) then if ((zero_mant_datab = true) or (reduced_functionality /= "NO")) then zero_datab := true; else if (denormal_support = "YES") then den_datab := true; else zero_datab := true; end if; end if; elsif (exp_datab = (2**width_exp) -1) then if (zero_mant_datab = true) then inf_datab := true; else nan_datab := true; end if; end if; --set status flag if special input exists no_multiply := false; if (nan_dataa or nan_datab or (inf_dataa and zero_datab) or (inf_datab and zero_dataa)) then temp_result(0)(WIDTH_MAN_EXP + 6) := '1'; --NaN temp_result(0)(WIDTH_MAN_EXP - 1 downto width_man -1) := (others => '1'); no_multiply := true; elsif (zero_dataa) then temp_result(0)(WIDTH_MAN_EXP + 3) := '1'; --zero result temp_result(0)(WIDTH_MAN_EXP downto 0) := (others => '0'); no_multiply := true; elsif (zero_datab) then temp_result(0)(WIDTH_MAN_EXP + 3) := '1'; --zero result temp_result(0)(WIDTH_MAN_EXP downto 0) := (others => '0'); no_multiply := true; elsif (inf_dataa) then temp_result(0)(WIDTH_MAN_EXP + 1) := '1'; --overflow temp_result(0)(WIDTH_MAN_EXP downto 0) := dataa; --result no_multiply := true; elsif (inf_datab) then temp_result(0)(WIDTH_MAN_EXP + 1) := '1'; --overflow temp_result(0)(WIDTH_MAN_EXP downto 0) := datab; --result no_multiply := true; end if; -- do multiplication if (no_multiply = false) then --perform exponent operation exp_result := (exp_dataa + exp_datab) - ((2**(width_exp -1)) - 1); -- mantissa multiplication --first operand for multiplication mant_dataa(width_man downto 0) := "1" & dataa(width_man - 1 downto 0); --second operand for multiplication mant_datab(width_man downto 0) := "1" & datab(width_man - 1 downto 0); --multiplication using add and shift algorithm for i in 0 to width_man loop cout := '0'; if (mant_dataa(i) = '1') then add_bits(mant_datab, mant_result, cout); end if; shift_right(cout, mant_result); end loop; sticky_bit := '0'; mant_result_msb := mant_result(mant_result'high); --Normalize the Result if (mant_result_msb = '1') then sticky_bit := mant_result(mant_result'low); shift_right('0', mant_result); exp_result := exp_result + 1; end if; round_bit := mant_result(width_man - 1); guard_bit := mant_result(width_man); no_rounding := false; -- check whether should perform rounding or not if (round_bit = '0') then no_rounding := true; else if (reduced_functionality = "NO") then for i in 0 to width_man - 2 loop sticky_bit := sticky_bit or mant_result(i); end loop; else sticky_bit := (mant_result(width_man - 2) and mant_result_msb); end if; if ((sticky_bit = '0') and (guard_bit = '0')) then no_rounding := true; end if; end if; if (no_rounding = false) then --do rounding carry := true; for i in width_man to mant_result'high loop if (carry = true) then if (mant_result(i) = '0') then mant_result(i) := '1'; carry := false; else mant_result(i) := '0'; end if; end if; end loop; -- If the mantissa of the result is 10.00.. after rounding, right shift the -- mantissa of the result by 1 bit and increase the exponent of the result by 1. if (mant_result(mant_result'high) = '1') then shift_right('0', mant_result); exp_result := exp_result + 1; end if; end if; --Normalize the Result if ((not bit_all_0(mant_result)) and (mant_result(mant_result'high -1) = '0')) then while ((mant_result(mant_result'high -1) = '0') and (exp_result /= 0)) loop shift_left(mant_result); exp_result := exp_result - 1; end loop; elsif ((exp_result < 0) and (exp_result >= - (2 * width_man))) then while (exp_result /= 0) loop shift_right('0', mant_result); exp_result := exp_result + 1; end loop; end if; --set status flag "indefinite" if normal * denormal --(ignore other status port since we dont care the output if (den_dataa or den_datab) then temp_result(0)(WIDTH_MAN_EXP + 5) := '1'; --indefinite --set status flag if special output exists elsif (exp_result >= ((2**width_exp) - 1)) then temp_result(0)(WIDTH_MAN_EXP + 1) := '1'; --overflow elsif (exp_result < 0) then temp_result(0)(WIDTH_MAN_EXP + 2) := '1'; --underflow temp_result(0)(WIDTH_MAN_EXP + 3) := '1'; --zero elsif (exp_result = 0) then temp_result(0)(WIDTH_MAN_EXP + 2) := '1'; --underflow if (bit_all_0 (mant_result, width_man + 1, mant_result'high -1)) then temp_result(0)(WIDTH_MAN_EXP + 3) := '1'; --zero else temp_result(0)(WIDTH_MAN_EXP + 4) := '1'; --denormal end if; end if; --get result mantissa if (exp_result < 0) then --result underflow temp_result(0)(width_man - 1 downto 0) := (others => '0'); elsif (exp_result = 0) then --denormalized output if ((reduced_functionality = "NO") and (denormal_support = "YES")) then for i in (mant_result'high - 1) downto (mant_result'high - width_man) loop temp_result(0)(i - width_man - 1) := mant_result(i); end loop; else temp_result(0)(width_man - 1 downto 0) := (others => '0'); temp_result(0)(WIDTH_MAN_EXP + 3) := '1'; end if; elsif exp_result >= ((2**width_exp) -1) then --result overflow temp_result(0)(width_man - 1 downto 0) := (others => '0'); elsif (exp_result > 0) then --normalized output for i in (mant_result'high - 2) downto (mant_result'high - width_man - 1) loop temp_result(0)(i - width_man) := mant_result(i); end loop; end if; --get result exponent if (exp_result <= 0) then temp_result(0)(WIDTH_MAN_EXP -1 downto width_man) := (others => '0'); elsif (exp_result >= ((2**width_exp) -1)) then for i in width_man to (WIDTH_MAN_EXP -1) loop temp_result(0)(i) := '1'; end loop; else --convert integer to binary bit for i in width_man to (WIDTH_MAN_EXP -1) loop if ((exp_result mod 2) = 1) then temp_result(0)(i) := '1'; else temp_result(0)(i) := '0'; end if; exp_result := exp_result / 2; end loop; end if; end if; --get result sign temp_result(0)(WIDTH_MAN_EXP) := dataa(dataa'high) xor datab(datab'high); end if; end if; --output port result <= temp_result(LATENCY)(WIDTH_MAN_EXP downto 0 ); overflow <= temp_result(LATENCY)(WIDTH_MAN_EXP + 1 ); if ((reduced_functionality = "YES") or (denormal_support = "YES")) then underflow <= temp_result(LATENCY)(WIDTH_MAN_EXP + 2 ); else underflow <= '0'; end if; if (reduced_functionality = "NO") then zero <= temp_result(LATENCY)(WIDTH_MAN_EXP + 3 ); if (denormal_support = "YES") then denormal <= temp_result(LATENCY)(WIDTH_MAN_EXP + 4 ); indefinite <= temp_result(LATENCY)(WIDTH_MAN_EXP + 5 ); else denormal <= '0'; indefinite <= '0'; end if; else zero <= '0'; denormal <= '0'; indefinite <= '0'; end if; nan <= temp_result(LATENCY)(WIDTH_MAN_EXP + 6 ); end process MULTIPLY_FP; end behavior; -- altfp_mult -- END OF ARCHITECTURE -- START ENTITY HEADER --------------------------------------------------------- -- -- Entity Name : altsqrt -- -- Description : Parameterized integer square root megafunction. -- This module computes q[] and remainder so that -- q[]^2 + remainder[] == radical[] (remainder <= 2 * q[]) -- It can support the sequential mode(pipeline > 0) or -- combinational mode (pipeline = 0). -- -- Limitations : The radical is assumed to be unsigned integer. -- --Results expected : Square root of the radical and the remainder. -- END ENTITY HEADER ----------------------------------------------------------- -- LIBRARY USED library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.ALTERA_COMMON_CONVERSION.all; -- ENTITY DECLARATION entity altsqrt is -- GENERIC DECLARATION generic ( q_port_width : natural := 1; -- The width of the q port r_port_width : natural := 1; -- The width of the remainder port width : natural := 1; -- The width of the radical pipeline : natural := 0; -- The latency for the output -- (0 for comb. mode) lpm_hint : string := "UNUSED"; lpm_type : string := "altsqrt" ); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION -- Input port for the radical radical : in std_logic_vector(width - 1 downto 0); -- Clock port clk : in std_logic := '1'; -- Clock enable port ena : in std_logic := '1'; -- Asynchronous clear port aclr : in std_logic := '0'; -- OUTPUT PORT DECLARATION -- Output port for returning the square root of the radical q : out std_logic_vector( q_port_width - 1 downto 0) := (others => '0'); -- Output port for returning the remainder of the square root. remainder : out std_logic_vector( r_port_width - 1 downto 0) := (others => '0') ); end altsqrt; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE architecture behavior of altsqrt is -- TYPE DECLARATION type PIPELINE_Q is array (pipeline downto 0) of std_logic_vector( q_port_width - 1 downto 0); type PIPELINE_R is array (pipeline downto 0) of std_logic_vector( r_port_width - 1 downto 0); -- SIGNAL DECLARATION signal q_pipe : std_logic_vector (q_port_width - 1 downto 0) := (others => '0'); signal q_value : std_logic_vector (q_port_width - 1 downto 0) := (others => '0'); signal remainder_pipe : std_logic_vector (r_port_width - 1 downto 0) := (others => '0'); signal remainder_value : std_logic_vector (r_port_width - 1 downto 0) := (others => '0'); begin -- SIGNAL ASSIGNMENTS q <= q_pipe when (pipeline > 0) else q_value; remainder <= remainder_pipe when (pipeline > 0) else remainder_value; -- PROCESS DECLARATION -- Perform square root calculation. -- In general, below are the steps to calculate the square root and the -- remainder. -- -- Start of with q = 0 and remainder= 0 -- For every iteration, do the same thing: -- 1) Shift in the next 2 bits of the radical into the remainder -- Eg. if the radical is b"101100". For the first iteration, -- the remainder will be equal to b"10". -- 2) Compare it to the 4* q + 1 -- 3) if the remainder is greater than or equal to 4*q + 1 -- remainder = remainder - (4*q + 1) -- q = 2*q + 1 -- otherwise -- q = 2*q SQUARE_ROOT: process(radical) variable value1 : integer := 0; variable value2 : integer := 0; variable i : integer := 0; variable index : integer := 0; variable q_index : integer := 0; variable q_temp : std_logic_vector (q_port_width - 1 downto 0) := (others => '0'); variable q_value_temp : std_logic_vector (q_port_width - 1 downto 0) := (others => '0'); variable q_value_comp : std_logic_vector (r_port_width downto 0) := (others => '0'); variable r_temp : std_logic_vector (r_port_width downto 0) := (others => '0'); variable radical_tmp : std_logic_vector(width - 1 downto 0) := (others => '0'); begin -- Check for illegal mode if (width < 1) then ASSERT FALSE REPORT "width (" & INT_TO_STR_ARITH(width) & ") must be greater than 0." SEVERITY ERROR; end if; -- Reset variables value1 := 0; value2 := 0; q_index := (width - 1) / 2; index := width; q_temp := (others => '0'); q_value_temp := (others => '0'); q_value_comp := (others => '0'); r_temp := (others => '0'); radical_tmp := radical; -- If the number of the bits of the radical is an odd number, -- Then for the first iteration, only the 1st bit will be shifted -- into the remainder. -- Eg. if the radical is b"11111", then the remainder is b"01". if ((width rem 2) = 1) then value1 := 0; if (radical_tmp(width - 1) = '1') then value2 := 1; else value2 := 0; end if; index := index + 1; elsif (width > 1) then -- Otherwise, for the first iteration, the first two bits will be -- shifted into the remainder. -- Eg. if the radical is b"101111", then the remainder is b"10". if (radical_tmp(width - 1) = '1') then value1 := 1; else value1 := 0; end if; if (radical_tmp(width - 2) = '1') then value2 := 1; else value2 := 0; end if; end if; -- For every iteration while (index >= 2) loop -- Get the remainder value by shifting in the next 2 bits -- of the radical into the remainder r_temp := r_temp(r_port_width-2 downto 0) & conv_std_logic_vector(value1, 1) & conv_std_logic_vector(value2, 1); q_value_comp := q_value_temp(q_port_width-1 downto 0) & conv_std_logic_vector(1, 2); -- if remainder >= (4*q + 1) if (r_temp >= q_value_comp) then -- remainder = remainder - (4*q + 1) r_temp := r_temp - q_value_comp; -- q = 2*q + 1 q_value_temp := q_value_temp(q_port_width-2 downto 0) & conv_std_logic_vector(1, 1); -- set the q[q_index] = 1 q_temp(q_index) := '1'; else -- if remainder < (4*q + 1) -- q = 2*q q_value_temp := q_value_temp(q_port_width-2 downto 0) & '0'; -- set the q[q_index] = 0 q_temp(q_index) := '0'; end if; index := index - 2; -- if not the last iteration, get the next 2 bits of the radical if (index >= 2) then if (radical(index - 1) = '1') then value1 := 1; else value1 := 0; end if; if (radical(index - 2) = '1') then value2 := 1; else value2 := 0; end if; end if; -- Reduce the current index of q by 1 q_index := q_index - 1; end loop; -- Store current result into the pipeline to create latency q_value <= q_temp; remainder_value <= r_temp(r_port_width-1 downto 0); end process SQUARE_ROOT; PIPELINE_REG : process(clk, aclr) variable pipe_ptr : natural := 0; variable q_pipeline : PIPELINE_Q := (others => (others => '0')); variable remainder_pipeline : PIPELINE_R := (others => (others => '0')); begin -- if asynchronous clear signal has been asserted if (aclr = '1') then -- reset pipelines and clear the output ports q_pipeline := (others => (others => '0')); remainder_pipeline := (others => (others => '0')); q_pipe <= (others => '0'); remainder_pipe <= (others => '0'); elsif (rising_edge(clk)) then if (ena = '1') then q_pipeline(pipe_ptr) := q_value; remainder_pipeline(pipe_ptr) := remainder_value; if (pipeline > 1) then pipe_ptr := (pipe_ptr + 1) mod pipeline; end if; q_pipe <= q_pipeline(pipe_ptr); remainder_pipe <= remainder_pipeline(pipe_ptr); end if; end if; end process PIPELINE_REG; end behavior; -- altsqrt -- END OF ARCHITECTURE -- START ENTITY HEADER --------------------------------------------------------- -- -- Entity Name : ALTCLKLOCK -- -- Description : Phase-Locked Loop (PLL) behavioral model. Supports basic -- PLL features such as multiplication and division of input -- clock frequency and phase shift. -- -- Limitations : Model supports NORMAL operation mode only. External -- feedback mode and zero-delay-buffer mode are not simulated. -- -- Expected results : Up to 4 clock outputs (clock0, clock1, clock2, clock_ext). -- locked output indicates when PLL locks. -- -- END ENTITY HEADER ----------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.ALTERA_DEVICE_FAMILIES.all; -- ENTITY DECLARATION entity altclklock is generic( inclock_period : natural := 10000; -- units in ps inclock_settings : string := "UNUSED"; valid_lock_cycles : natural := 5; invalid_lock_cycles : natural := 5; valid_lock_multiplier : natural := 5; invalid_lock_multiplier : natural := 5; operation_mode : string := "NORMAL"; clock0_boost : natural := 1; clock0_divide : natural := 1; clock0_settings : string := "UNUSED"; clock0_time_delay : string := "0"; clock1_boost : natural := 1; clock1_divide : natural := 1; clock1_settings : string := "UNUSED"; clock1_time_delay : string := "0"; clock2_boost : natural := 1; clock2_divide : natural := 1; clock2_settings : string := "UNUSED"; clock2_time_delay : string := "0"; clock_ext_boost : natural := 1; clock_ext_divide : natural := 1; clock_ext_settings : string := "UNUSED"; clock_ext_time_delay : string := "0"; outclock_phase_shift : natural := 0; -- units in ps intended_device_family : string := "Stratix" ; lpm_type : string := "altclklock"; lpm_hint : string := "UNUSED" ); port( inclock : in std_logic; -- required port, input reference clock inclocken : in std_logic := '1'; -- PLL enable signal fbin : in std_logic := '1'; -- feedback input for the PLL clock0 : out std_logic; -- clock0 output clock1 : out std_logic; -- clock1 output clock2 : out std_logic; -- clock2 output clock_ext : out std_logic; -- external clock output locked : out std_logic -- PLL lock signal ); -- -- function time_delay - converts time_delay in string format to time, and -- add result to outclock_phase_shift -- function time_delay (s : string) return time is -- VARIABLE DECLARATION variable outclock_phase_shift_adj : integer := 0; variable len : integer := s'length; 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) & "in 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; outclock_phase_shift_adj := (outclock_phase_shift_adj * 10) + digit; end loop; -- add outclock phase shift to the time delay outclock_phase_shift_adj := outclock_phase_shift + (sign * outclock_phase_shift_adj); -- adjust phase shift so that it is between 0 and 1 full inclock_period while (outclock_phase_shift_adj < 0) loop outclock_phase_shift_adj := outclock_phase_shift_adj + inclock_period; end loop; while (outclock_phase_shift_adj >= inclock_period) loop outclock_phase_shift_adj := outclock_phase_shift_adj - inclock_period; end loop; -- return the phase shift in ps return (outclock_phase_shift_adj * 1 ps); end; end altclklock; -- END ENTITY DECLARATION -- BEGINNING OF ARCHITECTURE BEHAVIOR architecture behavior of altclklock is -- SIGNAL DECLARATION SIGNAL pll_lock : std_logic := '0'; SIGNAL check_lock : std_logic := '0'; SIGNAL clk0_tmp : std_logic := 'X'; SIGNAL clk1_tmp : std_logic := 'X'; SIGNAL clk2_tmp : std_logic := 'X'; SIGNAL extclk_tmp : std_logic := 'X'; begin -- checking for invalid parameters MSG: process begin if (inclock_period <= 0) then ASSERT FALSE REPORT "The period of the input clock (inclock_period) must be greater than 0" SEVERITY ERROR; end if; if ((clock0_boost <= 0) or (clock0_divide <= 0)) then ASSERT FALSE REPORT "The multiplication and division factors for clock0 must be greater than 0" SEVERITY ERROR; end if; if ((clock1_boost <= 0) or (clock1_divide <= 0)) then ASSERT FALSE REPORT "The multiplication and division factors for clock1 must be greater than 0" SEVERITY ERROR; end if; if ((clock2_boost <= 0) or (clock2_divide <= 0)) then ASSERT FALSE REPORT "The multiplication and division factors for clock2 must be greater than 0" SEVERITY ERROR; end if; if ((clock_ext_boost <= 0) or (clock_ext_divide <= 0)) then ASSERT FALSE REPORT "The multiplication and division factors for clock_ext must be greater than 0" SEVERITY ERROR; end if; if (FEATURE_FAMILY_STRATIX(intended_device_family) = false) then ASSERT FALSE REPORT "Device family specified by the intended_device_family parameter, "& intended_device_family &", may not be supported by altclklock" SEVERITY WARNING; end if; wait; end process MSG; LOCK: process(inclock, inclocken, pll_lock, check_lock) -- VARIABLE DECLARATION variable inclk_ps : time := 0 ps; variable violation : boolean := false; variable pll_lock_tmp : std_logic := '0'; variable start_lock_count, stop_lock_count : integer := 0; variable pll_last_rising_edge, pll_last_falling_edge : time := 0 ps; variable pll_rising_edge_count : integer := 0; variable pll_cycle, pll_duty_cycle : time := 0 ps; variable expected_next_clk_edge : time := 0 ps; variable clk_per_tolerance : time := 0 ps; variable last_synchronizing_rising_edge_for_clk0 : time := 0 ps; variable last_synchronizing_rising_edge_for_clk1 : time := 0 ps; variable last_synchronizing_rising_edge_for_clk2 : time := 0 ps; variable last_synchronizing_rising_edge_for_extclk : time := 0 ps; variable input_cycles_per_clk0 : integer := clock0_divide; variable input_cycles_per_clk1 : integer := clock1_divide; variable input_cycles_per_clk2 : integer := clock2_divide; variable input_cycles_per_extclk : integer := clock_ext_divide; variable input_cycle_count_to_sync0 : integer := 0; variable input_cycle_count_to_sync1 : integer := 0; variable input_cycle_count_to_sync2 : integer := 0; variable input_cycle_count_to_sync_extclk : integer := 0; variable init : boolean := true; variable output_value : std_logic := '0'; variable vco_per : time := 0 ps; variable high_time : time := 0 ps; variable low_time : time := 0 ps; variable sched_time : time := 0 ps; variable tmp_per : integer := 0; variable temp, tmp_rem, my_rem : integer := 0; variable inc : integer := 1; variable cycle_to_adjust : integer := 0; variable clk0_synchronizing_period, clk1_synchronizing_period : time; variable clk2_synchronizing_period, extclk_synchronizing_period : time; variable clk0_cycles_per_sync_period : integer := clock0_boost; variable clk1_cycles_per_sync_period : integer := clock1_boost; variable clk2_cycles_per_sync_period : integer := clock2_boost; variable extclk_cycles_per_sync_period : integer := clock_ext_boost; variable schedule_clk0, schedule_clk1 : boolean := false; variable schedule_clk2, schedule_extclk : boolean := false; variable clk0_phase_delay : time := time_delay(clock0_time_delay); variable clk1_phase_delay : time := time_delay(clock1_time_delay); variable clk2_phase_delay : time := time_delay(clock2_time_delay); variable extclk_phase_delay : time := time_delay(clock_ext_time_delay); begin if (init) then if ((clock0_boost rem clock0_divide) = 0) then clk0_cycles_per_sync_period := clock0_boost / clock0_divide; input_cycles_per_clk0 := 1; end if; if ((clock1_boost rem clock1_divide) = 0) then clk1_cycles_per_sync_period := clock1_boost / clock1_divide; input_cycles_per_clk1 := 1; end if; if ((clock2_boost rem clock2_divide) = 0) then clk2_cycles_per_sync_period := clock2_boost / clock2_divide; input_cycles_per_clk2 := 1; end if; if ((clock_ext_boost rem clock_ext_divide) = 0) then extclk_cycles_per_sync_period := clock_ext_boost / clock_ext_divide; input_cycles_per_extclk := 1; end if; clk_per_tolerance := (0.1 * real(inclock_period)) * 1 ps; init := false; end if; if (inclocken = '0') then pll_lock_tmp := '0'; pll_rising_edge_count := 0; elsif (inclock'event and inclock = '1') then if (pll_lock_tmp = '1') then check_lock <= not check_lock after (inclk_ps+clk_per_tolerance)/2.0; end if; if pll_rising_edge_count = 0 then -- at 1st rising edge inclk_ps := (inclock_period / 1) * 1 ps; pll_duty_cycle := inclk_ps/2; elsif pll_rising_edge_count = 1 then -- at 2nd rising edge pll_cycle := now - pll_last_rising_edge; -- calculate period if ((NOW - pll_last_rising_edge) < (inclk_ps - clk_per_tolerance) or (NOW - pll_last_rising_edge) > (inclk_ps + clk_per_tolerance)) then ASSERT FALSE REPORT "Inclock_Period Violation" SEVERITY WARNING; violation := true; if (pll_lock = '1') then stop_lock_count := stop_lock_count + 1; if (stop_lock_count = invalid_lock_cycles) then pll_lock_tmp := '0'; ASSERT FALSE REPORT "altclklock out of lock." SEVERITY WARNING; end if; else start_lock_count := 1; end if; else violation := false; end if; if ((now - pll_last_falling_edge) < (pll_duty_cycle - clk_per_tolerance/2) or (now - pll_last_falling_edge) > (pll_duty_cycle + clk_per_tolerance/2)) then ASSERT FALSE REPORT "Duty Cycle Violation" SEVERITY WARNING; violation := true; else violation := false; end if; else pll_cycle := now - pll_last_rising_edge; -- calculate period if ((now - pll_last_rising_edge) < (inclk_ps - clk_per_tolerance) or (now - pll_last_rising_edge) > (inclk_ps + clk_per_tolerance)) then ASSERT FALSE REPORT "Cycle Violation" SEVERITY WARNING; violation := true; if (pll_lock = '1') then stop_lock_count := stop_lock_count + 1; if (stop_lock_count = invalid_lock_cycles) then pll_lock_tmp := '0'; ASSERT FALSE REPORT "altclklock out of lock." SEVERITY WARNING; end if; else start_lock_count := 1; end if; else violation := false; end if; end if; pll_last_rising_edge := now; pll_rising_edge_count := pll_rising_edge_count +1; if (not violation) then if (pll_lock_tmp = '1') then input_cycle_count_to_sync0 := input_cycle_count_to_sync0 + 1; if (input_cycle_count_to_sync0 = input_cycles_per_clk0) then clk0_synchronizing_period := now - last_synchronizing_rising_edge_for_clk0; last_synchronizing_rising_edge_for_clk0 := now; schedule_clk0 := true; input_cycle_count_to_sync0 := 0; end if; input_cycle_count_to_sync1 := input_cycle_count_to_sync1 + 1; if (input_cycle_count_to_sync1 = input_cycles_per_clk1) then clk1_synchronizing_period := now - last_synchronizing_rising_edge_for_clk1; last_synchronizing_rising_edge_for_clk1 := now; schedule_clk1 := true; input_cycle_count_to_sync1 := 0; end if; input_cycle_count_to_sync2 := input_cycle_count_to_sync2 + 1; if (input_cycle_count_to_sync2 = input_cycles_per_clk2) then clk2_synchronizing_period := now - last_synchronizing_rising_edge_for_clk2; last_synchronizing_rising_edge_for_clk2 := now; schedule_clk2 := true; input_cycle_count_to_sync2 := 0; end if; input_cycle_count_to_sync_extclk := input_cycle_count_to_sync_extclk + 1; if (input_cycle_count_to_sync_extclk = input_cycles_per_extclk) then extclk_synchronizing_period := now - last_synchronizing_rising_edge_for_extclk; last_synchronizing_rising_edge_for_extclk := now; schedule_extclk := true; input_cycle_count_to_sync_extclk := 0; end if; else start_lock_count := start_lock_count + 1; if (start_lock_count >= valid_lock_cycles) then pll_lock_tmp := '1'; input_cycle_count_to_sync0 := 0; input_cycle_count_to_sync1 := 0; input_cycle_count_to_sync2 := 0; input_cycle_count_to_sync_extclk := 0; clk0_synchronizing_period := ((pll_cycle/1 ps) * input_cycles_per_clk0) * 1 ps; clk1_synchronizing_period := ((pll_cycle/1 ps) * input_cycles_per_clk1) * 1 ps; clk2_synchronizing_period := ((pll_cycle/1 ps) * input_cycles_per_clk2) * 1 ps; extclk_synchronizing_period := ((pll_cycle/1 ps) * input_cycles_per_extclk) * 1 ps; last_synchronizing_rising_edge_for_clk0 := now; last_synchronizing_rising_edge_for_clk1 := now; last_synchronizing_rising_edge_for_clk2 := now; last_synchronizing_rising_edge_for_extclk := now; schedule_clk0 := true; schedule_clk1 := true; schedule_clk2 := true; schedule_extclk := true; end if; end if; else start_lock_count := 1; end if; elsif (inclock'event and inclock= '0') then if (pll_lock_tmp = '1') then check_lock <= not check_lock after (inclk_ps+clk_per_tolerance)/2.0; if (now > 0 ns and ((now - pll_last_rising_edge) < (pll_duty_cycle - clk_per_tolerance/2) or (now - pll_last_rising_edge) > (pll_duty_cycle + clk_per_tolerance/2))) then ASSERT FALSE REPORT "Duty Cycle Violation" SEVERITY WARNING; violation := true; if (pll_lock = '1') then stop_lock_count := stop_lock_count + 1; if (stop_lock_count = invalid_lock_cycles) then pll_lock_tmp := '0'; ASSERT FALSE REPORT "altclklock out of lock." SEVERITY WARNING; end if; end if; else violation := false; end if; else start_lock_count := start_lock_count + 1; end if; pll_last_falling_edge := now; else if pll_lock_tmp = '1' then if (inclock = '1') then expected_next_clk_edge := pll_last_rising_edge + (inclk_ps+clk_per_tolerance)/2.0; else expected_next_clk_edge := pll_last_falling_edge + (inclk_ps+clk_per_tolerance)/2.0; end if; violation := false; if (now < expected_next_clk_edge) then check_lock <= not check_lock after (expected_next_clk_edge - now); elsif (now = expected_next_clk_edge) then check_lock <= not check_lock after (inclk_ps+clk_per_tolerance)/2.0; else ASSERT FALSE REPORT "Inclock_Period Violation" SEVERITY WARNING; violation := true; if (pll_lock = '1') then stop_lock_count := stop_lock_count + 1; if (stop_lock_count = invalid_lock_cycles) then pll_lock_tmp := '0'; ASSERT FALSE REPORT "altclklock out of lock." SEVERITY WARNING; else check_lock <= not check_lock after (inclk_ps/2.0); end if; end if; end if; end if; end if; pll_lock <= pll_lock_tmp; if (pll_lock'event and pll_lock = '0') then start_lock_count := 1; stop_lock_count := 0; clk0_tmp <= 'X'; clk1_tmp <= 'X'; clk2_tmp <= 'X'; extclk_tmp <= 'X'; end if; -- clock0 output if (schedule_clk0 = true) then -- initialize variables sched_time := clk0_phase_delay; cycle_to_adjust := 0; inc := 1; output_value := '1'; temp := clk0_synchronizing_period / 1 ps; my_rem := temp rem clk0_cycles_per_sync_period; -- schedule number of output clock -- cycles in this loop in order to synchronize the output clock to the -- input clock - to get rid of drifting for cases where the input clock -- period is not always divisible for i in 1 to clk0_cycles_per_sync_period loop tmp_per := temp/clk0_cycles_per_sync_period; if ((my_rem /= 0) and (inc <= my_rem)) then tmp_rem := (clk0_cycles_per_sync_period * inc) rem my_rem; cycle_to_adjust := (clk0_cycles_per_sync_period * inc) / my_rem; if (tmp_rem /= 0) then cycle_to_adjust := cycle_to_adjust + 1; end if; end if; -- if this cycle is the one to adjust the output period in, then -- increment the period by 1 unit if (cycle_to_adjust = i) then tmp_per := tmp_per + 1; inc := inc + 1; end if; -- adjust the high and low cycle period vco_per := tmp_per * 1 ps; high_time := (tmp_per / 2) * 1 ps; if ((tmp_per rem 2) /= 0) then high_time := high_time + 1 ps; end if; low_time := vco_per - high_time; -- schedule the high and low cycle of 1 output clock period for j in 1 to 2 loop clk0_tmp <= transport output_value after sched_time; output_value := not output_value; if (output_value = '0') then sched_time := sched_time + high_time; elsif (output_value = '1') then sched_time := sched_time + low_time; end if; end loop; end loop; -- reset schedule_clk0 schedule_clk0 := false; end if; -- schedule_clk0 if (schedule_clk1 = true) then -- initialize variables sched_time := clk1_phase_delay; cycle_to_adjust := 0; inc := 1; output_value := '1'; temp := clk1_synchronizing_period / 1 ps; my_rem := temp rem clk1_cycles_per_sync_period; -- schedule number of output clock -- cycles in this loop in order to synchronize the output clock to the -- input clock - to get rid of drifting for cases where the input clock -- period is not always divisible for i in 1 to clk1_cycles_per_sync_period loop tmp_per := temp/clk1_cycles_per_sync_period; if ((my_rem /= 0) and (inc <= my_rem)) then tmp_rem := (clk1_cycles_per_sync_period * inc) rem my_rem; cycle_to_adjust := (clk1_cycles_per_sync_period * inc) / my_rem; if (tmp_rem /= 0) then cycle_to_adjust := cycle_to_adjust + 1; end if; end if; -- if this cycle is the one to adjust the output period in, then -- increment the period by 1 unit if (cycle_to_adjust = i) then tmp_per := tmp_per + 1; inc := inc + 1; end if; -- adjust the high and low cycle period vco_per := tmp_per * 1 ps; high_time := (tmp_per/2) * 1 ps; if ((tmp_per rem 2) /= 0) then high_time := high_time + 1 ps; end if; low_time := vco_per - high_time; -- schedule the high and low cycle of 1 output clock period for j in 1 to 2 loop clk1_tmp <= transport output_value after sched_time; output_value := not output_value; if (output_value = '0') then sched_time := sched_time + high_time; elsif (output_value = '1') then sched_time := sched_time + low_time; end if; end loop; end loop; -- reset schedule_clk1 schedule_clk1 := false; end if; -- schedule_clk1 if (FEATURE_FAMILY_STRATIX(intended_device_family)) then -- clock2 output if (schedule_clk2 = true) then -- initialize variables sched_time := clk2_phase_delay; cycle_to_adjust := 0; inc := 1; output_value := '1'; temp := clk2_synchronizing_period/1 ps; my_rem := temp rem clk2_cycles_per_sync_period; -- schedule number of output clock -- cycles in this loop in order to synchronize the output clock to the -- input clock - to get rid of drifting for cases where the input clock -- period is not always divisible for i in 1 to clk2_cycles_per_sync_period loop tmp_per := temp/clk2_cycles_per_sync_period; if ((my_rem /= 0) and (inc <= my_rem)) then tmp_rem := (clk2_cycles_per_sync_period * inc) rem my_rem; cycle_to_adjust := (clk2_cycles_per_sync_period * inc) / my_rem; if (tmp_rem /= 0) then cycle_to_adjust := cycle_to_adjust + 1; end if; end if; -- if this cycle is the one to adjust the output period in, then -- increment the period by 1 unit if (cycle_to_adjust = i) then tmp_per := tmp_per + 1; inc := inc + 1; end if; -- adjust the high and low cycle period vco_per := tmp_per * 1 ps; high_time := (tmp_per/2) * 1 ps; if ((tmp_per rem 2) /= 0) then high_time := high_time + 1 ps; end if; low_time := vco_per - high_time; -- schedule the high and low cycle of 1 output clock period for j in 1 to 2 loop clk2_tmp <= transport output_value after sched_time; output_value := not output_value; if (output_value = '0') then sched_time := sched_time + high_time; elsif (output_value = '1') then sched_time := sched_time + low_time; end if; end loop; end loop; -- reset schedule_clk2 schedule_clk2 := false; end if; -- schedule_clk2 -- clock_ext output if (schedule_extclk = true) then -- initialize variables sched_time := extclk_phase_delay; cycle_to_adjust := 0; inc := 1; output_value := '1'; temp := extclk_synchronizing_period/1 ps; my_rem := temp rem extclk_cycles_per_sync_period; -- schedule number of output clock -- cycles in this loop in order to synchronize the output clock to the -- input clock - to get rid of drifting for cases where the input clock -- period is not always divisible for i in 1 to extclk_cycles_per_sync_period loop tmp_per := temp/extclk_cycles_per_sync_period; if ((my_rem /= 0) and (inc <= my_rem)) then tmp_rem := (extclk_cycles_per_sync_period * inc) rem my_rem; cycle_to_adjust := (extclk_cycles_per_sync_period * inc) / my_rem; if (tmp_rem /= 0) then cycle_to_adjust := cycle_to_adjust + 1; end if; end if; -- if this cycle is the one to adjust the output period in, then -- increment the period by 1 unit if (cycle_to_adjust = i) then tmp_per := tmp_per + 1; inc := inc + 1; end if; -- adjust the high and low cycle period vco_per := tmp_per * 1 ps; high_time := (tmp_per/2) * 1 ps; if ((tmp_per rem 2) /= 0) then high_time := high_time + 1 ps; end if; low_time := vco_per - high_time; -- schedule the high and low cycle of 1 output clock period for j in 1 to 2 loop extclk_tmp <= transport output_value after sched_time; output_value := not output_value; if (output_value = '0') then sched_time := sched_time + high_time; elsif (output_value = '1') then sched_time := sched_time + low_time; end if; end loop; end loop; -- reset schedule_extclk schedule_extclk := false; end if; -- schedule_extclk end if; end process LOCK; clock0 <= clk0_tmp; clock1 <= clk1_tmp; clock2 <= clk2_tmp; clock_ext <= extclk_tmp; locked <= pll_lock; end behavior; -- END ARCHITECTURE BEHAVIOR -- START ENTITY NAME ----------------------------------------------------------- -- -- Entity Name : ALTDDIO_IN -- -- Description : Double Data Rate (DDR) input behavioural model. Receives -- data on both edges of the reference clock. -- -- Limitations : Not available for MAX device families. -- -- Expected results : Data sampled from the datain port at the rising edge of -- the reference clock (dataout_h) and at the falling edge of -- the reference clock (dataout_l). -- -- END ENTITY NAME ------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.ALTERA_DEVICE_FAMILIES.all; -- ENTITY DECLARATION entity altddio_in is generic ( width : positive; -- required parameter invert_input_clocks : string := "OFF"; intended_device_family : string := "Stratix"; power_up_high : string := "OFF"; lpm_hint : string := "UNUSED"; lpm_type : string := "altddio_in" ); port ( datain : in std_logic_vector(width-1 downto 0); -- required port, DDR -- input data inclock : in std_logic := '0'; -- input reference clock inclocken : in std_logic := '1'; -- input clock enable signal aset : in std_logic := '0'; -- asynchronous set aclr : in std_logic := '0'; -- asynchronous clear sset : in std_logic := '0'; -- synchronous set sclr : in std_logic := '0'; -- synchronous clear dataout_h : out std_logic_vector(width-1 downto 0); --data sampled at --rising edge of inclock dataout_l : out std_logic_vector(width-1 downto 0) --data sampled at --falling edge of inclock ); end altddio_in; -- END ENTITY DECLARATION -- BEGINNING OF ARCHITECTURE BEHAVE architecture behave of altddio_in is -- CONSTANT DECLARATION constant IS_STRATIXIII : boolean := FEATURE_FAMILY_STRATIXIII(intended_device_family); constant IS_STRATIX : boolean := FEATURE_FAMILY_STRATIX(intended_device_family); constant IS_MAXII : boolean := FEATURE_FAMILY_MAXII(intended_device_family); begin -- checking for invalid parameters MSG: process begin if (width <= 0) then ASSERT FALSE REPORT "The width parameter must be greater than 0" SEVERITY ERROR; end if; if (IS_VALID_FAMILY(intended_device_family) = false) then ASSERT FALSE REPORT intended_device_family & " is not a valid device family!" SEVERITY ERROR; end if; if (not ((IS_STRATIX and (not IS_MAXII)))) then ASSERT FALSE REPORT "Megafunction altddio_in is not supported in " & intended_device_family &"!" SEVERITY ERROR; end if; wait; end process MSG; process (inclock, aset, aclr) -- VARIABLE DECLARATION variable dataout_h_tmp : std_logic_vector(width-1 downto 0) := (OTHERS=>'0'); variable dataout_l_tmp : std_logic_vector(width-1 downto 0) := (OTHERS=>'0'); variable datain_latched : std_logic_vector(width-1 downto 0) := (OTHERS=>'0'); variable need_init : boolean := true; begin -- power up registers according the power_up_high parameter setting if ((NOW = 0 ps) or (need_init = true)) then if (power_up_high = "OFF") then dataout_h_tmp := (others => '0'); dataout_l_tmp := (others => '0'); datain_latched := (others => '0'); else dataout_h_tmp := (others => '1'); dataout_l_tmp := (others => '1'); datain_latched := (others => '1'); end if; need_init := false; end if; -- asynchronous clear is asserted if (aclr = '1') then dataout_h_tmp := (others => '0'); dataout_l_tmp := (others => '0'); datain_latched := (others => '0'); -- else asynchronous set is asserted elsif (aset = '1') then dataout_h_tmp := (others => '1'); dataout_l_tmp := (others => '1'); datain_latched := (others => '1'); -- not being cleared or preset -- rising edge of inclock elsif (inclock'event and (inclock = '1')) then if (inclocken = '1') then if (invert_input_clocks = "ON") then if (sclr = '1') then datain_latched := (others => '0'); elsif (sset = '1') then datain_latched := (others => '1'); else datain_latched := datain; end if; else if (IS_STRATIXIII) then if (sclr = '1') then dataout_h_tmp := (others => '0'); dataout_l_tmp := (others => '0'); elsif (sset = '1') then dataout_h_tmp := (others => '1'); dataout_l_tmp := (others => '1'); else dataout_h_tmp := datain; dataout_l_tmp := datain_latched; end if; else if (sclr = '1') then dataout_h_tmp := (others => '0'); elsif (sset = '1') then dataout_h_tmp := (others => '1'); else dataout_h_tmp := datain; end if; dataout_l_tmp := datain_latched; end if; end if; end if; -- falling edge of inclock elsif (inclock'event and (inclock = '0')) then if ((IS_STRATIX and (not IS_MAXII))) then if (inclocken = '1') then if (invert_input_clocks = "ON") then if (IS_STRATIXIII) then if (sclr = '1') then dataout_h_tmp := (others => '0'); dataout_l_tmp := (others => '0'); elsif (sset = '1') then dataout_h_tmp := (others => '1'); dataout_l_tmp := (others => '1'); else dataout_h_tmp := datain; dataout_l_tmp := datain_latched; end if; else if (sclr = '1') then dataout_h_tmp := (others => '0'); elsif (sset = '1') then dataout_h_tmp := (others => '1'); else dataout_h_tmp := datain; end if; dataout_l_tmp := datain_latched; end if; else if (sclr = '1') then datain_latched := (others => '0'); elsif (sset = '1') then datain_latched := (others => '1'); else datain_latched := datain; end if; end if; end if; else -- for future families if (invert_input_clocks = "ON") then dataout_h_tmp := datain; dataout_l_tmp := datain_latched; else datain_latched := datain; end if; end if; end if; -- assign variables to output ports dataout_l <= dataout_l_tmp; dataout_h <= dataout_h_tmp; end process; end behave; -- END ARCHITECTURE BEHAVE -- START ENTITY NAME ----------------------------------------------------------- -- -- Entity Name : ALTDDIO_OUT -- -- Description : Double Data Rate (DDR) output behavioural model. -- Transmits data on both edges of the reference clock. -- -- Limitations : Not available for MAX device families. -- -- Expected results : Double data rate output on dataout. -- --END ENTITY NAME ------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.ALTERA_DEVICE_FAMILIES.all; -- ENTITY DECLARATION entity altddio_out is generic ( width : positive; -- required parameter power_up_high : string := "OFF"; oe_reg : string := "UNUSED"; extend_oe_disable : string := "UNUSED"; invert_output : string := "OFF"; intended_device_family : string := "Stratix"; lpm_hint : string := "UNUSED"; lpm_type : string := "altddio_out" ); port ( datain_h : in std_logic_vector(width-1 downto 0); --required port, data --input for the rising --edge of outclock datain_l : in std_logic_vector(width-1 downto 0); --required port, data --input for the falling --edge of outclock outclock : in std_logic; -- required port, input reference clock to output -- data by outclocken : in std_logic := '1'; -- clock enable signal for outclock aset : in std_logic := '0'; -- asynchronous set aclr : in std_logic := '0'; -- asynchronous clear sset : in std_logic := '0'; -- synchronous set sclr : in std_logic := '0'; -- synchronous clear oe : in std_logic := '1'; -- output enable for dataout dataout : out std_logic_vector(width-1 downto 0); -- DDR data output oe_out : out std_logic_vector(width-1 downto 0) -- DDR data output ); end altddio_out; -- END ENTITY DECLARATION -- BEGINNING OF ARCHITECTURE BEHAVE architecture behave of altddio_out is -- CONSTANT DECLARATION constant INVERT_DATAOUT : boolean := FEATURE_FAMILY_HAS_INVERTED_OUTPUT_DDIO(intended_device_family) and (invert_output = "ON"); constant IS_STRATIXIII : boolean := FEATURE_FAMILY_STRATIXIII(intended_device_family); constant IS_STRATIX : boolean := FEATURE_FAMILY_STRATIX(intended_device_family); constant IS_MAXII : boolean := FEATURE_FAMILY_MAXII(intended_device_family); -- SIGNAL DECLARATION signal outclock_dly : std_logic; signal dataout_h : std_logic_vector(width-1 downto 0) := (OTHERS=>'0'); signal dataout_l : std_logic_vector(width-1 downto 0) := (OTHERS=>'0'); signal oe_rgd : std_logic := '0'; signal oe_reg_ext : std_logic := '0'; signal stratix_oe : std_logic; signal output_enable : std_logic; begin -- checking for invalid parameters MSG: process begin if (width <= 0) then ASSERT FALSE REPORT "The width parameter must be greater than 0" SEVERITY ERROR; end if; if (IS_VALID_FAMILY(intended_device_family) = false) then ASSERT FALSE REPORT intended_device_family & " is not a valid device family!" SEVERITY ERROR; end if; if (not ((IS_STRATIX and (not IS_MAXII)))) then ASSERT FALSE REPORT "Megafunction altddio_out is not supported in " & intended_device_family &"!" SEVERITY ERROR; end if; wait; end process MSG; outclock_dly <= outclock; -- output enable signals output_enable <= stratix_oe when ((IS_STRATIX and (not IS_MAXII))) else oe; stratix_oe <= (oe_reg_ext and oe_rgd) when (extend_oe_disable = "ON") else oe_rgd when ((oe_reg = "REGISTERED") and (extend_oe_disable /= "ON")) else oe; oe_out <= (others => output_enable); REGS: process (outclock, aset, aclr) -- VARIABLE DECLARATION variable need_init : boolean := true; begin -- power up the registers according to the power_up_high parameter setting if ((NOW = 0 ps) or (need_init = true)) then if (power_up_high = "OFF") then dataout_h <= (others => '0'); dataout_l <= (others => '0'); oe_rgd <= '0'; oe_reg_ext <= '0'; else dataout_h <= (others => '1'); dataout_l <= (others => '1'); oe_rgd <= '1'; oe_reg_ext <= '1'; end if; need_init := false; end if; -- asynchronous clear is asserted if (aclr = '1') then dataout_h <= (others => '0'); dataout_l <= (others => '0'); oe_rgd <= '0'; oe_reg_ext <= '0'; -- else if asynchronous set is asserted elsif (aset = '1') then dataout_h <= (others => '1'); dataout_l <= (others => '1'); oe_rgd <= '1'; oe_reg_ext <= '1'; -- else outclock is triggered elsif ((outclock = '1') and outclock'event) then -- rising edge of outclock if (outclocken = '1') then -- synchronous clear is asserted if (sclr = '1') then dataout_h <= (others => '0'); dataout_l <= (others => '0'); oe_rgd <= '0'; oe_reg_ext <= '0'; -- else if synchronous set is asserted elsif (sset = '1') then dataout_h <= (others => '1'); dataout_l <= (others => '1'); oe_rgd <= '1'; oe_reg_ext <= '1'; else if (INVERT_DATAOUT = true) then dataout_h <= not datain_h; dataout_l <= not datain_l; else dataout_h <= datain_h; dataout_l <= datain_l; end if; oe_rgd <= oe; end if; end if; elsif ((outclock = '0') and outclock'event) then -- falling edge of outclock if (outclocken = '1') then oe_reg_ext <= oe_rgd; end if; end if; end process REGS; DATA_OUTPUT: process(outclock_dly, dataout_h, dataout_l, output_enable) begin if (output_enable = '1') then if (outclock_dly = '1') then dataout <= dataout_h; else dataout <= dataout_l; end if; else -- output is not enabled dataout <= (others => 'Z'); end if; end process DATA_OUTPUT; end behave; -- END ARCHITECTURE BEHAVE -- START ENTITY NAME ----------------------------------------------------------- -- -- Entity Name : ALTDDIO_BIDIR -- -- Description : Double Data Rate (DDR) bi-directional behavioural model. -- Transmits and receives data on both edges of the reference -- clock. -- -- Limitations : Not available for MAX device families. -- -- Expected results : Data output sampled from padio port on rising edge of -- inclock signal (dataout_h) and falling edge of inclock -- signal (dataout_l). Combinatorial output fed by padio -- directly (combout). -- --END ENTITY NAME -------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.altddio_in; use work.altddio_out; -- ENTITY DECLARATION entity altddio_bidir is generic( width : positive; -- required parameter power_up_high : string := "OFF"; oe_reg : string := "UNUSED"; extend_oe_disable : string := "UNUSED"; implement_input_in_lcell : string := "UNUSED"; invert_output : string := "OFF"; intended_device_family : string := "Stratix"; lpm_hint : string := "UNUSED"; lpm_type : string := "altddio_bidir" ); port ( datain_h : in std_logic_vector(width-1 downto 0); --input data to be --output of padio port --at the rising edge of --outclock datain_l : in std_logic_vector(width-1 downto 0); --input data to be --output of padio port --at the falling edge of --outclock inclock : in std_logic := '0'; -- input reference clock to sample DDR input. inclocken : in std_logic := '1'; -- inclock enable outclock : in std_logic; -- input reference clock to register data output outclocken : in std_logic := '1'; -- outclock enable aset : in std_logic := '0'; -- asynchronour set aclr : in std_logic := '0'; -- asynchronous clear sset : in std_logic := '0'; -- synchronour set sclr : in std_logic := '0'; -- synchronous clear oe : in std_logic := '1'; -- output enable for padio port dataout_h : out std_logic_vector(width-1 downto 0);--data sampled from the --padio port at the --rising edge of --inclock dataout_l : out std_logic_vector(width-1 downto 0);--data sampled from the --padio port at the --falling edge of --inclock combout : out std_logic_vector(width-1 downto 0);--combinatorial output --directly fed by padio oe_out : out std_logic_vector(width-1 downto 0);--DDR OE output dqsundelayedout : out std_logic_vector(width-1 downto 0); -- undelayed DQS -- signal to the -- PLD core padio : inout std_logic_vector(width-1 downto 0) --bidirectional DDR --port ); end altddio_bidir; -- END ENTITY DECLARATION -- BEGINNING ARCHITECTURE STRUCT architecture struct of altddio_bidir is -- COMPONENT DECLARATION component altddio_in generic ( width : positive := 1; intended_device_family : string := "Stratix"; power_up_high : string := "OFF" ); port ( datain : in std_logic_vector(width-1 downto 0); inclock : in std_logic; inclocken : in std_logic := '1'; aset : in std_logic := '0'; aclr : in std_logic := '0'; sset : in std_logic := '0'; sclr : in std_logic := '0'; dataout_h : out std_logic_vector(width-1 downto 0); dataout_l : out std_logic_vector(width-1 downto 0) ); end component; component altddio_out generic ( width : positive := 1; power_up_high : string := "OFF"; intended_device_family : string := "Stratix"; oe_reg : string := "UNUSED"; extend_oe_disable : string := "UNUSED"; invert_output : string := "OFF" ); port ( datain_h : in std_logic_vector(width-1 downto 0); datain_l : in std_logic_vector(width-1 downto 0); outclock : in std_logic; outclocken : in std_logic := '1'; aset : in std_logic := '0'; aclr : in std_logic := '0'; sset : in std_logic := '0'; sclr : in std_logic := '0'; oe : in std_logic := '1'; dataout : out std_logic_vector(width-1 downto 0); oe_out : out std_logic_vector(width-1 downto 0) ); end component; begin -- checking for invalid parameters MSG: process begin if (width <= 0) then ASSERT FALSE REPORT "The width parameter must be greater than 0" SEVERITY ERROR; end if; wait; end process MSG; -- COMPONENT INSTANTIATION U1: altddio_in generic map ( width => width, intended_device_family => intended_device_family, power_up_high => power_up_high ) port map ( datain => padio, inclock => inclock, inclocken => inclocken, aset => aset, aclr => aclr, sset => sset, sclr => sclr, dataout_h => dataout_h, dataout_l => dataout_l ); U2: altddio_out generic map ( width => width, power_up_high => power_up_high, intended_device_family => intended_device_family, oe_reg => oe_reg, extend_oe_disable => extend_oe_disable, invert_output => invert_output ) port map ( datain_h => datain_h, datain_l => datain_l, outclock => outclock, outclocken => outclocken, aset => aset, aclr => aclr, sset => sset, sclr => sclr, oe => oe, dataout => padio, oe_out => oe_out ); -- assign padio to feed combout port combout <= padio; dqsundelayedout <= padio; end struct; -- END ARCHITECTURE STRUCT ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : stratixii_lvds_rx -- -- Description : Stratix II lvds receiver. Support both the dpa and non-dpa -- mode. -- -- Limitation : Only available to Stratix II. -- -- Results Expected: Deserialized output data, dpa lock signal and status bit -- indicating whether maximum bitslip has been reached. -- ---END_ENTITY_HEADER----------------------------------------------------------- -- LIBRARY USED---------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -- ENTITY DECLARATION entity stratixii_lvds_rx is -- GENERIC DECLARATION generic ( number_of_channels : natural; -- Required parameter deserialization_factor : natural; -- Required parameter enable_dpa_mode : string := "OFF"; data_align_rollover : natural := 10; lose_lock_on_one_change : string := "OFF"; reset_fifo_at_first_lock : string := "ON"; x_on_bitslip : string := "ON" ); -- PORT DECLARATION port( --INPUT PORT DECLARATION rx_in : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_fastclk : in std_logic; --Required port rx_enable : in std_logic := '1'; rx_locked : in std_logic; rx_dpaclock : in std_logic := '0'; rx_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_hold : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_enable : in std_logic_vector(number_of_channels-1 downto 0) := (others => '1'); rx_fifo_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_channel_data_align : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_cda_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); -- OUTPUT PORT DECLARATION rx_out : out std_logic_vector(deserialization_factor*number_of_channels -1 downto 0); rx_dpa_locked : out std_logic_vector(number_of_channels-1 downto 0); rx_cda_max : out std_logic_vector(number_of_channels-1 downto 0) := (others => '0') ); end stratixii_lvds_rx; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of stratixii_lvds_rx is -- CONSTANT DECLARATION constant REGISTER_WIDTH : natural := deserialization_factor * number_of_channels; constant MUX_WIDTH : natural := 12; -- TYPE DECLARATION type CHANNEL_CNT is array (number_of_channels-1 downto 0) of integer; type CHANNEL_BOOL is array (number_of_channels-1 downto 0) of boolean; type DPA_FIFO_RAM is array (number_of_channels -1 downto 0) of std_logic_vector(5 downto 0); type BITSLIP_REG_CHAIN is array (number_of_channels-1 downto 0) of std_logic_vector(MUX_WIDTH-1 downto 0); -- SIGNAL DECLARATION -- constant signals signal fifo_write_clk : std_logic := '0'; signal fifo_read_clk : std_logic := '0'; signal temp_zero : std_logic := '0'; signal enable0_reg : std_logic := '0'; signal enable_negedge_count : boolean := false; signal rx_shift_reg : std_logic_vector(REGISTER_WIDTH-1 downto 0) := (others => '0'); signal rx_parallel_load_reg : std_logic_vector(REGISTER_WIDTH-1 downto 0) := (others => '0'); signal rx_in_reg : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal fifo_out_sync_reg : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal bitslip_mux_out : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal dpa_in : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal retime_data : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal dpll_lock : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal dpll_first_lock : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal rx_channel_data_align_pre : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal write_side_sync_reset : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal read_side_sync_reset : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal ram_array : DPA_FIFO_RAM := (others => (others => '0')); signal dpa_fifo_in : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal dpa_fifo_out : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal rx_in_reg_clk : std_logic := '0'; signal rx_bload : std_logic := '0'; begin -- SIGNAL ASSIGNMENTS rx_out <= rx_parallel_load_reg; dpa_fifo_in <= retime_data; dpa_fifo_out <= fifo_out_sync_reg; fifo_write_clk <= rx_fastclk; fifo_read_clk <= rx_fastclk; rx_in_reg_clk <= rx_fastclk; rx_dpa_locked <= dpll_lock; rx_bload <= enable0_reg; -- PROCESS DECLARATION -- the deserializer STRATIXII_DESER : process(rx_fastclk) begin if (rx_fastclk'event and (rx_fastclk = '1')) then if (rx_bload = '1') then rx_parallel_load_reg <= rx_shift_reg; end if; for i in 0 to number_of_channels -1 loop for x in deserialization_factor-1 downto 1 loop rx_shift_reg(x + (i * deserialization_factor)) <= rx_shift_reg(x-1 + (i * deserialization_factor)); end loop; rx_shift_reg(i * deserialization_factor) <= bitslip_mux_out(i); end loop; -- Registering load enable signal enable0_reg <= rx_enable; end if; end process STRATIXII_DESER; -- input synchronization register IN_SYNC_REGISTER : process (rx_in_reg_clk) begin if (rx_in_reg_clk = '1' and rx_in_reg_clk'event) then rx_in_reg <= rx_in; end if; end process IN_SYNC_REGISTER; -- STRATIXII bitslip logic STRATIXII_BITSLIP : process (rx_fastclk, rx_cda_reset) variable start_corrupt_bits : CHANNEL_BOOL := (others => false); variable num_corrupt_bits : CHANNEL_CNT := (others => 0); variable bitslip_count : CHANNEL_CNT := (others => 0); variable shift_reg_chain : BITSLIP_REG_CHAIN := (others => (others => '0')); begin for i in 0 to number_of_channels-1 loop if (rx_cda_reset(i) = '1') then bitslip_count(i) := 0; rx_cda_max(i) <= '0'; end if; if (rx_fastclk'event and (rx_fastclk = '1')) then if ((((rx_channel_data_align(i) = '1') and (rx_channel_data_align_pre(i) = '0')) or ((start_corrupt_bits(i) = true) and (num_corrupt_bits(i) < 4) and (rx_channel_data_align(i) = '1'))) and (x_on_bitslip = "ON")) then bitslip_mux_out(i) <= 'X'; else bitslip_mux_out(i) <= shift_reg_chain(i)(bitslip_count(i)); end if; for j in data_align_rollover -1 downto 0 loop shift_reg_chain(i)(j + 1) := shift_reg_chain(i)(j); end loop; if ((enable_dpa_mode = "ON") and (rx_dpll_enable(i) = '1')) then shift_reg_chain(i)(0) := dpa_fifo_out(i); else shift_reg_chain(i)(0) := rx_in_reg(i); end if; if ((rx_channel_data_align(i) = '1') and (rx_channel_data_align_pre(i) = '0'))then bitslip_count(i) := (bitslip_count(i) + 1) rem (data_align_rollover + 1); if (bitslip_count(i) = data_align_rollover) then rx_cda_max(i) <= '1'; else rx_cda_max(i) <= '0'; end if; start_corrupt_bits(i) := true; num_corrupt_bits(i) := 1; elsif ((rx_channel_data_align(i) = '0') and (rx_channel_data_align_pre(i) = '1'))then start_corrupt_bits(i) := false; num_corrupt_bits(i) := 0; end if; if (start_corrupt_bits(i) = true) then if (num_corrupt_bits(i) = 3) then start_corrupt_bits(i) := false; else num_corrupt_bits(i) := num_corrupt_bits(i) + 1; end if; end if; rx_channel_data_align_pre(i) <= rx_channel_data_align(i); end if; end loop; end process STRATIXII_BITSLIP; -- STRATIXII Phase Compensation FIFO STRATIXII_DPA_FIFO : process (fifo_write_clk, fifo_read_clk, rx_reset) variable wrPtr : CHANNEL_CNT := (others => 0); variable rdPtr : CHANNEL_CNT := (others => 3); variable fifo_in_sync_reg : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); begin for i in 0 to number_of_channels-1 loop if (rx_reset(i) = '1') then wrPtr(i) := 0; rdPtr(i) := 3; ram_array(i) <= (others => '0'); fifo_in_sync_reg(i) := '0'; fifo_out_sync_reg(i) <= '0'; write_side_sync_reset(i) <= '1'; read_side_sync_reset(i) <= '1'; end if; end loop; if (fifo_write_clk'event and (fifo_write_clk = '1')) then for i in 0 to number_of_channels-1 loop if ((rx_reset(i) = '1') or (rx_fifo_reset(i) = '1') or ((reset_fifo_at_first_lock = "ON") and (dpll_first_lock(i) = '0'))) then wrPtr(i) := 0; ram_array(i) <= (others => '0'); fifo_in_sync_reg(i) := '0'; write_side_sync_reset(i) <= '1'; else write_side_sync_reset(i) <= '0'; if (write_side_sync_reset(i) = '0') then ram_array(i)(wrPtr(i)) <= fifo_in_sync_reg(i); fifo_in_sync_reg(i) := dpa_fifo_in(i); wrPtr(i) := (wrPtr(i) + 1) rem 6; end if; end if; end loop; end if; if (fifo_read_clk'event and (fifo_read_clk = '1')) then for i in 0 to number_of_channels-1 loop if ((rx_reset(i) = '1') or (rx_fifo_reset(i) = '1') or ((reset_fifo_at_first_lock = "ON") and (dpll_first_lock(i) = '0'))) then rdPtr(i) := 3; ram_array(i) <= (others =>'0'); fifo_out_sync_reg(i) <= '0'; read_side_sync_reset(i) <= '1'; else read_side_sync_reset(i) <= '0'; if (read_side_sync_reset(i) = '0') then fifo_out_sync_reg(i) <= ram_array(i)(rdPtr(i)); rdPtr(i) := (rdPtr(i) + 1) rem 6; end if; end if; end loop; end if; end process STRATIXII_DPA_FIFO; -- STRATIXII DPA Block STRATIXII_DPA_BLOCK : process (rx_fastclk, rx_reset) variable dpll_clk_count : CHANNEL_CNT := (others => 0); variable init : boolean := true; begin if (init = true) then if (enable_dpa_mode = "ON") then ASSERT false REPORT "DPA Phase tracking is not modeled, and once locked, DPA will continue to lock until the next reset is asserted. Please refer to the device handbook for further details." SEVERITY warning; end if; init := false; end if; for i in 0 to number_of_channels-1 loop if (rx_reset(i) = '1') then dpll_clk_count(i) := 0; dpll_lock(i) <= '0'; end if; if (rx_fastclk'event and (rx_fastclk = '1')) then dpa_in(i) <= rx_in(i); retime_data(i) <= dpa_in(i); if (rx_reset(i) /= '1') then dpll_clk_count(i) := dpll_clk_count(i) + 1; if (dpll_clk_count(i) > 2) then dpll_lock(i) <= '1'; dpll_first_lock(i) <= '1'; end if; end if; end if; end loop; end process STRATIXII_DPA_BLOCK; end behavior; -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : flexible_lvds_rx -- -- Description : flexible lvds receiver -- -- Limitation : Only available to Cyclone and Cyclone II families. -- -- Results Expected: Deserialized output data. -- ---END_ENTITY_HEADER----------------------------------------------------------- -- LIBRARY USED---------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -- ENTITY DECLARATION entity flexible_lvds_rx is -- GENERIC DECLARATION generic ( number_of_channels : natural; -- Required parameter deserialization_factor : natural; use_extra_ddio_register : boolean := true; use_extra_pll_clk : boolean := false; buffer_implementation : string := "RAM"; registered_data_align_input : string := "OFF"; use_external_pll : string := "OFF"; registered_output : string := "OFF"; add_latency : boolean := true ); -- PORT DECLARATION port( --INPUT PORT DECLARATION rx_in : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_fastclk : in std_logic; --Required port rx_slowclk : in std_logic; --Required port rx_syncclk : in std_logic; --Required port pll_areset : in std_logic; --Required port rx_data_reset : in std_logic; rx_data_align : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_cda_reset : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_locked : in std_logic; -- OUTPUT PORT DECLARATION rx_out : out std_logic_vector(deserialization_factor*number_of_channels -1 downto 0)); end flexible_lvds_rx; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of flexible_lvds_rx is -- FUNCTION DECLARATION function get_latency ( constant i_deserialization_factor : in natural) return natural is begin if ((deserialization_factor rem 2) = 1) then return (deserialization_factor / 2) + 1; else return (deserialization_factor / 2); end if; end get_latency; function get_num_of_sync_stages ( constant i_latency : in natural) return natural is variable num_of_sync_stages : natural := 0; begin if ((deserialization_factor = 4) and (add_latency = true)) then num_of_sync_stages := 1; else if (add_latency = false) then num_of_sync_stages := i_latency-2; else num_of_sync_stages := i_latency-3; end if; end if; if (((deserialization_factor rem 2) = 1) and (not (((buffer_implementation = "RAM") or (buffer_implementation = "LES"))))) then num_of_sync_stages := num_of_sync_stages + deserialization_factor/2; end if; return num_of_sync_stages; end get_num_of_sync_stages; -- CONSTANT DECLARATION constant REGISTER_WIDTH : natural := deserialization_factor * number_of_channels; constant LATENCY : natural := get_latency(deserialization_factor); constant NUM_OF_SYNC_STAGES : natural := get_num_of_sync_stages(LATENCY); -- TYPE DECLARATION type CHANNEL_CNT is array (number_of_channels-1 downto 0) of integer; type DFFPIPE is array (NUM_OF_SYNC_STAGES downto 0) of std_logic_vector(number_of_channels -1 downto 0); -- SIGNAL DECLARATION -- constant signals signal rx_shift_reg : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_shift_reg1 : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_shift_reg2 : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_sync_reg1 : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_sync_reg2 : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_sync_reg1_buf1 : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_sync_reg1_buf1_pipe : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_sync_reg2_buf1 : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_sync_reg1_buf2 : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_sync_reg1_buf2_pipe : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_sync_reg2_buf2 : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_out_odd : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_out_odd_mode : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_out_reg : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal rx_out_int : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal h_int_reg : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal l_int_reg : std_logic_vector (REGISTER_WIDTH -1 downto 0):= (others => '0'); signal ddio_h_reg : std_logic_vector (number_of_channels -1 downto 0):= (others => '0'); signal ddio_l_reg : std_logic_vector (number_of_channels -1 downto 0):= (others => '0'); signal datain_h_reg : std_logic_vector (number_of_channels -1 downto 0):= (others => '0'); signal datain_l_reg : std_logic_vector (number_of_channels -1 downto 0):= (others => '0'); signal datain_l_latch : std_logic_vector (number_of_channels -1 downto 0):= (others => '0'); signal select_bit : std_logic := '0'; signal sync_clock : std_logic := '0'; signal rx_data_align_reg : std_logic_vector (number_of_channels -1 downto 0):= (others => '0'); signal rx_data_align_int : std_logic_vector (number_of_channels -1 downto 0):= (others => '0'); signal rx_data_align_clk : std_logic := '0'; signal int_bitslip_reg : std_logic_vector (number_of_channels -1 downto 0):= (others => '0'); signal bitslip_count : CHANNEL_CNT := (others => 0); signal rx_reg_clk : std_logic := '0'; begin -- SIGNAL ASSIGNMENTS rx_out_int <= rx_shift_reg when ((deserialization_factor rem 2) = 0) else rx_out_odd when (buffer_implementation /= "MUX") else rx_sync_reg1_buf1 when (select_bit = '1') else rx_sync_reg2_buf1; rx_out <= rx_out_reg when ((registered_output = "ON") and (use_external_pll = "OFF")) else rx_out_int; rx_reg_clk <= rx_slowclk when (registered_output = "ON") else '0'; rx_data_align_clk <= rx_slowclk when ((deserialization_factor rem 2) = 0) else sync_clock when (use_extra_pll_clk = false) else rx_syncclk; rx_data_align_int <= rx_data_align_reg when (registered_data_align_input = "ON") and (use_external_pll = "OFF") else rx_data_align; -- PROCESS DECLARATION -- This always block implements the altddio_in that takes in the input serial -- data of each channel and deserialized it into two parallel data stream -- (ddio_h_reg and ddio_l_reg). Each parallel data stream will be registered -- before send to shift registers. DDIO_IN : process(rx_fastclk, pll_areset, rx_data_reset) variable datain_h_reg_int : DFFPIPE := (others => (others => '0')); variable datain_l_reg_int : DFFPIPE := (others => (others => '0')); variable pipe_ptr : natural := 0; begin if (pll_areset = '1' or rx_data_reset = '1') then ddio_h_reg <= (others => '0'); datain_h_reg <= (others => '0'); ddio_l_reg <= (others => '0'); datain_l_reg <= (others => '0'); datain_l_latch <= (others => '0'); datain_h_reg_int := (others => (others => '0')); datain_l_reg_int := (others => (others => '0')); elsif ((rx_fastclk = '1') and rx_fastclk'event) then if (NUM_OF_SYNC_STAGES > 0) then datain_h_reg <= datain_h_reg_int(pipe_ptr); datain_l_reg <= datain_l_reg_int(pipe_ptr); if (use_extra_ddio_register = true) then ddio_h_reg <= rx_in; datain_h_reg_int(pipe_ptr) := ddio_h_reg; else datain_h_reg_int(pipe_ptr) := rx_in; end if; datain_l_reg_int(pipe_ptr) := datain_l_latch; if (NUM_OF_SYNC_STAGES > 1) then pipe_ptr := (pipe_ptr + 1) rem NUM_OF_SYNC_STAGES; end if; else if (use_extra_ddio_register = true) then ddio_h_reg <= rx_in; datain_h_reg <= ddio_h_reg; else datain_h_reg <= rx_in; end if; datain_l_reg <= datain_l_latch; end if; elsif (rx_fastclk'event and (rx_fastclk = '0')) then if (use_extra_ddio_register = true) then ddio_l_reg <= rx_in; datain_l_latch <= ddio_l_reg; else datain_l_latch <= rx_in; end if; end if; end process DDIO_IN; -- bitslip counter BITSLIP_CNT : process(rx_fastclk, rx_cda_reset) begin for i in 0 to number_of_channels-1 loop if (rx_cda_reset(i) = '1') then bitslip_count(i) <= 0; elsif ((rx_fastclk = '1') and rx_fastclk'event) then if (((not int_bitslip_reg(i)) and rx_data_align_int(i)) = '1') then bitslip_count(i) <= (bitslip_count(i) + 1) rem deserialization_factor; end if; end if; end loop; end process BITSLIP_CNT; DATA_ALIGN_REG : process(rx_data_align_clk) begin if ((rx_data_align_clk = '1') and rx_data_align_clk'event) then rx_data_align_reg <= rx_data_align; end if; end process DATA_ALIGN_REG; BITSLIP_REG : process(rx_fastclk) begin if ((rx_fastclk = '1') and rx_fastclk'event) then int_bitslip_reg <= rx_data_align_int; end if; end process BITSLIP_REG; -- Loading input data to shift register SHIFTREG : process(rx_fastclk, pll_areset, rx_data_reset) begin if (pll_areset = '1' or rx_data_reset = '1') then rx_shift_reg <= (others => '0'); rx_shift_reg1 <= (others => '0'); rx_shift_reg2 <= (others => '0'); h_int_reg <= (others => '0'); l_int_reg <= (others => '0'); elsif ((rx_fastclk = '1') and rx_fastclk'event) then -- Implementation for even deserialization factor. if ((deserialization_factor rem 2) = 0) then for i in 0 to number_of_channels-1 loop for x in (deserialization_factor-1) downto 2 loop rx_shift_reg(x + (i * deserialization_factor)) <= rx_shift_reg(x-2 + (i * deserialization_factor)); end loop; for x in (deserialization_factor-1) downto 1 loop h_int_reg(x + (i * deserialization_factor)) <= h_int_reg(x-1 + (i * deserialization_factor)); l_int_reg(x + (i * deserialization_factor)) <= l_int_reg(x-1 + (i * deserialization_factor)); end loop; h_int_reg(i * deserialization_factor) <= datain_h_reg(i); l_int_reg(i * deserialization_factor) <= datain_l_reg(i); if (bitslip_count(i) = 0) then rx_shift_reg(i * deserialization_factor) <= datain_h_reg(i); rx_shift_reg((i * deserialization_factor)+1) <= datain_l_reg(i); elsif (bitslip_count(i) = 1) then rx_shift_reg(i * deserialization_factor) <= datain_l_reg(i); rx_shift_reg((i * deserialization_factor)+1) <= h_int_reg(i * deserialization_factor); else if (bitslip_count(i) rem 2 = 1) then rx_shift_reg(i * deserialization_factor) <= l_int_reg((bitslip_count(i)/2) -1 + (i * deserialization_factor)); rx_shift_reg((i * deserialization_factor)+1) <= h_int_reg((bitslip_count(i)/2) + (i * deserialization_factor)); else rx_shift_reg(i * deserialization_factor) <= h_int_reg((bitslip_count(i)/2) -1 + (i * deserialization_factor)); rx_shift_reg((i * deserialization_factor)+1) <= l_int_reg((bitslip_count(i)/2) -1 + (i * deserialization_factor)); end if; end if; end loop; else -- Implementation for odd deserialization factor. for i in 0 to number_of_channels-1 loop for x in (deserialization_factor-1) downto 2 loop rx_shift_reg1(x + (i * deserialization_factor)) <= rx_shift_reg1(x-2 + (i * deserialization_factor)); rx_shift_reg2(x + (i * deserialization_factor)) <= rx_shift_reg2(x-2 + (i * deserialization_factor)); end loop; for x in (deserialization_factor-1) downto 1 loop h_int_reg(x + (i * deserialization_factor)) <= h_int_reg(x-1 + (i * deserialization_factor)); l_int_reg(x + (i * deserialization_factor)) <= l_int_reg(x-1 + (i * deserialization_factor)); end loop; h_int_reg(i * deserialization_factor) <= datain_h_reg(i); l_int_reg(i * deserialization_factor) <= datain_l_reg(i); if (bitslip_count(i) = 0) then rx_shift_reg1(i * deserialization_factor) <= datain_h_reg(i); rx_shift_reg1((i * deserialization_factor)+1) <= datain_l_reg(i); elsif (bitslip_count(i) = 1) then rx_shift_reg1(i * deserialization_factor) <= datain_l_reg(i); rx_shift_reg1((i * deserialization_factor)+1) <= h_int_reg(i*deserialization_factor); elsif (bitslip_count(i) rem 2 = 0) then rx_shift_reg1(i * deserialization_factor) <= h_int_reg(bitslip_count(i)/2 -1 + (i * deserialization_factor)); rx_shift_reg1((i * deserialization_factor)+1) <= l_int_reg(bitslip_count(i)/2 -1 + (i * deserialization_factor)); else rx_shift_reg1(i * deserialization_factor) <= l_int_reg(bitslip_count(i)/2 -1 + (i * deserialization_factor)); rx_shift_reg1((i * deserialization_factor)+1) <= h_int_reg(bitslip_count(i)/2 + (i * deserialization_factor)); end if; rx_shift_reg2(i * deserialization_factor) <= rx_shift_reg1(((i+1)* deserialization_factor)-2); rx_shift_reg2((i * deserialization_factor)+1) <= rx_shift_reg1(((i+1)* deserialization_factor)-1); end loop; end if; end if; end process SHIFTREG; -- Loading input data to shift register BIT_SELECT : process(rx_slowclk, pll_areset, rx_data_reset) begin if (pll_areset = '1' or rx_data_reset = '1') then rx_sync_reg1 <= (others => '0'); rx_sync_reg2 <= (others => '0'); rx_sync_reg1_buf2_pipe <= (others => '0'); rx_out_odd <= (others => '0'); rx_out_odd_mode <= (others => '0'); elsif ((rx_slowclk = '1') and rx_slowclk'event) then rx_sync_reg1 <= rx_shift_reg1; rx_sync_reg2 <= rx_shift_reg2; rx_sync_reg1_buf2_pipe <= rx_sync_reg1_buf2; if(use_extra_pll_clk = false) then if (select_bit = '1') then rx_out_odd_mode <= rx_sync_reg1_buf1_pipe; else rx_out_odd_mode <= rx_sync_reg2_buf1; end if; else if (select_bit = '1') then rx_out_odd_mode <= rx_sync_reg1_buf2_pipe; else rx_out_odd_mode <= rx_sync_reg2_buf2; end if; end if; rx_out_odd <= rx_out_odd_mode; end if; end process BIT_SELECT; process(rx_slowclk) begin if ((rx_slowclk = '1') and rx_slowclk'event) then sync_clock <= not sync_clock; select_bit <= not select_bit; end if; end process; SYNC_REG : process(sync_clock, pll_areset, rx_data_reset) begin if (pll_areset = '1' or rx_data_reset = '1') then rx_sync_reg1_buf1 <= (others => '0'); rx_sync_reg2_buf1 <= (others => '0'); rx_sync_reg1_buf1_pipe <= (others => '0'); elsif ((sync_clock = '1') and sync_clock'event) then rx_sync_reg1_buf1 <= rx_sync_reg1; rx_sync_reg2_buf1 <= rx_sync_reg2; rx_sync_reg1_buf1_pipe <= rx_sync_reg1_buf1; end if; end process SYNC_REG; SYNC_REG2 : process(rx_syncclk, pll_areset, rx_data_reset) begin if (pll_areset = '1' or rx_data_reset = '1') then rx_sync_reg1_buf2 <= (others => '0'); rx_sync_reg2_buf2 <= (others => '0'); elsif ((rx_syncclk = '1') and rx_syncclk'event) then rx_sync_reg1_buf2 <= rx_sync_reg1; rx_sync_reg2_buf2 <= rx_sync_reg2; end if; end process SYNC_REG2; OUTPUT_REG : process(rx_reg_clk, pll_areset, rx_data_reset) begin if (pll_areset = '1' or rx_data_reset = '1') then rx_out_reg <= (others => '0'); elsif ((rx_reg_clk = '1') and rx_reg_clk'event) then rx_out_reg <= rx_out_int; end if; end process; end behavior; -- flexible_lvds_rx -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : stratixiii_lvds_rx_dpa -- -- Description : Simulation model for Stratix III DPA block. -- -- Limitation : Only available to Stratix III. -- -- Results expected: Retimed data, dpa clock, enable and lock signal with the selected phase. -- -- ---END_ENTITY_HEADER----------------------------------------------------------- -- LIBRARY USED---------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -- ENTITY DECLARATION entity stratixiii_lvds_rx_dpa is -- GENERIC DECLARATION generic ( enable_soft_cdr_mode : string := "OFF"; sim_dpa_is_negative_ppm_drift : string := "OFF"; sim_dpa_net_ppm_variation : natural := 0; enable_dpa_align_to_rising_edge_only : string := "OFF"; enable_dpa_initial_phase_selection : string := "OFF"; dpa_initial_phase_value : natural := 0 ); -- PORT DECLARATION port ( --INPUT PORT DECLARATION rx_in : in std_logic; rx_fastclk : in std_logic; rx_enable : in std_logic; rx_dpa_reset : in std_logic; rx_dpa_hold : in std_logic; -- OUTPUT PORT DECLARATION rx_out : out std_logic := '0'; rx_dpa_clk : out std_logic := '0'; rx_dpa_loaden : out std_logic := '0'; rx_dpa_locked : out std_logic := '0' ); end stratixiii_lvds_rx_dpa; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of stratixiii_lvds_rx_dpa is -- FUNCTION DECLARATION -- get phase_shift value for the clock that acts as enable signal (for StratixIII lvds) function get_initial_phase_select ( constant i_initial_phase_select : in natural) return natural is begin if ((enable_dpa_initial_phase_selection = "ON") and (i_initial_phase_select > 0) and (i_initial_phase_select <= 7)) then return i_initial_phase_select; else return 0; end if; end get_initial_phase_select; -- CONSTANT DECLARATION constant INITIAL_PHASE_SELECT : natural := get_initial_phase_select(dpa_initial_phase_value); constant PHASE_NUM : natural := 8; -- TYPE DECLARATION type PHASE_TAP is array (PHASE_NUM -1 downto 0) of natural; -- SIGNAL DECLARATION signal dpa_clk_tmp : std_logic_vector (PHASE_NUM -1 downto 0); signal dpa_loaden : std_logic_vector (PHASE_NUM -1 downto 0) := (others => '0'); signal dpa_dataout_tmp : std_logic_vector (PHASE_NUM -1 downto 0) := (others => '0'); signal ppm_offset : integer := 0; signal count : integer := 0; signal rx_in_reg0 : std_logic := '0'; signal rx_in_reg1 : std_logic := '0'; signal dpa_locked_tmp : std_logic := '0'; signal first_clkin_edge_detect : std_logic := '0'; signal reg_clk : std_logic; signal counter_reset_value : integer ; signal count_value : integer ; signal clk_period : time := 0 ps; signal last_clk_period : time := 0 ps; signal last_clkin_edge : time := 0 ps; signal j : integer ; begin -- SIGNAL ASSIGNMENTS rx_dpa_loaden <= '0' when (enable_soft_cdr_mode = "ON") else dpa_loaden(INITIAL_PHASE_SELECT); reg_clk <= dpa_clk_tmp(INITIAL_PHASE_SELECT); -- PROCESS DECLARATION -- Calculate the clock period process (rx_fastclk) variable clk_period_tmp : time := 0 ps; begin if (rx_fastclk'event and rx_fastclk = '1') then if (first_clkin_edge_detect = '0') then first_clkin_edge_detect <= '1'; else clk_period_tmp := now - last_clkin_edge; end if; if (((clk_period_tmp = last_clk_period) or (clk_period_tmp = last_clk_period + 1 ps) or (clk_period_tmp = last_clk_period - 1 ps)) and (clk_period_tmp /= 0 ps ) and (last_clk_period /= 0 ps)) then dpa_locked_tmp <= '1'; else dpa_locked_tmp <= '0'; end if; last_clkin_edge <= now; last_clk_period <= clk_period_tmp; end if; end process; -- Generate the phase shifted dpa clock signals process (rx_fastclk) begin dpa_clk_tmp(0) <= rx_fastclk; dpa_clk_tmp(1) <= transport rx_fastclk after (clk_period * 0.125); dpa_clk_tmp(2) <= transport rx_fastclk after (clk_period * 0.25); dpa_clk_tmp(3) <= transport rx_fastclk after (clk_period * 0.375); dpa_clk_tmp(4) <= transport rx_fastclk after (clk_period * 0.5); dpa_clk_tmp(5) <= transport rx_fastclk after (clk_period * 0.625); dpa_clk_tmp(6) <= transport rx_fastclk after (clk_period * 0.75); dpa_clk_tmp(7) <= transport rx_fastclk after (clk_period * 0.875); end process; -- Generate the phase shifted dpa enable signals process (rx_enable) begin dpa_loaden(0) <= rx_enable; dpa_loaden(1) <= transport rx_enable after (clk_period * 0.125); dpa_loaden(2) <= transport rx_enable after (clk_period * 0.25); dpa_loaden(3) <= transport rx_enable after (clk_period * 0.375); dpa_loaden(4) <= transport rx_enable after (clk_period * 0.5); dpa_loaden(5) <= transport rx_enable after (clk_period * 0.625); dpa_loaden(6) <= transport rx_enable after (clk_period * 0.75); dpa_loaden(7) <= transport rx_enable after (clk_period * 0.875); end process; -- Generate the phase shifted data signals process (rx_in_reg1) begin dpa_dataout_tmp(0) <= rx_in_reg1; dpa_dataout_tmp(1) <= transport rx_in_reg1 after (clk_period * 0.125) ; dpa_dataout_tmp(2) <= transport rx_in_reg1 after (clk_period * 0.25) ; dpa_dataout_tmp(3) <= transport rx_in_reg1 after (clk_period * 0.375) ; dpa_dataout_tmp(4) <= transport rx_in_reg1 after (clk_period * 0.5) ; dpa_dataout_tmp(5) <= transport rx_in_reg1 after (clk_period * 0.625) ; dpa_dataout_tmp(6) <= transport rx_in_reg1 after (clk_period * 0.75) ; dpa_dataout_tmp(7) <= transport rx_in_reg1 after (clk_period * 0.875) ; end process; process (reg_clk) begin if (reg_clk'event and reg_clk = '1') then rx_in_reg0 <= rx_in; rx_in_reg1 <= rx_in_reg0; end if; end process; process (dpa_dataout_tmp, ppm_offset, rx_dpa_reset) begin if (enable_soft_cdr_mode = "OFF") then rx_out <= dpa_dataout_tmp(0); else if (rx_dpa_reset = '1') then rx_out <= '0'; else if (sim_dpa_is_negative_ppm_drift = "ON") then rx_out <= dpa_dataout_tmp(ppm_offset rem PHASE_NUM); elsif (ppm_offset = 0) then rx_out <= dpa_dataout_tmp(0); else rx_out <= transport dpa_dataout_tmp(0) after (clk_period * 0.125 * ppm_offset); end if; end if; end if; end process; process (dpa_clk_tmp, ppm_offset, rx_dpa_reset) begin if (enable_soft_cdr_mode = "OFF") then rx_dpa_clk <= dpa_clk_tmp(INITIAL_PHASE_SELECT); else if (rx_dpa_reset = '1') then rx_dpa_clk <= '0'; else if (sim_dpa_is_negative_ppm_drift = "ON") then rx_dpa_clk <= dpa_clk_tmp((INITIAL_PHASE_SELECT + ppm_offset) rem PHASE_NUM); elsif ((INITIAL_PHASE_SELECT + ppm_offset) = 0) then rx_dpa_clk <= dpa_clk_tmp(0); else rx_dpa_clk <= transport dpa_clk_tmp(0) after (clk_period * 0.125 * (INITIAL_PHASE_SELECT + ppm_offset)); end if; end if; end if; end process; process (dpa_locked_tmp, rx_dpa_reset) begin if (rx_dpa_reset = '1') then rx_dpa_locked <= '0'; else rx_dpa_locked <= dpa_locked_tmp; end if; end process; STRATIXIII_PPM_OFFSET : if (enable_soft_cdr_mode = "ON") generate process (rx_fastclk, rx_dpa_reset, rx_dpa_hold) variable initial : boolean := true; begin if(initial) then if(sim_dpa_net_ppm_variation = 0) then counter_reset_value <= 1; count_value <= 1; else counter_reset_value <= 1000000 / (sim_dpa_net_ppm_variation * 8); count_value <= 1000000 / (sim_dpa_net_ppm_variation * 8); end if; initial := false; end if; if (sim_dpa_net_ppm_variation = 0) then ppm_offset <= 0; else if (rx_dpa_reset = '1') then count <= 0; ppm_offset <= 0; else if(rx_dpa_hold = '0') then if (rx_fastclk'event and rx_fastclk = '1') then if (count < count_value) then count <= count + 1; else if (sim_dpa_is_negative_ppm_drift = "ON") then ppm_offset <= (ppm_offset - 1 + PHASE_NUM) rem PHASE_NUM; else ppm_offset <= ppm_offset + 1; end if; count <= 0; end if; end if; end if; end if; end if; end process; end generate STRATIXIII_PPM_OFFSET; end behavior; -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : stratixv_local_clk_divider -- -- Description : Simulation model for Stratix V local clock divider. -- -- Limitation : Only available to Stratix V. -- -- Results expected: This module is used to generate the local loaden signal from fast clock for StratixV -- family. To mimic local clock divider block. -- -- ---END_ENTITY_HEADER----------------------------------------------------------- -- LIBRARY USED---------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -- ENTITY DECLARATION entity stratixv_local_clk_divider is -- GENERIC DECLARATION generic ( clk_divide_by : natural := 4 ); -- PORT DECLARATION port ( --INPUT PORT DECLARATION clkin : in std_logic; -- OUTPUT PORT DECLARATION lloaden : out std_logic := '0' ); end stratixv_local_clk_divider; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of stratixv_local_clk_divider is -- FUNCTION DECLARATION -- CONSTANT DECLARATION -- TYPE DECLARATION -- SIGNAL DECLARATION signal lloaden_tmp : std_logic := '0'; signal cnt : integer := 0; signal count : integer := 0; begin -- SIGNAL ASSIGNMENTS lloaden <= lloaden_tmp; -- PROCESS DECLARATION process (clkin) begin if (clkin'event and clkin = '1') then count <= 1; end if; end process; process (clkin) begin if (clkin'event and clkin = '0') then --falling edge on fastclock if (count = 1) then if (cnt < (clk_divide_by-1)) then cnt <= cnt + 1; else cnt <= 0; end if; end if; end if; end process; process (cnt) begin if (cnt = (clk_divide_by-1)) then lloaden_tmp <= '1'; else lloaden_tmp <= '0'; end if; end process; end behavior; -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : stratixiii_lvds_rx_channel -- -- Description : Simulation model for each channel of Stratix III lvds receiver. -- Support both the dpa and non-dpa mode. -- -- Limitation : Only available to Stratix III. -- -- Results Expected: Deserialized output data, dpa lock signal, forwarded clock -- and status bit indicating whether maximum bitslip has been -- reached. -- ---END_ENTITY_HEADER----------------------------------------------------------- -- LIBRARY USED---------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use work.stratixiii_lvds_rx_dpa; use work.stratixv_local_clk_divider; -- ENTITY DECLARATION entity stratixiii_lvds_rx_channel is -- GENERIC DECLARATION generic ( deserialization_factor : natural; -- Required parameter enable_dpa_mode : string := "OFF"; data_align_rollover : natural := 10; lose_lock_on_one_change : string := "OFF"; reset_fifo_at_first_lock : string := "ON"; x_on_bitslip : string := "ON"; rx_align_data_reg : string := "RISING_EDGE"; enable_soft_cdr_mode : string := "OFF"; sim_dpa_output_clock_phase_shift : integer := 0; sim_dpa_is_negative_ppm_drift : string := "OFF"; sim_dpa_net_ppm_variation : natural := 0; enable_dpa_align_to_rising_edge_only : string := "OFF"; enable_dpa_initial_phase_selection : string := "OFF"; dpa_initial_phase_value : natural := 0; registered_output : string := "ON"; use_external_pll : string := "OFF"; use_dpa_calibration : boolean := false; enable_clock_pin_mode : string := "UNUSED"; ARRIAII_RX_STYLE : boolean := false; STRATIXV_RX_STYLE : boolean := false ); -- PORT DECLARATION port( --INPUT PORT DECLARATION rx_in : in std_logic; rx_fastclk : in std_logic; rx_slowclk : in std_logic; rx_dpaclock : in std_logic := '0'; rx_enable : in std_logic; rx_reset : in std_logic; rx_dpll_reset : in std_logic; rx_dpll_hold : in std_logic; rx_dpll_enable : in std_logic; rx_fifo_reset : in std_logic; rx_channel_data_align : in std_logic; rx_cda_reset : in std_logic; rx_dpa_lock_reset : in std_logic; rx_locked : in std_logic; -- OUTPUT PORT DECLARATION rx_out : out std_logic_vector(deserialization_factor-1 downto 0); rx_dpa_locked : out std_logic := '0'; rx_cda_max : out std_logic := '0'; rx_divfwdclk : out std_logic := '0' ); end stratixiii_lvds_rx_channel; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of stratixiii_lvds_rx_channel is -- CONSTANT DECLARATION constant RAM_WIDTH : natural := 6; constant MUX_WIDTH : natural := 12; -- TYPE DECLARATION -- SIGNAL DECLARATION -- constant signals signal fifo_write_clk : std_logic := '0'; signal fifo_read_clk : std_logic := '0'; signal temp_zero : std_logic := '0'; signal enable0_reg : std_logic := '0'; signal enable_negedge_count : boolean := false; signal rx_shift_reg : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); signal rx_parallel_load_reg : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); signal rx_out_reg : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); signal rx_dpa_sync_reg : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); signal rx_in_reg_pos : std_logic := '0'; signal rx_in_reg_neg : std_logic := '0'; signal fifo_out_sync_reg : std_logic := '0'; signal bitslip_mux_out : std_logic := '0'; signal dpa_in : std_logic := '0'; signal retime_data : std_logic := '0'; signal dpll_lock : std_logic := '0'; signal dpll_first_lock : std_logic := '0'; signal rx_channel_data_align_pre : std_logic := '0'; signal write_side_sync_reset : std_logic := '0'; signal read_side_sync_reset : std_logic := '0'; signal ram_array : std_logic_vector(RAM_WIDTH-1 downto 0) := (others => '0'); signal dpa_fifo_in : std_logic := '0'; signal dpa_fifo_out : std_logic := '0'; signal rx_in_reg_clk : std_logic := '0'; signal rx_bload : std_logic := '0'; signal rx_enable_dly : std_logic := '0'; signal load_enable_cdr : std_logic := '0'; signal dpa_clock : std_logic := '0'; signal dpa_locked : std_logic := '0'; signal dpa_loaden : std_logic := '0'; signal fast_clock : std_logic := '0'; signal start_counter : std_logic := '0'; signal rx_reg_clk : std_logic := '0'; signal rx_dpa_sync_reg_clk : std_logic := '0'; signal rx_divfwdclk_int : std_logic := '0'; signal j : integer ; signal lock_out_regr : std_logic := '0'; signal pad_regr : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); signal extra_regr : std_logic := '0'; signal in_bus_add : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); signal lock_out_reg_dly : std_logic := '0'; signal fifo_reset_regr : std_logic := '0'; signal int_pll_kick_reset : std_logic := '0'; signal dpa_lock_fifo_reset : std_logic := '0'; signal pll_locked : std_logic := '0'; signal wire_lock_state_mc_d : std_logic_vector(1 DOWNTO 0); signal lock_state_mc : std_logic_vector(1 DOWNTO 0) := (others => '0'); signal wire_lock_state_mc_ena : std_logic_vector(1 DOWNTO 0); signal dpaswitch : std_logic := '0'; signal rx_in_wire : std_logic := '0'; signal rx_dpaclock_wire : std_logic := '0'; signal local_clk_div_lloaden : std_logic := '0'; -- COMPONENT DECLARATION -- stratixiii dpa block component stratixiii_lvds_rx_dpa generic ( enable_soft_cdr_mode : string := "OFF"; sim_dpa_is_negative_ppm_drift : string := "OFF"; sim_dpa_net_ppm_variation : natural := 0; enable_dpa_align_to_rising_edge_only : string := "OFF"; enable_dpa_initial_phase_selection : string := "OFF"; dpa_initial_phase_value : natural := 0 ); port( rx_in : in std_logic; rx_fastclk : in std_logic; rx_enable : in std_logic := '1'; rx_dpa_reset : in std_logic; rx_dpa_hold : in std_logic; rx_out : out std_logic := '0'; rx_dpa_clk : out std_logic := '0'; rx_dpa_loaden : out std_logic := '0'; rx_dpa_locked : out std_logic := '0' ); end component; -- stratixiii_lvds_rx_dpa -- stratix V local clock divider block component stratixv_local_clk_divider generic ( clk_divide_by : natural := 4 ); port( clkin : in std_logic; lloaden : out std_logic := '0' ); end component; -- stratix V local clock divider block begin -- SIGNAL ASSIGNMENTS rx_out <= rx_out_reg when (registered_output = "ON") else rx_parallel_load_reg; rx_divfwdclk <= not rx_divfwdclk_int; dpa_fifo_in <= retime_data; dpa_fifo_out <= fifo_out_sync_reg; fifo_write_clk <= dpa_clock; fifo_read_clk <= rx_fastclk; rx_in_reg_clk <= rx_fastclk; rx_dpa_locked <=((lock_state_mc(0) and lock_state_mc(1)) and lock_out_reg_dly) when (use_dpa_calibration = true) else lock_out_reg_dly; rx_bload <= enable0_reg; rx_enable_dly <= local_clk_div_lloaden when ((STRATIXV_RX_STYLE = true) and (enable_clock_pin_mode = "ON")) else rx_enable; fast_clock <= dpa_clock when ((enable_dpa_mode = "ON") and (enable_soft_cdr_mode = "ON")) else rx_fastclk; rx_reg_clk <= not rx_divfwdclk_int when ((enable_dpa_mode = "ON") and (enable_soft_cdr_mode = "ON")) else rx_slowclk; rx_dpa_sync_reg_clk <= rx_divfwdclk_int when ((enable_dpa_mode = "ON") and (enable_soft_cdr_mode = "ON")) else '0'; int_pll_kick_reset <= ((lock_state_mc(0) and (not lock_state_mc(1))) or ((lock_state_mc(0) and lock_state_mc(1)) and rx_dpa_lock_reset)) when (use_dpa_calibration = true) else rx_dpa_lock_reset; pll_locked <= rx_locked; wire_lock_state_mc_ena(1 downto 0) <= (others => ((lock_state_mc(0) and lock_state_mc(1) and rx_dpa_lock_reset) or (not lock_state_mc(0) and not lock_state_mc(1) and lock_out_regr) or (lock_state_mc(0) and not lock_state_mc(1) and lock_out_reg_dly) or (not lock_state_mc(0) and lock_state_mc(1) and lock_out_regr))); wire_lock_state_mc_d <= ((((lock_state_mc(0) and (not lock_state_mc(1))) and lock_out_reg_dly) or (((not lock_state_mc(0)) and lock_state_mc(1)) and lock_out_regr)) and (not (((lock_state_mc(0) and lock_state_mc(1)) and rx_dpa_lock_reset) or (((not lock_state_mc(0)) and (not lock_state_mc(1))) and lock_out_regr)))) & (((((not lock_state_mc(0)) and (not lock_state_mc(1))) and lock_out_regr) or (((not lock_state_mc(0)) and lock_state_mc(1)) and lock_out_regr)) and (not (((lock_state_mc(0) and lock_state_mc(1)) and rx_dpa_lock_reset) or ((lock_state_mc(0) and (not lock_state_mc(1))) and lock_out_reg_dly)))); dpaswitch <= ((not lock_state_mc(0)) and (not lock_state_mc(1))) when (use_dpa_calibration = true) else '1'; fifo_reset_regr <= (((not lock_state_mc(0)) and lock_state_mc(1)) and (lock_out_regr xor lock_out_reg_dly)) when (use_dpa_calibration = true) else ((lock_out_regr xor lock_out_reg_dly) or (not dpa_locked) or rx_fifo_reset); rx_in_wire <= TRANSPORT rx_in after 120 ps when ((use_dpa_calibration = true) and (dpaswitch = '1')) else rx_in; rx_dpaclock_wire <= TRANSPORT rx_dpaclock when ((use_external_pll = "ON") and (STRATIXV_RX_STYLE = true) and (enable_dpa_mode = "ON")) else rx_fastclk; -- COMPONENT ASSIGNMENTS STRATIXIII_DPA: if (enable_dpa_mode = "ON") generate dpa_block : stratixiii_lvds_rx_dpa -- Stratix III DPA block generic map ( enable_soft_cdr_mode => enable_soft_cdr_mode, sim_dpa_is_negative_ppm_drift => sim_dpa_is_negative_ppm_drift, sim_dpa_net_ppm_variation => sim_dpa_net_ppm_variation, enable_dpa_align_to_rising_edge_only => enable_dpa_align_to_rising_edge_only, enable_dpa_initial_phase_selection => enable_dpa_initial_phase_selection, dpa_initial_phase_value => dpa_initial_phase_value ) port map ( rx_in => rx_in_wire, rx_fastclk => rx_dpaclock_wire, rx_enable => rx_enable, rx_dpa_reset => rx_reset, rx_dpa_hold => rx_dpll_hold, rx_out => retime_data, rx_dpa_clk => dpa_clock, rx_dpa_loaden => dpa_loaden, rx_dpa_locked => dpa_locked ); end generate STRATIXIII_DPA; STRATIXV_RX_LOCAL_CLK_DIVIDER: if ((STRATIXV_RX_STYLE = true) and (enable_clock_pin_mode = "ON")) generate rx_local_clk_divider : stratixv_local_clk_divider -- Stratix V local clock divider block generic map ( clk_divide_by => deserialization_factor ) port map ( clkin => fast_clock, lloaden => local_clk_div_lloaden ); end generate STRATIXV_RX_LOCAL_CLK_DIVIDER; -- PROCESS DECLARATION -- input synchronization register IN_SYNC_REGISTER : process (fast_clock) begin if (fast_clock = '1' and fast_clock'event) then rx_in_reg_pos <= rx_in_wire; elsif (fast_clock = '0' and fast_clock'event) then rx_in_reg_neg <= rx_in_wire; end if; end process IN_SYNC_REGISTER; -- the deserializer STRATIXIII_DESER : process(fast_clock) begin if (fast_clock'event and (fast_clock = '1')) then if (rx_bload = '1') then rx_parallel_load_reg <= rx_shift_reg; end if; rx_shift_reg <= rx_shift_reg(deserialization_factor-2 downto 0) & bitslip_mux_out; -- Registering load enable signal if ((enable_dpa_mode = "ON") and (enable_soft_cdr_mode = "ON")) then enable0_reg <= load_enable_cdr; else enable0_reg <= rx_enable_dly; end if; end if; end process STRATIXIII_DESER; STRATIXIII_FWDCLK : if ((enable_dpa_mode = "ON") and (enable_soft_cdr_mode = "ON")) generate -- STRATIXIII forwarded clock process (fast_clock) variable div_clk_count_pos : integer := 0; variable div_clk_count_neg : integer := 0; begin if (fast_clock = '1' and fast_clock'event) then if (div_clk_count_pos = deserialization_factor) then div_clk_count_pos := 1; else div_clk_count_pos := div_clk_count_pos + 1; end if; elsif (fast_clock = '0' and fast_clock'event) then div_clk_count_neg := div_clk_count_pos; end if; -- even deser mode if (deserialization_factor rem 2 = 0) then if (div_clk_count_pos = 1) then rx_divfwdclk_int <= '0'; elsif (div_clk_count_pos = ((deserialization_factor/2) + 1)) then rx_divfwdclk_int <= '1'; end if; else -- odd deser mode if (div_clk_count_pos = 1) then rx_divfwdclk_int <= '0'; elsif (div_clk_count_neg = ((deserialization_factor+1) / 2)) then rx_divfwdclk_int <= '1'; end if; end if; if (div_clk_count_neg = (deserialization_factor-1)) then load_enable_cdr <= '1'; elsif (div_clk_count_neg = deserialization_factor) then load_enable_cdr <= '0'; end if; end process; end generate STRATIXIII_FWDCLK; -- STRATIXIII bitslip logic STRATIXIII_BITSLIP : process (fast_clock, rx_cda_reset) variable start_corrupt_bits : boolean := false; variable num_corrupt_bits : integer := 0; variable bitslip_count : integer := 0; variable shift_reg_chain : std_logic_vector(MUX_WIDTH-1 downto 0) := (others => '0'); begin if (rx_cda_reset = '1') then bitslip_count := 0; rx_cda_max <= '0'; end if; if (fast_clock'event and (fast_clock = '1')) then if ((((rx_channel_data_align = '1') and (rx_channel_data_align_pre = '0')) or ((start_corrupt_bits = true) and (num_corrupt_bits < 4) and (rx_channel_data_align = '1'))) and (x_on_bitslip = "ON")) then bitslip_mux_out <= 'X'; else bitslip_mux_out <= shift_reg_chain(bitslip_count); end if; for j in data_align_rollover -1 downto 0 loop shift_reg_chain(j + 1) := shift_reg_chain(j); end loop; if ((enable_dpa_mode = "ON") and (enable_soft_cdr_mode = "ON"))then shift_reg_chain(0) := retime_data; elsif ((enable_dpa_mode = "ON") and ((rx_dpll_enable = '1') or (dpaswitch = '1')))then shift_reg_chain(0) := dpa_fifo_out; elsif (rx_align_data_reg = "RISING_EDGE") then shift_reg_chain(0) := rx_in_reg_pos; else shift_reg_chain(0) := rx_in_reg_neg; end if; if ((rx_channel_data_align = '1') and (rx_channel_data_align_pre = '0'))then bitslip_count := (bitslip_count + 1) rem (data_align_rollover + 1); if (bitslip_count = data_align_rollover) then rx_cda_max <= '1'; else rx_cda_max <= '0'; end if; start_corrupt_bits := true; num_corrupt_bits := 1; elsif ((rx_channel_data_align = '0') and (rx_channel_data_align_pre = '1'))then start_corrupt_bits := false; num_corrupt_bits := 0; end if; if (start_corrupt_bits = true) then if (num_corrupt_bits = 3) then start_corrupt_bits := false; else num_corrupt_bits := num_corrupt_bits + 1; end if; end if; rx_channel_data_align_pre <= rx_channel_data_align; end if; end process STRATIXIII_BITSLIP; STRATIXIII_DPA_FIFO : if ((enable_dpa_mode = "ON") and (enable_soft_cdr_mode = "OFF")) generate -- STRATIXIII Phase Compensation FIFO DPA_FIFO : process (fifo_write_clk, fifo_read_clk, rx_reset, fifo_reset_regr) variable wrPtr : integer := 0; variable rdPtr : integer := 3; variable fifo_in_sync_reg : std_logic := '0'; begin if (rx_reset = '1' or fifo_reset_regr = '1') then wrPtr := 0; rdPtr := 3; ram_array <= (others => '0'); fifo_in_sync_reg := '0'; fifo_out_sync_reg <= '0'; write_side_sync_reset <= '1'; read_side_sync_reset <= '1'; else if (fifo_write_clk'event and (fifo_write_clk = '1')) then write_side_sync_reset <= '0'; if (write_side_sync_reset = '0') then ram_array(wrPtr) <= fifo_in_sync_reg; fifo_in_sync_reg := dpa_fifo_in; wrPtr := (wrPtr + 1) rem 6; end if; end if; if (fifo_read_clk'event and (fifo_read_clk = '1')) then read_side_sync_reset <= '0'; if (read_side_sync_reset = '0') then fifo_out_sync_reg <= ram_array(rdPtr); rdPtr := (rdPtr + 1) rem 6; end if; end if; end if; end process DPA_FIFO; end generate STRATIXIII_DPA_FIFO; OUTPUT_REGISTER : process (rx_reg_clk) begin if (rx_reg_clk = '1' and rx_reg_clk'event) then if ((enable_dpa_mode = "ON") and (enable_soft_cdr_mode = "ON")) then rx_out_reg <= rx_dpa_sync_reg; else rx_out_reg <= rx_parallel_load_reg; end if; end if; end process OUTPUT_REGISTER; DPA_SYNC_REGISTER : process (rx_dpa_sync_reg_clk) begin if ((rx_dpa_sync_reg_clk = '1') and rx_dpa_sync_reg_clk'event) then rx_dpa_sync_reg <= rx_parallel_load_reg; end if; end process DPA_SYNC_REGISTER; STRATIXIII_DPA_LOCKED : process (rx_slowclk, rx_reset, rx_fifo_reset, pll_locked ,int_pll_kick_reset) variable accum_regr_temp : unsigned(8 downto 0) := (others => '0'); variable int_accum_regr_temp : integer; begin if (rx_reset = '1' or pll_locked = '0' or int_pll_kick_reset = '1') then extra_regr <= '0'; lock_out_regr <= '0'; for j in deserialization_factor-1 downto 0 loop pad_regr(j) <= '0'; end loop; for j in 8 downto 0 loop accum_regr_temp(j) := '0'; end loop; if (rx_reset = '1' or pll_locked = '0') then lock_out_reg_dly <= '0'; end if; elsif rising_edge(rx_slowclk) then for j in deserialization_factor-1 downto 0 loop if (registered_output = "ON") then pad_regr <= rx_out_reg; else pad_regr <= rx_parallel_load_reg; end if; end loop; extra_regr <= pad_regr(deserialization_factor-1); in_bus_add(0) <= extra_regr xor pad_regr(0); lock_out_reg_dly <= lock_out_regr; for j in deserialization_factor-1 downto 1 loop in_bus_add(j) <= pad_regr(j) xor pad_regr(j-1); end loop; int_accum_regr_temp := conv_integer(accum_regr_temp); for j in deserialization_factor-1 downto 0 loop if (in_bus_add(j) = '1') then int_accum_regr_temp := int_accum_regr_temp + 1; end if; end loop; accum_regr_temp := conv_unsigned(int_accum_regr_temp, 9); if (accum_regr_temp >= 256) then lock_out_regr <= '1'; end if; end if; if (use_dpa_calibration = true) then if (rx_reset = '1' or pll_locked = '0') then lock_state_mc(1 downto 0) <= (others => '0'); elsif rising_edge(rx_slowclk) then if (wire_lock_state_mc_ena(1) = '1') then lock_state_mc(1) <= wire_lock_state_mc_d(1); end if; if (wire_lock_state_mc_ena(0) = '1') then lock_state_mc(0) <= wire_lock_state_mc_d(0); end if; end if; end if; end process STRATIXIII_DPA_LOCKED; end behavior; -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : stratixiii_lvds_rx -- -- Description : Stratix III lvds receiver. Support both the dpa and non-dpa -- mode. -- -- Limitation : Only available to Stratix III. -- -- Results Expected: Deserialized output data, dpa lock signal, forwarded clock -- and status bit indicating whether maximum bitslip has been -- reached. -- ---END_ENTITY_HEADER----------------------------------------------------------- -- LIBRARY USED---------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use work.stratixiii_lvds_rx_channel; -- ENTITY DECLARATION entity stratixiii_lvds_rx is -- GENERIC DECLARATION generic ( number_of_channels : natural; -- Required parameter deserialization_factor : natural; -- Required parameter enable_dpa_mode : string := "OFF"; data_align_rollover : natural := 10; lose_lock_on_one_change : string := "OFF"; reset_fifo_at_first_lock : string := "ON"; x_on_bitslip : string := "ON"; rx_align_data_reg : string := "RISING_EDGE"; enable_soft_cdr_mode : string := "OFF"; sim_dpa_output_clock_phase_shift : integer := 0; sim_dpa_is_negative_ppm_drift : string := "OFF"; sim_dpa_net_ppm_variation : natural := 0; enable_dpa_align_to_rising_edge_only : string := "OFF"; enable_dpa_initial_phase_selection : string := "OFF"; dpa_initial_phase_value : natural := 0; registered_output : string := "ON"; enable_clock_pin_mode : string := "UNUSED"; use_dpa_calibration : boolean := false; ARRIAII_RX_STYLE : boolean := false; STRATIXV_RX_STYLE : boolean := false ); -- PORT DECLARATION port( --INPUT PORT DECLARATION rx_in : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_fastclk : in std_logic; --Required port rx_slowclk : in std_logic; --Required port rx_enable : in std_logic := '1'; rx_dpaclock : in std_logic; rx_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_hold : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_enable : in std_logic_vector(number_of_channels-1 downto 0) := (others => '1'); rx_fifo_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_channel_data_align : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_cda_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpa_lock_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_locked : in std_logic; -- OUTPUT PORT DECLARATION rx_out : out std_logic_vector(deserialization_factor*number_of_channels -1 downto 0); rx_dpa_locked : out std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_cda_max : out std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_divfwdclk : out std_logic_vector(number_of_channels-1 downto 0) := (others => '0') ); end stratixiii_lvds_rx; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of stratixiii_lvds_rx is -- COMPONENT DECLARATION -- stratixiii lvds_rx_channel component stratixiii_lvds_rx_channel generic ( deserialization_factor : natural; -- Required parameter enable_dpa_mode : string := "OFF"; data_align_rollover : natural := 10; lose_lock_on_one_change : string := "OFF"; reset_fifo_at_first_lock : string := "ON"; x_on_bitslip : string := "ON"; rx_align_data_reg : string := "RISING_EDGE"; enable_soft_cdr_mode : string := "OFF"; sim_dpa_output_clock_phase_shift : integer := 0; sim_dpa_is_negative_ppm_drift : string := "OFF"; sim_dpa_net_ppm_variation : natural := 0; enable_dpa_align_to_rising_edge_only : string := "OFF"; enable_dpa_initial_phase_selection : string := "OFF"; dpa_initial_phase_value : natural := 0; registered_output : string := "ON"; enable_clock_pin_mode : string := "UNUSED"; use_dpa_calibration : boolean := false; ARRIAII_RX_STYLE : boolean := false; STRATIXV_RX_STYLE : boolean := false ); port ( rx_in : in std_logic; --Required port rx_fastclk : in std_logic; --Required port rx_slowclk : in std_logic; --Required port rx_enable : in std_logic := '1'; rx_dpaclock : in std_logic; rx_reset : in std_logic; rx_dpll_reset : in std_logic; rx_dpll_hold : in std_logic; rx_dpll_enable : in std_logic; rx_fifo_reset : in std_logic; rx_channel_data_align : in std_logic; rx_cda_reset : in std_logic; rx_dpa_lock_reset : in std_logic; rx_locked : in std_logic; rx_out : out std_logic_vector(deserialization_factor-1 downto 0); rx_dpa_locked : out std_logic; rx_cda_max : out std_logic; rx_divfwdclk : out std_logic ); end component; -- stratixiii_lvds_rx_channel begin -- COMPONENT ASSIGNMENTS STRATIXIII_RX_CHANNEL : for i in 0 to number_of_channels-1 generate LVDS_CHANNEL: stratixiii_lvds_rx_channel generic map ( deserialization_factor => deserialization_factor, enable_dpa_mode => enable_dpa_mode, data_align_rollover => data_align_rollover, lose_lock_on_one_change => lose_lock_on_one_change, reset_fifo_at_first_lock => reset_fifo_at_first_lock, x_on_bitslip => x_on_bitslip, rx_align_data_reg => rx_align_data_reg, enable_soft_cdr_mode => enable_soft_cdr_mode, sim_dpa_output_clock_phase_shift => sim_dpa_output_clock_phase_shift, sim_dpa_is_negative_ppm_drift => sim_dpa_is_negative_ppm_drift, sim_dpa_net_ppm_variation => sim_dpa_net_ppm_variation, enable_dpa_align_to_rising_edge_only => enable_dpa_align_to_rising_edge_only, enable_dpa_initial_phase_selection => enable_dpa_initial_phase_selection, dpa_initial_phase_value => dpa_initial_phase_value, registered_output => registered_output, enable_clock_pin_mode => enable_clock_pin_mode, use_dpa_calibration => use_dpa_calibration, ARRIAII_RX_STYLE => ARRIAII_RX_STYLE, STRATIXV_RX_STYLE => STRATIXV_RX_STYLE ) port map ( rx_in => rx_in(i), rx_fastclk => rx_fastclk, rx_slowclk => rx_slowclk, rx_enable => rx_enable, rx_dpaclock => rx_dpaclock, rx_reset => rx_reset(i), rx_dpll_reset => rx_dpll_reset(i), rx_dpll_hold => rx_dpll_hold(i), rx_dpll_enable => rx_dpll_enable(i), rx_fifo_reset => rx_fifo_reset(i), rx_channel_data_align => rx_channel_data_align(i), rx_cda_reset => rx_cda_reset(i), rx_out => rx_out((i+1)*deserialization_factor-1 downto i*deserialization_factor), rx_dpa_locked => rx_dpa_locked(i), rx_cda_max => rx_cda_max(i), rx_dpa_lock_reset => rx_dpa_lock_reset(i), rx_locked => rx_locked, rx_divfwdclk => rx_divfwdclk(i) ); end generate STRATIXIII_RX_CHANNEL; end behavior; -- END OF ARCHITECTURE -- START ENTITY HEADER --------------------------------------------------------- -- -- Entity Name : altlvds_rx -- -- Description : Low Voltage Differential Signaling (LVDS) receiver -- megafunction. The altlvds_rx megafunction implements a -- deserialization receiver. LVDS is a high speed IO interface -- that uses inputs without a reference voltage. LVDS uses -- two wires carrying differential values to create a single -- channel. These wires are connected to two pins on -- supported device to create a single LVDS channel -- -- Limitations : Only available for STRATIX, -- STRATIX GX, Stratix II, Cyclone and Cyclone II families. -- --Results expected : output clock, deserialized output data and pll locked -- signal. -- -- END ENTITY HEADER ----------------------------------------------------------- -- LIBRARY USED----------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use work.ALTERA_DEVICE_FAMILIES.all; use work.MF_stratix_pll; use work.MF_stratixii_pll; use work.MF_stratixiii_pll; use work.stratixii_lvds_rx; use work.flexible_lvds_rx; use work.stratixiii_lvds_rx; -- ENTITY DECLARATION entity altlvds_rx is -- GENERIC DECLARATION generic ( number_of_channels : natural; -- Required parameter deserialization_factor : natural; -- Required parameter registered_output : string := "ON"; inclock_period : natural := 10000; -- Required parameter inclock_boost : natural := 0; cds_mode : string := "UNUSED"; intended_device_family : string := "Stratix"; input_data_rate : natural := 0; inclock_data_alignment : string := "UNUSED"; registered_data_align_input : string := "ON"; common_rx_tx_pll : string := "ON"; enable_dpa_mode : string := "OFF"; enable_dpa_pll_calibration : string := "OFF"; enable_dpa_calibration : string := "ON"; enable_dpa_fifo : string := "ON"; use_dpll_rawperror : string := "OFF"; use_coreclock_input : string := "OFF"; dpll_lock_count : natural := 0; dpll_lock_window : natural := 0; outclock_resource : string := "AUTO"; data_align_rollover : natural := 10; lose_lock_on_one_change : string := "OFF"; reset_fifo_at_first_lock : string := "ON"; use_external_pll : string := "OFF"; implement_in_les : string := "OFF"; buffer_implementation : string := "RAM"; port_rx_data_align : string := "PORT_CONNECTIVITY"; port_rx_channel_data_align : string := "PORT_CONNECTIVITY"; pll_operation_mode : string := "NORMAL"; x_on_bitslip : string := "ON"; use_no_phase_shift : string := "ON"; rx_align_data_reg : string := "RISING_EDGE"; inclock_phase_shift : integer := 0; enable_soft_cdr_mode : string := "OFF"; sim_dpa_output_clock_phase_shift : integer := 0; sim_dpa_is_negative_ppm_drift : string := "OFF"; sim_dpa_net_ppm_variation : natural := 0; enable_dpa_align_to_rising_edge_only : string := "OFF"; enable_dpa_initial_phase_selection : string := "OFF"; dpa_initial_phase_value :natural := 0; pll_self_reset_on_loss_lock : string := "OFF"; refclk_frequency : string := "UNUSED"; enable_clock_pin_mode : string := "UNUSED"; data_rate : string := "UNUSED"; lpm_hint : string := "UNUSED"; lpm_type : string := "altlvds_rx"; -- Specifies whether the source of the input clock is from the PLL clk_src_is_pll : string := "off" ); -- PORT DECLARATION port ( --INPUT PORT DECLARATION rx_in : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_inclock : in std_logic := '0'; rx_syncclock : in std_logic := '0'; rx_dpaclock : in std_logic := '0'; rx_readclock : in std_logic := '0'; rx_enable : in std_logic := '0'; rx_deskew : in std_logic := '0'; rx_pll_enable : in std_logic := '1'; rx_data_align : in std_logic := 'Z'; rx_data_align_reset : in std_logic := '0'; rx_reset : in std_logic_vector(number_of_channels-1 downto 0):= (others => '0'); rx_dpll_reset : in std_logic_vector(number_of_channels-1 downto 0):= (others => '0'); rx_dpll_hold : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_enable : in std_logic_vector(number_of_channels-1 downto 0) := (others => '1'); rx_fifo_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_channel_data_align : in std_logic_vector(number_of_channels-1 downto 0) := (others => 'Z'); rx_cda_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_coreclk : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); pll_areset : in std_logic := '0'; rx_data_reset : in std_logic := '0'; dpa_pll_recal : in std_logic := '0'; pll_phasedone : in std_logic := '1'; rx_dpa_lock_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); -- OUTPUT PORT DECLARATION rx_out : out std_logic_vector(deserialization_factor*number_of_channels -1 downto 0); rx_outclock : out std_logic; rx_locked : out std_logic; rx_dpa_locked : out std_logic_vector(number_of_channels-1 downto 0); rx_cda_max : out std_logic_vector(number_of_channels-1 downto 0); rx_divfwdclk : out std_logic_vector(number_of_channels-1 downto 0); dpa_pll_cal_busy : out std_logic; pll_phasestep : out std_logic; pll_phaseupdown : out std_logic; pll_phasecounterselect: out std_logic_Vector(3 downto 0); pll_scanclk : out std_logic); end altlvds_rx; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of altlvds_rx is -- CONSTANT DECLARATION constant STRATIX_RX_STYLE : boolean := (FEATURE_FAMILY_STRATIX_NONGX(intended_device_family) or (FEATURE_FAMILY_STRATIXGX(intended_device_family) and (enable_dpa_mode = "OFF"))); constant STRATIXGX_DPA_RX_STYLE : boolean := (FEATURE_FAMILY_STRATIXGX(intended_device_family) and (enable_dpa_mode = "ON")); constant STRATIXII_RX_STYLE : boolean := FEATURE_FAMILY_BASE_STRATIXII(intended_device_family); constant STRATIXIII_RX_STYLE : boolean := FEATURE_FAMILY_BASE_STRATIXIII(intended_device_family); constant CYCLONE_RX_STYLE : boolean := FEATURE_FAMILY_BASE_CYCLONE(intended_device_family); constant CYCLONEII_RX_STYLE : boolean := FEATURE_FAMILY_BASE_CYCLONEII(intended_device_family); constant CYCLONEIII_RX_STYLE : boolean := FEATURE_FAMILY_BASE_CYCLONEIII(intended_device_family); constant ARRIAII_RX_STYLE : boolean := FEATURE_FAMILY_ARRIAIIGX(intended_device_family); constant STRATIXV_RX_STYLE : boolean := FEATURE_FAMILY_STRATIXV(intended_device_family); constant FAMILY_HAS_FLEXIBLE_LVDS : boolean := FEATURE_FAMILY_HAS_FLEXIBLE_LVDS(intended_device_family) or (((STRATIX_RX_STYLE = true) or (STRATIXII_RX_STYLE = true) or (STRATIXIII_RX_STYLE = true)) and (implement_in_les = "ON")); constant FAMILY_HAS_STRATIX_STYLE_PLL : boolean := FEATURE_FAMILY_HAS_STRATIX_STYLE_PLL(intended_device_family); constant FAMILY_HAS_STRATIXII_STYLE_PLL : boolean := FEATURE_FAMILY_HAS_STRATIXII_STYLE_PLL(intended_device_family); constant FAMILY_HAS_STRATIXIII_STYLE_PLL : boolean := FEATURE_FAMILY_USES_STRATIXIII_PLL(intended_device_family); constant VSERIES_FAMILY : boolean := (FEATURE_FAMILY_STRATIXV(intended_device_family) or FEATURE_FAMILY_ARRIAV(intended_device_family)); -- FUNCTION DECLARATION --- Convert integer to string --- function int_to_str( constant value : integer ) return string is variable ivalue : integer := 0; variable index : integer := 0; variable strlen : integer := 0; variable digit : integer := 0; variable temp : string(1 to 8) := "00000000"; begin ivalue := abs(value); strlen := 0; while (ivalue > 0) loop ivalue := ivalue/10; strlen := strlen + 1; end loop; if (strlen = 0) then strlen := 1; end if; ivalue := abs(value); index := strlen; 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(1 to strlen)); else return temp(1 to strlen); end if; end int_to_str; -- M value for stratix/stratix II/Cyclone/Cyclone II PLL function pll_m_value(constant i_input_data_rate, i_inclock_period : in natural) return natural is variable i_pll_m_value : natural; begin i_pll_m_value := (((i_input_data_rate * i_inclock_period) + (5* 100000)) / 1000000); return i_pll_m_value; end pll_m_value; -- D value for Stratix/Stratix II/Cyclone/Cyclone II PLL function pll_d_value(constant i_input_data_rate, i_inclock_period : in natural) return natural is variable i_pll_d_value : natural; begin if ((i_input_data_rate /= 0) and (i_inclock_period /= 0)) then if (FAMILY_HAS_FLEXIBLE_LVDS = true) then i_pll_d_value := 2; else i_pll_d_value := 1; end if; else i_pll_d_value := 1; end if; return i_pll_d_value; end pll_d_value; --- calculate clock boost value need by the pll --- function clock_boost_calc (constant i_input_data_rate, i_inclock_period, i_deserialization_factor, i_inclock_boost : in natural) return natural is variable i_input_clock_boost : natural; begin if ((i_input_data_rate /= 0) and (i_inclock_period /= 0)) then i_input_clock_boost := pll_m_value (i_input_data_rate, i_inclock_period); else if (inclock_boost = 0) then i_input_clock_boost := i_deserialization_factor; else i_input_clock_boost := i_inclock_boost; end if; end if; return i_input_clock_boost; end clock_boost_calc; --- get phase delay in ps for stratix pll --- function get_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; variable x, int_delay : integer := 0; begin -- get delay in ps ( * inclock period / 360 degress ) if ((i_phase_delay = "UNUSED") or (VSERIES_FAMILY = true)) then int_delay := inclock_phase_shift; else if (i_phase_delay = "EDGE_ALIGNED") then my_phase := 0; elsif (i_phase_delay = "CENTER_ALIGNED") then -- CENTER_ALIGNED means 180 degrees my_phase := (180 * inclock_period) / 360; elsif (i_phase_delay = "45_DEGREES") then my_phase := (45 * inclock_period) / 360; elsif (i_phase_delay = "90_DEGREES") then my_phase := (90 * inclock_period) / 360; elsif (i_phase_delay = "135_DEGREES") then my_phase := (135 * inclock_period) / 360; elsif (i_phase_delay = "180_DEGREES") then my_phase := (180 * inclock_period) / 360; elsif (i_phase_delay = "225_DEGREES") then my_phase := (225 * inclock_period) / 360; elsif (i_phase_delay = "270_DEGREES") then my_phase := (270 * inclock_period) / 360; elsif (i_phase_delay = "315_DEGREES") then my_phase := (315 * inclock_period) / 360; else ASSERT FALSE REPORT "Invalid clock data alignment. Using 'EDGE_ALIGNED' instead" SEVERITY WARNING; my_phase :=0; end if; -- Add 1 to "round up" calculation result my_phase := my_phase + 1; -- phase shift in ps = ( * inclock_period / 360 ) / fast clock multiply_by factor -- in other words, the phase shift is a percentage of the fast clock period int_delay := my_phase / clock_boost_calc(input_data_rate, inclock_period, deserialization_factor, inclock_boost); -- Add 1 to "round up" calculation result int_delay := int_delay + 1; end if; return int_delay; end get_phase_delay; --- get phase delay in ps for stratix ii pll --- function get_stxii_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; begin my_phase := get_phase_delay(i_phase_delay) - (inclock_period / (2 * clock_boost_calc(input_data_rate, inclock_period, deserialization_factor, inclock_boost))); return my_phase; end get_stxii_phase_delay; --- get clk1_multiply_by value for PLL (for flexible lvds) function get_flvds_clk1_multiply_by ( constant i_deserialization_factor : in natural) return natural is variable clk1_mult_by : natural := 0; begin if (FAMILY_HAS_FLEXIBLE_LVDS = true) then if ((i_deserialization_factor rem 2) = 1) then clk1_mult_by := clock_boost_calc(input_data_rate, inclock_period, deserialization_factor, inclock_boost); else clk1_mult_by := 1; end if; end if; return clk1_mult_by; end get_flvds_clk1_multiply_by; --- get clk1_divide_by value for PLL (for flexible lvds) function get_flvds_clk1_divide_by ( constant i_deserialization_factor : in natural) return natural is variable clk1_div_by : natural := 0; begin if (FAMILY_HAS_FLEXIBLE_LVDS = true) then if ((i_deserialization_factor rem 2) = 1) then clk1_div_by := i_deserialization_factor; clk1_div_by := clk1_div_by * pll_d_value(input_data_rate, inclock_period); else clk1_div_by := 1; end if; end if; return clk1_div_by; end get_flvds_clk1_divide_by; --- get clk1_phase_shift value for PLL (for flexible lvds) function get_flvds_clk1_phase_shift ( constant i_deserialization_factor : in natural; constant i_phase_shift : in string) return string is begin if (FAMILY_HAS_FLEXIBLE_LVDS = true) then if ((i_deserialization_factor rem 2) = 1) then return i_phase_shift; else return "0"; end if; else return "0"; end if; end get_flvds_clk1_phase_shift; --- get clk2_multiply_by value for PLL (for flexible lvds) function get_flvds_clk2_multiply_by ( constant i_deserialization_factor : in natural) return natural is variable clk2_mult_by : natural := 0; begin if (FAMILY_HAS_FLEXIBLE_LVDS = true) then if ((i_deserialization_factor rem 2) = 1) then clk2_mult_by := clock_boost_calc(input_data_rate, inclock_period, deserialization_factor, inclock_boost) * 2; else clk2_mult_by := clock_boost_calc(input_data_rate, inclock_period, deserialization_factor, inclock_boost); end if; end if; return clk2_mult_by; end get_flvds_clk2_multiply_by; --- get clk2_divide_by value for PLL (for flexible lvds) function get_flvds_clk2_divide_by ( constant i_deserialization_factor : in natural) return natural is variable clk2_div_by : natural := 0; begin if (FAMILY_HAS_FLEXIBLE_LVDS = true) then if ((i_deserialization_factor rem 2) = 0) then clk2_div_by := i_deserialization_factor / 2; else clk2_div_by := i_deserialization_factor; end if; end if; clk2_div_by := clk2_div_by * pll_d_value(input_data_rate, inclock_period); return clk2_div_by; end get_flvds_clk2_divide_by; --- get pll_type for PLL (for flexible lvds) function get_flvds_pll_type ( constant i_inclock_alignment : in string) return string is begin if (i_inclock_alignment = "UNUSED") then return "auto"; else return "flvds"; end if; end get_flvds_pll_type; --- get phase delay in ps for cyclone ii and stratix II in LE mode --- function get_stxii_le_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; begin if ((use_no_phase_shift = "OFF") and (pll_operation_mode = "SOURCE_SYNCHRONOUS")) then my_phase := get_phase_delay(i_phase_delay) - (inclock_period / (4 * clock_boost_calc(input_data_rate, inclock_period, deserialization_factor, inclock_boost))); else my_phase := get_phase_delay(i_phase_delay); end if; return my_phase; end get_stxii_le_phase_delay; --- get clk1_phase_shift value for PLL (for flexible lvds) function get_stxii_le_clk1_phase_shift ( constant i_deserialization_factor : in natural; constant i_phase_shift : in string) return string is begin if (FAMILY_HAS_FLEXIBLE_LVDS = true) then if ((i_deserialization_factor rem 2) = 1) then return i_phase_shift; else return "0"; end if; else return "0"; end if; end get_stxii_le_clk1_phase_shift; --- get phase delay in ps for stratix III in LE mode --- function get_stxiii_le_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; begin my_phase := get_phase_delay(i_phase_delay) - (inclock_period * pll_d_value(input_data_rate,inclock_period)/ (4 * clock_boost_calc(input_data_rate,inclock_period, deserialization_factor, inclock_boost))); return my_phase; end get_stxiii_le_phase_delay; --- get phase_shift value for the clock that acts as enable signal (for StratixIII lvds) function get_clk_ena_phase_shift ( constant i_phase_shift : in string) return string is variable fast_clk_ena_phase_shift : integer := 0; begin fast_clk_ena_phase_shift := (deserialization_factor*2-3) * (inclock_period/(2*clock_boost_calc(input_data_rate, inclock_period, deserialization_factor, inclock_boost))); return int_to_str(get_stxii_phase_delay(i_phase_shift) + fast_clk_ena_phase_shift); end get_clk_ena_phase_shift; -- converts uppercase parameter values (e.g. "AUTO") to lowercase ("auto") -- as expected by stratix_pll model function alpha_tolower (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin for i in 1 to string_length loop case given_string(i) is when 'A' => result_string(i) := 'a'; when 'B' => result_string(i) := 'b'; when 'C' => result_string(i) := 'c'; when 'D' => result_string(i) := 'd'; when 'E' => result_string(i) := 'e'; when 'F' => result_string(i) := 'f'; when 'G' => result_string(i) := 'g'; when 'H' => result_string(i) := 'h'; when 'I' => result_string(i) := 'i'; when 'J' => result_string(i) := 'j'; when 'K' => result_string(i) := 'k'; when 'L' => result_string(i) := 'l'; when 'M' => result_string(i) := 'm'; when 'N' => result_string(i) := 'n'; when 'O' => result_string(i) := 'o'; when 'P' => result_string(i) := 'p'; when 'Q' => result_string(i) := 'q'; when 'R' => result_string(i) := 'r'; when 'S' => result_string(i) := 's'; when 'T' => result_string(i) := 't'; when 'U' => result_string(i) := 'u'; when 'V' => result_string(i) := 'v'; when 'W' => result_string(i) := 'w'; when 'X' => result_string(i) := 'x'; when 'Y' => result_string(i) := 'y'; when 'Z' => result_string(i) := 'z'; when others => result_string(i) := given_string(i); end case; end loop; return (result_string(1 to string_length)); end; -- CONSTANT DECLARATION -- these constants are PLL parameters calculated from the altlvds_rx parameters given constant PHASE_INCLOCK : string := int_to_str(get_phase_delay(inclock_data_alignment)); constant STXII_PHASE_INCLOCK : string := int_to_str(get_stxii_phase_delay(inclock_data_alignment)); constant INT_CLOCK_BOOST : natural := clock_boost_calc(input_data_rate, inclock_period, deserialization_factor, inclock_boost); constant REGISTER_WIDTH : natural := deserialization_factor * number_of_channels; constant FLVDS_CLK0_DIV : natural := pll_d_value(input_data_rate, inclock_period); constant FLVDS_CLK1_MULT : natural := get_flvds_clk1_multiply_by(deserialization_factor); constant FLVDS_CLK1_DIV : natural := get_flvds_clk1_divide_by(deserialization_factor); constant FLVDS_CLK2_MULT : natural := get_flvds_clk2_multiply_by(deserialization_factor); constant FLVDS_CLK2_DIV : natural := get_flvds_clk2_divide_by(deserialization_factor); constant FLVDS_CLK1_PHASE_SHIFT : string := get_flvds_clk1_phase_shift(deserialization_factor, PHASE_INCLOCK); constant FLVDS_PLL_TYPE : string := get_flvds_pll_type(inclock_data_alignment); constant STXII_LE_PHASE_INCLOCK : string := int_to_str(get_stxii_le_phase_delay(inclock_data_alignment)); constant STXII_LE_CLK1_PHASE_SHIFT : string := get_stxii_le_clk1_phase_shift(deserialization_factor, STXII_LE_PHASE_INCLOCK); constant STXIII_LE_PHASE_INCLOCK : string := int_to_str(get_stxiii_le_phase_delay(inclock_data_alignment)); constant STXIII_LE_CLK1_PHASE_SHIFT : string := get_stxii_le_clk1_phase_shift(deserialization_factor, STXIII_LE_PHASE_INCLOCK); constant IS_USING_EXTRA_DDIO_REG : boolean := (CYCLONE_RX_STYLE = true) or (CYCLONEII_RX_STYLE = true) or (CYCLONEIII_RX_STYLE = true); constant IS_USING_EXTRA_PLL_CLK : boolean := (CYCLONE_RX_STYLE = false) and (CYCLONEII_RX_STYLE = false); constant IS_ADDING_EXTRA_LATENCY : boolean := (CYCLONE_RX_STYLE = true) or (CYCLONEII_RX_STYLE = true) or (CYCLONEIII_RX_STYLE = true); constant CLK_ENA_PHASE_SHIFT : string := get_clk_ena_phase_shift(inclock_data_alignment); constant use_dpa_calibration : boolean := ((ARRIAII_RX_STYLE = true) and (enable_dpa_calibration = "ON")); -- TYPE DECLARATION type CHANNEL_CNT is array (number_of_channels-1 downto 0) of integer; type DPA_FIFO_RAM is array (3 downto 0) of std_logic_vector(REGISTER_WIDTH -1 downto 0); -- SIGNAL DECLARATION signal rxpdat1 : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal rxpdat2 : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal rxpdat3 : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal rxpdatout : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal rx_out_reg : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal rx_out_rgd : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal rx_out_rgd2 : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal rx_out_extra_yeager_reg : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal rx_out_int : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal data_out : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal serdes_data_out : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal write_data : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal read_data : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal rx_ddio_in : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal stratixii_dataout : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal stratixiii_dataout : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal flvds_dataout : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); -- to store previous port values signal rx_coreclk_pre : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal rx_channel_data_align_wire : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal rx_channel_data_align_pre : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal pclk_pre : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); -- constant signals signal temp_high : std_logic_vector (5 downto 0):= (others => '1'); signal temp_z : std_logic_vector (number_of_channels-1 downto 0):= (others => 'Z'); -- FIFO ram for Stratix GX signal ram_array : DPA_FIFO_RAM := (others => (others => '0')); -- PLL ports signal rx_clock0_int : std_logic := '0'; -- fast clock signal rx_clock1_int : std_logic := '0'; -- slow clock signal rx_pll_clk0 : std_logic := '0'; signal rx_pll_clk1 : std_logic := '0'; signal rx_reg_clk : std_logic := '0'; signal yeager_locked_int : std_logic := '0'; signal aurora_locked_int : std_logic := '0'; signal stratixii_locked_int : std_logic := '0'; signal stratixiii_locked_int : std_logic := '0'; signal cyclone_locked_int : std_logic := '0'; signal cycloneii_locked_int : std_logic := '0'; signal rx_locked_int : std_logic := '0'; signal temp_zero : std_logic := '0'; -- Stratix, Stratix II, Stratix GX, Cyclone and Cyclone II specific signals signal rx_data_align_reg : std_logic := '0'; signal rx_data_align_int : std_logic := '0'; signal rx_data_align_wire : std_logic := '0'; signal rx_data_align_clk : std_logic := '0'; signal enable0_reg : std_logic; signal enable0_pipe : std_logic; signal enable0_neg : std_logic; signal enable1_reg : std_logic; signal sampling : std_logic := '0'; signal yeager_clock : std_logic_vector (5 downto 0) := (others => '0'); signal aurora_clock : std_logic_vector (5 downto 0) := (others => '0'); signal stratixii_clock : std_logic_vector (5 downto 0) := (others => '0'); signal stratixiii_clock : std_logic_vector (9 downto 0) := (others => '0'); signal cyclone_clock : std_logic_vector (5 downto 0) := (others => '0'); signal cycloneii_clock : std_logic_vector (5 downto 0) := (others => '0'); signal pclk : std_logic_vector (number_of_channels-1 downto 0) := (others => '0'); signal clkout_tmp : std_logic_vector (number_of_channels-1 downto 0) := (others => '0'); signal sync_reset : std_logic_vector (number_of_channels-1 downto 0) := (others => '0'); signal stratixii_dpa_locked : std_logic_vector (number_of_channels-1 downto 0) := (others => '0'); signal stratixiii_dpa_locked : std_logic_vector (number_of_channels-1 downto 0) := (others => '0'); signal stratixii_cda_max : std_logic_vector (number_of_channels-1 downto 0) := (others => '0'); signal stratixiii_cda_max : std_logic_vector (number_of_channels-1 downto 0) := (others => '0'); signal stratixiii_divfwdclk : std_logic_vector (number_of_channels-1 downto 0) := (others => '0'); signal rx_pll_sclkout0 : std_logic := '0'; signal rx_pll_sclkout1 : std_logic := '0'; signal stratixii_sclkout0 : std_logic := '0'; signal stratixii_fastclk : std_logic := '0'; signal stratixii_enable : std_logic := '0'; signal stratixiii_fastclk : std_logic := '0'; signal stratixiii_slowclk : std_logic := '0'; signal stratixiii_enable : std_logic := '0'; signal rx_pll_enable0 : std_logic := '0'; signal rx_pll_enable1 : std_logic := '0'; signal rx_pll_sclkout0_dly : std_logic := '0'; signal flvds_fastclk : std_logic := '0'; signal flvds_slowclk : std_logic := '0'; signal flvds_syncclk : std_logic := '0'; signal flvds_rx_data_align : std_logic_vector (number_of_channels-1 downto 0) := (others => '0'); signal flvds_rx_cda_reset : std_logic_vector (number_of_channels-1 downto 0) := (others => '0'); signal pll_lock_sync : std_logic := '1'; -- COMPONENT DECLARATION -- pll definition component MF_stratix_pll generic ( pll_type : string := "lvds"; inclk0_input_frequency : positive ; inclk1_input_frequency : positive ; valid_lock_multiplier : integer := 1; simulation_type : string := "functional"; clk0_multiply_by : positive := 1; clk0_divide_by : positive := 1; clk0_phase_shift : string := "0"; clk1_multiply_by : positive := 1; clk1_divide_by : positive := 1; clk1_phase_shift : string := "0"; clk2_multiply_by : positive := 1; clk2_divide_by : positive := 1; clk2_phase_shift : string := "0"; enable0_counter : string := "l0"; enable1_counter : string := "l1"; family_name : string := "Stratix"; m : integer := 0 ); port ( inclk : in std_logic_vector(1 downto 0) := (others => '0'); fbin : in std_logic := '1'; ena : in std_logic := '1'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; clkena : in std_logic_vector(5 downto 0) := (others => '1'); extclkena : in std_logic_vector(3 downto 0) := (OTHERS=>'1'); scanaclr : in std_logic := '0'; scandata : in std_logic := '0'; scanclk : in std_logic := '0'; comparator : in std_logic := '0'; clk : out std_logic_vector(5 downto 0); locked : out std_logic; enable0 : out std_logic; enable1 : out std_logic ); end component; -- MF_stratix_pll component MF_stratixii_pll generic ( operation_mode : string := "normal"; pll_type : string := "lvds"; vco_multiply_by : integer := 0; vco_divide_by : integer := 0; inclk0_input_frequency : positive ; inclk1_input_frequency : positive ; simulation_type : string := "functional"; clk0_multiply_by : positive := 1; clk0_divide_by : positive := 1; clk0_phase_shift : string := "0"; clk1_multiply_by : positive := 1; clk1_divide_by : positive := 1; clk1_phase_shift : string := "0"; clk2_multiply_by : positive := 1; clk2_divide_by : positive := 1; clk2_phase_shift : string := "0"; sclkout0_phase_shift : string := "0"; enable0_counter : string := "c0"; enable1_counter : string := "c1"; family_name : string := "Stratix II"; m : integer := 0 ); port ( inclk : in std_logic_vector(1 downto 0) := (others => '0'); fbin : in std_logic := '1'; ena : in std_logic := '1'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; scanread : in std_logic := '0'; scanwrite : in std_logic := '0'; scandata : in std_logic := '0'; scanclk : in std_logic := '0'; testin : in std_logic_vector(3 downto 0) := (OTHERS=>'0'); clk : out std_logic_vector(5 downto 0); locked : out std_logic; enable0 : out std_logic; enable1 : out std_logic; sclkout : out std_logic_vector(1 downto 0) ); end component; -- MF_stratixii_pll component MF_stratixiii_pll generic ( operation_mode : string := "normal"; pll_type : string := "lvds"; vco_multiply_by : integer := 0; vco_divide_by : integer := 0; inclk0_input_frequency : positive ; inclk1_input_frequency : positive ; simulation_type : string := "functional"; clk0_multiply_by : positive := 1; clk0_divide_by : positive := 1; clk0_phase_shift : string := "0"; clk1_multiply_by : positive := 1; clk1_divide_by : positive := 1; clk1_duty_cycle : integer := 50; clk1_phase_shift : string := "0"; clk2_multiply_by : positive := 1; clk2_divide_by : positive := 1; clk2_phase_shift : string := "0"; family_name : string := "Stratix III"; self_reset_on_loss_lock : string := "OFF"; m : integer := 0 ); port ( inclk : in std_logic_vector(1 downto 0) := (others => '0'); fbin : in std_logic := '1'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; scanclk : in std_logic := '1'; scandata : in std_logic := '1'; scanclkena : in std_logic := '1'; configupdate : in std_logic := '0'; phasecounterselect : in std_logic_vector(3 downto 0) := (OTHERS=>'1'); phaseupdown : in std_logic := '1'; phasestep : in std_logic := '1'; clk : out std_logic_vector(9 downto 0); locked : out std_logic ); end component; -- MF_stratixiii_pll component stratixii_lvds_rx generic ( number_of_channels : natural; -- Required parameter deserialization_factor : natural; -- Required parameter enable_dpa_mode : string := "OFF"; data_align_rollover : natural := 10; lose_lock_on_one_change : string := "OFF"; reset_fifo_at_first_lock : string := "ON"; x_on_bitslip : string := "ON" ); port ( rx_in : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_fastclk : in std_logic; --Required port rx_enable : in std_logic := '1'; rx_locked : in std_logic; rx_dpaclock : in std_logic := '0'; rx_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_hold : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_enable : in std_logic_vector(number_of_channels-1 downto 0) := (others => '1'); rx_fifo_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_channel_data_align : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_cda_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_out : out std_logic_vector(deserialization_factor*number_of_channels -1 downto 0); rx_dpa_locked : out std_logic_vector(number_of_channels-1 downto 0); rx_cda_max : out std_logic_vector(number_of_channels-1 downto 0) ); end component; -- stratixii_lvds_rx component stratixiii_lvds_rx generic ( number_of_channels : natural; -- Required parameter deserialization_factor : natural; -- Required parameter enable_dpa_mode : string := "OFF"; data_align_rollover : natural := 10; lose_lock_on_one_change : string := "OFF"; reset_fifo_at_first_lock : string := "ON"; x_on_bitslip : string := "ON"; rx_align_data_reg : string := "RISING_EDGE"; enable_soft_cdr_mode : string := "OFF"; sim_dpa_output_clock_phase_shift : integer := 0; sim_dpa_is_negative_ppm_drift : string := "OFF"; sim_dpa_net_ppm_variation : natural := 0; enable_dpa_align_to_rising_edge_only : string := "OFF"; enable_dpa_initial_phase_selection : string := "OFF"; dpa_initial_phase_value :natural := 0; registered_output : string := "ON"; enable_clock_pin_mode : string := "UNUSED"; use_dpa_calibration : boolean := false; ARRIAII_RX_STYLE : boolean := false; STRATIXV_RX_STYLE : boolean := false ); port ( rx_in : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_fastclk : in std_logic; --Required port rx_slowclk : in std_logic; --Required port rx_dpaclock : in std_logic; rx_enable : in std_logic := '1'; rx_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_hold : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_dpll_enable : in std_logic_vector(number_of_channels-1 downto 0) := (others => '1'); rx_fifo_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_channel_data_align : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_cda_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_locked : in std_logic := '1'; rx_dpa_lock_reset : in std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); rx_out : out std_logic_vector(deserialization_factor*number_of_channels -1 downto 0); rx_dpa_locked : out std_logic_vector(number_of_channels-1 downto 0); rx_cda_max : out std_logic_vector(number_of_channels-1 downto 0); rx_divfwdclk : out std_logic_vector(number_of_channels-1 downto 0) := (others => '0') ); end component; -- stratixiii_lvds_rx component flexible_lvds_rx generic ( number_of_channels : natural; -- Required parameter deserialization_factor : natural; use_extra_ddio_register : boolean := true; use_extra_pll_clk : boolean := false; buffer_implementation : string := "RAM"; registered_data_align_input : string := "OFF"; use_external_pll : string := "OFF"; registered_output : string := "OFF"; add_latency : boolean := true ); port ( rx_in : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_fastclk : in std_logic; --Required port rx_slowclk : in std_logic; --Required port rx_syncclk : in std_logic; --Required port pll_areset : in std_logic; --Required port rx_data_reset : in std_logic; rx_locked : in std_logic; --Required port rx_data_align : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_cda_reset : in std_logic_vector(number_of_channels-1 downto 0); --Required port rx_out : out std_logic_vector(deserialization_factor*number_of_channels -1 downto 0) ); end component; -- flexible_lvds_rx begin -- SIGNAL ASSIGNMENTS rx_out <= flvds_dataout when (FAMILY_HAS_FLEXIBLE_LVDS = true) and (deserialization_factor > 2) else stratixiii_dataout when (STRATIXIII_RX_STYLE = true) and (deserialization_factor > 2) else rx_out_reg when (registered_output = "ON") and (use_external_pll = "OFF") else rx_out_int; rx_dpa_locked <= stratixii_dpa_locked when (STRATIXII_RX_STYLE = true) else stratixiii_dpa_locked when (STRATIXIII_RX_STYLE = true) else (others => '1'); rx_cda_max <= stratixii_cda_max when (STRATIXII_RX_STYLE = true) else stratixiii_cda_max when (STRATIXIII_RX_STYLE = true) else (others => '0'); rx_out_int <= rx_in when (deserialization_factor = 1) else rx_ddio_in when (deserialization_factor = 2) else stratixii_dataout when (STRATIXII_RX_STYLE = true) else rxpdatout when (STRATIXGX_DPA_RX_STYLE = true) else rx_out_extra_yeager_reg when (STRATIX_RX_STYLE = true) else data_out; rx_out_reg <= rx_out_rgd2 when ((STRATIXGX_DPA_RX_STYLE = true) and (use_coreclock_input = "ON")) else rx_out_rgd; rx_clock0_int <= rx_pll_clk0 when (deserialization_factor > 2) else rx_inclock; rx_clock1_int <= rx_pll_clk1 when (deserialization_factor > 2) else rx_inclock; rx_divfwdclk <= stratixiii_divfwdclk; rx_outclock <= rx_clock1_int; rx_reg_clk <= rx_inclock when ((use_external_pll = "ON") or (deserialization_factor <= 2)) else rx_clock1_int; rx_locked <= rx_locked_int and pll_lock_sync when (((STRATIXIII_RX_STYLE = true) or (CYCLONEIII_RX_STYLE = true)) and (deserialization_factor > 2)) else rx_locked_int when (deserialization_factor > 2) else '1'; rx_pll_clk0 <= yeager_clock(0) when (STRATIX_RX_STYLE = true) else aurora_clock(0) when (STRATIXGX_DPA_RX_STYLE = true) else stratixii_clock(0) when (STRATIXII_RX_STYLE = true) else '0'; rx_pll_clk1 <= cyclone_clock(2) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIX_STYLE_PLL = true)) else cycloneii_clock(2) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXII_STYLE_PLL = true)) else yeager_clock(2) when (STRATIX_RX_STYLE = true) else aurora_clock(2) when (STRATIXGX_DPA_RX_STYLE = true) else stratixii_clock(2) when (STRATIXII_RX_STYLE = true) else stratixiii_clock(2) when (STRATIXIII_RX_STYLE = true) or (CYCLONEIII_RX_STYLE = true) else '0'; rx_locked_int <= '1' when (use_external_pll = "ON") else cyclone_locked_int when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIX_STYLE_PLL = true)) else cycloneii_locked_int when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXII_STYLE_PLL = true)) else yeager_locked_int when (STRATIX_RX_STYLE = true) else aurora_locked_int when (STRATIXGX_DPA_RX_STYLE = true) else stratixii_locked_int when (STRATIXII_RX_STYLE = true) else stratixiii_locked_int when (STRATIXIII_RX_STYLE = true) or (CYCLONEIII_RX_STYLE = true) else '1'; rxpdat1 <= read_data when ((STRATIXGX_DPA_RX_STYLE = true) and (enable_dpa_fifo = "ON")) else serdes_data_out; write_data <= serdes_data_out; pclk <= clkout_tmp; stratixii_fastclk <= '0' when (STRATIXII_RX_STYLE = false) or (implement_in_les = "ON") else rx_inclock when (use_external_pll = "ON") else rx_pll_sclkout0_dly; stratixii_enable <= '0' when (STRATIXII_RX_STYLE = false) or (implement_in_les = "ON") else rx_enable when (use_external_pll = "ON") else rx_pll_enable0; stratixiii_fastclk <= '0' when (STRATIXIII_RX_STYLE = false) or (implement_in_les = "ON") else rx_inclock when (use_external_pll = "ON") or (enable_clock_pin_mode = "ON") else stratixiii_clock(0); stratixiii_slowclk <= '0' when (STRATIXIII_RX_STYLE = false) or (implement_in_les = "ON") or (enable_clock_pin_mode = "ON") else rx_syncclock when (use_external_pll = "ON") else stratixiii_clock(2); stratixiii_enable <= '0' when (STRATIXIII_RX_STYLE = false) or (implement_in_les = "ON") or (enable_clock_pin_mode = "ON") else rx_enable when (use_external_pll = "ON") else stratixiii_clock(1); rx_data_align_clk <= rx_clock1_int when ((STRATIX_RX_STYLE = true) or (STRATIXII_RX_STYLE = true) or (STRATIXIII_RX_STYLE = true)) and (implement_in_les = "OFF") else '0'; rx_data_align_wire <= rx_data_align when (port_rx_data_align = "PORT_USED") else '0' when (port_rx_data_align = "PORT_UNUSED") else rx_data_align when (rx_data_align /= 'Z') else '0'; rx_data_align_int <= rx_data_align_reg when (registered_data_align_input = "ON") else rx_data_align_wire; rx_channel_data_align_wire <= rx_channel_data_align when (rx_channel_data_align /= temp_z) else (others => rx_data_align_int ) when ((STRATIXII_RX_STYLE = true) or (STRATIXIII_RX_STYLE = true)) else (others => '0'); flvds_fastclk <= '0' when (FAMILY_HAS_FLEXIBLE_LVDS = false) else rx_inclock when (use_external_pll = "ON") else cyclone_clock(0) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIX_STYLE_PLL = true)) else cycloneii_clock(0) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXII_STYLE_PLL = true)) else stratixiii_clock(0) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXIII_STYLE_PLL = true)) else '0'; flvds_slowclk <= '0' when (FAMILY_HAS_FLEXIBLE_LVDS = false) else rx_readclock when (use_external_pll = "ON") else cyclone_clock(2) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIX_STYLE_PLL = true)) else cycloneii_clock(2) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXII_STYLE_PLL = true)) else stratixiii_clock(2) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXIII_STYLE_PLL = true)) else '0'; flvds_syncclk <= '0' when (FAMILY_HAS_FLEXIBLE_LVDS = false) else rx_syncclock when (use_external_pll = "ON") else cyclone_clock(1) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIX_STYLE_PLL = true)) else cycloneii_clock(1) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXII_STYLE_PLL = true)) else stratixiii_clock(1) when ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXIII_STYLE_PLL = true)) else '0'; flvds_rx_data_align <= rx_channel_data_align when ((port_rx_channel_data_align = "PORT_USED") or ((port_rx_channel_data_align = "PORT_CONNECTIVITY") and (rx_channel_data_align /= temp_z))) else (others => rx_data_align_wire ) when (port_rx_data_align /= "PORT_UNUSED") else (others => '0'); flvds_rx_cda_reset <= rx_cda_reset when ((port_rx_channel_data_align = "PORT_USED") or ((port_rx_channel_data_align = "PORT_CONNECTIVITY") and (rx_channel_data_align /= temp_z))) else (others => rx_data_align_reset ) when (port_rx_data_align /= "PORT_UNUSED") else (others => '0'); -- COMPONENT ASSIGNMENTS -- instantiation of the PLLs used by LVDS_RX -- MF_stratix_pll used for Stratix and Stratix GX -- MF_stratixii_pll used for Stratix II -- MF_stratixiii_pll used for Stratix III STRATIX_PLL: if ((STRATIX_RX_STYLE = true) and (implement_in_les = "OFF") and (deserialization_factor > 2)) generate U2: MF_stratix_pll -- STRATIX PLL generic map ( inclk0_input_frequency => inclock_period, inclk1_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk2_multiply_by => INT_CLOCK_BOOST, clk2_divide_by => deserialization_factor, clk0_phase_shift => PHASE_INCLOCK, clk2_phase_shift => PHASE_INCLOCK, family_name => intended_device_family ) port map ( inclk(0) => rx_inclock, inclk(1) => rx_inclock, ena => rx_pll_enable, areset => pll_areset, clkena(5 downto 0) => temp_high, comparator => rx_data_align_int, clk => yeager_clock, enable0 => rx_pll_enable0, enable1 => rx_pll_enable1, locked => yeager_locked_int ); end generate STRATIX_PLL; STRATIXGX_DPA_PLL: if ((STRATIXGX_DPA_RX_STYLE = true) and (implement_in_les = "OFF") and (deserialization_factor > 2)) generate U2: MF_stratix_pll -- Stratix GX PLL generic map ( inclk0_input_frequency => inclock_period, inclk1_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk2_multiply_by => INT_CLOCK_BOOST, clk2_divide_by => deserialization_factor, clk0_phase_shift => "0", clk2_phase_shift => "0", family_name => intended_device_family ) port map ( inclk(0) => rx_inclock, inclk(1) => temp_zero, ena => rx_pll_enable, areset => pll_areset, clkena(5 downto 0) => temp_high, clk => aurora_clock, locked => aurora_locked_int ); end generate STRATIXGX_DPA_PLL; STRATIXII_PLL: if ((STRATIXII_RX_STYLE = true) and (implement_in_les = "OFF") and (use_external_pll /= "ON") and (deserialization_factor > 2)) generate U3: MF_stratixii_pll -- Stratix II PLL generic map ( vco_multiply_by => INT_CLOCK_BOOST, vco_divide_by => 1, inclk0_input_frequency => inclock_period, inclk1_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => deserialization_factor, clk2_multiply_by => INT_CLOCK_BOOST, clk2_divide_by => deserialization_factor, clk0_phase_shift => STXII_PHASE_INCLOCK, clk2_phase_shift => STXII_PHASE_INCLOCK, sclkout0_phase_shift => STXII_PHASE_INCLOCK, family_name => intended_device_family ) port map ( inclk(0) => rx_inclock, inclk(1) => temp_zero, ena => rx_pll_enable, areset => pll_areset, clk => stratixii_clock, locked => stratixii_locked_int, enable0 => rx_pll_enable0, sclkout(0) => rx_pll_sclkout0, sclkout(1) => rx_pll_sclkout1 ); end generate STRATIXII_PLL; STRATIXIII_PLL: if ((STRATIXIII_RX_STYLE = true) and (implement_in_les = "OFF") and (use_external_pll /= "ON") and (deserialization_factor > 2)) generate U4: MF_stratixiii_pll -- Stratix III PLL generic map ( vco_multiply_by => INT_CLOCK_BOOST, vco_divide_by => 1, inclk0_input_frequency => inclock_period, inclk1_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => 1, clk1_multiply_by => INT_CLOCK_BOOST, clk1_divide_by => deserialization_factor, clk1_duty_cycle => integer(real(100/deserialization_factor) + real(0.5)), clk2_multiply_by => INT_CLOCK_BOOST, clk2_divide_by => deserialization_factor, clk0_phase_shift => STXII_PHASE_INCLOCK, clk1_phase_shift => CLK_ENA_PHASE_SHIFT, clk2_phase_shift => STXII_PHASE_INCLOCK, family_name => intended_device_family ) port map ( inclk(0) => rx_inclock, inclk(1) => temp_zero, areset => pll_areset, clk => stratixiii_clock, locked => stratixiii_locked_int ); end generate STRATIXIII_PLL; FLVDS_STX_PLL: if ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIX_STYLE_PLL = true) and (deserialization_factor > 2)) generate U4: MF_stratix_pll -- Cyclone PLL generic map ( pll_type => FLVDS_PLL_TYPE, inclk0_input_frequency => inclock_period, inclk1_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => FLVDS_CLK0_DIV, clk1_multiply_by => FLVDS_CLK1_MULT, clk1_divide_by => FLVDS_CLK1_DIV, clk2_multiply_by => FLVDS_CLK2_MULT, clk2_divide_by => FLVDS_CLK2_DIV, clk0_phase_shift => PHASE_INCLOCK, clk1_phase_shift => FLVDS_CLK1_PHASE_SHIFT, clk2_phase_shift => PHASE_INCLOCK, family_name => intended_device_family ) port map ( inclk(0) => rx_inclock, inclk(1) => temp_zero, ena => rx_pll_enable, areset => pll_areset, clkena(5 downto 0) => temp_high, clk => cyclone_clock, locked => cyclone_locked_int ); end generate FLVDS_STX_PLL; FLVDS_STXII_PLL: if ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXII_STYLE_PLL = true) and (use_external_pll /= "ON") and (deserialization_factor > 2)) generate U5: MF_stratixii_pll -- Stratix II PLL generic map ( operation_mode => alpha_tolower(pll_operation_mode), pll_type => FLVDS_PLL_TYPE, vco_multiply_by => INT_CLOCK_BOOST, vco_divide_by => 1, inclk0_input_frequency => inclock_period, inclk1_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => FLVDS_CLK0_DIV, clk1_multiply_by => FLVDS_CLK1_MULT, clk1_divide_by => FLVDS_CLK1_DIV, clk2_multiply_by => FLVDS_CLK2_MULT, clk2_divide_by => FLVDS_CLK2_DIV, clk0_phase_shift => STXII_LE_PHASE_INCLOCK, clk1_phase_shift => STXII_LE_CLK1_PHASE_SHIFT, clk2_phase_shift => STXII_LE_PHASE_INCLOCK, sclkout0_phase_shift => PHASE_INCLOCK, family_name => intended_device_family ) port map ( inclk(0) => rx_inclock, inclk(1) => temp_zero, ena => rx_pll_enable, areset => pll_areset, clk => cycloneii_clock, locked => cycloneii_locked_int, enable0 => rx_pll_enable0, sclkout(0) => rx_pll_sclkout0, sclkout(1) => rx_pll_sclkout1 ); end generate FLVDS_STXII_PLL; FLVDS_STXIII_PLL: if ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXIII_STYLE_PLL = true) and (use_external_pll /= "ON") and (deserialization_factor > 2)) generate U5: MF_stratixiii_pll -- Stratix III PLL generic map ( operation_mode => alpha_tolower(pll_operation_mode), pll_type => FLVDS_PLL_TYPE, vco_multiply_by => INT_CLOCK_BOOST, vco_divide_by => 1, inclk0_input_frequency => inclock_period, inclk1_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => FLVDS_CLK0_DIV, clk1_multiply_by => FLVDS_CLK1_MULT, clk1_divide_by => FLVDS_CLK1_DIV, clk2_multiply_by => FLVDS_CLK2_MULT, clk2_divide_by => FLVDS_CLK2_DIV, clk0_phase_shift => STXIII_LE_PHASE_INCLOCK, clk1_phase_shift => STXIII_LE_CLK1_PHASE_SHIFT, clk2_phase_shift => STXIII_LE_PHASE_INCLOCK, family_name => intended_device_family, self_reset_on_loss_lock => alpha_tolower(pll_self_reset_on_loss_lock) ) port map ( inclk(0) => rx_inclock, inclk(1) => temp_zero, areset => pll_areset, clk => stratixiii_clock, locked => stratixiii_locked_int ); end generate FLVDS_STXIII_PLL; STRATIXII_LVDS_RECEIVER: if ((STRATIXII_RX_STYLE = true) and (implement_in_les = "OFF") and (deserialization_factor > 2)) generate U6: stratixii_lvds_rx generic map ( number_of_channels => number_of_channels, deserialization_factor => deserialization_factor, enable_dpa_mode => enable_dpa_mode, data_align_rollover => data_align_rollover, lose_lock_on_one_change => lose_lock_on_one_change, reset_fifo_at_first_lock => reset_fifo_at_first_lock, x_on_bitslip => x_on_bitslip ) port map ( rx_in => rx_in, rx_fastclk => stratixii_fastclk, rx_enable => stratixii_enable, rx_locked => stratixii_locked_int, rx_reset => rx_reset, rx_dpll_reset => rx_dpll_reset, rx_dpll_hold => rx_dpll_hold, rx_dpll_enable => rx_dpll_enable, rx_fifo_reset => rx_fifo_reset, rx_channel_data_align => rx_channel_data_align_wire, rx_cda_reset => rx_cda_reset, rx_out => stratixii_dataout, rx_dpa_locked => stratixii_dpa_locked, rx_cda_max => stratixii_cda_max ); end generate STRATIXII_LVDS_RECEIVER; FLEXIBLE_LVDS_RECEIVER: if ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (deserialization_factor > 2)) generate U7: flexible_lvds_rx generic map ( number_of_channels => number_of_channels, deserialization_factor => deserialization_factor, use_extra_ddio_register => IS_USING_EXTRA_DDIO_REG, use_extra_pll_clk => IS_USING_EXTRA_PLL_CLK, buffer_implementation => buffer_implementation, registered_data_align_input => registered_data_align_input, use_external_pll => use_external_pll, registered_output => registered_output, add_latency => IS_ADDING_EXTRA_LATENCY ) port map ( rx_in => rx_in, rx_fastclk => flvds_fastclk, rx_slowclk => flvds_slowclk, rx_syncclk => flvds_syncclk, pll_areset => pll_areset, rx_data_reset => rx_data_reset, rx_data_align => flvds_rx_data_align, rx_cda_reset => flvds_rx_cda_reset, rx_locked => rx_locked_int, rx_out => flvds_dataout ); end generate FLEXIBLE_LVDS_RECEIVER; STRATIXIII_LVDS_RECEIVER: if ((STRATIXIII_RX_STYLE = true) and (implement_in_les = "OFF") and (deserialization_factor > 2)) generate U8: stratixiii_lvds_rx generic map ( number_of_channels => number_of_channels, deserialization_factor => deserialization_factor, enable_dpa_mode => enable_dpa_mode, data_align_rollover => data_align_rollover, lose_lock_on_one_change => lose_lock_on_one_change, reset_fifo_at_first_lock => reset_fifo_at_first_lock, x_on_bitslip => x_on_bitslip, rx_align_data_reg => rx_align_data_reg, enable_soft_cdr_mode => enable_soft_cdr_mode, sim_dpa_output_clock_phase_shift => sim_dpa_output_clock_phase_shift, sim_dpa_is_negative_ppm_drift => sim_dpa_is_negative_ppm_drift, sim_dpa_net_ppm_variation => sim_dpa_net_ppm_variation, enable_dpa_align_to_rising_edge_only => enable_dpa_align_to_rising_edge_only, enable_dpa_initial_phase_selection => enable_dpa_initial_phase_selection, dpa_initial_phase_value => dpa_initial_phase_value, registered_output => registered_output, enable_clock_pin_mode => enable_clock_pin_mode, use_dpa_calibration => use_dpa_calibration, ARRIAII_RX_STYLE => ARRIAII_RX_STYLE, STRATIXV_RX_STYLE => STRATIXV_RX_STYLE ) port map ( rx_in => rx_in, rx_fastclk => stratixiii_fastclk, rx_slowclk => stratixiii_slowclk, rx_enable => stratixiii_enable, rx_dpaclock => rx_dpaclock, rx_reset => rx_reset, rx_dpll_reset => rx_dpll_reset, rx_dpll_hold => rx_dpll_hold, rx_dpll_enable => rx_dpll_enable, rx_fifo_reset => rx_fifo_reset, rx_channel_data_align => rx_channel_data_align_wire, rx_cda_reset => rx_cda_reset, rx_out => stratixiii_dataout, rx_dpa_locked => stratixiii_dpa_locked, rx_cda_max => stratixiii_cda_max, rx_divfwdclk => stratixiii_divfwdclk ); end generate STRATIXIII_LVDS_RECEIVER; -- PROCESS DECLARATION STRATIXII_FCLK : process (rx_pll_sclkout0) begin rx_pll_sclkout0_dly <= rx_pll_sclkout0; end process; -- STRATIXII_FCLK process -- basic error checking for invalid deserialization factors MSG: process(rx_channel_data_align, rx_data_align) variable all_z : std_logic_vector(number_of_channels-1 downto 0) := (others =>'Z'); variable init : boolean := true; begin if (init = true) then if (IS_VALID_FAMILY(intended_device_family) = false) then ASSERT FALSE REPORT intended_device_family & " is not a valid device family!" SEVERITY ERROR; elsif ((STRATIX_RX_STYLE = true) and (deserialization_factor /= 1) and (deserialization_factor /= 2) and ((deserialization_factor > 10) or (deserialization_factor < 4))) then ASSERT FALSE REPORT "Stratix and Stratix GX (non DPA mode) does not support the specified deserialization factor!" SEVERITY ERROR; elsif ((STRATIXGX_DPA_RX_STYLE = true) and (enable_dpa_mode = "ON") and (deserialization_factor /= 8) and (deserialization_factor /= 10)) then ASSERT FALSE REPORT "STRATIXGX in DPA mode does not support the specified deserialization factor!" SEVERITY ERROR; elsif ((STRATIXII_RX_STYLE = true) and (deserialization_factor > 10)) then ASSERT FALSE REPORT "STRATIXII does not support the specified deserialization factor!" SEVERITY ERROR; elsif ((STRATIXII_RX_STYLE = true) and (data_align_rollover > 11)) then ASSERT FALSE REPORT "Stratix II does not support data align rollover values > 11 !" SEVERITY ERROR; elsif (CYCLONE_RX_STYLE = true) then if ((use_external_pll = "OFF") and ((deserialization_factor > 10) or (deserialization_factor = 3))) then ASSERT FALSE REPORT "Cyclone does not support the specified deserialization factor when use_external_pll is 'OFF'!" SEVERITY ERROR; end if; elsif (CYCLONEII_RX_STYLE = true) then if ((use_external_pll = "OFF") and ((deserialization_factor > 10) or (deserialization_factor = 3))) then ASSERT FALSE REPORT "Cyclone II does not support the specified deserialization factor when use_external_pll is 'OFF'!" SEVERITY ERROR; end if; end if; if (((STRATIXII_RX_STYLE = true) or (STRATIXIII_RX_STYLE = true)) and (rx_channel_data_align = all_z) and (rx_data_align /= 'Z')) then ASSERT FALSE REPORT "Data alignment on Stratix II/III devices introduces one bit of latency for each assertion of the data alignment signal. In comparison, Stratix and Stratix GX devices remove one bit of latency for each assertion." SEVERITY Warning; end if; init := false; end if; end process; -- MSG process X2_MODE : if (deserialization_factor = 2) generate -- For x2 mode, data input is sampled in both the rising edge and falling edge -- of input clock. DDIO_IN : process (rx_inclock) variable datain_latched : std_logic_vector(number_of_channels-1 downto 0) := (others =>'0'); begin if (rx_inclock'event and (rx_inclock = '1')) then for i in 0 to number_of_channels -1 loop if (CYCLONEIII_RX_STYLE = true) then rx_ddio_in((i*2)+1) <= rx_in(i); rx_ddio_in((i*2)) <= datain_latched(i); else rx_ddio_in((i*2)) <= rx_in(i); rx_ddio_in((i*2)+1) <= datain_latched(i); end if; end loop; -- falling edge of inclock elsif (rx_inclock'event and (rx_inclock = '0')) then for i in 0 to number_of_channels -1 loop datain_latched(i) := rx_in(i); end loop; end if; end process; -- DDIO_IN process end generate X2_MODE; -- Register the load enable signal for Stratix LOAD_ENABLE_PROC: process (rx_clock0_int) begin if (rx_clock0_int'event and (rx_clock0_int ='1') and (rx_clock0_int'last_value ='0')) then enable0_pipe <= enable0_reg; enable0_reg <= rx_pll_enable0; enable1_reg <= rx_pll_enable1; elsif (rx_clock0_int'event and (rx_clock0_int = '0') and (rx_clock0_int'last_value ='1')) then enable0_neg <= enable0_pipe; elsif (rx_clock0_int'event and (rx_clock0_int = 'X')) then enable0_pipe <= 'X'; enable0_reg <= 'X'; enable1_reg <= 'X'; enable0_neg <= 'X'; end if; end process; -- LOAD_ENABLE_PROC process -- the deserializer LOAD_DATA: process(rx_clock0_int, rx_clock1_int) variable count : CHANNEL_CNT := (others => 0); variable sample : integer; variable start_data : integer := 0; variable data_int : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); variable x : integer:=0; begin if (rx_clock0_int'event and (rx_clock0_int = '0')) then -- For Stratix and Stratix GX non-DPA mode, load data -- when the registered load enable signal is high if ((enable0_neg = '1') and (STRATIX_RX_STYLE = true)) then data_out <= data_int; end if; -- Deserialize the incoming bits for i in 0 to number_of_channels -1 loop if (STRATIX_RX_STYLE = true) then for x in deserialization_factor-1 downto 1 loop -- Data gets shifted into MSB first. data_int(x + (i * deserialization_factor)) := data_int (x-1 + (i * deserialization_factor)); end loop; data_int(i * deserialization_factor) := rx_in(i); end if; end loop; end if; end process; -- LOAD_DATA process -- the parallel and hold registers PARALLEL_REG: process(rx_clock1_int, enable1_reg, stratixiii_divfwdclk) begin if (stratixiii_divfwdclk'event and (stratixiii_divfwdclk(0) = '1')) then if (enable_soft_cdr_mode = "ON") then rx_out_rgd <= rx_out_int; end if; end if; if(rx_clock1_int'event and (rx_clock1_int = '1')) then if (enable_soft_cdr_mode = "OFF") then rx_out_rgd <= rx_out_int; end if; end if; if (enable1_reg'event and (enable1_reg = '1')) then rx_out_extra_yeager_reg <= data_out; end if; end process; -- PARALLEL_REG process DATA_ALIGN_REG: process(rx_data_align_clk) begin if (rx_data_align_clk'event and (rx_data_align_clk = '1')) then rx_data_align_reg <= rx_data_align_wire; end if; end process; --DATA_ALIGN_REG -- Stratix GX DPA internal model STRATIXGX_DPA_RX : if (STRATIXGX_DPA_RX_STYLE = true) generate -- the synchronization register SYNC_REGISTER: process(rx_coreclk) begin if (use_coreclock_input = "ON") then for i in 0 to number_of_channels -1 loop if ((rx_coreclk_pre(i) = '0') and (rx_coreclk(i) = '1')) then rx_out_rgd2(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rx_out_int(deserialization_factor*(i+1) -1 downto deserialization_factor*i); end if; rx_coreclk_pre(i) <= rx_coreclk(i); end loop; end if; end process; --SYNC_REGISTER process -- deserializer logic DPA_SERDES: process(rx_clock0_int, rx_clock1_int, rx_coreclk, rx_reset, rx_dpll_reset) variable negedge_count: CHANNEL_CNT := (others => 0); variable posedge_count: CHANNEL_CNT := (others => 0); variable fast_clk_count : CHANNEL_CNT := (others => deserialization_factor); variable data_int : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); variable rx_in_pipe : std_logic_vector(number_of_channels -1 downto 0) := (others => '0'); begin -- count the fast clock edge after the rising edge of the global slow -- clock in order to generate the parallel unload enable signal for i in 0 to number_of_channels -1 loop if (((use_coreclock_input = "ON") and (rx_coreclk_pre(i) = '0') and (rx_coreclk(i) = '1')) or ((use_coreclock_input = "OFF") and rx_clock1_int'event and (rx_clock1_int = '1'))) then negedge_count(i) := 0; posedge_count(i) := 0; if ((rx_reset(i) = '1') or (rx_dpll_reset(i) = '1')) then sync_reset(i) <= '1'; else sync_reset(i) <= '0'; end if; end if; rx_coreclk_pre(i) <= rx_coreclk(i); end loop; if (rx_clock0_int'event and (rx_clock0_int = '1')) then for i in 0 to number_of_channels -1 loop posedge_count(i) := posedge_count(i) + 1; -- load the parallel data when parallel unload enable signal goes high if (negedge_count(i) = 2) then serdes_data_out <= data_int; end if; if (sync_reset(i) = '1') then fast_clk_count(i) := deserialization_factor; clkout_tmp(i) <= '0'; else if (fast_clk_count(i) = deserialization_factor) then fast_clk_count(i) := 0; clkout_tmp(i) <= not clkout_tmp(i); elsif (fast_clk_count(i) = (deserialization_factor+1)/2) then clkout_tmp(i) <= not clkout_tmp(i); end if; fast_clk_count(i) := fast_clk_count(i) + 1; end if; end loop; end if; -- deserialize the incoming bits if (rx_clock0_int'event and (rx_clock0_int = '0')) then for i in 0 to number_of_channels -1 loop for x in deserialization_factor-1 downto 1 loop -- Data gets shifted into MSB first. data_int(x + (i * deserialization_factor)) := data_int (x-1 + (i * deserialization_factor)); end loop; data_int(i * deserialization_factor) := rx_in_pipe(i); rx_in_pipe(i) := rx_in(i); if (((use_coreclock_input = "ON") and (posedge_count(i) > 0)) or (use_coreclock_input = "OFF")) then negedge_count(i) := negedge_count(i) + 1; end if; end loop; end if; end process; -- DPA_SERDES process -- phase compensation FIFO DPA_FIFO: process(pclk, rx_clock1_int, rx_coreclk) variable rd_index : CHANNEL_CNT := (others => 2); variable wr_index : CHANNEL_CNT := (others => 0); variable enable_fifo : boolean := false; variable clk0_posedge_count : integer := 0; begin -- enable the FIFO only when PLL locks if (rx_locked_int = '1') then enable_fifo := true; end if; if (enable_fifo = true) then -- Update write pointer and write data into the FIFO for i in 0 to number_of_channels-1 loop if ((pclk(i) = '1') and (pclk_pre(i) = '0')) then if (sync_reset(i) = '1') then wr_index(i) := 0; else ram_array(wr_index(i)) <= write_data; wr_index(i) := (wr_index(i) + 1) rem 4; end if; end if; pclk_pre(i) <= pclk(i); end loop; -- Read data from the FIFO and update read pointer for i in 0 to number_of_channels-1 loop if (((use_coreclock_input = "ON") and (rx_coreclk_pre(i) = '0') and (rx_coreclk(i) = '1')) or ((use_coreclock_input = "OFF") and (rx_clock1_int'event) and (rx_clock1_int = '1'))) then -- reset logic if ((rx_reset(i) = '1') or (rx_dpll_reset(i) = '1') or (sync_reset(i) = '1')) then read_data(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= (others => '0'); wr_index(i) := 0; rd_index(i) := 2; for j in 0 to 3 loop ram_array(j)(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= (others => '0'); end loop; else -- read data and update read pointer read_data(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= ram_array(rd_index(i))(deserialization_factor*(i+1) -1 downto deserialization_factor*i); rd_index(i) := (rd_index(i) + 1) rem 4; end if; end if; rx_coreclk_pre(i) <= rx_coreclk(i); end loop; end if; end process; -- DPA_FIFO process -- bit-slipping logic DPA_BIT_SLIP: process(rx_coreclk, rx_clock1_int, rx_channel_data_align) variable count: CHANNEL_CNT := (others => 0); variable count2: CHANNEL_CNT := (others => 0); variable count3: CHANNEL_CNT := (others => 0); begin for i in 0 to number_of_channels-1 loop -- increment the number-of-bits-to-slip counter once for each rising edge of the bitslip control signal if (((use_coreclock_input = "ON") and (rx_coreclk_pre(i) = '0') and (rx_coreclk(i) = '1')) or ((use_coreclock_input = "OFF") and rx_clock1_int'event and (rx_clock1_int = '1'))) then count3(i) := count2(i); count2(i) := count(i); if ((rx_channel_data_align_pre(i) = '0') and (rx_channel_data_align(i) = '1')) then count(i) := (count(i) + 1) rem deserialization_factor; end if; rx_channel_data_align_pre(i) <= rx_channel_data_align(i); -- reset logic if ((rx_reset(i) = '1') or (rx_dpll_reset(i) = '1') or (sync_reset(i) = '1')) then rxpdat2(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= (others => '0'); rxpdat3(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= (others => '0'); count(i) := 0; count2(i) := 0; count3(i) := 0; rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= (others => '0'); else -- register the parallel data from either the FIFO or the SERDES rxpdat2 <= rxpdat1; rxpdat3 <= rxpdat2; -- select which bits to output to core from rxpdat2 and rxpdat3 registers -- the bitslip counter determines how many bits to skip from rxpdat3, and -- how many to take from rxpdat2 -- MSB of the registers is the earliest bit to enter, hence the MSB will -- be the first bit to be skipped case count3(i) is when 0 => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*(i+1) -1 downto deserialization_factor*i); --(RXPDAT3[8:0],RXPDAT2[9] when 1 => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*(i+1) -2 downto deserialization_factor*i) & rxpdat2(deserialization_factor*(i+1) -1); --(RXPDAT3[7:0],RXPDAT2[9:8] when 2 => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*(i+1) -3 downto deserialization_factor*i) & rxpdat2(deserialization_factor*(i+1) -1 downto deserialization_factor*(i+1) -2); --(RXPDAT3[6:0],RXPDAT2[9:7] when 3 => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*(i+1) -4 downto deserialization_factor*i) & rxpdat2(deserialization_factor*(i+1) -1 downto deserialization_factor*(i+1) -3); --(RXPDAT3[5:0],RXPDAT2[9:6] when 4 => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*(i+1) -5 downto deserialization_factor*i) & rxpdat2(deserialization_factor*(i+1) -1 downto deserialization_factor*(i+1) -4); --(RXPDAT3[4:0],RXPDAT2[9:5] when 5 => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*(i+1) -6 downto deserialization_factor*i) & rxpdat2(deserialization_factor*(i+1) -1 downto deserialization_factor*(i+1) -5); --(RXPDAT3[3:0],RXPDAT2[9:4] when 6 => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*(i+1) -7 downto deserialization_factor*i) & rxpdat2(deserialization_factor*(i+1) -1 downto deserialization_factor*(i+1) -6); --(RXPDAT3[2:0],RXPDAT2[9:3] when 7 => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*(i+1) -8 downto deserialization_factor*i) & rxpdat2(deserialization_factor*(i+1) -1 downto deserialization_factor*(i+1) -7); --(RXPDAT3[1:0],RXPDAT2[9:2] when 8 => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*(i+1) -9 downto deserialization_factor*i) & rxpdat2(deserialization_factor*(i+1) -1 downto deserialization_factor*(i+1) -8); --(RXPDAT3[0:0],RXPDAT2[9:1] when 9 => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*i) & rxpdat2(deserialization_factor*(i+1) -1 downto deserialization_factor*(i+1) -9); when others => rxpdatout(deserialization_factor*(i+1) -1 downto deserialization_factor*i) <= rxpdat3(deserialization_factor*(i+1) -1 downto deserialization_factor*i); end case; end if; end if; rx_coreclk_pre(i) <= rx_coreclk(i); end loop; end process; -- DPA_BIT_SLIP process end generate STRATIXGX_DPA_RX; process (rx_locked_int, pll_areset) begin if (pll_areset = '1') then pll_lock_sync <= '0'; elsif (rx_locked_int = '1' and rx_locked_int'event) then pll_lock_sync <= '1'; end if; end process; end behavior; -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : stratix_tx_outclk -- -- Description : This module is used to generate the tx_outclock for Stratix -- and stratix GX family. -- -- Limitation : Only available to Stratix and Stratix GX family. -- -- Results Expected: Output clock. -- ---END_ENTITY_HEADER----------------------------------------------------------- -- LIBRARY USED---------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -- ENTITY DECLARATION entity stratix_tx_outclk is -- GENERIC DECLARATION generic ( deserialization_factor : natural; -- Required parameter bypass_serializer : boolean := FALSE; invert_clock : boolean := FALSE; use_falling_clock_edge : boolean := FALSE ); -- PORT DECLARATION port ( --INPUT PORT DECLARATION tx_in : in std_logic_vector(deserialization_factor-1 downto 0); tx_fastclk : in std_logic; tx_enable : in std_logic := '1'; -- OUTPUT PORT DECLARATION tx_out : out std_logic := '0' ); end stratix_tx_outclk; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of stratix_tx_outclk is -- SIGNAL DECLARATION -- constant signals signal enable1_reg1 : std_logic; signal enable1_reg2 : std_logic; signal tx_out_neg : std_logic := '0'; signal tx_shift_reg : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); signal tx_parallel_load_reg : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); begin -- SIGNAL ASSIGNMENTS tx_out <= tx_fastclk when (bypass_serializer = TRUE) and (invert_clock = FALSE) else not tx_fastclk when (bypass_serializer = TRUE) and (invert_clock = TRUE) else tx_out_neg when (use_falling_clock_edge = TRUE) else tx_shift_reg(deserialization_factor-1); -- PROCESS DECLARATION -- Register the load enable signal LOAD_ENABLE : process (tx_fastclk) variable enable1_reg0 : std_logic; begin if (tx_fastclk'event and (tx_fastclk ='1') and (tx_fastclk'last_value ='0')) then enable1_reg1 <= enable1_reg0; enable1_reg0 := tx_enable; elsif (tx_fastclk'event and (tx_fastclk = '0') and (tx_fastclk'last_value ='1')) then enable1_reg2 <= enable1_reg1; elsif (tx_fastclk'event and (tx_fastclk = 'X')) then enable1_reg0 := 'X'; enable1_reg1 <= 'X'; enable1_reg2 <= 'X'; end if; end process LOAD_ENABLE; -- LOAD_ENABLE process -- the deserializer FAST_CLOCK : process(tx_fastclk) begin if (tx_fastclk'event and (tx_fastclk = '0')) then -- Shift data from shift register to tx_out on negative edge of -- fast clock tx_out_neg <= tx_shift_reg(deserialization_factor-1); elsif (tx_fastclk'event and (tx_fastclk = '1')) then if (enable1_reg2 = '1') then tx_shift_reg <= tx_parallel_load_reg; else -- Shift data from shift register to tx_out on positive edge -- of fast clock for x in deserialization_factor-1 downto 1 loop tx_shift_reg(x) <= tx_shift_reg (x-1); end loop; end if; tx_parallel_load_reg <= tx_in; end if; end process FAST_CLOCK; end behavior; -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : stratixii_tx_outclk -- -- Description : This module is used to generate the tx_outclock for StratixII -- family. -- -- Limitation : Only available to Stratix II family. -- -- Results Expected: Output clock. -- ---END_ENTITY_HEADER----------------------------------------------------------- -- LIBRARY USED---------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -- ENTITY DECLARATION entity stratixii_tx_outclk is -- GENERIC DECLARATION generic ( deserialization_factor : natural; -- Required parameter bypass_serializer : boolean := FALSE; invert_clock : boolean := FALSE; use_falling_clock_edge : boolean := FALSE ); -- PORT DECLARATION port ( --INPUT PORT DECLARATION tx_in : in std_logic_vector(deserialization_factor-1 downto 0); tx_fastclk : in std_logic; tx_enable : in std_logic := '1'; -- OUTPUT PORT DECLARATION tx_out : out std_logic := '0' ); end stratixii_tx_outclk; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of stratixii_tx_outclk is -- SIGNAL DECLARATION -- constant signals signal tx_out_neg : std_logic := '0'; signal tx_shift_reg : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); signal tx_parallel_load_reg : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); begin -- SIGNAL ASSIGNMENTS tx_out <= tx_fastclk when (bypass_serializer = TRUE) and (invert_clock = FALSE) else not tx_fastclk when (bypass_serializer = TRUE) and (invert_clock = TRUE) else tx_out_neg when (use_falling_clock_edge = TRUE) else tx_shift_reg(deserialization_factor-1); -- PROCESS DECLARATION -- the deserializer FAST_CLOCK : process(tx_fastclk) variable enable1_reg : std_logic := '0'; begin if (tx_fastclk'event and (tx_fastclk = '0')) then tx_out_neg <= tx_shift_reg(deserialization_factor-1); elsif (tx_fastclk'event and (tx_fastclk = '1')) then if (enable1_reg = '1') then tx_shift_reg <= tx_parallel_load_reg; else -- Shift data from shift register to tx_out for x in deserialization_factor-1 downto 1 loop tx_shift_reg(x) <= tx_shift_reg (x-1); end loop; end if; -- registering enable1 signal enable1_reg := tx_enable; tx_parallel_load_reg <= tx_in; end if; end process FAST_CLOCK; end behavior; -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : flexible_lvds_tx -- -- Description : flexible lvds transmitter -- -- Limitation : Only available to Cyclone and Cyclone II families. -- -- Results Expected: Serialized output data. -- ---END_ENTITY_HEADER----------------------------------------------------------- -- LIBRARY USED---------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -- ENTITY DECLARATION entity flexible_lvds_tx is -- GENERIC DECLARATION generic ( number_of_channels : natural; -- Required parameter deserialization_factor : natural; -- Required parameter registered_input : string := "ON"; use_new_coreclk_ckt : boolean := false; outclock_multiply_by : natural := 1; outclock_divide_by : natural := 2; outclock_duty_cycle : natural := 50; use_self_generated_outclock : boolean := false ); -- PORT DECLARATION port ( --INPUT PORT DECLARATION tx_in : in std_logic_vector(deserialization_factor* number_of_channels -1 downto 0); tx_fastclk : in std_logic; tx_slowclk : in std_logic; tx_regclk : in std_logic; tx_data_reset : in std_logic; pll_areset : in std_logic; pll_outclock : in std_logic; tx_locked : in std_logic; -- OUTPUT PORT DECLARATION tx_out : out std_logic_vector(number_of_channels-1 downto 0); tx_outclock : out std_logic ); end flexible_lvds_tx; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of flexible_lvds_tx is -- FUNCTION DECLARATION function get_cntr_modulus(constant i_deserialization_factor : in natural) return natural is begin if (i_deserialization_factor rem 2 = 1) then return i_deserialization_factor; else return i_deserialization_factor/2; end if; end get_cntr_modulus; -- CONSTANT DECLARATION constant REGISTER_WIDTH : natural := deserialization_factor * number_of_channels; constant ZEROS : std_logic_vector(number_of_channels-1 downto 0) := (OTHERS => '0'); constant LOAD_CNTR_MODULUS : natural := get_cntr_modulus(deserialization_factor); -- TYPE DECLARATION type CHANNEL_CNT is array (number_of_channels-1 downto 0) of integer; type REG_ARRAY is array (deserialization_factor-1 downto 0) of std_logic_vector(number_of_channels -1 downto 0); -- SIGNAL DECLARATION signal tx_reg : std_logic_vector(REGISTER_WIDTH-1 downto 0) := (others => '0'); signal tx_reg2 : std_logic_vector((REGISTER_WIDTH*2)-1 downto 0) := (others => '0'); signal tx_shift_reg : std_logic_vector(REGISTER_WIDTH-1 downto 0) := (others => '0'); signal tx_shift_reg2 : std_logic_vector((REGISTER_WIDTH*2)-1 downto 0) := (others => '0'); signal h_sync_a : std_logic_vector(REGISTER_WIDTH-1 downto 0) := (others => '0'); signal sync_b_reg : std_logic_vector((REGISTER_WIDTH*2)-1 downto 0) := (others => '0'); signal dataout_h : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal dataout_l : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal dataout_tmp : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal tx_ddio_out : std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); signal tx_in_int : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal tx_in_int2 : std_logic_vector((REGISTER_WIDTH*2) -1 downto 0) := (others => '0'); signal stage1_a : std_logic_vector((number_of_channels*2)-1 downto 0) := (others => '0'); signal stage1_b : std_logic_vector((number_of_channels*2)-1 downto 0) := (others => '0'); signal stage2 : std_logic_vector((number_of_channels*2)-1 downto 0) := (others => '0'); signal tx_reg_2ary : REG_ARRAY := (others => (others => '0')); signal tx_slowclk_dly : std_logic; signal tx_outclock_tmp : std_logic := '0'; signal start_sm_p2s : boolean := false; signal loadcnt : natural := 0; signal sm_p2s : natural := 0; signal outclk_shift_l : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); signal outclk_shift_h : std_logic_vector(deserialization_factor-1 downto 0) := (others => '0'); signal outclock_l : std_logic := '0'; signal outclock_h : std_logic := '0'; signal outclk_load_cntr : natural := 0; signal sync_dffe : std_logic := '0'; signal load_enable : std_logic := '0'; signal load_cntr : natural := 0; signal h_ff : natural := 0; signal h_us_ff : natural := 0; signal l_s_ff : natural := 0; signal l_ff : natural := 0; signal l_us_ff : natural := 0; signal h_s_ff : natural := 0; begin -- SIGNAL ASSIGNMENTS tx_in_int <= tx_in when (registered_input = "OFF") else tx_reg; tx_in_int2 <= sync_b_reg when (registered_input = "OFF") else tx_reg2; tx_out <= tx_ddio_out; tx_outclock <= tx_outclock_tmp when (use_self_generated_outclock = true) else pll_outclock; -- PROCESS DECLARATION -- For each data channel, input data are separated into 2 data -- stream which will be transmitted on different edge of input clock. DDIO_OUT_RECEIVE : process(tx_fastclk, pll_areset, tx_data_reset) begin if (pll_areset = '1' or tx_data_reset = '1') then dataout_h <= (others => '0'); dataout_l <= (others => '0'); dataout_tmp <= (others => '0'); elsif ((tx_fastclk = '1') and tx_fastclk'event) then if ((deserialization_factor rem 2) = 0) then for i in 0 to number_of_channels -1 loop dataout_h(i) <= tx_shift_reg((i+1)*deserialization_factor-1); dataout_l(i) <= tx_shift_reg((i+1)*deserialization_factor-2); dataout_tmp(i) <= tx_shift_reg((i+1)*deserialization_factor-1); end loop; else if (use_new_coreclk_ckt = false) then for i in 0 to number_of_channels -1 loop dataout_h(i) <= tx_shift_reg2((i+1)*2*deserialization_factor-1); dataout_l(i) <= tx_shift_reg2((i+1)*2*deserialization_factor-2); dataout_tmp(i) <= tx_shift_reg2((i+1)*2*deserialization_factor-1); end loop; else dataout_h <= stage2(number_of_channels*2-1 downto number_of_channels); dataout_l <= stage2(number_of_channels-1 downto 0); dataout_tmp <= stage2(number_of_channels*2-1 downto number_of_channels); end if; end if; elsif ((tx_fastclk = '0') and tx_fastclk'event) then dataout_tmp <= dataout_l; end if; end process DDIO_OUT_RECEIVE; -- Transmits data on both edges of the input clock. DDIO_OUT_TRANSMIT : process (dataout_tmp) begin tx_ddio_out <= dataout_tmp; end process DDIO_OUT_TRANSMIT; -- Loading input data to shift register SHIFTREG : process (tx_fastclk, pll_areset, tx_data_reset) begin if (pll_areset = '1' or tx_data_reset = '1') then tx_shift_reg <= (others => '0'); tx_shift_reg2 <= (others => '0'); sm_p2s <= 0; stage1_a <= (others => '0'); stage1_b <= (others => '0'); stage2 <= (others => '0'); tx_reg_2ary <= (others => (others => '0')); elsif ((tx_fastclk = '1') and tx_fastclk'event) then -- Implementation for even deserialization factor. if ((deserialization_factor rem 2) = 0) then if(load_enable = '1') then tx_shift_reg <= tx_in_int; else for i in 0 to number_of_channels-1 loop for x in deserialization_factor-1 downto 2 loop tx_shift_reg(x + (i * deserialization_factor)) <= tx_shift_reg (x-2 + (i * deserialization_factor)); end loop; end loop; end if; else -- Implementation for odd deserialization factor. if (use_new_coreclk_ckt = false) then if(load_enable = '1') then tx_shift_reg2 <= tx_in_int2; else for i in 0 to number_of_channels-1 loop for x in deserialization_factor*2-1 downto 2 loop tx_shift_reg2(x + (i * 2 * deserialization_factor)) <= tx_shift_reg2 (x-2 + (i * 2 * deserialization_factor)); end loop; end loop; end if; else -- state machine counter if (((sm_p2s = 0) and (start_sm_p2s = true)) or (sm_p2s /= 0)) then sm_p2s <= (sm_p2s + 1) rem deserialization_factor; end if; -- synchronization register if (((sm_p2s = 0) and (start_sm_p2s = true)) or (sm_p2s = (deserialization_factor/2) + 1)) then for i in 0 to number_of_channels -1 loop for x in 0 to deserialization_factor-1 loop tx_reg_2ary(x)(i) <= tx_in_int(i*deserialization_factor + x); end loop; end loop; end if; -- stage 1a register if ((sm_p2s > 0) and (sm_p2s < deserialization_factor/2 +1)) then stage1_a <= tx_reg_2ary(deserialization_factor - (2*sm_p2s) + 1) & tx_reg_2ary(deserialization_factor - (2*sm_p2s)); elsif (sm_p2s = deserialization_factor/2 + 1) then stage1_a <= tx_reg_2ary(0) & ZEROS; end if; -- stage 1b register if ((sm_p2s = 0) and (start_sm_p2s = true)) then stage1_b <= tx_reg_2ary(1) & tx_reg_2ary(0); elsif ((sm_p2s > (deserialization_factor /2) + 1) and (sm_p2s < deserialization_factor)) then stage1_b <= tx_reg_2ary((deserialization_factor - sm_p2s)*2 + 1) & tx_reg_2ary((deserialization_factor - sm_p2s)*2); end if; -- stage 2 register if ((sm_p2s > 1) and (sm_p2s < (deserialization_factor/2) +2)) then stage2 <= stage1_a; elsif (((sm_p2s = 0) and (start_sm_p2s = true)) or (sm_p2s = 1) or ((sm_p2s > (deserialization_factor/2) + 2) and (sm_p2s < deserialization_factor))) then stage2 <= stage1_b; elsif (sm_p2s = (deserialization_factor/2) + 2) then stage2 <= stage1_a((number_of_channels*2)-1 downto number_of_channels) & tx_reg_2ary(deserialization_factor - 1); end if; end if; end if; end if; end process SHIFTREG; process (tx_fastclk) begin if ((tx_fastclk = '1') and tx_fastclk'event) then tx_slowclk_dly <= tx_slowclk; end if; end process; process (tx_slowclk, tx_slowclk_dly) begin if ((tx_slowclk_dly = '0') and (tx_slowclk = '1')) then start_sm_p2s <= true; else start_sm_p2s <= false; end if; end process; -- loading data to synchronization register SYNC_REG : process (tx_slowclk, pll_areset, tx_data_reset) begin if (pll_areset = '1' or tx_data_reset = '1') then h_sync_a <= (others => '0'); sync_b_reg <= (others => '0'); elsif ((tx_slowclk = '1') and tx_slowclk'event) then h_sync_a <= tx_in; elsif ((tx_slowclk = '0') and tx_slowclk'event) then for i in 0 to number_of_channels-1 loop for x in (deserialization_factor-1) downto 0 loop sync_b_reg(x + (((i * 2) + 1) * deserialization_factor)) <= h_sync_a(x + (i * deserialization_factor)); sync_b_reg(x + (i * 2 * deserialization_factor)) <= tx_in(x + (i * deserialization_factor)); end loop; end loop; end if; end process SYNC_REG; -- loading data to input register IN_REG : process (tx_regclk, pll_areset, tx_data_reset) begin if (pll_areset = '1' or tx_data_reset = '1') then tx_reg <= (others => '0'); tx_reg2 <= (others => '0'); elsif (tx_regclk'event and (tx_regclk = '1')) then if (((deserialization_factor rem 2) = 0) or (use_new_coreclk_ckt = true)) then tx_reg <= tx_in; else tx_reg2 <= sync_b_reg; end if; end if; end process IN_REG; -- generate outclock process (tx_fastclk, pll_areset, tx_data_reset) begin if (pll_areset = '1' or tx_data_reset = '1') then outclk_load_cntr <= 0; elsif (tx_fastclk'event and (tx_fastclk = '1')) then outclk_load_cntr <= (outclk_load_cntr + 1) rem deserialization_factor; end if; end process; process (pll_outclock, pll_areset, tx_data_reset) variable outclk_data_l : std_logic_vector(9 downto 0) := (others => '0'); variable outclk_data_h : std_logic_vector(9 downto 0) := (others => '0'); variable init : boolean := true; begin if (init = true) then if ((deserialization_factor rem 2 = 1) or (((deserialization_factor = 6) or (deserialization_factor = 10)) and (outclock_multiply_by = 2) and (outclock_divide_by = deserialization_factor))) then if (outclock_multiply_by = 2) then if (use_new_coreclk_ckt = true) then case deserialization_factor is when 5 => outclk_data_l := conv_std_logic_vector(22, 10); outclk_data_h := conv_std_logic_vector(21, 10); when 7 => outclk_data_l := conv_std_logic_vector(102, 10); outclk_data_h := conv_std_logic_vector(108, 10); when 9 => outclk_data_l := conv_std_logic_vector(206, 10); outclk_data_h := conv_std_logic_vector(460, 10); when 6 => outclk_data_l := conv_std_logic_vector(9, 10); outclk_data_h := conv_std_logic_vector(27, 10); when 10 => outclk_data_l := conv_std_logic_vector(99, 10); outclk_data_h := conv_std_logic_vector(231, 10); when others => outclk_data_l := (others => '0'); outclk_data_h := (others => '0'); end case; else case deserialization_factor is when 5 => outclk_data_l := conv_std_logic_vector(13, 10); outclk_data_h := conv_std_logic_vector(11, 10); when 7 => outclk_data_l := conv_std_logic_vector(27, 10); outclk_data_h := conv_std_logic_vector(51, 10); when 9 => outclk_data_l := conv_std_logic_vector(115, 10); outclk_data_h := conv_std_logic_vector(103, 10); when 6 => outclk_data_l := conv_std_logic_vector(9, 10); outclk_data_h := conv_std_logic_vector(27, 10); when 10 => outclk_data_l := conv_std_logic_vector(99, 10); outclk_data_h := conv_std_logic_vector(231, 10); when others => outclk_data_l := (others => '0'); outclk_data_h := (others => '0'); end case; end if; else if (outclock_duty_cycle /= 50) then if (use_new_coreclk_ckt = true) then case deserialization_factor is when 5 => outclk_data_l := conv_std_logic_vector(25, 10); outclk_data_h := conv_std_logic_vector(25, 10); when 7 => outclk_data_l := conv_std_logic_vector(113, 10); outclk_data_h := conv_std_logic_vector(113, 10); when 9 => outclk_data_l := conv_std_logic_vector(124, 10); outclk_data_h := conv_std_logic_vector(124, 10); when others => outclk_data_l := (others => '0'); outclk_data_h := (others => '0'); end case; else case deserialization_factor is when 5 => outclk_data_l := conv_std_logic_vector(28, 10); outclk_data_h := conv_std_logic_vector(25, 10); when 7 => outclk_data_l := conv_std_logic_vector(120, 10); outclk_data_h := conv_std_logic_vector(113, 10); when 9 => outclk_data_l := conv_std_logic_vector(31, 10); outclk_data_h := conv_std_logic_vector(31, 10); when others => outclk_data_l := (others => '0'); outclk_data_h := (others => '0'); end case; end if; else if (use_new_coreclk_ckt = true) then case deserialization_factor is when 5 => outclk_data_l := conv_std_logic_vector(24, 10); outclk_data_h := conv_std_logic_vector(25, 10); when 7 => outclk_data_l := conv_std_logic_vector(112, 10); outclk_data_h := conv_std_logic_vector(113, 10); when 9 => outclk_data_l := conv_std_logic_vector(60, 10); outclk_data_h := conv_std_logic_vector(124, 10); when 6 => outclk_data_l := conv_std_logic_vector(54, 10); outclk_data_h := conv_std_logic_vector(36, 10); when 10 => outclk_data_l := conv_std_logic_vector(924, 10); outclk_data_h := conv_std_logic_vector(792, 10); when others => outclk_data_l := (others => '0'); outclk_data_h := (others => '0'); end case; else case deserialization_factor is when 5 => outclk_data_l := conv_std_logic_vector(28, 10); outclk_data_h := conv_std_logic_vector(24, 10); when 7 => outclk_data_l := conv_std_logic_vector(120, 10); outclk_data_h := conv_std_logic_vector(112, 10); when 9 => outclk_data_l := conv_std_logic_vector(15, 10); outclk_data_h := conv_std_logic_vector(31, 10); when 6 => outclk_data_l := conv_std_logic_vector(54, 10); outclk_data_h := conv_std_logic_vector(36, 10); when 10 => outclk_data_l := conv_std_logic_vector(924, 10); outclk_data_h := conv_std_logic_vector(792, 10); when others => outclk_data_l := (others => '0'); outclk_data_h := (others => '0'); end case; end if; end if; end if; else if (deserialization_factor = 4) then case outclock_divide_by is when 2 => outclk_data_l := conv_std_logic_vector(5, 10); when 4 => outclk_data_l := conv_std_logic_vector(12, 10); when others => outclk_data_l := (others => '0'); end case; elsif (deserialization_factor = 6) then case outclock_divide_by is when 2 => outclk_data_l := conv_std_logic_vector(42, 10); when 6 => outclk_data_l := conv_std_logic_vector(56, 10); when others => outclk_data_l := (others => '0'); end case; elsif (deserialization_factor = 8) then case outclock_divide_by is when 2 => outclk_data_l := conv_std_logic_vector(170, 10); when 4 => outclk_data_l := conv_std_logic_vector(51, 10); when 8 => outclk_data_l := conv_std_logic_vector(240, 10); when others => outclk_data_l := (others => '0'); end case; elsif (deserialization_factor = 10) then case outclock_divide_by is when 2 => outclk_data_l := conv_std_logic_vector(682, 10); when 10 => outclk_data_l := conv_std_logic_vector(992, 10); when others => outclk_data_l := (others => '0'); end case; elsif (deserialization_factor = 5) then if (outclock_divide_by = 5) then outclk_data_l := conv_std_logic_vector(19, 10); else outclk_data_l := (others => '0'); end if; elsif (deserialization_factor = 7) then if (outclock_divide_by = 7) then outclk_data_l := conv_std_logic_vector(120, 10); else outclk_data_l := (others => '0'); end if; elsif (deserialization_factor = 9) then if (outclock_divide_by = 9) then outclk_data_l := conv_std_logic_vector(391, 10); else outclk_data_l := (others => '0'); end if; end if; outclk_data_h := outclk_data_l; end if; init := false; end if; if (pll_areset = '1' or tx_data_reset = '1') then outclk_shift_l <= (others => '0'); outclk_shift_h <= (others => '0'); elsif (pll_outclock'event and (pll_outclock = '1')) then if (outclk_load_cntr = 0) then outclk_shift_l <= outclk_data_l(deserialization_factor-1 downto 0); outclk_shift_h <= outclk_data_h(deserialization_factor-1 downto 0); else outclk_shift_l <= ('0' & outclk_shift_l(deserialization_factor-1 downto 1)); outclk_shift_h <= ('0' & outclk_shift_h(deserialization_factor-1 downto 1)); end if; end if; end process; process (pll_outclock, pll_areset, tx_data_reset) begin if (pll_areset = '1' or tx_data_reset = '1') then outclock_h <= '0'; outclock_l <= '0'; tx_outclock_tmp <= '0'; elsif (pll_outclock'event and (pll_outclock = '1')) then if (outclock_divide_by = 1) then outclock_h <= '1'; outclock_l <= '0'; tx_outclock_tmp <= '1'; else outclock_h <= outclk_shift_h(0); outclock_l <= outclk_shift_l(0); tx_outclock_tmp <= outclk_shift_h(0); end if; elsif (pll_outclock'event and (pll_outclock = '0')) then tx_outclock_tmp <= outclock_l; end if; end process; -- new synchronization circuit to generate the load enable pulse process (tx_slowclk) begin if (tx_slowclk'event and (tx_slowclk = '1')) then sync_dffe <= not sync_dffe; end if; end process; process (tx_fastclk, pll_areset, tx_data_reset) begin if (pll_areset = '1' or tx_data_reset = '1') then load_cntr <= 0; elsif (tx_fastclk'event and (tx_fastclk = '1')) then if (sync_dffe ='1') then load_cntr <= (load_cntr +1) rem LOAD_CNTR_MODULUS; else load_cntr <= (LOAD_CNTR_MODULUS + load_cntr - 1) rem LOAD_CNTR_MODULUS; end if; end if; end process; process (tx_fastclk) begin if (tx_fastclk'event and (tx_fastclk = '1')) then if (sync_dffe = '1') then h_ff <= load_cntr; h_us_ff <= h_ff; l_s_ff <= l_us_ff; else l_ff <= load_cntr; l_us_ff <= l_ff; h_s_ff <= h_us_ff; end if; if (((h_ff = h_s_ff) and (sync_dffe = '1')) or ((l_ff = l_s_ff) and (sync_dffe /= '1'))) then load_enable <= '1'; else load_enable <= '0'; end if; end if; end process; end behavior; -- flexible_lvds_tx -- END OF ARCHITECTURE -- START ENTITY HEADER --------------------------------------------------------- -- -- Entity Name : altlvds_tx -- -- Description : Low Voltage Differential Signaling (LVDS) transmitter -- megafunction. The altlvds_tx megafunction implements a -- serialization transmitter. LVDS is a high speed IO interface -- that uses inputs without a reference voltage. LVDS uses two -- wires carrying differential values to create a single -- channel. These wires are connected to two pins on supported -- device to create a single LVDS channel. -- -- Limitations : Only available for Stratix, -- Stratix GX, Stratix II, Cyclone and Cyclone II families. -- --Results expected : output clock, serialized output data and pll locked signal. -- END ENTITY HEADER ----------------------------------------------------------- -- LIBRARY USED----------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use work.ALTERA_DEVICE_FAMILIES.all; use work.MF_stratix_pll; use work.MF_stratixii_pll; use work.MF_stratixiii_pll; use work.stratix_tx_outclk; use work.stratixii_tx_outclk; use work.flexible_lvds_tx; use work.stratixv_local_clk_divider; -- ENTITY DECLARATION entity altlvds_tx is generic ( -- Specifies the number of LVDS channels (required) number_of_channels : natural; -- Specifies the number of bits per channel (required) deserialization_factor : natural := 4; -- Indicates whether the tx_in[] and tx_outclock ports should be -- registered. Choices for STRATIX are ON, OFF, TX_CLKIN or TX_CORECLK registered_input : string := "ON"; -- "ON" means that sync_inclock is also used -- (not used for Stratix and Stratix GX.) multi_clock : string := "OFF"; -- Specifies the period of the input clock in ps (Required) inclock_period : natural := 10000; -- Specifies the period of the tx_outclock port as -- [INCLOCK_PERIOD * OUTCLOCK_DIVIDE_BY] outclock_divide_by : positive := 1; -- The effective clock period used to sample output data inclock_boost : natural := 0; -- Aligns the Most Significant Bit(MSB) to the falling edge of the -- clock instead of the rising edge center_align_msb : string := "OFF"; -- Specifies the device family to be used intended_device_family : string := "Stratix"; -- Specifies the data rate out of the PLL. -- (required and only for Stratix and Stratix GX devices) output_data_rate : natural := 0; -- Specifies the alignment of the input data with respect to the -- tx_inclock port. (required and only available for Stratix and -- Stratix GX devices) inclock_data_alignment : string := "EDGE_ALIGNED"; -- Specifies the alignment of the output data with respect to the -- tx_outclock port. (required and only available for Stratix and -- Stratix GX devices) outclock_alignment : string := "EDGE_ALIGNED"; -- Specifies whether the compiler uses the same PLL for both the LVDS -- receiver and the LVDS transmitter common_rx_tx_pll : string := "ON"; outclock_resource : string := "AUTO"; use_external_pll : string := "OFF"; implement_in_les : STRING := "OFF"; preemphasis_setting : natural := 0; vod_setting : natural := 0; differential_drive : natural := 0; outclock_multiply_by : natural := 1; coreclock_divide_by : natural := 2; outclock_duty_cycle : natural := 50; inclock_phase_shift : integer := 0; outclock_phase_shift : integer := 0; use_no_phase_shift : string := "ON"; pll_self_reset_on_loss_lock : string := "OFF"; refclk_frequency : string := "UNUSED"; enable_clock_pin_mode : string := "UNUSED"; data_rate : string := "UNUSED"; lpm_type : string := "altlvds_tx"; lpm_hint : string := "UNUSED"; pll_compensation_mode : string := "AUTO"; -- Specifies whether the source of the input clock is from the PLL clk_src_is_pll : string := "off" ); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION -- Input data (required) tx_in : in std_logic_vector(deserialization_factor* number_of_channels -1 downto 0); -- Input clock (required) tx_inclock : in std_logic := '0'; tx_syncclock : in std_logic := '0'; tx_enable : in std_logic := '1'; -- Optional clock for input registers (Required if "multi_clock" -- parameters is turned on) sync_inclock : in std_logic := '0'; -- Enable control for the LVDS PLL tx_pll_enable : in std_logic := '1'; -- Asynchronously resets all counters to initial values (only for --Stratix and Stratix GX devices) pll_areset : in std_logic := '0'; tx_data_reset : in std_logic := '0'; -- OUTPUT PORT DECLARATION -- Serialized data signal(required) tx_out : out std_logic_vector(number_of_channels-1 downto 0) := (others => '0'); -- External reference clock tx_outclock : out std_logic; -- Output clock used to feed non-peripheral logic. -- Only available for Stratix, and Stratix GX devices only. tx_coreclock : out std_logic; -- Gives the status of the LVDS PLL -- (when the PLL is locked, this signal is VCC. GND otherwise) tx_locked : out std_logic ); end altlvds_tx; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of altlvds_tx is -- CONSTANT DECLARATION constant STRATIX_TX_STYLE : boolean := FEATURE_FAMILY_BASE_STRATIX(intended_device_family); constant STRATIXII_TX_STYLE : boolean := FEATURE_FAMILY_BASE_STRATIXII(intended_device_family); constant STRATIXIII_TX_STYLE : boolean := FEATURE_FAMILY_BASE_STRATIXIII(intended_device_family); constant CYCLONE_TX_STYLE : boolean := FEATURE_FAMILY_BASE_CYCLONE(intended_device_family); constant CYCLONEII_TX_STYLE : boolean := FEATURE_FAMILY_BASE_CYCLONEII(intended_device_family); constant CYCLONEIII_TX_STYLE : boolean := FEATURE_FAMILY_BASE_CYCLONEIII(intended_device_family); constant MAXV_TX_STYLE : boolean := FEATURE_FAMILY_MAXV(intended_device_family); constant FAMILY_HAS_FLEXIBLE_LVDS : boolean := FEATURE_FAMILY_HAS_FLEXIBLE_LVDS(intended_device_family) or (((STRATIX_TX_STYLE = true) or (STRATIXII_TX_STYLE = true) or (STRATIXIII_TX_STYLE = true)) and (implement_in_les = "ON")); constant FAMILY_HAS_STRATIX_STYLE_PLL : boolean := FEATURE_FAMILY_HAS_STRATIX_STYLE_PLL(intended_device_family); constant FAMILY_HAS_STRATIXII_STYLE_PLL : boolean := FEATURE_FAMILY_HAS_STRATIXII_STYLE_PLL(intended_device_family); constant FAMILY_HAS_STRATIXIII_STYLE_PLL : boolean := FEATURE_FAMILY_USES_STRATIXIII_PLL(intended_device_family); constant USE_NEW_CORECLK_CKT : boolean := ((deserialization_factor rem 2) = 1) and (coreclock_divide_by = 1); constant USE_SELF_GENERATED_OUTCLOCK : boolean := not FEATURE_FAMILY_BASE_CYCLONE(intended_device_family); -- FUNCTION DECLARATION -- converts uppercase parameter values (e.g. "AUTO") to lowercase ("auto") -- as expected by stratix_pll model function alpha_tolower (given_string : string) return string is -- VARIABLE DECLARATION variable string_length : integer := given_string'length; variable result_string : string(1 to 20) := " "; begin for i in 1 to string_length loop case given_string(i) is when 'A' => result_string(i) := 'a'; when 'B' => result_string(i) := 'b'; when 'C' => result_string(i) := 'c'; when 'D' => result_string(i) := 'd'; when 'E' => result_string(i) := 'e'; when 'F' => result_string(i) := 'f'; when 'G' => result_string(i) := 'g'; when 'H' => result_string(i) := 'h'; when 'I' => result_string(i) := 'i'; when 'J' => result_string(i) := 'j'; when 'K' => result_string(i) := 'k'; when 'L' => result_string(i) := 'l'; when 'M' => result_string(i) := 'm'; when 'N' => result_string(i) := 'n'; when 'O' => result_string(i) := 'o'; when 'P' => result_string(i) := 'p'; when 'Q' => result_string(i) := 'q'; when 'R' => result_string(i) := 'r'; when 'S' => result_string(i) := 's'; when 'T' => result_string(i) := 't'; when 'U' => result_string(i) := 'u'; when 'V' => result_string(i) := 'v'; when 'W' => result_string(i) := 'w'; when 'X' => result_string(i) := 'x'; when 'Y' => result_string(i) := 'y'; when 'Z' => result_string(i) := 'z'; when others => result_string(i) := given_string(i); end case; end loop; return (result_string(1 to string_length)); end; -- M value for stratix/stratix II/Cyclone/Cyclone II PLL function pll_m_value(constant i_output_data_rate, i_inclock_period : in natural) return natural is variable i_pll_m_value : natural; begin i_pll_m_value := (((i_output_data_rate * i_inclock_period) + (5* 100000)) / 1000000); return i_pll_m_value; end pll_m_value; -- D value for Stratix/Stratix II/Cyclone/Cyclone II PLL function pll_d_value(constant i_output_data_rate, i_inclock_period : in natural) return natural is variable i_pll_d_value : natural; begin if ((i_output_data_rate /= 0) and (i_inclock_period /= 0)) then if (FAMILY_HAS_FLEXIBLE_LVDS = true) then i_pll_d_value := 2; else i_pll_d_value := 1; end if; else i_pll_d_value := 1; end if; return i_pll_d_value; end pll_d_value; -- clock_boost_calc calculates the multiply_by factor for the PLL clocks -- used by LVDS_TX function clock_boost_calc (constant i_output_data_rate, i_inclock_period, i_deserialization_factor, i_inclock_boost : in natural) return natural is variable i_input_clock_boost: natural := 1; begin if ((i_output_data_rate /= 0) and (i_inclock_period /= 0)) then i_input_clock_boost := pll_m_value (i_output_data_rate, i_inclock_period); else if (inclock_boost = 0) then i_input_clock_boost := i_deserialization_factor; else i_input_clock_boost := i_inclock_boost; end if; end if; return i_input_clock_boost; end clock_boost_calc; -- int_to_str converts an integer to a string. This is mainly used for -- converting the calculated phase shift to a string as required by altpll function int_to_str(constant value : integer ) return string is variable ivalue : integer := 0; variable index : integer := 0; variable strlen : integer := 0; variable digit : integer := 0; variable str : string(1 to 8) := "00000000"; begin ivalue := abs(value); strlen := 0; while (ivalue > 0) loop ivalue := ivalue/10; strlen := strlen + 1; end loop; if (strlen = 0) then strlen := 1; end if; ivalue := abs(value); index := strlen; while (ivalue > 0) loop digit := ivalue mod 10; ivalue := ivalue / 10; case digit is when 0 => str(index) := '0'; when 1 => str(index) := '1'; when 2 => str(index) := '2'; when 3 => str(index) := '3'; when 4 => str(index) := '4'; when 5 => str(index) := '5'; when 6 => str(index) := '6'; when 7 => str(index) := '7'; when 8 => str(index) := '8'; when 9 => str(index) := '9'; when others => ASSERT FALSE REPORT "Illegal number!" SEVERITY ERROR; end case; index := index - 1; end loop; if (value < 0) then return ('-'& str(1 to strlen)); else return str(1 to strlen); end if; end int_to_str; -- get_phase_delay calculates the phase shift for each PLL clock as -- determined by the INCLOCK_DATA_ALIGNMENT parameter function get_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; variable x : integer := 0; variable int_delay : integer := 0; begin if (i_phase_delay = "UNUSED") then int_delay := inclock_phase_shift; else -- returns the delay in ps -- ( * inclock period / 360 degress) if (i_phase_delay = "EDGE_ALIGNED") then my_phase := 0; -- CENTER_ALIGNED means 180 degrees elsif (i_phase_delay = "CENTER_ALIGNED") then my_phase := (180 * inclock_period) / 360; elsif (i_phase_delay = "45_DEGREES") then my_phase := (45 * inclock_period) / 360; elsif (i_phase_delay = "90_DEGREES") then my_phase := (90 * inclock_period) / 360; elsif (i_phase_delay = "135_DEGREES") then my_phase := (135 * inclock_period) / 360; elsif (i_phase_delay = "180_DEGREES") then my_phase := (180 * inclock_period) / 360; elsif (i_phase_delay = "225_DEGREES") then my_phase := (225 * inclock_period) / 360; elsif (i_phase_delay = "270_DEGREES") then my_phase := (270 * inclock_period) / 360; elsif (i_phase_delay = "315_DEGREES") then my_phase := (315 * inclock_period) / 360; else ASSERT FALSE REPORT "Invalid clock data alignment. Using 'EDGE_ALIGNED' instead" SEVERITY WARNING; my_phase := 0; end if; -- add 1 to "round up" the calculation result my_phase := my_phase + 1; -- phase shift = ( * inclock_period / 360 ) / (fast -- clock multiply_by factor) -- in other words, the data alignment phase shift is a percentage of the -- fast clock period int_delay := my_phase / clock_boost_calc(output_data_rate, inclock_period, deserialization_factor, inclock_boost); -- add 1 to "round up" the calculation result int_delay := int_delay + 1; end if; return (int_delay); end get_phase_delay; -- get_stxii_inclock_phase_delay returns the adjusted input clock phase shift for Stratix II pll. function get_stxii_inclock_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; begin my_phase := get_phase_delay(i_phase_delay) - (inclock_period / (2 * clock_boost_calc (output_data_rate, inclock_period, deserialization_factor, inclock_boost))); return (my_phase); end get_stxii_inclock_phase_delay; -- get_outclock_phase_delay calculates the phase shift for the outclock port -- as determined by the OUTCLOCK_ALIGNMENT parameter function get_outclock_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; variable x : integer := 0; variable int_delay : integer := 0; begin if (i_phase_delay = "UNUSED") then my_phase := outclock_phase_shift; else -- returns the delay in ps -- ( * inclock period / 360 degress ) if (i_phase_delay = "EDGE_ALIGNED") then my_phase := 0; -- CENTER_ALIGNED means 180 degrees elsif (i_phase_delay = "CENTER_ALIGNED") then my_phase := (180 * inclock_period) / 360; elsif (i_phase_delay = "45_DEGREES") then my_phase := (45 * inclock_period) / 360; elsif (i_phase_delay = "90_DEGREES") then my_phase := (90 * inclock_period) / 360; elsif (i_phase_delay = "135_DEGREES") then my_phase := (135 * inclock_period) / 360; elsif (i_phase_delay = "180_DEGREES") then my_phase := (180 * inclock_period) / 360; elsif (i_phase_delay = "225_DEGREES") then my_phase := (225 * inclock_period) / 360; elsif (i_phase_delay = "270_DEGREES") then my_phase := (270 * inclock_period) / 360; elsif (i_phase_delay = "315_DEGREES") then my_phase := (315 * inclock_period) / 360; else ASSERT FALSE REPORT "Invalid outclock alignment. Using 'EDGE_ALIGNED' instead" SEVERITY WARNING; my_phase := 0; end if; -- add 1 to "round up" calculation result my_phase := my_phase + 1; my_phase := my_phase / clock_boost_calc (output_data_rate, inclock_period, deserialization_factor, inclock_boost); -- add 1 to "round up" calculation result my_phase := my_phase + 1; end if; if (FAMILY_HAS_FLEXIBLE_LVDS = true) then int_delay := my_phase; else int_delay := my_phase + get_phase_delay(inclock_data_alignment); end if; return int_delay; end get_outclock_phase_delay; -- Calculates the phase shift of the fastclk that feeds the -- stratix_tx_outclk or stratixii_tx_outclk. function get_lvds_outclock_phase_delay (constant i_phase_delay : in string; constant i_outclock_divide_by : in positive; constant i_intended_device_family : in string) return integer is variable my_phase : integer := 0; begin if (FAMILY_HAS_FLEXIBLE_LVDS = true) then my_phase := get_outclock_phase_delay(i_phase_delay); elsif ((i_outclock_divide_by = 1) or (i_phase_delay = "45_DEGREES") or (i_phase_delay = "90_DEGREES") or (i_phase_delay = "135_DEGREES")) then my_phase := get_outclock_phase_delay(i_phase_delay); elsif (outclock_alignment = "UNUSED") then if (outclock_phase_shift >= get_phase_delay("180_DEGREES")) then my_phase := get_outclock_phase_delay(i_phase_delay) - get_phase_delay("180_DEGREES"); else my_phase := get_outclock_phase_delay(i_phase_delay); end if; elsif ((i_phase_delay = "180_DEGREES") or (i_phase_delay = "CENTER_ALIGNED")) then my_phase := get_phase_delay(inclock_data_alignment); elsif (i_phase_delay = "225_DEGREES") then my_phase := get_outclock_phase_delay("45_DEGREES"); elsif (i_phase_delay = "270_DEGREES") then my_phase := get_outclock_phase_delay("90_DEGREES"); elsif (i_phase_delay = "315_DEGREES") then my_phase := get_outclock_phase_delay("135_DEGREES"); else my_phase := get_phase_delay(inclock_data_alignment); end if; if (FEATURE_FAMILY_STRATIXII(i_intended_device_family) and (implement_in_les = "OFF")) then my_phase := my_phase - (inclock_period / ( 2 * clock_boost_calc (output_data_rate, inclock_period, deserialization_factor, inclock_boost))); end if; return my_phase; end get_lvds_outclock_phase_delay; -- get clk1_multiply_by value for PLL (for flexible lvds) function get_flvds_clk1_multiply_by ( constant i_deserialization_factor : in natural; constant i_outclock_multiply_by : in natural; constant i_outclock_divide_by : in natural ) return natural is variable clk1_mult_by : natural := 0; begin if (CYCLONE_TX_STYLE = false) then clk1_mult_by := clock_boost_calc (output_data_rate, inclock_period, deserialization_factor, inclock_boost); elsif ( ( ((i_deserialization_factor rem 2) = 1) or (i_deserialization_factor = 6) or (i_deserialization_factor = 10) ) and (outclock_multiply_by = 2) and (outclock_divide_by = deserialization_factor)) then clk1_mult_by := clock_boost_calc (output_data_rate, inclock_period, deserialization_factor, inclock_boost) * 2; else clk1_mult_by := clock_boost_calc (output_data_rate, inclock_period, deserialization_factor, inclock_boost); end if; return clk1_mult_by; end get_flvds_clk1_multiply_by; -- get clk2_multiply_by value for PLL (for flexible lvds) function get_flvds_clk2_multiply_by ( constant i_deserialization_factor : in natural) return natural is variable clk2_mult_by : natural := 0; begin if (((i_deserialization_factor rem 2) = 0) or (USE_NEW_CORECLK_CKT = true)) then clk2_mult_by := clock_boost_calc (output_data_rate, inclock_period, deserialization_factor, inclock_boost) * 2; else clk2_mult_by := clock_boost_calc (output_data_rate, inclock_period, deserialization_factor, inclock_boost); end if; return clk2_mult_by; end get_flvds_clk2_multiply_by; -- get clk1_divide_by value for PLL (for flexible lvds) function get_flvds_clk1_divide_by ( constant i_outclock_divide_by : in natural) return natural is variable clk1_div_by : natural := 0; begin if (CYCLONE_TX_STYLE = false) then clk1_div_by := pll_d_value (output_data_rate, inclock_period); else clk1_div_by := i_outclock_divide_by * pll_d_value (output_data_rate, inclock_period); end if; return clk1_div_by; end get_flvds_clk1_divide_by; -- get clk2_divide_by value for PLL (for flexible lvds) function get_flvds_clk2_divide_by ( constant i_deserialization_factor : in natural) return natural is variable clk2_div_by : natural := 0; begin clk2_div_by := i_deserialization_factor * pll_d_value (output_data_rate, inclock_period); return clk2_div_by; end get_flvds_clk2_divide_by; --- get pll_type for PLL (for flexible lvds) function get_flvds_pll_type ( constant i_inclock_alignment : in string) return string is begin if (i_inclock_alignment = "UNUSED") then return "auto"; else return "flvds"; end if; end get_flvds_pll_type; --- get phase delay in ps for cyclone ii and stratix II in LE mode --- function get_stxii_le_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; begin if (use_no_phase_shift = "OFF") then my_phase := get_phase_delay(i_phase_delay) - (inclock_period / (4 * clock_boost_calc(output_data_rate, inclock_period, deserialization_factor, inclock_boost))); else my_phase := get_phase_delay(i_phase_delay); end if; return my_phase; end get_stxii_le_phase_delay; --- get phase delay in ps for stratix III in LE mode --- function get_stxiii_le_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; begin if (FEATURE_FAMILY_STRATIXIII(intended_device_family)) then my_phase := get_phase_delay(i_phase_delay); else my_phase := get_phase_delay(i_phase_delay) - (inclock_period / (4 * clock_boost_calc(output_data_rate, inclock_period, deserialization_factor, inclock_boost))); end if; return my_phase; end get_stxiii_le_phase_delay; --- get outclock phase delay in ps for cyclone ii and stratix II in LE mode --- function get_stxii_le_outclock_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; begin if (use_no_phase_shift = "OFF") then my_phase := get_outclock_phase_delay(i_phase_delay) - (inclock_period / (4 * clock_boost_calc(output_data_rate, inclock_period, deserialization_factor, inclock_boost))); else my_phase := get_outclock_phase_delay(i_phase_delay); end if; return my_phase; end get_stxii_le_outclock_phase_delay; --- get outclock phase delay in ps for stratix III in LE mode --- function get_stxiii_le_outclock_phase_delay (constant i_phase_delay : in string) return integer is variable my_phase : integer := 0; begin if (FEATURE_FAMILY_STRATIXIII(intended_device_family)) then my_phase := get_outclock_phase_delay(i_phase_delay); else my_phase := get_outclock_phase_delay(i_phase_delay) - (inclock_period / (4 * clock_boost_calc(output_data_rate, inclock_period, deserialization_factor, inclock_boost))); end if; return my_phase; end get_stxiii_le_outclock_phase_delay; --- get phase_shift value for the clock that acts as enable signal (for StratixIII lvds) function get_clk_ena_phase_shift ( constant i_phase_shift : in string) return string is variable fast_clk_ena_phase_shift : integer := 0; begin fast_clk_ena_phase_shift := (deserialization_factor*2-3) * (inclock_period/(2*clock_boost_calc(output_data_rate, inclock_period, deserialization_factor, inclock_boost))); return int_to_str(get_stxii_inclock_phase_delay(i_phase_shift) + fast_clk_ena_phase_shift); end get_clk_ena_phase_shift; --- get phase_shift value for the clock that acts as enable signal for outclock channel (for StratixIII lvds) function get_outclk_ena_phase_shift ( constant i_phase_shift : in string) return string is variable fast_clk_ena_phase_shift : integer := 0; begin fast_clk_ena_phase_shift := (deserialization_factor*2-3) * (inclock_period/(2*clock_boost_calc(output_data_rate, inclock_period, deserialization_factor, inclock_boost))); return int_to_str(get_lvds_outclock_phase_delay(i_phase_shift, outclock_divide_by, intended_device_family) + fast_clk_ena_phase_shift); end get_outclk_ena_phase_shift; -- CONSTANT DECLARATION -- these constants are PLL parameters calculated from the altlvds_tx -- parameters given constant PHASE_INCLOCK : string := int_to_str(get_phase_delay(inclock_data_alignment)); constant STXII_PHASE_INCLOCK : string := int_to_str(get_stxii_inclock_phase_delay(inclock_data_alignment)); constant PHASE_OUTCLOCK : string := int_to_str(get_lvds_outclock_phase_delay(outclock_alignment, outclock_divide_by, intended_device_family)); constant INT_CLOCK_BOOST : natural := clock_boost_calc(output_data_rate, inclock_period, deserialization_factor, inclock_boost); constant REGISTER_WIDTH : natural := deserialization_factor * number_of_channels; constant FLVDS_CLK1_MUL : natural := get_flvds_clk1_multiply_by(deserialization_factor, outclock_multiply_by, outclock_divide_by); constant FLVDS_CLK2_MUL : natural := get_flvds_clk2_multiply_by(deserialization_factor); constant FLVDS_CLK0_DIV : natural := pll_d_value(output_data_rate, inclock_period); constant FLVDS_CLK1_DIV : natural := get_flvds_clk1_divide_by(outclock_divide_by); constant FLVDS_CLK2_DIV : natural := get_flvds_clk2_divide_by(deserialization_factor); constant FLVDS_PLL_TYPE : string := get_flvds_pll_type(inclock_data_alignment); constant STXII_LE_PHASE_INCLOCK : string := int_to_str(get_stxii_le_phase_delay(inclock_data_alignment)); constant STXII_LE_PHASE_OUTCLOCK : string := int_to_str(get_stxii_le_outclock_phase_delay(outclock_alignment)); constant STXIII_LE_PHASE_INCLOCK : string := int_to_str(get_stxiii_le_phase_delay(inclock_data_alignment)); constant STXIII_LE_PHASE_OUTCLOCK : string := int_to_str(get_stxiii_le_outclock_phase_delay(outclock_alignment)); constant CLK_ENA_PHASE_SHIFT : string := get_clk_ena_phase_shift(inclock_data_alignment); constant OUTCLK_ENA_PHASE_SHIFT : string := get_outclk_ena_phase_shift(outclock_alignment); constant BYPASS_NEEDED : boolean := (outclock_divide_by = 1); constant INVERT_CLOCK_NEEDED : boolean := ((outclock_alignment = "180_DEGREES") or (outclock_alignment = "CENTER_ALIGNED")) and (use_external_pll = "ON"); constant FALLING_CLOCK_EDGE_NEEDED : boolean := (outclock_phase_shift >= get_phase_delay("180_DEGREES")) or (outclock_alignment = "180_DEGREES") or (outclock_alignment = "CENTER_ALIGNED") or (outclock_alignment = "225_DEGREES") or (outclock_alignment = "270_DEGREES") or (outclock_alignment = "315_DEGREES"); -- SIGNAL DECLARATION -- registers signal tx_in_reg : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal tx_in_int : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal tx_parallel_load_reg : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); signal dataout_l : std_logic_vector(number_of_channels -1 downto 0) := (others => '0'); signal dataout_h : std_logic_vector(number_of_channels -1 downto 0) := (others => '0'); signal tx_ddio_out : std_logic_vector(number_of_channels -1 downto 0) := (others => '0'); signal tx_out_stratix : std_logic_vector(number_of_channels -1 downto 0) := (others => '0'); signal flvds_dataout : std_logic_vector(number_of_channels -1 downto 0) := (others => '0'); signal stx_phase_shift_txdata : std_logic_vector(9 downto 0) := (others => '0'); signal phase_shift_txdata : std_logic_vector(9 downto 0) := (others => '0'); -- clock signals signal tx_fastclk : std_logic; -- fast clock signal tx_slowclk : std_logic; -- slow clock signal tx_pll_clk0 : std_logic; -- PLL clk0 output signal tx_pll_clk1 : std_logic; -- PLL clk1 output signal tx_pll_clk2 : std_logic; -- PLL clk2 output signal tx_pll_clk3 : std_logic; -- PLL clk3 output signal tx_pll_clk4 : std_logic; -- PLL clk4 output signal tx_reg_clk : std_logic; -- clock for sync register signal tx_coreclk_int : std_logic; signal tx_pll_sclkout : std_logic_vector (1 downto 0) := (others => '0'); -- PLL serial clk output signal stratix_inclock : std_logic := '0'; signal stratixii_inclock : std_logic := '0'; signal stratix_outclock : std_logic := '0'; signal stratixii_outclock : std_logic := '0'; signal flvds_fastclk : std_logic := '0'; signal flvds_slowclk : std_logic := '0'; signal flvds_outclock : std_logic := '0'; signal flvds_pll_outclock : std_logic := '0'; signal stratixiii_enable0 : std_logic := '0'; signal stratixiii_enable1 : std_logic := '0'; -- PLL locked signal signal tx_locked_int : std_logic; signal pll_lock_sync : std_logic := '1'; -- constant signals signal temp_zero : std_logic := '0'; signal temp_high : std_logic_vector (5 downto 0) := (others => '1'); signal temp_clk : std_logic_vector (6 downto 0) := (others => '0'); -- load enable signals for Stratix, Stratix GX and Stratix II signal tx_pll_enable0 : std_logic := '0'; signal tx_pll_enable1 : std_logic := '0'; signal enable0 : std_logic := '0'; signal enable0_reg : std_logic := '0'; signal enable0_pipe : std_logic := '0'; signal enable0_neg : std_logic := '0'; signal stratix_enable : std_logic := '0'; signal stratixii_enable : std_logic := '0'; signal local_clk_div_lloaden : std_logic := '0'; -- COMPONENT DECLARATION -- PLL for Stratix and Stratix GX component MF_stratix_pll generic ( pll_type : string := "lvds"; inclk0_input_frequency : positive ; --Required valid_lock_multiplier : integer := 1; simulation_type : string := "functional"; clk0_multiply_by : positive := 1; clk0_divide_by : positive := 1; clk0_phase_shift : string := "0"; clk1_multiply_by : positive := 1; clk1_divide_by : positive := 1; clk1_phase_shift : string := "0"; clk1_duty_cycle : natural := 50; clk2_multiply_by : positive := 1; clk2_divide_by : positive := 1; clk2_phase_shift : string := "0"; family_name : string := "Stratix"; m : integer := 0 ); port ( inclk : in std_logic_vector(1 downto 0) := (others => '0'); fbin : in std_logic := '1'; ena : in std_logic := '1'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; clkena : in std_logic_vector(5 downto 0) := (others => '1'); extclkena : in std_logic_vector(3 downto 0) := (OTHERS=>'1'); scanaclr : in std_logic := '0'; scandata : in std_logic := '0'; scanclk : in std_logic := '0'; comparator : in std_logic := '0'; clk : out std_logic_vector(5 downto 0); locked : out std_logic; enable0 : out std_logic; enable1 : out std_logic ); end component; -- MF_stratix_pll -- PLL for Stratix II component MF_stratixii_pll generic ( pll_type : string := "lvds"; vco_multiply_by : integer := 0; vco_divide_by : integer := 0; inclk0_input_frequency : positive ; --Required simulation_type : string := "functional"; clk0_multiply_by : positive := 1; clk0_divide_by : positive := 1; clk0_phase_shift : string := "0"; clk1_multiply_by : positive := 1; clk1_divide_by : positive := 1; clk1_phase_shift : string := "0"; clk1_duty_cycle : natural := 50; clk2_multiply_by : positive := 1; clk2_divide_by : positive := 1; clk2_phase_shift : string := "0"; sclkout0_phase_shift : string := "0"; sclkout1_phase_shift : string := "0"; family_name : string := "Stratix II"; m : integer := 0 ); port ( inclk : in std_logic_vector(1 downto 0) := (others => '0'); fbin : in std_logic := '1'; ena : in std_logic := '1'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; scanread : in std_logic := '0'; scanwrite : in std_logic := '0'; scandata : in std_logic := '0'; scanclk : in std_logic := '0'; testin : in std_logic_vector(3 downto 0) := (OTHERS=>'0'); clk : out std_logic_vector(5 downto 0); locked : out std_logic; enable0 : out std_logic; enable1 : out std_logic; sclkout : out std_logic_vector(1 downto 0) ); end component; -- MF_stratixii_pll -- PLL for Stratix III component MF_stratixiii_pll generic ( operation_mode : string := "normal"; pll_type : string := "lvds"; vco_multiply_by : integer := 0; vco_divide_by : integer := 0; inclk0_input_frequency : positive ; simulation_type : string := "functional"; clk0_multiply_by : positive := 1; clk0_divide_by : positive := 1; clk0_phase_shift : string := "0"; clk1_multiply_by : positive := 1; clk1_divide_by : positive := 1; clk1_duty_cycle : integer := 50; clk1_phase_shift : string := "0"; clk2_multiply_by : positive := 1; clk2_divide_by : positive := 1; clk2_phase_shift : string := "0"; clk3_multiply_by : positive := 1; clk3_divide_by : positive := 1; clk3_phase_shift : string := "0"; clk4_multiply_by : positive := 1; clk4_divide_by : positive := 1; clk4_phase_shift : string := "0"; clk4_duty_cycle : integer := 50; family_name : string := "Stratix III"; self_reset_on_loss_lock : string := "OFF"; m : integer := 0 ); port ( inclk : in std_logic_vector(1 downto 0) := (others => '0'); fbin : in std_logic := '1'; clkswitch : in std_logic := '0'; areset : in std_logic := '0'; pfdena : in std_logic := '1'; scanclk : in std_logic := '1'; scandata : in std_logic := '1'; scanclkena : in std_logic := '1'; configupdate : in std_logic := '0'; phasecounterselect : in std_logic_vector(3 downto 0) := (OTHERS=>'1'); phaseupdown : in std_logic := '1'; phasestep : in std_logic := '1'; clk : out std_logic_vector(9 downto 0); locked : out std_logic ); end component; -- MF_stratixiii_pll component stratix_tx_outclk generic ( deserialization_factor : natural; -- Required parameter bypass_serializer : boolean := FALSE; invert_clock : boolean := FALSE; use_falling_clock_edge : boolean := FALSE ); port ( tx_in : in std_logic_vector(deserialization_factor-1 downto 0); tx_fastclk : in std_logic; tx_enable : in std_logic := '1'; tx_out : out std_logic := '0' ); end component; -- stratix_tx_outclk component stratixii_tx_outclk generic ( deserialization_factor : natural; -- Required parameter bypass_serializer : boolean := FALSE; invert_clock : boolean := FALSE; use_falling_clock_edge : boolean := FALSE ); port ( tx_in : in std_logic_vector(deserialization_factor-1 downto 0); tx_fastclk : in std_logic; tx_enable : in std_logic := '1'; tx_out : out std_logic := '0' ); end component; -- stratixii_tx_outclk component flexible_lvds_tx generic ( number_of_channels : natural; -- Required parameter deserialization_factor : natural; -- Required parameter registered_input : string := "ON"; use_new_coreclk_ckt : boolean := false; outclock_multiply_by : natural := 1; outclock_divide_by : natural := 2; outclock_duty_cycle : natural := 50; use_self_generated_outclock : boolean := false ); port ( tx_in : in std_logic_vector(REGISTER_WIDTH -1 downto 0); tx_fastclk : in std_logic; tx_slowclk : in std_logic; tx_regclk : in std_logic; pll_areset : in std_logic; tx_data_reset : in std_logic; pll_outclock : in std_logic; tx_locked : in std_logic; tx_out : out std_logic_vector(number_of_channels-1 downto 0); tx_outclock : out std_logic ); end component; -- flexible_lvds_tx component stratixv_local_clk_divider generic ( clk_divide_by : natural := 4 ); port ( clkin : in std_logic; lloaden : out std_logic := '0' ); end component; -- stratixv_local_clk_divider begin -- SIGNAL ASSIGNMENTS tx_out <= tx_in_int when (deserialization_factor = 1) else tx_ddio_out when (deserialization_factor = 2) else flvds_dataout when (FAMILY_HAS_FLEXIBLE_LVDS = true) else tx_out_stratix when ((STRATIX_TX_STYLE = true) or (STRATIXII_TX_STYLE = true) or (STRATIXIII_TX_STYLE = true)) else tx_in_int; tx_in_int <= tx_in_reg when (registered_input /= "OFF") else tx_in; tx_fastclk <= '0' when (deserialization_factor < 3) else tx_inclock when ((use_external_pll = "ON") or (enable_clock_pin_mode = "ON")) else tx_pll_sclkout(0) when (STRATIXII_TX_STYLE = true) else tx_pll_clk0; tx_slowclk <= '0' when ((use_external_pll = "ON") or (deserialization_factor < 3)) else tx_pll_clk2 when ((STRATIX_TX_STYLE = true) or (STRATIXII_TX_STYLE = true) or (STRATIXIII_TX_STYLE = true) or (CYCLONE_TX_STYLE = true) or (CYCLONEIII_TX_STYLE = true) or (CYCLONEII_TX_STYLE = true)) else tx_pll_clk1; tx_outclock <= tx_inclock when (deserialization_factor < 3) else flvds_outclock when (FAMILY_HAS_FLEXIBLE_LVDS = true) else stratix_outclock when (STRATIX_TX_STYLE = true) else stratixii_outclock when (STRATIXII_TX_STYLE = true) or (STRATIXIII_TX_STYLE = true) else tx_slowclk; flvds_pll_outclock <= tx_pll_clk1; tx_coreclk_int <= tx_slowclk; tx_coreclock <= tx_coreclk_int; tx_reg_clk <= tx_inclock when (use_external_pll = "ON") else sync_inclock when (registered_input = "ON") and (multi_clock = "ON") and (STRATIX_TX_STYLE = false) and (STRATIXII_TX_STYLE = false) and (STRATIXIII_TX_STYLE = false) and (CYCLONE_TX_STYLE = false) and (CYCLONEIII_TX_STYLE = false) and (CYCLONEII_TX_STYLE = false) else tx_coreclk_int when (registered_input = "TX_CORECLK") and ((STRATIX_TX_STYLE = true) or (STRATIXII_TX_STYLE = true) or (STRATIXIII_TX_STYLE = true) or (CYCLONE_TX_STYLE = true) or (CYCLONEIII_TX_STYLE = true) or (CYCLONEII_TX_STYLE = true)) else tx_inclock; tx_locked <= tx_locked_int and pll_lock_sync when (((STRATIXIII_TX_STYLE = true) or (CYCLONEIII_TX_STYLE = true)) and (deserialization_factor > 2)) else tx_locked_int when (deserialization_factor > 2) else '1'; enable0 <= tx_enable when (use_external_pll = "ON") else stratixiii_enable0 when (STRATIXIII_TX_STYLE = true) and (implement_in_les = "OFF") else tx_pll_enable0; stratixiii_enable0 <= local_clk_div_lloaden when (enable_clock_pin_mode = "ON") else tx_pll_clk1; stratixiii_enable1 <= local_clk_div_lloaden when (enable_clock_pin_mode = "ON") else tx_pll_clk4; stratix_inclock <= '0' when (STRATIX_TX_STYLE = false) or (implement_in_les = "ON") else tx_pll_clk1; stratix_enable <= '0' when (STRATIX_TX_STYLE = false) or (implement_in_les = "ON") else tx_pll_enable1; stratixii_inclock <= '0' when ((STRATIXII_TX_STYLE = false) and (STRATIXIII_TX_STYLE = false)) or (implement_in_les = "ON") else tx_inclock when ((use_external_pll = "ON") or (enable_clock_pin_mode = "ON")) else tx_pll_clk3 when (STRATIXIII_TX_STYLE = true) else tx_pll_sclkout(1); stratixii_enable <= '0' when ((STRATIXII_TX_STYLE = false) and (STRATIXIII_TX_STYLE = false)) or (implement_in_les = "ON") else tx_enable when (use_external_pll = "ON") else stratixiii_enable1 when (STRATIXIII_TX_STYLE = true) else tx_pll_enable1; flvds_fastclk <= '0' when (FAMILY_HAS_FLEXIBLE_LVDS = false) else tx_inclock when (use_external_pll = "ON") else tx_pll_clk0; flvds_slowclk <= '0' when (FAMILY_HAS_FLEXIBLE_LVDS = false) else tx_syncclock when (use_external_pll = "ON") else tx_pll_clk2; -- COMPONENT ASSIGNMENTS -- PLL instantiations -- MF_stratix_pll used for Stratix and Stratix GX -- MF_stratixii_pll used for Stratix II -- MF_stratixiii_pll used for Stratix III STRATIX_PLL: if ((STRATIX_TX_STYLE = true) and (implement_in_les = "OFF") and (deserialization_factor > 2)) generate u2: MF_stratix_pll -- STRATIX PLL generic map ( inclk0_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => 1, clk0_phase_shift => PHASE_INCLOCK, clk1_multiply_by => INT_CLOCK_BOOST, clk1_divide_by => 1, clk1_phase_shift => PHASE_OUTCLOCK, clk1_duty_cycle => 50, clk2_multiply_by => INT_CLOCK_BOOST, clk2_divide_by => deserialization_factor, clk2_phase_shift => PHASE_INCLOCK, family_name => intended_device_family ) port map ( inclk(0) => tx_inclock, inclk(1) => temp_zero, ena => tx_pll_enable, areset => pll_areset, clkena(5 downto 0) => temp_high, clk(0) => tx_pll_clk0, clk(1) => tx_pll_clk1, clk(2) => tx_pll_clk2, clk (5 downto 3) => temp_clk(2 downto 0), locked => tx_locked_int, enable0 => tx_pll_enable0, enable1 => tx_pll_enable1 ); end generate STRATIX_PLL; STRATIXII_PLL: if ((STRATIXII_TX_STYLE = true) and (implement_in_les = "OFF") and (use_external_pll /= "ON") and (deserialization_factor > 2)) generate u2: MF_stratixii_pll -- STRATIX II PLL generic map ( vco_multiply_by => INT_CLOCK_BOOST, vco_divide_by => 1, inclk0_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => deserialization_factor, clk0_phase_shift => STXII_PHASE_INCLOCK, clk1_multiply_by => INT_CLOCK_BOOST, clk1_divide_by => deserialization_factor, clk1_phase_shift => PHASE_OUTCLOCK, clk1_duty_cycle => 50, clk2_multiply_by => INT_CLOCK_BOOST, clk2_divide_by => deserialization_factor, clk2_phase_shift => STXII_PHASE_INCLOCK, sclkout0_phase_shift => STXII_PHASE_INCLOCK, sclkout1_phase_shift => PHASE_OUTCLOCK, family_name => intended_device_family ) port map ( inclk(0) => tx_inclock, inclk(1) => temp_zero, ena => tx_pll_enable, areset => pll_areset, clk(0) => tx_pll_clk0, clk(1) => tx_pll_clk1, clk(2) => tx_pll_clk2, clk (5 downto 3) => temp_clk(2 downto 0), locked => tx_locked_int, enable0 => tx_pll_enable0, enable1 => tx_pll_enable1, sclkout(0) => tx_pll_sclkout(0), sclkout(1) => tx_pll_sclkout(1) ); end generate STRATIXII_PLL; STRATIXIII_PLL: if ((STRATIXIII_TX_STYLE = true) and (implement_in_les = "OFF") and (use_external_pll /= "ON") and (deserialization_factor > 2)) generate U4: MF_stratixiii_pll -- Stratix III PLL generic map ( vco_multiply_by => INT_CLOCK_BOOST, vco_divide_by => 1, inclk0_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => 1, clk1_multiply_by => INT_CLOCK_BOOST, clk1_divide_by => deserialization_factor, clk1_duty_cycle => integer(real(100/deserialization_factor) + real(0.5)), clk2_multiply_by => INT_CLOCK_BOOST, clk2_divide_by => deserialization_factor, clk3_multiply_by => INT_CLOCK_BOOST, clk3_divide_by => 1, clk4_multiply_by => INT_CLOCK_BOOST, clk4_divide_by => deserialization_factor, clk4_duty_cycle => integer(real(100/deserialization_factor) + real(0.5)), clk0_phase_shift => STXII_PHASE_INCLOCK, clk1_phase_shift => CLK_ENA_PHASE_SHIFT, clk2_phase_shift => STXII_PHASE_INCLOCK, clk3_phase_shift => PHASE_OUTCLOCK, clk4_phase_shift => OUTCLK_ENA_PHASE_SHIFT, family_name => intended_device_family ) port map ( inclk(0) => tx_inclock, inclk(1) => temp_zero, areset => pll_areset, clk(0) => tx_pll_clk0, clk(1) => tx_pll_clk1, clk(2) => tx_pll_clk2, clk(3) => tx_pll_clk3, clk(4) => tx_pll_clk4, clk (9 downto 5) => temp_clk(4 downto 0), locked => tx_locked_int ); end generate STRATIXIII_PLL; FLVDS_STX_PLL: if ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIX_STYLE_PLL = true) and (CYCLONE_TX_STYLE = false) and (deserialization_factor > 2)) generate u2: MF_stratix_pll -- STRATIX PLL generic map ( pll_type => FLVDS_PLL_TYPE, inclk0_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => FLVDS_CLK0_DIV, clk0_phase_shift => PHASE_INCLOCK, clk1_multiply_by => FLVDS_CLK1_MUL, clk1_divide_by => FLVDS_CLK1_DIV, clk1_phase_shift => PHASE_OUTCLOCK, clk1_duty_cycle => 50, clk2_multiply_by => FLVDS_CLK2_MUL, clk2_divide_by => FLVDS_CLK2_DIV, clk2_phase_shift => PHASE_INCLOCK, family_name => intended_device_family ) port map ( inclk(0) => tx_inclock, inclk(1) => temp_zero, ena => tx_pll_enable, areset => pll_areset, clkena(5 downto 0) => temp_high, clk(0) => tx_pll_clk0, clk(1) => tx_pll_clk1, clk(2) => tx_pll_clk2, clk (5 downto 3) => temp_clk(2 downto 0), locked => tx_locked_int, enable0 => tx_pll_enable0, enable1 => tx_pll_enable1 ); end generate FLVDS_STX_PLL; CYC_PLL: if ((CYCLONE_TX_STYLE = true) and (deserialization_factor > 2)) generate u2: MF_stratix_pll -- Cyclone PLL generic map ( pll_type => FLVDS_PLL_TYPE, inclk0_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => FLVDS_CLK0_DIV, clk0_phase_shift => PHASE_INCLOCK, clk1_multiply_by => FLVDS_CLK1_MUL, clk1_divide_by => FLVDS_CLK1_DIV, clk1_phase_shift => PHASE_OUTCLOCK, clk1_duty_cycle => outclock_duty_cycle, clk2_multiply_by => FLVDS_CLK2_MUL, clk2_divide_by => FLVDS_CLK2_DIV, clk2_phase_shift => PHASE_INCLOCK, family_name => intended_device_family ) port map ( inclk(0) => tx_inclock, inclk(1) => temp_zero, ena => tx_pll_enable, areset => pll_areset, clkena(5 downto 0) => temp_high, clk(0) => tx_pll_clk0, clk(1) => tx_pll_clk1, clk(2) => tx_pll_clk2, clk (5 downto 3) => temp_clk(2 downto 0), locked => tx_locked_int, enable0 => tx_pll_enable0, enable1 => tx_pll_enable1 ); end generate CYC_PLL; FLVDS_STXII_PLL: if ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXII_STYLE_PLL = true) and (use_external_pll /= "ON") and (deserialization_factor > 2)) generate u2: MF_stratixii_pll -- STRATIX II PLL generic map ( pll_type => FLVDS_PLL_TYPE, vco_multiply_by => INT_CLOCK_BOOST, vco_divide_by => 1, inclk0_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => FLVDS_CLK0_DIV, clk0_phase_shift => STXII_LE_PHASE_INCLOCK, clk1_multiply_by => FLVDS_CLK1_MUL, clk1_divide_by => FLVDS_CLK1_DIV, clk1_phase_shift => STXII_LE_PHASE_OUTCLOCK, clk1_duty_cycle => 50, clk2_multiply_by => FLVDS_CLK2_MUL, clk2_divide_by => FLVDS_CLK2_DIV, clk2_phase_shift => STXII_LE_PHASE_INCLOCK, sclkout0_phase_shift => STXII_LE_PHASE_INCLOCK, sclkout1_phase_shift => STXII_LE_PHASE_OUTCLOCK, family_name => intended_device_family ) port map ( inclk(0) => tx_inclock, inclk(1) => temp_zero, ena => tx_pll_enable, areset => pll_areset, clk(0) => tx_pll_clk0, clk(1) => tx_pll_clk1, clk(2) => tx_pll_clk2, clk (5 downto 3) => temp_clk(2 downto 0), locked => tx_locked_int, enable0 => tx_pll_enable0, enable1 => tx_pll_enable1, sclkout(0) => tx_pll_sclkout(0), sclkout(1) => tx_pll_sclkout(1) ); end generate FLVDS_STXII_PLL; FLVDS_STXIII_PLL: if ((FAMILY_HAS_FLEXIBLE_LVDS = true) and (FAMILY_HAS_STRATIXIII_STYLE_PLL = true) and (use_external_pll /= "ON") and (deserialization_factor > 2)) generate U5: MF_stratixiii_pll -- Stratix III PLL generic map ( pll_type => FLVDS_PLL_TYPE, vco_multiply_by => INT_CLOCK_BOOST, vco_divide_by => 1, inclk0_input_frequency => inclock_period, clk0_multiply_by => INT_CLOCK_BOOST, clk0_divide_by => FLVDS_CLK0_DIV, clk0_phase_shift => STXIII_LE_PHASE_INCLOCK, clk1_multiply_by => FLVDS_CLK1_MUL, clk1_divide_by => FLVDS_CLK1_DIV, clk1_phase_shift => STXIII_LE_PHASE_OUTCLOCK, clk1_duty_cycle => 50, clk2_multiply_by => FLVDS_CLK2_MUL, clk2_divide_by => FLVDS_CLK2_DIV, clk2_phase_shift => STXIII_LE_PHASE_INCLOCK, family_name => intended_device_family, self_reset_on_loss_lock => alpha_tolower(pll_self_reset_on_loss_lock) ) port map ( inclk(0) => tx_inclock, inclk(1) => temp_zero, areset => pll_areset, clk(0) => tx_pll_clk0, clk(1) => tx_pll_clk1, clk(2) => tx_pll_clk2, clk (9 downto 3) => temp_clk(6 downto 0), locked => tx_locked_int ); end generate FLVDS_STXIII_PLL; STRATIX_OUTCLK : if ((STRATIX_TX_STYLE = true) and (implement_in_les = "OFF") and (deserialization_factor > 2)) generate u3: stratix_tx_outclk generic map ( deserialization_factor => deserialization_factor, bypass_serializer => BYPASS_NEEDED, invert_clock => INVERT_CLOCK_NEEDED, use_falling_clock_edge => FALLING_CLOCK_EDGE_NEEDED ) port map ( tx_in => stx_phase_shift_txdata(deserialization_factor-1 downto 0), tx_fastclk => stratix_inclock, tx_enable => stratix_enable, tx_out => stratix_outclock ); end generate STRATIX_OUTCLK; STRATIXII_OUTCLK : if (((STRATIXII_TX_STYLE = true) or (STRATIXIII_TX_STYLE = true)) and (implement_in_les = "OFF") and (deserialization_factor > 2)) generate u3: stratixii_tx_outclk generic map ( deserialization_factor => deserialization_factor, bypass_serializer => BYPASS_NEEDED, invert_clock => INVERT_CLOCK_NEEDED, use_falling_clock_edge => FALLING_CLOCK_EDGE_NEEDED ) port map ( tx_in => phase_shift_txdata(deserialization_factor-1 downto 0), tx_fastclk => stratixii_inclock, tx_enable => stratixii_enable, tx_out => stratixii_outclock ); end generate STRATIXII_OUTCLK; FLEXIBLE_LVDS_TRANSMITTER: if (((FAMILY_HAS_FLEXIBLE_LVDS = true) and (deserialization_factor > 2)) or (MAXV_TX_STYLE = true)) generate U4: flexible_lvds_tx generic map ( number_of_channels => number_of_channels, deserialization_factor => deserialization_factor, registered_input => registered_input, use_new_coreclk_ckt => USE_NEW_CORECLK_CKT, outclock_multiply_by => outclock_multiply_by, outclock_divide_by => outclock_divide_by, outclock_duty_cycle => outclock_duty_cycle, use_self_generated_outclock => USE_SELF_GENERATED_OUTCLOCK ) port map ( tx_in => tx_in, tx_fastclk => flvds_fastclk, tx_slowclk => flvds_slowclk, tx_regclk => tx_reg_clk, pll_areset => pll_areset, tx_data_reset => tx_data_reset, pll_outclock => flvds_pll_outclock, tx_locked => tx_locked_int, tx_out => flvds_dataout, tx_outclock => flvds_outclock ); end generate FLEXIBLE_LVDS_TRANSMITTER; STRATIXV_TX_LOCAL_CLK_DIVIDER: if ((STRATIXIII_TX_STYLE = true) and (enable_clock_pin_mode = "ON")) generate U6: stratixv_local_clk_divider -- Stratix V local clock divider block generic map ( clk_divide_by => deserialization_factor ) port map ( clkin => tx_fastclk, lloaden => local_clk_div_lloaden ); end generate STRATIXV_TX_LOCAL_CLK_DIVIDER; -- PROCESS DECLARATION INITIAL : process variable non_50_duty_cycle_is_valid : boolean := false; begin -- basic error checking for invalid deserialization factors if (IS_VALID_FAMILY(intended_device_family) = false) then ASSERT FALSE REPORT intended_device_family & " is not a valid device family!" SEVERITY ERROR; elsif ((STRATIX_TX_STYLE = true) and (deserialization_factor /= 1) and (deserialization_factor /= 2) and ((deserialization_factor > 10) or (deserialization_factor < 4))) then ASSERT FALSE REPORT "Stratix and Stratix GX does not support the specified deserialization factor!" SEVERITY ERROR; elsif ((STRATIXII_TX_STYLE = true) and (deserialization_factor > 10)) then ASSERT FALSE REPORT "Stratix II does not support the specified deserialization factor!" SEVERITY ERROR; elsif (FAMILY_HAS_FLEXIBLE_LVDS = true) then if ((deserialization_factor rem 2) = 1) then if ((outclock_multiply_by /= 1) and (outclock_multiply_by /= 2)) then ASSERT FALSE REPORT "Only values of 1 and 2 are allowed for outclock_multiply_by." SEVERITY ERROR; end if; if ((coreclock_divide_by /= 1) and (coreclock_divide_by /= 2)) then ASSERT FALSE REPORT "Only values of 1 and 2 are allowed for coreclock_divide_by." SEVERITY ERROR; end if; if ((coreclock_divide_by = 2) and ((deserialization_factor rem 2) = 1)) then if (CYCLONE_TX_STYLE = true) then if (outclock_multiply_by = 2) then ASSERT FALSE REPORT "The specified combination of coreclock_divide_by, outclock_multiply_by, outclock_divide_by and deserialization_factor is not supported for " & intended_device_family & ". Use the megawizard to generate a valid configuration." SEVERITY ERROR; end if; end if; end if; if (outclock_multiply_by = 2) then if (outclock_divide_by /= deserialization_factor) then ASSERT FALSE REPORT "The specified combination of coreclock_divide_by, outclock_multiply_by, outclock_divide_by and deserialization_factor is not supported for " & intended_device_family & ". Use the megawizard to generate a valid configuration." SEVERITY ERROR; end if; end if; if (CYCLONE_TX_STYLE = true) then if ((outclock_divide_by = deserialization_factor) and (outclock_multiply_by = 1)) then non_50_duty_cycle_is_valid := true; end if; else if ((outclock_divide_by = deserialization_factor) and ((outclock_multiply_by = 1) or (coreclock_divide_by = 2))) then non_50_duty_cycle_is_valid := true; end if; end if; end if; if (outclock_duty_cycle /= 50) then if (non_50_duty_cycle_is_valid = true) then if ((outclock_multiply_by = 2) and ((deserialization_factor rem 2) = 1)) then if (deserialization_factor = 7) then if (outclock_duty_cycle /= 57) then ASSERT FALSE REPORT "Illegal value of " & int_to_str(outclock_duty_cycle) & " specified for outclock_duty_cycle parameter. The legal value(s) for the specified parameter are 57." SEVERITY ERROR; end if; elsif (deserialization_factor = 9) then if (outclock_duty_cycle /= 56) then ASSERT FALSE REPORT "Illegal value of " & int_to_str(outclock_duty_cycle) & " specified for outclock_duty_cycle parameter. The legal value(s) for the specified parameter are 56." SEVERITY ERROR; end if; elsif (deserialization_factor = 5) then if (outclock_duty_cycle /= 60) then ASSERT FALSE REPORT "Illegal value of " & int_to_str(outclock_duty_cycle) & " specified for outclock_duty_cycle parameter. The legal value(s) for the specified parameter are 60." SEVERITY ERROR; end if; end if; else if (deserialization_factor = 7) then if (outclock_duty_cycle /= 57) then ASSERT FALSE REPORT "Illegal value of " & int_to_str(outclock_duty_cycle) & " specified for outclock_duty_cycle parameter. The legal value(s) for the specified parameter are 50 and 57." SEVERITY ERROR; end if; elsif (deserialization_factor = 9) then if (outclock_duty_cycle /= 56) then ASSERT FALSE REPORT "Illegal value of " & int_to_str(outclock_duty_cycle) & " specified for outclock_duty_cycle parameter. The legal value(s) for the specified parameter are 50 and 56." SEVERITY ERROR; end if; elsif (deserialization_factor = 5) then if (outclock_duty_cycle /= 60) then ASSERT FALSE REPORT "Illegal value of " & int_to_str(outclock_duty_cycle) & " specified for outclock_duty_cycle parameter. The legal value(s) for the specified parameter are 50 and 60." SEVERITY ERROR; end if; end if; end if; else ASSERT FALSE REPORT "Illegal value of " & int_to_str(outclock_duty_cycle) & " specified for outclock_duty_cycle parameter. The legal value(s) for the specified parameter are 50." SEVERITY ERROR; end if; end if; end if; -- Input data needed by stratix_tx_outclk in order to generate the tx_outclock. if (outclock_divide_by > 1) then if (deserialization_factor = 4) then if ( outclock_divide_by = 2) then stx_phase_shift_txdata(3 downto 0) <= "1010"; elsif (outclock_divide_by = 4) then stx_phase_shift_txdata(3 downto 0) <= "0011"; end if; elsif (deserialization_factor = 8) then if (outclock_divide_by = 2) then stx_phase_shift_txdata(7 downto 0) <= "10101010"; elsif (outclock_divide_by = 4) then stx_phase_shift_txdata(7 downto 0) <= "00110011"; elsif (outclock_divide_by = 8) then stx_phase_shift_txdata(7 downto 0) <= "11000011"; end if; elsif (deserialization_factor = 10) then if (outclock_divide_by = 2) then stx_phase_shift_txdata(9 downto 0) <= "1010101010"; elsif (outclock_divide_by = 10) then stx_phase_shift_txdata(9 downto 0) <= "1110000011"; end if; elsif (deserialization_factor = 7) then if (outclock_divide_by = 7) then stx_phase_shift_txdata(6 downto 0) <= "1100011"; end if; elsif (deserialization_factor = 9) then if (outclock_divide_by = 9) then stx_phase_shift_txdata(8 downto 0) <= "110000111"; end if; elsif (deserialization_factor = 5) then if (outclock_divide_by = 5) then stx_phase_shift_txdata(4 downto 0) <= "10011"; end if; end if; end if; -- Input data needed by stratixii_tx_outclk in order to generate the tx_outclock. if (outclock_divide_by > 1) then if (deserialization_factor = 4) then if ( outclock_divide_by = 2) then phase_shift_txdata(3 downto 0) <= "1010"; elsif (outclock_divide_by = 4) then phase_shift_txdata(3 downto 0) <= "1100"; end if; elsif (deserialization_factor = 6) then if ( outclock_divide_by = 2) then phase_shift_txdata(5 downto 0) <= "101010"; elsif (outclock_divide_by = 6) then phase_shift_txdata(5 downto 0) <= "111000"; end if; elsif (deserialization_factor = 8) then if (outclock_divide_by = 2) then phase_shift_txdata(7 downto 0) <= "10101010"; elsif (outclock_divide_by = 4) then phase_shift_txdata(7 downto 0) <= "11001100"; elsif (outclock_divide_by = 8) then phase_shift_txdata(7 downto 0) <= "11110000"; end if; elsif (deserialization_factor = 10) then if (outclock_divide_by = 2) then phase_shift_txdata(9 downto 0) <= "1010101010"; elsif (outclock_divide_by = 10) then phase_shift_txdata(9 downto 0) <= "1111100000"; end if; elsif (deserialization_factor = 7) then if (outclock_divide_by = 7) then phase_shift_txdata(6 downto 0) <= "1111000"; end if; elsif (deserialization_factor = 9) then if (outclock_divide_by = 9) then phase_shift_txdata(8 downto 0) <= "110000111"; end if; elsif (deserialization_factor = 5) then if (outclock_divide_by = 5) then phase_shift_txdata(4 downto 0) <= "10011"; end if; -- SPR 338253 - add support for SIII deserialization 3, outclock divide 3 mode. elsif ((deserialization_factor = 3) and (STRATIXIII_TX_STYLE = true)) then if (outclock_divide_by = 3) then phase_shift_txdata(2 downto 0) <= "101"; end if; end if; end if; wait; end process; -- INITIAL process DDIO_OUT_RECEIVE : process (tx_inclock, tx_in_int) begin if (deserialization_factor = 2) then if (tx_inclock'event and (tx_inclock = '1')) then for i in 0 to (number_of_channels-1) loop dataout_l(i) <= tx_in_int(i*2); dataout_h(i) <= tx_in_int((i*2)+1); end loop; end if; end if; end process; -- DDIO_OUT_RECEIVE process DDIO_OUT_TRANSMIT : process(tx_inclock, dataout_h, dataout_l) begin if (deserialization_factor = 2) then if (tx_inclock = '1') then for i in 0 to (number_of_channels-1) loop tx_ddio_out(i) <= dataout_h(i); end loop; else for i in 0 to (number_of_channels-1) loop tx_ddio_out(i) <= dataout_l(i); end loop; end if; end if; end process; -- DDIO_OUT_TRANSMIT process -- Registering of the load enable signal for Stratix's registers TXLOADEN: process (tx_fastclk) begin if (tx_fastclk'event and (tx_fastclk ='1')) then enable0_pipe <= enable0_reg; enable0_reg <= enable0; elsif (tx_fastclk'event and (tx_fastclk = '0')) then enable0_neg <= enable0_pipe; end if; end process; -- TXLOADEN process STRATIX_SERIALIZE : if ((implement_in_les = "OFF") and (deserialization_factor > 2)) generate -- Load and serialize the data SERIALIZE2: process(tx_fastclk, enable0_reg) variable count : integer := 0; variable sample : integer; variable shift_data : std_logic := '0'; variable tx_shift_reg : std_logic_vector(REGISTER_WIDTH -1 downto 0) := (others => '0'); begin -- Load data when registered load enable signal goes high if (((STRATIX_TX_STYLE = true) and (enable0_reg = '1') and enable0_reg'event) or (((STRATIXII_TX_STYLE = true) or (STRATIXIII_TX_STYLE = true)) and tx_fastclk'event and (tx_fastclk = '1'))) then if (registered_input /= "OFF") then tx_parallel_load_reg <= tx_in_reg; else tx_parallel_load_reg <= tx_in; end if; end if; -- Serialize the data, MSB is the first bit to be shifted out if (tx_fastclk'event and (tx_fastclk = '1')) then if (((STRATIX_TX_STYLE = true) and (enable0_neg = '1')) or (((STRATIXII_TX_STYLE = true) or (STRATIXIII_TX_STYLE = true)) and (enable0_reg = '1'))) then tx_shift_reg := tx_parallel_load_reg; count := 0; shift_data := '1'; end if; if (shift_data = '1') then count := (count rem deserialization_factor) + 1; for i in 0 to number_of_channels-1 loop tx_out_stratix(i) <= tx_shift_reg((i+1)*deserialization_factor - count); end loop; end if; end if; end process; -- SERIALIZE2 process end generate STRATIX_SERIALIZE; -- synchronization register -- registers the data_in before passing on to the parallel load register or -- holding register SYNC_REG: process(tx_reg_clk) begin if ((tx_reg_clk = '1') and tx_reg_clk'event) then tx_in_reg <= tx_in after 5 ps; end if; end process; -- SYNC_REG process process (tx_locked_int, pll_areset) begin if (pll_areset = '1') then pll_lock_sync <= '0'; elsif (tx_locked_int = '1' and tx_locked_int'event) then pll_lock_sync <= '1'; end if; end process; end behavior; --END OF ARCHITECTURE ---------------------------------------------------------------------------- -- Module Name : altdpram -- -- Description : Parameterized Dual Port RAM megafunction -- -- Limitation : This megafunction is provided only for backward -- compatibility in Cyclone, Stratix, and Stratix GX -- designs. -- -- Results expected : RAM having dual ports behaviour -- ---------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use std.textio.all; use work.ALTERA_DEVICE_FAMILIES.all; use work.ALTERA_COMMON_CONVERSION.all; -- ENTITY DECLARATION entity altdpram is generic ( width : natural; widthad : natural; numwords : natural := 0; lpm_file : string := "UNUSED"; lpm_hint : string := "USE_EAB=ON"; use_eab : string := "ON"; indata_reg : string := "INCLOCK"; indata_aclr : string := "ON"; wraddress_reg : string := "INCLOCK"; wraddress_aclr : string := "ON"; wrcontrol_reg : string := "INCLOCK"; wrcontrol_aclr : string := "ON"; rdaddress_reg : string := "OUTCLOCK"; rdaddress_aclr : string := "ON"; rdcontrol_reg : string := "OUTCLOCK"; rdcontrol_aclr : string := "ON"; outdata_reg : string := "UNREGISTERED"; outdata_aclr : string := "ON"; ram_block_type : string := "AUTO"; width_byteena : natural := 1; byte_size : natural := 0; read_during_write_mode_mixed_ports : string := "DONT_CARE"; maximum_depth : natural := 2048; intended_device_family : string := "Stratix"; lpm_type : string := "altdpram"); port ( wren : in std_logic := '0'; data : in std_logic_vector(width-1 downto 0); wraddress : in std_logic_vector(widthad-1 downto 0); wraddressstall : in std_logic := '0'; inclock : in std_logic := '1'; inclocken : in std_logic := '1'; rden : in std_logic := '1'; rdaddress : in std_logic_vector(widthad-1 downto 0); rdaddressstall : in std_logic := '0'; byteena : in std_logic_vector(width_byteena-1 downto 0) := (others => '1'); outclock : in std_logic := '1'; outclocken : in std_logic := '1'; aclr : in std_logic := '0'; q : out std_logic_vector(width-1 downto 0) ); end altdpram; -- ARCHITECTURE DECLARATION architecture behavior of altdpram is -- FUNCTION DEFINITION function get_read_during_write_mode(read_during_write : string; wrcontrol_reg : string; rdaddress_reg : string; outdata_reg : string) return string is begin if ((wrcontrol_reg = "INCLOCK") and (rdaddress_reg = "INCLOCK") and (outdata_reg = "INCLOCK")) then return read_during_write; else return "NEW_DATA"; end if; end get_read_during_write_mode; -- CONSTANT DEFINITION constant i_read_during_write : string := get_read_during_write_mode(read_during_write_mode_mixed_ports, wrcontrol_reg, rdaddress_reg, outdata_reg); -- TYPE DECLARATION type alt_memory is array((2**WIDTHAD)-1 downto 0) of std_logic_vector(WIDTH-1 downto 0); -- SIGNAL DECLARATION signal idata_tmp: std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal idata_reg: std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal idata_hi : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal idata_lo : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal ibyteena_tmp : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '1'); signal ibyteena_reg : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '1'); signal iq_tmp : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal iq_reg : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal irdaddress_tmp : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal irdaddress_reg : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal irdaddress_reg_low : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal iwraddress_tmp : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal iwraddress_reg : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal iwraddress_hi : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal iwraddress_lo : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal iwren_tmp : std_logic := '0'; signal iwren_reg : std_logic := '0'; signal iwren_hi : std_logic := '0'; signal iwren_lo : std_logic := '0'; signal irden_tmp : std_logic := '0'; signal irden_reg : std_logic := '0'; signal write_at_low_clock : boolean := false; signal rden_low_output_0 : boolean := false; signal i_byte_size : integer := 0; signal i_byteena_mask_reg_hi : std_logic_vector(width - 1 downto 0) := (others => '1'); signal i_byteena_mask_reg_out_hi : std_logic_vector(width - 1 downto 0) := (others => '1'); signal i_byteena_mask_reg_x_hi : std_logic_vector(width - 1 downto 0) := (others => '0'); signal i_byteena_mask_reg_lo : std_logic_vector(width - 1 downto 0) := (others => '1'); signal i_byteena_mask_reg_out_lo : std_logic_vector(width - 1 downto 0) := (others => '1'); signal i_byteena_mask_reg_x_lo : std_logic_vector(width - 1 downto 0) := (others => '0'); signal first_clk_rising_edge : boolean := true; begin -- PROCESS BLOCKS CHECKING: process begin if ((indata_aclr = "ON") and ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family)))) then assert false report intended_device_family & " device family does not support aclr on input data. Aclr on this port will be ignored." severity warning; end if; if ((wraddress_aclr = "ON") and ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family)))) then assert false report intended_device_family & " device family does not support aclr on write address. Aclr on this port will be ignored." severity warning; end if; if ((wrcontrol_aclr = "ON") and ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family)))) then assert false report intended_device_family & " device family does not support aclr on write control. Aclr on this port will be ignored." severity warning; end if; if ((rdcontrol_aclr = "ON") and ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family)))) then assert false report intended_device_family & "device family does not have read control (rden). Parameter rdcontrol_aclr will be ignored." severity warning; end if; if (((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family))) and (wrcontrol_reg /= "INCLOCK")) then assert false report "wrcontrol_reg can only be INCLOCK for " & intended_device_family severity warning; end if; if (((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family))) and (read_during_write_mode_mixed_ports = "OLD_DATA") and (rdaddress_aclr = "ON")) then assert false report "rdaddress_aclr cannot be turned on when it is " & intended_device_family & " with read_during_write_mode_mixed_ports = OLD_DATA" severity warning; end if; if ((((width / width_byteena) = 5) or (width / width_byteena = 10) or (width / width_byteena = 8) or (width / width_byteena = 9)) and (byte_size = 0)) and ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family))) then assert false report "byte_size (width / width_byteena) should be in 5, 8, 9 or 10. It will default to 5." severity warning; end if; wait; end process; INITIAL: process (inclock, outclock) variable init : boolean := false; begin if (not init) then if ((((lpm_hint = "USE_EAB=ON") and (use_eab /= "OFF")) or (use_eab = "ON")) ) then if (wrcontrol_reg = "INCLOCK") then if (not (FEATURE_FAMILY_STRATIXV(intended_device_family) or FEATURE_FAMILY_ARRIAV(intended_device_family) or FEATURE_FAMILY_ARRIA10(intended_device_family))) then write_at_low_clock <= true; end if; end if; end if; if ((byte_size = 0) and (width_byteena > 0)) then if (((width / width_byteena) = 5) or (width / width_byteena = 10) or (width / width_byteena = 8) or (width / width_byteena = 9)) then i_byte_size <= 5; else i_byte_size <= width / width_byteena; end if; else i_byte_size <= byte_size; end if; init := true; end if; end process; -- initial SYNC: process( data, idata_reg, rden, irden_reg, rdaddress, irdaddress_reg, wren, iwren_reg, wraddress, iwraddress_reg, iq_tmp, iq_reg, aclr, ibyteena_reg, irdaddress_reg_low) begin ibyteena_tmp <= ibyteena_reg; if (((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family))) and (rdaddress_reg = "INCLOCK") and (i_read_during_write = "OLD_DATA")) then irdaddress_tmp <= irdaddress_reg_low; elsif ((rdaddress_reg = "INCLOCK") or (rdaddress_reg = "OUTCLOCK")) then irdaddress_tmp <= irdaddress_reg; else irdaddress_tmp <= rdaddress; end if; if (((rdcontrol_reg = "INCLOCK") or (rdcontrol_reg = "OUTCLOCK")) and not ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family)))) then irden_tmp <= irden_reg; else irden_tmp <= rden; end if; if (wraddress_reg = "INCLOCK") then iwraddress_tmp <= iwraddress_reg; else iwraddress_tmp <= wraddress; end if; if (wrcontrol_reg = "INCLOCK") then iwren_tmp <= iwren_reg; else iwren_tmp <= wren; end if; if (indata_reg = "INCLOCK") then idata_tmp <= idata_reg; else idata_tmp <= data; end if; if (outdata_reg /= "UNREGISTERED") then q <= iq_reg; else q <= iq_tmp; end if; if (aclr = '1') then if( (indata_aclr = "ON") and ( indata_reg /= "UNREGISTERED") and not ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family)))) then idata_tmp <= (OTHERS => '0'); end if; if( (wraddress_aclr = "ON") and ( wraddress_reg /= "UNREGISTERED") and not ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family))))then iwraddress_tmp <= (OTHERS => '0'); end if; if( (wrcontrol_aclr = "ON") and ( wrcontrol_reg /= "UNREGISTERED") and not ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family))))then iwren_tmp <= '0'; end if; if( (rdaddress_aclr = "ON") and ( rdaddress_reg /= "UNREGISTERED") and not ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family)))and (read_during_write_mode_mixed_ports = "OLD_DATA"))then irdaddress_tmp <= (OTHERS => '0'); end if; if( (rdcontrol_aclr = "ON") and ( rdcontrol_reg /= "UNREGISTERED") and not ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family))))then irden_tmp <= '0'; end if; if( (outdata_aclr = "ON") and (outdata_reg /= "UNREGISTERED") ) then q <= (OTHERS => '0'); end if; end if; end process; -- sync SYNC2: process( idata_hi, idata_lo, iwraddress_hi, iwraddress_lo, iwren_hi, iwren_lo, write_at_low_clock, i_byteena_mask_reg_hi, i_byteena_mask_reg_lo) begin if (write_at_low_clock) then idata_reg <= idata_lo; iwren_reg <= iwren_lo; iwraddress_reg <= iwraddress_lo; ibyteena_reg <= i_byteena_mask_reg_lo; else idata_reg <= idata_hi; iwren_reg <= iwren_hi; iwraddress_reg <= iwraddress_hi; ibyteena_reg <= i_byteena_mask_reg_hi; end if; end process; -- sync2 IFG1: if (rdaddress_reg = "INCLOCK") generate process (inclock, aclr) begin if ((aclr = '1') and (rdaddress_aclr = "ON") and not ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family)))and (read_during_write_mode_mixed_ports = "OLD_DATA")) then irdaddress_reg <= (OTHERS => '0'); elsif rising_edge(inclock) then if ((inclocken = '1') and (rdaddressstall /= '1')) then irdaddress_reg <= rdaddress; end if; end if; if falling_edge(inclock) then if (inclocken = '1') then irdaddress_reg_low <= irdaddress_reg; end if; end if; end process; end generate IFG1; IFG2: if (rdcontrol_reg = "INCLOCK") generate process (inclock, aclr) begin if ((aclr = '1') and (rdcontrol_aclr = "ON")) then irden_reg <= '0'; elsif rising_edge(inclock) then if (inclocken = '1') then irden_reg <= rden; end if; end if; end process; end generate IFG2; IFG3: if (rdaddress_reg = "OUTCLOCK") generate process (outclock, aclr) begin if ((aclr = '1') and (rdaddress_aclr = "ON") and not ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family)))and (read_during_write_mode_mixed_ports = "OLD_DATA")) then irdaddress_reg <= (OTHERS => '0'); elsif rising_edge(outclock) then if ((outclocken = '1') and (rdaddressstall /= '1')) then irdaddress_reg <= rdaddress; end if; end if; end process; end generate IFG3; IFG4: if (rdcontrol_reg = "OUTCLOCK") generate process (outclock, aclr) begin if ((aclr = '1') and (rdcontrol_aclr = "ON")) then irden_reg <= '0'; elsif rising_edge(outclock) then if (outclocken = '1') then irden_reg <= rden; end if; end if; end process; end generate IFG4; REGISTERS: process (inclock, outclock, aclr) variable m_byteena_mask_reg : std_logic_vector(width - 1 downto 0); variable m_byteena_mask_reg_out : std_logic_vector(width - 1 downto 0); variable m_byteena_mask_reg_x : std_logic_vector(width - 1 downto 0):= (others => '0'); begin -- WRITE REGS -- if ((aclr = '1') and (indata_aclr = "ON") and (indata_reg /= "UNREGISTERED") ) then idata_hi <= (OTHERS => '0'); idata_lo <= (OTHERS => '0'); elsif rising_edge(inclock) then if (inclocken = '1') then idata_hi <= data; end if; elsif falling_edge(inclock) then idata_lo <= idata_hi; end if; if ((aclr = '1') and (wraddress_aclr = "ON") and (wraddress_reg /= "UNREGISTERED") ) then iwraddress_hi <= (OTHERS => '0'); iwraddress_lo <= (OTHERS => '0'); elsif rising_edge(inclock) then if ((inclocken = '1') and (wraddressstall /= '1')) then iwraddress_hi <= wraddress; end if; elsif falling_edge(inclock) then iwraddress_lo <= iwraddress_hi; end if; if ((aclr = '1') and (wrcontrol_aclr = "ON") and (wrcontrol_reg /= "UNREGISTERED") ) then iwren_hi <= '0'; iwren_lo <= '0'; elsif rising_edge(inclock) then if (inclocken = '1') then iwren_hi <= wren; end if; elsif falling_edge(inclock) then iwren_lo <= iwren_hi; end if; if rising_edge(inclock) then if (width_byteena = 1) then m_byteena_mask_reg := (others => byteena(0)); if (byteena(0) = '1') then m_byteena_mask_reg_out := (others => '0'); m_byteena_mask_reg_x := (others => '0'); elsif (byteena(0) = '0') then m_byteena_mask_reg_x := (others => '0'); m_byteena_mask_reg_out := (others => 'X'); else m_byteena_mask_reg_x := (others => 'X'); m_byteena_mask_reg_out := (others => 'X'); end if; else for k in 0 to (width - 1) loop m_byteena_mask_reg(k) := byteena(k / i_byte_size); if (m_byteena_mask_reg(k) = '1') then m_byteena_mask_reg_out(k) := '0'; m_byteena_mask_reg_x(k) := '0'; elsif (m_byteena_mask_reg(k) = '0') then m_byteena_mask_reg_x(k) := '0'; m_byteena_mask_reg_out(k) := 'X'; else m_byteena_mask_reg_out(k) := 'X'; m_byteena_mask_reg_x(k) := 'X'; end if; end loop; end if; i_byteena_mask_reg_out_hi <= m_byteena_mask_reg_out; i_byteena_mask_reg_hi <= m_byteena_mask_reg; i_byteena_mask_reg_x_hi <= m_byteena_mask_reg_x; if (inclocken = '1') then first_clk_rising_edge <= false; end if; elsif falling_edge(inclock) then i_byteena_mask_reg_out_lo <= i_byteena_mask_reg_out_hi; i_byteena_mask_reg_lo <= i_byteena_mask_reg_hi; i_byteena_mask_reg_x_lo <= i_byteena_mask_reg_x_hi; end if; -- READ REGS -- if ((aclr = '1') and (outdata_aclr = "ON") and ( outdata_reg /= "UNREGISTERED") ) then iq_reg <= (OTHERS => '0'); elsif (rising_edge(outclock) and (outdata_reg = "OUTCLOCK")) then if (outclocken = '1') then iq_reg <= iq_tmp; end if; elsif (rising_edge(inclock) and (outdata_reg = "INCLOCK")) then if (inclocken = '1') then iq_reg <= iq_tmp; end if; end if; end process; -- registers MEMORY: process(idata_tmp, iwren_tmp, irden_tmp, irdaddress_tmp, iwraddress_tmp, ibyteena_tmp, rden_low_output_0, inclocken, first_clk_rising_edge) variable mem_data : alt_memory; variable mem_data_word : std_logic_vector(width-1 downto 0); variable mem_init : boolean := false; variable i : integer := 0; variable j : integer := 0; variable k : integer := 0; variable n : integer := 0; variable m : integer := 0; variable lineno : integer := 0; variable buf : line; variable booval : boolean; FILE mem_data_file : TEXT; variable char : string(1 downto 1) := " "; variable base : string(2 downto 1); variable byte : string(2 downto 1); variable rec_type : string(2 downto 1); variable datain : string(2 downto 1); variable addr : string(2 downto 1); variable checksum : string(2 downto 1); variable startadd: string(4 downto 1); variable ibase : integer := 0; variable ibyte : integer := 0; variable istartadd : integer := 0; variable check_sum_vec : std_logic_vector(7 downto 0); variable check_sum_vec_tmp : std_logic_vector(7 downto 0); variable m_write_event : std_logic := '0'; variable m_old_data : std_logic_vector(width-1 downto 0); variable m_string : string(1 to 15); variable m_data_radix : string(1 to 3); variable m_address_radix : string(1 to 3); variable m_width : integer; variable m_depth : integer; variable m_start_address_int : integer := 0; variable m_end_address_int : integer := 0; variable m_address_int : integer := 0; variable m_data_int : std_logic_vector(width+4 downto 0) := (OTHERS => '0'); variable found_keyword_content : boolean := false; variable get_memory_content : boolean := false; variable get_start_Address : boolean := false; variable get_end_Address : boolean := false; begin -- INITIALIZE -- if NOT(mem_init) then -- INITIALIZE TO 0 -- for i in mem_data'LOW to mem_data'HIGH loop mem_data(i) := (OTHERS => '0'); end loop; if (lpm_file /= "UNUSED") then FILE_OPEN(mem_data_file, LPM_FILE, READ_MODE); if (ALPHA_TOLOWER(lpm_file(lpm_file'length -3 to lpm_file'length)) = ".hex") then WHILE NOT ENDFILE(mem_data_file) loop booval := true; READLINE(mem_data_file, buf); lineno := lineno + 1; check_sum_vec := (OTHERS => '0'); if (buf(buf'LOW) = ':') then i := 1; SHRINK_LINE(buf, i); READ(L=>buf, VALUE=>byte, good=>booval); if (not booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format!" SEVERITY ERROR; end if; ibyte := HEX_STR_TO_INT(byte); check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8)); READ(L=>buf, VALUE=>startadd, good=>booval); if (not booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; istartadd := HEX_STR_TO_INT(startadd); addr(2) := startadd(4); addr(1) := startadd(3); check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(addr), 8)); addr(2) := startadd(2); addr(1) := startadd(1); check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(addr), 8)); READ(L=>buf, VALUE=>rec_type, good=>booval); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(rec_type), 8)); else ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; case rec_type is when "00"=> -- Data record i := 0; k := (WIDTH + 7) / 8; -- # of bytes per entry while (i < ibyte) loop mem_data_word := (others => '0'); j := 1; while ( (j <= k) and (i < ibyte) ) loop READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time. if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(datain), 8)); if (WIDTH > 8) then mem_data_word := mem_data_word(WIDTH - 9 downto 0) & CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(datain), 8); else mem_data_word := CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(datain), WIDTH); end if; j := j + 1; i := i + 1; end loop; if ((ibase + istartadd) <= (2 ** widthad - 1)) then mem_data(ibase + istartadd) := mem_data_word; else ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]: Unable to initialized memory with this data record since the specified address is out of valid address range!" SEVERITY WARNING; end if; istartadd := istartadd + 1; end loop; when "01"=> exit; when "02"=> ibase := 0; if (ibyte /= 2) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format for record type 02! " SEVERITY ERROR; end if; for i in 0 to (ibyte-1) loop READ(L=>buf, VALUE=>base,good=>booval); ibase := (ibase * 256) + HEX_STR_TO_INT(base); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(base), 8)); end loop; ibase := ibase * 16; when "03"=> if (ibyte /= 4) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format for record type 03! " SEVERITY ERROR; end if; for i in 0 to (ibyte-1) loop READ(L=>buf, VALUE=>base,good=>booval); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(base), 8)); end loop; when "04"=> ibase := 0; if (ibyte /= 2) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format for record type 04! " SEVERITY ERROR; end if; for i in 0 to (ibyte-1) loop READ(L=>buf, VALUE=>base,good=>booval); ibase := (ibase * 256) + HEX_STR_TO_INT(base); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(base), 8)); end loop; ibase := ibase * 65536; when "05"=> if (ibyte /= 4) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format for record type 05! " SEVERITY ERROR; end if; for i in 0 to (ibyte-1) loop READ(L=>buf, VALUE=>base,good=>booval); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(base), 8)); end loop; when OTHERS => ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal record type in Intel Hex File! " SEVERITY ERROR; end case; READ(L=>buf, VALUE=>checksum,good=>booval); if (not booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Checksum is missing! " SEVERITY ERROR; end if; check_sum_vec := unsigned(not (check_sum_vec)) + 1 ; check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(checksum),8); if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Incorrect checksum!" SEVERITY ERROR; end if; end loop; elsif (ALPHA_TOLOWER(lpm_file(lpm_file'length -3 to lpm_file'length)) = ".mif") then -- ************************************************ -- Read in RAM initialization file (mif) -- ************************************************ while not endfile(mem_data_file) loop booval := true; readline(mem_data_file, buf); lineno := lineno + 1; LOOP2 : while (buf'length > 0) loop if (buf(buf'low) = '-') then if (buf(buf'low) = '-') then -- ignore comment started with --. exit LOOP2; end if; elsif (buf(buf'low) = '%') then i := 1; -- ignore comment which begin with % and end with another %. while ((i < buf'high) and (buf(buf'low + i) /= '%')) loop i := i+1; end loop; if (i >= buf'high) then exit LOOP2; else SHRINK_LINE(buf, i+1); end if; elsif ((buf(buf'low) = ' ') or (buf(buf'low) = HT)) then i := 1; -- ignore space or tab character. while ((i < buf'high-1) and ((buf(buf'low +i) = ' ') or (buf(buf'low+i) = HT))) loop i := i+1; end loop; if (i >= buf'high) then exit LOOP2; else SHRINK_LINE(buf, i); end if; elsif (get_memory_content = true) then if ((buf(buf'low to buf'low +2) = "end") or (buf(buf'low to buf'low +2) = "END") or (buf(buf'low to buf'low +2) = "End")) then get_memory_content := false; exit LOOP2; else get_start_address := false; get_end_address := false; m_start_address_int := 0; m_end_address_int := 0; m_address_int := 0; m_data_int := (others => '0'); if (buf(buf'low) = '[') then get_start_Address := true; SHRINK_LINE(buf, 1); end if; case m_address_radix is when "hex" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ':') and (buf(buf'low) /= '.')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *16 + HEX_STR_TO_INT(char); end loop; when "bin" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ':') and (buf(buf'low) /= '.')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *2 + BIN_STR_TO_INT(char); end loop; when "dec" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ':') and (buf(buf'low) /= '.')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *10 + INT_STR_TO_INT(char); end loop; when "uns" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ':') and (buf(buf'low) /= '.')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *10 + INT_STR_TO_INT(char); end loop; when "oct" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ':') and (buf(buf'low) /= '.')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *8 + OCT_STR_TO_INT(char); end loop; when others => assert false report "Unsupported address_radix!" severity error; end case; if (get_start_Address = true) then i := 0; -- ignore space or tab character. while ((i < buf'high-1) and ((buf(buf'low +i) = ' ') or (buf(buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(buf, i); end if; if ((buf(buf'low) = '.') and (buf(buf'low+1) = '.')) then get_start_Address := false; get_end_Address := true; m_start_address_int := m_address_int; SHRINK_LINE(buf, 2); end if; end if; if (get_end_address = true) then i := 0; -- ignore space or tab character. while ((i < buf'high-1) and ((buf(buf'low +i) = ' ') or (buf(buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(buf, i); end if; m_address_int := 0; case m_address_radix is when "hex" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ']')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *16 + HEX_STR_TO_INT(char); end loop; when "bin" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ']')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *2 + BIN_STR_TO_INT(char); end loop; when "dec" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ']')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *10 + INT_STR_TO_INT(char); end loop; when "uns" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ']')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *10 + INT_STR_TO_INT(char); end loop; when "oct" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ']')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *8 + OCT_STR_TO_INT(char); end loop; when others => assert false report "Unsupported address_radix!" severity error; end case; if (buf(buf'low) = ']') then get_end_address := false; m_end_address_int := m_address_int; SHRINK_LINE(buf, 1); end if; end if; i := 0; -- ignore space or tab character. while ((i < buf'high-1) and ((buf(buf'low +i) = ' ') or (buf(buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(buf, i); end if; if (buf(buf'low) = ':') then SHRINK_LINE(buf, 1); end if; i := 0; -- ignore space or tab character. while ((i < buf'high-1) and ((buf(buf'low +i) = ' ') or (buf(buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(buf, i); end if; case m_data_radix is when "hex" => while ((buf(buf'low) /= ';') and (buf(buf'low) /= ' ') and (buf(buf'low) /= HT)) loop read(l => buf, value => char, good => booval); m_data_int(width+4 downto 0) := m_data_int(width-1 downto 0) * "10000" + conv_std_logic_vector(HEX_STR_TO_INT(char), 4); end loop; when "bin" => while ((buf(buf'low) /= ';') and (buf(buf'low) /= ' ') and (buf(buf'low) /= HT)) loop read(l => buf, value => char, good => booval); m_data_int(width+1 downto 0) := m_data_int(width-1 downto 0) * "10" + conv_std_logic_vector(BIN_STR_TO_INT(char), 4); end loop; when "dec" => while ((buf(buf'low) /= ';') and (buf(buf'low) /= ' ') and (buf(buf'low) /= HT)) loop read(l => buf, value => char, good => booval); m_data_int(width+3 downto 0) := m_data_int(width-1 downto 0) * "1010" + conv_std_logic_vector(INT_STR_TO_INT(char), 4); end loop; when "uns" => while ((buf(buf'low) /= ';') and (buf(buf'low) /= ' ') and (buf(buf'low) /= HT)) loop read(l => buf, value => char, good => booval); m_data_int(width+3 downto 0) := m_data_int(width-1 downto 0) * "1010" + conv_std_logic_vector(INT_STR_TO_INT(char), 4); end loop; when "oct" => while ((buf(buf'low) /= ';') and (buf(buf'low) /= ' ') and (buf(buf'low) /= HT)) loop read(l => buf, value => char, good => booval); m_data_int(width+3 downto 0) := m_data_int(width-1 downto 0) * "1000" + conv_std_logic_vector(OCT_STR_TO_INT(char), 4); end loop; when others => assert false report "Unsupported data_radix!" severity error; end case; if (m_start_address_int /= m_end_address_int) then for i in m_start_address_int to m_end_address_int loop mem_data(i) := m_data_int(width-1 downto 0); end loop; else mem_data(m_address_int) := m_data_int(width-1 downto 0); end if; exit LOOP2; end if; elsif ((buf(buf'low) = 'W') or (buf(buf'low) = 'w')) then read(l=>buf, value=>m_string(1 to 5)); if (ALPHA_TOLOWER(m_string(1 to 5)) = "width") then i := 0; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; if (buf(buf'low + i) = '=') then i := i+1; end if; while ((buf(buf'low +i) = ' ') or (buf(buf'low +i) = HT)) loop i := i+1; end loop; SHRINK_LINE(buf, i); i := 0; while (buf(buf'low + i) /= ';') loop i := i+1; end loop; read(l=>buf, value=>m_string(1 to i)); m_width := INT_STR_TO_INT(m_string(1 to i)); end if; exit LOOP2; elsif (((buf(buf'low) = 'D') or (buf(buf'low) = 'd')) and ((buf(buf'low+1) = 'E') or (buf(buf'low+1) = 'e'))) then read(l=>buf, value=>m_string(1 to 5)); if (ALPHA_TOLOWER(m_string(1 to 5)) = "depth") then i := 0; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; if (buf(buf'low + i) = '=') then i := i+1; end if; while ((buf(buf'low +i) = ' ') or (buf(buf'low +i) = HT)) loop i := i+1; end loop; SHRINK_LINE(buf, i); i := 0; while (buf(buf'low + i) /= ';') loop i := i+1; end loop; read(l=>buf, value=>m_string(1 to i)); m_depth := INT_STR_TO_INT(m_string(1 to i)); end if; exit LOOP2; elsif ((buf(buf'low) = 'D') or (buf(buf'low) = 'd')) then read(l=>buf, value=>m_string(1 to 10)); if (ALPHA_TOLOWER(m_string(1 to 10)) = "data_radix") then i := 0; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; if (buf(buf'low + i) = '=') then i := i+1; end if; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; SHRINK_LINE(buf, i); i := 0; while (buf(buf'low + i) /= ';') loop i := i+1; end loop; read(l=>buf, value=>m_string(1 to 3)); m_data_radix := ALPHA_TOLOWER(m_string(1 to 3)); end if; exit LOOP2; elsif ((buf(buf'low) = 'A') or (buf(buf'low) = 'a')) then read(l=>buf, value=>m_string(1 to 13)); if (ALPHA_TOLOWER(m_string(1 to 13)) = "address_radix") then i := 0; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; if (buf(buf'low + i) = '=') then i := i+1; end if; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; SHRINK_LINE(buf, i); i := 0; while (buf(buf'low + i) /= ';') loop i := i+1; end loop; read(l=>buf, value=>m_string(1 to 3)); m_address_radix := ALPHA_TOLOWER(m_string(1 to 3)); end if; exit LOOP2; elsif ((buf(buf'low) = 'C') or (buf(buf'low) = 'c')) then read(l=>buf, value=>m_string(1 to 7)); if (ALPHA_TOLOWER(m_string(1 to 7)) = "content") then found_keyword_content := true; end if; elsif ((buf(buf'low) = 'B') or (buf(buf'low) = 'b')) then read(l=>buf, value=>m_string(1 to 5)); if (ALPHA_TOLOWER(m_string(1 to 5)) = "begin") then if (found_keyword_content = true) then get_memory_content := true; end if; end if; end if; end loop; end loop; else assert false report "Unsupported memory initialization file type (" & lpm_file(lpm_file'length -3 to lpm_file'length) & ")!" severity error; end if; -- VHDL93 FILE_CLOSE(mem_data_file); end if; mem_init := TRUE; else -- already initialized if (iwren_tmp'event or iwraddress_tmp'event or idata_tmp'event or ibyteena_tmp'event) then m_write_event := '1'; end if; -- MEMORY FUNCTION -- -- Write and read data to and from the memory. -- If write and read are at the same address, whatever wrote into -- the memory will immediately reflected at the read results. if ((iwren_tmp = '1') and (m_write_event = '1')) then if ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family))) then if (inclocken = '1') then m_old_data := mem_data (ieee.std_logic_unsigned.conv_integer(iwraddress_tmp)); mem_data (ieee.std_logic_unsigned.conv_integer(iwraddress_tmp)) := ((idata_tmp and ibyteena_tmp) or (mem_data(ieee.std_logic_unsigned.conv_integer(iwraddress_tmp)) and not ibyteena_tmp)); end if; else mem_data (ieee.std_logic_unsigned.conv_integer(iwraddress_tmp)) := idata_tmp; end if; end if; m_write_event := '0'; if (irden_tmp = '1') then if ((irdaddress_tmp = iwraddress_tmp) and (iwren_tmp = '1') and ((FEATURE_FAMILY_STRATIXV(intended_device_family)) or (FEATURE_FAMILY_STRATIXIII(intended_device_family)))) then if ((i_read_during_write = "DONT_CARE") or (i_read_during_write = "CONSTRAINED_DONT_CARE")) then iq_tmp <= (others => 'X'); elsif (i_read_during_write = "OLD_DATA") then iq_tmp <= m_old_data; else iq_tmp <= mem_data(ieee.std_logic_unsigned.conv_integer(irdaddress_tmp)); end if; elsif ((not first_clk_rising_edge) or (i_read_during_write /= "OLD_DATA")) then iq_tmp <= mem_data(ieee.std_logic_unsigned.conv_integer(irdaddress_tmp)); end if; elsif (rden_low_output_0) then iq_tmp <= (OTHERS => '0'); end if; end if; -- if NOT(mem_init) end process; -- memory end behavior; -- altdpram ---START_ENTITY_HEADER---------------------------------------------------------- -- -- Entity Name : ALTSYNCRAM -- -- Description : Synchronous ram model for Stratix series family -- -- Limitation : -- ---END_ENTITY_HEADER------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use std.textio.all; use work.ALTERA_COMMON_CONVERSION.all; use work.ALTERA_DEVICE_FAMILIES.all; -- BEGINNING OF ENTITY -- ENTITY DECLARATION entity altsyncram is -- GENERIC DECLARATION generic ( -- PORT A PARAMETERS width_a : integer := 1; widthad_a : integer := 1; numwords_a : integer := 0; outdata_reg_a : string := "UNREGISTERED"; address_aclr_a : string := "NONE"; outdata_aclr_a : string := "NONE"; indata_aclr_a : string := "NONE"; wrcontrol_aclr_a : string := "NONE"; byteena_aclr_a : string := "NONE"; width_byteena_a : integer := 1; clock_enable_input_a : string := "NORMAL"; clock_enable_output_a : string := "NORMAL"; clock_enable_core_a : string := "USE_INPUT_CLKEN"; read_during_write_mode_port_a : string := "NEW_DATA_NO_NBE_READ"; -- PORT B PARAMETERS width_b : integer := 1; widthad_b : integer := 1; numwords_b : integer := 0; rdcontrol_reg_b : string := "CLOCK1"; address_reg_b : string := "CLOCK1"; outdata_reg_b : string := "UNREGISTERED"; outdata_aclr_b : string := "NONE"; rdcontrol_aclr_b : string := "NONE"; indata_reg_b : string := "CLOCK1"; wrcontrol_wraddress_reg_b : string := "CLOCK1"; byteena_reg_b : string := "CLOCK1"; indata_aclr_b : string := "NONE"; wrcontrol_aclr_b : string := "NONE"; address_aclr_b : string := "NONE"; byteena_aclr_b : string := "NONE"; width_byteena_b : integer := 1; clock_enable_input_b : string := "NORMAL"; clock_enable_output_b : string := "NORMAL"; clock_enable_core_b : string := "USE_INPUT_CLKEN"; read_during_write_mode_port_b : string := "NEW_DATA_NO_NBE_READ"; -- ECC STATUS PARAMETERS enable_ecc : string := "FALSE"; width_eccstatus : integer := 3; ecc_pipeline_stage_enabled : string := "FALSE"; -- GLOBAL PARAMETERS operation_mode : string := "BIDIR_DUAL_PORT"; byte_size : integer := 0; read_during_write_mode_mixed_ports : string := "DONT_CARE"; ram_block_type : string := "AUTO"; init_file : string := "UNUSED"; init_file_layout : string := "UNUSED"; maximum_depth : integer := 0; intended_device_family : string := "Stratix"; power_up_uninitialized : string := "FALSE"; implement_in_les : string := "OFF"; sim_show_memory_data_in_port_b_layout : string := "OFF"; lpm_hint : string := "UNUSED"; lpm_type : string := "altsyncram" ); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION wren_a : in std_logic := '0'; -- Port A write/read enable input wren_b : in std_logic := '0'; -- Port B write enable input rden_a : in std_logic := '1'; -- Port A read enable input rden_b : in std_logic := '1'; -- Port B read enable input data_a : in std_logic_vector(width_a - 1 downto 0) := (others => '1'); -- Port A data input data_b : in std_logic_vector(width_b - 1 downto 0) := (others => '1'); -- Port B data input address_a : in std_logic_vector(widthad_a - 1 downto 0); -- Port A address input address_b : in std_logic_vector(widthad_b - 1 downto 0) := (others => '1'); -- Port B address input -- clock inputs on both ports and here are their usages: -- Port A -- 1. all input registers must be clocked by clock0. -- 2. output register can be clocked by either by clock0, clock1 or none. -- Port B -- 1. all input registers must be clocked by either clock0 or clock1. -- 2. output register can be clocked by either clock0, clock1 or none. clock0 : in std_logic := '1'; clock1 : in std_logic := 'Z'; -- clock enable inputs and here are their usages: -- clocken0 -- can only be used for enabling clock0. -- clocken1 -- can only be used for enabling clock1. -- clocken2 -- as an alternative for enabling clock0. -- clocken3 -- as an alternative for enabling clock1. clocken0 : in std_logic := '1'; clocken1 : in std_logic := '1'; clocken2 : in std_logic := '1'; clocken3 : in std_logic := '1'; -- clear inputs on both ports and here are their usages: -- Port A -- 1. all input registers can only be cleared by clear0 or none. -- 2. output register can be cleared by either clear0, clear1 or none. -- Port B -- 1. all input registers can be cleared by either clear0, clear1 or none. -- 2. output register can be cleared by either clear0, clear1 or none. aclr0 : in std_logic := '0'; aclr1 : in std_logic := '0'; addressstall_a : in std_logic := '0'; addressstall_b : in std_logic := '0'; byteena_a : in std_logic_vector( (width_byteena_a) - 1 downto 0) := (others => '1'); -- Port A byte enable input byteena_b : in std_logic_vector( (width_byteena_b) - 1 downto 0) := (others => 'Z'); -- Port B byte enable input -- OUTPUT PORT DECLARATION q_a : out std_logic_vector(width_a - 1 downto 0); -- Port A output q_b : out std_logic_vector(width_b - 1 downto 0); -- Port B output -- ECC status flag eccstatus : out std_logic_vector(width_eccstatus-1 downto 0) := (others => '0') ); -- TYPE DECLARATION type width_a_array is array (2 ** widthad_a - 1 downto 0) of std_logic_vector(width_a - 1 downto 0); type width_b_array is array (2 ** widthad_b - 1 downto 0) of std_logic_vector(width_b - 1 downto 0); -- FUNCTION DEFINITION -- This procedure read the hex file into the memory content procedure read_my_memory ( constant use_a : in boolean; variable mem_data_a : out width_a_array; variable mem_data_b : out width_b_array ) is variable m_mem_data_word_a : std_logic_vector(width_a-1 downto 0); variable m_mem_data_word_b : std_logic_vector(width_b-1 downto 0); variable i : integer := 0; variable j : integer := 0; variable m_num_of_bytes : integer := 0; variable m_line_no : integer := 0; variable m_line_buf : line ; variable m_err_check : boolean := true; variable m_base : string(2 downto 1); variable m_ibase : integer := 0; variable m_byte_str : string(2 downto 1); variable m_rec_type : string(2 downto 1); variable m_datain : string(2 downto 1); variable m_character : string(1 downto 1); variable m_addr : string(2 downto 1); variable m_checksum : string(2 downto 1); variable m_startadd : string(4 downto 1); variable m_istartadd : integer := 0; variable m_istartadd_pre : integer := 0; variable m_byte_int : integer := 0; variable m_check_sum_vec : std_logic_vector(7 downto 0); variable m_check_sum_vec_tmp : std_logic_vector(7 downto 0); variable m_string : string(1 to 15); variable m_data_radix : string(1 to 3); variable m_address_radix : string(1 to 3); variable m_width : integer; variable m_depth : integer; variable m_start_address_int : integer := 0; variable m_end_address_int : integer := 0; variable m_address_int : integer := 0; variable m_data_int : std_logic_vector(width_a+width_b+4 downto 0) := (OTHERS => '0'); variable found_keyword_content : boolean := false; variable get_memory_content : boolean := false; variable get_start_Address : boolean := false; variable get_end_Address : boolean := false; variable m_divide_factor : integer := 1; variable first_normal_record : boolean := true; variable is_word_address_format : boolean := false; file m_mem_data_file : text; begin -- Initialize memory content if (use_a) then for i in mem_data_a'low to mem_data_a'high loop mem_data_a(i) := (others => '0'); end loop; else for i in mem_data_b'low to mem_data_b'high loop mem_data_b(i) := (others => '0'); end loop; end if; file_open(m_mem_data_file, init_file, read_mode); if (ALPHA_TOLOWER(init_file(init_file'right -3 to init_file'right)) = ".hex") then while not endfile(m_mem_data_file) loop m_err_check := true; readline(m_mem_data_file, m_line_buf); m_line_no := m_line_no + 1; m_check_sum_vec := (others=> '0'); if (m_line_buf(m_line_buf'low) = ':') then i := 1; SHRINK_LINE(m_line_buf, i); read(l=>m_line_buf, value=>m_byte_str, good=>m_err_check); if not (m_err_check) then assert false report "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format!" severity error; end if; m_byte_int := HEX_STR_TO_INT(m_byte_str); m_check_sum_vec := unsigned(m_check_sum_vec) + unsigned(conv_std_logic_vector(m_byte_int, 8)); read(l=>m_line_buf, value=>m_startadd, good=>m_err_check); if not (m_err_check) then assert false report "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format! " severity error; end if; m_istartadd_pre := m_istartadd; m_istartadd := HEX_STR_TO_INT(m_startadd); m_addr(2) := m_startadd(4); m_addr(1) := m_startadd(3); m_check_sum_vec := unsigned(m_check_sum_vec) + unsigned(conv_std_logic_vector(HEX_STR_TO_INT(m_addr), 8)); m_addr(2) := m_startadd(2); m_addr(1) := m_startadd(1); m_check_sum_vec := unsigned(m_check_sum_vec) + unsigned(conv_std_logic_vector(HEX_STR_TO_INT(m_addr), 8)); read(l=>m_line_buf, value=>m_rec_type, good=>m_err_check); if not (m_err_check) then assert false report "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format! " severity error; end if; m_check_sum_vec := unsigned(m_check_sum_vec) + unsigned(conv_std_logic_vector(HEX_STR_TO_INT(m_rec_type), 8)); else assert false report "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format! " severity error; end if; case m_rec_type is when "00"=> -- Data record i := 0; if (use_a) then m_num_of_bytes := (width_a + 7) / 8; else m_num_of_bytes := (width_b + 7) / 8; end if; if ((first_normal_record = false) and (m_istartadd /= m_num_of_bytes)) then is_word_address_format := true; end if; first_normal_record := false; if ((m_istartadd = m_num_of_bytes) and (is_word_address_format = false)) then m_divide_factor := m_num_of_bytes; end if; while (i < m_byte_int) loop if (use_a) then m_mem_data_word_a := (others => '0'); else m_mem_data_word_b := (others => '0'); end if; j := 1; while ( j <= m_num_of_bytes and i < m_byte_int ) loop read(l => m_line_buf, value => m_datain, good => m_err_check); if not (m_err_check) then assert false report "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format! " severity error; end if; m_check_sum_vec := unsigned(m_check_sum_vec) + unsigned(conv_std_logic_vector(HEX_STR_TO_INT(m_datain), 8)); if (use_a) then if (width_a > 8) then m_mem_data_word_a := m_mem_data_word_a(width_a - 9 downto 0) & conv_std_logic_vector(HEX_STR_TO_INT(m_datain), 8); else m_mem_data_word_a := conv_std_logic_vector(HEX_STR_TO_INT(m_datain), width_a); end if; else if (width_b > 8) then m_mem_data_word_b := m_mem_data_word_b(width_b - 9 downto 0) & conv_std_logic_vector(HEX_STR_TO_INT(m_datain), 8); else m_mem_data_word_b := conv_std_logic_vector(HEX_STR_TO_INT(m_datain), width_b); end if; end if; j := j + 1; i := i + 1; end loop; if ((use_a) and ((m_ibase + m_istartadd) / m_divide_factor <= (2 ** widthad_a - 1)))then mem_data_a((m_ibase + m_istartadd) / m_divide_factor) := m_mem_data_word_a; elsif ((m_ibase + m_istartadd) / m_divide_factor <= (2 ** widthad_b - 1)) then mem_data_b((m_ibase + m_istartadd) / m_divide_factor) := m_mem_data_word_b; else assert false report "[Line "& INT_TO_STR_RAM(m_line_no) & "]: Unable to initialized memory with this data record since the specified address is out of valid address range!" severity warning; end if; m_istartadd := m_istartadd + 1; end loop; when "01"=> exit; when "02"=> m_ibase := 0; if (m_byte_int /= 2) then assert false report "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format for record type 02! " severity error; end if; for i in 0 to (m_byte_int-1) loop read(l=>m_line_buf, value=>m_base,good=>m_err_check); m_ibase := m_ibase * 256 + HEX_STR_TO_INT(m_base); if not (m_err_check) then assert false report "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format! " severity error; end if; m_check_sum_vec := unsigned(m_check_sum_vec) + unsigned(conv_std_logic_vector(HEX_STR_TO_INT(m_base), 8)); end loop; m_ibase := m_ibase * 16; when "03"=> if (m_byte_int /= 4) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format for record type 03! " SEVERITY ERROR; end if; for i in 0 to (m_byte_int-1) loop READ(L=>m_line_buf, VALUE=>m_base,good=>m_err_check); if not (m_err_check) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; m_check_sum_vec := unsigned(m_check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(m_base), 8)); end loop; when "04"=> m_ibase := 0; if (m_byte_int /= 2) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format for record type 04! " SEVERITY ERROR; end if; for i in 0 to (m_byte_int-1) loop READ(L=>m_line_buf, VALUE=>m_base,good=>m_err_check); m_ibase := (m_ibase * 256) + HEX_STR_TO_INT(m_base); if not (m_err_check) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; m_check_sum_vec := unsigned(m_check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(m_base), 8)); end loop; m_ibase := m_ibase * 65536; when "05"=> if (m_byte_int /= 4) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format for record type 05! " SEVERITY ERROR; end if; for i in 0 to (m_byte_int-1) loop READ(L=>m_line_buf, VALUE=>m_base,good=>m_err_check); if not (m_err_check) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; m_check_sum_vec := unsigned(m_check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(m_base), 8)); end loop; when others=> assert false report "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Illegal record type in Intel Hex File! " severity error; end case; read(l=>m_line_buf, value=>m_checksum, good=>m_err_check); if not (m_err_check) then assert false report"[Line "& INT_TO_STR_RAM(m_line_no) & "]:Checksum is missing! " severity error; end if; m_check_sum_vec := unsigned(not (m_check_sum_vec)) + 1; m_check_sum_vec_tmp := conv_std_logic_vector(HEX_STR_TO_INT(m_checksum),8); if (unsigned(m_check_sum_vec) /= unsigned(m_check_sum_vec_tmp)) then assert false report "[Line "& INT_TO_STR_RAM(m_line_no) & "]:Incorrect checksum!" severity error; end if; end loop; elsif (ALPHA_TOLOWER(init_file(init_file'length -3 to init_file'length)) = ".mif") then while not endfile(m_mem_data_file) loop m_err_check := true; readline(m_mem_data_file, m_line_buf); m_line_no := m_line_no + 1; m_check_sum_vec := (others=> '0'); LOOP2 : while (m_line_buf'length > 0) loop if (m_line_buf(m_line_buf'low) = CR) then -- strip out CR (carriage return) character. exit LOOP2; elsif (m_line_buf(m_line_buf'low) = LF) then -- strip out LF (line feed) character. exit LOOP2; elsif (m_line_buf(m_line_buf'low) = '-') then if (m_line_buf(m_line_buf'low) = '-') then -- ignore comment started with --. exit LOOP2; end if; elsif (m_line_buf(m_line_buf'low) = '%') then i := 1; -- ignore comment which begin with % and end with another %. while ((i < m_line_buf'high) and (m_line_buf(m_line_buf'low + i) /= '%')) loop i := i+1; end loop; if (i >= m_line_buf'high) then exit LOOP2; else SHRINK_LINE(m_line_buf, i+1); end if; elsif ((m_line_buf(m_line_buf'low) = ' ') or (m_line_buf(m_line_buf'low) = HT)) then i := 1; -- ignore space or tab character. while ((i < m_line_buf'high-1) and ((m_line_buf(m_line_buf'low +i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT))) loop i := i+1; end loop; if (i >= m_line_buf'high) then exit LOOP2; else SHRINK_LINE(m_line_buf, i); end if; elsif (get_memory_content = true) then if ((m_line_buf(m_line_buf'low to m_line_buf'low +2) = "end") or (m_line_buf(m_line_buf'low to m_line_buf'low +2) = "END") or (m_line_buf(m_line_buf'low to m_line_buf'low +2) = "End")) then get_memory_content := false; exit LOOP2; else get_start_address := false; get_end_address := false; m_start_address_int := 0; m_end_address_int := 0; m_address_int := 0; m_data_int := (others => '0'); if (m_line_buf(m_line_buf'low) = '[') then get_start_Address := true; SHRINK_LINE(m_line_buf, 1); end if; case m_address_radix is when "hex" => while ((m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT) and (m_line_buf(m_line_buf'low) /= ':') and (m_line_buf(m_line_buf'low) /= '.')) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_address_int := m_address_int *16 + HEX_STR_TO_INT(m_character); end loop; when "bin" => while ((m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT) and (m_line_buf(m_line_buf'low) /= ':') and (m_line_buf(m_line_buf'low) /= '.')) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_address_int := m_address_int *2 + BIN_STR_TO_INT(m_character); end loop; when "dec" => while ((m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT) and (m_line_buf(m_line_buf'low) /= ':') and (m_line_buf(m_line_buf'low) /= '.')) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_address_int := m_address_int *10 + INT_STR_TO_INT(m_character); end loop; when "uns" => while ((m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT) and (m_line_buf(m_line_buf'low) /= ':') and (m_line_buf(m_line_buf'low) /= '.')) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_address_int := m_address_int *10 + INT_STR_TO_INT(m_character); end loop; when "oct" => while ((m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT) and (m_line_buf(m_line_buf'low) /= ':') and (m_line_buf(m_line_buf'low) /= '.')) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_address_int := m_address_int *8 + OCT_STR_TO_INT(m_character); end loop; when others => assert false report "Unsupported address_radix!" severity error; end case; if (get_start_Address = true) then i := 0; -- ignore space or tab character. while ((i < m_line_buf'high-1) and ((m_line_buf(m_line_buf'low +i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(m_line_buf, i); end if; if ((m_line_buf(m_line_buf'low) = '.') and (m_line_buf(m_line_buf'low+1) = '.')) then get_start_Address := false; get_end_Address := true; m_start_address_int := m_address_int; SHRINK_LINE(m_line_buf, 2); end if; end if; if (get_end_address = true) then i := 0; -- ignore space or tab character. while ((i < m_line_buf'high-1) and ((m_line_buf(m_line_buf'low +i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(m_line_buf, i); end if; m_address_int := 0; case m_address_radix is when "hex" => while ((m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT) and (m_line_buf(m_line_buf'low) /= ']')) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_address_int := m_address_int *16 + HEX_STR_TO_INT(m_character); end loop; when "bin" => while ((m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT) and (m_line_buf(m_line_buf'low) /= ']')) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_address_int := m_address_int *2 + BIN_STR_TO_INT(m_character); end loop; when "dec" => while ((m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT) and (m_line_buf(m_line_buf'low) /= ']')) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_address_int := m_address_int *10 + INT_STR_TO_INT(m_character); end loop; when "uns" => while ((m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT) and (m_line_buf(m_line_buf'low) /= ']')) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_address_int := m_address_int *10 + INT_STR_TO_INT(m_character); end loop; when "oct" => while ((m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT) and (m_line_buf(m_line_buf'low) /= ']')) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_address_int := m_address_int *8 + OCT_STR_TO_INT(m_character); end loop; when others => assert false report "Unsupported address_radix!" severity error; end case; if (m_line_buf(m_line_buf'low) = ']') then get_end_address := false; m_end_address_int := m_address_int; SHRINK_LINE(m_line_buf, 1); end if; end if; i := 0; -- ignore space or tab character. while ((i < m_line_buf'high-1) and ((m_line_buf(m_line_buf'low +i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(m_line_buf, i); end if; if (m_line_buf(m_line_buf'low) = ':') then SHRINK_LINE(m_line_buf, 1); end if; i := 0; -- ignore space or tab character. while ((i < m_line_buf'high-1) and ((m_line_buf(m_line_buf'low +i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(m_line_buf, i); end if; case m_data_radix is when "hex" => while ((m_line_buf(m_line_buf'low) /= ';') and (m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT)) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_data_int(width_a+width_b+4 downto 0) := m_data_int(width_a+width_b-1 downto 0) * "10000" + conv_std_logic_vector(HEX_STR_TO_INT(m_character), 4); end loop; when "bin" => while ((m_line_buf(m_line_buf'low) /= ';') and (m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT)) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_data_int(width_a+width_b+1 downto 0) := m_data_int(width_a+width_b-1 downto 0) * "10" + conv_std_logic_vector(BIN_STR_TO_INT(m_character), 4); end loop; when "dec" => while ((m_line_buf(m_line_buf'low) /= ';') and (m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT)) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_data_int(width_a+width_b+3 downto 0) := m_data_int(width_a+width_b-1 downto 0) * "1010" + conv_std_logic_vector(INT_STR_TO_INT(m_character), 4); end loop; when "uns" => while ((m_line_buf(m_line_buf'low) /= ';') and (m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT)) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_data_int(width_a+width_b+3 downto 0) := m_data_int(width_a+width_b-1 downto 0) * "1010" + conv_std_logic_vector(INT_STR_TO_INT(m_character), 4); end loop; when "oct" => while ((m_line_buf(m_line_buf'low) /= ';') and (m_line_buf(m_line_buf'low) /= ' ') and (m_line_buf(m_line_buf'low) /= HT)) loop read(l => m_line_buf, value => m_character, good => m_err_check); m_data_int(width_a+width_b+3 downto 0) := m_data_int(width_a+width_b-1 downto 0) * "1000" + conv_std_logic_vector(OCT_STR_TO_INT(m_character), 4); end loop; when others => assert false report "Unsupported data_radix!" severity error; end case; if (use_a) then if (m_start_address_int /= m_end_address_int) then for i in m_start_address_int to m_end_address_int loop mem_data_a(i) := m_data_int(width_a-1 downto 0); end loop; else mem_data_a(m_address_int) := m_data_int(width_a-1 downto 0); end if; else if (m_start_address_int /= m_end_address_int) then for i in m_start_address_int to m_end_address_int loop mem_data_b(i) := m_data_int(width_b-1 downto 0); end loop; else mem_data_b(m_address_int) := m_data_int(width_b-1 downto 0); end if; end if; exit LOOP2; end if; elsif ((m_line_buf(m_line_buf'low) = 'W') or (m_line_buf(m_line_buf'low) = 'w')) then read(l=>m_line_buf, value=>m_string(1 to 5)); if (ALPHA_TOLOWER(m_string(1 to 5)) = "width") then i := 0; while ((m_line_buf(m_line_buf'low+i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT)) loop i := i+1; end loop; if (m_line_buf(m_line_buf'low + i) = '=') then i := i+1; end if; while ((m_line_buf(m_line_buf'low +i) = ' ') or (m_line_buf(m_line_buf'low +i) = HT)) loop i := i+1; end loop; SHRINK_LINE(m_line_buf, i); i := 0; while (m_line_buf(m_line_buf'low + i) /= ';') loop i := i+1; end loop; read(l=>m_line_buf, value=>m_string(1 to i)); m_width := INT_STR_TO_INT(m_string(1 to i)); end if; exit LOOP2; elsif (((m_line_buf(m_line_buf'low) = 'D') or (m_line_buf(m_line_buf'low) = 'd')) and ((m_line_buf(m_line_buf'low+1) = 'E') or (m_line_buf(m_line_buf'low+1) = 'e'))) then read(l=>m_line_buf, value=>m_string(1 to 5)); if (ALPHA_TOLOWER(m_string(1 to 5)) = "depth") then i := 0; while ((m_line_buf(m_line_buf'low+i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT)) loop i := i+1; end loop; if (m_line_buf(m_line_buf'low + i) = '=') then i := i+1; end if; while ((m_line_buf(m_line_buf'low +i) = ' ') or (m_line_buf(m_line_buf'low +i) = HT)) loop i := i+1; end loop; SHRINK_LINE(m_line_buf, i); i := 0; while (m_line_buf(m_line_buf'low + i) /= ';') loop i := i+1; end loop; read(l=>m_line_buf, value=>m_string(1 to i)); m_depth := INT_STR_TO_INT(m_string(1 to i)); end if; exit LOOP2; elsif ((m_line_buf(m_line_buf'low) = 'D') or (m_line_buf(m_line_buf'low) = 'd')) then read(l=>m_line_buf, value=>m_string(1 to 10)); if (ALPHA_TOLOWER(m_string(1 to 10)) = "data_radix") then i := 0; while ((m_line_buf(m_line_buf'low+i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT)) loop i := i+1; end loop; if (m_line_buf(m_line_buf'low + i) = '=') then i := i+1; end if; while ((m_line_buf(m_line_buf'low+i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT)) loop i := i+1; end loop; SHRINK_LINE(m_line_buf, i); i := 0; while (m_line_buf(m_line_buf'low + i) /= ';') loop i := i+1; end loop; read(l=>m_line_buf, value=>m_string(1 to 3)); m_data_radix := ALPHA_TOLOWER(m_string(1 to 3)); end if; exit LOOP2; elsif ((m_line_buf(m_line_buf'low) = 'A') or (m_line_buf(m_line_buf'low) = 'a')) then read(l=>m_line_buf, value=>m_string(1 to 13)); if (ALPHA_TOLOWER(m_string(1 to 13)) = "address_radix") then i := 0; while ((m_line_buf(m_line_buf'low+i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT)) loop i := i+1; end loop; if (m_line_buf(m_line_buf'low + i) = '=') then i := i+1; end if; while ((m_line_buf(m_line_buf'low+i) = ' ') or (m_line_buf(m_line_buf'low+i) = HT)) loop i := i+1; end loop; SHRINK_LINE(m_line_buf, i); i := 0; while (m_line_buf(m_line_buf'low + i) /= ';') loop i := i+1; end loop; read(l=>m_line_buf, value=>m_string(1 to 3)); m_address_radix := ALPHA_TOLOWER(m_string(1 to 3)); end if; exit LOOP2; elsif ((m_line_buf(m_line_buf'low) = 'C') or (m_line_buf(m_line_buf'low) = 'c')) then read(l=>m_line_buf, value=>m_string(1 to 7)); if (ALPHA_TOLOWER(m_string(1 to 7)) = "content") then found_keyword_content := true; end if; elsif ((m_line_buf(m_line_buf'low) = 'B') or (m_line_buf(m_line_buf'low) = 'b')) then read(l=>m_line_buf, value=>m_string(1 to 5)); if (ALPHA_TOLOWER(m_string(1 to 5)) = "begin") then if (found_keyword_content = true) then get_memory_content := true; end if; end if; else assert false report "MIF contains illegal character" & m_line_buf(m_line_buf'low) severity error; end if; end loop; end loop; else assert false report "Unsupported memory initialization file type (" & init_file(init_file'length -3 to init_file'length) & ")!" severity error; end if; file_close(m_mem_data_file); end read_my_memory; end altsyncram; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE architecture translated of altsyncram is function is_lutram (ram_block_type : string) return boolean is begin if ((ram_block_type = "LUTRAM") or (ram_block_type = "MLAB")) then return true; else return false; end if; end is_lutram; function get_write_mode(read_during_write_mode_mixed_ports : string; device : string) return string is begin if (FEATURE_FAMILY_CYCLONE(device) or FEATURE_FAMILY_CYCLONEII(device)) then return "OLD_DATA"; elsif (read_during_write_mode_mixed_ports = "UNUSED") or (read_during_write_mode_mixed_ports = "DONT_CARE") then return "DONT_CARE"; end if; return read_during_write_mode_mixed_ports; end get_write_mode; function get_read_operation(operation_mode : string; port_name : string) return boolean is begin if (port_name = "A") then if ((operation_mode = "BIDIR_DUAL_PORT") or (operation_mode = "SINGLE_PORT") or (operation_mode= "ROM")) then return true; else return false; end if; else if ((operation_mode = "BIDIR_DUAL_PORT") or (operation_mode = "DUAL_PORT")) then return true; else return false; end if; end if; end get_read_operation; function get_write_operation(operation_mode : string; port_name : string) return boolean is begin if (port_name = "A") then if ((operation_mode = "BIDIR_DUAL_PORT") or (operation_mode = "SINGLE_PORT") or (operation_mode= "DUAL_PORT")) then return true; else return false; end if; else if (operation_mode = "BIDIR_DUAL_PORT") then return true; else return false; end if; end if; end get_write_operation; function check_simultaneous(operation_mode : string; ram_type : string; cread : string) return boolean is begin if (operation_mode = "BIDIR_DUAL_PORT") then if ((ram_type = "MEGARAM") or (ram_type = "M-RAM") or ((cread = "DONT_CARE") and (ram_type = "AUTO")) or ((cread = "NEW_DATA") and (is_lutram(ram_type)))) then return true; else return false; end if; else return false; end if; end check_simultaneous; function get_ram_block_type (intended_device_family : string; ram_block_type : string) return string is begin if (FEATURE_FAMILY_HAS_STRATIXV_STYLE_RAM(intended_device_family)) then if ((((ram_block_type = "M10K") or (is_lutram(ram_block_type))) and FEATURE_FAMILY_ARRIAV(intended_device_family)) or (((ram_block_type = "M20K") or (is_lutram(ram_block_type))) and (FEATURE_FAMILY_STRATIXV(intended_device_family) or FEATURE_FAMILY_ARRIA10(intended_device_family))) ) then return ram_block_type; else return "AUTO"; end if; elsif (FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM(intended_device_family)) then if (((ram_block_type = "M-RAM") or (ram_block_type = "MEGARAM")) and FEATURE_FAMILY_STRATIXIII(intended_device_family)) then return "M144K"; elsif ((((ram_block_type = "M144K") or (is_lutram(ram_block_type))) and FEATURE_FAMILY_STRATIXIII(intended_device_family)) or (ram_block_type = "M9K")) then return ram_block_type; else return "AUTO"; end if; else if ((ram_block_type /= "AUTO") and (ram_block_type /= "M-RAM") and (ram_block_type /= "MEGARAM") and (ram_block_type /= "M512") and (ram_block_type /= "M4K")) then return "AUTO"; else return ram_block_type; end if; end if; end get_ram_block_type; function get_byte_size (byte_size : integer; width_byteena_a : integer; width_a : integer; device_family : string) return integer is variable temp : integer; begin if ((byte_size = 0) and (width_byteena_a > 1)) then temp := width_a / width_byteena_a; if (((FEATURE_FAMILY_STRATIX(device_family) or FEATURE_FAMILY_STRATIXV(device_family)) and (temp /= 8) and (temp /= 9)) or ((FEATURE_FAMILY_BASE_STRATIXII(device_family) or FEATURE_FAMILY_BASE_CYCLONEII(device_family)) and (temp /= 1) and (temp /= 2) and (temp /= 4)) or ((FEATURE_FAMILY_STRATIXIII(device_family) or FEATURE_FAMILY_STRATIXV(device_family)) and (temp /= 5) and (temp /= 10))) then return 8; else return temp; end if; elsif (byte_size = 0) then return 8; else return byte_size; end if; end get_byte_size; function get_write_edge (ram_block_type : string; device_family : string) return boolean is begin if ((ram_block_type = "M-RAM") or (ram_block_type = "MEGARAM") or (ram_block_type = "M9K") or (ram_block_type = "M144K") or ((FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM(device_family) and (ram_block_type = "AUTO")))) then return true; elsif ((ram_block_type = "M20K") or (ram_block_type = "M10K") or (FEATURE_FAMILY_HAS_STRATIXV_STYLE_RAM(device_family) and (is_lutram(ram_block_type) or (ram_block_type = "AUTO")))) then return true; else return false; end if; end get_write_edge; function get_numwords(numwords : integer; widthad : integer) return integer is begin if (numwords /= 0) then return numwords; else return (2 ** widthad); end if; end get_numwords; function is_lutram_single_port_fast_read(ram_block_type : string; read_during_write : string; operation_mode : string) return boolean is begin if ((is_lutram(ram_block_type)) and ((read_during_write = "DONT_CARE") or ((outdata_reg_a = "UNREGISTERED") AND (operation_mode = "SINGLE_PORT")))) then return true; else return false; end if; end is_lutram_single_port_fast_read; function is_lutram_dual_port_fast_read (ram_block_type : string; read_during_write_mixed_ports : string; address_reg_b : string; operation_mode : string) return boolean is begin if ((is_lutram(ram_block_type)) and (operation_mode = "DUAL_PORT") and ((read_during_write_mixed_ports = "NEW_DATA") or (read_during_write_mixed_ports = "DONT_CARE") or (read_during_write_mixed_ports = "CONSTRAINED_DONT_CARE") or ((read_during_write_mixed_ports = "OLD_DATA") and (outdata_reg_b = "UNREGISTERED")))) then return true; else return false; end if; end is_lutram_dual_port_fast_read; function get_rden_reg_initial_value(device : string) return std_logic is begin if (FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM(intended_device_family)) then return '0'; else return '1'; end if; end get_rden_reg_initial_value; function get_byteena_reg_initial_value(device : string) return std_logic is begin if (FEATURE_FAMILY_HAS_STRATIXV_STYLE_RAM(intended_device_family)) then return '0'; else return '1'; end if; end get_byteena_reg_initial_value; -- CONSTANT DECLARATION constant IS_STRATIXV : boolean := FEATURE_FAMILY_STRATIXV(intended_device_family); constant IS_STRATIXIII : boolean := FEATURE_FAMILY_STRATIXIII(intended_device_family); constant IS_HARDCOPYII : boolean := FEATURE_FAMILY_HARDCOPYII(intended_device_family); constant IS_HARDCOPYIII : boolean := FEATURE_FAMILY_HARDCOPYIII(intended_device_family); constant IS_HARDCOPYIV : boolean := FEATURE_FAMILY_HARDCOPYIV(intended_device_family); constant IS_CYCLONEIII : boolean := FEATURE_FAMILY_CYCLONEIII(intended_device_family); constant IS_BASE_STRATIXIII : boolean := FEATURE_FAMILY_BASE_STRATIXIII(intended_device_family); constant IS_BASE_STRATIXII : boolean := FEATURE_FAMILY_BASE_STRATIXII(intended_device_family); constant IS_BASE_CYCLONEII : boolean := FEATURE_FAMILY_BASE_CYCLONEII(intended_device_family); constant HAS_STRATIXI_STYLE_RAM : boolean := FEATURE_FAMILY_HAS_STRATIXI_STYLE_RAM(intended_device_family); constant HAS_STRATIXII_STYLE_RAM : boolean := FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM(intended_device_family); constant HAS_STRATIXIII_STYLE_RAM : boolean := FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM(intended_device_family); constant HAS_STRATIXV_STYLE_RAM : boolean := FEATURE_FAMILY_HAS_STRATIXV_STYLE_RAM(intended_device_family); constant HAS_LUTRAM : boolean := FEATURE_FAMILY_HAS_LUTRAM(intended_device_family); constant HAS_M512 : boolean := FEATURE_FAMILY_HAS_M512(intended_device_family); constant HAS_MEGARAM : boolean := FEATURE_FAMILY_HAS_MEGARAM(intended_device_family); constant i_is_lutram : boolean := is_lutram(ram_block_type); constant i_ram_block_type : string := get_ram_block_type(intended_device_family, ram_block_type); constant cread_during_write_mode_mixed_ports : string := get_write_mode(read_during_write_mode_mixed_ports, intended_device_family); constant read_operation_a : boolean := get_read_operation(operation_mode, "A"); constant write_operation_a : boolean := get_write_operation(operation_mode, "A"); constant read_operation_b : boolean := get_read_operation(operation_mode, "B"); constant write_operation_b : boolean := get_write_operation(operation_mode, "B"); constant check_simultaneous_read_write : boolean := check_simultaneous(operation_mode, ram_block_type, cread_during_write_mode_mixed_ports); constant i_byte_size : integer := get_byte_size(byte_size, width_byteena_a, width_a, intended_device_family); constant is_write_positive_edge : boolean := get_write_edge(i_ram_block_type, intended_device_family); constant i_numwords_a : integer := get_numwords(numwords_a, widthad_a); constant i_numwords_b : integer := get_numwords(numwords_b, widthad_b); constant i_lutram_single_port_fast_read : boolean := is_lutram_single_port_fast_read(ram_block_type, read_during_write_mode_port_a, operation_mode); constant i_lutram_dual_port_fast_read : boolean := is_lutram_dual_port_fast_read(ram_block_type, read_during_write_mode_mixed_ports, address_reg_b, operation_mode); constant rden_reg_initial_value : std_logic := get_rden_reg_initial_value(intended_device_family); constant byteena_reg_initial_value : std_logic := get_byteena_reg_initial_value(intended_device_family); constant enable_mem_data_b_reading : boolean := (sim_show_memory_data_in_port_b_layout = "ON") and ((operation_mode = "BIDIR_DUAL_PORT") or (operation_mode = "DUAL_PORT")); constant all_z : std_logic_vector(width_byteena_b-1 downto 0) := (others => 'Z'); -- SIGNAL DECLARATION signal i_data_reg_a : std_logic_vector(width_a - 1 downto 0) := (others => '0'); signal i_data_reg_b : std_logic_vector(width_b - 1 downto 0) := (others => '0'); signal i_q_reg_a : std_logic_vector(width_a - 1 downto 0) := (others => '0'); signal i_q_tmp_a : std_logic_vector(width_a - 1 downto 0) := (others => '0'); signal i_q_tmp2_a : std_logic_vector(width_a - 1 downto 0) := (others => '0'); signal i_q_tmp_wren_a : std_logic_vector(width_a - 1 downto 0) := (others => '0'); signal i_q_tmp2_wren_a : std_logic_vector(width_a - 1 downto 0) := (others => '0'); signal i_q_tmp_wren_b : std_logic_vector(width_b - 1 downto 0) := (others => '0'); signal i_q_reg_b : std_logic_vector(width_b - 1 downto 0) := (others => '0'); signal i_q_tmp_b : std_logic_vector(width_b - 1 downto 0) := (others => '0'); signal i_q_tmp2_b : std_logic_vector(width_b - 1 downto 0) := (others => '0'); signal i_q_output_latch : std_logic_vector(width_b - 1 downto 0) := (others => '0'); signal i_q_ecc_reg_b : std_logic_vector(width_b - 1 downto 0) := (others => '0'); signal i_q_ecc_tmp_b : std_logic_vector(width_b - 1 downto 0) := (others => '0'); signal i_current_written_data_a : std_logic_vector(width_a - 1 downto 0) := (others => '0'); signal i_original_data_a : std_logic_vector(width_a - 1 downto 0) := (others => '0'); signal i_original_data_b : std_logic_vector(width_b - 1 downto 0) := (others => '0'); signal i_byteena_mask_reg_a_x : std_logic_vector(width_a - 1 downto 0) := (others => '0'); signal i_byteena_mask_reg_b_x : std_logic_vector(width_b - 1 downto 0) := (others => '0'); signal i_byteena_mask_reg_a : std_logic_vector(width_a - 1 downto 0) := (others => byteena_reg_initial_value); signal i_byteena_mask_reg_b : std_logic_vector(width_b - 1 downto 0) := (others => byteena_reg_initial_value); signal i_byteena_mask_reg_a_out : std_logic_vector(width_a - 1 downto 0) := (others => byteena_reg_initial_value); signal i_byteena_mask_reg_b_out : std_logic_vector(width_b - 1 downto 0) := (others => byteena_reg_initial_value); signal i_byteena_mask_reg_a_out_b : std_logic_vector(width_a - 1 downto 0) := (others => byteena_reg_initial_value); signal i_byteena_mask_reg_b_out_a : std_logic_vector(width_b - 1 downto 0) := (others => byteena_reg_initial_value); signal i_address_reg_a : std_logic_vector(widthad_a - 1 downto 0) := (others => '0'); signal i_address_reg_b : std_logic_vector(widthad_b - 1 downto 0) := (others => '0'); signal i_wren_reg_a : std_logic := '0'; signal i_wren_reg_b : std_logic := '0'; signal i_rden_reg_a : std_logic := rden_reg_initial_value; signal i_rden_reg_b : std_logic := rden_reg_initial_value; signal i_read_flag_a : std_logic := '0'; signal i_read_flag_b : std_logic := '0'; signal i_reread_flag_a : std_logic := '0'; signal i_reread_flag_b : std_logic := '0'; signal i_reread_flag2_a : std_logic := '0'; signal i_reread_flag2_b : std_logic := '0'; signal i_write_flag_a : std_logic := '0'; signal i_write_flag_b : std_logic := '0'; signal i_nmram_write_a : std_logic := '0'; signal i_nmram_write_b : std_logic := '0'; signal i_indata_aclr_a : std_logic := '0'; signal i_address_aclr_a : std_logic := '0'; signal i_wrcontrol_aclr_a : std_logic := '0'; signal i_indata_aclr_b : std_logic := '0'; signal i_address_aclr_b : std_logic := '0'; signal i_wrcontrol_aclr_b : std_logic := '0'; signal i_outdata_aclr_a : std_logic := '0'; signal i_outdata_aclr_b : std_logic := '0'; signal i_rdcontrol_aclr_b : std_logic := '0'; signal i_byteena_aclr_a : std_logic := '0'; signal i_byteena_aclr_b : std_logic := '0'; signal good_to_go_a : std_logic := '0'; signal good_to_go_b : std_logic := '0'; signal i_core_clocken_a : std_logic := '1'; signal i_core_clocken_b : std_logic := '1'; signal i_core_clocken_b0 : std_logic := '1'; signal i_core_clocken_b1 : std_logic := '1'; signal i_inclocken0 : std_logic := '0'; signal i_input_clocken_b : std_logic := '0'; signal i_outdata_clken_b : std_logic := '0'; signal i_outdata_clken_a : std_logic := '0'; signal i_outlatch_clken_a : std_logic := '1'; signal i_outlatch_clken_b : std_logic := '1'; signal i_core_clocken_a_reg : std_logic := '0'; signal i_core_clocken_b_reg : std_logic := '0'; signal default_val : std_logic := '0'; signal i_data_zero_a : std_logic_vector (width_a - 1 downto 0) := (others => '0'); signal i_data_zero_b : std_logic_vector (width_b - 1 downto 0) := (others => '0'); signal i_data_ones_a : std_logic_vector (width_a - 1 downto 0) := (others => '1'); signal i_data_ones_b : std_logic_vector (width_b - 1 downto 0) := (others => '1'); signal same_clock_pulse0 : std_logic := '0'; signal same_clock_pulse1 : std_logic := '0'; signal i_force_reread_a : std_logic := '0'; signal i_force_reread_a1 : std_logic := '0'; signal i_force_reread_b : std_logic := '0'; signal i_force_reread_b1 : std_logic := '0'; signal i_force_reread_signal_a : std_logic := '0'; signal i_force_reread_signal_b : std_logic := '0'; signal i_good_to_write_a : std_logic := '1'; signal i_good_to_write_b : std_logic := '1'; begin -- Parameter Checking process begin if ((operation_mode /= "BIDIR_DUAL_PORT") and (operation_mode /= "SINGLE_PORT") and (operation_mode /= "DUAL_PORT") and (operation_mode /= "ROM")) then assert false report "Error: Not a valid operation mode." severity error; end if; if ((ram_block_type /= "M4K") and (ram_block_type /= "M512") and (ram_block_type /= "LARGE") and (ram_block_type /= "MEGARAM") and (ram_block_type /= "M-RAM") and (ram_block_type /= "AUTO") and (ram_block_type /= "M9K") and (ram_block_type /= "M144K") and (ram_block_type /= "M20K") and (ram_block_type /= "M10K") and (not i_is_lutram)) then assert false report "Error: RAM_BLOCK_TYPE has an invalid value." severity error; end if; if (ram_block_type /= i_ram_block_type) then assert false report "Warning: RAM block type is assumed as " & i_ram_block_type severity warning; end if; if ((cread_during_write_mode_mixed_ports /= "DONT_CARE") and (cread_during_write_mode_mixed_ports /= "CONSTRAINED_DONT_CARE") and (cread_during_write_mode_mixed_ports /= "OLD_DATA") and (cread_during_write_mode_mixed_ports /= "NEW_DATA")) then assert false report "Error: Invalid value for READ_DURING_WRITE_MODE_MIXED_PORTS parameter. It has to be OLD_DATA or DONT_CARE or CONSTRAINED_DONT_CARE or NEW_DATA" severity error; end if; if ((read_during_write_mode_mixed_ports /= cread_during_write_mode_mixed_ports) and ((operation_mode /= "SINGLE_PORT") and (operation_mode /= "ROM"))) then assert false report "Warning: READ_DURING_WRITE_MODE_MIXED_PORTS is assumed as " & cread_during_write_mode_mixed_ports severity warning; end if; if (((i_ram_block_type = "M-RAM") or (i_ram_block_type = "MEGARAM")) and (init_file /= "UNUSED")) then assert false report "Error: M-RAM block type doesn't support the use of an initialization file" severity error; end if; if ((i_byte_size /= 8) and (i_byte_size /= 9) and (HAS_STRATIXI_STYLE_RAM)) then assert false report "Error: BYTE_SIZE has to be either 8 or 9" severity error; end if; if ((i_byte_size /= 8) and (i_byte_size /= 9) and (i_byte_size /= 1) and (i_byte_size /= 2) and (i_byte_size /= 4) and (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)) then assert false report "Error: BYTE_SIZE has to be either 1, 2, 4, 8 or 9" severity error; end if; if ((i_byte_size /= 8) and (i_byte_size /= 9) and (i_byte_size /= 5) and (i_byte_size /= 10) and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) then assert false report "Error: BYTE_SIZE has to be either 5, 8, 9 or 10" severity error; end if; if (width_a <= 0) then assert false report "Error: Invalid value for WIDTH_A parameter" severity error; end if; if ((width_b <= 0) and ((operation_mode /= "SINGLE_PORT") and (operation_mode /= "ROM"))) then assert false report "Error: Invalid value for WIDTH_B parameter" severity error; end if; if (widthad_a <= 0) then assert false report "Error: Invalid value for WIDTHAD_A parameter" severity error; end if; if ((widthad_b <= 0) and ((operation_mode /= "SINGLE_PORT") and (operation_mode /= "ROM"))) then assert false report "Error: Invalid value for WIDTHAD_B parameter" severity error; end if; if ((operation_mode = "ROM") and ((i_ram_block_type = "M-RAM") or (i_ram_block_type = "MEGARAM"))) then assert false report "Error: ROM mode does not support ram_block_type = M-RAM" severity error; end if; if ((IS_BASE_STRATIXII or IS_BASE_CYCLONEII) and (((indata_aclr_a /= "UNUSED") and (indata_aclr_a /= "NONE")) or ((wrcontrol_aclr_a /= "UNUSED") and (wrcontrol_aclr_a /= "NONE")) or ((byteena_aclr_a /= "UNUSED") and (byteena_aclr_a /= "NONE")) or ((address_aclr_a /= "UNUSED") and (address_aclr_a /= "NONE")) or ((indata_aclr_b /= "UNUSED") and (indata_aclr_b /= "NONE")) or ((rdcontrol_aclr_b /= "UNUSED") and (rdcontrol_aclr_b /= "NONE")) or ((wrcontrol_aclr_b /= "UNUSED") and (wrcontrol_aclr_b /= "NONE")) or ((byteena_aclr_b /= "UNUSED") and (byteena_aclr_b /= "NONE")) or ((address_aclr_b /= "UNUSED") and (address_aclr_b /= "NONE")))) then assert false report "Warning: " & intended_device_family & " device family does not support aclr signal on input ports. The aclr to input ports will be ignored." severity warning; end if; if ((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM) and (read_during_write_mode_port_a /= "NEW_DATA_NO_NBE_READ")) then assert false report "Warning: " & read_during_write_mode_port_a & " value for read_during_write_mode_port_a is not supported in " & intended_device_family & " device family, it might cause incorrect behavioural simulation result" severity warning; end if; if ((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM) and (read_during_write_mode_port_b /= "NEW_DATA_NO_NBE_READ")) then assert false report "Warning: " & read_during_write_mode_port_b & " value for read_during_write_mode_port_b is not supported in " & intended_device_family & " device family, it might cause incorrect behavioural simulation result" severity warning; end if; -- SPR 249576: Enable don't care as RDW setting in MegaFunctions - eliminates checking for ram_block_type = "AUTO" if (not (i_is_lutram or ((i_ram_block_type = "AUTO") and (HAS_LUTRAM)) or ((i_ram_block_type /= "AUTO") and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)))) and (operation_mode /= "SINGLE_PORT") and (read_during_write_mode_port_a = "DONT_CARE")) then assert false report "Error: " & read_during_write_mode_port_a & " value for read_during_write_mode_port_a is not supported in " & intended_device_family & " device family for " & ram_block_type & " ram block type in " & operation_mode & " operation mode" severity error; end if; if ((not i_is_lutram) and (cread_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE")) then assert false report "Warning : read_during_write_mode_mixed_ports cannot be set to CONSTRAINED_DONT_CARE for non-LUTRAM ram block type. This will cause incorrect simulation result." severity warning; end if; if ((not i_is_lutram) and (cread_during_write_mode_mixed_ports = "NEW_DATA")) then assert false report "Warning : read_during_write_mode_mixed_ports cannot be set to NEW_DATA for non-LUTRAM ram block type. This will cause incorrect simulation result." severity warning; end if; if ((operation_mode = "DUAL_PORT") and (outdata_reg_b /= "CLOCK0") and (i_is_lutram) and (cread_during_write_mode_mixed_ports = "OLD_DATA")) then assert false report "Warning: Value for read_during_write_mode_mixed_ports is not honoured in " & operation_mode & " operation mode when output registers are not clocked by clock0 for ram_block_type LUTRAM" severity warning; end if; if ((i_is_lutram) and (operation_mode = "BIDIR_DUAL_PORT")) then assert false report "Error: LUTRAM RAM block type does not support BIDIR_DUAL_PORT operation mode" severity error; end if; if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (indata_aclr_a /= "NONE") and (indata_aclr_a /= "UNUSED")) then assert false report "Warning : " & indata_aclr_a & "value for indata_aclr_a is not supported in " & intended_device_family & " device family. The aclr to data_a registers will be ignored." severity warning; end if; if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (wrcontrol_aclr_a /= "NONE") and (wrcontrol_aclr_a /= "UNUSED")) then assert false report "Warning : " & wrcontrol_aclr_a & " value for wrcontrol_aclr_a is not supported in " & intended_device_family & " device family. The aclr to data_a registers will be ignored." severity warning; end if; if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (byteena_aclr_a /= "NONE") and (byteena_aclr_a /= "UNUSED")) then assert false report "Warning : " & byteena_aclr_a & " value for byteena_aclr_a is not supported in " & intended_device_family & " device family. The aclr to data_a registers will be ignored." severity warning; end if; if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (address_aclr_a /= "NONE") and (address_aclr_a /= "UNUSED") and (operation_mode /= "ROM")) then assert false report "Warning : " & address_aclr_a & " value for address_aclr_a is not supported for write port in " & intended_device_family & " device family. The aclr to data_a registers will be ignored." severity warning; end if; if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (indata_aclr_b /= "NONE") and (indata_aclr_b /= "UNUSED")) then assert false report "Warning : " & indata_aclr_b & " value for indata_aclr_b is not supported in " & intended_device_family & " device family. The aclr to data_a registers will be ignored." severity warning; end if; if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (rdcontrol_aclr_b /= "NONE") and (rdcontrol_aclr_b /= "UNUSED")) then assert false report "Warning : " & rdcontrol_aclr_b & " value for rdcontrol_aclr_b is not supported in " & intended_device_family & " device family. The aclr to data_a registers will be ignored." severity warning; end if; if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (wrcontrol_aclr_b /= "NONE") and (wrcontrol_aclr_b /= "UNUSED")) then assert false report "Warning : " & wrcontrol_aclr_b & " value for wrcontrol_aclr_b is not supported in " & intended_device_family & " device family. The aclr to data_a registers will be ignored." severity warning; end if; if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (byteena_aclr_b /= "NONE") and (byteena_aclr_b /= "UNUSED")) then assert false report "Warning : " & byteena_aclr_b & " value for byteena_aclr_b is not supported in " & intended_device_family & " device family. The aclr to data_a registers will be ignored." severity warning; end if; if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (address_aclr_b /= "NONE") and (address_aclr_b /= "UNUSED") and (operation_mode = "BIDIR_DUAL_PORT")) then assert false report "Warning : " & address_aclr_b & " value for address_aclr_b is not supported for write port in " & intended_device_family & " device family. The aclr to data_a registers will be ignored." severity warning; end if; if ((i_is_lutram) and (address_aclr_b /= "NONE") and (address_aclr_b /= "UNUSED") and (operation_mode = "DUAL_PORT") and (cread_during_write_mode_mixed_ports = "OLD_DATA")) then assert false report "Warning : aclr signal for address_b is ignored for RAM block type " & ram_block_type & " when read_during_write_mode_mixed_ports is set to OLD_DATA" severity warning; end if; if (((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)) and ((clock_enable_core_a /= "USE_INPUT_CLKEN") and (clock_enable_core_a /= clock_enable_input_a))) then assert false report "Warning: clock_enable_core_a value must be 'USE_INPUT_CLKEN' or same as clock_enable_input_a in " & intended_device_family & " device family. It will be set to follow clock_enable_input_a value." severity warning; end if; if (((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)) and ((clock_enable_core_b /= "USE_INPUT_CLKEN") and (clock_enable_core_b /= clock_enable_input_b))) then assert false report "Warning: clock_enable_core_b value must be 'USE_INPUT_CLKEN' or same as clock_enable_input_b in " & intended_device_family & " device family. It will be set to follow clock_enable_input_b value." severity warning; end if; if ((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM) and (clock_enable_input_a = "ALTERNATE")) then assert false report "Error: ALTERNATE value for clock_enable_input_a is not supported in " & intended_device_family severity error; end if; if ((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM) and (clock_enable_input_b = "ALTERNATE")) then assert false report "Error: ALTERNATE value for clock_enable_input_b is not supported in " & intended_device_family severity error; end if; if ((enable_ecc = "TRUE") and (((i_ram_block_type /= "M20K") and (i_ram_block_type /= "M144K")) or (operation_mode /= "DUAL_PORT"))) then assert false report "Error: " & enable_ecc & " value for enable_ecc is not supported in " & ram_block_type & " ram block type for " & intended_device_family & " device family in " & operation_mode & " operation mode." severity error; end if; if ((i_ram_block_type /= "M20K") and (ecc_pipeline_stage_enabled = "TRUE")) then assert false report "Error: " & ecc_pipeline_stage_enabled & " value for ecc_pipeline_stage_enabled is not supported in " & ram_block_type & " ram block type." severity error; end if; if ((outdata_reg_b = "UNREGISTERED") and (ecc_pipeline_stage_enabled = "TRUE")) then assert false report "Error: " & ecc_pipeline_stage_enabled & " is not supported when output_reg_b is set to " & outdata_reg_b & " ." severity error; end if; --Setting this to only warning because in synthesis it will ignore the ecc_pipeline_stage_enabled parameter when enable_ecc is set to false if ((ecc_pipeline_stage_enabled = "TRUE") and (enable_ecc /= "TRUE")) then assert false report "Warning: " & ecc_pipeline_stage_enabled & " value for ecc_pipeline_stage_enabled is not supported when enable_ecc is set to " & enable_ecc & " ." severity warning; end if; if ((cread_during_write_mode_mixed_ports = "OLD_DATA") and (enable_ecc = "TRUE") and ((i_ram_block_type = "M20K") or (i_ram_block_type = "M144K"))) then assert false report "Error : ECC is not supported for read-before-write mode." severity error; end if; if (((wrcontrol_aclr_a /= "NONE") and (wrcontrol_aclr_a /= "UNUSED")) and (i_ram_block_type = "M512") and (operation_mode = "SINGLE_PORT")) then assert false report "Error: Wren_a cannot have clear in single port mode for M512 block" severity error; end if; if ((operation_mode = "DUAL_PORT") and (numwords_a * width_a /= numwords_b * width_b)) then assert false report "Error: Total number of bits of port A and port B should be the same for dual port mode" severity error; end if; if (((rdcontrol_aclr_b /= "NONE") and (rdcontrol_aclr_b /= "UNUSED")) and (i_ram_block_type = "M512") and (operation_mode = "DUAL_PORT")) then assert false report "Error: rden_b cannot have clear in simple dual port mode for M512 block" severity error; end if; if ((operation_mode = "BIDIR_DUAL_PORT") and (numwords_a * width_a /= numwords_b * width_b)) then assert false report "Error: Total number of bits of port A and port B should be the same for bidir dual port mode" severity error; end if; if ((operation_mode = "BIDIR_DUAL_PORT") and (i_ram_block_type = "M512")) then assert false report "Error: M512 block type doesn't support bidir dual mode" severity error; end if; if (((i_ram_block_type = "M-RAM") or (i_ram_block_type = "MEGARAM")) and (cread_during_write_mode_mixed_ports = "OLD_DATA")) then assert false report "Error: M-RAM doesn't support OLD_DATA value for READ_DURING_WRITE_MODE_MIXED_PORTS parameter" severity error; end if; if ((not HAS_STRATIXII_STYLE_RAM) and (clock_enable_input_a = "BYPASS")) then assert false report "Error: BYPASS value for CLOCK_ENABLE_INPUT_A is not supported in "& intended_device_family &" device family" severity error; end if; if ((not HAS_STRATIXII_STYLE_RAM) and (clock_enable_output_a = "BYPASS")) then assert false report "Error: BYPASS value for CLOCK_ENABLE_OUTPUT_A is not supported in "& intended_device_family &" device family" severity error; end if; if ((not HAS_STRATIXII_STYLE_RAM) and (clock_enable_input_b = "BYPASS") and ((operation_mode = "BIDIR_DUAL_PORT") or (operation_mode = "DUAL_PORT"))) then assert false report "Error: BYPASS value for CLOCK_ENABLE_INPUT_B is not supported in "& intended_device_family &" device family" severity error; end if; if ((not HAS_STRATIXII_STYLE_RAM) and (clock_enable_output_b = "BYPASS") and ((operation_mode = "BIDIR_DUAL_PORT") or (operation_mode = "DUAL_PORT"))) then assert false report "Error: BYPASS value for CLOCK_ENABLE_OUTPUT_B is not supported in "& intended_device_family &" device family" severity error; end if; if ((implement_in_les /= "OFF") and (implement_in_les /= "ON")) then assert false report "Error: Illegal parameter value for implement_in_les" severity error; end if; if ((not HAS_M512) and (i_ram_block_type = "M512")) then assert false report "Error: M512 as ram_block_type is not supported in "& intended_device_family &" device family" severity error; end if; if ((not HAS_MEGARAM) and (i_ram_block_type = "MEGARAM")) then assert false report "Error: MEGARAM as ram_block_type is not supported in "& intended_device_family &" device family" severity error; end if; if (operation_mode /= "DUAL_PORT") then if ((outdata_reg_a /= "CLOCK0") and (outdata_reg_a /= "CLOCK1") and (outdata_reg_a /= "UNUSED") and (outdata_reg_a /= "UNREGISTERED")) then assert false report "Error: " & outdata_reg_a & " value for outdata_reg_a is not supported." severity error; end if; end if; if ((operation_mode = "BIDIR_DUAL_PORT") or (operation_mode = "DUAL_PORT")) then if ((address_reg_b /= "CLOCK0") and (address_reg_b /= "CLOCK1") and (address_reg_b /= "UNUSED")) then assert false report "Error: " & address_reg_b & " value for address_reg_b is not supported." severity error; end if; if ((outdata_reg_b /= "CLOCK0") and (outdata_reg_b /= "CLOCK1") and (outdata_reg_b /= "UNUSED") and (outdata_reg_b /= "UNREGISTERED")) then assert false report "Error: " & outdata_reg_b & " value for outdata_reg_b is not supported." severity error; end if; if ((rdcontrol_reg_b /= "CLOCK0") and (rdcontrol_reg_b /= "CLOCK1") and (rdcontrol_reg_b /= "UNUSED") and (operation_mode = "DUAL_PORT")) then assert false report "Error: " & rdcontrol_reg_b & " value for rdcontrol_reg_b is not supported." severity error; end if; if ((indata_reg_b /= "CLOCK0") and (indata_reg_b /= "CLOCK1") and (indata_reg_b /= "UNUSED") and (operation_mode = "BIDIR_DUAL_PORT")) then assert false report "Error: " & indata_reg_b & " value for indata_reg_b is not supported." severity error; end if; if ((wrcontrol_wraddress_reg_b /= "CLOCK0") and (wrcontrol_wraddress_reg_b /= "CLOCK1") and (wrcontrol_wraddress_reg_b /= "UNUSED") and (operation_mode = "BIDIR_DUAL_PORT")) then assert false report "Error: " & wrcontrol_wraddress_reg_b & " value for wrcontrol_wraddress_reg_b is not supported." severity error; end if; if ((byteena_reg_b /= "CLOCK0") and (byteena_reg_b /= "CLOCK1") and (byteena_reg_b /= "UNUSED") and (operation_mode = "BIDIR_DUAL_PORT")) then assert false report "Error: " & byteena_reg_b & " value for byteena_reg_b is not supported." severity error; end if; end if; wait; end process; -- SIGNAL ASSIGNMENTS -- Checking for same clock phase process (clock0, clock1) begin if (rising_edge(clock0)) then if (clock1 = '1') then same_clock_pulse0 <= '1'; else same_clock_pulse0 <= '0'; end if; end if; if (rising_edge(clock1)) then if (clock0 = '1') then same_clock_pulse1 <= '1'; else same_clock_pulse1 <= '0'; end if; end if; if (falling_edge(clock0) and (clock1 = '1')) then same_clock_pulse0 <= '0'; end if; if (falling_edge(clock1) and (clock0 = '1')) then same_clock_pulse1 <= '0'; end if; end process; -- Checking ram_block_type and setting default_val IFG01: if ((((i_ram_block_type = "AUTO") and ((cread_during_write_mode_mixed_ports = "DONT_CARE") or (cread_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE"))) or (i_ram_block_type = "MEGARAM") or (i_ram_block_type = "M-RAM")) and (operation_mode /= "ROM") and not (HAS_STRATIXV_STYLE_RAM) and not (HAS_STRATIXIII_STYLE_RAM)) generate default_val <= 'X'; end generate IFG01; IFG02: if (not ((((i_ram_block_type = "AUTO") and ((cread_during_write_mode_mixed_ports = "DONT_CARE") or (cread_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE"))) or (i_ram_block_type = "MEGARAM") or (i_ram_block_type = "M-RAM")) and (operation_mode /= "ROM") and not (HAS_STRATIXV_STYLE_RAM) and not (HAS_STRATIXIII_STYLE_RAM))) generate default_val <= '0'; end generate IFG02; -- Assigning the correct clock enable signals based on the input clock -- for input ports in a IFG03: if (clock_enable_input_a = "NORMAL") generate i_inclocken0 <= clocken0; end generate IFG03; IFG03a: if (clock_enable_input_a = "BYPASS") generate i_inclocken0 <= '1'; end generate IFG03a; IFG03b: if (clock_enable_input_a = "ALTERNATE") generate i_inclocken0 <= clocken2; end generate IFG03b; -- for input ports in b IFG14: if ((address_reg_b = "CLOCK0") and (clock_enable_input_b = "NORMAL")) generate i_input_clocken_b <= clocken0; end generate IFG14; IFG14b: if ((address_reg_b = "CLOCK0") and (clock_enable_input_b = "ALTERNATE")) generate i_input_clocken_b <= clocken2; end generate IFG14b; IFG14a: if (clock_enable_input_b = "BYPASS") generate i_input_clocken_b <= '1'; end generate IFG14a; IFG15: if ((address_reg_b = "CLOCK1") and (clock_enable_input_b = "NORMAL")) generate i_input_clocken_b <= clocken1; end generate IFG15; IFG14c: if ((address_reg_b = "CLOCK1") and (clock_enable_input_b = "ALTERNATE")) generate i_input_clocken_b <= clocken3; end generate IFG14c; -- for data out a IFG171: if ((outdata_reg_a = "CLOCK0") and (clock_enable_output_a = "NORMAL")) generate i_outdata_clken_a <= clocken0; end generate IFG171; IFG172b: if ((outdata_reg_a = "CLOCK0") and (clock_enable_output_a = "ALTERNATE")) generate i_outdata_clken_a <= clocken2; end generate IFG172b; IFG172a: if (clock_enable_output_a = "BYPASS") generate i_outdata_clken_a <= '1'; end generate IFG172a; IFG173 : if ((outdata_reg_a = "CLOCK1") and (clock_enable_output_a = "NORMAL")) generate i_outdata_clken_a <= clocken1; end generate IFG173; IFG173a : if ((outdata_reg_a = "CLOCK1") and (clock_enable_output_a = "ALTERNATE")) generate i_outdata_clken_a <= clocken3; end generate IFG173a; -- case:32394, on SV onwards clear deassertion depends on output clock instead of core clock IFG171a: if ((clock_enable_output_b = "NORMAL") and (outdata_reg_a = "UNREGISTERED") and (outdata_reg_b = "CLOCK0") and (HAS_STRATIXV_STYLE_RAM) and (operation_mode = "BIDIR_DUAL_PORT")) generate i_outlatch_clken_a <= clocken0; end generate IFG171a; -- for data out b IFG17: if ((outdata_reg_b = "CLOCK0") and (clock_enable_output_b = "NORMAL")) generate i_outdata_clken_b <= clocken0; end generate IFG17; IFG17b: if ((outdata_reg_b = "CLOCK0") and (clock_enable_output_b = "ALTERNATE")) generate i_outdata_clken_b <= clocken2; end generate IFG17b; IFG17a: if (clock_enable_output_b = "BYPASS") generate i_outdata_clken_b <= '1'; end generate IFG17a; IFG18 : if ((outdata_reg_b = "CLOCK1") and (clock_enable_output_b = "NORMAL")) generate i_outdata_clken_b <= clocken1; end generate IFG18; IFG18a : if ((outdata_reg_b = "CLOCK1") and (clock_enable_output_b = "ALTERNATE")) generate i_outdata_clken_b <= clocken3; end generate IFG18a; -- case:32394, on SV onwards clear deassertion depends on output clock instead of core clock IFG171b: if ((clock_enable_output_a = "NORMAL") and (outdata_reg_b = "UNREGISTERED") and (outdata_reg_a = "CLOCK0") and (address_reg_b = "CLOCK0") and (HAS_STRATIXV_STYLE_RAM) and (operation_mode = "BIDIR_DUAL_PORT")) generate i_outlatch_clken_b <= clocken0; end generate IFG171b; -- case:32394, on SV onwards clear deassertion depends on output clock instead of core clock IFG171c: if ((clock_enable_output_a = "NORMAL") and (outdata_reg_b = "UNREGISTERED") and (outdata_reg_a = "CLOCK1") and (address_reg_b = "CLOCK1") and (HAS_STRATIXV_STYLE_RAM) and (operation_mode = "BIDIR_DUAL_PORT")) generate i_outlatch_clken_b <= clocken1; end generate IFG171c; -- for core clock a IFG50a: if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (clock_enable_core_a = "USE_INPUT_CLKEN")) generate i_core_clocken_a <= i_inclocken0; end generate IFG50a; IFG50b: if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (clock_enable_core_a = "ALTERNATE")) generate i_core_clocken_a <= clocken2; end generate IFG50b; IFG50d: if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (clock_enable_core_a = "BYPASS")) generate i_core_clocken_a <= '1'; end generate IFG50d; IFG50c: if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (clock_enable_core_a = "NORMAL")) generate i_core_clocken_a <= clocken0; end generate IFG50c; IFG50e: if ((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)) generate i_core_clocken_a <= i_inclocken0; end generate IFG50e; -- for core clock b IFG51a: if ((((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (clock_enable_core_b = "USE_INPUT_CLKEN")) or ((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM))) generate i_core_clocken_b0 <= i_input_clocken_b; i_core_clocken_b1 <= i_input_clocken_b; end generate IFG51a; IFG51e: if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (clock_enable_core_b = "NORMAL")) generate i_core_clocken_b0 <= clocken0; i_core_clocken_b1 <= clocken1; end generate IFG51e; IFG51b: if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (clock_enable_core_b = "ALTERNATE")) generate i_core_clocken_b0 <= clocken2; i_core_clocken_b1 <= clocken3; end generate IFG51b; IFG51c: if (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (clock_enable_core_b = "BYPASS")) generate i_core_clocken_b0 <= '1'; i_core_clocken_b1 <= '1'; end generate IFG51c; IFG52a: if (address_reg_b = "CLOCK0") generate i_core_clocken_b <= i_core_clocken_b0; end generate IFG52a; IFG52b: if (address_reg_b = "CLOCK1") generate i_core_clocken_b <= i_core_clocken_b1; end generate IFG52b; -- Assigning the correct clear signals -- for data in a IFG20: if ((indata_aclr_a = "CLEAR0") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_indata_aclr_a <= aclr0; end generate IFG20; -- for address a IFG22: if ((address_aclr_a = "CLEAR0") and (not ((((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (operation_mode /= "ROM")) or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_address_aclr_a <= aclr0; end generate IFG22; -- for wren a IFG24: if ((wrcontrol_aclr_a = "CLEAR0") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_wrcontrol_aclr_a <= aclr0; end generate IFG24; -- for byteena a IFG26: if ((byteena_aclr_a = "CLEAR0") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_byteena_aclr_a <= aclr0; end generate IFG26; IFG27: if ((byteena_aclr_a = "CLEAR1") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_byteena_aclr_a <= aclr1; end generate IFG27; -- for data out a IFG29: if (outdata_aclr_a = "CLEAR0") generate i_outdata_aclr_a <= aclr0; end generate IFG29; IFG30: if (outdata_aclr_a = "CLEAR1") generate i_outdata_aclr_a <= aclr1; end generate IFG30; -- for data out b IFG31a: if (outdata_aclr_b = "CLEAR0") generate i_outdata_aclr_b <= aclr0; end generate IFG31a; IFG31b: if (outdata_aclr_b = "CLEAR1") generate i_outdata_aclr_b <= aclr1; end generate IFG31b; -- for data in b IFG32: if ((indata_aclr_b = "CLEAR0") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_indata_aclr_b <= aclr0; end generate IFG32; IFG33: if ((indata_aclr_b = "CLEAR1") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_indata_aclr_b <= aclr1; end generate IFG33; -- for address b IFG35: if ((address_aclr_b = "CLEAR0") and not (IS_BASE_STRATIXII) and not (IS_BASE_CYCLONEII) and not (HAS_STRATIXV_STYLE_RAM) and not (HAS_STRATIXIII_STYLE_RAM)) generate i_address_aclr_b <= aclr0; end generate IFG35; IFG35a: if ((address_aclr_b = "CLEAR0") and (operation_mode = "DUAL_PORT") and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) generate i_address_aclr_b <= aclr0; end generate IFG35a; IFG36: if ((address_aclr_b = "CLEAR1") and not (IS_BASE_STRATIXII) and not (IS_BASE_CYCLONEII) and not ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) generate i_address_aclr_b <= aclr1; end generate IFG36; IFG36a: if ((address_aclr_b = "CLEAR1") and (operation_mode = "DUAL_PORT") and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) generate i_address_aclr_b <= aclr1; end generate IFG36a; -- for wren b IFG38:if ((wrcontrol_aclr_b = "CLEAR0") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_wrcontrol_aclr_b <= aclr0; end generate IFG38; IFG39: if ((wrcontrol_aclr_b = "CLEAR1") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_wrcontrol_aclr_b <= aclr1; end generate IFG39; -- for rden b IFG41: if ((rdcontrol_aclr_b = "CLEAR0") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_rdcontrol_aclr_b <= aclr0; end generate IFG41; IFG42: if ((rdcontrol_aclr_b = "CLEAR1") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_rdcontrol_aclr_b <= aclr1; end generate IFG42; -- for byteena b IFG44: if ((byteena_aclr_b = "CLEAR0") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_byteena_aclr_b <= aclr0; end generate IFG44; IFG45: if ((byteena_aclr_b = "CLEAR1") and (not (HAS_STRATIXV_STYLE_RAM or HAS_STRATIXIII_STYLE_RAM or (IS_BASE_STRATIXII or IS_BASE_CYCLONEII)))) generate i_byteena_aclr_b <= aclr1; end generate IFG45; -- This process initializes and updates the memory content in the RAM accordingly MEMORY: process (i_read_flag_a, i_write_flag_a, i_read_flag_b, i_write_flag_b, default_val, i_reread_flag_a, i_reread_flag_b, i_reread_flag2_a, i_reread_flag2_b) variable j : integer := 0; variable port_a_bit_count_low : integer := 0; variable port_a_bit_count_high : integer := 0; variable port_b_bit_count_low : integer := 0; variable port_b_bit_count_high : integer := 0; variable i_byteena_count : integer := 0; variable m_mem_data_a : width_a_array; variable m_mem_data_b : width_b_array; variable m_temp_wa : std_logic_vector(width_a - 1 downto 0); variable m_temp_wa2 : std_logic_vector(width_a - 1 downto 0) := (others => 'U'); variable m_temp_wa3 : std_logic_vector(width_a - 1 downto 0); variable m_temp_wb : std_logic_vector(width_b - 1 downto 0); variable m_temp_wb2 : std_logic; variable m_init_file_b_port : boolean := false; variable m_temp_wb3 : std_logic_vector(width_a - 1 downto 0); variable m_current_written_data_b : std_logic_vector(width_b - 1 downto 0); variable m_address_a : integer := 0; variable m_address_b : integer := 0; variable m_original_address_a : integer := 0; variable m_data_write_time_a : time := 0 ps; variable m_q_tmp2_a : std_logic_vector(width_a - 1 downto 0); variable write_by_a : integer := 0; variable prev_write_by_a : integer := 0; variable write_by_b : integer := 0; variable prev_write_by_b : integer := 0; variable ctime : time := 0 ps; variable reread_a : boolean := false; variable reread_b : boolean := false; variable last_read_a_event : boolean := false; variable last_read_b_event : boolean := false; variable need_init_var : boolean := true; variable m_current_written_data_a : std_logic_vector(width_a - 1 downto 0); variable m_original_data_a : std_logic_vector(width_a - 1 downto 0); variable m_original_data_b : std_logic_vector(width_b - 1 downto 0); variable m_data_a_x : std_logic_vector(width_a - 1 downto 0) := (others => 'X'); variable m_data_b_x : std_logic_vector(width_b - 1 downto 0) := (others => 'X'); begin if (need_init_var) then -- Begin of initializations m_original_data_a := (others => default_val); m_original_data_b := (others => default_val); if (init_file = "UNUSED" or init_file = "NONE" or init_file = "") then -- No memory file used if (operation_mode /= "ROM") then if (( ( (i_ram_block_type = "AUTO") and ( (cread_during_write_mode_mixed_ports = "DONT_CARE") or (cread_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE"))) or IS_HARDCOPYII or IS_HARDCOPYIII or IS_HARDCOPYIV or (i_ram_block_type = "MEGARAM") or (i_ram_block_type = "M-RAM") or (power_up_uninitialized = "TRUE")) and (implement_in_les = "OFF") and not ((((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (not IS_HARDCOPYIII) and (not IS_HARDCOPYIV) ) and (power_up_uninitialized /= "TRUE"))) then for i in 0 to (2**widthad_a - 1) loop m_mem_data_a(i) := (others => 'X'); end loop; if (enable_mem_data_b_reading = true) then for i in 0 to (2**widthad_b - 1) loop m_mem_data_b(i) := (others => 'X'); end loop; end if; else for i in 0 to (2**widthad_a - 1) loop m_mem_data_a(i) := (others => '0'); end loop; if (enable_mem_data_b_reading = true) then for i in 0 to (2**widthad_b - 1) loop m_mem_data_b(i) := (others => '0'); end loop; end if; end if; end if; else -- Using memory file to initialize memory content if (( ((i_ram_block_type = "AUTO") and ( (cread_during_write_mode_mixed_ports = "DONT_CARE") or (cread_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE"))) or IS_HARDCOPYII or (power_up_uninitialized = "TRUE") or (i_ram_block_type = "MEGARAM") or (i_ram_block_type = "M-RAM")) and not (HAS_STRATIXV_STYLE_RAM) and not (HAS_STRATIXIII_STYLE_RAM) and (operation_mode /= "ROM") ) then for i in 0 to (2 ** widthad_a - 1) loop m_mem_data_a(i) := (others => 'X'); end loop; if (enable_mem_data_b_reading = true) then for i in 0 to (2**widthad_b - 1) loop m_mem_data_b(i) := (others => 'X'); end loop; end if; else for i in 0 to (2 ** widthad_a - 1) loop m_mem_data_a(i) := (others => '0'); end loop; if (enable_mem_data_b_reading = true) then for i in 0 to (2**widthad_b - 1) loop m_mem_data_b(i) := (others => '0'); end loop; end if; end if; if (init_file_layout = "UNUSED") then if (operation_mode = "DUAL_PORT") then m_init_file_b_port := true; else m_init_file_b_port := false; end if; else if (init_file_layout = "PORT_A") then m_init_file_b_port := false; elsif (init_file_layout = "PORT_B") then m_init_file_b_port := true; end if; end if; if (m_init_file_b_port) then read_my_memory (false, m_mem_data_a, m_mem_data_b); for i in 0 to (i_numwords_b * width_b - 1) loop m_temp_wb := m_mem_data_b(i / width_b); m_temp_wb2 := m_temp_wb((i)mod width_b); m_temp_wa := m_mem_data_a(i / width_a); m_temp_wa(i mod width_a) := m_temp_wb2; m_mem_data_a(i / width_a) := m_temp_wa; end loop; else read_my_memory (true, m_mem_data_a, m_mem_data_b); if (enable_mem_data_b_reading = true) then for i in 0 to (i_numwords_a * width_a - 1) loop m_temp_wa := m_mem_data_a(i / width_a); m_temp_wb2 := m_temp_wa((i)mod width_a); m_temp_wb := m_mem_data_b(i / width_b); m_temp_wb(i mod width_b) := m_temp_wb2; m_mem_data_b(i / width_b) := m_temp_wb; end loop; end if; end if; end if; if (i_is_lutram) then if (operation_mode = "DUAL_PORT") then for i in 0 to (width_b - 1) loop m_temp_wa2 := m_mem_data_a(i / width_a); m_temp_wb(i) := m_temp_wa2(i mod width_a); end loop; i_q_tmp2_b <= m_temp_wb; end if; if ((operation_mode = "SINGLE_PORT") or (operation_mode = "ROM")) then i_q_tmp2_a <= m_mem_data_a(0); end if; end if; need_init_var := false; -- End of initializations end if; -- Port A writing if ((rising_edge(i_write_flag_a) or falling_edge(i_write_flag_a)) and (need_init_var = false)) then if ((write_operation_a) and (i_good_to_write_a = '1')) then m_original_data_a := m_mem_data_a(conv_integer(unsigned(i_address_reg_a))); i_original_data_a <= m_mem_data_a(conv_integer(unsigned(i_address_reg_a))); if (i_wren_reg_a = '1') then if ((i_address_aclr_a = '1') and (conv_integer(unsigned(i_address_reg_a)) /= 0)) then for i in 0 to (i_numwords_a - 1) loop m_mem_data_a(i) := (others => 'X'); end loop; if (enable_mem_data_b_reading = true) then for i in 0 to (i_numwords_b - 1) loop m_mem_data_b(i) := (others => 'X'); end loop; end if; elsif (((i_indata_aclr_a = '1') and (i_data_reg_a /= i_data_zero_a)) or ((i_byteena_aclr_a = '1') and (i_byteena_mask_reg_a /= i_data_ones_a)) or ((i_wrcontrol_aclr_a = '1') and (i_wren_reg_a /= '0'))) then m_mem_data_a (conv_integer(unsigned(i_address_reg_a))) := (others => 'X'); j := conv_integer(unsigned(i_address_reg_a)) * width_a; if (enable_mem_data_b_reading = true) then for i in 0 to (width_a - 1) loop m_temp_wb := m_mem_data_b((j + i) / width_b); m_temp_wb((j + i) mod width_b) := 'X'; m_mem_data_b((j + i) / width_b) := m_temp_wb; end loop; end if; else port_a_bit_count_low := (conv_integer(unsigned(i_address_reg_a)) * width_a); port_b_bit_count_low := (conv_integer(unsigned(i_address_reg_b)) * width_b); port_b_bit_count_high := ((conv_integer(unsigned(i_address_reg_b)) * width_b) + width_b); m_temp_wa := m_mem_data_a(conv_integer(unsigned(i_address_reg_a))); for i in 0 to (width_a - 1) loop port_a_bit_count_high := port_a_bit_count_low + i; i_byteena_count := port_a_bit_count_high mod width_b; if ((port_a_bit_count_high >= port_b_bit_count_low) and (port_a_bit_count_high < port_b_bit_count_high)) then if ((i_core_clocken_b_reg = '1') and (i_wren_reg_b = '1') and ((address_reg_b = "CLOCK0") or (same_clock_pulse0 = '1' and same_clock_pulse1 = '1')) and (i_byteena_mask_reg_b(i_byteena_count) = '1') and (i_byteena_mask_reg_a(i) = '1') and i_write_flag_b'event) then m_temp_wa(i) := 'X'; elsif (i_byteena_mask_reg_a(i) = '1') then m_temp_wa(i) := i_data_reg_a(i); end if; elsif (i_byteena_mask_reg_a(i) = '1') then m_temp_wa(i) := i_data_reg_a(i); end if; if (enable_mem_data_b_reading = true) then m_temp_wb := m_mem_data_b(port_a_bit_count_high / width_b); m_temp_wb(port_a_bit_count_high mod width_b) := m_temp_wa(i); m_mem_data_b(port_a_bit_count_high / width_b) := m_temp_wb; end if; end loop; m_mem_data_a (conv_integer(unsigned(i_address_reg_a))) := m_temp_wa; m_original_address_a := conv_integer(unsigned(i_address_reg_a)); m_data_write_time_a := now; write_by_a := write_by_a + 1; end if; end if; m_current_written_data_a := m_mem_data_a(conv_integer(unsigned(i_address_reg_a))); i_current_written_data_a <= m_mem_data_a(conv_integer(unsigned(i_address_reg_a))); end if; end if; -- Port B writing if ((rising_edge(i_write_flag_b) or falling_edge(i_write_flag_b)) and (need_init_var = false)) then if ((write_operation_b) and (i_good_to_write_b = '1')) then j := conv_integer(unsigned(i_address_reg_b)) * width_b; for i in 0 to (width_b - 1) loop m_temp_wb3 := m_mem_data_a((j + i) / width_a); m_original_data_b(i) := m_temp_wb3((j + i) mod width_a); i_original_data_b(i) <= m_temp_wb3((j + i) mod width_a); end loop; if (i_wren_reg_b = '1') then if ((i_wrcontrol_aclr_b = '1') and (conv_integer(unsigned(i_address_reg_b)) /= 0)) then for i in 0 to (i_numwords_a - 1) loop m_mem_data_a(i) := (others => 'X'); end loop; if (enable_mem_data_b_reading = true) then for i in 0 to (i_numwords_b - 1) loop m_mem_data_b(i) := (others => 'X'); end loop; end if; elsif (((i_byteena_aclr_b = '1') and (i_byteena_mask_reg_b /= i_data_ones_b)) or ((i_indata_aclr_b = '1') and (i_data_reg_b /= i_data_zero_b)) or ((i_wrcontrol_aclr_b = '1') and (i_wren_reg_b /= '0'))) then if (width_a = width_b) then j := conv_integer(unsigned(i_address_reg_b)); m_mem_data_a(j) := (others => 'X'); else j := conv_integer(unsigned(i_address_reg_b)) * width_b; for i in 0 to (width_b - 1) loop m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wa2((j + i) mod width_a) := 'X'; m_mem_data_a((j + i) / width_a) := m_temp_wa2; end loop; end if; if (enable_mem_data_b_reading = true) then m_mem_data_b(conv_integer(unsigned(i_address_reg_b))) := (others => 'X'); end if; else port_b_bit_count_low := (conv_integer(unsigned(i_address_reg_b)) * width_b); port_a_bit_count_low := (conv_integer(unsigned(i_address_reg_a)) * width_a); port_a_bit_count_high := (conv_integer(unsigned(i_address_reg_a)) * width_a) + width_a; for i in 0 to (width_b - 1) loop port_b_bit_count_high := port_b_bit_count_low + i; m_temp_wa2 := m_mem_data_a((port_b_bit_count_high) / width_a); if ((port_b_bit_count_high >= port_a_bit_count_low) and (port_b_bit_count_high < port_a_bit_count_high) and (i_core_clocken_a_reg = '1') and (i_wren_reg_a = '1') and ((address_reg_b = "CLOCK0") or (same_clock_pulse0 = '1' and same_clock_pulse1 = '1')) and (i_byteena_mask_reg_a((port_b_bit_count_high) mod width_a) = '1') and (i_byteena_mask_reg_b(i) = '1') and i_write_flag_a'event) then m_temp_wa2((port_b_bit_count_high) mod width_a) := 'X'; elsif (i_byteena_mask_reg_b(i) = '1') then m_temp_wa2((port_b_bit_count_high) mod width_a) := i_data_reg_b(i); end if; m_mem_data_a((port_b_bit_count_high) / width_a) := m_temp_wa2; m_current_written_data_b(i) := m_temp_wa2((port_b_bit_count_high) mod width_a); m_temp_wb(i) := m_temp_wa2((port_b_bit_count_high) mod width_a); end loop; if (enable_mem_data_b_reading = true) then m_mem_data_b (conv_integer(unsigned(i_address_reg_b))) := m_temp_wb; end if; write_by_b := write_by_b + 1; end if; -- end of choice selection end if; -- i_wren_reg_b = '1' end if;-- write_operation_b end if; -- i_write_flag_b'event -- To ensure that the model will reread port if two event (read & write) event triggered -- at the different time quantum reread_a := false; reread_b := false; if (ctime /= 0 ps) and (ctime = now) and ((i_write_flag_a'event) or (i_write_flag_b'event)) then if last_read_a_event then reread_a := true; end if; if last_read_b_event then reread_b := true; end if; end if; if (i_write_flag_a'event and i_lutram_dual_port_fast_read) then reread_b := true; end if; last_read_a_event := i_read_flag_a'event; last_read_b_event := i_read_flag_b'event; ctime := now; -- Port A reading if ((rising_edge(i_read_flag_a) or falling_edge(i_read_flag_a)) or (reread_a) or rising_edge(i_reread_flag_a) or falling_edge(i_reread_flag_a) or rising_edge(i_reread_flag2_a) or falling_edge(i_reread_flag2_a)) then if (write_by_a /= prev_write_by_a) then prev_write_by_a := write_by_a; end if; if (read_operation_a) then if (i_rden_reg_a = '1') then m_address_a := conv_integer(unsigned(i_address_reg_a)); if (i_wren_reg_a = '1') then if (i_core_clocken_a = '1') then if (read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ") then if (i_is_lutram and (clock0 = '1')) then m_q_tmp2_a := m_mem_data_a(m_address_a); else m_q_tmp2_a := ((i_data_reg_a and i_byteena_mask_reg_a) or (m_data_a_x and not i_byteena_mask_reg_a)); end if; elsif (read_during_write_mode_port_a = "NEW_DATA_WITH_NBE_READ") then if (i_is_lutram and (clock0 = '1')) then m_q_tmp2_a := m_mem_data_a(m_address_a); else m_q_tmp2_a := ((i_data_reg_a and i_byteena_mask_reg_a) or (m_mem_data_a(m_address_a) and not i_byteena_mask_reg_a)) xor i_byteena_mask_reg_a_x; end if; elsif (read_during_write_mode_port_a = "OLD_DATA") then m_q_tmp2_a := m_original_data_a; else m_q_tmp2_a := i_data_reg_a xor i_byteena_mask_reg_a_out; if ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) then m_q_tmp2_a := (others => 'X'); end if; end if; end if; if (i_lutram_single_port_fast_read) then m_q_tmp2_a := m_mem_data_a(m_address_a); end if; else m_address_a := conv_integer(unsigned(i_address_reg_a)); m_q_tmp2_a := m_mem_data_a(m_address_a); -- This is to output an "X" when the other port is writing into the same location -- when read_during_write_mode_mixed_ports = "DONT_CARE" if (((address_reg_b = "CLOCK0") or (same_clock_pulse0 = '1' and same_clock_pulse1 = '1')) and (is_write_positive_edge)) then if ((i_wren_reg_b = '1') and (((i_core_clocken_b = '1') and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) or ((i_input_clocken_b = '1') and (not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)))) then m_address_b := conv_integer(unsigned(i_address_reg_b)); if (width_a = width_b) then if (m_address_b = m_address_a) then if (cread_during_write_mode_mixed_ports = "OLD_DATA") then m_q_tmp2_a := m_original_data_b; else m_q_tmp2_a := m_q_tmp2_a xor i_byteena_mask_reg_b_out_a; end if; end if; else for i in (m_address_a * width_a) to ((m_address_a * width_a) + width_a - 1) loop if ((i >= (m_address_b * width_b)) and (i <= ((m_address_b * width_b) + width_b - 1))) then j := i - (m_address_a * width_a); i_byteena_count := i - (m_address_b * width_b); if (cread_during_write_mode_mixed_ports = "OLD_DATA") then m_q_tmp2_a(j) := m_original_data_b(i_byteena_count); else m_q_tmp2_a(j) := m_q_tmp2_a(j) xor i_byteena_mask_reg_b_out_a(i_byteena_count); end if; end if; end loop; end if; end if; end if; end if; if (conv_integer(unsigned(i_address_reg_a)) >= i_numwords_a) then if ((i_wren_reg_a = '0') or (i_core_clocken_a = '0')) then i_q_tmp2_a <= (others => 'X'); else i_q_tmp2_a <= m_q_tmp2_a; end if; assert false report "Address pointed at port A is out of bound! " severity warning; else if (((HAS_STRATIXV_STYLE_RAM) or (IS_CYCLONEIII)) and (((outdata_aclr_a = "CLEAR0") and (aclr0 = '1')) or ((outdata_aclr_a = "CLEAR1") and (aclr1 = '1'))) and (outdata_reg_a = "UNREGISTERED")) then i_q_tmp2_a <= (others => '0'); else i_q_tmp2_a <= m_q_tmp2_a; end if; if (i_is_lutram and (i_address_aclr_a = '1') and (operation_mode = "ROM")) then i_q_tmp2_a <= m_mem_data_a(0); end if; end if; else if (((HAS_STRATIXV_STYLE_RAM) or (IS_CYCLONEIII)) and (not i_is_lutram) and (((outdata_aclr_a = "CLEAR0") and (aclr0 = '1')) or ((outdata_aclr_a = "CLEAR1") and (aclr1 = '1'))) and (outdata_reg_a /= "CLOCK0") and (outdata_reg_a /= "CLOCK1")) then i_q_tmp2_a <= (others => '0'); end if; end if; end if; -- end read_operation_a end if; -- Port B reading if ((rising_edge(i_read_flag_b) or falling_edge(i_read_flag_b)) or (reread_b) or rising_edge(i_reread_flag_b) or falling_edge(i_reread_flag_b) or rising_edge(i_reread_flag2_b) or falling_edge(i_reread_flag2_b)) then if (write_by_b /= prev_write_by_b) then prev_write_by_b := write_by_b; end if; if (read_operation_b) then if (i_rden_reg_b = '1') then m_address_a := conv_integer(unsigned(i_address_reg_a)); m_address_b := conv_integer(unsigned(i_address_reg_b)); -- No address conversion calculation if width_a is equals to width_b if (width_a = width_b) then if (i_wren_reg_b = '1') then if (i_core_clocken_b = '1') then if (read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ") then i_q_tmp2_b <= ((i_data_reg_b and i_byteena_mask_reg_b) or (m_data_b_x and not i_byteena_mask_reg_b)); elsif (read_during_write_mode_port_b = "NEW_DATA_WITH_NBE_READ") then i_q_tmp2_b <= ((i_data_reg_b and i_byteena_mask_reg_b) or (m_mem_data_a(m_address_b) and not i_byteena_mask_reg_b)) xor i_byteena_mask_reg_b_x; elsif (read_during_write_mode_port_b = "OLD_DATA") then i_q_tmp2_b <= m_original_data_b; else i_q_tmp2_b <= (others => 'X'); end if; end if; elsif (((m_data_write_time_a = now) and (operation_mode = "DUAL_PORT") and (not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM))) then if ((m_address_a = m_address_b) and (m_address_a = m_original_address_a)) then if (address_reg_b /= "CLOCK0") then i_q_tmp2_b <= m_mem_data_a(m_address_b) xor i_byteena_mask_reg_a_out_b; elsif (cread_during_write_mode_mixed_ports = "OLD_DATA") then i_q_tmp2_b <= m_original_data_a; elsif ((cread_during_write_mode_mixed_ports = "DONT_CARE") or (cread_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE")) then i_q_tmp2_b <= m_mem_data_a(m_address_b) xor i_byteena_mask_reg_a_out_b; else i_q_tmp2_b <= m_mem_data_a(m_address_b); end if; else i_q_tmp2_b <= m_mem_data_a(m_address_b); end if; else if (m_address_a = m_address_b) then if (i_is_lutram) then if (((address_reg_b = "CLOCK0") or (same_clock_pulse0 = '1' and same_clock_pulse1 = '1')) and (is_write_positive_edge)) then if ((i_wren_reg_a = '1') and (((i_core_clocken_a = '1') and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) or ((i_inclocken0 = '1') and (not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)))) then if ((cread_during_write_mode_mixed_ports = "OLD_DATA") and (outdata_reg_b = "CLOCK0")) then i_q_tmp2_b <= m_mem_data_a(m_address_b); else i_q_tmp2_b <= m_current_written_data_a; end if; else i_q_tmp2_b <= m_mem_data_a(m_address_b); end if; else i_q_tmp2_b <= m_mem_data_a(m_address_b); end if; elsif ((i_ram_block_type = "MEGARAM") or (i_ram_block_type = "M-RAM") or (((cread_during_write_mode_mixed_ports = "DONT_CARE") or (cread_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE")) and (i_ram_block_type = "AUTO"))) then if (((address_reg_b = "CLOCK0") or (same_clock_pulse0 = '1' and same_clock_pulse1 = '1')) and (is_write_positive_edge)) then if ((i_wren_reg_a = '1') and (((i_core_clocken_a = '1') and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) or ((i_inclocken0 = '1') and (not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)))) then i_q_tmp2_b <= m_mem_data_a(m_address_b) xor i_byteena_mask_reg_a_out_b; else i_q_tmp2_b <= m_mem_data_a(m_address_b); end if; else i_q_tmp2_b <= m_mem_data_a(m_address_b); end if; else if (((address_reg_b = "CLOCK0") or (same_clock_pulse0 = '1' and same_clock_pulse1 = '1')) and (is_write_positive_edge)) then if ((i_wren_reg_a = '1') and (((i_core_clocken_a = '1') and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) or ((i_inclocken0 = '1') and (not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM))) and (is_write_positive_edge)) then if (cread_during_write_mode_mixed_ports = "OLD_DATA") then i_q_tmp2_b <= m_original_data_a; else i_q_tmp2_b <= m_mem_data_a(m_address_b) xor i_byteena_mask_reg_a_out_b; end if; else i_q_tmp2_b <= m_mem_data_a(m_address_b); end if; else i_q_tmp2_b <= m_mem_data_a(m_address_b); end if; end if; else i_q_tmp2_b <= m_mem_data_a(m_address_b); end if; end if; else j := m_address_b * width_b; for i in 0 to (width_b - 1) loop if (i_wren_reg_b = '1') then if (read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ") then m_temp_wb(i) := ((i_data_reg_b(i) and i_byteena_mask_reg_b(i)) or (m_data_b_x(i) and not i_byteena_mask_reg_b(i))); elsif (read_during_write_mode_port_b = "NEW_DATA_WITH_NBE_READ") then m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := ((i_data_reg_b(i) and i_byteena_mask_reg_b(i)) or (m_temp_wa2((j + i) mod width_a) and not i_byteena_mask_reg_b(i))) xor i_byteena_mask_reg_b_x(i); elsif (read_during_write_mode_port_b = "OLD_DATA") then m_temp_wb(i) := m_original_data_b(i); else m_temp_wb(i) := 'X'; end if; elsif ((m_data_write_time_a = now) and (operation_mode = "DUAL_PORT") and (not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)) then if ((m_address_a = ((j + i) / width_a)) and (m_address_a = m_original_address_a)) then if (address_reg_b /= "CLOCK0") then m_temp_wa2 := (m_mem_data_a((j + i) / width_a)) xor i_byteena_mask_reg_a_out_b; m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); elsif (cread_during_write_mode_mixed_ports = "OLD_DATA") then m_temp_wb(i) := m_original_data_a((j + i) mod width_a); elsif ((cread_during_write_mode_mixed_ports = "DONT_CARE") or (cread_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE"))then m_temp_wa2 := (m_mem_data_a((j + i) / width_a)) xor i_byteena_mask_reg_a_out_b; m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); else m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end if; else m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end if; else if (((j + i) / width_a) = m_address_a) then if (i_is_lutram) then if (((address_reg_b = "CLOCK0") or (same_clock_pulse0 = '1' and same_clock_pulse1 = '1')) and (is_write_positive_edge)) then if ((i_wren_reg_a = '1') and (((i_core_clocken_a = '1') and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) or ((i_inclocken0 = '1') and (not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)))) then if ((cread_during_write_mode_mixed_ports = "OLD_DATA") and (outdata_reg_b = "CLOCK0")) then m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); else m_temp_wb(i) := m_current_written_data_a((j + i) mod width_a); end if; else m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end if; else m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end if; elsif ((i_ram_block_type = "MEGARAM") or (i_ram_block_type = "M-RAM") or (((cread_during_write_mode_mixed_ports = "DONT_CARE") or (cread_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE")) and (i_ram_block_type = "AUTO"))) then if (((address_reg_b = "CLOCK0") or (same_clock_pulse0 = '1' and same_clock_pulse1 = '1')) and (is_write_positive_edge)) then if ((i_wren_reg_a = '1') and (((i_core_clocken_a = '1') or (i_inclocken0 = '1')) and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)))) then m_temp_wa2 := (m_mem_data_a((j + i) / width_a)) xor i_byteena_mask_reg_a_out_b; m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); else m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end if; else m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end if; else if (((address_reg_b = "CLOCK0") or (same_clock_pulse0 = '1' and same_clock_pulse1 = '1')) and (is_write_positive_edge)) then if ((i_wren_reg_a = '1') and (((i_core_clocken_a = '1') or (i_inclocken0 = '1')) and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) and (is_write_positive_edge)) then if (cread_during_write_mode_mixed_ports = "OLD_DATA") then m_temp_wb(i) := m_original_data_a((j + i) mod width_a); else m_temp_wa2 := (m_mem_data_a((j + i) / width_a)) xor i_byteena_mask_reg_a_out_b; m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end if; else m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end if; else m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end if; end if; else m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end if; end if; end loop; i_q_tmp2_b <= m_temp_wb; end if; end if; if (i_is_lutram and (i_address_aclr_b = '1') and operation_mode = "DUAL_PORT") then for i in 0 to (width_b - 1) loop m_temp_wa2 := m_mem_data_a(i / width_a); m_temp_wb(i) := m_temp_wa2(i mod width_a); end loop; i_q_tmp2_b <= m_temp_wb; elsif (i_is_lutram and operation_mode = "DUAL_PORT") then j := m_address_b * width_b; for i in 0 to (width_b - 1) loop m_temp_wa2 := m_mem_data_a((j + i) / width_a); m_temp_wb(i) := m_temp_wa2((j + i) mod width_a); end loop; i_q_tmp2_b <= m_temp_wb; end if; if ((((outdata_aclr_b = "CLEAR0") and (aclr0 = '1')) or ((outdata_aclr_b = "CLEAR1") and (aclr1 = '1'))) and (outdata_reg_b /= "CLOCK0") and (outdata_reg_b /= "CLOCK1") and (((HAS_STRATIXV_STYLE_RAM) or (IS_CYCLONEIII)) and (not i_is_lutram))) then i_q_tmp2_b <= (others => '0'); end if; end if; end if; end process memory; -- Port A inputs registered : indata, address, byeteena, wren process (clock0) variable m_byteena_mask_reg_a : std_logic_vector(width_a - 1 downto 0); variable m_byteena_mask_reg_a_out : std_logic_vector(width_a - 1 downto 0); variable m_byteena_mask_reg_a_x : std_logic_vector(width_a - 1 downto 0):= (others => '0'); variable m_indata_reg_aclr_a : std_logic := '0'; variable m_wren_reg_aclr_a : std_logic := '0'; variable m_byteena_reg_aclr_a : std_logic := '0'; variable m_address_reg_aclr_a : std_logic := '0'; variable m_byteena_mask_reg_a_out_b : std_logic_vector(width_a - 1 downto 0); variable need_init_var : boolean := true; begin if (need_init_var = true) then if ((IS_HARDCOPYII) and (ram_block_type = "M4K") and (operation_mode /= "SINGLE_PORT") and (clock0 = '1')) then i_good_to_write_b <= '0'; end if; need_init_var := false; end if; if (rising_edge(clock0)) then if (i_address_aclr_a = '1') then i_address_reg_a <= (others => '0'); end if; if (i_force_reread_a = '1' and (i_outlatch_clken_a = '1')) then i_force_reread_signal_a <= not i_force_reread_signal_a; end if; i_core_clocken_a_reg <= i_core_clocken_a; if (i_core_clocken_a = '1') then if (i_force_reread_a1 = '1') then i_force_reread_signal_a <= not i_force_reread_signal_a; end if; if ((HAS_STRATIXV_STYLE_RAM or IS_STRATIXIII) and (not i_is_lutram)) then good_to_go_a <= '1'; if (i_wrcontrol_aclr_a = '1') then i_wren_reg_a <= '0'; else i_wren_reg_a <= wren_a; end if; i_rden_reg_a <= rden_a; end if; if ((not i_is_lutram) and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) then i_read_flag_a <= not i_read_flag_a; end if; if ((is_write_positive_edge) and ((wren_a = '1') or (i_wren_reg_a = '1'))) then i_write_flag_a <= not i_write_flag_a; end if; if (operation_mode /= "ROM") then i_nmram_write_a <= '1'; end if; else if (operation_mode /= "ROM") then i_nmram_write_a <= '0'; end if; end if; if (i_is_lutram) then if (i_wrcontrol_aclr_a = '1') then i_wren_reg_a <= '0'; elsif (i_core_clocken_a = '1') then i_wren_reg_a <= wren_a; end if; end if; if (((clock_enable_input_a = "NORMAL") and (clocken0 = '1')) or ((clock_enable_input_a = "ALTERNATE") and (clocken2 = '1')) or (clock_enable_input_a = "BYPASS")) then if (((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)) or i_is_lutram) then i_read_flag_a <= not i_read_flag_a; end if; if (i_indata_aclr_a = '1') then i_data_reg_a <= (others => '0'); else i_data_reg_a <= data_a; end if; if (((not HAS_STRATIXV_STYLE_RAM) and (not IS_STRATIXIII)) or (i_is_lutram)) then good_to_go_a <= '1'; if (i_wrcontrol_aclr_a = '1') then i_wren_reg_a <= '0'; else i_wren_reg_a <= wren_a; end if; i_rden_reg_a <= rden_a; end if; if (i_byteena_aclr_a = '1') then m_byteena_mask_reg_a := (others => '1'); m_byteena_mask_reg_a_out := (others => '0'); m_byteena_mask_reg_a_out_b := (others => 'X'); else if (width_byteena_a = 1) then m_byteena_mask_reg_a := (others => byteena_a(0)); if (byteena_a(0) = '1') then m_byteena_mask_reg_a_out := (others => '0'); m_byteena_mask_reg_a_x := (others => '0'); m_byteena_mask_reg_a_out_b := (others => 'X'); elsif (byteena_a(0) = '0') then m_byteena_mask_reg_a_x := (others => '0'); m_byteena_mask_reg_a_out := (others => 'X'); m_byteena_mask_reg_a_out_b := (others => '0'); else m_byteena_mask_reg_a_x := (others => 'X'); m_byteena_mask_reg_a_out := (others => 'X'); m_byteena_mask_reg_a_out_b := (others => 'X'); end if; else for k in 0 to (width_a - 1) loop m_byteena_mask_reg_a(k) := byteena_a(k / i_byte_size); if (m_byteena_mask_reg_a(k) = '1') then m_byteena_mask_reg_a_out(k) := '0'; m_byteena_mask_reg_a_x(k) := '0'; m_byteena_mask_reg_a_out_b(k) := 'X'; elsif (m_byteena_mask_reg_a(k) = '0') then m_byteena_mask_reg_a_x(k) := '0'; m_byteena_mask_reg_a_out(k) := 'X'; m_byteena_mask_reg_a_out_b(k) := '0'; else m_byteena_mask_reg_a_out(k) := 'X'; m_byteena_mask_reg_a_x(k) := 'X'; m_byteena_mask_reg_a_out_b(k) := 'X'; end if; end loop; end if; end if; i_byteena_mask_reg_a_out <= m_byteena_mask_reg_a_out; i_byteena_mask_reg_a <= m_byteena_mask_reg_a; i_byteena_mask_reg_a_x <= m_byteena_mask_reg_a_x; i_byteena_mask_reg_a_out_b <= m_byteena_mask_reg_a_out_b; if (i_address_aclr_a = '1') then i_address_reg_a <= (others => '0'); elsif (addressstall_a /= '1') then i_address_reg_a <= address_a; end if; end if; end if; if (falling_edge(clock0)) then if (i_core_clocken_a = '1') then i_good_to_write_b <= '1'; end if; if (not is_write_positive_edge) then if (i_nmram_write_a = '1') then i_write_flag_a <= not i_write_flag_a; if (i_is_lutram) then i_read_flag_a <= not i_read_flag_a; end if; end if; end if; end if; end process; IFCLR01 : if ((HAS_STRATIXV_STYLE_RAM) or (IS_CYCLONEIII)) generate process (i_outdata_aclr_a) begin if ((outdata_reg_a /= "CLOCK0") and (outdata_reg_a /= "CLOCK1")) then if (rising_edge(i_outdata_aclr_a)) then i_reread_flag_a <= not i_reread_flag_a; end if; end if; end process; process (i_outdata_aclr_b) begin if ((outdata_reg_b /= "CLOCK0") and (outdata_reg_b /= "CLOCK1")) then if (rising_edge(i_outdata_aclr_b)) then i_reread_flag_b <= not i_reread_flag_b; end if; end if; end process; end generate IFCLR01; IFCLR02 : if (i_is_lutram and (operation_mode = "DUAL_PORT")) generate process (i_address_aclr_b) begin if (rising_edge(i_address_aclr_b)) then i_reread_flag2_b <= not i_reread_flag2_b; end if; end process; end generate IFCLR02; IFCLR03 : if (i_is_lutram and (operation_mode = "ROM")) generate process (i_address_aclr_a) begin if (rising_edge(i_address_aclr_a)) then i_reread_flag2_a <= not i_reread_flag2_a; end if; end process; end generate IFCLR03; -- Port B address input registered (for dual_port mode) IFG48: if (((address_reg_b = "CLOCK0") or (address_reg_b = "CLOCK1")) and (operation_mode = "DUAL_PORT")) generate process (clock0, clock1, i_address_aclr_b) variable need_init_var : boolean := true; begin if (need_init_var = true) then if ((IS_HARDCOPYII) and (ram_block_type = "M4K") and (operation_mode /= "SINGLE_PORT") and (((address_reg_b = "CLOCK0") and (clock0 = '1')) or ((address_reg_b = "CLOCK1") and (clock1 = '1')))) then i_good_to_write_a <= '0'; end if; need_init_var := false; end if; if (rising_edge(i_address_aclr_b)) then if (i_address_aclr_b = '1') then if (i_is_lutram) then i_address_reg_b <= (others => '0'); i_read_flag_b <= not i_read_flag_b; end if; end if; end if; if ((rising_edge(clock0) and (address_reg_b = "CLOCK0")) or (rising_edge(clock1) and (address_reg_b = "CLOCK1"))) then i_core_clocken_b_reg <= i_core_clocken_b; if (i_force_reread_b = '1' and (i_outlatch_clken_b = '1')) then i_force_reread_signal_b <= not i_force_reread_signal_b; end if; if (i_address_aclr_b = '1') then i_address_reg_b <= (others => '0'); end if; if (i_core_clocken_b = '1') then if (i_force_reread_b1 = '1') then i_force_reread_signal_b <= not i_force_reread_signal_b; end if; if ((HAS_STRATIXV_STYLE_RAM or IS_STRATIXIII) and not i_is_lutram) then good_to_go_b <= '1'; if (i_rdcontrol_aclr_b = '1') then i_rden_reg_b <= '1'; else i_rden_reg_b <= rden_b; end if; end if; end if; if (i_input_clocken_b = '1') then if (((not HAS_STRATIXV_STYLE_RAM) and (not IS_STRATIXIII)) or i_is_lutram) then good_to_go_b <= '1'; if (i_rdcontrol_aclr_b = '1') then i_rden_reg_b <= '1'; else i_rden_reg_b <= rden_b; end if; end if; if (i_indata_aclr_b = '1') then i_data_reg_b <= (others => '0'); else i_data_reg_b <= data_b; end if; if (i_address_aclr_b = '1') then i_address_reg_b <= (others => '0'); elsif (addressstall_b /= '1') then i_address_reg_b <= address_b; end if; end if; if (not i_lutram_dual_port_fast_read and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) then if (i_core_clocken_b = '1') then i_read_flag_b <= not i_read_flag_b; end if; elsif (((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)) or (i_is_lutram)) then if (i_input_clocken_b = '1') then i_read_flag_b <= not i_read_flag_b; end if; end if; end if; if (((i_is_lutram) and (i_lutram_dual_port_fast_read)) and falling_edge(clock0)) then if (i_core_clocken_b = '1') then i_read_flag_b <= not i_read_flag_b; end if; end if; if ((falling_edge(clock0) and (address_reg_b = "CLOCK0")) or (falling_edge(clock1) and (address_reg_b = "CLOCK1"))) then if (i_core_clocken_b = '1') then i_good_to_write_a <= '1'; end if; end if; end process; end generate IFG48; -- Port B inputs registered : wren, address, byteena (for bidir_dual_port mode) IFG49: if (((address_reg_b = "CLOCK0") or (address_reg_b = "CLOCK1")) and (operation_mode = "BIDIR_DUAL_PORT")) generate process (clock0, clock1) variable m_byteena_mask_reg_b : std_logic_vector(width_b - 1 downto 0); variable m_byteena_mask_reg_b_out : std_logic_vector(width_b - 1 downto 0); variable m_byteena_mask_reg_b_x : std_logic_vector(width_b - 1 downto 0) := (others => '0'); variable m_byteena_mask_reg_b_out_a : std_logic_vector(width_b - 1 downto 0); variable need_init_var : boolean := true; begin if (need_init_var = true) then if ((IS_HARDCOPYII) and (ram_block_type = "M4K") and (operation_mode /= "SINGLE_PORT") and (((address_reg_b = "CLOCK0") and (clock0 = '1')) or ((address_reg_b = "CLOCK1") and (clock1 = '1')))) then i_good_to_write_a <= '0'; end if; need_init_var := false; end if; if (((address_reg_b = "CLOCK0") and (rising_edge(clock0))) or ((address_reg_b = "CLOCK1") and (rising_edge(clock1)))) then if (i_force_reread_b = '1' and (i_outlatch_clken_b = '1')) then i_force_reread_signal_b <= not i_force_reread_signal_b; end if; if (i_core_clocken_b = '1') then if (HAS_STRATIXV_STYLE_RAM or IS_STRATIXIII) then good_to_go_b <= '1'; if (i_rdcontrol_aclr_b = '1') then i_rden_reg_b <= '1'; else i_rden_reg_b <= rden_b; end if; if (i_wrcontrol_aclr_b = '1') then i_wren_reg_b <= '0'; else i_wren_reg_b <= wren_b; i_read_flag_b <= not i_read_flag_b; end if; end if; else i_nmram_write_b <= '0'; end if; if (i_input_clocken_b = '1') then if ((not HAS_STRATIXV_STYLE_RAM) and (not HAS_STRATIXIII_STYLE_RAM)) then i_read_flag_b <= not i_read_flag_b; end if; if (i_indata_aclr_b = '1') then i_data_reg_b <= (others => '0'); else i_data_reg_b <= data_b; end if; if ((not HAS_STRATIXV_STYLE_RAM) and (not IS_STRATIXIII)) then good_to_go_b <= '1'; if (i_rdcontrol_aclr_b = '1') then i_rden_reg_b <= '1'; else i_rden_reg_b <= rden_b; end if; if (i_wrcontrol_aclr_b = '1') then i_wren_reg_b <= '0'; else i_wren_reg_b <= wren_b; end if; end if; if (i_wrcontrol_aclr_b = '1') then i_address_reg_b <= (others => '0'); elsif (addressstall_b /= '1') then i_address_reg_b <= address_b; end if; if (i_byteena_aclr_b = '1') then m_byteena_mask_reg_b := (others => '1'); m_byteena_mask_reg_b_out := (others => '0'); m_byteena_mask_reg_b_x := (others => '0'); m_byteena_mask_reg_b_out_a := (others => 'X'); else if (width_byteena_b = 1) then if (byteena_b(0) = 'Z') then m_byteena_mask_reg_b := (others => '1'); else m_byteena_mask_reg_b := (others => byteena_b(0)); end if; if ((byteena_b(0) = '1') or (byteena_b(0) = 'Z')) then m_byteena_mask_reg_b_out := (others => '0'); m_byteena_mask_reg_b_x := (others => '0'); m_byteena_mask_reg_b_out_a := (others => 'X'); elsif (byteena_b(0) = '0') then m_byteena_mask_reg_b_x := (others => '0'); m_byteena_mask_reg_b_out := (others => 'X'); m_byteena_mask_reg_b_out_a := (others => '0'); else m_byteena_mask_reg_b_x := (others => 'X'); m_byteena_mask_reg_b_out := (others => 'X'); m_byteena_mask_reg_b_out_a := (others => 'X'); end if; else for k in 0 to (width_b - 1) loop if (byteena_b(k / i_byte_size) = 'Z') then m_byteena_mask_reg_b(k) := '1'; else m_byteena_mask_reg_b(k) := byteena_b(k / i_byte_size); end if; if (m_byteena_mask_reg_b(k) = '1') then m_byteena_mask_reg_b_out(k) := '0'; m_byteena_mask_reg_b_x(k) := '0'; m_byteena_mask_reg_b_out_a(k) := 'X'; elsif (m_byteena_mask_reg_b(k) = '0') then m_byteena_mask_reg_b_out(k) := 'X'; m_byteena_mask_reg_b_x(k) := '0'; m_byteena_mask_reg_b_out_a(k) := '0'; else m_byteena_mask_reg_b_out(k) := 'X'; m_byteena_mask_reg_b_x(k) := 'X'; m_byteena_mask_reg_b_out_a(k) := 'X'; end if; end loop; end if; end if; i_byteena_mask_reg_b_out <= m_byteena_mask_reg_b_out; i_byteena_mask_reg_b <= m_byteena_mask_reg_b; i_byteena_mask_reg_b_x <= m_byteena_mask_reg_b_x; i_byteena_mask_reg_b_out_a <= m_byteena_mask_reg_b_out_a; end if; if ((i_core_clocken_b = '1') and ((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM))) then i_read_flag_b <= not i_read_flag_b; end if; if ((i_core_clocken_b = '1') and ((wren_b = '1') or (i_wren_reg_b = '1'))) then if (is_write_positive_edge) then i_write_flag_b <= not i_write_flag_b; end if; i_nmram_write_b <= '1'; end if; end if; if (((address_reg_b = "CLOCK0") and (falling_edge(clock0))) or ((address_reg_b = "CLOCK1") and (falling_edge(clock1)))) then if (i_core_clocken_b = '1') then i_good_to_write_a <= '1'; end if; if (not is_write_positive_edge) then if ((i_nmram_write_b = '1') and (i_wren_reg_b = '1')) then i_write_flag_b <= not i_write_flag_b; end if; end if; end if; end process; end generate IFG49; -- Port A : assigning the correct output values for i_q_tmp_a (non-registered output) process (i_q_tmp2_a, i_force_reread_signal_a, i_outdata_aclr_a, good_to_go_a, default_val, i_address_aclr_a) variable i_force_reread_a1_flag : std_logic := '0'; begin if (not good_to_go_a = '1') then if (i_is_lutram) then i_q_tmp_a <= i_q_tmp2_a; else i_q_tmp_a <= (others => default_val); end if; else if ((i_outdata_aclr_a = '1')and (outdata_reg_a /= "CLOCK0") and (outdata_reg_a /= "CLOCK1") and (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (not i_is_lutram))) then i_q_tmp_a <= (others => '0'); elsif (falling_edge(i_outdata_aclr_a)and (outdata_reg_a /= "CLOCK0") and (outdata_reg_a /= "CLOCK1") and (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (not i_is_lutram))) then i_force_reread_a <= '1'; elsif (rising_edge(i_address_aclr_a) and (outdata_reg_a /= "CLOCK0") and (outdata_reg_a /= "CLOCK1") and (((HAS_STRATIXV_STYLE_RAM) or (IS_BASE_STRATIXIII)) and (not i_is_lutram))) then i_q_tmp_a <= (others => 'X'); i_force_reread_a1 <= '1'; i_force_reread_a1_flag := '1'; elsif ((i_force_reread_signal_a'event) or (i_force_reread_a1_flag = '0' and i_force_reread_a = '0')) then if(i_force_reread_a = '0' or (not HAS_STRATIXV_STYLE_RAM)) then i_q_tmp_a <= i_q_tmp2_a; end if; i_force_reread_a1 <= '0'; i_force_reread_a <= '0'; i_force_reread_a1_flag := '0'; elsif (i_force_reread_a = '1')then i_q_tmp_a <= (others => '0'); end if; end if; end process; -- Port A outdata output registered process (clock0, clock1, i_outdata_aclr_a, i_address_aclr_a, i_rden_reg_a) variable i_address_aclr_a_flag : std_logic := '0'; begin if ((i_address_aclr_a'event) and (i_address_aclr_a = '1') and (i_rden_reg_a = '1')) then i_address_aclr_a_flag := '1'; end if; if (i_outdata_aclr_a = '1') then i_q_reg_a <= (others => '0'); i_address_aclr_a_flag := '0'; elsif (((outdata_reg_a = "CLOCK0") and (rising_edge(clock0))) or ((outdata_reg_a = "CLOCK1") and (rising_edge(clock1)))) then if i_outdata_clken_a = '1' then -- clear for 1 clock cycle if ((i_address_aclr_a_flag = '1') and ((HAS_STRATIXV_STYLE_RAM) or (IS_BASE_STRATIXIII)) and (outdata_reg_a = "CLOCK0") and (not i_is_lutram)) then i_q_reg_a <= (others => 'X'); else i_q_reg_a <= i_q_tmp_a; end if; if (i_core_clocken_a = '1') then i_address_aclr_a_flag := '0'; end if; elsif (i_core_clocken_a = '1') then i_address_aclr_a_flag := '0'; end if; end if; end process; -- Port A : assigning the correct output values for q_a IFG52: if (((outdata_reg_a = "CLOCK0") or (outdata_reg_a = "CLOCK1")) and (operation_mode /= "DUAL_PORT")) generate q_a <= i_q_reg_a; end generate IFG52; IFG53: if (((outdata_reg_a /= "CLOCK0") and (outdata_reg_a /= "CLOCK1")) and (operation_mode /= "DUAL_PORT")) generate q_a <= i_q_tmp_a; end generate IFG53; IFG54: if (operation_mode = "DUAL_PORT") generate q_a <= (others => '0'); end generate IFG54; -- Port B : assigning the correct output values for i_q_tmp_b (non-registered output) process (i_q_tmp2_b, good_to_go_b, i_rden_reg_b, i_wren_reg_b, i_data_reg_b, i_address_aclr_b, i_byteena_mask_reg_b_out, default_val, i_address_reg_b, i_core_clocken_b, i_original_data_b, i_outdata_aclr_b, i_force_reread_signal_b) variable i_force_reread_b1_flag : std_logic := '0'; variable m_address_a : integer := 0; variable m_address_b : integer := 0; begin if ((operation_mode = "DUAL_PORT") or (operation_mode = "BIDIR_DUAL_PORT")) then if (not good_to_go_b = '1') then if (i_is_lutram) then i_q_tmp_b <= i_q_tmp2_b; else i_q_tmp_b <= (others => default_val); end if; else if (i_q_tmp2_b'event or good_to_go_b'event or i_rden_reg_b'event or i_wren_reg_b'event or i_data_reg_b'event or i_byteena_mask_reg_b_out'event or i_address_reg_b'event or i_original_data_b'event or i_force_reread_signal_b'event) then if (((i_rden_reg_b = '1') and (i_force_reread_b1_flag = '0')) or (i_is_lutram)) then if ((conv_integer(unsigned(i_address_reg_b)) >= i_numwords_b)) then if ((i_wren_reg_b = '1') and (i_core_clocken_b = '1')) then i_q_tmp_b <= i_q_tmp2_b; else i_q_tmp_b <= (others => 'X'); end if; assert false report "Address pointed at port B is out of bound! " severity warning; else i_q_tmp_b <= i_q_tmp2_b; end if; end if; end if; if ((i_outdata_aclr_b = '1') and (outdata_reg_b /= "CLOCK0") and (outdata_reg_b /= "CLOCK1") and (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (not i_is_lutram))) then i_q_tmp_b <= (others => '0'); elsif (falling_edge(i_outdata_aclr_b)and (outdata_reg_b /= "CLOCK0") and (outdata_reg_b /= "CLOCK1") and (((HAS_STRATIXV_STYLE_RAM) or (HAS_STRATIXIII_STYLE_RAM)) and (not i_is_lutram))) then i_force_reread_b <= '1'; elsif (rising_edge(i_address_aclr_b) and (outdata_reg_b /= "CLOCK0") and (outdata_reg_b /= "CLOCK1") and ((HAS_STRATIXV_STYLE_RAM) or (IS_BASE_STRATIXIII)) and (not i_is_lutram)) then if (i_rden_reg_b = '1') then i_q_tmp_b <= (others => 'X'); end if; i_force_reread_b1 <= '1'; i_force_reread_b1_flag := '1'; elsif (i_force_reread_signal_b'event) then if(i_force_reread_b = '0' or (not HAS_STRATIXV_STYLE_RAM)) then i_q_tmp_b <= i_q_tmp2_b; end if; i_force_reread_b <= '0'; i_force_reread_b1 <= '0'; i_force_reread_b1_flag := '0'; elsif(i_force_reread_b = '1') then i_q_tmp_b <= (others => '0'); end if; if ((i_is_lutram) and (is_write_positive_edge) and (cread_during_write_mode_mixed_ports = "OLD_DATA")) then m_address_a := conv_integer(unsigned(i_address_reg_a)); m_address_b := conv_integer(unsigned(i_address_reg_b)); if((width_a = width_b) and (m_address_a = m_address_b) and (i_wren_reg_a = '1') and (i_rden_reg_b = '1')) then i_q_tmp_b <= i_original_data_a; else i_q_tmp_b <= i_q_tmp2_b; end if; end if; end if; end if; end process; -- Port B outdata output registered process (clock0, clock1, i_outdata_aclr_b, i_address_aclr_b, i_rden_reg_b) variable i_address_aclr_b_flag : std_logic := '0'; variable m_address_a : integer := 0; variable m_address_b : integer := 0; begin if ((i_address_aclr_b'event) and (i_address_aclr_b = '1') and (i_rden_reg_b = '1')) then i_address_aclr_b_flag := '1'; end if; if (i_outdata_aclr_b = '1') then i_q_reg_b <= (others => '0'); i_address_aclr_b_flag := '0'; elsif (((outdata_reg_b = "CLOCK0") and (rising_edge(clock0))) or ((outdata_reg_b = "CLOCK1") and (rising_edge(clock1)))) then if (i_outdata_clken_b = '1') then if ((i_is_lutram) and (cread_during_write_mode_mixed_ports = "OLD_DATA") and (outdata_reg_b = "CLOCK0")) then i_q_reg_b <= i_q_output_latch; else if ((i_address_aclr_b_flag = '1') and ((HAS_STRATIXV_STYLE_RAM) or (IS_BASE_STRATIXIII)) and (outdata_reg_b = "CLOCK0") and (not i_is_lutram)) then i_q_reg_b <= (others => 'X'); else i_q_reg_b <= i_q_tmp_b; end if; if (i_core_clocken_b = '1') then i_address_aclr_b_flag := '0'; end if; end if; elsif (i_core_clocken_b = '1') then i_address_aclr_b_flag := '0'; end if; end if; if (((outdata_reg_b = "CLOCK0") and (falling_edge(clock0))) or ((outdata_reg_b = "CLOCK1") and (falling_edge(clock1)))) then if (i_core_clocken_a = '1') then m_address_a := conv_integer(unsigned(i_address_reg_a)); m_address_b := conv_integer(unsigned(i_address_reg_b)); if((width_a = width_b) and (m_address_a = m_address_b) and (i_wren_reg_a = '1') and (i_rden_reg_b = '1')) then i_q_output_latch <= i_original_data_a; else i_q_output_latch <= i_q_tmp_b; end if; end if; end if; end process; -- ECC Pipeline Register process (clock0, clock1, i_outdata_aclr_b) begin if (i_outdata_aclr_b = '1') then i_q_ecc_reg_b <= (others => '0'); elsif (((outdata_reg_b = "CLOCK0") and (rising_edge(clock0))) or ((outdata_reg_b = "CLOCK1") and (rising_edge(clock1)))) then if (i_outdata_clken_b = '1') then i_q_ecc_reg_b <= i_q_reg_b; end if; end if; end process; -- Port B : assigning the correct output values for q_b IFG55: if ((ecc_pipeline_stage_enabled = "FALSE") and ((outdata_reg_b = "CLOCK0") or (outdata_reg_b = "CLOCK1")) and (operation_mode /= "SINGLE_PORT") and (operation_mode /= "ROM")) generate q_b <= i_q_reg_b; end generate IFG55; IFG56: if ((ecc_pipeline_stage_enabled = "FALSE") and ((outdata_reg_b /= "CLOCK0") and (outdata_reg_b /= "CLOCK1")) and (operation_mode /= "SINGLE_PORT") and (operation_mode /= "ROM")) generate q_b <= i_q_tmp_b; end generate IFG56; IFG57: if ((operation_mode = "SINGLE_PORT") or (operation_mode = "ROM")) generate q_b <= (others => '0'); end generate IFG57; IFG58: if ((ecc_pipeline_stage_enabled = "TRUE") and ((outdata_reg_b = "CLOCK0") or (outdata_reg_b = "CLOCK1")) and (operation_mode /= "SINGLE_PORT") and (operation_mode /= "ROM")) generate q_b <= i_q_ecc_reg_b; end generate IFG58; IFG59: if ((ecc_pipeline_stage_enabled = "TRUE") and ((outdata_reg_b /= "CLOCK0") and (outdata_reg_b /= "CLOCK1")) and (operation_mode /= "SINGLE_PORT") and (operation_mode /= "ROM")) generate q_b <= i_q_ecc_tmp_b; --i_q_ecc_tmp_b has 'x' output end generate IFG59; -- ECC status eccstatus <= (others => '0'); end translated; -- END OF ARCHITECTURE ALTSYNCRAM -------------------------------------------------------------------------------+ -- Module Name : alt3pram -- -- Description : Triple-Port RAM megafunction. This megafunction implements -- RAM with 1 write port and 2 read ports. -- -- Limitation : This megafunction is provided only for backward -- compatibility in Stratix™ designs; instead, Altera® -- recommends using the altsyncram megafunction -- -- In MAX 3000, and MAX 7000 devices, -- or if the USE_EAB paramter is set to "OFF", uses one -- logic cell (LCs) per memory bit. -- -- -- Results expected : The alt3pram function represents asynchronous memory -- or memory with synchronous inputs and/or outputs. -- (note: ^ below indicates posedge) -- -- [ Synchronous Write to Memory (all inputs registered) ] -- inclock inclocken wren Function -- X L L No change. -- not ^ H H No change. -- ^ L X No change. -- ^ H H The memory location -- pointed to by wraddress[] -- is loaded with data[]. -- -- [ Synchronous Read from Memory ] -- inclock inclocken rden_a/rden_b Function -- X L L No change. -- not ^ H H No change. -- ^ L X No change. -- ^ H H The q_a[]/q_b[]port -- outputs the contents of -- the memory location. -- -- [ Asynchronous Memory Operations ] -- wren Function -- L No change. -- H The memory location pointed to by wraddress[] is -- loaded with data[] and controlled by wren. -- The output q_a[] is asynchronous and reflects -- the memory location pointed to by rdaddress_a[]. -- -------------------------------------------------------------------------------+ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use std.textio.all; use work.ALTERA_DEVICE_FAMILIES.all; use work.ALTERA_COMMON_CONVERSION.all; use work.altsyncram; use work.ALTERA_MF_HINT_EVALUATION.all; --------------------- -- ENTITY DECLARATION --------------------- entity alt3pram is generic ( width : natural; -- data[], qa[] and qb[] widthad : natural; -- rdaddress_a,rdaddress_b,wraddress numwords : natural := 0; -- words stored in memory lpm_file : string := "UNUSED"; -- name of hex file lpm_hint : string := "USE_EAB=ON"; -- non-LPM parameters (Altera) indata_reg : string := "UNREGISTERED";-- clock used by data[] port indata_aclr : string := "ON"; -- aclr affects data[]? write_reg : string := "UNREGISTERED";-- clock used by wraddress & wren write_aclr : string := "ON"; -- aclr affects wraddress? rdaddress_reg_a : string := "UNREGISTERED";-- clock used by readdress_a rdaddress_aclr_a : string := "ON"; -- aclr affects rdaddress_a? rdaddress_reg_b : string := "UNREGISTERED";-- clock used by readdress_b rdaddress_aclr_b : string := "ON"; -- aclr affects rdaddress_b? rdcontrol_reg_a : string := "UNREGISTERED";-- clock used by rden_a rdcontrol_aclr_a : string := "ON"; -- aclr affects rden_a? rdcontrol_reg_b : string := "UNREGISTERED";-- clock used by rden_b rdcontrol_aclr_b : string := "ON"; -- aclr affects rden_b? outdata_reg_a : string := "UNREGISTERED";-- clock used by qa[] outdata_aclr_a : string := "ON"; -- aclr affects qa[]? outdata_reg_b : string := "UNREGISTERED";-- clock used by qb[] outdata_aclr_b : string := "ON"; -- aclr affects qb[]? intended_device_family : string := "Stratix"; ram_block_type : string := "AUTO"; -- ram block type to be used maximum_depth : integer := 0; -- maximum segmented value of the RAM lpm_type : string := "alt3pram" ); port ( wren : in std_logic := '0'; data : in std_logic_vector(width-1 downto 0); wraddress : in std_logic_vector(widthad-1 downto 0); inclock : in std_logic := '0'; inclocken : in std_logic := '1'; rden_a : in std_logic := '1'; rden_b : in std_logic := '1'; rdaddress_a : in std_logic_vector(widthad-1 downto 0); rdaddress_b : in std_logic_vector(widthad-1 downto 0); outclock : in std_logic := '0'; outclocken : in std_logic := '1'; aclr : in std_logic := '0'; qa : out std_logic_vector(width-1 downto 0); qb : out std_logic_vector(width-1 downto 0) ); end alt3pram; -- Entity: alt3pram --------------------------- -- ARCHITECTURE DECLARATION --------------------------- architecture behavior of alt3pram is ------------------------ -- FUNCTION DECLARATION ------------------------ -- The following functions take in parameters values used in alt3pram and convert -- to a corresponding(or suitable) parameters value that used in altsyncram. function get_num_words (i_numwords : natural; i_widthad : natural) return integer is begin if (i_numwords = 0) then return 2**i_widthad; else return i_numwords; end if; end; function get_read_during_write_mode_mixed_ports(i_ram_block_type : string) return string is begin if (i_ram_block_type = "AUTO") then return "OLD_DATA"; else return "DONT_CARE"; end if; end; function get_write_aclr_a_clk(i_write_aclr : string) return string is begin if ((not FEATURE_FAMILY_STRATIXII(intended_device_family)) and i_write_aclr = "ON") then return "CLEAR0"; else return "NONE"; end if; end; function get_indata_aclr_a_clk(i_indata_aclr : string) return string is begin if ((not FEATURE_FAMILY_STRATIXII(intended_device_family)) and i_indata_aclr = "ON") then return "CLEAR0"; else return "NONE"; end if; end; function get_rdcontrol_reg_a_clk(i_rdcontrol_reg_a : string) return string is begin if (i_rdcontrol_reg_a = "INCLOCK") then return "CLOCK0"; elsif (i_rdcontrol_reg_a = "OUTCLOCK") then return "CLOCK1"; else return "UNUSED"; end if; end; function get_rdaddress_reg_a_clk(i_rdaddress_reg_a : string) return string is begin if (i_rdaddress_reg_a = "INCLOCK") then return "CLOCK0"; elsif (i_rdaddress_reg_a = "OUTCLOCK") then return "CLOCK1"; else return "UNUSED"; end if; end; function get_outdata_reg_a_clk(i_outdata_reg_a : string) return string is begin if (i_outdata_reg_a = "INCLOCK") then return "CLOCK0"; elsif (i_outdata_reg_a = "OUTCLOCK") then return "CLOCK1"; else return "UNREGISTERED"; end if; end; function get_outdata_aclr_a_clk(i_outdata_aclr_a : string) return string is begin if (i_outdata_aclr_a = "ON") then return "CLEAR0"; else return "NONE"; end if; end; function get_rdcontrol_aclr_a_clk(i_rdcontrol_aclr_a : string) return string is begin if ((not FEATURE_FAMILY_STRATIXII(intended_device_family)) and i_rdcontrol_aclr_a = "ON") then return "CLEAR0"; else return "NONE"; end if; end; function get_rdaddress_aclr_a_clk(i_rdaddress_aclr_a : string) return string is begin if ((not FEATURE_FAMILY_STRATIXII(intended_device_family)) and i_rdaddress_aclr_a = "ON") then return "CLEAR0"; else return "NONE"; end if; end; function get_rdcontrol_reg_b_clk(i_rdcontrol_reg_b : string) return string is begin if (i_rdcontrol_reg_b = "INCLOCK") then return "CLOCK0"; elsif (i_rdcontrol_reg_b = "OUTCLOCK") then return "CLOCK1"; else return "UNUSED"; end if; end; function get_rdaddress_reg_b_clk(i_rdaddress_reg_b : string) return string is begin if (i_rdaddress_reg_b = "INCLOCK") then return "CLOCK0"; elsif (i_rdaddress_reg_b = "OUTCLOCK") then return "CLOCK1"; else return "UNUSED"; end if; end; function get_outdata_reg_b_clk(i_outdata_reg_b : string) return string is begin if (i_outdata_reg_b = "INCLOCK") then return "CLOCK0"; elsif (i_outdata_reg_b = "OUTCLOCK") then return "CLOCK1"; else return "UNREGISTERED"; end if; end; function get_outdata_aclr_b_clk(i_outdata_aclr_b : string) return string is begin if (i_outdata_aclr_b = "ON") then return "CLEAR0"; else return "NONE"; end if; end; function get_rdcontrol_aclr_b_clk(i_rdcontrol_aclr_b : string) return string is begin if ((not FEATURE_FAMILY_STRATIXII(intended_device_family)) and i_rdcontrol_aclr_b = "ON") then return "CLEAR0"; else return "NONE"; end if; end; function get_rdaddress_aclr_b_clk(i_rdaddress_aclr_b : string) return string is begin if ((not FEATURE_FAMILY_STRATIXII(intended_device_family)) and i_rdaddress_aclr_b = "ON") then return "CLEAR0"; else return "NONE"; end if; end; ------------------- -- TYPE DECLARATION ------------------- type alt_memory is array((2**WIDTHAD)-1 downto 0) of std_logic_vector(WIDTH-1 downto 0); ----------------------- -- CONSTANT DECLARATION ----------------------- constant IS_STRATIX : boolean := FEATURE_FAMILY_STRATIX(intended_device_family); constant NUM_WORDS : integer := get_num_words(numwords, widthad); constant READ_DURING_WRITE_MODE : string := get_read_during_write_mode_mixed_ports(ram_block_type); constant WRITE_ACLR_A_CLK : string := get_write_aclr_a_clk(write_aclr); constant INDATA_ACLR_A_CLK : string := get_indata_aclr_a_clk(indata_aclr); constant RDCONTROL_REG_A_CLK : string := get_rdcontrol_reg_a_clk(rdcontrol_reg_a); constant RDADDRESS_REG_A_CLK : string := get_rdaddress_reg_a_clk(rdaddress_reg_a); constant OUTDATA_REG_A_CLK : string := get_outdata_reg_a_clk(outdata_reg_a); constant OUTDATA_ACLR_A_CLK : string := get_outdata_aclr_a_clk(outdata_aclr_a); constant RDCONTROL_ACLR_A_CLK : string := get_rdcontrol_aclr_a_clk(rdcontrol_aclr_a); constant RDADDRESS_ACLR_A_CLK : string := get_rdaddress_aclr_a_clk(rdaddress_aclr_a); constant RDCONTROL_REG_B_CLK : string := get_rdcontrol_reg_b_clk(rdcontrol_reg_b); constant RDADDRESS_REG_B_CLK : string := get_rdaddress_reg_b_clk(rdaddress_reg_b); constant OUTDATA_REG_B_CLK : string := get_outdata_reg_b_clk(outdata_reg_b); constant OUTDATA_ACLR_B_CLK : string := get_outdata_aclr_b_clk(outdata_aclr_b); constant RDCONTROL_ACLR_B_CLK : string := get_rdcontrol_aclr_b_clk(rdcontrol_aclr_b); constant RDADDRESS_ACLR_B_CLK : string := get_rdaddress_aclr_b_clk(rdaddress_aclr_b); constant LPM_HINT_USE_EAB : string := GET_PARAMETER_VALUE(lpm_hint, "USE_EAB"); --------------------- -- SIGNAL DECLARATION --------------------- signal idata_tmp : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal idata_reg : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal idata_hi : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal idata_lo : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal iqa_tmp : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal iqa_reg : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal iqb_tmp : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal iqb_reg : std_logic_vector(WIDTH-1 downto 0) := (OTHERS => '0'); signal iwren_tmp : std_logic := '0'; signal iwren_reg : std_logic := '0'; signal iwren_hi : std_logic := '0'; signal iwren_lo : std_logic := '0'; signal irdaddress_tmp_a : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal irdaddress_reg_a : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal irdaddress_tmp_b : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal irdaddress_reg_b : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal iwraddress_tmp : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal iwraddress_reg : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal iwraddress_hi : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal iwraddress_lo : std_logic_vector(WIDTHAD-1 downto 0) := (OTHERS => '0'); signal irden_tmp_a : std_logic := '0'; signal irden_reg_a : std_logic := '0'; signal irden_tmp_b : std_logic := '0'; signal irden_reg_b : std_logic := '0'; signal unused_port0 : std_logic_vector(width-1 downto 0); signal unused_port1 : std_logic_vector(width-1 downto 0); signal iqa_non_stratix : std_logic_vector(width-1 downto 0); signal iqb_non_stratix : std_logic_vector(width-1 downto 0); signal iqa_stratix : std_logic_vector(width-1 downto 0); signal iqb_stratix : std_logic_vector(width-1 downto 0); signal iinclock_non_stratix : std_logic; -- inclock signal for non-Stratix families signal ioutclock_non_stratix : std_logic; -- outclock signal for non-Stratix families signal write_at_low_clock : boolean := false; signal rden_low_output_0 : boolean := false; -------------------------- -- COMPONENTS DECLARATION -------------------------- component altsyncram GENERIC ( operation_mode : string := "SINGLE_PORT"; width_a : natural := 8; widthad_a : natural := 2; numwords_a : natural := 4; address_aclr_a : string := "NONE"; indata_aclr_a : string := "CLEAR0"; wrcontrol_aclr_a : string := "NONE"; width_b : natural := 8; widthad_b : natural := 4; numwords_b : natural := 4; rdcontrol_reg_b : string := "CLOCK1"; address_reg_b : string := "CLOCK1"; outdata_reg_b : string := "UNREGISTERED"; outdata_aclr_b : string := "NONE"; rdcontrol_aclr_b : string := "NONE"; address_aclr_b : string := "NONE"; read_during_write_mode_mixed_ports: string := READ_DURING_WRITE_MODE; ram_block_type : string := "AUTO"; init_file : string := "UNUSED"; init_file_layout : string := "UNUSED"; maximum_depth : integer := 0; intended_device_family : string := "Stratix" ); PORT ( wren_a : IN std_logic := '0'; rden_b : IN std_logic := '1'; data_a : IN std_logic_vector(width_a - 1 DOWNTO 0):= (others => '0'); address_a : IN std_logic_vector(widthad_a - 1 DOWNTO 0) := (others => '0'); address_b : IN std_logic_vector(widthad_b - 1 DOWNTO 0) := (others => '0'); clock0 : IN std_logic := '1'; clock1 : IN std_logic := '1'; clocken0 : IN std_logic := '1'; clocken1 : IN std_logic := '1'; aclr0 : IN std_logic := '0'; q_a : OUT std_logic_vector(width_a - 1 DOWNTO 0); q_b : OUT std_logic_vector(width_b - 1 DOWNTO 0)); END component; begin -------------------------- -- COMPONENTS ASSIGNMENTS -------------------------- -- The alt3pram for Stratix/Stratix II/ Stratix GX and Cyclone device families -- are basically consists of 2 instances of altsyncram with write port of each -- instance been tied together. STRATIX_DUALPORT_RAM0: if (IS_STRATIX = true) generate U0: altsyncram generic map ( operation_mode => "DUAL_PORT", width_a => width, widthad_a => widthad, numwords_a => NUM_WORDS, address_aclr_a => WRITE_ACLR_A_CLK, indata_aclr_a => INDATA_ACLR_A_CLK, wrcontrol_aclr_a => WRITE_ACLR_A_CLK, width_b => width, widthad_b => widthad, numwords_b => NUM_WORDS, rdcontrol_reg_b => RDCONTROL_REG_A_CLK, address_reg_b => RDADDRESS_REG_A_CLK, outdata_reg_b => OUTDATA_REG_A_CLK, outdata_aclr_b => OUTDATA_ACLR_A_CLK, rdcontrol_aclr_b => RDCONTROL_ACLR_A_CLK, address_aclr_b => RDADDRESS_ACLR_A_CLK, read_during_write_mode_mixed_ports => READ_DURING_WRITE_MODE, ram_block_type => ram_block_type, init_file => lpm_file, init_file_layout => "PORT_B", maximum_depth => maximum_depth, intended_device_family => intended_device_family) port map ( wren_a => wren, rden_b => rden_a, data_a => data, address_a => wraddress, address_b => rdaddress_a, clock0 => inclock, clock1 => outclock, clocken0 => inclocken, clocken1 => outclocken, aclr0 => aclr, q_a => unused_port0, q_b => iqa_stratix); end generate STRATIX_DUALPORT_RAM0; STRATIX_DUALPORT_RAM1: if (IS_STRATIX = true) generate U1: altsyncram generic map ( operation_mode => "DUAL_PORT", width_a => width, widthad_a => widthad, numwords_a => NUM_WORDS, address_aclr_a => WRITE_ACLR_A_CLK, indata_aclr_a => INDATA_ACLR_A_CLK, wrcontrol_aclr_a => WRITE_ACLR_A_CLK, width_b => width, widthad_b => widthad, numwords_b => NUM_WORDS, rdcontrol_reg_b => RDCONTROL_REG_B_CLK, address_reg_b => RDADDRESS_REG_B_CLK, outdata_reg_b => OUTDATA_REG_B_CLK, outdata_aclr_b => OUTDATA_ACLR_B_CLK, rdcontrol_aclr_b => RDCONTROL_ACLR_B_CLK, address_aclr_b => RDADDRESS_ACLR_B_CLK, read_during_write_mode_mixed_ports => READ_DURING_WRITE_MODE, ram_block_type => ram_block_type, init_file => lpm_file, init_file_layout => "PORT_B", maximum_depth => maximum_depth, intended_device_family => intended_device_family) port map ( wren_a => wren, rden_b => rden_b, data_a => data, address_a => wraddress, address_b => rdaddress_b, clock0 => inclock, clock1 => outclock, clocken0 => inclocken, clocken1 => outclocken, aclr0 => aclr, q_a => unused_port1, q_b => iqb_stratix); end generate STRATIX_DUALPORT_RAM1; -- ****************** -- SIGNAL ASSIGNMENTS -- ****************** qa <= iqa_stratix when (IS_STRATIX = true) else iqa_non_stratix; qb <= iqb_stratix when (IS_STRATIX = true) else iqb_non_stratix; iinclock_non_stratix <= inclock when (IS_STRATIX = false) else '0'; ioutclock_non_stratix <= outclock when (IS_STRATIX = false) else '0'; -- ************* -- PROCESS BLOCK -- ************* -- The following process blocks are used to implement the alt3pram behavior for -- device families other than Stratix/Stratix II/Stratix GX and Cyclone. -- Initial Block ---------------- INITIAL: process (iinclock_non_stratix, ioutclock_non_stratix) variable init : boolean := false; begin if (not init) then if (LPM_HINT_USE_EAB = "ON") then -- ------------------------------------------------------------------------- -- the following behaviour come in effect when RAM is implemented in EAB/ESB -- This is the flag to indicate if the memory is constructed using EAB/ESB: -- A write request requires both rising and falling edge of the clock -- to complete. First the data will be clocked in (registered) at the -- rising edge and will not be written into the ESB/EAB memory until -- the falling edge appears on the the write clock. -- No such restriction if the memory is constructed using LCs. if (write_reg = "INCLOCK") then write_at_low_clock <= true; end if; end if; init := true; end if; end process INITIAL; ------------------------- -- Syncronization Process ------------------------- SYNC: process (data, idata_reg, rden_a, rden_b, irden_reg_a, irden_reg_b, rdaddress_a, rdaddress_b, irdaddress_reg_a, irdaddress_reg_b, wren, iwren_reg, wraddress, iwraddress_reg, iqa_tmp, iqb_tmp, iqa_reg, iqb_reg, aclr) begin if ((rdaddress_reg_a = "INCLOCK") or (rdaddress_reg_a = "OUTCLOCK")) then irdaddress_tmp_a <= irdaddress_reg_a; else irdaddress_tmp_a <= rdaddress_a; end if; if ((rdcontrol_reg_a = "INCLOCK") or (rdcontrol_reg_a = "OUTCLOCK")) then irden_tmp_a <= irden_reg_a; else irden_tmp_a <= rden_a; end if; if ((rdaddress_reg_b = "INCLOCK") or (rdaddress_reg_b = "OUTCLOCK")) then irdaddress_tmp_b <= irdaddress_reg_b; else irdaddress_tmp_b <= rdaddress_b; end if; if ((rdcontrol_reg_b = "INCLOCK") or (rdcontrol_reg_b = "OUTCLOCK")) then irden_tmp_b <= irden_reg_b; else irden_tmp_b <= rden_b; end if; if (write_reg = "INCLOCK") then iwraddress_tmp <= iwraddress_reg; iwren_tmp <= iwren_reg; else iwraddress_tmp <= wraddress; iwren_tmp <= wren; end if; if (indata_reg = "INCLOCK") then idata_tmp <= idata_reg; else idata_tmp <= data; end if; if (outdata_reg_a = "OUTCLOCK") then iqa_non_stratix <= iqa_reg; else iqa_non_stratix <= iqa_tmp; end if; if (outdata_reg_b = "OUTCLOCK") then iqb_non_stratix <= iqb_reg; else iqb_non_stratix <= iqb_tmp; end if; if (aclr = '1') then if(indata_aclr = "ON") then idata_tmp <= (OTHERS => '0'); end if; if(write_aclr = "ON") then iwraddress_tmp <= (OTHERS => '0'); iwren_tmp <= '0'; end if; if(rdaddress_aclr_a = "ON") then irdaddress_tmp_a <= (OTHERS => '0'); end if; if(rdcontrol_aclr_a = "ON") then irden_tmp_a <= '0'; end if; if(rdaddress_aclr_b = "ON") then irdaddress_tmp_b <= (OTHERS => '0'); end if; if(rdcontrol_aclr_b = "ON") then irden_tmp_b <= '0'; end if; if(outdata_aclr_a = "ON") then iqa_non_stratix <= (OTHERS => '0'); end if; if(outdata_aclr_b = "ON") then iqb_non_stratix <= (OTHERS => '0'); end if; end if; end process SYNC; ------------------------- -- Syncronization Process ------------------------- SYNC2: process (idata_hi, idata_lo, iwraddress_hi, iwraddress_lo, iwren_hi, iwren_lo, write_at_low_clock) begin if (write_at_low_clock) then idata_reg <= idata_lo; iwren_reg <= iwren_lo; iwraddress_reg <= iwraddress_lo; else idata_reg <= idata_hi; iwren_reg <= iwren_hi; iwraddress_reg <= iwraddress_hi; end if; end process SYNC2; ------------------------------------------------- -- Synchronous READ Operation (SHARED CLOCK MODE) ------------------------------------------------- -- READ REGS PORT A ------------------- IFG1: if (rdaddress_reg_a = "INCLOCK") generate process (iinclock_non_stratix, aclr) begin if ((aclr = '1') and (rdaddress_aclr_a = "ON")) then irdaddress_reg_a <= (OTHERS => '0'); elsif rising_edge(iinclock_non_stratix) then if (inclocken = '1') then irdaddress_reg_a <= rdaddress_a; end if; end if; end process; end generate IFG1; IFG2: if (rdcontrol_reg_a = "INCLOCK") generate process (iinclock_non_stratix, aclr) begin if ((aclr = '1') and (rdcontrol_aclr_a = "ON")) then irden_reg_a <= '0'; elsif rising_edge(iinclock_non_stratix) then if (inclocken = '1') then irden_reg_a <= rden_a; end if; end if; end process; end generate IFG2; IFG3: if (rdaddress_reg_a = "OUTCLOCK") generate process (ioutclock_non_stratix, aclr) begin if ((aclr = '1') and (rdaddress_aclr_a = "ON")) then irdaddress_reg_a <= (OTHERS => '0'); elsif rising_edge(ioutclock_non_stratix) then if (outclocken = '1') then irdaddress_reg_a <= rdaddress_a; end if; end if; end process; end generate IFG3; IFG4: if (rdcontrol_reg_a = "OUTCLOCK") generate process (ioutclock_non_stratix, aclr) begin if ((aclr = '1') and (rdcontrol_aclr_a = "ON")) then irden_reg_a <= '0'; elsif rising_edge(ioutclock_non_stratix) then if (outclocken = '1') then irden_reg_a <= rden_a; end if; end if; end process; end generate IFG4; IFG5: if (rdaddress_reg_b = "INCLOCK") generate process (iinclock_non_stratix, aclr) begin if (aclr = '1' and rdaddress_aclr_b = "ON") then irdaddress_reg_b <= (OTHERS => '0'); elsif rising_edge(iinclock_non_stratix) then if (inclocken = '1') then irdaddress_reg_b <= rdaddress_b; end if; end if; end process; end generate IFG5; IFG6: if (rdcontrol_reg_b = "INCLOCK") generate process (iinclock_non_stratix, aclr) begin if (aclr = '1' and rdcontrol_aclr_b = "ON") then irden_reg_b <= '0'; elsif rising_edge(iinclock_non_stratix) then if (inclocken = '1') then irden_reg_b <= rden_b; end if; end if; end process; end generate IFG6; IFG7 : if (rdaddress_reg_b = "OUTCLOCK") generate process (ioutclock_non_stratix, aclr) begin if ((aclr = '1') and (rdaddress_aclr_b = "ON")) then irdaddress_reg_b <= (OTHERS => '0'); elsif rising_edge(ioutclock_non_stratix) then if (outclocken = '1') then irdaddress_reg_b <= rdaddress_b; end if; end if; end process; end generate IFG7; IFG8: if (rdcontrol_reg_b = "OUTCLOCK") generate process (ioutclock_non_stratix, aclr) begin if ((aclr = '1') and (rdcontrol_aclr_b = "ON")) then irden_reg_b <= '0'; elsif rising_edge(ioutclock_non_stratix) then if (outclocken = '1') then irden_reg_b <= rden_b; end if; end if; end process; end generate IFG8; -- At posedge of the write clock: -- All input ports values (data, address and control) are -- clocked in from physical ports to internal variables -- Write Cycle: i*_hi -- Read Cycle: i*_reg (Shared Clock Mode) -- -- At negedge of the write clock: -- Write Cycle: since internally data only completed written on memory -- at the falling edge of write clock, the "write" related -- data, address and controls need to be shift to another -- varibles (i*_hi -> i*_lo) during falling edge. PROC_INCLOCK_OUTCLOCK: process (iinclock_non_stratix, ioutclock_non_stratix, aclr) begin -- WRITE REGS -- if ((aclr = '1') and (indata_aclr = "ON")) then idata_hi <= (OTHERS => '0'); idata_lo <= (OTHERS => '0'); elsif rising_edge(iinclock_non_stratix) then if (inclocken = '1') then idata_hi <= data; end if; elsif falling_edge(iinclock_non_stratix) then idata_lo <= idata_hi; end if; if ((aclr = '1') and (write_aclr = "ON")) then iwraddress_hi <= (OTHERS => '0'); iwraddress_lo <= (OTHERS => '0'); iwren_hi <= '0'; iwren_lo <= '0'; elsif rising_edge(iinclock_non_stratix) then if (inclocken = '1') then iwraddress_hi <= wraddress; iwren_hi <= wren; end if; elsif falling_edge(iinclock_non_stratix) then iwraddress_lo <= iwraddress_hi; iwren_lo <= iwren_hi; end if; -- READ REGS PORT A-- if (aclr = '1' and outdata_aclr_a = "ON") then iqa_reg <= (OTHERS => '0'); elsif rising_edge(ioutclock_non_stratix) then if (outclocken = '1') then iqa_reg <= iqa_tmp; end if; end if; ---------------------------------------------------- -- Synchronouse READ Operation (SEPERATE CLOCK MODE) -- At posedge of read clock: -- Read Cycle: This block is valid only if the operating mode is -- in "Seperate Clock Mode". All read data, address -- and control are clocked out from internal vars -- (i*_reg) to output port. ---------------------------------------------------- -- READ REGS PORT B ------------------- if ((aclr = '1') and (outdata_aclr_b = "ON")) then iqb_reg <= (OTHERS => '0'); elsif rising_edge(ioutclock_non_stratix) then if (outclocken = '1') then iqb_reg <= iqb_tmp; end if; end if; end process PROC_INCLOCK_OUTCLOCK; ----------------------- -- MEMORY Process Block ----------------------- MEMORY: process(idata_tmp, iwren_tmp, irden_tmp_a, irden_tmp_b, irdaddress_tmp_a, irdaddress_tmp_b, iwraddress_tmp, rden_low_output_0) variable mem_data : alt_memory; variable mem_data_word : std_logic_vector(width-1 downto 0) := (OTHERS => '0'); variable mem_init : boolean := false; variable i : integer := 0; variable j : integer := 0; variable k : integer := 0; variable n : integer := 0; variable m : integer := 0; variable lineno : integer := 0; variable buf : line; variable booval : boolean := false; FILE mem_data_file : TEXT; variable char : string(1 downto 1) := " "; variable base : string(2 downto 1) := " "; variable byte : string(2 downto 1) := " "; variable rec_type : string(2 downto 1) := " "; variable datain : string(2 downto 1) := " "; variable addr : string(2 downto 1) := " "; variable checksum : string(2 downto 1) := " "; variable startadd : string(4 downto 1) := " "; variable ibase : integer := 0; variable ibyte : integer := 0; variable istartadd : integer := 0; variable check_sum_vec : std_logic_vector(7 downto 0) := (OTHERS => '0'); variable check_sum_vec_tmp : std_logic_vector(7 downto 0) := (OTHERS => '0'); variable m_string : string(1 to 15); variable m_data_radix : string(1 to 3); variable m_address_radix : string(1 to 3); variable m_width : integer; variable m_depth : integer; variable m_start_address_int : integer := 0; variable m_end_address_int : integer := 0; variable m_address_int : integer := 0; variable m_data_int : std_logic_vector(width+4 downto 0) := (OTHERS => '0'); variable found_keyword_content : boolean := false; variable get_memory_content : boolean := false; variable get_start_Address : boolean := false; variable get_end_Address : boolean := false; begin -- INITIALIZE -- if NOT(mem_init) then --INITIALIZE TO X, IF WRITE_REG IS "UNREGISTERED" if (write_reg = "UNREGISTERED") then for i in mem_data'LOW to mem_data'HIGH loop mem_data(i) := (OTHERS => 'X'); end loop; else -- INITIALIZE TO 0 -- for i in mem_data'LOW to mem_data'HIGH loop mem_data(i) := (OTHERS => '0'); end loop; end if; if (lpm_file /= "UNUSED") then FILE_OPEN(mem_data_file, lpm_file, READ_MODE); if (ALPHA_TOLOWER(lpm_file(lpm_file'length -3 to lpm_file'length)) = ".hex") then -- ************************************************ -- Read in RAM intialization file (hex) -- ************************************************ WHILE NOT ENDFILE(mem_data_file) loop booval := true; READLINE(mem_data_file, buf); lineno := lineno + 1; check_sum_vec := (OTHERS => '0'); if (buf(buf'LOW) = ':') then i := 1; shrink_line(buf, i); READ(L=>buf, VALUE=>byte, good=>booval); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format!" SEVERITY ERROR; end if; ibyte := HEX_STR_TO_INT(byte); check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8)); READ(L=>buf, VALUE=>startadd, good=>booval); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; istartadd := HEX_STR_TO_INT(startadd); addr(2) := startadd(4); addr(1) := startadd(3); check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(addr), 8)); addr(2) := startadd(2); addr(1) := startadd(1); check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(addr), 8)); READ(L=>buf, VALUE=>rec_type, good=>booval); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(rec_type), 8)); else ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; case rec_type is when "00"=> -- Data record i := 0; k := (WIDTH + 7) / 8; -- # of bytes per entry while (i < ibyte) loop mem_data_word := (others => '0'); j := 1; while ( (j <= k) and (i < ibyte) ) loop -- read in data a byte (2 hex chars) at a time. READ(L=>buf, VALUE=>datain,good=>booval); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(datain), 8)); if (WIDTH > 8) then mem_data_word := mem_data_word(WIDTH - 9 downto 0) & CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(datain), 8); else mem_data_word := CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(datain), WIDTH); end if; j := j + 1; i := i + 1; end loop; if ((ibase + istartadd) <= (2 ** widthad - 1)) then mem_data(ibase + istartadd) := mem_data_word; else ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]: Unable to initialized memory with this data record since the specified address is out of valid address range!" SEVERITY WARNING; end if; istartadd := istartadd + 1; end loop; when "01"=> exit; when "02"=> ibase := 0; if (ibyte /= 2) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format for record type 02! " SEVERITY ERROR; end if; for i in 0 to (ibyte-1) loop READ(L=>buf, VALUE=>base,good=>booval); ibase := (ibase * 256) + HEX_STR_TO_INT(base); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(base), 8)); end loop; ibase := ibase * 16; when "03"=> if (ibyte /= 4) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format for record type 03! " SEVERITY ERROR; end if; for i in 0 to (ibyte-1) loop READ(L=>buf, VALUE=>base,good=>booval); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(base), 8)); end loop; when "04"=> ibase := 0; if (ibyte /= 2) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format for record type 04! " SEVERITY ERROR; end if; for i in 0 to (ibyte-1) loop READ(L=>buf, VALUE=>base,good=>booval); ibase := (ibase * 256) + HEX_STR_TO_INT(base); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(base), 8)); end loop; ibase := ibase * 65536; when "05"=> if (ibyte /= 4) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format for record type 05! " SEVERITY ERROR; end if; for i in 0 to (ibyte-1) loop READ(L=>buf, VALUE=>base,good=>booval); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal Intel Hex Format! " SEVERITY ERROR; end if; check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(base), 8)); end loop; when OTHERS => ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Illegal record type in Intel Hex File! " SEVERITY ERROR; end case; READ(L=>buf, VALUE=>checksum,good=>booval); if not (booval) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Checksum is missing! " SEVERITY ERROR; end if; check_sum_vec := unsigned(not (check_sum_vec)) + 1 ; check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(HEX_STR_TO_INT(checksum),8); if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then ASSERT FALSE REPORT "[Line "& INT_TO_STR_RAM(lineno) & "]:Incorrect checksum!" SEVERITY ERROR; end if; end loop; elsif (ALPHA_TOLOWER(lpm_file(lpm_file'length -3 to lpm_file'length)) = ".mif") then -- ************************************************ -- Read in RAM initialization file (mif) -- ************************************************ while not endfile(mem_data_file) loop booval := true; readline(mem_data_file, buf); lineno := lineno + 1; LOOP2 : while (buf'length > 0) loop if (buf(buf'low) = '-') then if (buf(buf'low) = '-') then -- ignore comment started with --. exit LOOP2; end if; elsif (buf(buf'low) = '%') then i := 1; -- ignore comment which begin with % and end with another %. while ((i < buf'high) and (buf(buf'low + i) /= '%')) loop i := i+1; end loop; if (i >= buf'high) then exit LOOP2; else SHRINK_LINE(buf, i+1); end if; elsif ((buf(buf'low) = ' ') or (buf(buf'low) = HT)) then i := 1; -- ignore space or tab character. while ((i < buf'high-1) and ((buf(buf'low +i) = ' ') or (buf(buf'low+i) = HT))) loop i := i+1; end loop; if (i >= buf'high) then exit LOOP2; else SHRINK_LINE(buf, i); end if; elsif (get_memory_content = true) then if ((buf(buf'low to buf'low +2) = "end") or (buf(buf'low to buf'low +2) = "END") or (buf(buf'low to buf'low +2) = "End")) then get_memory_content := false; exit LOOP2; else get_start_address := false; get_end_address := false; m_start_address_int := 0; m_end_address_int := 0; m_address_int := 0; m_data_int := (others => '0'); if (buf(buf'low) = '[') then get_start_Address := true; SHRINK_LINE(buf, 1); end if; case m_address_radix is when "hex" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ':') and (buf(buf'low) /= '.')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *16 + HEX_STR_TO_INT(char); end loop; when "bin" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ':') and (buf(buf'low) /= '.')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *2 + BIN_STR_TO_INT(char); end loop; when "dec" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ':') and (buf(buf'low) /= '.')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *10 + INT_STR_TO_INT(char); end loop; when "uns" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ':') and (buf(buf'low) /= '.')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *10 + INT_STR_TO_INT(char); end loop; when "oct" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ':') and (buf(buf'low) /= '.')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *8 + OCT_STR_TO_INT(char); end loop; when others => assert false report "Unsupported address_radix!" severity error; end case; if (get_start_Address = true) then i := 0; -- ignore space or tab character. while ((i < buf'high-1) and ((buf(buf'low +i) = ' ') or (buf(buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(buf, i); end if; if ((buf(buf'low) = '.') and (buf(buf'low+1) = '.')) then get_start_Address := false; get_end_Address := true; m_start_address_int := m_address_int; SHRINK_LINE(buf, 2); end if; end if; if (get_end_address = true) then i := 0; -- ignore space or tab character. while ((i < buf'high-1) and ((buf(buf'low +i) = ' ') or (buf(buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(buf, i); end if; m_address_int := 0; case m_address_radix is when "hex" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ']')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *16 + HEX_STR_TO_INT(char); end loop; when "bin" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ']')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *2 + BIN_STR_TO_INT(char); end loop; when "dec" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ']')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *10 + INT_STR_TO_INT(char); end loop; when "uns" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ']')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *10 + INT_STR_TO_INT(char); end loop; when "oct" => while ((buf(buf'low) /= ' ') and (buf(buf'low) /= HT) and (buf(buf'low) /= ']')) loop read(l => buf, value => char, good => booval); m_address_int := m_address_int *8 + OCT_STR_TO_INT(char); end loop; when others => assert false report "Unsupported address_radix!" severity error; end case; if (buf(buf'low) = ']') then get_end_address := false; m_end_address_int := m_address_int; SHRINK_LINE(buf, 1); end if; end if; i := 0; -- ignore space or tab character. while ((i < buf'high-1) and ((buf(buf'low +i) = ' ') or (buf(buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(buf, i); end if; if (buf(buf'low) = ':') then SHRINK_LINE(buf, 1); end if; i := 0; -- ignore space or tab character. while ((i < buf'high-1) and ((buf(buf'low +i) = ' ') or (buf(buf'low+i) = HT))) loop i := i+1; end loop; if (i > 0) then SHRINK_LINE(buf, i); end if; case m_data_radix is when "hex" => while ((buf(buf'low) /= ';') and (buf(buf'low) /= ' ') and (buf(buf'low) /= HT)) loop read(l => buf, value => char, good => booval); m_data_int(width+4 downto 0) := m_data_int(width-1 downto 0) * "10000" + conv_std_logic_vector(HEX_STR_TO_INT(char), 4); end loop; when "bin" => while ((buf(buf'low) /= ';') and (buf(buf'low) /= ' ') and (buf(buf'low) /= HT)) loop read(l => buf, value => char, good => booval); m_data_int(width+1 downto 0) := m_data_int(width-1 downto 0) * "10" + conv_std_logic_vector(BIN_STR_TO_INT(char), 4); end loop; when "dec" => while ((buf(buf'low) /= ';') and (buf(buf'low) /= ' ') and (buf(buf'low) /= HT)) loop read(l => buf, value => char, good => booval); m_data_int(width+3 downto 0) := m_data_int(width-1 downto 0) * "1010" + conv_std_logic_vector(INT_STR_TO_INT(char), 4); end loop; when "uns" => while ((buf(buf'low) /= ';') and (buf(buf'low) /= ' ') and (buf(buf'low) /= HT)) loop read(l => buf, value => char, good => booval); m_data_int(width+3 downto 0) := m_data_int(width-1 downto 0) * "1010" + conv_std_logic_vector(INT_STR_TO_INT(char), 4); end loop; when "oct" => while ((buf(buf'low) /= ';') and (buf(buf'low) /= ' ') and (buf(buf'low) /= HT)) loop read(l => buf, value => char, good => booval); m_data_int(width+3 downto 0) := m_data_int(width-1 downto 0) * "1000" + conv_std_logic_vector(OCT_STR_TO_INT(char), 4); end loop; when others => assert false report "Unsupported data_radix!" severity error; end case; if (m_start_address_int /= m_end_address_int) then for i in m_start_address_int to m_end_address_int loop mem_data(i) := m_data_int(width-1 downto 0); end loop; else mem_data(m_address_int) := m_data_int(width-1 downto 0); end if; exit LOOP2; end if; elsif ((buf(buf'low) = 'W') or (buf(buf'low) = 'w')) then read(l=>buf, value=>m_string(1 to 5)); if (ALPHA_TOLOWER(m_string(1 to 5)) = "width") then i := 0; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; if (buf(buf'low + i) = '=') then i := i+1; end if; while ((buf(buf'low +i) = ' ') or (buf(buf'low +i) = HT)) loop i := i+1; end loop; SHRINK_LINE(buf, i); i := 0; while (buf(buf'low + i) /= ';') loop i := i+1; end loop; read(l=>buf, value=>m_string(1 to i)); m_width := INT_STR_TO_INT(m_string(1 to i)); end if; exit LOOP2; elsif (((buf(buf'low) = 'D') or (buf(buf'low) = 'd')) and ((buf(buf'low+1) = 'E') or (buf(buf'low+1) = 'e'))) then read(l=>buf, value=>m_string(1 to 5)); if (ALPHA_TOLOWER(m_string(1 to 5)) = "depth") then i := 0; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; if (buf(buf'low + i) = '=') then i := i+1; end if; while ((buf(buf'low +i) = ' ') or (buf(buf'low +i) = HT)) loop i := i+1; end loop; SHRINK_LINE(buf, i); i := 0; while (buf(buf'low + i) /= ';') loop i := i+1; end loop; read(l=>buf, value=>m_string(1 to i)); m_depth := INT_STR_TO_INT(m_string(1 to i)); end if; exit LOOP2; elsif ((buf(buf'low) = 'D') or (buf(buf'low) = 'd')) then read(l=>buf, value=>m_string(1 to 10)); if (ALPHA_TOLOWER(m_string(1 to 10)) = "data_radix") then i := 0; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; if (buf(buf'low + i) = '=') then i := i+1; end if; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; SHRINK_LINE(buf, i); i := 0; while (buf(buf'low + i) /= ';') loop i := i+1; end loop; read(l=>buf, value=>m_string(1 to 3)); m_data_radix := ALPHA_TOLOWER(m_string(1 to 3)); end if; exit LOOP2; elsif ((buf(buf'low) = 'A') or (buf(buf'low) = 'a')) then read(l=>buf, value=>m_string(1 to 13)); if (ALPHA_TOLOWER(m_string(1 to 13)) = "address_radix") then i := 0; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; if (buf(buf'low + i) = '=') then i := i+1; end if; while ((buf(buf'low+i) = ' ') or (buf(buf'low+i) = HT)) loop i := i+1; end loop; SHRINK_LINE(buf, i); i := 0; while (buf(buf'low + i) /= ';') loop i := i+1; end loop; read(l=>buf, value=>m_string(1 to 3)); m_address_radix := ALPHA_TOLOWER(m_string(1 to 3)); end if; exit LOOP2; elsif ((buf(buf'low) = 'C') or (buf(buf'low) = 'c')) then read(l=>buf, value=>m_string(1 to 7)); if (ALPHA_TOLOWER(m_string(1 to 7)) = "content") then found_keyword_content := true; end if; elsif ((buf(buf'low) = 'B') or (buf(buf'low) = 'b')) then read(l=>buf, value=>m_string(1 to 5)); if (ALPHA_TOLOWER(m_string(1 to 5)) = "begin") then if (found_keyword_content = true) then get_memory_content := true; end if; end if; end if; end loop; end loop; else assert false report "Unsupported memory initialization file type (" & lpm_file(lpm_file'length -3 to lpm_file'length) & ")!" severity error; end if; FILE_CLOSE(mem_data_file); end if; mem_init := TRUE; -- --******************************************* else -- already initialized -- MEMORY FUNCTION -- -- This is where data is being write to the internal memory: mem_data[] -- if (iwren_tmp = '1') then mem_data (ieee.std_logic_unsigned.conv_integer(iwraddress_tmp)) := idata_tmp; end if; -- Triple-Port Ram (alt3pram) has one write port and two read ports (a and b) -- Below is the operation to read data from internal memory (mem_data[]) -- to the output port (iqa_tmp or iqb_tmp) -- Note: iq*_tmp will serve as the var directly link to the physical -- output port q* if alt3pram is operate in "Shared Clock Mode", -- else data read from iq*_tmp will need to be latched to i_q*_reg -- through outclock before it is fed to the output port q* (qa or qb). if (irden_tmp_a = '1') then iqa_tmp <= mem_data(ieee.std_logic_unsigned.conv_integer(irdaddress_tmp_a)); elsif (rden_low_output_0) then iqa_tmp <= (OTHERS => '0'); end if; if (irden_tmp_b = '1') then iqb_tmp <= mem_data(ieee.std_logic_unsigned.conv_integer(irdaddress_tmp_b)); elsif (rden_low_output_0) then iqb_tmp <= (OTHERS => '0'); end if; end if; end process MEMORY; end behavior; -- architecture of alt3pram --end of alt3pram ---START_ENTITY_HEADER--------------------------------------------------------- -- -- entity Name : parallel_add -- -- Description : Parameterized parallel adder megafunction. The data input -- is a concatenated group of input words. The size -- parameter indicates the number of 'width'-bit words. -- -- Each word is added together to generate the result output. -- Each word is left shifted according to the shift -- parameter. The shift amount is multiplied by the word -- index, with the least significant word being word 0. -- The shift for word I is (shift * I). -- -- The most significant word can be subtracted from the total -- by setting the msw_subtract parameter to 1. -- if the result width is less than is required to show the -- full result, the result output can be aligned to the MSB -- or the LSB of the internal result. when aligning to the -- MSB, the internally calculated BEST_RESULT_WIDTH is used -- to find the true MSB. -- The input data can be signed or unsigned, and the output -- can be pipelined. -- -- Limitations : Minimum data width is 1, and at least 2 words are required. -- -- Results expected: result - The sum of all inputs. -- ---END_ENTITY_HEADER----------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use IEEE.std_logic_arith.all; use work.altera_mf_components.all; -- BEGINNING OF ENTITY -- ENTITY DECLARATION entity parallel_add is -- GENERIC DECLARATION generic ( width : natural := 4; size : natural := 2; widthr : natural := 4; shift : natural := 0; msw_subtract : string := "NO"; representation : string := "UNSIGNED"; pipeline : natural := 0; result_alignment : string := "LSB"; lpm_hint : string := "UNUSED"; lpm_type : string := "parallel_add" ); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION data : in altera_mf_logic_2D(size - 1 downto 0, width- 1 downto 0); clock : in std_logic := '1'; aclr : in std_logic := '0'; clken : in std_logic := '1'; -- OUTPUT PORT DECLARATION result : out std_logic_vector(widthr - 1 downto 0) ); end parallel_add; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE architecture behaviour OF parallel_add IS -- TYPE DECLARATION TYPE pipeline_type is ARRAY (pipeline downto 0) OF std_logic_vector(widthr - 1 downto 0); -- Maximum precision required for internal calculations. -- This is a pessimistic estimate, but it is guaranteed to be sufficient. -- The +30 is there only to simplify the test generator, which occasionally asks -- for output widths far in excess of what is needed. The excess is always less than 30. constant MAX_PRECISION : natural := (width + size + shift * (size - 1) + 30); -- Bitwise Left shift -- Bitwise Left shift procedure shift_left ( val : inout std_logic_vector; num : in natural) is variable temp : std_logic_vector((val'length - 1) downto 0); begin if num /= 0 then temp := val; if (val'length > 1) then for i in temp'high downto num loop temp(i) := temp(i- num); end loop; for i in num-1 downto 0 loop temp(i) := '0'; end loop; end if; temp(0) :='0'; val := temp; end if; end shift_left; -- Bitwise right shift procedure shift_right ( val : inout std_logic_vector; num : in natural ) is variable temp : std_logic_vector(val'length-1 downto 0); begin if num /= 0 then temp := val; if (val'length > 1) then for i in 0 to temp'high - 1 loop if (i + num) <= (temp'high - 1) then temp(i) := temp(i+num); else temp(i) := '0'; end if; end loop; end if; temp(temp'high) := '0'; val := temp; end if; end shift_right; function ceil_log2 (input_num : in std_logic_vector(MAX_PRECISION - 1 downto 0)) return natural IS variable i : natural; variable try_result : std_logic_vector(MAX_PRECISION - 1 downto 0); variable ceil_log2 : natural; begin i := 0; try_result := conv_std_logic_vector(1,MAX_PRECISION); while (i < MAX_PRECISION) loop shift_left(try_result,1); if (unsigned(try_result) < unsigned(input_num)) then i := i + 1; else exit; end if; end loop; ceil_log2 := i; return (ceil_log2); end ceil_log2; -- best_result_width calculation -- DEFINE CALC_PADD_WIDTHR(w, z, s) = (s == 0) ? CEIL(LOG2(z*((2^w)-1))) : -- CEIL(LOG2(((2^w)-1) * (2^(z*s)-1) / ((2^s)-1))); -- Note: The recommended value for WIDTHR parameter, -- the width of addition result, for full -- precision is: -- if shift = 0 then -- WIDTHR = CEIL(LOG2( ((2^WIDTH)-1) * SIZE)) -- -- -- if shift /= 0 then -- ((2^WIDTH)-1) * (2^(SIZE*SHIFT)-1) -- WIDTHR = CEIL(LOG2(-----------------------------------)) -- (2^SHIFT)-1 function get_best_result_width (shift, width, size : in natural) return natural is variable best_result_width : natural; variable input_num : std_logic_vector(MAX_PRECISION - 1 downto 0) := (others => '0'); variable size_vec : std_logic_vector(size downto 0) := (others => '0'); variable width_power : std_logic_vector(width downto 0) := (others => '0'); variable size_shift_power : std_logic_vector((size * shift) downto 0) := (others => '0'); variable i_denom : std_logic_vector(width + (size * shift) + 1 downto 0) := (others => '0'); variable mult_power : std_logic_vector(width + (size * shift) + 1 downto 0) := (others => '0'); variable max_width : natural; variable trailing_zero_count : natural; variable i_remain : std_logic_vector(width + (size * shift) + 1 downto 0) := (others => '0'); variable i_quotient : std_logic_vector(MAX_PRECISION - 1 downto 0) := (others => '0'); begin -- Convert size natural into std logic vector size_vec := conv_std_logic_vector(size,size+1); -- width_power = (2^WIDTH)-1) width_power := conv_std_logic_vector(1,width+1); shift_left(width_power,width+1); width_power := width_power - '1'; if (shift = 0) then input_num(size + width + 1 downto 0) := (width_power * size_vec); else -- size_shift_power = (2^(SIZE*SHIFT)-1) size_shift_power := conv_std_logic_vector(1, size * shift+1); shift_left(size_shift_power,size * shift + 1); size_shift_power := size_shift_power - '1'; -- i_denom = (2^SHIFT)-1 i_denom := conv_std_logic_vector(1, width + (size * shift) + 2); shift_left(i_denom,shift+1); i_denom := i_denom - '1'; -- mult_power := ((2^WIDTH)-1) * (2^(SIZE*SHIFT)-1) mult_power := (width_power * size_shift_power); max_width := width + (size * shift) + 1; -- perform division using long division algorithm using LPM_DIVIDE method trailing_zero_count := 0; for i in 0 to max_width loop if i_denom(i) /= '0' then trailing_zero_count := i; exit; end if; end loop; for i in 0 to max_width loop if i_denom(max_width - i) /= '0' then shift_left(i_denom,i); exit; end if; end loop; i_remain := mult_power; if (unsigned(i_remain) >= unsigned(i_denom)) then i_remain := i_remain - i_denom; i_quotient(0) := '1'; else i_quotient(0) := '0'; end if; while (i_denom(trailing_zero_count) = '0') loop shift_right(i_denom,1); shift_left(i_quotient, 1); if (unsigned(i_remain) >= unsigned(i_denom)) then i_remain := i_remain - i_denom; i_quotient(0) := '1'; else i_quotient(0) := '0'; end if; end loop; input_num := i_quotient; end if; best_result_width := ceil_log2(input_num); return (best_result_width); end get_best_result_width; constant BEST_RESULT_WIDTH : natural := get_best_result_width(shift, width, size); -- constant BEST_RESULT_WIDTH : natural := 33; -- INTERNAL SIGNAL DECLARATION signal isigned : std_logic; signal imsw_subtract : std_logic; signal imsb_align : std_logic; signal aligned_result : std_logic_vector(widthr - 1 downto 0); signal result_tmp : std_logic_vector(widthr - 1 downto 0); begin -- checking for invalid parameters MSG: process begin if (width <= 0) then ASSERT FALSE REPORT "The width parameter must be greater than 0" SEVERITY ERROR; end if; if (widthr > MAX_PRECISION) then ASSERT FALSE REPORT "Error! WIDTHR must not exceed WIDTH+SIZE+SHIFT*(SIZE-1)." SEVERITY ERROR; end if; if (size < 2) then ASSERT FALSE REPORT "Error! SIZE must be greater than 1." SEVERITY ERROR; end if; wait; end process MSG; isigned <= '0' when (representation = "UNSIGNED") else '1'; imsw_subtract <= '1' when (msw_subtract = "YES") else '0'; imsb_align <= '1' when (result_alignment = "MSB" and widthr < BEST_RESULT_WIDTH) else '0'; process (data, isigned, imsw_subtract, imsb_align) variable zero_padding : std_logic_vector(MAX_PRECISION - width - 1 downto 0) := (others => '0'); variable one_padding : std_logic_vector(MAX_PRECISION - width - 1 downto 0) := (others => '1'); variable tmp_result : std_logic_vector(MAX_PRECISION - 1 downto 0); variable idata_word : std_logic_vector(width - 1 downto 0); variable idata : std_logic_vector(MAX_PRECISION - 1 downto 0); variable idata_extended : std_logic_vector(MAX_PRECISION - 1 downto 0); variable ni : natural; variable nj : natural; begin tmp_result := (others => '0'); idata_extended := (others => '0'); idata_word := (others => '0'); for ni in 0 to (size - 1) loop for nj in 0 to (width - 1) loop idata_word(nj) := '0'; -- To ensure there is only '1' or '0' in idata_word to avoid any -- warning arithmetic message . if (data(ni, nj) = '1') then idata_word(nj) := '1'; end if; end loop; if ((isigned = '1') and (idata_word(width - 1) = '1')) then idata_extended := one_padding & idata_word; shift_left(idata_extended, (shift * ni)); else idata_extended := zero_padding & idata_word; shift_left(idata_extended,(shift * ni)); end if; if ((imsw_subtract = '1') and (ni = (size - 1))) then tmp_result := tmp_result - idata_extended; else tmp_result := tmp_result + idata_extended; end if; end loop; if (imsb_align = '1') then shift_right(tmp_result, (BEST_RESULT_WIDTH - widthr)); end if; aligned_result <= tmp_result(widthr - 1 downto 0); end process; process (clock, aclr, clken, aligned_result) variable ni : natural; variable pipe_ptr : natural := 0; variable resultpipe : pipeline_type := (others => (others => '0')); begin if (aclr = '1') then for ni in 0 to (pipeline - 1) loop resultpipe(ni) := (others => '0'); end loop; result_tmp <= (others => '0'); elsif ((clock = '1') and (clock'last_value = '0') and clock'event and (clken = '1')) then resultpipe(pipe_ptr) := aligned_result; if (pipeline > 1) then pipe_ptr := (pipe_ptr + 1) mod pipeline; end if; result_tmp <= resultpipe(pipe_ptr); end if; end process; result <= result_tmp when (pipeline > 0) else aligned_result; end behaviour; -- END OF ARCHITECTURE PARALLEL_ADD ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : scfifo -- -- Description : Single Clock FIFO -- -- Limitation : USE_EAB=OFF is not supported -- -- Results Expected: -- ---END_ENTITY_HEADER----------------------------------------------------------- -- BEGINNING OF ENTITY library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.ALTERA_DEVICE_FAMILIES.all; -- ENTITY DECLARATION entity SCFIFO is -- GENERIC DECLARATION generic ( lpm_width : natural; lpm_widthu : natural; lpm_numwords : natural; lpm_showahead : string := "OFF"; lpm_type : string := "scfifo"; lpm_hint : string := "USE_EAB=ON"; intended_device_family : string := "Stratix"; underflow_checking : string := "ON"; overflow_checking : string := "ON"; allow_rwcycle_when_full : string := "OFF"; use_eab : string := "ON"; add_ram_output_register : string := "OFF"; almost_full_value : natural := 0; almost_empty_value : natural := 0; maximum_depth : natural := 0 ); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION data : in std_logic_vector(lpm_width-1 downto 0); clock : in std_logic; wrreq : in std_logic; rdreq : in std_logic; aclr : in std_logic := '0'; sclr : in std_logic := '0'; -- OUTPUT PORT DECLARATION q : out std_logic_vector(lpm_width-1 downto 0); usedw : out std_logic_vector(lpm_widthu-1 downto 0); full : out std_logic; empty : out std_logic; almost_full : out std_logic; almost_empty : out std_logic); end SCFIFO; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of SCFIFO is -- TYPE DECLARATION type lpm_memory is array (2**lpm_widthu-1 downto 0) of std_logic_vector(lpm_width-1 downto 0); -- CONSTANT DECLARATION constant ZEROS : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0'); constant NIL : std_logic_vector(2**lpm_widthu-1 downto 0) := (OTHERS => '0'); constant UNKNOWNS : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => 'X'); constant USEDW_UNKNOWNS : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => 'X'); -- SIGNAL DECLARATION signal i_count_id : integer := 0; signal i_read_id : integer := 0; signal i_full_flag : std_logic := '0'; signal i_empty_flag : std_logic := '1'; signal i_almost_full_flag : std_logic := '0'; signal i_almost_empty_flag : std_logic := '1'; signal i_set_q_to_x : std_logic := '0'; signal i_set_q_to_x_by_empty : std_logic := '0'; signal i_tmp_q : std_logic_vector(lpm_width-1 downto 0) := ZEROS; signal i_write_id : integer := 0; signal i_write_latency1 : integer := 0; signal i_write_latency2 : integer := 0; signal i_write_latency3 : integer := 0; signal i_wrt_count : integer := 0; signal i_empty_latency1 : std_logic := '1'; signal i_empty_latency2 : std_logic := '1'; signal i_data_ready : std_logic_vector(2**lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_data_shown : std_logic_vector(2**lpm_widthu-1 downto 0) := (OTHERS => '0'); begin -- PROCESS DECLARATION process (clock, aclr) -- VARIABLE DECLARATION variable mem_data : lpm_memory := (OTHERS => ZEROS); variable tmp_data : std_logic_vector(lpm_width-1 downto 0) := ZEROS; variable write_flag : boolean := false; variable full_flag : boolean := false; variable valid_rreq : boolean := false; variable valid_wreq : boolean := false; variable max_widthu : integer := 0; variable numwords_minus_one : integer := 0; variable almost_full_minus_one : integer := 0; variable almost_empty_minus_one : integer := 0; variable need_init : boolean := true; variable stratix_family : boolean := ( FEATURE_FAMILY_STRATIX(intended_device_family) ) ; variable showahead_area : boolean := (lpm_showahead = "ON" and add_ram_output_register = "OFF"); variable showahead_speed : boolean := (lpm_showahead = "ON" and add_ram_output_register = "ON"); variable legacy_speed : boolean := (lpm_showahead = "OFF" and add_ram_output_register = "ON"); begin if (need_init) then if ((lpm_showahead /= "ON") and (lpm_showahead /= "OFF")) then ASSERT FALSE REPORT "Illegal LPM_SHOWAHEAD property value for SCFIFO!" SEVERITY ERROR; end if; if ((underflow_checking /= "ON") and (underflow_checking /= "OFF")) then ASSERT FALSE REPORT "Illegal UNDERFLOW_CHECKING property value for SCFIFO!" SEVERITY ERROR; end if; if ((overflow_checking /= "ON") and (overflow_checking /= "OFF")) then ASSERT FALSE REPORT "Illegal OVERFLOW_CHECKING property value for SCFIFO!" SEVERITY ERROR; end if; if ((allow_rwcycle_when_full /= "ON") and (allow_rwcycle_when_full /= "OFF")) then ASSERT FALSE REPORT "Illegal ALLOW_RWCYCLE_WHEN_FULL property value for SCFIFO!" SEVERITY ERROR; end if; if (IS_VALID_FAMILY(intended_device_family) = false) then ASSERT FALSE REPORT "Illegal INTENDED_DEVICE_FAMILY for SCFIFO!" SEVERITY ERROR; end if; if ((add_ram_output_register /= "ON") and (add_ram_output_register /= "OFF")) then ASSERT FALSE REPORT "Error! ADD_RAM_OUTPUT_REGISTER must be ON or OFF." SEVERITY ERROR; end if; for i in 0 to (lpm_widthu - 1) loop if (stratix_family) then if ((add_ram_output_register = "ON") or (use_eab = "OFF") or (FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM(intended_device_family))) then mem_data(i) := ZEROS; else mem_data(i) := UNKNOWNS; end if; else mem_data(i) := ZEROS; end if; end loop; if (stratix_family) then if ((add_ram_output_register = "ON") or (use_eab = "OFF") or (FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM(intended_device_family))) then i_tmp_q <= ZEROS; else i_tmp_q <= UNKNOWNS; end if; else i_tmp_q <= ZEROS; end if; if (almost_full_value = 0) then i_almost_full_flag <= '1'; else i_almost_full_flag <= '0'; end if; if (almost_empty_value = 0) then i_almost_empty_flag <= '0'; else i_almost_empty_flag <= '1'; end if; max_widthu := (2 ** lpm_widthu) - 1; numwords_minus_one := lpm_numwords - 1; almost_full_minus_one := almost_full_value - 1; almost_empty_minus_one := almost_empty_value - 1; i_write_latency1 <= max_widthu+1; i_write_latency2 <= max_widthu+1; i_write_latency3 <= max_widthu+1; need_init := false; end if; if (aclr = '1') then full_flag := false; i_read_id <= 0; i_count_id <= 0; i_full_flag <= '0'; i_empty_flag <= '1'; i_empty_latency1 <= '1'; i_empty_latency2 <= '1'; i_set_q_to_x <= '0'; i_set_q_to_x_by_empty <= '0'; i_wrt_count <= 0; if (add_ram_output_register = "ON") then i_tmp_q <= ZEROS; elsif ((lpm_showahead = "ON") and (use_eab = "ON")) then i_tmp_q <= UNKNOWNS; else if (not stratix_family) then i_tmp_q <= ZEROS; else i_tmp_q <= UNKNOWNS; end if; end if; end if; if (clock'event and (clock = '1') and ((aclr = '0') or (stratix_family))) then valid_rreq := rdreq = '1' and ((i_empty_flag = '0') or (underflow_checking = "OFF")); valid_wreq := wrreq = '1' and ((i_full_flag = '0') or (overflow_checking = "OFF") or ((rdreq = '1') and (allow_rwcycle_when_full = "ON"))); if ((sclr = '1') or (aclr = '1')) then if (add_ram_output_register = "ON") then i_tmp_q <= ZEROS; else i_tmp_q <= UNKNOWNS; end if; i_read_id <= 0; i_count_id <= 0; i_full_flag <= '0'; i_empty_flag <= '1'; i_empty_latency1 <= '1'; i_empty_latency2 <= '1'; i_set_q_to_x <= '0'; i_set_q_to_x_by_empty <= '0'; i_wrt_count <= 0; if (almost_full_value > 0) then i_almost_full_flag <= '0'; end if; if (almost_empty_value > 0) then i_almost_empty_flag <= '1'; end if; full_flag := false; if (not(stratix_family)) then if (valid_wreq) then tmp_data := data; write_flag := true; else i_write_id <= 0; end if; else i_write_id <= 0; end if; else -- READ operation only if (valid_rreq) then if (not ((i_set_q_to_x = '1') or (i_set_q_to_x_by_empty = '1'))) then if (not valid_wreq) then i_wrt_count <= i_wrt_count - 1; end if; if (not valid_wreq) then i_full_flag <= '0'; full_flag := false; if (i_count_id <= 0) then i_count_id <= max_widthu; else i_count_id <= i_count_id - 1; end if; end if; if ((use_eab = "ON") and stratix_family and (showahead_speed or showahead_area or legacy_speed)) then if ((i_wrt_count = 1) or ((i_wrt_count = 1) and valid_wreq and valid_rreq)) then i_empty_flag <= '1'; else if (showahead_speed) then if (i_write_latency2 <= max_widthu) then if (i_data_shown(i_write_latency2) = '0') then i_empty_flag <= '1'; end if; end if; else if (showahead_area or legacy_speed) then if (i_write_latency1 <= max_widthu) then if (i_data_shown(i_write_latency1) = '0') then i_empty_flag <= '1'; end if; end if; end if; end if; end if; else if (not(valid_wreq)) then if (i_count_id = 1 and i_full_flag = '0') then i_empty_flag <= '1'; end if; end if; end if; if (i_empty_flag = '1') then if (underflow_checking = "ON") then if ((use_eab = "OFF") or stratix_family) then i_tmp_q <= ZEROS; end if; else i_set_q_to_x_by_empty <= '1'; ASSERT FALSE REPORT "Warning : Underflow occurred! Fifo output is unknown until the next reset is asserted" SEVERITY WARNING; end if; else if (i_read_id >= max_widthu) then if (lpm_showahead = "ON") then if ((use_eab = "ON") and stratix_family and (showahead_speed or showahead_area)) then if (showahead_speed) then if ((i_write_latency2 = ZEROS) or (i_data_ready(0) = '1')) then if (i_data_shown(0) = '1') then i_tmp_q <= mem_data(0); i_data_shown(0) <= '0'; i_data_ready(0) <= '0'; end if; end if; else if (i_count_id = 1 and i_full_flag = '0') then if (underflow_checking = "ON") then if ((use_eab = "OFF") or stratix_family) then i_tmp_q <= ZEROS; end if; else i_tmp_q <= UNKNOWNS; end if; else if ((i_write_latency1 = ZEROS) or (i_data_ready(0) = '1')) then if (i_data_shown(0) = '1') then i_tmp_q <= mem_data(0); i_data_shown(0) <= '0'; i_data_ready(0) <= '0'; end if; end if; end if; end if; else if (i_count_id = 1 and i_full_flag = '0') then if (valid_wreq) then i_tmp_q <= data; else if (underflow_checking = "ON") then if ((use_eab = "OFF") or stratix_family) then i_tmp_q <= ZEROS; end if; else i_tmp_q <= UNKNOWNS; end if; end if; else i_tmp_q <= mem_data(0); end if; end if; else if ((use_eab = "ON") and (stratix_family and legacy_speed)) then if ((i_write_latency1 = i_read_id) or (i_data_ready(i_read_id) = '1')) then if (i_data_shown(i_read_id) = '1') then i_tmp_q <= mem_data(i_read_id); i_data_shown(i_read_id) <= '0'; i_data_ready(i_read_id) <= '0'; end if; else i_tmp_q <= UNKNOWNS; end if; else i_tmp_q <= mem_data(i_read_id); end if; end if; i_read_id <= 0; else if (lpm_showahead = "ON") then if ((use_eab = "ON") and (stratix_family and (showahead_speed or showahead_area))) then if (showahead_speed) then if ((i_write_latency2 = i_read_id+1) or (i_data_ready(i_read_id+1) = '1')) then if (i_data_shown(i_read_id+1) = '1') then i_tmp_q <= mem_data(i_read_id + 1); i_data_shown(i_read_id+1) <= '0'; i_data_ready(i_read_id+1) <= '0'; end if; end if; else if (i_count_id = 1 and i_full_flag = '0') then if (underflow_checking = "ON") then if ((use_eab = "OFF") or stratix_family) then i_tmp_q <= ZEROS; end if; else i_tmp_q <= UNKNOWNS; end if; else if ((i_write_latency1 = i_read_id+1) or (i_data_ready(i_read_id+1) = '1')) then if (i_data_shown(i_read_id+1) = '1') then i_tmp_q <= mem_data(i_read_id + 1); i_data_shown(i_read_id+1) <= '0'; i_data_ready(i_read_id+1) <= '0'; end if; end if; end if; end if; else if (i_count_id = 1 and i_full_flag = '0') then if ((use_eab = "OFF") and stratix_family) then if (valid_wreq) then i_tmp_q <= data; else if (underflow_checking = "ON") then i_tmp_q <= ZEROS; else i_tmp_q <= UNKNOWNS; end if; end if; else i_tmp_q <= UNKNOWNS; end if; else i_tmp_q <= mem_data(i_read_id + 1); end if; end if; else if ((use_eab = "ON") and stratix_family and legacy_speed) then if ((i_write_latency1 = i_read_id) or (i_data_ready(i_read_id) = '1')) then if (i_data_shown(i_read_id) = '1') then i_tmp_q <= mem_data(i_read_id); i_data_shown(i_read_id) <= '0'; i_data_ready(i_read_id) <= '0'; end if; else i_tmp_q <= UNKNOWNS; end if; else i_tmp_q <= mem_data(i_read_id); end if; end if; i_read_id <= i_read_id + 1; end if; end if; end if; end if; -- WRITE operation only if (valid_wreq) then if (not ((i_set_q_to_x = '1') or (i_set_q_to_x_by_empty = '1'))) then if ((overflow_checking = "OFF") and full_flag) then i_set_q_to_x <= '1'; ASSERT FALSE REPORT "Warning : Overflow occurred! Fifo output is unknown until the next reset is asserted" SEVERITY WARNING; else tmp_data := data; write_flag := true; if (not((use_eab = "ON") and (stratix_family) and (showahead_speed or showahead_area or legacy_speed))) then i_empty_flag <= '0'; else i_empty_latency1 <= '0'; end if; if (not valid_rreq) then i_wrt_count <= i_wrt_count + 1; end if; if (not valid_rreq) then if (i_count_id >= max_widthu) then i_count_id <= 0; else i_count_id <= i_count_id + 1; end if; else if (allow_rwcycle_when_full = "OFF") then i_full_flag <= '0'; end if; end if; if (not(stratix_family) or(stratix_family and not(showahead_speed or showahead_area or legacy_speed))) then if (not valid_rreq) then if ((i_count_id = numwords_minus_one) and (i_empty_flag = '0')) then i_full_flag <= '1'; full_flag := true; end if; end if; else if (not valid_rreq) then if (i_count_id = numwords_minus_one) then i_full_flag <= '1'; full_flag := true; end if; end if; end if; if (lpm_showahead = "ON") then if ((use_eab = "ON") and (stratix_family) and (showahead_speed or showahead_area)) then i_write_latency1 <= i_write_id; if (i_write_id <= max_widthu) then i_data_shown(i_write_id) <= '1'; i_data_ready(i_write_id) <= 'X'; end if; else if ((use_eab = "OFF") and stratix_family and (i_count_id = 0) and (not full_flag)) then i_tmp_q <= data; else if ((not i_empty_flag = '0') and (not valid_rreq)) then i_tmp_q <= mem_data(i_read_id); end if; end if; end if; else if ((use_eab = "ON") and stratix_family and legacy_speed) then i_write_latency1 <= i_write_id; if (i_write_id <= max_widthu) then i_data_shown(i_write_id) <= '1'; i_data_ready(i_write_id) <= 'X'; end if; end if; end if; end if; end if; end if; if (almost_full_value = 0) then i_almost_full_flag <= '1'; elsif (lpm_numwords = almost_full_value) then if (full_flag) then i_almost_full_flag <= '1'; else i_almost_full_flag <= '0'; end if; else if (i_almost_full_flag = '1') then if ((i_count_id = almost_full_value) and (wrreq = '0') and (rdreq = '1')) then i_almost_full_flag <= '0'; end if; else if ((almost_full_value = 1) and (i_count_id = 0) and (wrreq = '1')) then i_almost_full_flag <= '1'; elsif ((almost_full_value > 1) and (i_count_id = almost_full_minus_one) and (wrreq = '1') and (rdreq = '0')) then i_almost_full_flag <= '1'; end if; end if; end if; if (almost_empty_value = 0) then i_almost_empty_flag <= '0'; elsif (lpm_numwords = almost_empty_value) then if (full_flag) then i_almost_empty_flag <= '0'; else i_almost_empty_flag <= '1'; end if; else if (i_almost_empty_flag = '1') then if ((almost_empty_value = 1) and (i_count_id = 0) and (wrreq = '1')) then i_almost_empty_flag <= '0'; elsif ((almost_empty_value > 1) and (i_count_id = almost_empty_minus_one) and (wrreq = '1') and (rdreq = '0')) then i_almost_empty_flag <= '0'; end if; else if ((i_count_id = almost_empty_value) and (wrreq = '0') and (rdreq = '1')) then i_almost_empty_flag <= '1'; end if; end if; end if; end if; if ((clock'event and (clock = '1')) and ((use_eab = "ON") and stratix_family)) then if (showahead_speed) then i_write_latency2 <= i_write_latency1; i_write_latency3 <= i_write_latency2; if (i_write_latency3 /= i_write_latency2) then if (i_write_latency2 <= max_widthu) then i_data_ready(i_write_latency2) <= '1'; end if; end if; i_empty_latency2 <= i_empty_latency1; if ((aclr = '1') or (sclr = '1')) then i_write_latency1 <= max_widthu+1; i_write_latency2 <= max_widthu+1; i_data_shown <= NIL; if (add_ram_output_register = "ON") then i_tmp_q <= ZEROS; else i_tmp_q <= UNKNOWNS; end if; end if; if (i_write_latency2 <= max_widthu) then if (i_data_shown(i_write_latency2) = '1') then if ((i_read_id = i_write_latency2) or (aclr = '1') or (sclr = '1')) then if (not (aclr = '1') and (not(sclr = '1'))) then i_tmp_q <= mem_data(i_write_latency2); i_data_shown(i_write_latency2) <= '0'; i_data_ready(i_write_latency2) <= '0'; if (not valid_rreq) then i_empty_flag <= i_empty_latency2; end if; end if; end if; end if; end if; elsif (showahead_area) then i_write_latency2 <= i_write_latency1; if (i_write_latency2 /= i_write_latency1) then if (i_write_latency1 <= max_widthu) then i_data_ready(i_write_latency1) <= '1'; end if; end if; if ((aclr = '1') or (sclr = '1')) then i_write_latency1 <= max_widthu+1; i_write_latency2 <= max_widthu+1; i_data_shown <= NIL; if (add_ram_output_register = "ON") then i_tmp_q <= ZEROS; else i_tmp_q <= UNKNOWNS; end if; end if; if (i_write_latency1 <= max_widthu) then if (i_data_shown(i_write_latency1) = '1') then if ((i_read_id = i_write_latency1) or (aclr = '1') or (sclr = '1')) then if (not (aclr = '1') and (not(sclr = '1'))) then i_tmp_q <= mem_data(i_write_latency1); i_data_shown(i_write_latency1) <= '0'; i_data_ready(i_write_latency1) <= '0'; if (not valid_rreq) then i_empty_flag <= i_empty_latency1; end if; end if; end if; end if; end if; else if (legacy_speed) then i_write_latency2 <= i_write_latency1; if (i_write_latency2 /= i_write_latency1) then if (i_write_latency1 <= max_widthu) then i_data_ready(i_write_latency1) <= '1'; end if; end if; if ((aclr = '1') or (sclr = '1')) then i_write_latency1 <= max_widthu+1; i_write_latency2 <= max_widthu+1; i_data_shown <= NIL; if (add_ram_output_register = "ON") then i_tmp_q <= ZEROS; else i_tmp_q <= UNKNOWNS; end if; end if; if ((i_wrt_count = 0 and (not valid_wreq)) or (aclr = '1') or (sclr = '1') or (i_wrt_count = 1 and valid_rreq and (not valid_wreq))) then i_empty_flag <= '1'; i_empty_latency1 <= '1'; else if (i_wrt_count = 1 and valid_wreq and valid_rreq) then i_empty_flag <= '1'; else i_empty_flag <= i_empty_latency1; end if; end if; end if; end if; end if; elsif (clock'event and (clock = '0')) then if (write_flag) then write_flag := false; mem_data(i_write_id) := tmp_data; if ((aclr = '1') or (sclr = '1') or (i_write_id >= max_widthu)) then i_write_id <= 0; else i_write_id <= i_write_id + 1; end if; end if; if (not(stratix_family)) then if (not i_empty_flag = '1') then if (lpm_showahead = "ON") then i_tmp_q <= mem_data(i_read_id); end if; end if; end if; end if; if (aclr = '1') then i_full_flag <= '0'; i_empty_flag <= '1'; if (almost_full_value > 0) then i_almost_full_flag <= '0'; end if; if (almost_empty_value > 0) then i_almost_empty_flag <= '1'; end if; i_read_id <= 0; i_write_id <= 0; i_count_id <= 0; i_set_q_to_x <= '0'; i_wrt_count <= 0; end if; end process; q <= i_tmp_q when (not ((i_set_q_to_x = '1') or (i_set_q_to_x_by_empty = '1'))) else UNKNOWNS; full <= i_full_flag when (not ((i_set_q_to_x = '1') or (i_set_q_to_x_by_empty = '1'))) else 'X'; empty <= i_empty_flag when (not ((i_set_q_to_x = '1') or (i_set_q_to_x_by_empty = '1'))) else 'X'; almost_full <= i_almost_full_flag when (not ((i_set_q_to_x = '1') or (i_set_q_to_x_by_empty = '1'))) else 'X'; almost_empty <= i_almost_empty_flag when (not ((i_set_q_to_x = '1') or (i_set_q_to_x_by_empty = '1'))) else 'X'; usedw <= conv_std_logic_vector(i_count_id, lpm_widthu) when (not ((i_set_q_to_x = '1') or (i_set_q_to_x_by_empty = '1'))) else USEDW_UNKNOWNS ; end behavior; -- scfifo -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : dcfifo_dffpipe -- -- Description : Dual Clocks FIFO -- -- Limitation : -- -- Results Expected: -- ---END_ENTITY_HEADER----------------------------------------------------------- -- BEGINNING OF ENTITY library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; -- ENTITY DECLARATION entity DCFIFO_DFFPIPE is -- GENERIC DECLARATION generic ( lpm_delay : natural; lpm_width : natural); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION d : in std_logic_vector (lpm_width-1 downto 0); clock : in std_logic; aclr : in std_logic := '0'; -- OUTPUT PORT DECLARATION q : out std_logic_vector (lpm_width-1 downto 0)); end DCFIFO_DFFPIPE; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of DCFIFO_DFFPIPE is -- TYPE DECLARATION type DELAYPIPE is array (lpm_delay downto 0) of std_logic_vector (lpm_width-1 downto 0); -- CONSTANT DECLARATION constant ZEROS : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0'); begin -- PROCESS DECLARATION process (clock, aclr, d) ------ VARIABLE DECLARATION variable intpipe : DELAYPIPE := (OTHERS => ZEROS); variable delay : integer := lpm_delay - 1; variable need_init : boolean := true; begin if (lpm_delay = 0) then if ((aclr = '1') or need_init) then q <= ZEROS; need_init := false; else q <= d; end if; else if ((aclr = '1') or need_init) then for i in lpm_delay downto 0 loop intpipe(i) := ZEROS; end loop; need_init := false; q <= ZEROS; end if; if (clock'event and (clock = '1') and (NOW > 0 ns)) then if (delay > 0) then for i in delay downto 1 loop intpipe(i) := intpipe(i-1); end loop; end if; intpipe(0) := d; q <= intpipe(delay); end if; end if; -- (lpm_delay = 0) end process; -- clock, aclr, d events end behavior; -- dcfifo_dffpipe -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : dcfifo_fefifo -- -- Description : Dual Clocks FIFO -- -- Limitation : -- -- Results Expected: -- ---END_ENTITY_HEADER----------------------------------------------------------- -- BEGINNING OF ENTITY library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; -- ENTITY DECLARATION entity DCFIFO_FEFIFO is -- GENERIC DECLARATION generic ( lpm_widthad : natural; lpm_numwords : natural; underflow_checking : string := "ON"; overflow_checking : string := "ON"; lpm_mode : string); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION usedw_in : in std_logic_vector(lpm_widthad-1 downto 0); wreq : in std_logic := 'Z'; rreq : in std_logic := 'Z'; clock : in std_logic; aclr : in std_logic := '0'; -- OUTPUT PORT DECLARATION empty : out std_logic; full : out std_logic); end DCFIFO_FEFIFO; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of DCFIFO_FEFIFO is -- SIGNAL DECLARATION signal i_empty : std_logic := '1'; signal i_full : std_logic := '0'; begin -- PROCESS DECLARATION process (clock, aclr) ------ VARIABLE DECLARATION variable sm_empty : std_logic_vector(1 downto 0) := "00"; variable lrreq : std_logic := '0'; variable almost_full : integer := 0; variable usedw_is_1 : boolean := false; variable need_init : boolean := true; begin if (need_init) then if ((lpm_mode /= "READ") and (lpm_mode /= "WRITE")) then ASSERT FALSE REPORT "Error! LPM_MODE must be READ or WRITE." SEVERITY ERROR; end if; if ((underflow_checking /= "ON") and (underflow_checking /= "OFF")) then ASSERT FALSE REPORT "Error! UNDERFLOW_CHECKING must be ON or OFF." SEVERITY ERROR; end if; if ((overflow_checking /= "ON") and (overflow_checking /= "OFF")) then ASSERT FALSE REPORT "Error! OVERFLOW_CHECKING must be ON or OFF." SEVERITY ERROR; end if; if (lpm_numwords >= 3) then almost_full := lpm_numwords - 3; else almost_full := 0; end if; need_init := false; end if; -- need_init if (aclr'event and (aclr = '1')) then sm_empty := "00"; lrreq := '0'; i_empty <= '1'; i_full <= '0'; end if; -- aclr event if (clock'event and (clock = '1') and (aclr = '0') and (NOW > 0 ns)) then if (lpm_mode = "READ") then case sm_empty is -- state_empty when "00" => if (usedw_in /= 0) then sm_empty := "01"; end if; -- state_non_empty when "01" => if (lpm_widthad > 1) then usedw_is_1 := ((usedw_in = 1) and (lrreq = '0')) or ((usedw_in = 2) and (lrreq = '1')); else usedw_is_1 := (usedw_in = 1) and (lrreq = '0'); end if; if ((rreq = '1') and usedw_is_1) then sm_empty := "10"; end if; -- state_emptywait when "10" => if (usedw_in > 1) then sm_empty := "01"; else sm_empty := "00"; end if; when others => ASSERT FALSE REPORT "Error! Invalid sm_empty state in read mode." SEVERITY ERROR; end case; elsif (lpm_mode = "WRITE") then case sm_empty is -- state_empty when "00" => if (wreq = '1') then sm_empty := "01"; end if; -- state_one when "01" => if (wreq = '0') then sm_empty := "11"; end if; -- state_non_empty when "11" => if (wreq = '1') then sm_empty := "01"; elsif (usedw_in = 0) then sm_empty := "00"; end if; when others => ASSERT FALSE REPORT "Error! Invalid sm_empty state in write mode." SEVERITY ERROR; end case; end if; i_empty <= not sm_empty(0); if ((aclr = '0') and (usedw_in >= almost_full) and (NOW > 0 ns)) then i_full <= '1'; else i_full <= '0'; end if; if (underflow_checking = "OFF") then lrreq := rreq; else lrreq := rreq and not i_empty; end if; end if; -- clock event end process; -- clock, aclr events empty <= i_empty; full <= i_full; end behavior; -- dcfifo_fefifo -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : dcfifo_async -- -- Description : Asynchoronous Dual Clocks FIFO -- -- Limitation : -- -- Results Expected: -- ---END_ENTITY_HEADER----------------------------------------------------------- -- BEGINNING OF ENTITY library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.ALTERA_DEVICE_FAMILIES.all; use work.DCFIFO_FEFIFO; use work.DCFIFO_DFFPIPE; -- ENTITY DECLARATION entity DCFIFO_ASYNC is -- GENERIC DECLARATION generic ( lpm_width : natural; lpm_widthu : natural; lpm_numwords : natural; delay_rdusedw : natural := 1; delay_wrusedw : natural := 1; rdsync_delaypipe : natural := 0; wrsync_delaypipe : natural := 0; intended_device_family : string := "Stratix"; lpm_showahead : string := "OFF"; underflow_checking : string := "ON"; overflow_checking : string := "ON"; use_eab : string := "ON"; add_ram_output_register : string := "OFF"; clocks_are_synchronized : string := "FALSE"; lpm_hint : string := "USE_EAB=ON"); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION data : in std_logic_vector(lpm_width-1 downto 0); rdclk : in std_logic; wrclk : in std_logic; rdreq : in std_logic; wrreq : in std_logic; aclr : in std_logic := '0'; -- OUTPUT PORT DECLARATION rdempty : out std_logic; wrempty : out std_logic; rdfull : out std_logic; wrfull : out std_logic; rdusedw : out std_logic_vector(lpm_widthu-1 downto 0); wrusedw : out std_logic_vector(lpm_widthu-1 downto 0); q : out std_logic_vector(lpm_width-1 downto 0)); end DCFIFO_ASYNC; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of DCFIFO_ASYNC is -- TYPE DECLARATION type LPM_MEMORY is array (2**lpm_widthu-1 downto 0) of std_logic_vector(lpm_width-1 downto 0); type LPM_BOOLEAN is array (2**lpm_widthu-1 downto 0) of boolean; type LPM_NATURAL is array (2**lpm_widthu-1 downto 0) of natural; -- CONSTANT DECLARATION constant ZEROS : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0'); constant UNKNOWN : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => 'X'); constant ZEROU : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); constant GRAY_DELAYPIPE : integer := 1; constant WRUSEDW_DELAYPIPE : integer := 1; -- delayed usedw to compute empty/full constant RDUSEDW_DELAYPIPE : integer := 1; -- delayed usedw to compute empty/full -- SIGNAL DECLARATION signal i_data_tmp : std_logic_vector(lpm_width-1 downto 0); signal i_rdptr : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_wrptr : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_wrptr_tmp : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_rdptrrg : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_wrdelaycycle : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_rden : std_logic := '0'; signal i_wren : std_logic := '0'; signal i_rdenclock : std_logic := '0'; signal i_wren_tmp : std_logic := '0'; signal i_rdempty : std_logic := '1'; signal i_wrempty : std_logic := '1'; signal i_rdfull : std_logic := '0'; signal i_wrfull : std_logic := '0'; signal i_rdusedw : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_wrusedw : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_ws_nbrp : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_rs_nbwp : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_ws_dbrp : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_rs_dbwp : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_wr_udwn : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_rd_udwn : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_wr_dbuw : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_rd_dbuw : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_q_tmp : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0'); signal i_showahead_flag : std_logic := '0'; signal i_showahead_flag1 : std_logic := '0'; signal i_showahead_flag2 : std_logic := '0'; signal i_showahead_flag3 : std_logic := '0'; signal i_data_ready : LPM_BOOLEAN := (OTHERS => false); signal i_data_delay_count : LPM_NATURAL := (OTHERS => 0); signal i_zero : std_logic := '0'; -- COMPONENT DECLARATION component DCFIFO_FEFIFO generic ( lpm_widthad : natural; lpm_numwords : natural; underflow_checking : string := "ON"; overflow_checking : string := "ON"; lpm_mode : string); port ( usedw_in : in std_logic_vector(lpm_widthad-1 downto 0); wreq : in std_logic := 'Z'; rreq : in std_logic := 'Z'; clock : in std_logic; aclr : in std_logic := '0'; empty : out std_logic; full : out std_logic); end component; component DCFIFO_DFFPIPE generic ( lpm_delay : natural; lpm_width : natural); port ( d : in std_logic_vector(lpm_width-1 downto 0); clock : in std_logic; aclr : in std_logic := '0'; q : out std_logic_vector(lpm_width-1 downto 0)); end component; begin -- COMPONENT ASSIGNMENTS -- Delays & DFF Pipes DP_RDPTR_D: DCFIFO_DFFPIPE generic map ( lpm_delay => 0, lpm_width => lpm_widthu) port map ( d => i_rdptr, clock => i_rdenclock, aclr => aclr, q => i_rdptrrg); DP_WRPTR_D: DCFIFO_DFFPIPE generic map ( lpm_delay => 1, lpm_width => lpm_widthu) port map ( d => i_wrptr, clock => wrclk, aclr => aclr, q => i_wrdelaycycle); DP_WS_NBRP: DCFIFO_DFFPIPE generic map ( lpm_delay => WRSYNC_DELAYPIPE, lpm_width => lpm_widthu) port map ( d => i_rdptrrg, clock => wrclk, aclr => aclr, q => i_ws_nbrp); DP_RS_NBWP: DCFIFO_DFFPIPE generic map ( lpm_delay => RDSYNC_DELAYPIPE, lpm_width => lpm_widthu) port map ( d => i_wrdelaycycle, clock => rdclk, aclr => aclr, q => i_rs_nbwp); DP_WS_DBRP: DCFIFO_DFFPIPE generic map ( lpm_delay => GRAY_DELAYPIPE, lpm_width => lpm_widthu) port map ( d => i_ws_nbrp, clock => wrclk, aclr => aclr, q => i_ws_dbrp); DP_RS_DBWP: DCFIFO_DFFPIPE generic map ( lpm_delay => GRAY_DELAYPIPE, lpm_width => lpm_widthu) port map ( d => i_rs_nbwp, clock => rdclk, aclr => aclr, q => i_rs_dbwp); DP_WR_USEDW: DCFIFO_DFFPIPE generic map ( lpm_delay => DELAY_WRUSEDW, lpm_width => lpm_widthu) port map ( d => i_wr_udwn, clock => wrclk, aclr => aclr, q => i_wrusedw); DP_RD_USEDW: DCFIFO_DFFPIPE generic map ( lpm_delay => DELAY_RDUSEDW, lpm_width => lpm_widthu) port map ( d => i_rd_udwn, clock => rdclk, aclr => aclr, q => i_rdusedw); DP_WR_DBUW: DCFIFO_DFFPIPE generic map ( lpm_delay => WRUSEDW_DELAYPIPE, lpm_width => lpm_widthu) port map ( d => i_wr_udwn, clock => wrclk, aclr => aclr, q => i_wr_dbuw); DP_RD_DBUW: DCFIFO_DFFPIPE generic map ( lpm_delay => RDUSEDW_DELAYPIPE, lpm_width => lpm_widthu) port map ( d => i_rd_udwn, clock => rdclk, aclr => aclr, q => i_rd_dbuw); -- Empty/Full WR_FE: DCFIFO_FEFIFO generic map ( lpm_widthad => lpm_widthu, lpm_numwords => lpm_numwords, underflow_checking => UNDERFLOW_CHECKING, overflow_checking => OVERFLOW_CHECKING, lpm_mode => "WRITE") port map ( usedw_in => i_wr_dbuw, wreq => wrreq, rreq => i_zero, clock => wrclk, aclr => aclr, empty => i_wrempty, full => i_wrfull); RD_FE: DCFIFO_FEFIFO generic map ( lpm_widthad => lpm_widthu, lpm_numwords => lpm_numwords, underflow_checking => underflow_checking, overflow_checking => overflow_checking, lpm_mode => "READ") port map ( usedw_in => i_rd_dbuw, wreq => i_zero, rreq => rdreq, clock => rdclk, aclr => aclr, empty => i_rdempty, full => i_rdfull); -- PROCESS DECLARATION -- FIFOram process (wrclk, rdclk, aclr, i_showahead_flag) ------ VARIABLE DECLARATION variable max_widthu : integer := 0; variable max_widthu_minus_one : integer := 0; variable mem_data : LPM_MEMORY := (OTHERS => ZEROS); variable mem_data2 : LPM_MEMORY := (OTHERS => ZEROS); variable wrptr_tmp : integer := 0; variable rdptr_tmp : integer := 0; variable need_init : boolean := true; begin if (need_init) then if ((lpm_showahead /= "ON") and (lpm_showahead /= "OFF")) then ASSERT FALSE REPORT "Error! LPM_SHOWAHEAD must be ON or OFF." SEVERITY ERROR; end if; if ((underflow_checking /= "ON") and (underflow_checking /= "OFF")) then ASSERT FALSE REPORT "Error! UNDERFLOW_CHECKING must be ON or OFF." SEVERITY ERROR; end if; if ((overflow_checking /= "ON") and (overflow_checking /= "OFF")) then ASSERT FALSE REPORT "Error! OVERFLOW_CHECKING must be ON or OFF." SEVERITY ERROR; end if; if ((use_eab /= "ON") and (use_eab /= "OFF")) then ASSERT FALSE REPORT "Error! USE_EAB must be ON or OFF." SEVERITY ERROR; end if; if ((add_ram_output_register /= "ON") and (add_ram_output_register /= "OFF")) then ASSERT FALSE REPORT "Error! ADD_RAM_OUTPUT_REGISTER must be ON or OFF." SEVERITY ERROR; end if; if (IS_VALID_FAMILY(intended_device_family) = false) then ASSERT FALSE REPORT "Error! Illegal INTENDED_DEVICE_FAMILY." SEVERITY ERROR; end if; max_widthu := 2 ** lpm_widthu; max_widthu_minus_one := (2 ** lpm_widthu) - 1; for i in lpm_numwords - 1 downto 0 loop mem_data(i) := ZEROS; end loop; if ((add_ram_output_register = "OFF") and (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family))) then for i in 0 to max_widthu_minus_one loop mem_data2(i) := UNKNOWN; end loop; else for i in 0 to max_widthu_minus_one loop mem_data2(i) := ZEROS; end loop; end if; need_init := false; end if; -- need_init if (aclr'event and (aclr = '1')) then i_rdptr <= ZEROU; i_wrptr <= ZEROU; if (not (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)) or (use_eab = "OFF")) then if (lpm_showahead = "ON") then i_q_tmp <= mem_data(0); else i_q_tmp <= ZEROS; end if; elsif ((add_ram_output_register = "ON") and (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family))) then if (lpm_showahead = "OFF") then i_q_tmp <= ZEROS; else i_q_tmp <= UNKNOWN; for i in 0 to max_widthu_minus_one loop i_data_ready(i) <= false; i_data_delay_count(i) <= 0; end loop; end if; end if; end if; -- aclr event if (wrclk'event and (wrclk = '1')) then if ((aclr = '1') and (not (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)) or (add_ram_output_register = "ON") or (use_eab = "OFF"))) then i_data_tmp <= ZEROS; i_wrptr_tmp <= ZEROU; i_wren_tmp <= '0'; elsif (NOW > 0 ns) then i_data_tmp <= data; i_wrptr_tmp <= i_wrptr; i_wren_tmp <= i_wren; if (i_wren = '1') then if ((aclr = '0') and (i_wrptr < max_widthu_minus_one)) then i_wrptr <= i_wrptr + 1; else i_wrptr <= ZEROU; end if; if (use_eab = "OFF") then mem_data(CONV_INTEGER(i_wrptr) mod max_widthu) := data; if (lpm_showahead = "ON") then i_q_tmp <= mem_data(CONV_INTEGER(i_rdptr) mod max_widthu); end if; end if; end if; end if; end if; if (wrclk'event and (wrclk = '0')) then if ((use_eab = "ON") and (NOW > 0 ns)) then if (i_wren_tmp = '1') then wrptr_tmp := CONV_INTEGER(i_wrptr_tmp) mod max_widthu; mem_data(wrptr_tmp) := i_data_tmp; i_data_ready(wrptr_tmp) <= false; end if; if ((lpm_showahead = "ON") and (not (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)))) then i_q_tmp <= mem_data(CONV_INTEGER(i_rdptr) mod max_widthu); end if; end if; end if; -- wrclk'event and (wrclk = '0') if ((rdclk'event) and (rdclk = '1') and (NOW > 0 ns)) then if ((lpm_showahead = "ON") and (add_ram_output_register = "ON") and (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family))) then for i in 0 to max_widthu_minus_one loop if (i_data_ready(i) = false) then i_data_delay_count(i) <= i_data_delay_count(i) + 1; end if; if (i_data_delay_count(i) = (rdsync_delaypipe+2)) then i_data_ready(i) <= true; i_data_delay_count(i) <= 0; end if; end loop; if (aclr = '0') then i_showahead_flag3 <= '1'; end if; end if; if ((aclr = '1') and (not (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)) or (use_eab = "OFF"))) then if (lpm_showahead = "ON") then i_q_tmp <= mem_data(0); else i_q_tmp <= ZEROS; end if; elsif ((aclr = '1') and (add_ram_output_register = "ON") and (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family))) then if (lpm_showahead = "ON") then i_q_tmp <= UNKNOWN; else i_q_tmp <= ZEROS; end if; elsif ((i_rden = '1') and (NOW > 0 ns)) then if ((aclr = '0') and (i_rdptr < max_widthu_minus_one)) then i_rdptr <= i_rdptr + 1; else i_rdptr <= ZEROU; end if; if (lpm_showahead = "ON") then if ((add_ram_output_register = "ON") and (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family))) then i_showahead_flag3 <= '1'; else i_q_tmp <= mem_data(CONV_INTEGER(i_rdptr + 1) mod max_widthu); end if; else i_q_tmp <= mem_data(CONV_INTEGER(i_rdptr) mod max_widthu); end if; end if; end if; -- (rdclk'event) and (rdclk = '1') if (i_showahead_flag'event and (i_showahead_flag = '1')) then if ((lpm_showahead = "ON") and (add_ram_output_register = "ON") and (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family))) then if (i_rdempty = '0') then rdptr_tmp := CONV_INTEGER(i_rdptr) mod max_widthu; if (i_data_ready(rdptr_tmp) = true) then i_q_tmp <= mem_data(rdptr_tmp); mem_data2(rdptr_tmp) := mem_data(rdptr_tmp); else i_q_tmp <= mem_data2(rdptr_tmp); end if; end if; end if; i_showahead_flag3 <= '0'; end if; end process; -- aclr, wrclk, rdclk events process (i_showahead_flag3) begin i_showahead_flag2 <= i_showahead_flag3; end process; process (i_showahead_flag2) begin i_showahead_flag1 <= i_showahead_flag2; end process; process (i_showahead_flag1) begin i_showahead_flag <= i_showahead_flag1; end process; i_rden <= rdreq when underflow_checking = "OFF" else rdreq and not i_rdempty; i_wren <= wrreq when overflow_checking = "OFF" else wrreq and not i_wrfull; -- Delays & DFF Pipes process (rdclk) begin if (rdclk'event and (rdclk = '0')) then i_rdenclock <= '0'; elsif (rdclk'event and (rdclk = '1')) then if (i_rden = '1') then i_rdenclock <= '1'; end if; end if; end process; -- rdclk event process (i_wrptr, i_ws_dbrp) begin if (NOW > 0 ns) then i_wr_udwn <= i_wrptr - i_ws_dbrp; end if; end process; -- i_wrptr, i_ws_dbrp events process (i_rdptr, i_rs_dbwp) begin if (NOW > 0 ns) then i_rd_udwn <= i_rs_dbwp - i_rdptr; end if; end process; -- i_rdptr, i_rs_dbwp events -- Outputs rdempty <= i_rdempty; rdfull <= i_rdfull; wrempty <= i_wrempty; wrfull <= i_wrfull; rdusedw <= i_rdusedw; wrusedw <= i_wrusedw; q <= i_q_tmp; end behavior; -- dcfifo_async -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : dcfifo_sync -- -- Description : Synchronous Dual Clocks FIFO -- -- Limitation : -- -- Results Expected: -- ---END_ENTITY_HEADER----------------------------------------------------------- -- BEGINNING OF ENTITY library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.ALTERA_DEVICE_FAMILIES.all; use work.DCFIFO_DFFPIPE; -- ENTITY DECLARATION entity DCFIFO_SYNC is -- GENERIC DECLARATION generic ( lpm_width : natural; lpm_widthu : natural; lpm_numwords : natural; intended_device_family : string := "Stratix"; lpm_showahead : string := "OFF"; underflow_checking : string := "ON"; overflow_checking : string := "ON"; use_eab : string := "ON"; add_ram_output_register : string := "OFF"); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION data : in std_logic_vector(lpm_width-1 downto 0); rdclk : in std_logic; wrclk : in std_logic; aclr : in std_logic := '0'; rdreq : in std_logic; wrreq : in std_logic; -- OUTPUT PORT DECLARATION rdfull : out std_logic; wrfull : out std_logic; rdempty : out std_logic; wrempty : out std_logic; rdusedw : out std_logic_vector(lpm_widthu-1 downto 0); wrusedw : out std_logic_vector(lpm_widthu-1 downto 0); q : out std_logic_vector(lpm_width-1 downto 0)); end DCFIFO_SYNC; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of DCFIFO_SYNC is -- TYPE DECLARATION type LPM_MEMORY is array (2**lpm_widthu-1 downto 0) of std_logic_vector(lpm_width-1 downto 0); -- CONSTANT DECLARATION constant ZEROS : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0'); constant ZEROU : std_logic_vector(lpm_widthu downto 0) := (OTHERS => '0'); -- SIGNAL DECLARATION signal i_data_tmp : std_logic_vector(lpm_width-1 downto 0); signal i_rdptr : std_logic_vector(lpm_widthu downto 0) := (OTHERS => '0'); signal i_wrptr : std_logic_vector(lpm_widthu downto 0) := (OTHERS => '0'); signal i_wrptr_tmp : std_logic_vector(lpm_widthu downto 0) := (OTHERS => '0'); signal i_rdptr_s : std_logic_vector(lpm_widthu downto 0) := (OTHERS => '0'); signal i_wrptr_r : std_logic_vector(lpm_widthu downto 0) := (OTHERS => '0'); signal i_wrptr_s : std_logic_vector(lpm_widthu downto 0) := (OTHERS => '0'); signal i_rdempty : std_logic := '1'; signal i_wrempty : std_logic := '1'; signal i_rdfull : std_logic := '0'; signal i_wrfull : std_logic := '0'; signal i_rden : std_logic := '0'; signal i_wren : std_logic := '0'; signal i_wren_tmp : std_logic := '0'; signal i_rdusedw : std_logic_vector(lpm_widthu downto 0) := (OTHERS => '0'); signal i_wrusedw : std_logic_vector(lpm_widthu downto 0) := (OTHERS => '0'); signal i_q_tmp : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0'); signal i_cnt_mod : natural := 0; signal i_max_widthu : natural := 0; -- COMPONENT DECLARATION component DCFIFO_DFFPIPE generic ( lpm_delay : natural; lpm_width : natural); port ( d : in std_logic_vector(LPM_WIDTH-1 downto 0); clock : in std_logic; aclr : in std_logic := '0'; q : out std_logic_vector(LPM_WIDTH-1 downto 0)); end component; begin -- Delays RDPTR_D: DCFIFO_DFFPIPE generic map ( lpm_delay => 1, lpm_width => lpm_widthu + 1) port map ( d => i_rdptr, clock => wrclk, aclr => aclr, q => i_rdptr_s); WRPTR_D: DCFIFO_DFFPIPE generic map ( lpm_delay => 1, lpm_width => lpm_widthu + 1) port map ( d => i_wrptr, clock => wrclk, aclr => aclr, q => i_wrptr_r); WRPTR_E: DCFIFO_DFFPIPE generic map ( lpm_delay => 1, lpm_width => lpm_widthu + 1) port map ( d => i_wrptr_r, clock => rdclk, aclr => aclr, q => i_wrptr_s); -- PROCESS DECLARATION -- FIFOram process (aclr, wrclk, rdclk) variable need_init : boolean := true; variable mem_data : LPM_MEMORY := (OTHERS => ZEROS); begin if (need_init) then if ((lpm_showahead /= "ON") and (lpm_showahead /= "OFF")) then ASSERT FALSE REPORT "Error! LPM_SHOWAHEAD must be ON or OFF." SEVERITY ERROR; end if; if ((underflow_checking /= "ON") and (underflow_checking /= "OFF")) then ASSERT FALSE REPORT "Error! UNDERFLOW_CHECKING must be ON or OFF." SEVERITY ERROR; end if; if ((overflow_checking /= "ON") and (overflow_checking /= "OFF")) then ASSERT FALSE REPORT "Error! OVERFLOW_CHECKING must be ON or OFF." SEVERITY ERROR; end if; if ((use_eab /= "ON") and (use_eab /= "OFF")) then ASSERT FALSE REPORT "Error! USE_EAB must be ON or OFF." SEVERITY ERROR; end if; if (lpm_numwords > 2 ** lpm_widthu) then ASSERT FALSE REPORT "Error! LPM_NUMWORDS must be less than or equal to 2**LPM_WIDTHU." SEVERITY ERROR; end if; if ((add_ram_output_register /= "ON") and (add_ram_output_register /= "OFF")) then ASSERT FALSE REPORT "Error! ADD_RAM_OUTPUT_REGISTER must be ON or OFF." SEVERITY ERROR; end if; if (IS_VALID_FAMILY(intended_device_family) = false) then ASSERT FALSE REPORT "Error! Illegal INTENDED_DEVICE_FAMILY." SEVERITY ERROR; end if; for i in lpm_numwords-1 downto 0 loop mem_data(i) := ZEROS; end loop; if (lpm_numwords = 2 ** lpm_widthu) then i_cnt_mod <= 2 ** (lpm_widthu + 1); else i_cnt_mod <= 2 ** lpm_widthu; end if; i_max_widthu <= 2 ** lpm_widthu; need_init := false; end if; -- need_init if (aclr'event and (aclr = '1')) then i_rdptr <= ZEROU; i_wrptr <= ZEROU; if (not (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)) or ((add_ram_output_register = "ON") and (use_eab = "OFF"))) then if (lpm_showahead = "ON") then if ((FEATURE_FAMILY_STRATIXII(intended_device_family)) or (FEATURE_FAMILY_CYCLONEII(intended_device_family))) then i_q_tmp <= (OTHERS => 'X'); else i_q_tmp <= mem_data(0); end if; else i_q_tmp <= ZEROS; end if; end if; end if; -- aclr event if (wrclk'event and (wrclk = '1')) then if ((aclr = '1') and (not (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)) or ((add_ram_output_register = "ON") and (use_eab = "OFF")))) then i_data_tmp <= ZEROS; i_wrptr_tmp <= ZEROU; i_wren_tmp <= '0'; elsif (NOW > 0 ns) then i_data_tmp <= data; i_wrptr_tmp <= i_wrptr; i_wren_tmp <= i_wren; if (i_wren = '1') then if ((aclr = '0') and (i_wrptr < i_cnt_mod - 1)) then i_wrptr <= i_wrptr + 1; else i_wrptr <= ZEROU; end if; if (use_eab = "OFF") then mem_data(CONV_INTEGER(i_wrptr) mod i_max_widthu) := data; if (lpm_showahead = "ON") then i_q_tmp <= mem_data(CONV_INTEGER(i_rdptr) mod i_max_widthu); end if; end if; end if; end if; end if; -- wrclk'event and (wrclk = '1') if (wrclk'event and (wrclk = '0')) then if((use_eab = "ON") and (NOW > 0 ns)) then if (i_wren_tmp = '1') then mem_data(CONV_INTEGER(i_wrptr_tmp) mod i_max_widthu) := i_data_tmp; end if; if ((lpm_showahead = "ON") and (not(FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)))) then i_q_tmp <= mem_data(CONV_INTEGER(i_rdptr) mod i_max_widthu); end if; end if; end if; -- wrclk'event and (wrclk = '0') if (rdclk'event and (rdclk = '1')) then if ((aclr = '1') and (not (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)) or ((add_ram_output_register = "ON") and (use_eab = "OFF")))) then if (lpm_showahead = "ON") then if ((FEATURE_FAMILY_STRATIXII(intended_device_family)) or (FEATURE_FAMILY_CYCLONEII(intended_device_family))) then i_q_tmp <= (OTHERS => 'X'); else i_q_tmp <= mem_data(0); end if; else i_q_tmp <= ZEROS; end if; elsif ((i_rden = '1') and (NOW > 0 ns)) then if ((aclr = '0') and (i_rdptr < i_cnt_mod - 1)) then i_rdptr <= i_rdptr + 1; else i_rdptr <= ZEROU; end if; if ((lpm_showahead = "ON") and (not ((use_eab = "ON") and (FEATURE_FAMILY_BASE_STRATIX(intended_device_family) or FEATURE_FAMILY_BASE_CYCLONE(intended_device_family))))) then i_q_tmp <= mem_data(CONV_INTEGER(i_rdptr + 1) mod i_max_widthu); else i_q_tmp <= mem_data(CONV_INTEGER(i_rdptr) mod i_max_widthu); end if; end if; end if; -- rdclk'event and (rdclk = '1') end process; -- aclr, wrclk, rdclk events i_rden <= rdreq when (underflow_checking = "OFF") else rdreq and not i_rdempty; i_wren <= wrreq when (overflow_checking = "OFF") else wrreq and not i_wrfull; -- Usedw/Empty/Full process (i_rdptr, i_wrptr_s, i_cnt_mod) begin if (NOW > 0 ns) then if (CONV_INTEGER (i_wrptr_s) >= CONV_INTEGER (i_rdptr)) then i_rdusedw <= i_wrptr_s - i_rdptr; else i_rdusedw <= i_wrptr_s + i_cnt_mod - i_rdptr; end if; end if; end process; -- i_rdusedw event process (i_wrptr, i_rdptr_s, i_cnt_mod) begin if (NOW > 0 ns) then if (CONV_INTEGER (i_wrptr) >= CONV_INTEGER (i_rdptr_s)) then i_wrusedw <= i_wrptr - i_rdptr_s; else i_wrusedw <= i_wrptr + i_cnt_mod - i_rdptr_s; end if; end if; end process; -- i_wrusedw event process (i_rdusedw, i_max_widthu) begin if (i_rdusedw = 0) then i_rdempty <= '1'; else i_rdempty <= '0'; end if; if ((lpm_numwords = i_max_widthu) and (i_rdusedw >= i_max_widthu)) or ((lpm_numwords < i_max_widthu) and (i_rdusedw = lpm_numwords)) then i_rdfull <= '1'; else i_rdfull <= '0'; end if; end process; -- i_rdempty and i_rdfull event process (i_wrusedw, i_max_widthu) begin if (i_wrusedw = 0) then i_wrempty <= '1'; else i_wrempty <= '0'; end if; if ((lpm_numwords = i_max_widthu) and (i_wrusedw >= i_max_widthu)) or ((lpm_numwords < i_max_widthu) and (i_wrusedw = lpm_numwords)) then i_wrfull <= '1'; else i_wrfull <= '0'; end if; end process; -- i_wrempty and i_wrfull event -- Outputs rdfull <= i_rdfull; wrfull <= i_wrfull; rdempty <= i_rdempty; wrempty <= i_wrempty; rdusedw <= i_rdusedw (lpm_widthu-1 downto 0); wrusedw <= i_wrusedw (lpm_widthu-1 downto 0); q <= i_q_tmp; end behavior; -- dcfifo_sync -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : dcfifo_low_latency -- -- Description : Dual Clocks FIFO with lowest latency. This fifo implements -- the fifo behavior for Stratix II, Cyclone II, Stratix III, -- Cyclone III and Stratix showahead area mode (LPM_SHOWAHEAD= -- ON, ADD_RAM_OUTPUT_REGISTER=OFF) -- -- Limitation : -- -- Results Expected: -- ---END_ENTITY_HEADER----------------------------------------------------------- -- BEGINNING OF ENTITY library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.ALTERA_DEVICE_FAMILIES.all; use work.DCFIFO_DFFPIPE; use work.ALTERA_MF_HINT_EVALUATION.all; -- ENTITY DECLARATION entity DCFIFO_LOW_LATENCY is -- GENERIC DECLARATION generic ( lpm_width : natural; lpm_widthu : natural; lpm_width_r : natural; lpm_widthu_r : natural; lpm_numwords : natural; delay_rdusedw : natural := 2; delay_wrusedw : natural := 2; rdsync_delaypipe : natural := 0; wrsync_delaypipe : natural := 0; intended_device_family : string := "Stratix"; lpm_showahead : string := "OFF"; underflow_checking : string := "ON"; overflow_checking : string := "ON"; add_usedw_msb_bit : string := "OFF"; read_aclr_synch : string := "OFF"; write_aclr_synch : string := "OFF"; lpm_hint : string := "USE_EAB=ON"); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION data : in std_logic_vector(lpm_width-1 downto 0); rdclk : in std_logic; wrclk : in std_logic; aclr : in std_logic := '0'; rdreq : in std_logic; wrreq : in std_logic; -- OUTPUT PORT DECLARATION rdfull : out std_logic; wrfull : out std_logic; rdempty : out std_logic; wrempty : out std_logic; rdusedw : out std_logic_vector(lpm_widthu_r-1 downto 0); wrusedw : out std_logic_vector(lpm_widthu-1 downto 0); q : out std_logic_vector(lpm_width_r-1 downto 0)); end DCFIFO_LOW_LATENCY; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of DCFIFO_LOW_LATENCY is -- FUNCTION DECLARATION function get_delay_rdusedw (constant i_input_delay_rdusedw : in natural) return natural is variable i_delay_rdusedw : natural; begin if (i_input_delay_rdusedw > 2) then i_delay_rdusedw := 2; else i_delay_rdusedw := i_input_delay_rdusedw; end if; return i_delay_rdusedw; end get_delay_rdusedw; function get_delay_wrusedw (constant i_input_delay_wrusedw : in natural) return natural is variable i_delay_wrusedw : natural; begin if (i_input_delay_wrusedw > 2) then i_delay_wrusedw := 2; else i_delay_wrusedw := i_input_delay_wrusedw; end if; return i_delay_wrusedw; end get_delay_wrusedw; function STR_TO_INT ( str : string ) return integer is variable ivalue : integer := 0; variable digit : integer := 0; begin for i in str'left to str'right loop case str(i) is 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 "& str(i) & "in string parameter! " SEVERITY ERROR; end case; ivalue := ivalue * 10 + digit; end loop; return ivalue; end STR_TO_INT; function is_wrempty_speed (constant i_maximize_speed : in string) return boolean is begin if (FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM(intended_device_family)) then return true; elsif (FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM(intended_device_family)) then if ((STR_TO_INT(i_maximize_speed) > 5) or (wrsync_delaypipe >= 2)) then return true; else return false; end if; else return false; end if; end is_wrempty_speed; function is_rdfull_speed (constant i_maximize_speed : in string) return boolean is begin if (FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM(intended_device_family)) then return true; elsif (FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM(intended_device_family)) then if ((STR_TO_INT(i_maximize_speed) > 5) or (rdsync_delaypipe >= 2)) then return true; else return false; end if; else return false; end if; end is_rdfull_speed; function get_cnt_mod (constant i_intended_device_family : in string) return natural is begin if (FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM(i_intended_device_family)) then if (add_usedw_msb_bit = "OFF") then if (lpm_width_r > lpm_width) then return (2 ** lpm_widthu) + lpm_width_r/lpm_width; else return (2 ** lpm_widthu) + 1; end if; else if (lpm_width_r > lpm_width) then return (2 ** (lpm_widthu-1)) + lpm_width_r/lpm_width; else return (2 ** (lpm_widthu-1)) + 1; end if; end if; else return 2 ** lpm_widthu; end if; end get_cnt_mod; function get_cnt_mod_r (constant i_intended_device_family : in string) return natural is begin if (FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM(i_intended_device_family)) then if (add_usedw_msb_bit = "OFF") then if (lpm_width_r > lpm_width) then return (2 ** lpm_widthu_r) + 1; else return (2 ** lpm_widthu_r) + lpm_width/lpm_width_r; end if; else if (lpm_width_r > lpm_width) then return (2 ** (lpm_widthu_r-1)) + 1; else return (2 ** (lpm_widthu_r-1)) + lpm_width/lpm_width_r; end if; end if; else return 2 ** lpm_widthu_r; end if; end get_cnt_mod_r; function get_width_ratio (constant L, R : natural) return natural is begin if L > R then return L/R; else return R/L; end if; end get_width_ratio; function get_fifo_depth (constant widthu_r : natural) return natural is begin if (add_usedw_msb_bit = "OFF") then return widthu_r; else return widthu_r -1; end if; end get_fifo_depth; -- CONSTANT DECLARATION constant ZEROS : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0'); constant ZEROU : std_logic_vector(lpm_widthu+1 downto 0) := (OTHERS => '0'); constant ZEROS_R : std_logic_vector(lpm_width_r-1 downto 0) := (OTHERS => '0'); constant ZEROU_R : std_logic_vector(lpm_widthu_r+1 downto 0) := (OTHERS => '0'); constant MAXIMIZE_SPEED : string := GET_PARAMETER_VALUE(lpm_hint, "MAXIMIZE_SPEED"); constant USE_WREMPTY_SPEED : boolean := is_wrempty_speed(MAXIMIZE_SPEED); constant USE_RDFULL_SPEED : boolean := is_rdfull_speed(MAXIMIZE_SPEED); constant CNT_MOD : natural := get_cnt_mod(intended_device_family); constant CNT_MOD_R : natural := get_cnt_mod_r(intended_device_family); constant WIDTH_RATIO : natural := get_width_ratio(lpm_width, lpm_width_r); constant FIFO_DEPTH : natural := get_fifo_depth(lpm_widthu_r); constant USE_SYNC_READ_ACLR : boolean := (FEATURE_FAMILY_STRATIXIII(intended_device_family) or FEATURE_FAMILY_CYCLONEIII(intended_device_family)) and (read_aclr_synch = "ON"); constant USE_SYNC_WRITE_ACLR : boolean := (FEATURE_FAMILY_STRATIXII(intended_device_family) or FEATURE_FAMILY_CYCLONEII(intended_device_family)) and (write_aclr_synch = "ON"); -- TYPE DECLARATION type LPM_MEMORY is array (2**(FIFO_DEPTH)+ WIDTH_RATIO downto 0) of std_logic_vector(lpm_width_r-1 downto 0); -- SIGNAL DECLARATION signal mem_data : LPM_MEMORY := (OTHERS => ZEROS_R); signal i_rdptr_g : std_logic_vector(lpm_widthu_r+1 downto 0) := (OTHERS => '0'); signal i_rdptr_g1p : std_logic_vector(lpm_widthu_r+1 downto 0) := CONV_STD_LOGIC_VECTOR(1, lpm_widthu_r+2); signal i_wrptr_g : std_logic_vector(lpm_widthu+1 downto 0) := (OTHERS => '0'); signal i_wrptr_g1 : std_logic_vector(lpm_widthu+1 downto 0) := CONV_STD_LOGIC_VECTOR(1, lpm_widthu+2); signal i_delayed_wrptr_g : std_logic_vector(lpm_widthu+1 downto 0) := (OTHERS => '0'); signal i_rden : std_logic := '0'; signal i_wren : std_logic := '0'; signal i_showahead_flag : std_logic := '0'; signal i_rdempty : std_logic := '1'; signal i_wrempty_area : std_logic := '1'; signal i_wrempty_speed : std_logic := '1'; signal i_rdempty_rreg : std_logic := '1'; signal i_rdfull_area : std_logic := '0'; signal i_rdfull_speed : std_logic := '0'; signal i_wrfull : std_logic := '0'; signal i_wrfull_wreg : std_logic := '0'; signal i_rdusedw : std_logic_vector(lpm_widthu_r+1 downto 0) := (OTHERS => '0'); signal i_wrusedw : std_logic_vector(lpm_widthu+1 downto 0) := (OTHERS => '0'); signal i_rdusedw_tmp : std_logic_vector(lpm_widthu_r+1 downto 0) := (OTHERS => '0'); signal i_wrusedw_tmp : std_logic_vector(lpm_widthu+1 downto 0) := (OTHERS => '0'); signal i_rs_dgwp : std_logic_vector(lpm_widthu+1 downto 0) := (OTHERS => '0'); signal i_ws_dgrp : std_logic_vector(lpm_widthu_r+1 downto 0) := (OTHERS => '0'); signal i_q : std_logic_vector(lpm_width_r-1 downto 0) := (OTHERS => '0'); signal sync_rdaclr : std_logic := '1'; signal sync_rdaclr_pre : std_logic := '1'; signal read_aclr : std_logic := '0'; signal sync_wraclr : std_logic := '1'; signal sync_wraclr_pre : std_logic := '1'; signal write_aclr : std_logic := '0'; signal is_overflow : boolean := false; signal is_underflow : boolean := false; -- COMPONENT DECLARATION component DCFIFO_DFFPIPE generic ( lpm_delay : natural; lpm_width : natural); port ( d : in std_logic_vector(lpm_width-1 downto 0); clock : in std_logic; aclr : in std_logic := '0'; q : out std_logic_vector(lpm_width-1 downto 0)); end component; begin -- COMPONENT INSTANTIATIONS DP_WS_DGRP : dcfifo_dffpipe generic map ( lpm_delay => wrsync_delaypipe, lpm_width => lpm_widthu_r + 2) port map ( d => i_rdptr_g, clock => wrclk, aclr => aclr, q => i_ws_dgrp); DP_RS_DGWP : dcfifo_dffpipe generic map ( lpm_delay => rdsync_delaypipe, lpm_width => lpm_widthu + 2) port map ( d => i_delayed_wrptr_g, clock => rdclk, aclr => aclr, q => i_rs_dgwp); DP_RDUSEDW : dcfifo_dffpipe generic map ( lpm_delay => get_delay_rdusedw(delay_rdusedw), lpm_width => lpm_widthu_r + 2) port map ( d => i_rdusedw_tmp, clock => rdclk, aclr => aclr, q => i_rdusedw); DP_WRUSEDW : dcfifo_dffpipe generic map ( lpm_delay => get_delay_wrusedw(delay_wrusedw), lpm_width => lpm_widthu + 2) port map ( d => i_wrusedw_tmp, clock => wrclk, aclr => aclr, q => i_wrusedw); -- PROCESS DECLARATION -- FIFOram process (aclr, wrclk, rdclk, write_aclr, read_aclr) variable need_init : boolean := true; variable mem_data : LPM_MEMORY := (OTHERS => ZEROS_R); variable i_q_is_registered : boolean := false; variable max_widthu_r : integer := 0; variable no_warn : boolean := false; variable start_address : integer := 0; begin if (need_init) then if ((lpm_showahead /= "ON") and (lpm_showahead /= "OFF")) then ASSERT FALSE REPORT "Error! LPM_SHOWAHEAD must be ON or OFF." SEVERITY ERROR; end if; if ((underflow_checking /= "ON") and (underflow_checking /= "OFF")) then ASSERT FALSE REPORT "Error! UNDERFLOW_CHECKING must be ON or OFF." SEVERITY ERROR; end if; if ((overflow_checking /= "ON") and (overflow_checking /= "OFF")) then ASSERT FALSE REPORT "Error! OVERFLOW_CHECKING must be ON or OFF." SEVERITY ERROR; end if; if (lpm_numwords > 2 ** lpm_widthu) then ASSERT FALSE REPORT "Error! LPM_NUMWORDS must be less than or equal to 2**LPM_WIDTHU." SEVERITY ERROR; end if; if (IS_VALID_FAMILY(intended_device_family) = false) then ASSERT FALSE REPORT "Error! Illegal INTENDED_DEVICE_FAMILY." SEVERITY ERROR; end if; max_widthu_r := CNT_MOD_R; if ((lpm_showahead = "OFF") and ((FEATURE_FAMILY_STRATIXII(intended_device_family)) or (FEATURE_FAMILY_CYCLONEII(intended_device_family)))) then i_q_is_registered := true; else i_q_is_registered := false; end if; need_init := false; end if; -- need_init if (aclr'event and (aclr = '1')) then i_rdptr_g <= ZEROU_R; i_rdptr_g1p <= CONV_STD_LOGIC_VECTOR(1, lpm_widthu_r+2); i_wrptr_g <= ZEROU; i_wrptr_g1 <= CONV_STD_LOGIC_VECTOR(1, lpm_widthu+2); i_delayed_wrptr_g <= ZEROU; i_wrempty_area <= '1'; i_rdempty_rreg <= '1'; i_rdfull_area <= '0'; i_wrfull_wreg <= '0'; is_overflow <= false; is_underflow <= false; no_warn := false; if(i_q_is_registered) then i_q <= (OTHERS => '0'); elsif ((FEATURE_FAMILY_STRATIXII(intended_device_family)) or (FEATURE_FAMILY_CYCLONEII(intended_device_family))) then i_q <= (OTHERS => 'X'); end if; end if; if ((wrclk'event) and (wrclk = '1') and (NOW > 0 ns)) then if (write_aclr = '0') then if (i_wren = '1') then if ((i_wrfull = '1') and (overflow_checking = "OFF")) then if (no_warn = false) then ASSERT FALSE REPORT "Overflow occurred! Fifo output is unknown until the next reset is asserted" SEVERITY WARNING; no_warn := true; end if; is_overflow <= true; else if (i_wrptr_g1 < (cnt_mod - 1)) then i_wrptr_g1 <= i_wrptr_g1 + 1; else i_wrptr_g1 <= ZEROU; end if; i_wrptr_g <= i_wrptr_g1; if (lpm_width > lpm_width_r) then for i in 0 to (lpm_width/lpm_width_r-1) loop mem_data((CONV_INTEGER(i_wrptr_g)*lpm_width/lpm_width_r+i) mod max_widthu_r) := data(lpm_width_r*(i + 1) -1 downto lpm_width_r*i); end loop; elsif (lpm_width < lpm_width_r) then start_address := CONV_INTEGER(i_wrptr_g) mod (lpm_width_r/lpm_width); mem_data((CONV_INTEGER(i_wrptr_g)*lpm_width/lpm_width_r) mod max_widthu_r)((start_address +1 )*lpm_width -1 downto (start_address * lpm_width)) := data; else mem_data(CONV_INTEGER(i_wrptr_g) mod max_widthu_r) := data; end if; end if; end if; i_delayed_wrptr_g <= i_wrptr_g; end if; i_wrempty_area <= i_rdempty_rreg; if ((aclr = '0') and (write_aclr_synch = "ON") and (FEATURE_FAMILY_STRATIXII(intended_device_family) or FEATURE_FAMILY_CYCLONEII(intended_device_family))) then i_wrfull_wreg <= (i_wrfull or write_aclr); else i_wrfull_wreg <= i_wrfull; end if; end if; if (rdclk'event and (rdclk = '1')) then if (read_aclr = '0') then if ((i_rden = '1') and (NOW > 0 ns)) then if ((i_rdempty = '1') and (underflow_checking = "OFF")) then if (no_warn = false) then ASSERT FALSE REPORT "Underflow occurred! Fifo output is unknown until the next reset is asserted" SEVERITY WARNING; no_warn := true; end if; is_underflow <= true; else if (i_rdptr_g1p < (cnt_mod_r - 1)) then i_rdptr_g1p <= i_rdptr_g1p + 1; else i_rdptr_g1p <= ZEROU_R; end if; i_rdptr_g <= i_rdptr_g1p; end if; end if; end if; if ((is_overflow = true) or (is_underflow = true)) then i_q <= (OTHERS => 'X'); else if ((i_q_is_registered = false) and (NOW > 0 ns)) then if ((read_aclr = '1') and ((FEATURE_FAMILY_STRATIXII(intended_device_family)) or (FEATURE_FAMILY_CYCLONEII(intended_device_family)))) then i_q <= (OTHERS => 'X'); else if (i_rdempty = '1') then i_q <= mem_data(CONV_INTEGER(i_rdptr_g) mod max_widthu_r); elsif (i_rden = '1') then i_q <= mem_data(CONV_INTEGER(i_rdptr_g1p) mod max_widthu_r); end if; end if; elsif ((read_aclr = '0') and (i_rden = '1') and (NOW > 0 ns)) then i_q <= mem_data(CONV_INTEGER(i_rdptr_g) mod max_widthu_r); end if; end if; if ((rdclk = '1') and (NOW > 0 ns)) then i_rdfull_area <= i_wrfull_wreg; i_rdempty_rreg <= i_rdempty; end if; end if; -- rdclk event end process; process (wrclk, aclr) begin if (aclr = '1') then sync_wraclr <= '1'; sync_wraclr_pre <= '1'; elsif (wrclk'event and (wrclk = '1') and (NOW > 0 ns)) then sync_wraclr <= sync_wraclr_pre; sync_wraclr_pre <= '0'; end if; end process; process (rdclk, aclr) begin if (aclr = '1') then sync_rdaclr <= '1'; sync_rdaclr_pre <= '1'; elsif (rdclk'event and (rdclk = '1') and (NOW > 0 ns)) then sync_rdaclr <= sync_rdaclr_pre; sync_rdaclr_pre <= '0'; end if; end process; process (i_rdptr_g, i_rs_dgwp) begin if (lpm_width > lpm_width_r) then if (CONV_INTEGER(i_rdptr_g(lpm_widthu_r downto 0))*lpm_width_r/lpm_width = CONV_INTEGER((i_rs_dgwp(lpm_widthu downto 0)))) then i_rdempty <= '1'; else i_rdempty <= '0'; end if; else if (CONV_INTEGER(i_rdptr_g(lpm_widthu_r downto 0)) = CONV_INTEGER((i_rs_dgwp(lpm_widthu downto 0)))*lpm_width/lpm_width_r) then i_rdempty <= '1'; else i_rdempty <= '0'; end if; end if; end process; process (i_wrptr_g1, i_ws_dgrp) begin if (lpm_width < lpm_width_r) then if (((CONV_INTEGER(i_wrptr_g1(lpm_widthu downto 0)) + WIDTH_RATIO -1) mod CNT_MOD) = CONV_INTEGER(i_ws_dgrp(lpm_widthu_r downto 0))*lpm_width_r/lpm_width) then i_wrfull <= '1'; else i_wrfull <= '0'; end if; else if (CONV_INTEGER(i_wrptr_g1(lpm_widthu downto 0)) = CONV_INTEGER(i_ws_dgrp(lpm_widthu_r downto 0))*lpm_width_r/lpm_width) then i_wrfull <= '1'; else i_wrfull <= '0'; end if; end if; end process; process (i_wrptr_g, i_ws_dgrp) begin if ((NOW > 0 ns) and (CONV_INTEGER(i_wrptr_g) < CONV_INTEGER(i_ws_dgrp)*lpm_width_r/lpm_width)) then i_wrusedw_tmp <= CONV_STD_LOGIC_VECTOR(CNT_MOD + CONV_INTEGER(i_wrptr_g) - CONV_INTEGER(i_ws_dgrp)*lpm_width_r/lpm_width, lpm_widthu + 2); else i_wrusedw_tmp <= CONV_STD_LOGIC_VECTOR(CONV_INTEGER(i_wrptr_g) - CONV_INTEGER(i_ws_dgrp)*lpm_width_r/lpm_width, lpm_widthu + 2); end if; if (lpm_width > lpm_width_r) then if (CONV_INTEGER(i_wrptr_g) = CONV_INTEGER(i_ws_dgrp)*lpm_width_r/lpm_width) then i_wrempty_speed <= '1'; else i_wrempty_speed <= '0'; end if; else if (CONV_INTEGER(i_wrptr_g)*lpm_width/lpm_width_r = CONV_INTEGER(i_ws_dgrp)) then i_wrempty_speed <= '1'; else i_wrempty_speed <= '0'; end if; end if; end process; process (i_rdptr_g, i_rs_dgwp) begin if ((NOW > 0 ns) and (CONV_INTEGER(i_rs_dgwp)*lpm_width/lpm_width_r < CONV_INTEGER(i_rdptr_g))) then i_rdusedw_tmp <= CONV_STD_LOGIC_VECTOR((CNT_MOD + CONV_INTEGER(i_rs_dgwp))*lpm_width/lpm_width_r - CONV_INTEGER(i_rdptr_g), lpm_widthu_r + 2); else i_rdusedw_tmp <= CONV_STD_LOGIC_VECTOR(CONV_INTEGER(i_rs_dgwp)*lpm_width/lpm_width_r - CONV_INTEGER(i_rdptr_g), lpm_widthu_r + 2); end if; if (lpm_width < lpm_width_r) then if (CONV_INTEGER(i_rdptr_g)*lpm_width_r/lpm_width = ((CONV_INTEGER(i_rs_dgwp) + WIDTH_RATIO) mod CNT_MOD)) then i_rdfull_speed <= '1'; else i_rdfull_speed <= '0'; end if; else if (CONV_INTEGER(i_rdptr_g) = ((CONV_INTEGER(i_rs_dgwp) +1) mod CNT_MOD)*lpm_width/lpm_width_r) then i_rdfull_speed <= '1'; else i_rdfull_speed <= '0'; end if; end if; end process; -- SIGNAL ASSIGNMENTS i_rden <= rdreq and not sync_rdaclr when ((underflow_checking = "OFF") and (USE_SYNC_READ_ACLR = true)) else rdreq and not (i_rdempty or sync_rdaclr) when (USE_SYNC_READ_ACLR = true) else rdreq when (underflow_checking = "OFF") else rdreq and not i_rdempty; i_wren <= wrreq and not sync_wraclr when ((overflow_checking = "OFF") and (USE_SYNC_WRITE_ACLR = true)) else wrreq and not (i_wrfull or sync_wraclr) when (USE_SYNC_WRITE_ACLR = true) else wrreq when (overflow_checking = "OFF") else wrreq and not i_wrfull; read_aclr <= sync_rdaclr when ((FEATURE_FAMILY_STRATIXIII(intended_device_family) or FEATURE_FAMILY_CYCLONEIII(intended_device_family)) and (read_aclr_synch = "ON")) else aclr; write_aclr <= sync_wraclr when ((FEATURE_FAMILY_STRATIXII(intended_device_family) or FEATURE_FAMILY_CYCLONEII(intended_device_family)) and (write_aclr_synch = "ON")) else aclr; -- Outputs rdempty <= 'X' when ((is_overflow = true) or (is_underflow = true)) else (i_rdempty or sync_rdaclr) when (USE_SYNC_READ_ACLR = true) else i_rdempty; wrempty <= 'X' when ((is_overflow = true) or (is_underflow = true)) else i_wrempty_speed when (USE_WREMPTY_SPEED) else i_wrempty_area; rdfull <= 'X' when ((is_overflow = true) or (is_underflow = true)) else i_rdfull_speed when (USE_RDFULL_SPEED) else i_rdfull_area; wrfull <= 'X' when ((is_overflow = true) or (is_underflow = true)) else (i_wrfull or sync_wraclr) when (USE_SYNC_WRITE_ACLR = true) else i_wrfull; wrusedw <= (OTHERS => 'X') when ((is_overflow = true) or (is_underflow = true)) else i_wrusedw(lpm_widthu-1 downto 0); rdusedw <= (OTHERS => 'X') when ((is_overflow = true) or (is_underflow = true)) else i_rdusedw(lpm_widthu_r-1 downto 0); q <= (OTHERS => 'X') when ((is_overflow = true) or (is_underflow = true)) else i_q; end behavior; -- dcfifo_low_latency -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : dcfifo_mixed_widths -- -- Description : Mixed Widths Dual clocks FIFO -- -- Limitation : -- -- Results Expected: -- ---END_ENTITY_HEADER----------------------------------------------------------- -- BEGINNING OF ENTITY library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.ALTERA_DEVICE_FAMILIES.all; use work.DCFIFO_ASYNC; use work.DCFIFO_SYNC; use work.DCFIFO_LOW_LATENCY; -- ENTITY DECLARATION entity DCFIFO_MIXED_WIDTHS is -- GENERIC DECLARATION generic ( lpm_width : natural; lpm_widthu : natural; lpm_width_r : natural := 0; lpm_widthu_r : natural := 0; lpm_numwords : natural; delay_rdusedw : natural := 1; delay_wrusedw : natural := 1; rdsync_delaypipe : natural := 0; wrsync_delaypipe : natural := 0; intended_device_family : string := "Stratix"; lpm_showahead : string := "OFF"; underflow_checking : string := "ON"; overflow_checking : string := "ON"; clocks_are_synchronized : string := "FALSE"; use_eab : string := "ON"; add_ram_output_register : string := "OFF"; add_width : natural := 1; ram_block_type : string := "AUTO"; add_usedw_msb_bit : string := "OFF"; read_aclr_synch : string := "OFF"; write_aclr_synch : string := "OFF"; lpm_hint : string := "USE_EAB=ON"; lpm_type : string := "dcfifo_mixed_widths"); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION data : in std_logic_vector(lpm_width-1 downto 0); rdclk : in std_logic; wrclk : in std_logic; aclr : in std_logic := '0'; rdreq : in std_logic; wrreq : in std_logic; -- OUTPUT PORT DECLARATION rdfull : out std_logic; wrfull : out std_logic; rdempty : out std_logic; wrempty : out std_logic; rdusedw : out std_logic_vector(lpm_widthu_r-1 downto 0); wrusedw : out std_logic_vector(lpm_widthu-1 downto 0); q : out std_logic_vector(lpm_width_r-1 downto 0)); end DCFIFO_MIXED_WIDTHS; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of DCFIFO_MIXED_WIDTHS is -- FUNCTION DECLARATION function dcfifo_max(L, R: INTEGER) return INTEGER is begin if L > R then return L; else return R; end if; end; function get_rdsync_delaypipe(i_rdsync_delaypipe : natural) return natural is begin if (i_rdsync_delaypipe = 0) then if ((FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM (intended_device_family) or FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM (intended_device_family)) and (clocks_are_synchronized = "FALSE")) then return 4; else return 3; end if; else return i_rdsync_delaypipe; end if; end; function get_wrsync_delaypipe(i_wrsync_delaypipe : natural) return natural is begin if (i_wrsync_delaypipe = 0) then if ((FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM (intended_device_family) or FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM (intended_device_family)) and (clocks_are_synchronized = "FALSE")) then return 4; else return 3; end if; else return i_wrsync_delaypipe; end if; end; -- CONSTANT DECLARATION constant USE_LOW_LATENCY_FIFO : boolean := (FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM (intended_device_family) and ((use_eab = "ON") or ((use_eab = "OFF") and (lpm_width /= lpm_width_r) and (lpm_width_r /= 0)) or ((lpm_numwords < 16) and (clocks_are_synchronized = "FALSE")))) or (FEATURE_FAMILY_STRATIX(intended_device_family) and (use_eab = "ON") and (((lpm_showahead = "ON") and (add_ram_output_register = "OFF")) or (clocks_are_synchronized = "FALSE_LOW_LATENCY"))); -- CONSTANT DECLARATION constant READ_SIDE_SYNCHRONIZERS : natural := get_rdsync_delaypipe(rdsync_delaypipe); constant WRITE_SIDE_SYNCHRONIZERS : natural := get_wrsync_delaypipe(wrsync_delaypipe); -- For low-latency FIFO, reduce the default number of synchronization stages by 2, but need at least 1 stage constant LOW_RDSYNC_DELAYPIPE : natural := dcfifo_max((READ_SIDE_SYNCHRONIZERS - 2), 1); constant LOW_WRSYNC_DELAYPIPE : natural := dcfifo_max((WRITE_SIDE_SYNCHRONIZERS - 2), 1); constant WIDTH_R : natural := lpm_width_r; constant WIDTHU_R : natural := lpm_widthu_r; -- SIGNAL DECLARATION signal i_rdfull_a : std_logic := '0'; signal i_wrfull_a : std_logic := '0'; signal i_rdempty_a : std_logic := '1'; signal i_wrempty_a : std_logic := '1'; signal i_rdfull_s : std_logic := '0'; signal i_wrfull_s : std_logic := '0'; signal i_rdempty_s : std_logic := '1'; signal i_wrempty_s : std_logic := '1'; signal i_rdfull_l : std_logic := '0'; signal i_wrfull_l : std_logic := '0'; signal i_rdempty_l : std_logic := '1'; signal i_wrempty_l : std_logic := '1'; signal i_rdusedw_a : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_wrusedw_a : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_rdusedw_s : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_wrusedw_s : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_rdusedw_l : std_logic_vector(WIDTHU_R-1 downto 0) := (OTHERS => '0'); signal i_wrusedw_l : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_q_a : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0'); signal i_q_s : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0'); signal i_q_l : std_logic_vector(WIDTH_R-1 downto 0) := (OTHERS => '0'); -- COMPONENT DECLARATION component DCFIFO_ASYNC generic ( lpm_width : natural; lpm_widthu : natural; lpm_numwords : natural; delay_rdusedw : natural := 1; delay_wrusedw : natural := 1; rdsync_delaypipe : natural := 0; wrsync_delaypipe : natural := 0; intended_device_family : string := "Stratix"; lpm_showahead : string := "OFF"; underflow_checking : string := "ON"; overflow_checking : string := "ON"; use_eab : string := "ON"; add_ram_output_register : string := "OFF"); port ( data : in std_logic_vector(lpm_width-1 downto 0); rdclk : in std_logic; wrclk : in std_logic; aclr : in std_logic := '0'; rdreq : in std_logic; wrreq : in std_logic; rdfull : out std_logic; wrfull : out std_logic; rdempty : out std_logic; wrempty : out std_logic; rdusedw : out std_logic_vector(lpm_widthu-1 downto 0); wrusedw : out std_logic_vector(lpm_widthu-1 downto 0); q : out std_logic_vector(lpm_width-1 downto 0)); end component; component DCFIFO_SYNC generic ( lpm_width : natural; lpm_widthu : natural; lpm_numwords : natural; intended_device_family : string := "Stratix"; lpm_showahead : string := "OFF"; underflow_checking : string := "ON"; overflow_checking : string := "ON"; use_eab : string := "ON"; add_ram_output_register : string := "OFF"); port ( data : in std_logic_vector(lpm_width-1 downto 0); rdclk : in std_logic; wrclk : in std_logic; aclr : in std_logic := '0'; rdreq : in std_logic; wrreq : in std_logic; rdfull : out std_logic; wrfull : out std_logic; rdempty : out std_logic; wrempty : out std_logic; rdusedw : out std_logic_vector(lpm_widthu-1 downto 0); wrusedw : out std_logic_vector(lpm_widthu-1 downto 0); q : out std_logic_vector(lpm_width-1 downto 0)); end component; component DCFIFO_LOW_LATENCY generic ( lpm_width : natural; lpm_widthu : natural; lpm_width_r : natural; lpm_widthu_r : natural; lpm_numwords : natural; delay_rdusedw : natural := 2; delay_wrusedw : natural := 2; rdsync_delaypipe : natural := 0; wrsync_delaypipe : natural := 0; intended_device_family : string := "Stratix"; lpm_showahead : string := "OFF"; underflow_checking : string := "ON"; overflow_checking : string := "ON"; add_usedw_msb_bit : string := "OFF"; read_aclr_synch : string := "OFF"; write_aclr_synch : string := "OFF"; lpm_hint : string := "USE_EAB=ON"); port ( data : in std_logic_vector(lpm_width-1 downto 0); rdclk : in std_logic; wrclk : in std_logic; aclr : in std_logic := '0'; rdreq : in std_logic; wrreq : in std_logic; rdfull : out std_logic; wrfull : out std_logic; rdempty : out std_logic; wrempty : out std_logic; rdusedw : out std_logic_vector(WIDTHU_R-1 downto 0); wrusedw : out std_logic_vector(lpm_widthu-1 downto 0); q : out std_logic_vector(WIDTH_R-1 downto 0)); end component; begin -- COMPONENT ASSIGNMENTS ASYNC: DCFIFO_ASYNC generic map ( lpm_width => lpm_width, lpm_widthu => lpm_widthu, lpm_numwords => lpm_numwords, delay_rdusedw => delay_rdusedw, delay_wrusedw => delay_wrusedw, rdsync_delaypipe => READ_SIDE_SYNCHRONIZERS, wrsync_delaypipe => WRITE_SIDE_SYNCHRONIZERS, intended_device_family => intended_device_family, lpm_showahead => lpm_showahead, underflow_checking => underflow_checking, overflow_checking => overflow_checking, use_eab => use_eab, add_ram_output_register => add_ram_output_register) port map ( data => data, rdclk => rdclk, wrclk => wrclk, aclr => aclr, rdreq => rdreq, wrreq => wrreq, rdfull => i_rdfull_a, wrfull => i_wrfull_a, rdempty => i_rdempty_a, wrempty => i_wrempty_a, rdusedw => i_rdusedw_a, wrusedw => i_wrusedw_a, q => i_q_a); SYNC: DCFIFO_SYNC generic map ( lpm_width => lpm_width, lpm_widthu => lpm_widthu, lpm_numwords => lpm_numwords, intended_device_family => intended_device_family, lpm_showahead => lpm_showahead, underflow_checking => underflow_checking, overflow_checking => overflow_checking, use_eab => use_eab, add_ram_output_register => add_ram_output_register) port map ( data => data, rdclk => rdclk, wrclk => wrclk, aclr => aclr, rdreq => rdreq, wrreq => wrreq, rdfull => i_rdfull_s, wrfull => i_wrfull_s, rdempty => i_rdempty_s, wrempty => i_wrempty_s, rdusedw => i_rdusedw_s, wrusedw => i_wrusedw_s, q => i_q_s); LOWLATENCY_FIFO: if (USE_LOW_LATENCY_FIFO = true) generate LOWLATENCY : DCFIFO_LOW_LATENCY generic map ( lpm_width => lpm_width, lpm_widthu => lpm_widthu, lpm_width_r => WIDTH_R, lpm_widthu_r => WIDTHU_R, lpm_numwords => lpm_numwords, delay_rdusedw => delay_rdusedw, delay_wrusedw => delay_wrusedw, rdsync_delaypipe => LOW_RDSYNC_DELAYPIPE, wrsync_delaypipe => LOW_WRSYNC_DELAYPIPE, intended_device_family => intended_device_family, lpm_showahead => lpm_showahead, underflow_checking => underflow_checking, overflow_checking => overflow_checking, add_usedw_msb_bit => add_usedw_msb_bit, read_aclr_synch => read_aclr_synch, write_aclr_synch => write_aclr_synch, lpm_hint => lpm_hint) port map ( data => data, rdclk => rdclk, wrclk => wrclk, aclr => aclr, rdreq => rdreq, wrreq => wrreq, rdfull => i_rdfull_l, wrfull => i_wrfull_l, rdempty => i_rdempty_l, wrempty => i_wrempty_l, rdusedw => i_rdusedw_l, wrusedw => i_wrusedw_l, q => i_q_l); end generate LOWLATENCY_FIFO; rdfull <= i_rdfull_l when USE_LOW_LATENCY_FIFO = true else i_rdfull_s when clocks_are_synchronized = "TRUE" else i_rdfull_a; wrfull <= i_wrfull_l when USE_LOW_LATENCY_FIFO = true else i_wrfull_s when clocks_are_synchronized = "TRUE" else i_wrfull_a; rdempty <= i_rdempty_l when USE_LOW_LATENCY_FIFO = true else i_rdempty_s when clocks_are_synchronized = "TRUE" else i_rdempty_a; wrempty <= i_wrempty_l when USE_LOW_LATENCY_FIFO = true else i_wrempty_s when clocks_are_synchronized = "TRUE" else i_wrempty_a; rdusedw <= i_rdusedw_l when USE_LOW_LATENCY_FIFO = true else i_rdusedw_s when clocks_are_synchronized = "TRUE" else i_rdusedw_a; wrusedw <= i_wrusedw_l when USE_LOW_LATENCY_FIFO = true else i_wrusedw_s when clocks_are_synchronized = "TRUE" else i_wrusedw_a; q <= i_q_l when USE_LOW_LATENCY_FIFO = true else i_q_s when clocks_are_synchronized = "TRUE" else i_q_a; -- PROCESS DECLARATION INITIAL : process begin if (((wrsync_delaypipe = 0) or (rdsync_delaypipe = 0)) and (clocks_are_synchronized = "FALSE")) then if (FEATURE_FAMILY_HAS_STRATIXII_STYLE_RAM (intended_device_family) or FEATURE_FAMILY_HAS_STRATIXIII_STYLE_RAM (intended_device_family)) then ASSERT FALSE REPORT "Number of metastability protection registers is not specified. Based on the parameter value CLOCKS_ARE_SYNCHRONIZED=FALSE, the synchronization register chain length between read and write clock domains will be 2." SEVERITY WARNING; end if; end if; wait; end process; -- INITIAL process end behavior; -- DCFIFO_MIXED_WIDTHS -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : dcfifo -- -- Description : Dual clocks FIFO -- -- Limitation : -- -- Results Expected: -- ---END_ENTITY_HEADER----------------------------------------------------------- -- BEGINNING OF ENTITY library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use work.DCFIFO_MIXED_WIDTHS; -- ENTITY DECLARATION entity DCFIFO is -- GENERIC DECLARATION generic ( lpm_width : natural; lpm_widthu : natural; lpm_numwords : natural; delay_rdusedw : natural := 1; delay_wrusedw : natural := 1; rdsync_delaypipe : natural := 0; wrsync_delaypipe : natural := 0; intended_device_family : string := "Stratix"; lpm_showahead : string := "OFF"; underflow_checking : string := "ON"; overflow_checking : string := "ON"; clocks_are_synchronized : string := "FALSE"; use_eab : string := "ON"; add_ram_output_register : string := "OFF"; add_width : natural := 1; ram_block_type : string := "AUTO"; add_usedw_msb_bit : string := "OFF"; read_aclr_synch : string := "OFF"; write_aclr_synch : string := "OFF"; lpm_hint : string := "USE_EAB=ON"; lpm_type : string := "dcfifo"); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION data : in std_logic_vector(lpm_width-1 downto 0); rdclk : in std_logic; wrclk : in std_logic; aclr : in std_logic := '0'; rdreq : in std_logic; wrreq : in std_logic; -- OUTPUT PORT DECLARATION rdfull : out std_logic; wrfull : out std_logic; rdempty : out std_logic; wrempty : out std_logic; rdusedw : out std_logic_vector(lpm_widthu-1 downto 0); wrusedw : out std_logic_vector(lpm_widthu-1 downto 0); q : out std_logic_vector(lpm_width-1 downto 0)); end DCFIFO; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of DCFIFO is -- SIGNAL DECLARATION signal i_rdfull : std_logic := '0'; signal i_wrfull : std_logic := '0'; signal i_rdempty : std_logic := '1'; signal i_wrempty : std_logic := '1'; signal i_rdusedw : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_wrusedw : std_logic_vector(lpm_widthu-1 downto 0) := (OTHERS => '0'); signal i_q : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0'); -- COMPONENT DECLARATION component DCFIFO_MIXED_WIDTHS generic ( lpm_width : natural; lpm_widthu : natural; lpm_width_r : natural; lpm_widthu_r : natural; lpm_numwords : natural; delay_rdusedw : natural; delay_wrusedw : natural; rdsync_delaypipe : natural; wrsync_delaypipe : natural; intended_device_family : string; lpm_showahead : string; underflow_checking : string; overflow_checking : string; clocks_are_synchronized : string; use_eab : string; add_ram_output_register : string; add_width : natural; ram_block_type : string; add_usedw_msb_bit : string; read_aclr_synch : string; write_aclr_synch : string; lpm_hint : string ); port ( data : in std_logic_vector(lpm_width-1 downto 0); rdclk : in std_logic; wrclk : in std_logic; aclr : in std_logic := '0'; rdreq : in std_logic; wrreq : in std_logic; rdfull : out std_logic; wrfull : out std_logic; rdempty : out std_logic; wrempty : out std_logic; rdusedw : out std_logic_vector(lpm_widthu-1 downto 0); wrusedw : out std_logic_vector(lpm_widthu-1 downto 0); q : out std_logic_vector(lpm_width-1 downto 0)); end component; begin -- COMPONENT ASSIGNMENTS DCFIFO_MW : DCFIFO_MIXED_WIDTHS generic map ( lpm_width => lpm_width, lpm_widthu => lpm_widthu, lpm_width_r => lpm_width, lpm_widthu_r => lpm_widthu, lpm_numwords => lpm_numwords, delay_rdusedw => delay_rdusedw, delay_wrusedw => delay_wrusedw, rdsync_delaypipe => rdsync_delaypipe, wrsync_delaypipe => wrsync_delaypipe, intended_device_family => intended_device_family, lpm_showahead => lpm_showahead, underflow_checking => underflow_checking, overflow_checking => overflow_checking, clocks_are_synchronized => clocks_are_synchronized, use_eab => use_eab, add_ram_output_register => add_ram_output_register, add_width => add_width, ram_block_type => ram_block_type, add_usedw_msb_bit => add_usedw_msb_bit, read_aclr_synch => read_aclr_synch, write_aclr_synch => write_aclr_synch, lpm_hint => lpm_hint) port map ( data => data, rdclk => rdclk, wrclk => wrclk, aclr => aclr, rdreq => rdreq, wrreq => wrreq, rdfull => i_rdfull, wrfull => i_wrfull, rdempty => i_rdempty, wrempty => i_wrempty, rdusedw => i_rdusedw, wrusedw => i_wrusedw, q => i_q); rdfull <= i_rdfull; wrfull <= i_wrfull; rdempty <= i_rdempty; wrempty <= i_wrempty; rdusedw <= i_rdusedw; wrusedw <= i_wrusedw; q <= i_q; end behavior; -- dcfifo -- END OF ARCHITECTURE -------------------------------------------------------------------------------- -- Module Name : altshift_taps -- -- Description : Parameterized shift register with taps megafunction. -- Implements a RAM-based shift register for efficient -- creation of very large shift registers -- -- Limitation : This megafunction is provided only for backward -- compatibility in Cyclone, Stratix, and Stratix GX -- designs. -- -- Results expected : Produce output from the end of the shift register -- and from the regularly spaced taps along the -- shift register. -- -------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; -- ENTITY DECLARATION entity altshift_taps is generic ( number_of_taps : natural := 4; -- Specifies the number of regularly spaced -- taps along the shift register tap_distance : natural := 3; -- Specifies the distance between the -- regularly spaced taps in clock cycles -- This number translates to the number of -- RAM words that will be used width : natural := 8; power_up_state : string := "CLEARED"; lpm_hint : string := "UNUSED"; lpm_type : string := "altshift_taps"; intended_device_family : string := "Stratix" ); port (-- data input to the shifter shiftin : in std_logic_vector (width-1 downto 0); -- Positive-edge triggered clock clock : in std_logic; -- Clock enable for the clock port clken : in std_logic := '1'; -- Asynchronous clear port aclr : in std_logic := '0'; -- Output from the end of the shift register shiftout : out std_logic_vector (width-1 downto 0); -- Output from the regularly spaced taps along the shift register taps : out std_logic_vector ((width*number_of_taps)-1 downto 0) ); end altshift_taps; -- ARCHITECTURE DECLARATION architecture behavioural of altshift_taps is -- CONSTANT DECLARATION constant TOTAL_TAP_DISTANCE : natural := number_of_taps * tap_distance; -- TYPE DECLARATION type mxn_array is array (TOTAL_TAP_DISTANCE-1 downto 0) of std_logic_vector (width downto 0); -- SIGNAL DECLARATION signal contents : mxn_array; signal head_pipe : natural := 0; signal i : natural := 0; begin -- PROCESS BLOCKS SHIFT: process (clock, aclr) variable head: natural := 0; variable init : boolean := true; begin if init and (power_up_state = "CLEARED") then shiftout <= (others => '0'); taps <= (others => '0'); contents <= (others => (others => '0')); init := false; end if; if (aclr = '1') then shiftout <= (others => '0'); taps <= (others => '0'); contents <= (others => (others => '0')); head := 0; head_pipe <= 0; elsif (rising_edge(clock)) then if (clken = '1') then head := head_pipe; contents (head)(width-1 downto 0) <= shiftin; shiftout <= contents ((head+1) mod TOTAL_TAP_DISTANCE)(width-1 downto 0); head := (head+1) mod TOTAL_TAP_DISTANCE; for i in 0 to (number_of_taps-1) loop taps (((i+1)*width)-1 downto (i*width) ) <= contents ((((number_of_taps - i - 1)*tap_distance) + head) mod TOTAL_TAP_DISTANCE)(width-1 downto 0); end loop; head_pipe <= head; end if; end if; end process shift; end behavioural; -- altshift_taps ---START_ENTITY_HEADER--------------------------------------------------------- -- -- Entity Name : a_graycounter -- -- Description : Gray counter with Count-enable, Up/Down, aclr and sclr -- -- Limitation : Sync sigal priority: clk_en (higher),sclr,cnt_en (lower) -- -- Results Expected: q is graycounter output and qbin is normal counter -- ---END_ENTITY_HEADER----------------------------------------------------------- -- BEGINNING OF ENTITY library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; -- ENTITY DECLARATION entity A_GRAYCOUNTER is -- GENERIC DECLARATION generic ( width : natural; pvalue : natural; lpm_hint : string := "UNUSED"; lpm_type : string := "a_graycounter"); -- PORT DECLARATION port ( -- INPUT PORT DECLARATION clock : in std_logic; clk_en : in std_logic := '1'; cnt_en : in std_logic := '1'; updown : in std_logic := '1'; aclr : in std_logic := '0'; sclr : in std_logic := '0'; -- OUTPUT PORT DECLARATION qbin : out std_logic_vector(width-1 downto 0); q : out std_logic_vector(width-1 downto 0)); end A_GRAYCOUNTER; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE -- ARCHITECTURE DECLARATION architecture behavior of A_GRAYCOUNTER is -- SIGNAL DECLARATION signal cnt : std_logic_vector(width-1 downto 0); signal qbin_tmp : std_logic_vector(width-1 downto 0); begin -- PROCESS DECLARATION -- basic error checking for invalid parameters MSG: process begin if (width <= 0) then ASSERT FALSE REPORT "Value of WIDTH parameter of a_graycounter must be greater than 0!" SEVERITY ERROR; end if; wait; end process MSG; process(aclr, clock) variable init : boolean := true; begin if (init) then -- Initialize to pvalue cnt <= conv_std_logic_vector(pvalue, width); init := false; elsif (aclr'event and (aclr = '1')) then cnt <= conv_std_logic_vector(pvalue, width); elsif (clock'event and (clock = '1')) then if ((aclr = '0') and (clk_en = '1')) then if (sclr = '1') then cnt <= conv_std_logic_vector(pvalue, width); elsif (cnt_en = '1') then if (updown = '1') then cnt <= cnt + 1; else cnt <= cnt - 1; end if; end if; end if; end if; end process; qbin_tmp <= cnt; process(qbin_tmp) variable qbin_rshift : std_logic_vector(width-1 downto 0); begin if (width > 1) then qbin_rshift(width-2 downto 0) := qbin_tmp(width-1 downto 1); end if; qbin_rshift(width-1) := '0'; q <= qbin_tmp xor qbin_rshift; end process; qbin <= cnt; end behavior; -- a_graycounter -- END OF ARCHITECTURE ---START_ENTITY_HEADER--------------------------------------------------------- -- -- entity Name : altsquare -- -- Description : Parameterized integer square megafunction. -- The input data can be signed or unsigned, and the output -- can be pipelined. -- -- Limitations : Minimum data width is 1. -- -- Results expected: result - The square of input data. -- ---END_ENTITY_HEADER----------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; -- BEGINNING OF ENTITY -- ENTITY DECLARATION entity altsquare is -- GENERIC DECLARATION generic ( data_width : natural; result_width : natural; pipeline : natural := 0; representation : string := "UNSIGNED"; result_alignment : string := "LSB"; lpm_hint : string := "UNUSED"; lpm_type : string := "altsquare" ); -- PORT DECLARATION port ( data : in std_logic_vector (data_width - 1 downto 0); clock : in std_logic := '0'; ena : in std_logic := '1'; aclr : in std_logic := '0'; result : out std_logic_vector (result_width - 1 downto 0) ); end altsquare; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE architecture altsquare_syn of altsquare is -- TYPE DECLARATION -- for storing the pipeline values type T_PIPE_ARRAY is array (0 to pipeline) of std_logic_vector(2 * data_width - 1 downto 0); -- SIGNAL DECLARATION signal stage_value : T_PIPE_ARRAY; signal next_value : std_logic_vector(2 * data_width - 1 downto 0); begin -- error checking assert data_width > 0 report "Value of data_width parameter must be greater than 0" severity error; assert result_width > 0 report "Value of result_width parameter must be greater than 0" severity error; assert representation = "UNSIGNED" or representation = "SIGNED" report "Value of representation parameter must be signed or unsigned" severity error; -- PROCESS DECLARATION process(clock, aclr, data) variable stage_value : T_PIPE_ARRAY; begin if aclr = '1' and pipeline > 0 then stage_value := (others => (others => '0')); elsif (clock = '1' and clock'event) or pipeline = 0 then if (ena = '1') or (pipeline = 0) then if representation = "SIGNED" then stage_value(0) := signed(data) * signed(data); else stage_value(0) := unsigned(data) * unsigned(data); end if; if pipeline > 0 then for i in pipeline downto 1 loop stage_value(i) := stage_value(i - 1); end loop; end if; end if; end if; next_value <= stage_value(pipeline); end process; -- now set the result data_shrink_LSB : if (result_width <= 2 * data_width) and (result_alignment = "LSB") generate result(result_width - 1 downto 0) <= next_value(result_width - 1 downto 0); end generate; data_shrink_MSB : if (result_width <= 2 * data_width) and (result_alignment = "MSB") generate result(result_width - 1 downto 0) <= next_value((2*data_width)-1 downto (2*data_width)-result_width); end generate; data_expand : if result_width > 2 * data_width generate result(result_width - 1 downto 2* data_width) <= (others => '0'); result((2 * data_width) - 1 downto 0) <= next_value; end generate; end altsquare_syn; -- altsquare -- END OF ARCHITECTURE -- START_FILE_HEADER ---------------------------------------------------------- -- -- Filename : altera_std_synchronizer.vhd -- -- Description : Contains the simulation model for the altera_std_synchronizer -- -- Owner : Paul Scheidt -- -- Copyright (C) Altera Corporation 2008, All Rights Reserved -- -- END_FILE_HEADER ------------------------------------------------------------ -- -- START_ENTITY_HEADER -------------------------------------------------------- -- -- Entity Name : altera_std_synchronizer -- -- Description : Single bit clock domain crossing synchronizer. -- Composed of two flip flops connected in series. -- -- Limitations : -- -- END_FILE_HEADER ------------------------------------------------------------ -- library ieee ; use ieee.std_logic_1164.all; use work.all; -- BEGINNING OF ENTITY entity altera_std_synchronizer is -- GENERIC DECLARATION generic (depth : integer := 3); -- must be >= 2 -- PORT DECLARATION port ( clk : in std_logic; reset_n : in std_logic; din : in std_logic; dout : out std_logic ); end altera_std_synchronizer; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE architecture behavioral of altera_std_synchronizer is -- SIGNAL DECLARATION signal din_s1 : std_logic; signal dreg : std_logic_vector(depth-2 downto 0); begin process (din, clk) begin if (clk'event and clk='1') then if reset_n='0' then din_s1 <= '0'; else din_s1 <= din; end if; end if; end process; g1: if depth = 1 generate -- normally this is an illegal condition dout <= din_s1; end generate g1; g2: if depth = 2 generate process (din, clk) begin if (clk'event and clk='1') then if reset_n='0' then dout <= '0'; else dout <= din_s1; end if; end if; end process; end generate g2; g3: if depth >= 3 generate process (din, clk) begin if (clk'event and clk='1') then if reset_n='0' then dreg <= (others => '0'); else dreg <= dreg(depth-3 downto 0) & din_s1; end if; end if; end process; dout <= dreg(depth-2); end generate g3; end behavioral; -- END OF ARCHITECTURE -- START_FILE_HEADER ---------------------------------------------------------- -- -- Filename : altera_std_synchronizer_bundle.vhd -- -- Description : Contains the simulation model for the altera_std_synchronizer_bundle -- -- Owner : Paul Scheidt -- -- Copyright (C) Altera Corporation 2008, All Rights Reserved -- -- END_FILE_HEADER ------------------------------------------------------------ -- -- START_ENTITY_HEADER -------------------------------------------------------- -- -- Entity Name : altera_std_synchronizer_bundle -- -- Description : Bundle of bit synchronizers. -- WARNING: only use this to synchronize a bundle of -- *independent* single bit signals or a Gray encoded -- bus of signals. Also remember that pulses entering -- the synchronizer will be swallowed upon a metastable -- condition if the pulse width is shorter than twice -- the synchronizing clock period. -- -- Limitations : -- -- END_FILE_HEADER ------------------------------------------------------------- -- library ieee ; use ieee.std_logic_1164.all; use work.all; -- BEGINNNG OF ENTITY entity altera_std_synchronizer_bundle is -- GENERIC DECLARATION generic ( depth : integer := 3; -- must be >= 2 width : integer := 1); -- PORT DECLARATION port ( clk : in std_logic; reset_n : in std_logic; din : in std_logic_vector(width-1 downto 0); dout : out std_logic_vector(width-1 downto 0) ); end altera_std_synchronizer_bundle; -- END OF ENTITY -- BEGINNING OF ARCHITECTURE architecture behavioral of altera_std_synchronizer_bundle is -- COMPONENT DECLARATION component altera_std_synchronizer generic (depth : integer := 3); port ( clk : in std_logic; reset_n : in std_logic; din : in std_logic; dout : out std_logic ); end component; begin g1: for i in 0 to width-1 generate s: altera_std_synchronizer generic map (depth => depth) port map ( clk => clk, reset_n => reset_n, din => din(i), dout => dout(i) ); end generate g1; end behavioral; -- END OF ARCHITECTURE LIBRARY ieee; USE ieee.std_logic_unsigned.all; --synthesis_resources = lut 4 reg 5 LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY alt_cal IS generic ( number_of_channels : integer := 1; channel_address_width : integer := 1; sim_model_mode : string := "TRUE"; lpm_hint : string := "UNUSED"; lpm_type : string := "alt_cal" ); PORT ( busy : OUT STD_LOGIC; cal_error : OUT STD_LOGIC_VECTOR (number_of_channels - 1 DOWNTO 0); clock : IN STD_LOGIC; dprio_addr : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_busy : IN STD_LOGIC; dprio_datain : IN STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_dataout : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_rden : OUT STD_LOGIC; dprio_wren : OUT STD_LOGIC; quad_addr : OUT STD_LOGIC_VECTOR (8 DOWNTO 0); remap_addr : IN STD_LOGIC_VECTOR (11 DOWNTO 0) := (OTHERS => '0'); reset : IN STD_LOGIC := '0'; retain_addr : OUT STD_LOGIC; start : IN STD_LOGIC := '0'; transceiver_init : IN STD_LOGIC := '0'; testbuses : IN STD_LOGIC_VECTOR (4 * number_of_channels - 1 DOWNTO 0) := (OTHERS => '0') ); END alt_cal; ARCHITECTURE RTL OF alt_cal IS ATTRIBUTE synthesis_clearbox : natural; ATTRIBUTE synthesis_clearbox OF RTL : ARCHITECTURE IS 1; ATTRIBUTE ALTERA_ATTRIBUTE : string; ATTRIBUTE ALTERA_ATTRIBUTE OF RTL : ARCHITECTURE IS "PRESERVE_REGISTER=ON"; SIGNAL p0addr_sim : STD_LOGIC_VECTOR(0 DOWNTO 0) -- synopsys translate_off := (OTHERS => '0') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF p0addr_sim : SIGNAL IS "PRESERVE_REGISTER=ON;POWER_UP_LEVEL=LOW"; SIGNAL wire_p0addr_sim_w_lg_w_lg_q4w5w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_p0addr_sim_w_lg_q4w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_reg : STD_LOGIC_VECTOR(3 DOWNTO 0) -- synopsys translate_off := (OTHERS => '0') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF sim_counter_reg : SIGNAL IS "POWER_UP_LEVEL=LOW"; SIGNAL first_run : STD_LOGIC_VECTOR(0 DOWNTO 0) -- synopsys translate_off := (OTHERS => '1') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF first_run : SIGNAL IS "POWER_UP_LEVEL=HIGH"; SIGNAL wire_next_scount_num_dataa : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_next_scount_num_datab : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_next_scount_num_result : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_w_lg_w_lg_w_lg_reset7w8w9w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_w_lg_w_lg_reset7w8w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_w_lg_sim_counter_and2w3w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_sim_counter_and1w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_w_lg_reset7w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_sim_counter_and2w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL busy_sim : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_activator : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_and : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_next : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL sim_counter_or : STD_LOGIC_VECTOR (0 DOWNTO 0); BEGIN loop0 : FOR i IN 0 TO 3 GENERATE wire_w_lg_w_lg_w_lg_reset7w8w9w(i) <= (wire_w_lg_w_lg_reset7w8w(0) AND wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w(i) AND NOT(reset AND first_run(0))) OR (reset AND NOT first_run(0)); END GENERATE loop0; -- wire_w_lg_w_lg_reset7w8w(0) <= wire_w_lg_reset7w(0) AND sim_activator(0); wire_w_lg_w_lg_reset7w8w(0) <= (NOT transceiver_init AND NOT start) AND sim_activator(0); wire_w_lg_w_lg_sim_counter_and2w3w(0) <= wire_w_lg_sim_counter_and2w(0) AND sim_counter_or(0); loop1 : FOR i IN 0 TO 3 GENERATE wire_w_lg_sim_counter_and1w(i) <= sim_counter_and(0) AND sim_counter_reg(i); END GENERATE loop1; wire_w_lg_reset7w(0) <= NOT reset; wire_w_lg_sim_counter_and2w(0) <= NOT sim_counter_and(0); busy <= busy_sim(0); busy_sim(0) <= (wire_w_lg_reset7w(0) AND p0addr_sim(0) AND wire_w_lg_sim_counter_and2w(0)); cal_error <= (OTHERS => '0'); dprio_addr <= (OTHERS => '0'); dprio_dataout <= (OTHERS => '0'); dprio_rden <= '0'; dprio_wren <= '0'; quad_addr <= (OTHERS => '0'); retain_addr <= '0'; sim_activator <= p0addr_sim; sim_counter_and(0) <= (((sim_counter_reg(0) AND sim_counter_reg(1)) AND sim_counter_reg(2)) AND sim_counter_reg(3)); sim_counter_next <= wire_next_scount_num_result; sim_counter_or(0) <= (((sim_counter_reg(0) OR sim_counter_reg(1)) OR sim_counter_reg(2)) OR sim_counter_reg(3)); PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN p0addr_sim <= "1"; END IF; END PROCESS; loop2 : FOR i IN 0 TO 3 GENERATE wire_p0addr_sim_w_lg_w_lg_q4w5w(i) <= wire_p0addr_sim_w_lg_q4w(0) AND sim_counter_next(i); END GENERATE loop2; loop3 : FOR i IN 0 TO 3 GENERATE wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w(i) <= wire_p0addr_sim_w_lg_w_lg_q4w5w(i) OR wire_w_lg_sim_counter_and1w(i); END GENERATE loop3; wire_p0addr_sim_w_lg_q4w(0) <= p0addr_sim(0) OR wire_w_lg_w_lg_sim_counter_and2w3w(0); PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN sim_counter_reg <= wire_w_lg_w_lg_w_lg_reset7w8w9w; END IF; END PROCESS; PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN IF (first_run(0) = '1') THEN first_run(0) <= (NOT sim_counter_and(0)); ELSE first_run(0) <= '0'; END IF; END IF; END PROCESS; wire_next_scount_num_result <= wire_next_scount_num_dataa + wire_next_scount_num_datab; wire_next_scount_num_dataa <= sim_counter_reg; wire_next_scount_num_datab <= "0001"; END RTL; --alt_cal --VALID FILE LIBRARY ieee; USE ieee.std_logic_unsigned.all; --synthesis_resources = lut 4 reg 5 LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY alt_cal_mm IS generic ( number_of_channels : integer := 1; channel_address_width : integer := 1; sim_model_mode : string := "TRUE"; CAL_PD_WR : string := "00101"; CAL_RX_RD : string := "00110"; CAL_RX_WR : string := "00111"; CH_ADV : string := "01100"; CH_WAIT : string := "00001"; DPRIO_READ : string := "01110"; DPRIO_WAIT : string := "01000"; DPRIO_WRITE : string := "01111"; IDLE : string := "00000"; KICK_DELAY_OC : integer := 10010; KICK_PAUSE : integer := 10001; KICK_START_RD : string := "01101"; KICK_START_WR : integer := 10000; OFFSETS_PDEN_RD : string := "00011"; OFFSETS_PDEN_WR : string := "00100"; sample_length : string := "01100100"; SAMPLE_TB : string := "01001"; TEST_INPUT : string := "01010"; TESTBUS_SET : string := "00010"; lpm_hint : string := "UNUSED"; lpm_type : string := "alt_cal_mm" ); PORT ( busy : OUT STD_LOGIC; cal_error : OUT STD_LOGIC_VECTOR (number_of_channels - 1 DOWNTO 0); clock : IN STD_LOGIC; dprio_addr : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_busy : IN STD_LOGIC; dprio_datain : IN STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_dataout : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_rden : OUT STD_LOGIC; dprio_wren : OUT STD_LOGIC; quad_addr : OUT STD_LOGIC_VECTOR (8 DOWNTO 0); remap_addr : IN STD_LOGIC_VECTOR (11 DOWNTO 0) := (OTHERS => '0'); reset : IN STD_LOGIC := '0'; retain_addr : OUT STD_LOGIC; start : IN STD_LOGIC := '0'; transceiver_init : IN STD_LOGIC := '0'; testbuses : IN STD_LOGIC_VECTOR (4 * number_of_channels - 1 DOWNTO 0) := (OTHERS => '0') ); END alt_cal_mm; ARCHITECTURE RTL OF alt_cal_mm IS ATTRIBUTE synthesis_clearbox : natural; ATTRIBUTE synthesis_clearbox OF RTL : ARCHITECTURE IS 1; ATTRIBUTE ALTERA_ATTRIBUTE : string; ATTRIBUTE ALTERA_ATTRIBUTE OF RTL : ARCHITECTURE IS "PRESERVE_REGISTER=ON"; SIGNAL p0addr_sim : STD_LOGIC_VECTOR(0 DOWNTO 0) -- synopsys translate_off := (OTHERS => '0') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF p0addr_sim : SIGNAL IS "PRESERVE_REGISTER=ON;POWER_UP_LEVEL=LOW"; SIGNAL wire_p0addr_sim_w_lg_w_lg_q4w5w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_p0addr_sim_w_lg_q4w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_reg : STD_LOGIC_VECTOR(3 DOWNTO 0) -- synopsys translate_off := (OTHERS => '0') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF sim_counter_reg : SIGNAL IS "POWER_UP_LEVEL=LOW"; SIGNAL first_run : STD_LOGIC_VECTOR(0 DOWNTO 0) -- synopsys translate_off := (OTHERS => '1') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF first_run : SIGNAL IS "POWER_UP_LEVEL=HIGH"; SIGNAL wire_next_scount_num_dataa : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_next_scount_num_datab : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_next_scount_num_result : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_w_lg_w_lg_w_lg_reset7w8w9w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_w_lg_w_lg_reset7w8w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_w_lg_sim_counter_and2w3w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_sim_counter_and1w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_w_lg_reset7w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_sim_counter_and2w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL busy_sim : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_activator : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_and : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_next : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL sim_counter_or : STD_LOGIC_VECTOR (0 DOWNTO 0); BEGIN loop0 : FOR i IN 0 TO 3 GENERATE wire_w_lg_w_lg_w_lg_reset7w8w9w(i) <= ((NOT start AND NOT transceiver_init) AND wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w(i) AND NOT (reset AND first_run(0))) OR (reset AND NOT first_run(0)); END GENERATE loop0; wire_w_lg_w_lg_reset7w8w(0) <= wire_w_lg_reset7w(0) AND sim_activator(0); wire_w_lg_w_lg_sim_counter_and2w3w(0) <= wire_w_lg_sim_counter_and2w(0) AND sim_counter_or(0); loop1 : FOR i IN 0 TO 3 GENERATE wire_w_lg_sim_counter_and1w(i) <= sim_counter_and(0) AND sim_counter_reg(i); END GENERATE loop1; wire_w_lg_reset7w(0) <= NOT reset; wire_w_lg_sim_counter_and2w(0) <= NOT sim_counter_and(0); busy <= busy_sim(0); busy_sim(0) <= wire_w_lg_reset7w(0) AND (p0addr_sim(0) AND wire_w_lg_sim_counter_and2w(0)); cal_error <= (OTHERS => '0'); dprio_addr <= (OTHERS => '0'); dprio_dataout <= (OTHERS => '0'); dprio_rden <= '0'; dprio_wren <= '0'; quad_addr <= (OTHERS => '0'); retain_addr <= '0'; sim_activator <= p0addr_sim; sim_counter_and(0) <= (((sim_counter_reg(0) AND sim_counter_reg(1)) AND sim_counter_reg(2)) AND sim_counter_reg(3)); sim_counter_next <= wire_next_scount_num_result; sim_counter_or(0) <= (((sim_counter_reg(0) OR sim_counter_reg(1)) OR sim_counter_reg(2)) OR sim_counter_reg(3)); PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN p0addr_sim <= "1"; END IF; END PROCESS; loop2 : FOR i IN 0 TO 3 GENERATE wire_p0addr_sim_w_lg_w_lg_q4w5w(i) <= wire_p0addr_sim_w_lg_q4w(0) AND sim_counter_next(i); END GENERATE loop2; loop3 : FOR i IN 0 TO 3 GENERATE wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w(i) <= wire_p0addr_sim_w_lg_w_lg_q4w5w(i) OR wire_w_lg_sim_counter_and1w(i); END GENERATE loop3; wire_p0addr_sim_w_lg_q4w(0) <= p0addr_sim(0) OR wire_w_lg_w_lg_sim_counter_and2w3w(0); PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN sim_counter_reg <= wire_w_lg_w_lg_w_lg_reset7w8w9w; END IF; END PROCESS; PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN IF (first_run(0) = '1') THEN first_run(0) <= (NOT sim_counter_and(0)); ELSE first_run(0) <= '0'; END IF; END IF; END PROCESS; wire_next_scount_num_result <= wire_next_scount_num_dataa + wire_next_scount_num_datab; wire_next_scount_num_dataa <= sim_counter_reg; wire_next_scount_num_datab <= "0001"; END RTL; --alt_cal_mm --VALID FILE LIBRARY ieee; USE ieee.std_logic_unsigned.all; --synthesis_resources = lut 4 reg 5 LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY alt_cal_c3gxb IS generic ( number_of_channels : integer := 1; channel_address_width : integer := 1; sim_model_mode : string := "TRUE"; lpm_hint : string := "UNUSED"; lpm_type : string := "alt_cal_c3gxb" ); PORT ( busy : OUT STD_LOGIC; cal_error : OUT STD_LOGIC_VECTOR (number_of_channels - 1 DOWNTO 0); clock : IN STD_LOGIC; dprio_addr : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_busy : IN STD_LOGIC; dprio_datain : IN STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_dataout : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_rden : OUT STD_LOGIC; dprio_wren : OUT STD_LOGIC; quad_addr : OUT STD_LOGIC_VECTOR (8 DOWNTO 0); remap_addr : IN STD_LOGIC_VECTOR (11 DOWNTO 0) := (OTHERS => '0'); reset : IN STD_LOGIC := '0'; retain_addr : OUT STD_LOGIC; start : IN STD_LOGIC := '0'; testbuses : IN STD_LOGIC_VECTOR (number_of_channels - 1 DOWNTO 0) := (OTHERS => '0') ); END alt_cal_c3gxb; ARCHITECTURE RTL OF alt_cal_c3gxb IS ATTRIBUTE synthesis_clearbox : natural; ATTRIBUTE synthesis_clearbox OF RTL : ARCHITECTURE IS 1; ATTRIBUTE ALTERA_ATTRIBUTE : string; ATTRIBUTE ALTERA_ATTRIBUTE OF RTL : ARCHITECTURE IS "PRESERVE_REGISTER=ON"; SIGNAL p0addr_sim : STD_LOGIC_VECTOR(0 DOWNTO 0) -- synopsys translate_off := (OTHERS => '0') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF p0addr_sim : SIGNAL IS "PRESERVE_REGISTER=ON;POWER_UP_LEVEL=LOW"; SIGNAL wire_p0addr_sim_w_lg_w_lg_q4w5w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_p0addr_sim_w_lg_q4w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_reg : STD_LOGIC_VECTOR(3 DOWNTO 0) -- synopsys translate_off := (OTHERS => '0') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF sim_counter_reg : SIGNAL IS "POWER_UP_LEVEL=LOW"; SIGNAL first_run : STD_LOGIC_VECTOR(0 DOWNTO 0) -- synopsys translate_off := (OTHERS => '1') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF first_run : SIGNAL IS "POWER_UP_LEVEL=HIGH"; SIGNAL wire_next_scount_num_dataa : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_next_scount_num_datab : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_next_scount_num_result : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_w_lg_w_lg_w_lg_reset7w8w9w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_w_lg_w_lg_reset7w8w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_w_lg_sim_counter_and2w3w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_sim_counter_and1w : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL wire_w_lg_reset7w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_sim_counter_and2w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL busy_sim : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_activator : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_and : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_next : STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL sim_counter_or : STD_LOGIC_VECTOR (0 DOWNTO 0); BEGIN loop0 : FOR i IN 0 TO 3 GENERATE wire_w_lg_w_lg_w_lg_reset7w8w9w(i) <= (wire_w_lg_w_lg_reset7w8w(0) AND wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w(i) AND NOT (reset AND first_run(0))) OR (reset AND NOT first_run(0)); END GENERATE loop0; wire_w_lg_w_lg_reset7w8w(0) <= (NOT start) AND sim_activator(0); wire_w_lg_w_lg_sim_counter_and2w3w(0) <= wire_w_lg_sim_counter_and2w(0) AND sim_counter_or(0); loop1 : FOR i IN 0 TO 3 GENERATE wire_w_lg_sim_counter_and1w(i) <= sim_counter_and(0) AND sim_counter_reg(i); END GENERATE loop1; wire_w_lg_reset7w(0) <= NOT reset; wire_w_lg_sim_counter_and2w(0) <= NOT sim_counter_and(0); busy <= busy_sim(0); busy_sim(0) <= (wire_w_lg_reset7w(0) AND p0addr_sim(0) AND wire_w_lg_sim_counter_and2w(0)); cal_error <= (OTHERS => '0'); dprio_addr <= (OTHERS => '0'); dprio_dataout <= (OTHERS => '0'); dprio_rden <= '0'; dprio_wren <= '0'; quad_addr <= (OTHERS => '0'); retain_addr <= '0'; sim_activator <= p0addr_sim; sim_counter_and(0) <= (((sim_counter_reg(0) AND sim_counter_reg(1)) AND sim_counter_reg(2)) AND sim_counter_reg(3)); sim_counter_next <= wire_next_scount_num_result; sim_counter_or(0) <= (((sim_counter_reg(0) OR sim_counter_reg(1)) OR sim_counter_reg(2)) OR sim_counter_reg(3)); PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN p0addr_sim <= "1"; END IF; END PROCESS; loop2 : FOR i IN 0 TO 3 GENERATE wire_p0addr_sim_w_lg_w_lg_q4w5w(i) <= wire_p0addr_sim_w_lg_q4w(0) AND sim_counter_next(i); END GENERATE loop2; loop3 : FOR i IN 0 TO 3 GENERATE wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w(i) <= wire_p0addr_sim_w_lg_w_lg_q4w5w(i) OR wire_w_lg_sim_counter_and1w(i); END GENERATE loop3; wire_p0addr_sim_w_lg_q4w(0) <= p0addr_sim(0) OR wire_w_lg_w_lg_sim_counter_and2w3w(0); PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN sim_counter_reg <= wire_w_lg_w_lg_w_lg_reset7w8w9w; END IF; END PROCESS; PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN IF (first_run(0) = '1') THEN first_run(0) <= (NOT sim_counter_and(0)); ELSE first_run(0) <= '0'; END IF; END IF; END PROCESS; wire_next_scount_num_result <= wire_next_scount_num_dataa + wire_next_scount_num_datab; wire_next_scount_num_dataa <= sim_counter_reg; wire_next_scount_num_datab <= "0001"; END RTL; --VALID FILE LIBRARY ieee; USE ieee.std_logic_unsigned.all; --synthesis_resources = lut 4 reg 5 LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY alt_cal_sv IS generic ( number_of_channels : integer := 1; channel_address_width : integer := 1; sim_model_mode : string := "TRUE"; lpm_hint : string := "UNUSED"; lpm_type : string := "alt_cal_sv"; sample_length : integer := 100; pma_base_address : integer := 0 ); PORT ( busy : OUT STD_LOGIC; clock : IN STD_LOGIC; dprio_addr : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_busy : IN STD_LOGIC; dprio_datain : IN STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_dataout : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_rden : OUT STD_LOGIC; dprio_wren : OUT STD_LOGIC; quad_addr : OUT STD_LOGIC_VECTOR (8 DOWNTO 0); remap_addr : IN STD_LOGIC_VECTOR (11 DOWNTO 0) := (OTHERS => '0'); reset : IN STD_LOGIC := '0'; start : IN STD_LOGIC := '0'; testbuses : IN STD_LOGIC_VECTOR (7 DOWNTO 0) := (OTHERS => '0') ); END alt_cal_sv; ARCHITECTURE RTL OF alt_cal_sv IS ATTRIBUTE synthesis_clearbox : natural; ATTRIBUTE synthesis_clearbox OF RTL : ARCHITECTURE IS 1; ATTRIBUTE ALTERA_ATTRIBUTE : string; ATTRIBUTE ALTERA_ATTRIBUTE OF RTL : ARCHITECTURE IS "PRESERVE_REGISTER=ON"; SIGNAL p0addr_sim : STD_LOGIC_VECTOR(0 DOWNTO 0) -- synopsys translate_off := (OTHERS => '0') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF p0addr_sim : SIGNAL IS "PRESERVE_REGISTER=ON;POWER_UP_LEVEL=LOW"; SIGNAL wire_p0addr_sim_w_lg_w_lg_q4w5w : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_p0addr_sim_w_lg_q4w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_reg : STD_LOGIC_VECTOR(8 DOWNTO 0) -- synopsys translate_off := (OTHERS => '0') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF sim_counter_reg : SIGNAL IS "POWER_UP_LEVEL=LOW"; SIGNAL first_run : STD_LOGIC_VECTOR(0 DOWNTO 0) -- synopsys translate_off := (OTHERS => '1') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF first_run : SIGNAL IS "POWER_UP_LEVEL=HIGH"; SIGNAL wire_next_scount_num_dataa : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_next_scount_num_datab : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_next_scount_num_result : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_w_lg_w_lg_w_lg_reset7w8w9w : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_w_lg_w_lg_reset7w8w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_w_lg_sim_counter_and2w3w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_sim_counter_and1w : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_w_lg_reset7w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_sim_counter_and2w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL busy_sim : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_activator : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_and : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_next : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL sim_counter_or : STD_LOGIC_VECTOR (0 DOWNTO 0); BEGIN loop0 : FOR i IN 0 TO 8 GENERATE wire_w_lg_w_lg_w_lg_reset7w8w9w(i) <= (wire_w_lg_w_lg_reset7w8w(0) AND wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w(i) AND NOT (reset AND first_run(0))) OR (reset AND NOT first_run(0)); END GENERATE loop0; wire_w_lg_w_lg_reset7w8w(0) <= (NOT start) AND sim_activator(0); wire_w_lg_w_lg_sim_counter_and2w3w(0) <= wire_w_lg_sim_counter_and2w(0) AND sim_counter_or(0); loop1 : FOR i IN 0 TO 8 GENERATE wire_w_lg_sim_counter_and1w(i) <= sim_counter_and(0) AND sim_counter_reg(i); END GENERATE loop1; wire_w_lg_reset7w(0) <= NOT reset; wire_w_lg_sim_counter_and2w(0) <= NOT sim_counter_and(0); busy <= busy_sim(0); busy_sim(0) <= (wire_w_lg_reset7w(0) AND p0addr_sim(0) AND wire_w_lg_sim_counter_and2w(0)); dprio_addr <= (OTHERS => '0'); dprio_dataout <= (OTHERS => '0'); dprio_rden <= '0'; dprio_wren <= '0'; quad_addr <= (OTHERS => '0'); sim_activator <= p0addr_sim; sim_counter_and(0) <= (sim_counter_reg(0) AND sim_counter_reg(1) AND sim_counter_reg(2) AND sim_counter_reg(3) AND sim_counter_reg(4) AND sim_counter_reg(5) AND sim_counter_reg(6) AND sim_counter_reg(7) AND sim_counter_reg(8)); sim_counter_next <= wire_next_scount_num_result; sim_counter_or(0) <= (sim_counter_reg(0) OR sim_counter_reg(1) OR sim_counter_reg(2) OR sim_counter_reg(3) OR sim_counter_reg(4) OR sim_counter_reg(5) OR sim_counter_reg(6) OR sim_counter_reg(7) OR sim_counter_reg(8)); PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN p0addr_sim <= "1"; END IF; END PROCESS; loop2 : FOR i IN 0 TO 8 GENERATE wire_p0addr_sim_w_lg_w_lg_q4w5w(i) <= wire_p0addr_sim_w_lg_q4w(0) AND sim_counter_next(i); END GENERATE loop2; loop3 : FOR i IN 0 TO 8 GENERATE wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w(i) <= wire_p0addr_sim_w_lg_w_lg_q4w5w(i) OR wire_w_lg_sim_counter_and1w(i); END GENERATE loop3; wire_p0addr_sim_w_lg_q4w(0) <= p0addr_sim(0) OR wire_w_lg_w_lg_sim_counter_and2w3w(0); PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN sim_counter_reg <= wire_w_lg_w_lg_w_lg_reset7w8w9w; END IF; END PROCESS; PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN IF (first_run(0) = '1') THEN first_run(0) <= (NOT sim_counter_and(0)); ELSE first_run(0) <= '0'; END IF; END IF; END PROCESS; wire_next_scount_num_result <= wire_next_scount_num_dataa + wire_next_scount_num_datab; wire_next_scount_num_dataa <= sim_counter_reg; wire_next_scount_num_datab <= "000000001"; END RTL; --VALID FILE LIBRARY ieee; USE ieee.std_logic_unsigned.all; --synthesis_resources = lut 4 reg 5 LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY alt_cal_av IS generic ( number_of_channels : integer := 1; channel_address_width : integer := 1; sim_model_mode : string := "TRUE"; lpm_hint : string := "UNUSED"; lpm_type : string := "alt_cal_av"; sample_length : integer := 100; pma_base_address : integer := 0 ); PORT ( busy : OUT STD_LOGIC; clock : IN STD_LOGIC; dprio_addr : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_busy : IN STD_LOGIC; dprio_datain : IN STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_dataout : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); dprio_rden : OUT STD_LOGIC; dprio_wren : OUT STD_LOGIC; quad_addr : OUT STD_LOGIC_VECTOR (8 DOWNTO 0); remap_addr : IN STD_LOGIC_VECTOR (11 DOWNTO 0) := (OTHERS => '0'); reset : IN STD_LOGIC := '0'; start : IN STD_LOGIC := '0'; testbuses : IN STD_LOGIC_VECTOR (7 DOWNTO 0) := (OTHERS => '0') ); END alt_cal_av; ARCHITECTURE RTL OF alt_cal_av IS ATTRIBUTE synthesis_clearbox : natural; ATTRIBUTE synthesis_clearbox OF RTL : ARCHITECTURE IS 1; ATTRIBUTE ALTERA_ATTRIBUTE : string; ATTRIBUTE ALTERA_ATTRIBUTE OF RTL : ARCHITECTURE IS "PRESERVE_REGISTER=ON"; SIGNAL p0addr_sim : STD_LOGIC_VECTOR(0 DOWNTO 0) -- synopsys translate_off := (OTHERS => '0') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF p0addr_sim : SIGNAL IS "PRESERVE_REGISTER=ON;POWER_UP_LEVEL=LOW"; SIGNAL wire_p0addr_sim_w_lg_w_lg_q4w5w : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_p0addr_sim_w_lg_q4w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_reg : STD_LOGIC_VECTOR(8 DOWNTO 0) -- synopsys translate_off := (OTHERS => '0') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF sim_counter_reg : SIGNAL IS "POWER_UP_LEVEL=LOW"; SIGNAL first_run : STD_LOGIC_VECTOR(0 DOWNTO 0) -- synopsys translate_off := (OTHERS => '1') -- synopsys translate_on ; ATTRIBUTE ALTERA_ATTRIBUTE OF first_run : SIGNAL IS "POWER_UP_LEVEL=HIGH"; SIGNAL wire_next_scount_num_dataa : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_next_scount_num_datab : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_next_scount_num_result : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_w_lg_w_lg_w_lg_reset7w8w9w : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_w_lg_w_lg_reset7w8w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_w_lg_sim_counter_and2w3w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_sim_counter_and1w : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL wire_w_lg_reset7w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL wire_w_lg_sim_counter_and2w : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL busy_sim : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_activator : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_and : STD_LOGIC_VECTOR (0 DOWNTO 0); SIGNAL sim_counter_next : STD_LOGIC_VECTOR (8 DOWNTO 0); SIGNAL sim_counter_or : STD_LOGIC_VECTOR (0 DOWNTO 0); BEGIN loop0 : FOR i IN 0 TO 8 GENERATE wire_w_lg_w_lg_w_lg_reset7w8w9w(i) <= (wire_w_lg_w_lg_reset7w8w(0) AND wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w(i) AND NOT (reset AND first_run(0))) OR (reset AND NOT first_run(0)); END GENERATE loop0; wire_w_lg_w_lg_reset7w8w(0) <= (NOT start) AND sim_activator(0); wire_w_lg_w_lg_sim_counter_and2w3w(0) <= wire_w_lg_sim_counter_and2w(0) AND sim_counter_or(0); loop1 : FOR i IN 0 TO 8 GENERATE wire_w_lg_sim_counter_and1w(i) <= sim_counter_and(0) AND sim_counter_reg(i); END GENERATE loop1; wire_w_lg_reset7w(0) <= NOT reset; wire_w_lg_sim_counter_and2w(0) <= NOT sim_counter_and(0); busy <= busy_sim(0); busy_sim(0) <= (wire_w_lg_reset7w(0) AND p0addr_sim(0) AND wire_w_lg_sim_counter_and2w(0)); dprio_addr <= (OTHERS => '0'); dprio_dataout <= (OTHERS => '0'); dprio_rden <= '0'; dprio_wren <= '0'; quad_addr <= (OTHERS => '0'); sim_activator <= p0addr_sim; sim_counter_and(0) <= (sim_counter_reg(0) AND sim_counter_reg(1) AND sim_counter_reg(2) AND sim_counter_reg(3) AND sim_counter_reg(4) AND sim_counter_reg(5) AND sim_counter_reg(6) AND sim_counter_reg(7) AND sim_counter_reg(8)); sim_counter_next <= wire_next_scount_num_result; sim_counter_or(0) <= (sim_counter_reg(0) OR sim_counter_reg(1) OR sim_counter_reg(2) OR sim_counter_reg(3) OR sim_counter_reg(4) OR sim_counter_reg(5) OR sim_counter_reg(6) OR sim_counter_reg(7) OR sim_counter_reg(8)); PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN p0addr_sim <= "1"; END IF; END PROCESS; loop2 : FOR i IN 0 TO 8 GENERATE wire_p0addr_sim_w_lg_w_lg_q4w5w(i) <= wire_p0addr_sim_w_lg_q4w(0) AND sim_counter_next(i); END GENERATE loop2; loop3 : FOR i IN 0 TO 8 GENERATE wire_p0addr_sim_w_lg_w_lg_w_lg_q4w5w6w(i) <= wire_p0addr_sim_w_lg_w_lg_q4w5w(i) OR wire_w_lg_sim_counter_and1w(i); END GENERATE loop3; wire_p0addr_sim_w_lg_q4w(0) <= p0addr_sim(0) OR wire_w_lg_w_lg_sim_counter_and2w3w(0); PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN sim_counter_reg <= wire_w_lg_w_lg_w_lg_reset7w8w9w; END IF; END PROCESS; PROCESS (clock) BEGIN IF (clock = '1' AND clock'event) THEN IF (first_run(0) = '1') THEN first_run(0) <= (NOT sim_counter_and(0)); ELSE first_run(0) <= '0'; END IF; END IF; END PROCESS; wire_next_scount_num_result <= wire_next_scount_num_dataa + wire_next_scount_num_datab; wire_next_scount_num_dataa <= sim_counter_reg; wire_next_scount_num_datab <= "000000001"; END RTL; --VALID FILE ------------------------------------------------------------------- -- Filename : alt_aeq_s4.vhd -- -- Description : Simulation model for ADCE -- -- Limitation : Currently, only applies for Stratix IV -- -- Copyright (c) Altera Corporation 1997-2008 -- All rights reserved -- --------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; LIBRARY std; USE std.textio.all; PACKAGE alt_aeq_s4_func IS FUNCTION to_integer ( val : std_logic) RETURN integer; FUNCTION to_integer ( val : std_logic_vector) RETURN integer; FUNCTION or_br ( val : std_logic_vector) RETURN std_logic; END; PACKAGE BODY alt_aeq_s4_func IS FUNCTION to_integer ( val : std_logic) RETURN integer IS VARIABLE rtn : integer := 0; BEGIN IF (val = '1') THEN rtn := 1; ELSE rtn := 0; END IF; RETURN(rtn); END to_integer; -- FUNCTION to_integer ( val : std_logic_vector) RETURN integer IS CONSTANT vec : std_logic_vector(val'high-val'low DOWNTO 0) := val; VARIABLE rtn : integer := 0; BEGIN FOR index IN vec'RANGE LOOP IF (vec(index) = '1') THEN rtn := rtn + (2**index); END IF; END LOOP; RETURN(rtn); END to_integer; FUNCTION or_br ( val : std_logic_vector) RETURN std_logic IS VARIABLE rtn : std_logic := '0'; BEGIN FOR index IN val'RANGE LOOP rtn := rtn OR val(index); END LOOP; RETURN(rtn); END or_br; END; -- USE work.alt_aeq_s4_func.all; LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY alt_aeq_s4 IS GENERIC ( show_errors : STRING := "NO"; radce_hflck : INTEGER := 0; radce_lflck : INTEGER := 0; use_hw_conv_det : INTEGER := 0; number_of_channels : INTEGER := 5; channel_address_width : INTEGER := 3; lpm_type : STRING := "alt_aeq_s4"; lpm_hint : STRING := "UNUSED" ); PORT ( reconfig_clk : IN STD_LOGIC; aclr : IN STD_LOGIC; calibrate : IN STD_LOGIC; shutdown : IN STD_LOGIC; all_channels : IN STD_LOGIC; logical_channel_address : IN STD_LOGIC_VECTOR(channel_address_width - 1 DOWNTO 0); remap_address : IN STD_LOGIC_VECTOR(11 DOWNTO 0); quad_address : OUT STD_LOGIC_VECTOR(8 DOWNTO 0); adce_done : IN STD_LOGIC_VECTOR(number_of_channels - 1 DOWNTO 0); busy : OUT STD_LOGIC; adce_standby : OUT STD_LOGIC_VECTOR(number_of_channels - 1 DOWNTO 0); adce_continuous : IN STD_LOGIC; adce_cal_busy : OUT STD_LOGIC; dprio_busy : IN STD_LOGIC; dprio_in : IN STD_LOGIC_VECTOR(15 DOWNTO 0); dprio_wren : OUT STD_LOGIC; dprio_rden : OUT STD_LOGIC; dprio_addr : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); dprio_data : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); eqout : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); timeout : OUT STD_LOGIC; testbuses : IN STD_LOGIC_VECTOR(7 * number_of_channels - 1 DOWNTO 0); testbus_sels : OUT STD_LOGIC_VECTOR(4 * number_of_channels - 1 DOWNTO 0); conv_error : OUT STD_LOGIC_VECTOR(number_of_channels - 1 DOWNTO 0); error : OUT STD_LOGIC_VECTOR(number_of_channels - 1 DOWNTO 0) ); END alt_aeq_s4; ARCHITECTURE trans OF alt_aeq_s4 IS SIGNAL busy_counter : STD_LOGIC_VECTOR(7 DOWNTO 0); -- Declare intermediate signals for referenced outputs SIGNAL busy_xhdl0 : STD_LOGIC; SIGNAL adce_cal_busy_xhdl0 : STD_LOGIC; BEGIN -- Drive referenced outputs busy <= busy_xhdl0; adce_cal_busy <= adce_cal_busy_xhdl0; dprio_addr <= (OTHERS => '0'); dprio_data <= (OTHERS => '0'); dprio_rden <= '0'; dprio_wren <= '0'; quad_address <= (OTHERS => '0'); busy_xhdl0 <= (or_br(busy_counter)); adce_cal_busy_xhdl0 <= (or_br(busy_counter(7 downto 4))); timeout <= '0'; error <= (OTHERS => '0'); conv_error <= (OTHERS => '0'); eqout <= (OTHERS => '0'); testbus_sels <= (OTHERS => '0'); PROCESS (reconfig_clk) BEGIN IF (reconfig_clk'EVENT AND reconfig_clk = '1') THEN IF (aclr = '1') THEN busy_counter <= "00000000"; adce_standby(to_integer(logical_channel_address)) <= '0'; ELSIF (calibrate = '1') THEN busy_counter <= "11111111"; adce_standby <= (OTHERS => '0'); ELSIF (shutdown = '1') THEN busy_counter <= "00001111"; adce_standby(to_integer(logical_channel_address)) <= '1'; ELSIF (busy_xhdl0 = '1') THEN busy_counter <= busy_counter - "00000001"; END IF; END IF; END PROCESS; END trans; ------------------------------------------------------------------- -- Filename : alt_eyemon.vhd -- -- Description : Simulation model for Eye Monitor (EyeQ) -- -- Limitation : Currently, only supported for Stratix IV -- -- Copyright (c) Altera Corporation 1997-2008 -- All rights reserved -- --------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; library std; use std.textio.all; package alt_eyemon_func is function or_br ( val : std_logic_vector) return std_logic; FUNCTION to_integer ( val : bit_vector) RETURN integer; FUNCTION to_integer ( val : std_logic_vector) RETURN integer; function to_integer ( val : std_logic) return integer; function to_stdlogic ( val : in boolean) return std_logic; function to_stdlogicvector ( val : in integer; len : in integer) return std_logic_vector; function to_stdlogicvector ( val : in boolean; len : in integer) return std_logic_vector; end; package body alt_eyemon_func is function to_integer ( val : bit_vector) return integer is constant vec : bit_vector(val'high-val'low downto 0) := val; variable rtn : integer := 0; begin for index in vec'range loop if (vec(index) = '1') then rtn := rtn + (2**index); end if; end loop; return(rtn); end to_integer; -- function to_integer ( val : std_logic_vector) return integer is constant vec : std_logic_vector(val'high-val'low downto 0) := val; variable rtn : integer := 0; begin for index in vec'range loop if (vec(index) = '1') then rtn := rtn + (2**index); end if; end loop; return(rtn); end to_integer; -- function or_br ( val : std_logic_vector) return std_logic is variable rtn : std_logic := '0'; begin for index in val'range loop rtn := rtn or val(index); end loop; return(rtn); end or_br; -- function to_integer ( val : std_logic) return integer is variable rtn : integer := 0; begin if (val = '1') then rtn := 1; else rtn := 0; end if; return(rtn); end to_integer; -- function to_stdlogic ( val : in boolean) return std_logic is begin if (val) then return('1'); else return('0'); end if; end to_stdlogic; -- function to_stdlogicvector ( val : in integer; len : in integer) return std_logic_vector is variable rtn : std_logic_vector(len-1 downto 0) := (others => '0'); variable num : integer := val; variable r : integer; begin for index in 0 to len-1 loop r := num rem 2; num := num/2; if (r = 1) then rtn(index) := '1'; else rtn(index) := '0'; end if; end loop; return(rtn); end to_stdlogicvector; -- function to_stdlogicvector ( val : in boolean; len : in integer) return std_logic_vector is variable rtn : std_logic_vector(len-1 downto 0) := (others => '0'); begin rtn(0) := to_stdlogic(val); return(rtn); end to_stdlogicvector; end; -- use work.alt_eyemon_func.all; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity alt_eyemon is generic ( channel_address_width : integer := 3; lpm_type : string := "alt_eyemon"; lpm_hint : string := "UNUSED"; avmm_slave_addr_width : integer := 16; avmm_slave_rdata_width : integer := 16; avmm_slave_wdata_width : integer := 16; avmm_master_addr_width : integer := 16; avmm_master_rdata_width : integer := 16; avmm_master_wdata_width : integer := 16; dprio_addr_width : integer := 16; dprio_data_width : integer := 16; ireg_wdaddr_width : integer := 2; ireg_chaddr_width : integer := 2; ireg_data_width : integer := 16 ); port ( i_resetn : in std_logic; i_avmm_clk : in std_logic; i_avmm_saddress : in std_logic_vector(avmm_slave_addr_width - 1 downto 0); i_avmm_sread : in std_logic; i_avmm_swrite : in std_logic; i_avmm_swritedata : in std_logic_vector(avmm_slave_wdata_width - 1 downto 0); o_avmm_sreaddata : out std_logic_vector(avmm_slave_rdata_width - 1 downto 0); o_avmm_swaitrequest : out std_logic; i_remap_phase : in std_logic; i_remap_address : in std_logic_vector(11 downto 0); o_quad_address : out std_logic_vector(8 downto 0); o_reconfig_busy : out std_logic; i_dprio_busy : in std_logic; i_dprio_in : in std_logic_vector(dprio_data_width - 1 downto 0); o_dprio_wren : out std_logic; o_dprio_rden : out std_logic; o_dprio_addr : out std_logic_vector(dprio_addr_width - 1 downto 0); o_dprio_data : out std_logic_vector(dprio_data_width - 1 downto 0) ); end alt_eyemon; architecture trans of alt_eyemon is type type_xhdl0 is array (((2 ** channel_address_width) - 1) downto 0) of std_logic_vector(6 downto 0); type state_type is (ST_IDLE, ST_WRITE, ST_READ); signal state : state_type := ST_IDLE; signal state0q : state_type := ST_IDLE; signal reg_read : std_logic; signal reg_write : std_logic; signal busy_counter : std_logic_vector(5 downto 0) := "000000"; signal reg_chaddress : std_logic_vector(channel_address_width - 1 downto 0) := to_stdlogicvector(0, channel_address_width); signal reg_chaddress0q : std_logic_vector(channel_address_width - 1 downto 0) := to_stdlogicvector(0, channel_address_width); signal reg_data : std_logic_vector(ireg_data_width - 1 downto 0) := to_stdlogicvector(0, ireg_data_width); signal reg_data0q : std_logic_vector(ireg_data_width - 1 downto 0) := to_stdlogicvector(0, ireg_data_width); signal reg_ctrlstatus : std_logic_vector(ireg_data_width - 1 downto 0) := to_stdlogicvector(0, ireg_data_width); signal reg_ctrlstatus0q : std_logic_vector(ireg_data_width - 1 downto 0) := to_stdlogicvector(0, ireg_data_width); signal reg_wdaddress : std_logic_vector(ireg_wdaddr_width - 1 downto 0) := to_stdlogicvector(0, ireg_wdaddr_width); signal reg_wdaddress0q : std_logic_vector(ireg_wdaddr_width - 1 downto 0) := to_stdlogicvector(0, ireg_wdaddr_width); signal dprio_reg : type_xhdl0; signal dprio_reg0q : type_xhdl0; signal invalid_channel_address : std_logic; signal invalid_word_address : std_logic; signal i : integer; -- X-HDL generated signals signal xhdl1 : std_logic; signal xhdl2 : std_logic; begin o_dprio_wren <= '0'; o_dprio_rden <= '0'; o_dprio_addr <= (others => '0'); o_dprio_data <=(others => '0'); o_quad_address <= (others => '0'); o_reconfig_busy <= reg_ctrlstatus0q(15); process (i_avmm_clk) begin if (i_avmm_clk'event and i_avmm_clk = '1') then if ((not(i_resetn)) = '1') then state0q <= ST_IDLE; else state0q <= state; end if; end if; end process; process (i_avmm_clk) begin if (i_avmm_clk'event and i_avmm_clk = '1') then if ((not(i_resetn)) = '1') then busy_counter <= "000000"; elsif (((reg_ctrlstatus(0) = '1') and (reg_ctrlstatus0q(0) = '0')) and ((not(reg_ctrlstatus(1))) = '1')) then busy_counter <= "111111"; elsif (((reg_ctrlstatus(0) = '1') and (reg_ctrlstatus0q(0) = '0')) and ((reg_ctrlstatus(1)) = '1')) then busy_counter <= "011111"; elsif ((or_BR(busy_counter)) = '1') then busy_counter <= busy_counter - "000001"; end if; end if; end process; process (state0q, i_avmm_sread, i_avmm_swrite, reg_ctrlstatus0q) begin o_avmm_swaitrequest <= '0'; reg_write <= '0'; reg_read <= '0'; case state0q is when ST_WRITE => o_avmm_swaitrequest <= '0'; state <= ST_IDLE; when ST_READ => o_avmm_swaitrequest <= '0'; reg_read <= '1'; state <= ST_IDLE; when others => if (i_avmm_sread = '1') then o_avmm_swaitrequest <= '1'; reg_read <= '1'; state <= ST_READ; elsif (i_avmm_swrite = '1') then o_avmm_swaitrequest <= '1'; if ((reg_ctrlstatus0q(15)) = '1') then reg_write <= '0'; else reg_write <= '1'; end if; state <= ST_WRITE; else o_avmm_swaitrequest <= '0'; state <= ST_IDLE; end if; end case; end process; process (i_avmm_clk) begin if (i_avmm_clk'event and i_avmm_clk = '1') then if ((not(i_resetn)) = '1') then reg_chaddress0q <= (others => '0'); reg_data0q <= (others => '0'); reg_ctrlstatus0q <= (others => '0'); reg_wdaddress0q <= (others => '0'); for i in 0 to ((2 ** channel_address_width)) - 1 loop dprio_reg0q(i) <= (others => '0'); end loop; else reg_chaddress0q <= reg_chaddress; reg_data0q <= reg_data; reg_ctrlstatus0q <= reg_ctrlstatus; reg_wdaddress0q <= reg_wdaddress; for i in 0 to ((2 ** channel_address_width)) - 1 loop dprio_reg0q(i) <= dprio_reg(i); end loop; end if; end if; end process; process (reg_read, i_avmm_saddress, reg_ctrlstatus0q, reg_chaddress0q, reg_wdaddress0q, reg_data0q) begin if (reg_read = '1') then if (i_avmm_saddress (15 downto 0) = "0000000000000000") then o_avmm_sreaddata(ireg_data_width - 1 downto 0) <= reg_ctrlstatus0q; elsif (i_avmm_saddress (15 downto 0)= "0000000000000001") then o_avmm_sreaddata(channel_address_width - 1 downto 0) <= reg_chaddress0q; elsif (i_avmm_saddress(15 downto 0) = "0000000000000010") then o_avmm_sreaddata(ireg_wdaddr_width - 1 downto 0) <= reg_wdaddress0q; elsif (i_avmm_saddress(15 downto 0) = "0000000000000011") then o_avmm_sreaddata <= reg_data0q; else o_avmm_sreaddata <= (others => '0'); end if; else o_avmm_sreaddata <= (others => '0'); end if; end process; invalid_channel_address <= to_stdlogic((i_remap_address = "111111111111")); invalid_word_address <= to_stdlogic((reg_wdaddress0q > "01")); xhdl1 <= '0' when ((i_avmm_swritedata(14)) = '1') else reg_ctrlstatus0q(14); xhdl2 <= '0' when ((i_avmm_swritedata(13)) = '1') else reg_ctrlstatus0q(13); process (reg_chaddress0q, reg_data0q, reg_ctrlstatus0q, reg_wdaddress0q, i, dprio_reg, busy_counter, dprio_reg0q, reg_write, i_avmm_saddress, i_avmm_swritedata, invalid_channel_address, invalid_word_address) begin reg_chaddress <= reg_chaddress0q; reg_data <= reg_data0q; reg_ctrlstatus <= reg_ctrlstatus0q; reg_wdaddress <= reg_wdaddress0q; for i in 0 to ((2 ** channel_address_width)) - 1 loop dprio_reg0q(i) <= dprio_reg(i); end loop; if (busy_counter = "000001") then reg_ctrlstatus(15) <= '0'; reg_ctrlstatus(0) <= '0'; if ((reg_ctrlstatus0q(1)) = '1') then if (reg_wdaddress0q = "00") then reg_data(0) <= dprio_reg0q(to_integer(reg_chaddress0q))(0); reg_data(15 downto 1) <= "000000000000000"; elsif (reg_wdaddress0q = "01") then reg_data(5 downto 0) <= dprio_reg0q(to_integer(reg_chaddress0q))(6 downto 1); reg_data(15 downto 6) <= "0000000000"; end if; end if; end if; if (reg_write = '1') then if (i_avmm_saddress = "0000000000000000") then reg_ctrlstatus(1) <= i_avmm_swritedata(1); if ((i_avmm_swritedata(0)) = '1') then if ((invalid_channel_address = '1') or (invalid_word_address = '1')) then reg_ctrlstatus(15) <= '0'; reg_ctrlstatus(14) <= invalid_word_address; reg_ctrlstatus(13) <= invalid_channel_address; else if ((not(i_avmm_swritedata(1))) = '1') then if (reg_wdaddress0q = "00") then dprio_reg(to_integer(reg_chaddress0q))(0) <= (reg_data0q(0)); elsif (reg_wdaddress0q = "01") then dprio_reg(to_integer(reg_chaddress0q))(6 downto 1) <= (reg_data0q(5 downto 0)); end if; end if; reg_ctrlstatus(0) <= '1'; reg_ctrlstatus(15) <= '1'; reg_ctrlstatus(14) <= '0'; reg_ctrlstatus(13) <= '0'; end if; else reg_ctrlstatus(15) <= '0'; reg_ctrlstatus(14) <= xhdl1; reg_ctrlstatus(13) <= xhdl2; end if; elsif (i_avmm_saddress(15 downto 0) = "0000000000000001") then if (channel_address_width < 2) then reg_chaddress <= i_avmm_swritedata(0 downto 0); else reg_chaddress <= i_avmm_swritedata(channel_address_width - 1 downto 0); end if; elsif (i_avmm_saddress(15 downto 0) = "0000000000000010") then reg_wdaddress <= i_avmm_swritedata(ireg_wdaddr_width - 1 downto 0); elsif (i_avmm_saddress(15 downto 0) = "0000000000000011") then reg_data <= i_avmm_swritedata(ireg_data_width - 1 downto 0); end if; end if; end process; end trans; ------------------------------------------------------------------- -- Filename : alt_dfe.vhd -- -- Description : Simulation model for DFE -- -- Limitation : Currently, only supported for Stratix IV -- -- Copyright (c) Altera Corporation 1997-2008 -- All rights reserved -- --------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; library std; use std.textio.all; package alt_dfe_func is function or_br ( val : std_logic_vector) return std_logic; FUNCTION to_integer ( val : bit_vector) RETURN integer; FUNCTION to_integer ( val : std_logic_vector) RETURN integer; function to_integer ( val : std_logic) return integer; function to_stdlogic ( val : in boolean) return std_logic; function to_stdlogicvector ( val : in integer; len : in integer) return std_logic_vector; function to_stdlogicvector ( val : in boolean; len : in integer) return std_logic_vector; end; package body alt_dfe_func is function to_integer ( val : bit_vector) return integer is constant vec : bit_vector(val'high-val'low downto 0) := val; variable rtn : integer := 0; begin for index in vec'range loop if (vec(index) = '1') then rtn := rtn + (2**index); end if; end loop; return(rtn); end to_integer; -- function to_integer ( val : std_logic_vector) return integer is constant vec : std_logic_vector(val'high-val'low downto 0) := val; variable rtn : integer := 0; begin for index in vec'range loop if (vec(index) = '1') then rtn := rtn + (2**index); end if; end loop; return(rtn); end to_integer; -- function or_br ( val : std_logic_vector) return std_logic is variable rtn : std_logic := '0'; begin for index in val'range loop rtn := rtn or val(index); end loop; return(rtn); end or_br; -- function to_integer ( val : std_logic) return integer is variable rtn : integer := 0; begin if (val = '1') then rtn := 1; else rtn := 0; end if; return(rtn); end to_integer; -- function to_stdlogic ( val : in boolean) return std_logic is begin if (val) then return('1'); else return('0'); end if; end to_stdlogic; -- function to_stdlogicvector ( val : in integer; len : in integer) return std_logic_vector is variable rtn : std_logic_vector(len-1 downto 0) := (others => '0'); variable num : integer := val; variable r : integer; begin for index in 0 to len-1 loop r := num rem 2; num := num/2; if (r = 1) then rtn(index) := '1'; else rtn(index) := '0'; end if; end loop; return(rtn); end to_stdlogicvector; -- function to_stdlogicvector ( val : in boolean; len : in integer) return std_logic_vector is variable rtn : std_logic_vector(len-1 downto 0) := (others => '0'); begin rtn(0) := to_stdlogic(val); return(rtn); end to_stdlogicvector; end; -- use work.alt_dfe_func.all; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity alt_dfe is generic ( channel_address_width : integer := 3; lpm_type : string := "alt_dfe"; lpm_hint : string := "UNUSED"; avmm_slave_addr_width : integer := 16; avmm_slave_rdata_width : integer := 16; avmm_slave_wdata_width : integer := 16; avmm_master_addr_width : integer := 16; avmm_master_rdata_width : integer := 16; avmm_master_wdata_width : integer := 16; dprio_addr_width : integer := 16; dprio_data_width : integer := 16; ireg_chaddr_width : integer := 2; ireg_wdaddr_width : integer := 2; ireg_data_width : integer := 16 ); port ( i_resetn : in std_logic; i_avmm_clk : in std_logic; i_avmm_saddress : in std_logic_vector(avmm_slave_addr_width - 1 downto 0); i_avmm_sread : in std_logic; i_avmm_swrite : in std_logic; i_avmm_swritedata : in std_logic_vector(avmm_slave_wdata_width - 1 downto 0); o_avmm_sreaddata : out std_logic_vector(avmm_slave_rdata_width - 1 downto 0); o_avmm_swaitrequest : out std_logic; i_remap_address : in std_logic_vector(11 downto 0); o_quad_address : out std_logic_vector(8 downto 0); o_reconfig_busy : out std_logic; i_dprio_busy : in std_logic; i_dprio_in : in std_logic_vector(dprio_data_width - 1 downto 0); o_dprio_wren : out std_logic; o_dprio_rden : out std_logic; o_dprio_addr : out std_logic_vector(dprio_addr_width - 1 downto 0); o_dprio_data : out std_logic_vector(dprio_data_width - 1 downto 0) ); end alt_dfe; architecture trans of alt_dfe is type type_xhdl0 is array (((2 ** channel_address_width) - 1) downto 0) of std_logic_vector(12 downto 0); type state_type is (ST_IDLE, ST_WRITE, ST_READ); signal state : state_type := ST_IDLE; signal state0q : state_type := ST_IDLE; signal reg_read : std_logic; signal reg_write : std_logic; signal busy_counter : std_logic_vector(5 downto 0) := "000000"; signal reg_chaddress : std_logic_vector(channel_address_width - 1 downto 0) := to_stdlogicvector(0, channel_address_width); signal reg_chaddress0q : std_logic_vector(channel_address_width - 1 downto 0) := to_stdlogicvector(0, channel_address_width); signal reg_data : std_logic_vector(ireg_data_width - 1 downto 0) := to_stdlogicvector(0, ireg_data_width); signal reg_data0q : std_logic_vector(ireg_data_width - 1 downto 0) := to_stdlogicvector(0, ireg_data_width); signal reg_ctrlstatus : std_logic_vector(ireg_data_width - 1 downto 0) := to_stdlogicvector(0, ireg_data_width); signal reg_ctrlstatus0q : std_logic_vector(ireg_data_width - 1 downto 0) := to_stdlogicvector(0, ireg_data_width); signal reg_wdaddress : std_logic_vector(ireg_wdaddr_width - 1 downto 0) := to_stdlogicvector(0, ireg_wdaddr_width); signal reg_wdaddress0q : std_logic_vector(ireg_wdaddr_width - 1 downto 0) := to_stdlogicvector(0, ireg_wdaddr_width); signal dprio_reg : type_xhdl0; signal dprio_reg0q : type_xhdl0; signal invalid_channel_address : std_logic; signal invalid_word_address : std_logic; signal i : integer; -- X-HDL generated signals signal xhdl1 : std_logic; signal xhdl2 : std_logic; begin o_dprio_wren <= '0'; o_dprio_rden <= '0'; o_dprio_addr <= (others => '0'); o_dprio_data <= (others => '0'); o_quad_address <= (others => '0'); o_reconfig_busy <= reg_ctrlstatus0q(15); process (i_avmm_clk) begin if (i_avmm_clk'event and i_avmm_clk = '1') then if ((not(i_resetn)) = '1') then state0q <= ST_IDLE; else state0q <= state; end if; end if; end process; process (i_avmm_clk) begin if (i_avmm_clk'event and i_avmm_clk = '1') then if ((not(i_resetn)) = '1') then busy_counter <= (others => '0'); elsif (((reg_ctrlstatus(0) = '1') and (reg_ctrlstatus0q(0) = '0')) and ((not(reg_ctrlstatus(1))) = '1')) then busy_counter <= "111111"; elsif (((reg_ctrlstatus(0) = '1') and (reg_ctrlstatus0q(0) = '0')) and ((reg_ctrlstatus(1)) = '1')) then busy_counter <= "011111"; elsif ((or_BR(busy_counter)) = '1') then busy_counter <= busy_counter - "000001"; end if; end if; end process; process (state0q, i_avmm_sread, i_avmm_swrite, reg_ctrlstatus0q) begin o_avmm_swaitrequest <= '0'; reg_write <= '0'; reg_read <= '0'; case state0q is when ST_WRITE => o_avmm_swaitrequest <= '0'; state <= ST_IDLE; when ST_READ => o_avmm_swaitrequest <= '0'; reg_read <= '1'; state <= ST_IDLE; when others => if (i_avmm_sread = '1') then o_avmm_swaitrequest <= '1'; reg_read <= '1'; state <= ST_READ; elsif (i_avmm_swrite = '1') then o_avmm_swaitrequest <= '1'; if ((reg_ctrlstatus0q(15)) = '1') then reg_write <= '0'; else reg_write <= '1'; end if; state <= ST_WRITE; else o_avmm_swaitrequest <= '0'; state <= ST_IDLE; end if; end case; end process; process (i_avmm_clk) begin if (i_avmm_clk'event and i_avmm_clk = '1') then if ((not(i_resetn)) = '1') then reg_chaddress0q <= (others => '0'); reg_data0q <= (others => '0'); reg_ctrlstatus0q <= (others => '0'); reg_wdaddress0q <= (others => '0'); for i in 0 to ((2 ** channel_address_width)) - 1 loop dprio_reg0q(i) <= (others => '0'); end loop; else reg_chaddress0q <= reg_chaddress; reg_data0q <= reg_data; reg_ctrlstatus0q <= reg_ctrlstatus; reg_wdaddress0q <= reg_wdaddress; for i in 0 to ((2 ** channel_address_width)) - 1 loop dprio_reg0q(i) <= dprio_reg(i); end loop; end if; end if; end process; process (reg_read, i_avmm_saddress, reg_ctrlstatus0q, reg_chaddress0q, reg_wdaddress0q, reg_data0q) begin if (reg_read = '1') then if (i_avmm_saddress(15 downto 0) = "0000000000000000") then o_avmm_sreaddata(ireg_data_width - 1 downto 0) <= reg_ctrlstatus0q; elsif (i_avmm_saddress(15 downto 0) = "0000000000000001") then o_avmm_sreaddata(channel_address_width - 1 downto 0) <= reg_chaddress0q; elsif (i_avmm_saddress(15 downto 0) = "0000000000000010") then o_avmm_sreaddata(ireg_wdaddr_width - 1 downto 0) <= reg_wdaddress0q; elsif (i_avmm_saddress(15 downto 0) = "0000000000000011") then o_avmm_sreaddata <= reg_data0q; else o_avmm_sreaddata <= (others => '0'); end if; else o_avmm_sreaddata <= (others => '0'); end if; end process; invalid_channel_address <= to_stdlogic((i_remap_address = "111111111111")); invalid_word_address <= to_stdlogic((reg_wdaddress0q > "10")); xhdl1 <= '0' when ((i_avmm_swritedata(14)) = '1') else reg_ctrlstatus0q(14); xhdl2 <= '0' when ((i_avmm_swritedata(13)) = '1') else reg_ctrlstatus0q(13); process (reg_chaddress0q, reg_data0q, reg_ctrlstatus0q, reg_wdaddress0q, i, dprio_reg, busy_counter, dprio_reg0q, reg_write, i_avmm_saddress, i_avmm_swritedata, invalid_channel_address, invalid_word_address) begin reg_chaddress <= reg_chaddress0q; reg_data <= reg_data0q; reg_ctrlstatus <= reg_ctrlstatus0q; reg_wdaddress <= reg_wdaddress0q; for i in 0 to ((2 ** channel_address_width)) - 1 loop dprio_reg0q(i) <= dprio_reg(i); end loop; if (busy_counter = "000001") then reg_ctrlstatus(15) <= '0'; reg_ctrlstatus(0) <= '0'; if ((reg_ctrlstatus0q(1)) = '1') then if (reg_wdaddress0q = "00") then reg_data(2 downto 0) <= dprio_reg0q(to_integer(reg_chaddress0q))(2 downto 0); reg_data(15 downto 3) <= "0000000000000"; elsif (reg_wdaddress0q = "01") then reg_data(3 downto 0) <= dprio_reg0q(to_integer(reg_chaddress0q))(6 downto 3); reg_data(15 downto 4) <= "000000000000"; elsif (reg_wdaddress0q = "10") then reg_data(5 downto 0) <= dprio_reg0q(to_integer(reg_chaddress0q))(12 downto 7); reg_data(15 downto 6) <= "0000000000"; end if; end if; end if; if (reg_write = '1') then if (i_avmm_saddress(15 downto 0) = "0000000000000000") then reg_ctrlstatus(1) <= i_avmm_swritedata(1); if ((i_avmm_swritedata(0)) = '1') then if ((invalid_channel_address = '1') or (invalid_word_address = '1')) then reg_ctrlstatus(15) <= '0'; reg_ctrlstatus(14) <= invalid_word_address; reg_ctrlstatus(13) <= invalid_channel_address; else if ((not(i_avmm_swritedata(1))) = '1') then if (reg_wdaddress0q = "00") then dprio_reg(to_integer(reg_chaddress0q))(2 downto 0) <= (reg_data0q(2 downto 0)); elsif (reg_wdaddress0q = "01") then dprio_reg(to_integer(reg_chaddress0q))(6 downto 3) <= (reg_data0q(3 downto 0)); elsif (reg_wdaddress0q = "10") then dprio_reg(to_integer(reg_chaddress0q))(12 downto 7) <= (reg_data0q(5 downto 0)); end if; end if; reg_ctrlstatus(0) <= '1'; reg_ctrlstatus(15) <= '1'; reg_ctrlstatus(14) <= '0'; reg_ctrlstatus(13) <= '0'; end if; else reg_ctrlstatus(15) <= '0'; reg_ctrlstatus(14) <= xhdl1; reg_ctrlstatus(13) <= xhdl2; end if; elsif (i_avmm_saddress(15 downto 0) = "0000000000000001") then if (channel_address_width < 2) then reg_chaddress <= i_avmm_swritedata(0 downto 0); else reg_chaddress <= i_avmm_swritedata(channel_address_width - 1 downto 0); end if; elsif (i_avmm_saddress(15 downto 0) = "0000000000000010") then reg_wdaddress <= i_avmm_swritedata(ireg_wdaddr_width - 1 downto 0); elsif (i_avmm_saddress(15 downto 0) = "0000000000000011") then reg_data <= i_avmm_swritedata(ireg_data_width - 1 downto 0); end if; end if; end process; end trans; ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; package SLD_NODE is constant CLK_PERIOD : time := 100 NS; -- the clock period of the system (10Mhz) constant NUM_SELECTION_BITS : natural := 4; -- the number of selection bits + 3 to be added to the IR register -- in the dummy hub. 3 is the width of -- hub instructions constant PARAM_ERROR : string := "Invalid parameter specification : SLD_NODE_SIM_ACTION"; -- error message for invalid parameters constant HEXCON_ERROR : string := "Invalid hexadecimal character : SLD_NODE_SIM_ACTION"; -- error message for invalid -- hexadecimal parameters constant TYPE_ERROR : string := "Invalid Scan type specified : SLD_NODE_SIM_ACTION"; -- error message for an invalid scan type constant FIRST_TYPE_ERROR : string := "First scan should always be an IR scan. : SLD_NODE_SIM_ACTION"; -- error message for an invalid first scan type constant LENGTH_ERROR : string := "IR length specified is less than SLD_NODE_IR_WIDTH : SLD_NODE_SIM_ACTION"; -- error message for an invalid ir length constant ZERO_LENGTH_ERROR : string := "Zero is not a valid length parameter : SLD_NODE_SIM_ACTION"; -- error message when zero length is given constant V_IR_SCAN_TYPE : std_logic_vector(3 downto 0) := "0001"; -- ir type signal constant V_DR_SCAN_TYPE : std_logic_vector(3 downto 0) := "0010"; -- dr type signal constant JTAG_USR1_INSTR : std_logic_vector(9 downto 0) := "0000001110"; -- the usr1 instruction for jtag controller -- purpose: handles errors based on the severity level. Can stop simulation and will also display message procedure message ( mess : string; -- string to be displayed sev : severity_level); -- severity level of message procedure hexmessage ( mess : string; -- string to be displayed value : character; -- string to be displayed sev : severity_level); -- purpose: converts a character to a 4 bit value. All characters beyond F generate a warning and convert to -- zero function hexToBits ( constant hexValue : character) -- the charcater to be decoded return unsigned; -- purpose: converts a character to an exact number of bits value. All characters beyond 7 generate a warning and convert -- to zero function hexToExactBits ( constant hexValue : character; -- the character to be converted constant num_bits : natural) -- the number of bits to return return unsigned; -- purpose: move JTAG tap into a dr shift state procedure goto_dr_shift_state ( signal tck : out std_logic; -- tck signal signal tms : out std_logic); -- tms signal -- purpose: shifts usr0 into the jtag tap controller. Assumes tap is in update or rti state. procedure jtag_ir_usr0 ( signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic); -- tdi signal -- purpose: shifts the usr1 instruction into the jtag tap controller. Works if jtag is in an update state or rti state procedure jtag_ir_usr1 ( signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic); -- tdi signal -- purpose: sends a HUB_FORCE_IR_CAPTURE instruction to the hub procedure send_force_ir_capture ( constant ir_width : in integer; -- ir_width - 4 signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic); -- tdi signal -- purpose: a dr scan with the passed in value. Assumes we are in udr/uir state procedure dr_scan ( constant length : in natural; -- length of the value constant idx_lsb : in natural; -- the index to start reading values from constant idx_msb : in natural; -- the index to stop reading at constant value : in std_logic_vector; -- the value to be shifted signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic); -- tdi signal -- purpose: virtual dr scan procedure v_dr_scan ( constant length : in natural; -- length of the value constant idx_lsb : in natural; -- the index to start reading values from constant idx_msb : in natural; -- the index to stop reading at constant value : in std_logic_vector; -- the value to be shifted signal jtag_usr1 : in std_logic; -- high if jtag is in usr1 state signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic); -- tdi signal -- purpose: virtual ir scan procedure v_ir_scan ( constant length : in natural; -- length of bit stream constant idx_lsb : in natural; -- the index to start reading values from constant idx_msb : in natural; -- the index to stop reading at constant value : in std_logic_vector; -- the value to be shifted out constant ir_width : in integer; -- sld_node_ir_width - 4 signal jtag_usr1 : in std_logic; -- high if jtag is in usr1 state signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic); -- tdi signal end SLD_NODE; package body SLD_NODE is -- purpose: handles errors based on the severity level. Can stop simulation and will also display message procedure message ( mess : string; -- string to be displayed sev : severity_level) is -- severity level of message begin -- message assert (FALSE) report mess severity sev; end message; -- purpose: handles errors based on the severity level. Can stop simulation and will also display message procedure hexmessage ( mess : string; -- string to be displayed value : character; -- string to be displayed sev : severity_level) is -- severity level of message begin -- message assert (FALSE) report mess & " Character is : " & value severity sev; end hexmessage; -- purpose: converts a character to a 4 bit value. All characters beyond F generate a warning and convert to -- zero function hexToBits ( constant hexValue : character) -- the character to be converted return unsigned is variable result : unsigned(3 downto 0) := (others => '0'); -- variable to hold decoded bits begin -- hexToBits case hexValue is when '0' => result := "0000"; when '1' => result := "0001"; when '2' => result := "0010"; when '3' => result := "0011"; when '4' => result := "0100"; when '5' => result := "0101"; when '6' => result := "0110"; when '7' => result := "0111"; when '8' => result := "1000"; when '9' => result := "1001"; when 'A' => result := "1010"; when 'a' => result := "1010"; when 'B' => result := "1011"; when 'b' => result := "1011"; when 'C' => result := "1100"; when 'c' => result := "1100"; when 'D' => result := "1101"; when 'd' => result := "1101"; when 'E' => result := "1110"; when 'e' => result := "1110"; when 'F' => result := "1111"; when 'f' => result := "1111"; when others => hexmessage(hexcon_error, hexValue, WARNING); result := "0000"; end case; return result; end hexToBits; -- purpose: converts a character to an exact number of bits value. All characters beyond 7 generate a warning and convert -- to zero function hexToExactBits ( constant hexValue : character; -- the character to be converted constant num_bits : natural) -- the number of bits to return return unsigned is variable result : unsigned(3 downto 0) := (others => '0'); -- variable to hold bits begin -- hexToExactBits result := hexToBits(hexValue); return result(num_bits - 1 downto 0); end hexToExactBits; -- purpose: move JTAG tap into a dr shift state procedure goto_dr_shift_state ( signal tck : out std_logic; -- tck signal signal tms : out std_logic) is -- tms signal begin -- goto_dr_shift_state -- get into drs state tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- get into cdr state tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- get into sdr state tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; end goto_dr_shift_state; -- purpose: move jtag from dr/ir shift state to ir/dr update state procedure goto_update_state ( signal tck : out std_logic; -- tck signal signal tms : out std_logic) is -- tms signal begin -- goto_update_state -- get into e1(i/d)r state tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- get into u(i/d)r state tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; end goto_update_state; -- purpose: shifts the usr1 instruction into the jtag tap controller. Works if jtag is in an update state or rti state procedure jtag_ir_usr1 ( signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic) is -- tdi signal begin -- jtag_to_usr1 -- get into drs state tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- get into irs state tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- get into cir state tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- get into sir state tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- shift in data i.e usr1 instruction -- usr1 = 0x0E = 0b00 0000 1110 tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '1'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '1'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '1'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- done with 1110 tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- done with 0000 tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '0'; tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- done with 00 -- now in e1ir state -- get into uir state tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; end jtag_ir_usr1; -- purpose: shifts usr0 into the jtag tap controller. Assumes tap is in update or rti state. procedure jtag_ir_usr0 ( signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic) is -- tdi signal begin -- jtag_ir_usr0 -- get into drs state tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- get into irs state tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- get into cir state tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- get into sir state tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- shift in data i.e usr0 instruction -- usr1 = 0x0E = 0b00 0000 1100 tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '1'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '1'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- done with 1100 tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- done with 0000 tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- done with 00 -- get into e1ir state tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- get into uir state tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; end jtag_ir_usr0; -- purpose: sends a HUB_FORCE_IR_CAPTURE instruction to the hub procedure send_force_ir_capture ( constant ir_width : in integer; -- ir_width - 4 signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic) is -- tdi signal begin -- send_force_ir_capture goto_dr_shift_state(tck, tms); -- shift in the instruction tdi <= '1'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '1'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- done with 011 -- fill up for ir width for j in 0 to ir_width - 1 loop tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; end loop; -- j -- one select bit tdi <= '0'; tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; goto_update_state(tck, tms); end send_force_ir_capture; -- purpose: a dr scan with the passed in value. Assumes we are in udr/uir state procedure dr_scan ( constant length : in natural; -- length of the value constant idx_lsb : in natural; -- the index to start reading values from constant idx_msb : in natural; -- the index to stop reading at constant value : in std_logic_vector; -- the value to be shifted signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic) is -- tdi signal begin -- dr_scan goto_dr_shift_state(tck, tms); for i in idx_lsb to idx_msb - 1 loop tms <= '0'; tdi <= value(i); tck <= '0', '1' after clk_period/2; wait for clk_period; end loop; -- i -- check if we need to pad with zeros if ((idx_msb - idx_lsb + 1) < length ) then -- clock last value bit tdi <= value(idx_msb); tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; -- pad with zeros for j in idx_msb - idx_lsb + 1 to length - 2 loop tms <= '0'; tdi <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; end loop; -- j tdi <= '0'; else tdi <= value(idx_msb); end if; -- last bit is clocked together with state transition goto_update_state(tck, tms); end dr_scan; -- purpose: virtual dr scan procedure v_dr_scan ( constant length : in natural; -- length of the value constant idx_lsb : in natural; -- the index to start reading values from constant idx_msb : in natural; -- the index to stop reading at constant value : in std_logic_vector; -- the value to be shifted signal jtag_usr1 : in std_logic; -- high if jtag is in usr1 state signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic) is -- tdi signal begin -- v_dr_scan if (jtag_usr1 = '1') then -- shift in usr0 instruction jtag_ir_usr0(tck, tms, tdi); end if; -- shift in the dr value dr_scan(length, idx_lsb, idx_msb, value, tck, tms, tdi); end v_dr_scan; -- purpose: virtual ir scan procedure v_ir_scan ( constant length : in natural; -- length of bit stream this is ignored constant idx_lsb : in natural; -- the index to start reading values from constant idx_msb : in natural; -- the index to stop reading at constant value : in std_logic_vector; -- the value to be shifted out constant ir_width : in integer; -- sld_node_ir_width - 4 signal jtag_usr1 : in std_logic; -- high if jtag is in usr1 state signal tck : out std_logic; -- tck signal signal tms : out std_logic; -- tms signal signal tdi : out std_logic) is -- tdi signal begin -- v_ir_scan if (jtag_usr1 = '0' ) then -- shift in usr1 instruction jtag_ir_usr1(tck, tms, tdi); end if; -- send capture_ir instructions send_force_ir_capture(ir_width, tck, tms, tdi); -- shift in the ir value goto_dr_shift_state(tck, tms); for i in idx_lsb to idx_msb loop tms <= '0'; tdi <= value(i); tck <= '0', '1' after clk_period/2; wait for clk_period; end loop; -- i -- pad with zeros if necessary for j in idx_msb - idx_lsb + 1 to ir_width + 3 loop tms <= '0'; tdi <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; end loop; -- j -- last bit is clocked together with state transition -- last bit is selection bit. For IR scans this is always 1 implying -- node as opposed to hub tdi <= '1'; goto_update_state(tck, tms); end v_ir_scan; end SLD_NODE; ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; use work.sld_node.all; ------------------------------------------------------------------------------- -- Entity Name : signal_gen -- -- Description : Simulates customizable actions on a JTAG input -- -- Limitation : See file limitations above -- -- Results Expected : -- -- ------------------------------------------------------------------------------- entity signal_gen is generic ( sld_node_ir_width : integer; -- ir width for this instance sld_node_n_scan : natural; -- the number of scans to be executed sld_node_total_length : natural; -- the total length of all scan values sld_node_sim_action : string); -- the actions to be simulated. port ( tck : out std_logic; -- jtag clock tms : out std_logic; -- tms signal for jtag tdi : out std_logic; -- tdi signal to the jtag jtag_usr1 : in std_logic; -- high when jtag is in usr1 state tdo : in std_logic); -- tdo signal from jtag end signal_gen; architecture simModel of signal_gen is ------------------------------------------------------------------------------- type instr is record -- represents a single instruction scan_time : time; -- the time to wait before executing this instruction scan_type : std_logic_vector(3 downto 0); -- the type of scan this is length : unsigned(31 downto 0); -- the bit length of the value to be shifted idx_lsb : natural; -- the starting index of value idx_msb : natural; -- the starting index of value end record; ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- array for instructions type scansArray is array (sld_node_n_scan - 1 downto 0) of instr; -- the scansArray ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Parsed string data structure type decodedScans is record -- decodedScans for this instance of the model scans : scansArray; -- the array of instructions values : std_logic_vector(sld_node_total_length - 1 downto 0); -- the values for all scans end record; ------------------------------------------------------------------------------- -- purpose: takes in a string and returns the decoded scans for use by the model function decode ( constant actions : string) -- the string to be decoded return decodedScans is type mStates is (STARTSTATE, TIMESTATE, TYPESTATE, LENGTHSTATE, VALUESTATE); -- the states of the parsing machine variable decScans : decodedScans; -- the variable to store the decoded scans variable decValues : std_logic_vector(sld_node_total_length - 1 downto 0); -- variable to store decoded values variable decScanArray : scansArray; -- variable to store decoded scans variable cState : mStates := STARTSTATE; -- the current state variable variable cTime : unsigned(31 downto 0) := (others => '0'); -- the current Time being decoded variable cIdx_lsb : natural := 0; -- the current lsb idx for the value array variable cIdx_msb : natural := 0; -- the current msb idx for the value array variable cType : std_logic_vector(3 downto 0) := (others => '0'); -- the current type variable scanArrIdx : natural range 0 to sld_node_n_scan := 0; -- the index to the scan array -- scanArrIdx is one more than needed to allow for the loop not to crash, since we -- increment index at the end of the loop variable cLength : unsigned(31 downto 0) := (others => '0'); -- the current length value begin -- decode decValues := (others =>'0'); -- initialize all bits to zero for i in 2 to actions'length - 1 loop case cState is when STARTSTATE => if (actions(i) = '(') then cState := TIMESTATE; end if; when TIMESTATE => if (actions(i) = ',') then cState := TYPESTATE; else cTime(31 downto 4) := cTime(27 downto 0); cTime(3 downto 0) := hexToBits(actions(i)); end if; when TYPESTATE => if (actions(i) = ',') then cState := VALUESTATE; else cType := std_logic_vector(hexToBits(actions(i))); end if; when VALUESTATE => if (actions(i) = ',') then cState := LENGTHSTATE; elsif ((sld_node_total_length - cIdx_lsb) < 4) then decValues(sld_node_total_length - 1 downto cIdx_lsb) := std_logic_vector(hexToExactBits(actions(i),sld_node_total_length - cIdx_lsb)); cIdx_msb := cIdx_msb + sld_node_total_length - cIdx_lsb; else -- the line below shifts the previous character decValues(sld_node_total_length - 1 downto cIdx_lsb + 4) := decValues(sld_node_total_length - 5 downto cIdx_lsb); decValues(cIdx_lsb + 3 downto cIdx_lsb) := std_logic_vector(hexToBits(actions(i))); cIdx_msb := cIdx_msb + 4; end if; when LENGTHSTATE => if (actions(i) = ')') then -- zero is not a valid length if (conv_integer(cLength) = 0) then message(ZERO_LENGTH_ERROR,FAILURE); end if; decScanArray(scanArrIdx).scan_time := CLK_PERIOD * 10000 * conv_integer(cTime); decScanArray(scanArrIdx).scan_type := cType; decScanArray(scanArrIdx).length := cLength; decScanArray(scanArrIdx).idx_lsb := cIdx_lsb; -- error checking for cases when actual bit length > -- specified length i.e need for truncation if (cIdx_lsb + conv_integer(cLength) < cIdx_msb) then cIdx_msb := cIdx_lsb + conv_integer(cLength); end if; decScanArray(scanArrIdx).idx_msb := cIdx_msb - 1; cTime := (others => '0'); cType := (others => '0'); cLength := (others => '0'); cIdx_lsb := cIdx_msb; scanArrIdx := scanArrIdx + 1 ; cState := STARTSTATE; else cLength(31 downto 4) := cLength(27 downto 0); cLength(3 downto 0) := hexToBits(actions(i)); end if; when others => null; end case; end loop; -- i decScans.scans := decScanArray; decScans.values := decValues; return decScans; end decode; ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Resets the JTAP controller. procedure reset_jtag ( constant length : in unsigned(31 downto 0); -- the ir-calue to be shifted constant idx : in natural; -- the index to start reading value from constant values : in std_logic_vector(sld_node_total_length - 1 downto 0); -- the values to be shifted out signal tck : out std_logic; -- the tck signal signal tms : out std_logic; -- the tms signal signal tdi : out std_logic) is -- the tdi signal begin -- ir_scan -- get into tlr state for i in 0 to 5 loop tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; end loop; -- i -- get into rti state tms <= '0'; tck <= '0', '1' after clk_period/2; wait for clk_period; jtag_ir_usr1(tck,tms,tdi); end reset_jtag; ------------------------------------------------------------------------------- signal myScans : decodedScans; -- the decoded scan begin -- simModel -- purpose: Resets jtag and then iterates through instructions and performs -- actions. -- type : combinational -- inputs : -- outputs: tck,tdi,tms simulate : process begin -- process simulate tck <= '1'; tdi <= '0'; tms <= '0'; myScans <= decode(sld_node_sim_action); wait for CLK_PERIOD; reset_jtag(myScans.scans(0).length, myScans.scans(0).idx_lsb,myScans.values,tck,tms,tdi); -- first instruction needs to be an IR intsruction. if (myScans.scans(0).scan_type /= V_IR_SCAN_TYPE) then message(FIRST_TYPE_ERROR,FAILURE); end if; for l in 0 to sld_node_n_scan - 1 loop wait for myScans.scans(l).scan_time; if (myScans.scans(l).scan_type = V_IR_SCAN_TYPE) then v_ir_scan(conv_integer(myScans.scans(l).length), myScans.scans(l).idx_lsb, myScans.scans(l).idx_msb, myScans.values, sld_node_ir_width - 4, jtag_usr1, tck, tms, tdi); -- do error checking for when length is not equal to SLD_NODE_IR_WIDTH if (conv_integer(myScans.scans(l).length) /= sld_node_ir_width) then message(LENGTH_ERROR,WARNING); end if; elsif (myScans.scans(l).scan_type = V_DR_SCAN_TYPE) then v_dr_scan(conv_integer(myScans.scans(l).length), myScans.scans(l).idx_lsb, myScans.scans(l).idx_msb, myScans.values, jtag_usr1, tck, tms, tdi); else message(TYPE_ERROR,ERROR); end if; end loop; -- l -- get into tlr state for i in 0 to 5 loop tms <= '1'; tck <= '0', '1' after clk_period/2; wait for clk_period; end loop; -- i wait; end process simulate; end simModel; ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.sld_node.all; ------------------------------------------------------------------------------- -- Entity Name : jtag_tap_controller -- -- Description : Behavioral model of JTAg tap controller with state signals -- -- Limitation : Can only decode USER1 and USER0 instructions -- -- Results Expected : -- -- ------------------------------------------------------------------------------- entity jtag_tap_controller is generic ( ir_register_width : integer); -- the width of the shift register port ( tck : in std_logic; -- tck signal from signal_gen tms : in std_logic; -- tms signal from signal_gen tdi : in std_logic; -- tdi signal from signal_gen jtag_tdo : in std_logic; -- tdo signal from hub tdo : out std_logic; -- tdo signal to signal_gen jtag_tck : out std_logic; -- tck signal from jtag jtag_tms : out std_logic; -- tms signal from jtag jtag_tdi : out std_logic; -- tdi signal from jtag jtag_state_tlr : out std_logic; -- tlr state jtag_state_rti : out std_logic; -- rti state jtag_state_drs : out std_logic; -- select dr scan state jtag_state_cdr : out std_logic; -- capture dr state jtag_state_sdr : out std_logic; -- shift dr state jtag_state_e1dr : out std_logic; -- exit1 dr state jtag_state_pdr : out std_logic; -- pause dr sart jtag_state_e2dr : out std_logic; -- exit2 dr state jtag_state_udr : out std_logic; -- update dr state jtag_state_irs : out std_logic; -- select ir scan state jtag_state_cir : out std_logic; -- capture ir state jtag_state_sir : out std_logic; -- shift ir state jtag_state_e1ir : out std_logic; -- exit1 ir state jtag_state_pir : out std_logic; -- pause ir state jtag_state_e2ir : out std_logic; -- exit2 ir state jtag_state_uir : out std_logic; -- update ir state jtag_usr1 : out std_logic); -- jtag has usr1 instruction end jtag_tap_controller; architecture FSM of jtag_tap_controller is type tap_states is (TLR_ST, RTI_ST, DRS_ST, CDR_ST, SDR_ST, E1DR_ST, PDR_ST, E2DR_ST, UDR_ST, IRS_ST, CIR_ST, SIR_ST, E1IR_ST, PIR_ST, E2IR_ST, UIR_ST); -- the tap states signal nState : tap_states; -- the next state signal signal cState : tap_states; -- the current state signal signal ir_srl : std_logic_vector(ir_register_width -1 downto 0); -- the shift register for the controller signal ir_srl_hold : std_logic_vector(ir_register_width -1 downto 0); -- the hold register for the controller signal jtag_usr1_c : std_logic; -- combinational usr1 signal signal jtag_usr1_r : std_logic; -- registered usr1 signal signal jtag_e1ir_i : std_logic; -- internal signal to tell enable hold part of ir shift register signal tdo_i : std_logic; -- internal signal for tdo signal tdo_i_c : std_logic; -- internal combinational signal for tdo signal jtag_reset_i : std_logic; -- internal reset signal that goes high when in TLR state begin -- FSM -- purpose: state transitions for the FSM -- type : combinational -- inputs : cState, tms -- outputs: nState stateTrans: process (cState, tms, jtag_usr1_r, ir_srl_hold) begin -- process stateTrans nState <= cState; jtag_e1ir_i <= '0'; jtag_state_tlr <= '0'; jtag_state_rti <= '0'; jtag_state_drs <= '0'; jtag_state_cdr <= '0'; jtag_state_sdr <= '0'; jtag_state_e1dr <= '0'; jtag_state_pdr <= '0'; jtag_state_e2dr <= '0'; jtag_state_udr <= '0'; jtag_state_irs <= '0'; jtag_state_cir <= '0'; jtag_state_sir <= '0'; jtag_state_e1ir <= '0'; jtag_state_pir <= '0'; jtag_state_e2ir <= '0'; jtag_state_uir <= '0'; jtag_reset_i <= '0'; jtag_usr1_c <= jtag_usr1_r; case cState is when TLR_ST => if (tms = '0') then nState <= RTI_ST; jtag_reset_i <= '0'; else jtag_reset_i <= '1'; end if; jtag_state_tlr <= '1'; jtag_usr1_c <= '0'; when RTI_ST => if (tms = '1') then nState <= DRS_ST; end if; jtag_state_rti <= '1'; when DRS_ST => if (tms = '1') then nState <= IRS_ST; else nState <= CDR_ST; end if; jtag_state_drs <= '1'; when CDR_ST => if (tms = '1') then nState <= E1DR_ST; else nState <= SDR_ST; end if; jtag_state_cdr <= '1'; when SDR_ST => if (tms = '1') then nState <= E1DR_ST; end if; jtag_state_sdr <= '1'; when E1DR_ST => if (tms = '1') then nState <= UDR_ST; else nState <= PDR_ST; end if; jtag_state_e1dr <= '1'; when PDR_ST => if (tms = '1') then nState <= E2DR_ST; end if; jtag_state_pdr <= '1'; when E2DR_ST => if (tms = '1') then nState <= UDR_ST; else nState <= SDR_ST; end if; jtag_state_e2dr <= '1'; when UDR_ST => if (tms = '1') then nState <= DRS_ST; else nState <= RTI_ST; end if; jtag_state_udr <= '1'; when IRS_ST => if (tms = '1') then nState <= TLR_ST; else nState <= CIR_ST; end if; jtag_state_irs <= '1'; when CIR_ST => if (tms = '1') then nState <= E1IR_ST; else nState <= SIR_ST; end if; jtag_state_cir <= '1'; when SIR_ST => if (tms = '1') then nState <= E1IR_ST; end if; jtag_state_sir <= '1'; when E1IR_ST => if (tms = '1') then nState <= UIR_ST; else nState <= PIR_ST; end if; jtag_state_e1ir <= '1'; jtag_e1ir_i <= '1'; when PIR_ST => if (tms = '1') then nState <= E2IR_ST; end if; jtag_state_pir <= '1'; when E2IR_ST => if (tms = '1') then nState <= UIR_ST; else nState <= SIR_ST; end if; jtag_state_e2ir <= '1'; when UIR_ST => if (tms = '1') then nState <= DRS_ST; else nState <= RTI_ST; end if; if (ir_srl_hold = JTAG_USR1_INSTR) then jtag_usr1_c <= '1'; else jtag_usr1_c <= '0'; end if; jtag_state_uir <= '1'; when others => null; end case; end process stateTrans; -- purpose: Regsiter for state machine and shift register -- type : sequential -- inputs : tck, jtag_reset_i -- outputs: cState, sr stateReg: process (tck, jtag_reset_i) begin -- process stateReg if jtag_reset_i = '1' then -- asynchronous reset (active high) cState <= TLR_ST; ir_srl <= (others =>'0'); jtag_usr1_r <= '0'; tdo_i <= '0'; tdo_i_c <= '0'; elsif tck'event and tck = '1' then -- rising clock edge cState <= nState; jtag_usr1_r <= jtag_usr1_c; if (cState = CIR_ST) then tdo_i_c <= '0'; -- so that we can generate 010101... -- during SIR elsif (cState = SIR_ST) then ir_srl(ir_register_width - 2 downto 0) <= ir_srl(ir_register_width - 1 downto 1); ir_srl(ir_register_width - 1) <= tdi; tdo_i_c <= not(tdo_i_c); tdo_i <= tdo_i_c; else tdo_i <= jtag_tdo; end if; end if; end process stateReg; jtag_usr1 <= jtag_usr1_r; tdo <= tdo_i; -- pipe through signals jtag_tck <= tck; jtag_tdi <= tdi; jtag_tms <= tms; -- purpose: hold register of shift register -- type : sequential -- inputs : tck, jtag_reset_i -- outputs: ir_srl_hold holdReg: process (tck, jtag_reset_i) begin -- process holdReg if jtag_reset_i = '1' then -- asynchronous reset (active high) ir_srl_hold <= (others => '0'); elsif tck'event and tck = '0' then -- falling clock edge if (jtag_e1ir_i = '1') then ir_srl_hold <= ir_srl; end if; end if; end process holdReg; end FSM; ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.sld_node.all; ------------------------------------------------------------------------------- -- Entity Name : dummy_hub -- -- Description : Acts as node and mux between the tap controller and -- user design. Generates hub signals -- -- Limitation : Assumes only one node. Ignores user input on tdo and ir_out. -- -- Results Expected : -- -- ------------------------------------------------------------------------------ entity dummy_hub is generic ( sld_node_ir_width : integer); -- the width of the ir registers port ( jtag_tck : in std_logic; -- tck signal from tap controller jtag_tdi : in std_logic; -- tdi signal from tap controller jtag_tms : in std_logic; -- tms signal from tap controller jtag_usr1 : in std_logic; -- usr1 signal from tap controller jtag_state_tlr : in std_logic; -- tlr state signal from tap controller jtag_state_rti : in std_logic; -- rti state signal from tap controller jtag_state_drs : in std_logic; -- drs state signal from tap controller jtag_state_cdr : in std_logic; -- cdr state signal from tap controller jtag_state_sdr : in std_logic; -- sdr state signal from tap controller jtag_state_e1dr : in std_logic; -- e1dr state signal from tap controller jtag_state_pdr : in std_logic; -- pdr state signal from tap controller jtag_state_e2dr : in std_logic; -- esdr state signal from tap controller jtag_state_udr : in std_logic; -- udr state signal from tap controller jtag_state_irs : in std_logic; -- irs state signal from tap controller jtag_state_cir : in std_logic; -- cir state signals from tap controller jtag_state_sir : in std_logic; -- sir state signal from tap controller jtag_state_e1ir : in std_logic; -- e1ir state signal from tap controller jtag_state_pir : in std_logic; -- pir state signals from tap controller jtag_state_e2ir : in std_logic; -- e2ir state signal from tap controller jtag_state_uir : in std_logic; -- uir state signal from tap controller dummy_tdo : in std_logic; -- tdo signal from world virtual_ir_out : in std_logic_vector(sld_node_ir_width - 1 downto 0); -- captures parallel input from -- user design jtag_tdo : out std_logic; -- tdo signal to tap controller dummy_tck : out std_logic; -- tck signal to world dummy_tdi : out std_logic; -- tdi signal to world dummy_tms : out std_logic; -- tms signal to world dummy_state_tlr : out std_logic; -- tlr state signal to world dummy_state_rti : out std_logic; -- rti state signal to world dummy_state_drs : out std_logic; -- drs state signal to world dummy_state_cdr : out std_logic; -- cdr state signal to world dummy_state_sdr : out std_logic; -- sdr state signal to world dummy_state_e1dr : out std_logic; -- e1dr state signal to the world dummy_state_pdr : out std_logic; -- pdr state signal to world dummy_state_e2dr : out std_logic; -- e2dr state signal to world dummy_state_udr : out std_logic; -- udr state signal to world dummy_state_irs : out std_logic; -- irs state signal to world dummy_state_cir : out std_logic; -- cir state signal to world dummy_state_sir : out std_logic; -- sir state signal to world dummy_state_e1ir : out std_logic; -- e1ir state signal to world dummy_state_pir : out std_logic; -- pir state signal to world dummy_state_e2ir : out std_logic; -- e2ir state signal to world dummy_state_uir : out std_logic; -- uir state signal to world virtual_state_cdr : out std_logic; -- virtual cdr state signal virtual_state_sdr : out std_logic; -- virtual sdr state signal virtual_state_e1dr : out std_logic; -- virtual e1dr state signal virtual_state_pdr : out std_logic; -- virtula pdr state signal virtual_state_e2dr : out std_logic; -- virtual e2dr state signal virtual_state_udr : out std_logic; -- virtual udr state signal virtual_state_cir : out std_logic; -- virtual cir state signal virtual_state_uir : out std_logic; -- virtual uir state signal virtual_ir_in : out std_logic_vector(sld_node_ir_width - 1 downto 0)); -- parallel output to user design end dummy_hub; architecture behavior of dummy_hub is constant SLD_NODE_IR_WIDTH_i : integer := sld_node_ir_width + NUM_SELECTION_BITS; -- the internal ir_width representation signal ir_srl : std_logic_vector(SLD_NODE_IR_WIDTH_i - 1 downto 0); -- ir shift register signal virtual_ir_in_i : std_logic_vector(SLD_NODE_IR_WIDTH_i - 1 downto 0); -- internal hold portion of ir shift register signal capture_ir : std_logic; -- signals a force_ir_capture begin -- behavior -- purpose: the register for the fsm and other registered data -- type : sequential -- inputs : tck, trst -- outputs: stateReg : process (jtag_tck,jtag_state_tlr) begin -- process stateReg if jtag_state_tlr = '1' then -- asynchronous reset (active high) ir_srl <= (others => '0'); jtag_tdo <= '0'; dummy_tdi <= '0'; capture_ir <= '0'; virtual_ir_in <= (others => '0'); elsif jtag_tck'event and jtag_tck = '1' then -- rising clock edge virtual_ir_in <= virtual_ir_in_i(SLD_NODE_IR_WIDTH_i - 2 downto NUM_SELECTION_BITS - 1); -- should check for 011 instruction -- but we know that it is the only instruction ever sent to the -- hub. So all we have to do is check the selection bit, udr and -- usr1 state if (jtag_state_udr = '1' and ir_srl(SLD_NODE_IR_WIDTH_i - 1) = '0') then capture_ir <= jtag_usr1; elsif (jtag_state_e1dr = '1') then capture_ir <= '0'; end if; if (jtag_usr1 = '1' and jtag_state_sdr = '1') then ir_srl(SLD_NODE_IR_WIDTH_i - 2 downto 0) <= ir_srl(SLD_NODE_IR_WIDTH_i - 1 downto 1); ir_srl(SLD_NODE_IR_WIDTH_i - 1) <= jtag_tdi; jtag_tdo <= ir_srl(0); elsif (capture_ir = '1' and jtag_state_cdr = '1') then ir_srl(SLD_NODE_IR_WIDTH_i - 2 downto NUM_SELECTION_BITS - 1) <= virtual_ir_out; elsif (capture_ir = '1' and jtag_state_sdr = '1') then ir_srl(SLD_NODE_IR_WIDTH_i - 2 downto 0) <= ir_srl(SLD_NODE_IR_WIDTH_i - 1 downto 1); ir_srl(SLD_NODE_IR_WIDTH_i - 1) <= jtag_tdi; jtag_tdo <= ir_srl(0); elsif (jtag_state_sdr = '1') then dummy_tdi <= jtag_tdi; jtag_tdo <= dummy_tdo; end if; end if; end process stateReg; -- pipe through signals dummy_state_tlr <= jtag_state_tlr; dummy_state_rti <= jtag_state_rti; dummy_state_drs <= jtag_state_drs; dummy_state_cdr <= jtag_state_cdr; dummy_state_sdr <= jtag_state_sdr; dummy_state_e1dr <= jtag_state_e1dr; dummy_state_pdr <= jtag_state_pdr; dummy_state_e2dr <= jtag_state_e2dr; dummy_state_udr <= jtag_state_udr; dummy_state_irs <= jtag_state_irs; dummy_state_cir <= jtag_state_cir; dummy_state_sir <= jtag_state_sir; dummy_state_e1ir <= jtag_state_e1ir; dummy_state_pir <= jtag_state_pir; dummy_state_e2ir <= jtag_state_e2ir; dummy_state_uir <= jtag_state_uir; dummy_tms <= jtag_tms; dummy_tck <= jtag_tck; -- virtual signals virtual_state_uir <= jtag_usr1 and jtag_state_udr and virtual_ir_in_i(SLD_NODE_IR_WIDTH_i - 1); virtual_state_cir <= jtag_usr1 and jtag_state_cdr and virtual_ir_in_i(SLD_NODE_IR_WIDTH_i - 1); virtual_state_udr <= not jtag_usr1 and jtag_state_udr and virtual_ir_in_i(SLD_NODE_IR_WIDTH_i - 1); virtual_state_e2dr <= not jtag_usr1 and jtag_state_e2dr and virtual_ir_in_i(SLD_NODE_IR_WIDTH_i - 1); virtual_state_pdr <= not jtag_usr1 and jtag_state_pdr and virtual_ir_in_i(SLD_NODE_IR_WIDTH_i - 1); virtual_state_e1dr <= not jtag_usr1 and jtag_state_e1dr and virtual_ir_in_i(SLD_NODE_IR_WIDTH_i - 1); virtual_state_sdr <= not jtag_usr1 and jtag_state_sdr and virtual_ir_in_i(SLD_NODE_IR_WIDTH_i - 1); virtual_state_cdr <= not jtag_usr1 and jtag_state_cdr and virtual_ir_in_i(SLD_NODE_IR_WIDTH_i - 1); -- purpose: captures the shift register during jtag_state_e1dr -- type : sequential -- inputs : jtag_tck, jtag_state_tlr -- outputs: virtual_ir_in SHIFT_REG_HOLD : process (jtag_tck, jtag_state_tlr) begin -- process SHIFT_REG_HOLD if jtag_state_tlr = '1' then -- asynchronous reset (active high) virtual_ir_in_i <= (others => '0'); elsif jtag_tck'event and jtag_tck = '0' then -- falling clock edge if (ir_srl(SLD_NODE_IR_WIDTH_i - 1) = '1' and jtag_state_e1dr = '1') then virtual_ir_in_i <= ir_srl; end if; end if; end process SHIFT_REG_HOLD; end behavior; ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.signal_gen; use work.jtag_tap_controller; use work.dummy_hub; ------------------------------------------------------------------------------- -- Entity Name : sld_virtual_jtag -- -- Description : Simulatiom model for SLD_VIRTUAL_JTAG megafunction -- -- Limitation : -- -- Results Expected : -- -- ------------------------------------------------------------------------------- entity sld_virtual_jtag is generic ( lpm_type : string := "SLD_VIRTUAL_JTAG"; -- required by coding standard lpm_hint : string := "SLD_VIRTUAL_JTAG"; -- required by coding standard sld_auto_instance_index : string := "NO"; -- Yes of auto index is desired and no otherwise sld_instance_index : integer := 0; -- Index to be used if SLD_AUTO_INSTANCE_INDEX is no sld_ir_width : integer := 1; -- the width of the IR register sld_sim_n_scan : integer := 0; -- the number of scans in the simulation model sld_sim_total_length : integer := 0; -- the total bit width of all DR scan values sld_sim_action : string := ""); -- the actions to be simulated in a format specified by the documentation port ( tdo : in std_logic := '0'; -- tdo signal into megafunction ir_out : in std_logic_vector(sld_ir_width - 1 downto 0) := (others => '0'); -- parallel ir data into megafunction tck : out std_logic; -- tck signal from megafunction tdi : out std_logic; -- tdi signal from megafunction ir_in : out std_logic_vector(sld_ir_width - 1 downto 0); -- paraller ir data from megafunction virtual_state_cdr : out std_logic; -- cdr state signal of megafunction virtual_state_sdr : out std_logic; -- sdr state signal of megafunction virtual_state_e1dr : out std_logic; -- e1dr state signal of megafunction virtual_state_pdr : out std_logic; -- pdr state signal of megafunction virtual_state_e2dr : out std_logic; -- e2dr state signal of megafunction virtual_state_udr : out std_logic; -- udr state signal of megafunction virtual_state_cir : out std_logic; -- cir state signal of megafunction virtual_state_uir : out std_logic; -- uir state signal of megafunction jtag_state_tlr : out std_logic; -- Test, Logic, Reset state jtag_state_rti : out std_logic; -- Run, Test, Idle state jtag_state_sdrs : out std_logic; -- Select DR scan state jtag_state_cdr : out std_logic; -- capture DR state jtag_state_sdr : out std_logic; -- Shift DR state jtag_state_e1dr : out std_logic; -- exit 1 dr state jtag_state_pdr : out std_logic; -- pause dr state jtag_state_e2dr : out std_logic; -- exit 2 dr state jtag_state_udr : out std_logic; -- update dr state jtag_state_sirs : out std_logic; -- Select IR scan state jtag_state_cir : out std_logic; -- capture IR state jtag_state_sir : out std_logic; -- shift IR state jtag_state_e1ir : out std_logic; -- exit 1 IR state jtag_state_pir : out std_logic; -- pause IR state jtag_state_e2ir : out std_logic; -- exit 2 IR state jtag_state_uir : out std_logic; -- update IR state tms : out std_logic); -- tms signal end sld_virtual_jtag; architecture structural of sld_virtual_jtag is component signal_gen generic ( sld_node_ir_width : integer; sld_node_n_scan : natural; sld_node_total_length : natural; sld_node_sim_action : string); port ( tck : out std_logic; tms : out std_logic; tdi : out std_logic; jtag_usr1 : in std_logic; tdo : in std_logic); end component; component jtag_tap_controller generic ( ir_register_width : integer); port ( tck : in std_logic; tms : in std_logic; tdi : in std_logic; jtag_tdo : in std_logic; tdo : out std_logic; jtag_tck : out std_logic; jtag_tms : out std_logic; jtag_tdi : out std_logic; jtag_state_tlr : out std_logic; jtag_state_rti : out std_logic; jtag_state_drs : out std_logic; jtag_state_cdr : out std_logic; jtag_state_sdr : out std_logic; jtag_state_e1dr : out std_logic; jtag_state_pdr : out std_logic; jtag_state_e2dr : out std_logic; jtag_state_udr : out std_logic; jtag_state_irs : out std_logic; jtag_state_cir : out std_logic; jtag_state_sir : out std_logic; jtag_state_e1ir : out std_logic; jtag_state_pir : out std_logic; jtag_state_e2ir : out std_logic; jtag_state_uir : out std_logic; jtag_usr1 : out std_logic); end component; component dummy_hub generic ( sld_node_ir_width : integer); port ( jtag_tck : in std_logic; jtag_tdi : in std_logic; jtag_tms : in std_logic; jtag_usr1 : in std_logic; jtag_state_tlr : in std_logic; jtag_state_rti : in std_logic; jtag_state_drs : in std_logic; jtag_state_cdr : in std_logic; jtag_state_sdr : in std_logic; jtag_state_e1dr : in std_logic; jtag_state_pdr : in std_logic; jtag_state_e2dr : in std_logic; jtag_state_udr : in std_logic; jtag_state_irs : in std_logic; jtag_state_cir : in std_logic; jtag_state_sir : in std_logic; jtag_state_e1ir : in std_logic; jtag_state_pir : in std_logic; jtag_state_e2ir : in std_logic; jtag_state_uir : in std_logic; dummy_tdo : in std_logic; virtual_ir_out : in std_logic_vector(sld_node_ir_width - 1 downto 0); jtag_tdo : out std_logic; dummy_tck : out std_logic; dummy_tdi : out std_logic; dummy_tms : out std_logic; dummy_state_tlr : out std_logic; dummy_state_rti : out std_logic; dummy_state_drs : out std_logic; dummy_state_cdr : out std_logic; dummy_state_sdr : out std_logic; dummy_state_e1dr : out std_logic; dummy_state_pdr : out std_logic; dummy_state_e2dr : out std_logic; dummy_state_udr : out std_logic; dummy_state_irs : out std_logic; dummy_state_cir : out std_logic; dummy_state_sir : out std_logic; dummy_state_e1ir : out std_logic; dummy_state_pir : out std_logic; dummy_state_e2ir : out std_logic; dummy_state_uir : out std_logic; virtual_state_cdr : out std_logic; virtual_state_sdr : out std_logic; virtual_state_e1dr : out std_logic; virtual_state_pdr : out std_logic; virtual_state_e2dr : out std_logic; virtual_state_udr : out std_logic; virtual_state_cir : out std_logic; virtual_state_uir : out std_logic; virtual_ir_in : out std_logic_vector(sld_node_ir_width - 1 downto 0)); end component; --------------------------------------------------------------------------- -- internal signals signal tck_i : std_logic; signal tms_i : std_logic; signal tdi_i : std_logic; signal tdo_i : std_logic; signal jtag_tdo_i : std_logic; signal jtag_tck_i : std_logic; signal jtag_tms_i : std_logic; signal jtag_tdi_i : std_logic; signal jtag_state_tlr_i : std_logic; signal jtag_state_rti_i : std_logic; signal jtag_state_drs_i : std_logic; signal jtag_state_cdr_i : std_logic; signal jtag_state_sdr_i : std_logic; signal jtag_state_e1dr_i : std_logic; signal jtag_state_pdr_i : std_logic; signal jtag_state_e2dr_i : std_logic; signal jtag_state_udr_i : std_logic; signal jtag_state_irs_i : std_logic; signal jtag_state_cir_i : std_logic; signal jtag_state_sir_i : std_logic; signal jtag_state_e1ir_i : std_logic; signal jtag_state_pir_i : std_logic; signal jtag_state_e2ir_i : std_logic; signal jtag_state_uir_i : std_logic; signal jtag_usr1_i : std_logic; constant ir_register_width : integer := 10; -- the width of the ir shift register begin -- structural user_input: signal_gen generic map ( sld_node_ir_width => sld_ir_width, sld_node_n_scan => sld_sim_n_scan, sld_node_total_length => sld_sim_total_length, sld_node_sim_action => sld_sim_action) port map ( tck => tck_i, tms => tms_i, tdi => tdi_i, jtag_usr1 => jtag_usr1_i, tdo => tdo_i); jtag : jtag_tap_controller generic map ( ir_register_width => ir_register_width) port map ( tck => tck_i, tms => tms_i, tdi => tdi_i, jtag_tdo => jtag_tdo_i, tdo => tdo_i, jtag_tck => jtag_tck_i, jtag_tms => jtag_tms_i, jtag_tdi => jtag_tdi_i, jtag_state_tlr => jtag_state_tlr_i, jtag_state_rti => jtag_state_rti_i, jtag_state_drs => jtag_state_drs_i, jtag_state_cdr => jtag_state_cdr_i, jtag_state_sdr => jtag_state_sdr_i, jtag_state_e1dr => jtag_state_e1dr_i, jtag_state_pdr => jtag_state_pdr_i, jtag_state_e2dr => jtag_state_e2dr_i, jtag_state_udr => jtag_state_udr_i, jtag_state_irs => jtag_state_irs_i, jtag_state_cir => jtag_state_cir_i, jtag_state_sir => jtag_state_sir_i, jtag_state_e1ir => jtag_state_e1ir_i, jtag_state_pir => jtag_state_pir_i, jtag_state_e2ir => jtag_state_e2ir_i, jtag_state_uir => jtag_state_uir_i, jtag_usr1 => jtag_usr1_i); hub: dummy_hub generic map ( sld_node_ir_width => sld_ir_width) port map ( jtag_tck => jtag_tck_i, jtag_tdi => jtag_tdi_i, jtag_tms => jtag_tms_i, jtag_usr1 => jtag_usr1_i, jtag_state_tlr => jtag_state_tlr_i, jtag_state_rti => jtag_state_rti_i, jtag_state_drs => jtag_state_drs_i, jtag_state_cdr => jtag_state_cdr_i, jtag_state_sdr => jtag_state_sdr_i, jtag_state_e1dr => jtag_state_e1dr_i, jtag_state_pdr => jtag_state_pdr_i, jtag_state_e2dr => jtag_state_e2dr_i, jtag_state_udr => jtag_state_udr_i, jtag_state_irs => jtag_state_irs_i, jtag_state_cir => jtag_state_cir_i, jtag_state_sir => jtag_state_sir_i, jtag_state_e1ir => jtag_state_e1ir_i, jtag_state_pir => jtag_state_pir_i, jtag_state_e2ir => jtag_state_e2ir_i, jtag_state_uir => jtag_state_uir_i, dummy_tdo => tdo, virtual_ir_out => ir_out, jtag_tdo => jtag_tdo_i, dummy_tck => tck, dummy_tdi => tdi, dummy_tms => tms, dummy_state_tlr => jtag_state_tlr, dummy_state_rti => jtag_state_rti, dummy_state_drs => jtag_state_sdrs, dummy_state_cdr => jtag_state_cdr, dummy_state_sdr => jtag_state_sdr, dummy_state_e1dr => jtag_state_e1dr, dummy_state_pdr => jtag_state_pdr, dummy_state_e2dr => jtag_state_e2dr, dummy_state_udr => jtag_state_udr, dummy_state_irs => jtag_state_sirs, dummy_state_cir => jtag_state_cir, dummy_state_sir => jtag_state_sir, dummy_state_e1ir => jtag_state_e1ir, dummy_state_pir => jtag_state_pir, dummy_state_e2ir => jtag_state_e2ir, dummy_state_uir => jtag_state_uir, virtual_state_cdr => virtual_state_cdr, virtual_state_sdr => virtual_state_sdr, virtual_state_e1dr => virtual_state_e1dr, virtual_state_pdr => virtual_state_pdr, virtual_state_e2dr => virtual_state_e2dr, virtual_state_udr => virtual_state_udr, virtual_state_cir => virtual_state_cir, virtual_state_uir => virtual_state_uir, virtual_ir_in => ir_in); end structural; library ieee; use ieee.std_logic_1164.all; use work.altera_mf_components.all; entity sld_signaltap is generic ( SLD_USE_JTAG_SIGNAL_ADAPTER : natural := 1; SLD_CURRENT_RESOURCE_WIDTH : natural := 0; SLD_INVERSION_MASK : std_logic_vector := "0"; SLD_POWER_UP_TRIGGER : natural := 0; SLD_ADVANCED_TRIGGER_6 : string := "NONE"; SLD_ADVANCED_TRIGGER_9 : string := "NONE"; SLD_ADVANCED_TRIGGER_7 : string := "NONE"; SLD_HPS_EVENT_ENABLED : natural := 0; SLD_STORAGE_QUALIFIER_ADVANCED_CONDITION_ENTITY : string := "basic"; SLD_STORAGE_QUALIFIER_GAP_RECORD : natural := 0; SLD_SECTION_ID : string := "hdl_signaltap_0"; SLD_INCREMENTAL_ROUTING : natural := 0; SLD_STORAGE_QUALIFIER_PIPELINE : natural := 0; SLD_TRIGGER_IN_ENABLED : natural := 0; SLD_STATE_BITS : natural := 11; SLD_HPS_EVENT_ID : natural := 0; SLD_CREATE_MONITOR_INTERFACE : natural := 0; SLD_STATE_FLOW_USE_GENERATED : natural := 0; SLD_INVERSION_MASK_LENGTH : integer := 1; SLD_DATA_BITS : natural := 1; SLD_BUFFER_FULL_STOP : natural := 1; SLD_STORAGE_QUALIFIER_INVERSION_MASK_LENGTH : natural := 0; SLD_ATTRIBUTE_MEM_MODE : string := "OFF"; SLD_STORAGE_QUALIFIER_MODE : string := "OFF"; SLD_STATE_FLOW_MGR_ENTITY : string := "state_flow_mgr_entity.vhd"; SLD_HPS_TRIGGER_IN_ENABLED : natural := 0; SLD_NODE_CRC_LOWORD : natural := 50132; SLD_ADVANCED_TRIGGER_5 : string := "NONE"; SLD_TRIGGER_BITS : natural := 1; SLD_STORAGE_QUALIFIER_BITS : natural := 1; SLD_HPS_TRIGGER_OUT_ENABLED : natural := 0; SLD_ADVANCED_TRIGGER_10 : string := "NONE"; SLD_MEM_ADDRESS_BITS : natural := 7; SLD_ADVANCED_TRIGGER_ENTITY : string := "basic"; SLD_ADVANCED_TRIGGER_4 : string := "NONE"; SLD_ADVANCED_TRIGGER_8 : string := "NONE"; SLD_TRIGGER_LEVEL : natural := 10; SLD_RAM_BLOCK_TYPE : string := "AUTO"; SLD_ADVANCED_TRIGGER_2 : string := "NONE"; SLD_ADVANCED_TRIGGER_1 : string := "NONE"; SLD_DATA_BIT_CNTR_BITS : natural := 4; SLD_SAMPLE_DEPTH : natural := 16; lpm_type : string := "sld_signaltap"; SLD_NODE_CRC_BITS : natural := 32; SLD_ENABLE_ADVANCED_TRIGGER : natural := 0; SLD_SEGMENT_SIZE : natural := 0; SLD_NODE_INFO : natural := 0; SLD_STORAGE_QUALIFIER_ENABLE_ADVANCED_CONDITION : natural := 0; SLD_NODE_CRC_HIWORD : natural := 41394; SLD_TRIGGER_LEVEL_PIPELINE : natural := 1; SLD_ADVANCED_TRIGGER_3 : string := "NONE" ); port ( jtag_state_sdr : in std_logic := '0'; ir_in : in std_logic_vector(SLD_IR_BITS-1 downto 0) := (others => '0'); acq_trigger_out : out std_logic_vector(SLD_TRIGGER_BITS-1 downto 0); gnd : out std_logic; jtag_state_cir : in std_logic := '0'; jtag_state_e2ir : in std_logic := '0'; jtag_state_pir : in std_logic := '0'; jtag_state_udr : in std_logic := '0'; vcc : out std_logic; jtag_state_e1dr : in std_logic := '0'; jtag_state_rti : in std_logic := '0'; jtag_state_e1ir : in std_logic := '0'; jtag_state_pdr : in std_logic := '0'; acq_clk : in std_logic; clr : in std_logic := '0'; trigger_in : in std_logic := '0'; ir_out : out std_logic_vector(SLD_IR_BITS-1 downto 0); jtag_state_sirs : in std_logic := '0'; jtag_state_cdr : in std_logic := '0'; jtag_state_sir : in std_logic := '0'; jtag_state_e2dr : in std_logic := '0'; tms : in std_logic := '0'; jtag_state_tlr : in std_logic := '0'; jtag_state_sdrs : in std_logic := '0'; tdi : in std_logic := '0'; jtag_state_uir : in std_logic := '0'; acq_trigger_in : in std_logic_vector(SLD_TRIGGER_BITS-1 downto 0) := (others => '0'); trigger_out : out std_logic; storage_enable : in std_logic := '0'; acq_data_out : out std_logic_vector(SLD_DATA_BITS-1 downto 0); acq_storage_qualifier_in : in std_logic_vector(SLD_STORAGE_QUALIFIER_BITS-1 downto 0) := (others => '0'); acq_data_in : in std_logic_vector(SLD_DATA_BITS-1 downto 0) := (others => '0'); tdo : out std_logic; crc : in std_logic_vector(SLD_NODE_CRC_BITS-1 downto 0) := (others => '0'); clrn : in std_logic := '0'; raw_tck : in std_logic := '0'; irq : out std_logic; usr1 : in std_logic := '0'; ena : in std_logic := '0' ); end sld_signaltap; architecture sim_sld_signaltap of sld_signaltap is begin end sim_sld_signaltap; library ieee; use ieee.std_logic_1164.all; use work.altera_mf_components.all; entity altstratixii_oct is generic ( lpm_type : string := "altstratixii_oct" ); port ( terminationenable : in std_logic; terminationclock : in std_logic; rdn : in std_logic; rup : in std_logic ); end altstratixii_oct; architecture sim_altstratixii_oct of altstratixii_oct is begin end sim_altstratixii_oct; library ieee; use ieee.std_logic_1164.all; use work.altera_mf_components.all; entity altparallel_flash_loader is generic ( flash_data_width : NATURAL := 16; dclk_create_delay : NATURAL := 0; flash_burst_extra_cycle : NATURAL := 0; safe_mode_retry : NATURAL := 1; us_unit_counter : NATURAL := 1; burst_mode_numonyx : NATURAL := 0; burst_mode : NATURAL := 0; clk_divisor : NATURAL := 1; addr_width : NATURAL := 20; tristate_checkbox : NATURAL := 0; nflash_mfc : STRING := "NUMONYX"; safe_mode_revert_addr : NATURAL := 0; flash_static_wait_width : NATURAL := 15; page_mode : NATURAL := 0; flash_ecc_checkbox : NATURAL := 0; features_pgm : NATURAL := 1; BURST_MODE_LATENCY_COUNT : NATURAL := 4; auto_restart : STRING := "OFF"; page_clk_divisor : NATURAL := 1; safe_mode_halt : NATURAL := 0; flash_nreset_counter : NATURAL := 1; normal_mode : NATURAL := 1; safe_mode_revert : NATURAL := 0; fifo_size : NATURAL := 16; nrb_addr : NATURAL := 65667072; nand_size : NATURAL := 67108864; dclk_divisor : NATURAL := 1; rsu_watchdog_counter : NATURAL := 100000000; flash_nreset_checkbox : NATURAL := 0; flash_type : STRING := "CFI_FLASH"; features_cfg : NATURAL := 1; burst_mode_intel : NATURAL := 0; extra_addr_byte : NATURAL := 0; qspi_data_delay : NATURAL := 0; option_bits_start_address : NATURAL := 0; pfl_rsu_watchdog_enabled : NATURAL := 0; qflash_fast_speed : NATURAL := 0; enhanced_flash_programming : NATURAL := 0; qspi_data_delay_count : NATURAL := 1; conf_wait_timer_width : NATURAL := 16; lpm_type : STRING := "ALTPARALLEL_FLASH_LOADER"; n_flash : NATURAL := 1; disable_crc_checkbox : NATURAL := 0; burst_mode_spansion : NATURAL := 0; qflash_mfc : STRING := "ALTERA"; decompressor_mode : STRING := "NONE"; conf_data_width : NATURAL := 1 ); port ( flash_nce : out std_logic_vector(n_flash-1 downto 0); fpga_data : out std_logic_vector(conf_data_width-1 downto 0); fpga_dclk : out std_logic; fpga_nstatus : in std_logic := '0'; flash_ale : out std_logic; pfl_clk : in std_logic := '0'; fpga_nconfig : out std_logic; flash_io2 : inout std_logic_vector(n_flash-1 downto 0); flash_sck : out std_logic_vector(n_flash-1 downto 0); flash_noe : out std_logic; flash_nwe : out std_logic; pfl_watchdog_error : out std_logic; pfl_reset_watchdog : in std_logic := '0'; fpga_conf_done : in std_logic := '0'; flash_rdy : in std_logic := '1'; pfl_flash_access_granted : in std_logic := '0'; pfl_nreconfigure : in std_logic := '1'; flash_cle : out std_logic; flash_nreset : out std_logic; flash_io0 : inout std_logic_vector(n_flash-1 downto 0); pfl_nreset : in std_logic := '0'; flash_data : inout std_logic_vector(flash_data_width-1 downto 0); flash_io1 : inout std_logic_vector(n_flash-1 downto 0); flash_nadv : out std_logic; flash_clk : out std_logic; flash_io3 : inout std_logic_vector(n_flash-1 downto 0); flash_io : inout std_logic_vector(7 downto 0); flash_addr : out std_logic_vector(addr_width-1 downto 0); pfl_flash_access_request : out std_logic; flash_ncs : out std_logic_vector(n_flash-1 downto 0); fpga_pgm : in std_logic_vector(2 downto 0) := (others => '0') ); end altparallel_flash_loader; architecture sim_altparallel_flash_loader of altparallel_flash_loader is begin end sim_altparallel_flash_loader; library ieee; use ieee.std_logic_1164.all; use work.altera_mf_components.all; entity altserial_flash_loader is generic ( enhanced_mode : natural := 0; intended_device_family : STRING := "Cyclone"; enable_shared_access : STRING := "OFF"; enable_quad_spi_support : natural := 0; ncso_width : natural := 1; lpm_type : STRING := "ALTSERIAL_FLASH_LOADER" ); port ( data_in : in std_logic_vector(3 downto 0) := (others => '0'); noe : in std_logic := '0'; asmi_access_granted : in std_logic := '1'; data_out : out std_logic_vector(3 downto 0); data_oe : in std_logic_vector(3 downto 0) := (others => '0'); sdoin : in std_logic := '0'; asmi_access_request : out std_logic; data0out : out std_logic; scein : in std_logic_vector(ncso_width-1 downto 0) := (others => '0'); dclkin : in std_logic := '0' ); end altserial_flash_loader; architecture sim_altserial_flash_loader of altserial_flash_loader is begin end sim_altserial_flash_loader; library ieee; use ieee.std_logic_1164.all; use work.altera_mf_components.all; entity sld_virtual_jtag_basic is generic ( lpm_hint : string := "UNUSED"; sld_sim_action : string := "UNUSED"; sld_instance_index : natural := 0; sld_ir_width : natural := 1; sld_sim_n_scan : natural := 0; sld_mfg_id : natural := 0; sld_version : natural := 0; sld_type_id : natural := 0; lpm_type : string := "sld_virtual_jtag_basic"; sld_auto_instance_index : string := "NO"; sld_sim_total_length : natural := 0 ); port ( jtag_state_sdr : out std_logic; jtag_state_sirs : out std_logic; ir_out : in std_logic_vector(sld_ir_width-1 downto 0); jtag_state_sir : out std_logic; jtag_state_cdr : out std_logic; jtag_state_e2dr : out std_logic; tms : out std_logic; jtag_state_sdrs : out std_logic; jtag_state_tlr : out std_logic; ir_in : out std_logic_vector(sld_ir_width-1 downto 0); virtual_state_sdr : out std_logic; tdi : out std_logic; jtag_state_uir : out std_logic; jtag_state_cir : out std_logic; virtual_state_cdr : out std_logic; virtual_state_uir : out std_logic; virtual_state_e2dr : out std_logic; jtag_state_e2ir : out std_logic; virtual_state_cir : out std_logic; jtag_state_pir : out std_logic; jtag_state_udr : out std_logic; virtual_state_udr : out std_logic; tdo : in std_logic; jtag_state_e1dr : out std_logic; jtag_state_rti : out std_logic; virtual_state_pdr : out std_logic; virtual_state_e1dr : out std_logic; jtag_state_e1ir : out std_logic; jtag_state_pdr : out std_logic; tck : out std_logic ); end sld_virtual_jtag_basic; architecture sim_sld_virtual_jtag_basic of sld_virtual_jtag_basic is begin end sim_sld_virtual_jtag_basic; library ieee; use ieee.std_logic_1164.all; use work.altera_mf_components.all; entity altsource_probe is generic ( lpm_hint : string := "UNUSED"; sld_instance_index : natural := 0; source_initial_value : string := "0"; sld_ir_width : natural := 4; probe_width : natural := 1; source_width : natural := 1; instance_id : string := "UNUSED"; lpm_type : string := "altsource_probe"; sld_auto_instance_index : string := "YES"; SLD_NODE_INFO : natural := 4746752; enable_metastability : string := "NO" ); port ( source_clk : in std_logic; probe : in std_logic_vector(probe_width-1 downto 0); source : out std_logic_vector(source_width-1 downto 0); source_ena : in std_logic ); end altsource_probe; architecture sim_altsource_probe of altsource_probe is begin end sim_altsource_probe;