Files
vhdl/Common/sim/altera/altera_mf.vhd
T
jens e919e0028e - added
git-svn-id: http://moon:8086/svn/vhdl/trunk@1095 cc03376c-175c-47c8-b038-4cd826a8556b
2015-05-16 17:25:11 +00:00

52597 lines
2.3 MiB
Plaintext

-- 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 <clk0_cycles_per_sync_period> 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 <clk1_cycles_per_sync_period> 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 <clk2_cycles_per_sync_period> 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 <extclk_cycles_per_sync_period> 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 (<alignment degree> * 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 = ( <alignment degree> * 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
-- (<alignment degree> * 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 = ( <alignment degree> * 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
-- (<alignment degree> * 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;