URL
https://opencores.org/ocsvn/aes-128-ecb-encoder/aes-128-ecb-encoder/trunk
Subversion Repositories aes-128-ecb-encoder
[/] [aes-128-ecb-encoder/] [trunk/] [fpga/] [aes128_ecb_2017/] [aes128_ecb.ip_user_files/] [ipstatic/] [hdl/] [axi_lite_ipif_v3_0_vh_rfs.vhd] - Rev 2
Compare with Previous | Blame | View Log
-- IPIF Common Library Package ------------------------------------------------------------------------------- -- -- ************************************************************************* -- ** ** -- ** DISCLAIMER OF LIABILITY ** -- ** ** -- ** This text/file contains proprietary, confidential ** -- ** information of Xilinx, Inc., is distributed under ** -- ** license from Xilinx, Inc., and may be used, copied ** -- ** and/or disclosed only pursuant to the terms of a valid ** -- ** license agreement with Xilinx, Inc. Xilinx hereby ** -- ** grants you a license to use this text/file solely for ** -- ** design, simulation, implementation and creation of ** -- ** design files limited to Xilinx devices or technologies. ** -- ** Use with non-Xilinx devices or technologies is expressly ** -- ** prohibited and immediately terminates your license unless ** -- ** covered by a separate agreement. ** -- ** ** -- ** Xilinx is providing this design, code, or information ** -- ** "as-is" solely for use in developing programs and ** -- ** solutions for Xilinx devices, with no obligation on the ** -- ** part of Xilinx to provide support. By providing this design, ** -- ** code, or information as one possible implementation of ** -- ** this feature, application or standard, Xilinx is making no ** -- ** representation that this implementation is free from any ** -- ** claims of infringement. You are responsible for obtaining ** -- ** any rights you may require for your implementation. ** -- ** Xilinx expressly disclaims any warranty whatsoever with ** -- ** respect to the adequacy of the implementation, including ** -- ** but not limited to any warranties or representations that this ** -- ** implementation is free from claims of infringement, implied ** -- ** warranties of merchantability or fitness for a particular ** -- ** purpose. ** -- ** ** -- ** Xilinx products are not intended for use in life support ** -- ** appliances, devices, or systems. Use in such applications is ** -- ** expressly prohibited. ** -- ** ** -- ** Any modifications that are made to the Source Code are ** -- ** done at the user’s sole risk and will be unsupported. ** -- ** The Xilinx Support Hotline does not have access to source ** -- ** code and therefore cannot answer specific questions related ** -- ** to source HDL. The Xilinx Hotline support of original source ** -- ** code IP shall only address issues and questions related ** -- ** to the standard Netlist version of the core (and thus ** -- ** indirectly, the original core source). ** -- ** ** -- ** Copyright (c) 2002-2010 Xilinx, Inc. All rights reserved. ** -- ** ** -- ** This copyright and support notice must be retained as part ** -- ** of this text at all times. ** -- ** ** -- ************************************************************************* -- ------------------------------------------------------------------------------- -- Filename: ipif_pkg.vhd -- Version: Intital -- Description: This file contains the constants and functions used in the -- ipif common library components. -- ------------------------------------------------------------------------------- -- Structure: -- ------------------------------------------------------------------------------- -- Author: DET -- History: -- DET 02/21/02 -- Created from proc_common_pkg.vhd -- -- DET 03/13/02 -- PLB IPIF development updates -- ^^^^^^ -- - Commented out string types and string functions due to an XST -- problem with string arrays and functions. THe string array -- processing functions were replaced with comperable functions -- operating on integer arrays. -- ~~~~~~ -- -- -- DET 4/30/2002 Initial -- ~~~~~~ -- - Added three functions: rebuild_slv32_array, rebuild_slv64_array, and -- rebuild_int_array to support removal of unused elements from the -- ARD arrays. -- ^^^^^^ -- -- -- FLO 8/12/2002 -- ~~~~~~ -- - Added three functions: bits_needed_for_vac, bits_needed_for_occ, -- and get_id_index_iboe. -- (Removed provisional functions bits_needed_for_vacancy, -- bits needed_for_occupancy, and bits_needed_for.) -- ^^^^^^ -- -- FLO 3/24/2003 -- ~~~~~~ -- - Added dependent property paramters for channelized DMA. -- - Added common property parameter array type. -- - Definded the KEYHOLD_BURST common-property parameter. -- ^^^^^^ -- -- FLO 10/22/2003 -- ~~~~~~ -- - Some adjustment to CHDMA parameterization. -- - Cleanup of obsolete code and comments. (The former "XST workaround" -- has become the officially deployed method.) -- ^^^^^^ -- -- LSS 03/24/2004 -- ~~~~~~ -- - Added 5 functions -- ^^^^^^ -- -- ALS 09/03/04 -- ^^^^^^ -- -- Added constants to describe the channel protocols used in MCH_OPB_IPIF -- ~~~~~~ -- -- DET 1/17/2008 v4_0 -- ~~~~~~ -- - Changed proc_common library version to v4_0 -- - Incorporated new disclaimer header -- ^^^^^^ -- ------------------------------------------------------------------------------- -- Naming Conventions: -- active low signals: "*_n" -- clock signals: "clk", "clk_div#", "clk_#x" -- reset signals: "rst", "rst_n" -- generics: "C_*" -- user defined types: "*_TYPE" -- state machine next state: "*_ns" -- state machine current state: "*_cs" -- combinatorial signals: "*_com" -- pipelined or register delay signals: "*_d#" -- counter signals: "*cnt*" -- clock enable signals: "*_ce" -- internal version of output port "*_i" -- device pins: "*_pin" -- ports: - Names begin with Uppercase -- processes: "*_PROCESS" -- component instantiations: "<ENTITY_>I_<#|FUNC> ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; -- need conversion function to convert reals/integers to std logic vectors use ieee.std_logic_arith.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; package ipif_pkg is ------------------------------------------------------------------------------- -- Type Declarations ------------------------------------------------------------------------------- type SLV32_ARRAY_TYPE is array (natural range <>) of std_logic_vector(0 to 31); subtype SLV64_TYPE is std_logic_vector(0 to 63); type SLV64_ARRAY_TYPE is array (natural range <>) of SLV64_TYPE; type INTEGER_ARRAY_TYPE is array (natural range <>) of integer; ------------------------------------------------------------------------------- -- Function and Procedure Declarations ------------------------------------------------------------------------------- function "=" (s1: in string; s2: in string) return boolean; function equaluseCase( str1, str2 : STRING ) RETURN BOOLEAN; function calc_num_ce (ce_num_array : INTEGER_ARRAY_TYPE) return integer; function calc_start_ce_index (ce_num_array : INTEGER_ARRAY_TYPE; index : integer) return integer; function get_min_dwidth (dwidth_array: INTEGER_ARRAY_TYPE) return integer; function get_max_dwidth (dwidth_array: INTEGER_ARRAY_TYPE) return integer; function S32 (in_string : string) return string; -------------------------------------------------------------------------------- -- ARD support functions. -- These function can be useful when operating with the ARD parameterization. -------------------------------------------------------------------------------- function get_id_index (id_array :INTEGER_ARRAY_TYPE; id : integer) return integer; function get_id_index_iboe (id_array :INTEGER_ARRAY_TYPE; id : integer) return integer; function find_ard_id (id_array : INTEGER_ARRAY_TYPE; id : integer) return boolean; function find_id_dwidth (id_array : INTEGER_ARRAY_TYPE; dwidth_array: INTEGER_ARRAY_TYPE; id : integer; default_i : integer) return integer; function cnt_ipif_id_blks (id_array : INTEGER_ARRAY_TYPE) return integer; function get_ipif_id_dbus_index (id_array : INTEGER_ARRAY_TYPE; id : integer) return integer ; function rebuild_slv32_array (slv32_array : SLV32_ARRAY_TYPE; num_valid_pairs : integer) return SLV32_ARRAY_TYPE; function rebuild_slv64_array (slv64_array : SLV64_ARRAY_TYPE; num_valid_pairs : integer) return SLV64_ARRAY_TYPE; function rebuild_int_array (int_array : INTEGER_ARRAY_TYPE; num_valid_entry : integer) return INTEGER_ARRAY_TYPE; -- 5 Functions Added 3/24/04 function populate_intr_mode_array (num_user_intr : integer; intr_capture_mode : integer) return INTEGER_ARRAY_TYPE ; function add_intr_ard_id_array(include_intr : boolean; ard_id_array : INTEGER_ARRAY_TYPE) return INTEGER_ARRAY_TYPE; function add_intr_ard_addr_range_array(include_intr : boolean; ZERO_ADDR_PAD : std_logic_vector; intr_baseaddr : std_logic_vector; intr_highaddr : std_logic_vector; ard_id_array : INTEGER_ARRAY_TYPE; ard_addr_range_array : SLV64_ARRAY_TYPE) return SLV64_ARRAY_TYPE; function add_intr_ard_num_ce_array(include_intr : boolean; ard_id_array : INTEGER_ARRAY_TYPE; ard_num_ce_array : INTEGER_ARRAY_TYPE) return INTEGER_ARRAY_TYPE; function add_intr_ard_dwidth_array(include_intr : boolean; intr_dwidth : integer; ard_id_array : INTEGER_ARRAY_TYPE; ard_dwidth_array : INTEGER_ARRAY_TYPE) return INTEGER_ARRAY_TYPE; function log2(x : natural) return integer; function clog2(x : positive) return natural; ------------------------------------------------------------------------------- -- Constant Declarations ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Channel Protocols -- The constant declarations below give symbolic-name aliases for values that -- can be used in the C_MCH_PROTOCOL_ARRAY generic of the MCH_OPB_IPIF. ------------------------------------------------------------------------------- constant XCL : integer := 0; constant DAG : integer := 1; -------------------------------------------------------------------------------- -- Address range types. -- The constant declarations, below, give symbolic-name aliases for values -- that can be used in the C_ARD_ID_ARRAY generic of IPIFs. The first set -- gives aliases that are used to include IPIF services. -------------------------------------------------------------------------------- -- IPIF module aliases Constant IPIF_INTR : integer := 1; Constant IPIF_RST : integer := 2; Constant IPIF_SESR_SEAR : integer := 3; Constant IPIF_DMA_SG : integer := 4; Constant IPIF_WRFIFO_REG : integer := 5; Constant IPIF_WRFIFO_DATA : integer := 6; Constant IPIF_RDFIFO_REG : integer := 7; Constant IPIF_RDFIFO_DATA : integer := 8; Constant IPIF_CHDMA_CHANNELS : integer := 9; Constant IPIF_CHDMA_GLOBAL_REGS : integer := 10; Constant CHDMA_STATUS_FIFO : integer := 90; -- Some predefined user module aliases Constant USER_00 : integer := 100; Constant USER_01 : integer := 101; Constant USER_02 : integer := 102; Constant USER_03 : integer := 103; Constant USER_04 : integer := 104; Constant USER_05 : integer := 105; Constant USER_06 : integer := 106; Constant USER_07 : integer := 107; Constant USER_08 : integer := 108; Constant USER_09 : integer := 109; Constant USER_10 : integer := 110; Constant USER_11 : integer := 111; Constant USER_12 : integer := 112; Constant USER_13 : integer := 113; Constant USER_14 : integer := 114; Constant USER_15 : integer := 115; Constant USER_16 : integer := 116; ---( Start of Dependent Properties declarations -------------------------------------------------------------------------------- -- Declarations for Dependent Properties (properties that depend on the type of -- the address range, or in other words, address-range-specific parameters). -- There is one property, i.e. one parameter, encoded as an integer at -- each index of the properties array. There is one properties array for -- each address range. -- -- The C_ARD_DEPENDENT_PROPS_ARRAY generic parameter in (most) IPIFs is such -- a properties array and it is usually giving its (static) value using a -- VHDL aggregate construct. (--ToDo, give an example of this.) -- -- The the "assigned" default value of a dependent property is zero. This value -- is usually specified the aggregate by leaving its (index) name out so that -- it is covered by an "others => 0" choice in the aggregate. Some parameters, -- as noted in the definitions, below, have an "effective" default value that is -- different from the assigned default value of zero. In such cases, the -- function, eff_dp, given below, can be used to get the effective value of -- the dependent property. -------------------------------------------------------------------------------- constant DEPENDENT_PROPS_SIZE : integer := 32; subtype DEPENDENT_PROPS_TYPE is INTEGER_ARRAY_TYPE(0 to DEPENDENT_PROPS_SIZE-1); type DEPENDENT_PROPS_ARRAY_TYPE is array (natural range <>) of DEPENDENT_PROPS_TYPE; -------------------------------------------------------------------------------- -- Below are the indices of dependent properties for the different types of -- address ranges. -- -- Example: Let C_ARD_DEPENDENT_PROPS_ARRAY hold the dependent properites -- for a set of address ranges. Then, e.g., -- -- C_ARD_DEPENDENT_PROPS_ARRAY(i)(FIFO_CAPACITY_BITS) -- -- gives the fifo capacity in bits, provided that the i'th address range -- is of type IPIF_WRFIFO_DATA or IPIF_RDFIFO_DATA. -- -- These indices should be referenced only by the names below and never -- by numerical literals. (The right to change numerical index assignments -- is reserved; applications using the names will not be affected by such -- reassignments.) -------------------------------------------------------------------------------- -- --ToDo, if the interrupt controller parameterization is ever moved to -- C_ARD_DEPENDENT_PROPS_ARRAY, then the following declarations -- could be uncommented and used. ---- IPIF_INTR IDX ---------------------------------------------------------------------------- --- constant EXCLUDE_DEV_ISC : integer := 0; -- 1 specifies that only the global interrupt -- enable is present in the device interrupt source -- controller and that the only source of interrupts -- in the device is the IP interrupt source controller. -- 0 specifies that the full device interrupt -- source controller structure will be included. constant INCLUDE_DEV_PENCODER : integer := 1; -- 1 will include the Device IID in the device interrupt -- source controller, 0 will exclude it. -- -- IPIF_WRFIFO_DATA or IPIF_RDFIFO_DATA IDX ---------------------------------------------------------------------------- --- constant FIFO_CAPACITY_BITS : integer := 0; constant WR_WIDTH_BITS : integer := 1; constant RD_WIDTH_BITS : integer := 2; constant EXCLUDE_PACKET_MODE : integer := 3; -- 1 Don't include packet mode features -- 0 Include packet mode features constant EXCLUDE_VACANCY : integer := 4; -- 1 Don't include vacancy calculation -- 0 Include vacancy calculation -- See also the functions -- bits_needed_for_vac and -- bits_needed_for_occ that are declared below. constant INCLUDE_DRE : integer := 5; constant INCLUDE_AUTOPUSH_POP : integer := 6; constant AUTOPUSH_POP_CE : integer := 7; constant INCLUDE_CSUM : integer := 8; -------------------------------------------------------------------------------- -- -- DMA_SG IDX ---------------------------------------------------------------------------- --- -------------------------------------------------------------------------------- -- IPIF_CHDMA_CHANNELS IDX ---------------------------------------------------------------------------- --- constant NUM_SUBS_FOR_PHYS_0 : integer :=0; constant NUM_SUBS_FOR_PHYS_1 : integer :=1; constant NUM_SUBS_FOR_PHYS_2 : integer :=2; constant NUM_SUBS_FOR_PHYS_3 : integer :=3; constant NUM_SUBS_FOR_PHYS_4 : integer :=4; constant NUM_SUBS_FOR_PHYS_5 : integer :=5; constant NUM_SUBS_FOR_PHYS_6 : integer :=6; constant NUM_SUBS_FOR_PHYS_7 : integer :=7; constant NUM_SUBS_FOR_PHYS_8 : integer :=8; constant NUM_SUBS_FOR_PHYS_9 : integer :=9; constant NUM_SUBS_FOR_PHYS_10 : integer :=10; constant NUM_SUBS_FOR_PHYS_11 : integer :=11; constant NUM_SUBS_FOR_PHYS_12 : integer :=12; constant NUM_SUBS_FOR_PHYS_13 : integer :=13; constant NUM_SUBS_FOR_PHYS_14 : integer :=14; constant NUM_SUBS_FOR_PHYS_15 : integer :=15; -- Gives the number of sub-channels for physical channel i. -- -- These constants, which will be MAX_NUM_PHYS_CHANNELS in number (see -- below), have consecutive values starting with 0 for -- NUM_SUBS_FOR_PHYS_0. (The constants serve the purpose of giving symbolic -- names for use in the dependent-properties aggregates that parameterize -- an IPIF_CHDMA_CHANNELS address range.) -- -- [Users can ignore this note for developers -- If the number of physical channels changes, both the -- IPIF_CHDMA_CHANNELS constants and MAX_NUM_PHYS_CHANNELS, -- below, must be adjusted. -- (Use of an array constant or a function of the form -- NUM_SUBS_FOR_PHYS(i) to define the indices -- runs afoul of LRM restrictions on non-locally static aggregate -- choices. (Further, the LRM imposes perhaps unnecessarily -- strict limits on what qualifies as a locally static primary.) -- Note: This information is supplied for the benefit of anyone seeking -- to improve the way that these NUM_SUBS_FOR_PHYS parameter -- indices are defined.) -- End of note for developers ] -- -- The value associated with any index NUM_SUBS_FOR_PHYS_i in the -- dependent-properties array must be even since TX and RX channels -- come in pairs with the TX followed immediately by -- the corresponding RX. -- constant NUM_SIMPLE_DMA_CHANS : integer :=16; -- The number of simple DMA channels. constant NUM_SIMPLE_SG_CHANS : integer :=17; -- The number of simple SG channels. constant INTR_COALESCE : integer :=18; -- 0 Interrupt coalescing is disabled -- 1 Interrupt coalescing is enabled constant CLK_PERIOD_PS : integer :=19; -- The period of the OPB Bus clock in ps. -- The default value of 0 is a special value that -- is synonymous with 10000 ps (10 ns). -- The value for CLK_PERIOD_PS is relevant only if (INTR_COALESCE = 1). constant PACKET_WAIT_UNIT_NS : integer :=20; -- Gives the unit for used for timing of pack-wait bounds. -- The default value of 0 is a special value that -- is synonymous with 1,000,000 ns (1 ms) and a non-default -- value is typically only used for testing. -- Relevant only if (INTR_COALESCE = 1). constant BURST_SIZE : integer :=21; -- 1, 2, 4, 8 or 16 -- The default value of 0 is a special value that -- is synonymous with a burst size of 16. -- Setting the BURST_SIZE to 1 effectively disables -- bursts. constant REMAINDER_AS_SINGLES : integer :=22; -- 0 Remainder handled as a short burst -- 1 Remainder handled as a series of singles -------------------------------------------------------------------------------- -- The constant below is not the index of a dependent-properties -- parameter (and, as such, would never appear as a choice in a -- dependent-properties aggregate). Rather, it is fixed to the maximum -- number of physical channels that an Address Range of type -- IPIF_CHDMA_CHANNELS supports. It must be maintained in conjuction with -- the constants named, e.g., NUM_SUBS_FOR_PHYS_15, above. -------------------------------------------------------------------------------- constant MAX_NUM_PHYS_CHANNELS : natural := 16; -------------------------------------------------------------------------- -- EXAMPLE: Here is an example dependent-properties aggregate for an -- address range of type IPIF_CHDMA_CHANNELS. -- To have a compact list of all of the CHDMA parameters, all are -- shown, however three are commented out and the unneeded -- MUM_SUBS_FOR_PHYS_x are excluded. The "OTHERS => 0" association -- gives these parameters their default values, such that, for the example -- -- - All physical channels above 2 have zero subchannels (effectively, -- these physical channels are not used) -- - There are no simple SG channels -- - The packet-wait time unit is 1 ms -- - Burst size is 16 -------------------------------------------------------------------------- -- ( -- NUM_SUBS_FOR_PHYS_0 => 8, -- NUM_SUBS_FOR_PHYS_1 => 4, -- NUM_SUBS_FOR_PHYS_2 => 14, -- NUM_SIMPLE_DMA_CHANS => 1, -- --NUM_SIMPLE_SG_CHANS => 5, -- INTR_COALESCE => 1, -- CLK_PERIOD_PS => 20000, -- --PACKET_WAIT_UNIT_NS => 50000, -- --BURST_SIZE => 1, -- REMAINDER_AS_SINGLES => 1, -- OTHERS => 0 -- ) -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Calculates the number of bits needed to convey the vacancy (emptiness) of -- the fifo described by dependent_props, if fifo_present. If not fifo_present, -- returns 0 (or the smallest value allowed by tool limitations on null arrays) -- without making reference to dependent_props. -------------------------------------------------------------------------------- function bits_needed_for_vac( fifo_present: boolean; dependent_props : DEPENDENT_PROPS_TYPE ) return integer; -------------------------------------------------------------------------------- -- Calculates the number of bits needed to convey the occupancy (fullness) of -- the fifo described by dependent_props, if fifo_present. If not fifo_present, -- returns 0 (or the smallest value allowed by tool limitations on null arrays) -- without making reference to dependent_props. -------------------------------------------------------------------------------- function bits_needed_for_occ( fifo_present: boolean; dependent_props : DEPENDENT_PROPS_TYPE ) return integer; -------------------------------------------------------------------------------- -- Function eff_dp. -- -- For some of the dependent properties, the default value of zero is meant -- to imply an effective default value of other than zero (see e.g. -- PKT_WAIT_UNIT_NS for the IPIF_CHDMA_CHANNELS address-range type). The -- following function is used to get the (possibly default-adjusted) -- value for a dependent property. -- -- Example call: -- -- eff_value_of_param := -- eff_dp( -- C_IPIF_CHDMA_CHANNELS, -- PACKET_WAIT_UNIT_NS, -- C_ARD_DEPENDENT_PROPS_ARRAY(i)(PACKET_WAIT_UNIT_NS) -- ); -- -- where C_ARD_DEPENDENT_PROPS_ARRAY(i) is an object of type -- DEPENDENT_PROPS_ARRAY_TYPE, that was parameterized for an address range of -- type C_IPIF_CHDMA_CHANNELS. -------------------------------------------------------------------------------- function eff_dp(id : integer; -- The type of address range. dep_prop : integer; -- The index of the dependent prop. value : integer -- The value at that index. ) return integer; -- The effective value, possibly adjusted -- if value has the default value of 0. ---) End of Dependent Properties declarations -------------------------------------------------------------------------------- -- Declarations for Common Properties (properties that apply regardless of the -- type of the address range). Structurally, these work the same as -- the dependent properties. -------------------------------------------------------------------------------- constant COMMON_PROPS_SIZE : integer := 2; subtype COMMON_PROPS_TYPE is INTEGER_ARRAY_TYPE(0 to COMMON_PROPS_SIZE-1); type COMMON_PROPS_ARRAY_TYPE is array (natural range <>) of COMMON_PROPS_TYPE; -------------------------------------------------------------------------------- -- Below are the indices of the common properties. -- -- These indices should be referenced only by the names below and never -- by numerical literals. -- IDX ---------------------------------------------------------------------------- --- constant KEYHOLE_BURST : integer := 0; -- 1 All addresses of a burst are forced to the initial -- address of the burst. -- 0 Burst addresses follow the bus protocol. -- IP interrupt mode array constants Constant INTR_PASS_THRU : integer := 1; Constant INTR_PASS_THRU_INV : integer := 2; Constant INTR_REG_EVENT : integer := 3; Constant INTR_REG_EVENT_INV : integer := 4; Constant INTR_POS_EDGE_DETECT : integer := 5; Constant INTR_NEG_EDGE_DETECT : integer := 6; end ipif_pkg; package body ipif_pkg is ------------------------------------------------------------------------------- -- Function log2 -- returns number of bits needed to encode x choices -- x = 0 returns 0 -- x = 1 returns 0 -- x = 2 returns 1 -- x = 4 returns 2, etc. ------------------------------------------------------------------------------- -- function log2(x : natural) return integer is variable i : integer := 0; variable val: integer := 1; begin if x = 0 then return 0; else for j in 0 to 29 loop -- for loop for XST if val >= x then null; else i := i+1; val := val*2; end if; end loop; -- Fix per CR520627 XST was ignoring this anyway and printing a -- Warning in SRP file. This will get rid of the warning and not -- impact simulation. -- synthesis translate_off assert val >= x report "Function log2 received argument larger" & " than its capability of 2^30. " severity failure; -- synthesis translate_on return i; end if; end function log2; -------------------------------------------------------------------------------- -- Function clog2 - returns the integer ceiling of the base 2 logarithm of x, -- i.e., the least integer greater than or equal to log2(x). -------------------------------------------------------------------------------- function clog2(x : positive) return natural is variable r : natural := 0; variable rp : natural := 1; -- rp tracks the value 2**r begin while rp < x loop -- Termination condition T: x <= 2**r -- Loop invariant L: 2**(r-1) < x r := r + 1; if rp > integer'high - rp then exit; end if; -- If doubling rp overflows -- the integer range, the doubled value would exceed x, so safe to exit. rp := rp + rp; end loop; -- L and T <-> 2**(r-1) < x <= 2**r <-> (r-1) < log2(x) <= r return r; -- end clog2; ------------------------------------------------------------------------------- -- Function Definitions ------------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Function "=" -- -- This function can be used to overload the "=" operator when comparing -- strings. ----------------------------------------------------------------------------- function "=" (s1: in string; s2: in string) return boolean is constant tc: character := ' '; -- string termination character variable i: integer := 1; variable v1 : string(1 to s1'length) := s1; variable v2 : string(1 to s2'length) := s2; begin while (i <= v1'length) and (v1(i) /= tc) and (i <= v2'length) and (v2(i) /= tc) and (v1(i) = v2(i)) loop i := i+1; end loop; return ((i > v1'length) or (v1(i) = tc)) and ((i > v2'length) or (v2(i) = tc)); end; ---------------------------------------------------------------------------- -- Function equaluseCase -- -- This function returns true if case sensitive string comparison determines -- that str1 and str2 are the same. ----------------------------------------------------------------------------- FUNCTION equaluseCase( str1, str2 : STRING ) RETURN BOOLEAN IS CONSTANT len1 : INTEGER := str1'length; CONSTANT len2 : INTEGER := str2'length; VARIABLE equal : BOOLEAN := TRUE; BEGIN IF NOT (len1=len2) THEN equal := FALSE; ELSE FOR i IN str1'range LOOP IF NOT (str1(i) = str2(i)) THEN equal := FALSE; END IF; END LOOP; END IF; RETURN equal; END equaluseCase; ----------------------------------------------------------------------------- -- Function calc_num_ce -- -- This function is used to process the array specifying the number of Chip -- Enables required for a Base Address specification. The array is input to -- the function and an integer is returned reflecting the total number of -- Chip Enables required for the CE, RdCE, and WrCE Buses ----------------------------------------------------------------------------- function calc_num_ce (ce_num_array : INTEGER_ARRAY_TYPE) return integer is Variable ce_num_sum : integer := 0; begin for i in 0 to (ce_num_array'length)-1 loop ce_num_sum := ce_num_sum + ce_num_array(i); End loop; return(ce_num_sum); end function calc_num_ce; ----------------------------------------------------------------------------- -- Function calc_start_ce_index -- -- This function is used to process the array specifying the number of Chip -- Enables required for a Base Address specification. The CE Size array is -- input to the function and an integer index representing the index of the -- target module in the ce_num_array. An integer is returned reflecting the -- starting index of the assigned Chip Enables within the CE, RdCE, and -- WrCE Buses. ----------------------------------------------------------------------------- function calc_start_ce_index (ce_num_array : INTEGER_ARRAY_TYPE; index : integer) return integer is Variable ce_num_sum : integer := 0; begin If (index = 0) Then ce_num_sum := 0; else for i in 0 to index-1 loop ce_num_sum := ce_num_sum + ce_num_array(i); End loop; End if; return(ce_num_sum); end function calc_start_ce_index; ----------------------------------------------------------------------------- -- Function get_min_dwidth -- -- This function is used to process the array specifying the data bus width -- for each of the target modules. The dwidth_array is input to the function -- and an integer is returned that is the smallest value found of all the -- entries in the array. ----------------------------------------------------------------------------- function get_min_dwidth (dwidth_array: INTEGER_ARRAY_TYPE) return integer is Variable temp_min : Integer := 1024; begin for i in 0 to dwidth_array'length-1 loop If (dwidth_array(i) < temp_min) Then temp_min := dwidth_array(i); else null; End if; End loop; return(temp_min); end function get_min_dwidth; ----------------------------------------------------------------------------- -- Function get_max_dwidth -- -- This function is used to process the array specifying the data bus width -- for each of the target modules. The dwidth_array is input to the function -- and an integer is returned that is the largest value found of all the -- entries in the array. ----------------------------------------------------------------------------- function get_max_dwidth (dwidth_array: INTEGER_ARRAY_TYPE) return integer is Variable temp_max : Integer := 0; begin for i in 0 to dwidth_array'length-1 loop If (dwidth_array(i) > temp_max) Then temp_max := dwidth_array(i); else null; End if; End loop; return(temp_max); end function get_max_dwidth; ----------------------------------------------------------------------------- -- Function S32 -- -- This function is used to expand an input string to 32 characters by -- padding with spaces. If the input string is larger than 32 characters, -- it will truncate to 32 characters. ----------------------------------------------------------------------------- function S32 (in_string : string) return string is constant OUTPUT_STRING_LENGTH : integer := 32; Constant space : character := ' '; variable new_string : string(1 to 32); Variable start_index : Integer := in_string'length+1; begin If (in_string'length < OUTPUT_STRING_LENGTH) Then for i in 1 to in_string'length loop new_string(i) := in_string(i); End loop; for j in start_index to OUTPUT_STRING_LENGTH loop new_string(j) := space; End loop; else -- use first 32 chars of in_string (truncate the rest) for k in 1 to OUTPUT_STRING_LENGTH loop new_string(k) := in_string(k); End loop; End if; return(new_string); end function S32; ----------------------------------------------------------------------------- -- Function get_id_index -- -- This function is used to process the array specifying the target function -- assigned to a Base Address pair address range. The id_array and a -- id number is input to the function. A integer is returned reflecting the -- array index of the id matching the id input number. This function -- should only be called if the id number is known to exist in the -- name_array input. This can be detirmined by using the find_ard_id -- function. ----------------------------------------------------------------------------- function get_id_index (id_array :INTEGER_ARRAY_TYPE; id : integer) return integer is Variable match : Boolean := false; Variable match_index : Integer := 10000; -- a really big number! begin for array_index in 0 to id_array'length-1 loop If (match = true) Then -- match already found so do nothing null; else -- compare the numbers one by one match := (id_array(array_index) = id); If (match) Then match_index := array_index; else null; End if; End if; End loop; return(match_index); end function get_id_index; -------------------------------------------------------------------------------- -- get_id_index but return a value in bounds on error (iboe). -- -- This function is the same as get_id_index, except that when id does -- not exist in id_array, the value returned is any index that is -- within the index range of id_array. -- -- This function would normally only be used where function find_ard_id -- is used to establish the existence of id but, even when non-existent, -- an element of one of the ARD arrays will be computed from the -- returned get_id_index_iboe value. See, e.g., function bits_needed_for_vac -- and the example call, below -- -- bits_needed_for_vac( -- find_ard_id(C_ARD_ID_ARRAY, IPIF_RDFIFO_DATA), -- C_ARD_DEPENDENT_PROPS_ARRAY(get_id_index_iboe(C_ARD_ID_ARRAY, -- IPIF_RDFIFO_DATA)) -- ) -------------------------------------------------------------------------------- function get_id_index_iboe (id_array :INTEGER_ARRAY_TYPE; id : integer) return integer is Variable match : Boolean := false; Variable match_index : Integer := id_array'left; -- any valid array index begin for array_index in 0 to id_array'length-1 loop If (match = true) Then -- match already found so do nothing null; else -- compare the numbers one by one match := (id_array(array_index) = id); If (match) Then match_index := array_index; else null; End if; End if; End loop; return(match_index); end function get_id_index_iboe; ----------------------------------------------------------------------------- -- Function find_ard_id -- -- This function is used to process the array specifying the target function -- assigned to a Base Address pair address range. The id_array and a -- integer id is input to the function. A boolean is returned reflecting the -- presence (or not) of a number in the array matching the id input number. ----------------------------------------------------------------------------- function find_ard_id (id_array : INTEGER_ARRAY_TYPE; id : integer) return boolean is Variable match : Boolean := false; begin for array_index in 0 to id_array'length-1 loop If (match = true) Then -- match already found so do nothing null; else -- compare the numbers one by one match := (id_array(array_index) = id); End if; End loop; return(match); end function find_ard_id; ----------------------------------------------------------------------------- -- Function find_id_dwidth -- -- This function is used to find the data width of a target module. If the -- target module exists, the data width is extracted from the input dwidth -- array. If the module is not in the ID array, the default input is -- returned. This function is needed to assign data port size constraints on -- unconstrained port widths. ----------------------------------------------------------------------------- function find_id_dwidth (id_array : INTEGER_ARRAY_TYPE; dwidth_array: INTEGER_ARRAY_TYPE; id : integer; default_i : integer) return integer is Variable id_present : Boolean := false; Variable array_index : Integer := 0; Variable dwidth : Integer := default_i; begin id_present := find_ard_id(id_array, id); If (id_present) Then array_index := get_id_index (id_array, id); dwidth := dwidth_array(array_index); else null; -- use default input End if; Return (dwidth); end function find_id_dwidth; ----------------------------------------------------------------------------- -- Function cnt_ipif_id_blks -- -- This function is used to detirmine the number of IPIF components specified -- in the ARD ID Array. An integer is returned representing the number -- of elements counted. User IDs are ignored in the counting process. ----------------------------------------------------------------------------- function cnt_ipif_id_blks (id_array : INTEGER_ARRAY_TYPE) return integer is Variable blk_count : integer := 0; Variable temp_id : integer; begin for array_index in 0 to id_array'length-1 loop temp_id := id_array(array_index); If (temp_id = IPIF_WRFIFO_DATA or temp_id = IPIF_RDFIFO_DATA or temp_id = IPIF_RST or temp_id = IPIF_INTR or temp_id = IPIF_DMA_SG or temp_id = IPIF_SESR_SEAR ) Then -- IPIF block found blk_count := blk_count+1; else -- go to next loop iteration null; End if; End loop; return(blk_count); end function cnt_ipif_id_blks; ----------------------------------------------------------------------------- -- Function get_ipif_id_dbus_index -- -- This function is used to detirmine the IPIF relative index of a given -- ID value. User IDs are ignored in the index detirmination. ----------------------------------------------------------------------------- function get_ipif_id_dbus_index (id_array : INTEGER_ARRAY_TYPE; id : integer) return integer is Variable blk_index : integer := 0; Variable temp_id : integer; Variable id_found : Boolean := false; begin for array_index in 0 to id_array'length-1 loop temp_id := id_array(array_index); If (id_found) then null; elsif (temp_id = id) then id_found := true; elsif (temp_id = IPIF_WRFIFO_DATA or temp_id = IPIF_RDFIFO_DATA or temp_id = IPIF_RST or temp_id = IPIF_INTR or temp_id = IPIF_DMA_SG or temp_id = IPIF_SESR_SEAR ) Then -- IPIF block found blk_index := blk_index+1; else -- user block so do nothing null; End if; End loop; return(blk_index); end function get_ipif_id_dbus_index; ------------------------------------------------------------------------------ -- Function: rebuild_slv32_array -- -- Description: -- This function takes an input slv32 array and rebuilds an output slv32 -- array composed of the first "num_valid_entry" elements from the input -- array. ------------------------------------------------------------------------------ function rebuild_slv32_array (slv32_array : SLV32_ARRAY_TYPE; num_valid_pairs : integer) return SLV32_ARRAY_TYPE is --Constants constant num_elements : Integer := num_valid_pairs * 2; -- Variables variable temp_baseaddr32_array : SLV32_ARRAY_TYPE( 0 to num_elements-1); begin for array_index in 0 to num_elements-1 loop temp_baseaddr32_array(array_index) := slv32_array(array_index); end loop; return(temp_baseaddr32_array); end function rebuild_slv32_array; ------------------------------------------------------------------------------ -- Function: rebuild_slv64_array -- -- Description: -- This function takes an input slv64 array and rebuilds an output slv64 -- array composed of the first "num_valid_entry" elements from the input -- array. ------------------------------------------------------------------------------ function rebuild_slv64_array (slv64_array : SLV64_ARRAY_TYPE; num_valid_pairs : integer) return SLV64_ARRAY_TYPE is --Constants constant num_elements : Integer := num_valid_pairs * 2; -- Variables variable temp_baseaddr64_array : SLV64_ARRAY_TYPE( 0 to num_elements-1); begin for array_index in 0 to num_elements-1 loop temp_baseaddr64_array(array_index) := slv64_array(array_index); end loop; return(temp_baseaddr64_array); end function rebuild_slv64_array; ------------------------------------------------------------------------------ -- Function: rebuild_int_array -- -- Description: -- This function takes an input integer array and rebuilds an output integer -- array composed of the first "num_valid_entry" elements from the input -- array. ------------------------------------------------------------------------------ function rebuild_int_array (int_array : INTEGER_ARRAY_TYPE; num_valid_entry : integer) return INTEGER_ARRAY_TYPE is -- Variables variable temp_int_array : INTEGER_ARRAY_TYPE( 0 to num_valid_entry-1); begin for array_index in 0 to num_valid_entry-1 loop temp_int_array(array_index) := int_array(array_index); end loop; return(temp_int_array); end function rebuild_int_array; function bits_needed_for_vac( fifo_present: boolean; dependent_props : DEPENDENT_PROPS_TYPE ) return integer is begin if not fifo_present then return 1; -- Zero would be better but leads to "0 to -1" null -- ranges that are not handled by XST Flint or earlier -- because of the negative index. else return log2(1 + dependent_props(FIFO_CAPACITY_BITS) / dependent_props(RD_WIDTH_BITS) ); end if; end function bits_needed_for_vac; function bits_needed_for_occ( fifo_present: boolean; dependent_props : DEPENDENT_PROPS_TYPE ) return integer is begin if not fifo_present then return 1; -- Zero would be better but leads to "0 to -1" null -- ranges that are not handled by XST Flint or earlier -- because of the negative index. else return log2(1 + dependent_props(FIFO_CAPACITY_BITS) / dependent_props(WR_WIDTH_BITS) ); end if; end function bits_needed_for_occ; function eff_dp(id : integer; dep_prop : integer; value : integer) return integer is variable dp : integer := dep_prop; type bo2na_type is array (boolean) of natural; constant bo2na : bo2na_type := (0, 1); begin if value /= 0 then return value; end if; -- Not default case id is when IPIF_CHDMA_CHANNELS => ------------------- return( bo2na(dp = CLK_PERIOD_PS ) * 10000 + bo2na(dp = PACKET_WAIT_UNIT_NS ) * 1000000 + bo2na(dp = BURST_SIZE ) * 16 ); when others => return 0; end case; end eff_dp; function populate_intr_mode_array (num_user_intr : integer; intr_capture_mode : integer) return INTEGER_ARRAY_TYPE is variable intr_mode_array : INTEGER_ARRAY_TYPE(0 to num_user_intr-1); begin for i in 0 to num_user_intr-1 loop intr_mode_array(i) := intr_capture_mode; end loop; return intr_mode_array; end function populate_intr_mode_array; function add_intr_ard_id_array(include_intr : boolean; ard_id_array : INTEGER_ARRAY_TYPE) return INTEGER_ARRAY_TYPE is variable intr_ard_id_array : INTEGER_ARRAY_TYPE(0 to ard_id_array'length); begin intr_ard_id_array(0 to ard_id_array'length-1) := ard_id_array; if include_intr then intr_ard_id_array(ard_id_array'length) := IPIF_INTR; return intr_ard_id_array; else return ard_id_array; end if; end function add_intr_ard_id_array; function add_intr_ard_addr_range_array(include_intr : boolean; ZERO_ADDR_PAD : std_logic_vector; intr_baseaddr : std_logic_vector; intr_highaddr : std_logic_vector; ard_id_array : INTEGER_ARRAY_TYPE; ard_addr_range_array : SLV64_ARRAY_TYPE) return SLV64_ARRAY_TYPE is variable intr_ard_addr_range_array : SLV64_ARRAY_TYPE(0 to ard_addr_range_array'length+1); begin intr_ard_addr_range_array(0 to ard_addr_range_array'length-1) := ard_addr_range_array; if include_intr then intr_ard_addr_range_array(2*get_id_index(ard_id_array,IPIF_INTR)) := ZERO_ADDR_PAD & intr_baseaddr; intr_ard_addr_range_array(2*get_id_index(ard_id_array,IPIF_INTR)+1) := ZERO_ADDR_PAD & intr_highaddr; return intr_ard_addr_range_array; else return ard_addr_range_array; end if; end function add_intr_ard_addr_range_array; function add_intr_ard_dwidth_array(include_intr : boolean; intr_dwidth : integer; ard_id_array : INTEGER_ARRAY_TYPE; ard_dwidth_array : INTEGER_ARRAY_TYPE) return INTEGER_ARRAY_TYPE is variable intr_ard_dwidth_array : INTEGER_ARRAY_TYPE(0 to ard_dwidth_array'length); begin intr_ard_dwidth_array(0 to ard_dwidth_array'length-1) := ard_dwidth_array; if include_intr then intr_ard_dwidth_array(get_id_index(ard_id_array, IPIF_INTR)) := intr_dwidth; return intr_ard_dwidth_array; else return ard_dwidth_array; end if; end function add_intr_ard_dwidth_array; function add_intr_ard_num_ce_array(include_intr : boolean; ard_id_array : INTEGER_ARRAY_TYPE; ard_num_ce_array : INTEGER_ARRAY_TYPE) return INTEGER_ARRAY_TYPE is variable intr_ard_num_ce_array : INTEGER_ARRAY_TYPE(0 to ard_num_ce_array'length); begin intr_ard_num_ce_array(0 to ard_num_ce_array'length-1) := ard_num_ce_array; if include_intr then intr_ard_num_ce_array(get_id_index(ard_id_array, IPIF_INTR)) := 16; return intr_ard_num_ce_array; else return ard_num_ce_array; end if; end function add_intr_ard_num_ce_array; end package body ipif_pkg; -- pselect_f.vhd - entity/architecture pair ------------------------------------------------------------------------------- -- -- ************************************************************************* -- ** ** -- ** DISCLAIMER OF LIABILITY ** -- ** ** -- ** This text/file contains proprietary, confidential ** -- ** information of Xilinx, Inc., is distributed under ** -- ** license from Xilinx, Inc., and may be used, copied ** -- ** and/or disclosed only pursuant to the terms of a valid ** -- ** license agreement with Xilinx, Inc. Xilinx hereby ** -- ** grants you a license to use this text/file solely for ** -- ** design, simulation, implementation and creation of ** -- ** design files limited to Xilinx devices or technologies. ** -- ** Use with non-Xilinx devices or technologies is expressly ** -- ** prohibited and immediately terminates your license unless ** -- ** covered by a separate agreement. ** -- ** ** -- ** Xilinx is providing this design, code, or information ** -- ** "as-is" solely for use in developing programs and ** -- ** solutions for Xilinx devices, with no obligation on the ** -- ** part of Xilinx to provide support. By providing this design, ** -- ** code, or information as one possible implementation of ** -- ** this feature, application or standard, Xilinx is making no ** -- ** representation that this implementation is free from any ** -- ** claims of infringement. You are responsible for obtaining ** -- ** any rights you may require for your implementation. ** -- ** Xilinx expressly disclaims any warranty whatsoever with ** -- ** respect to the adequacy of the implementation, including ** -- ** but not limited to any warranties or representations that this ** -- ** implementation is free from claims of infringement, implied ** -- ** warranties of merchantability or fitness for a particular ** -- ** purpose. ** -- ** ** -- ** Xilinx products are not intended for use in life support ** -- ** appliances, devices, or systems. Use in such applications is ** -- ** expressly prohibited. ** -- ** ** -- ** Any modifications that are made to the Source Code are ** -- ** done at the user’s sole risk and will be unsupported. ** -- ** The Xilinx Support Hotline does not have access to source ** -- ** code and therefore cannot answer specific questions related ** -- ** to source HDL. The Xilinx Hotline support of original source ** -- ** code IP shall only address issues and questions related ** -- ** to the standard Netlist version of the core (and thus ** -- ** indirectly, the original core source). ** -- ** ** -- ** Copyright (c) 2008-2010 Xilinx, Inc. All rights reserved. ** -- ** ** -- ** This copyright and support notice must be retained as part ** -- ** of this text at all times. ** -- ** ** -- ************************************************************************* -- ------------------------------------------------------------------------------- -- Filename: pselect_f.vhd -- -- Description: -- (Note: At least as early as I.31, XST implements a carry- -- chain structure for most decoders when these are coded in -- inferrable VHLD. An example of such code can be seen -- below in the "INFERRED_GEN" Generate Statement. -- -- -> New code should not need to instantiate pselect-type -- components. -- -- -> Existing code can be ported to Virtex5 and later by -- replacing pselect instances by pselect_f instances. -- As long as the C_FAMILY parameter is not included -- in the Generic Map, an inferred implementation -- will result. -- -- -> If the designer wishes to force an explicit carry- -- chain implementation, pselect_f can be used with -- the C_FAMILY parameter set to the target -- Xilinx FPGA family. -- ) -- -- Parameterizeable peripheral select (address decode). -- AValid qualifier comes in on Carry In at bottom -- of carry chain. -- -- -- VHDL-Standard: VHDL'93 ------------------------------------------------------------------------------- -- Structure: pselect_f.vhd -- family_support.vhd -- ------------------------------------------------------------------------------- -- History: -- Vaibhav & FLO 05/26/06 First Version -- -- DET 1/17/2008 v4_0 -- ~~~~~~ -- - Changed proc_common library version to v4_0 -- - Incorporated new disclaimer header -- ^^^^^^ -- ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Naming Conventions: -- active low signals: "*_n" -- clock signals: "clk", "clk_div#", "clk_#x" -- reset signals: "rst", "rst_n" -- generics: "C_*" -- user defined types: "*_TYPE" -- state machine next state: "*_ns" -- state machine current state: "*_cs" -- combinatorial signals: "*_com" -- pipelined or register delay signals: "*_d#" -- counter signals: "*cnt*" -- clock enable signals: "*_ce" -- internal version of output port "*_i" -- device pins: "*_pin" -- ports: - Names begin with Uppercase -- processes: "*_PROCESS" -- component instantiations: "<ENTITY_>I_<#|FUNC> ------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; ----------------------------------------------------------------------------- -- Entity section ----------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Definition of Generics: -- C_AB -- number of address bits to decode -- C_AW -- width of address bus -- C_BAR -- base address of peripheral (peripheral select -- is asserted when the C_AB most significant -- address bits match the C_AB most significant -- C_BAR bits -- Definition of Ports: -- A -- address input -- AValid -- address qualifier -- CS -- peripheral select ------------------------------------------------------------------------------- entity pselect_f is generic ( C_AB : integer := 9; C_AW : integer := 32; C_BAR : std_logic_vector; C_FAMILY : string := "nofamily" ); port ( A : in std_logic_vector(0 to C_AW-1); AValid : in std_logic; CS : out std_logic ); end entity pselect_f; ----------------------------------------------------------------------------- -- Architecture section ----------------------------------------------------------------------------- architecture imp of pselect_f is ----------------------------------------------------------------------------- -- C_BAR may not be indexed from 0 and may not be ascending; -- BAR recasts C_BAR to have these properties. ----------------------------------------------------------------------------- constant BAR : std_logic_vector(0 to C_BAR'length-1) := C_BAR; -- type bo2sl_type is array (boolean) of std_logic; -- constant bo2sl : bo2sl_type := (false => '0', true => '1'); function min(i, j: integer) return integer is begin if i<j then return i; else return j; end if; end; begin ------------------------------------------------------------------------------ -- Check that the generics are valid. ------------------------------------------------------------------------------ -- synthesis translate_off assert (C_AB <= C_BAR'length) and (C_AB <= C_AW) report "pselect_f generic error: " & "(C_AB <= C_BAR'length) and (C_AB <= C_AW)" & " does not hold." severity failure; -- synthesis translate_on ------------------------------------------------------------------------------ -- Build a behavioral decoder ------------------------------------------------------------------------------ XST_WA:if C_AB > 0 generate CS <= AValid when A(0 to C_AB-1) = BAR (0 to C_AB-1) else '0' ; end generate XST_WA; PASS_ON_GEN:if C_AB = 0 generate CS <= AValid ; end generate PASS_ON_GEN; end imp; ------------------------------------------------------------------- -- (c) Copyright 1984 - 2012 Xilinx, Inc. All rights reserved. -- -- This file contains confidential and proprietary information -- of Xilinx, Inc. and is protected under U.S. and -- international copyright and other intellectual property -- laws. -- -- DISCLAIMER -- This disclaimer is not a license and does not grant any -- rights to the materials distributed herewith. Except as -- otherwise provided in a valid license issued to you by -- Xilinx, and to the maximum extent permitted by applicable -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- (2) Xilinx shall not be liable (whether in contract or tort, -- including negligence, or under any other theory of -- liability) for any loss or damage of any kind or nature -- related to, arising under or in connection with these -- materials, including for any direct, or any indirect, -- special, incidental, or consequential loss or damage -- (including loss of data, profits, goodwill, or any type of -- loss or damage suffered as a result of any action brought -- by a third party) even if such damage or loss was -- reasonably foreseeable or Xilinx had been advised of the -- possibility of the same. -- -- CRITICAL APPLICATIONS -- Xilinx products are not designed or intended to be fail- -- safe, or for use in any application requiring fail-safe -- performance, such as life-support or safety devices or -- systems, Class III medical devices, nuclear facilities, -- applications related to the deployment of airbags, or any -- other applications that could lead to death, personal -- injury, or severe property or environmental damage -- (individually and collectively, "Critical -- Applications"). Customer assumes the sole risk and -- liability of any use of Xilinx products in Critical -- Applications, subject only to applicable laws and -- regulations governing limitations on product liability. -- -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- PART OF THIS FILE AT ALL TIMES. ------------------------------------------------------------------- -- ************************************************************************ -- ------------------------------------------------------------------------------- -- Filename: address_decoder.vhd -- Version: v2.0 -- Description: Address decoder utilizing unconstrained arrays for Base -- Address specification and ce number. ------------------------------------------------------------------------------- -- Structure: This section shows the hierarchical structure of axi_lite_ipif. -- -- --axi_lite_ipif.vhd -- --slave_attachment.vhd -- --address_decoder.vhd ------------------------------------------------------------------------------- -- Author: BSB -- -- History: -- -- BSB 05/20/10 -- First version -- ~~~~~~ -- - Created the first version v1.00.a -- ^^^^^^ -- ~~~~~~ -- SK 08/09/2010 -- -- - updated the core with optimziation. Closed CR 574507 -- - combined the CE generation logic to further optimize the code. -- ^^^^^^ -- ~~~~~~ -- SK 12/16/12 -- v2.0 -- 1. up reved to major version for 2013.1 Vivado release. No logic updates. -- 2. Updated the version of AXI LITE IPIF to v2.0 in X.Y format -- 3. updated the proc common version to proc_common_base_v5_0 -- 4. No Logic Updates -- ^^^^^^ ------------------------------------------------------------------------------- -- Naming Conventions: -- active low signals: "*_n" -- clock signals: "clk", "clk_div#", "clk_#x" -- reset signals: "rst", "rst_n" -- generics: "C_*" -- user defined types: "*_TYPE" -- state machine next state: "*_ns" -- state machine current state: "*_cs" -- combinatorial signals: "*_cmb" -- pipelined or register delay signals: "*_d#" -- counter signals: "*cnt*" -- clock enable signals: "*_ce" -- internal version of output port "*_i" -- device pins: "*_pin" -- ports: - Names begin with Uppercase -- processes: "*_PROCESS" -- component instantiations: "<ENTITY_>I_<#|FUNC> ------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use ieee.numeric_std.all; --library proc_common_base_v5_0; --use proc_common_base_v5_0.proc_common_pkg.clog2; --use proc_common_base_v5_0.pselect_f; --use proc_common_base_v5_0.ipif_pkg.all; library axi_lite_ipif_v3_0_4; use axi_lite_ipif_v3_0_4.ipif_pkg.all; ------------------------------------------------------------------------------- -- Definition of Generics ------------------------------------------------------------------------------- -- C_BUS_AWIDTH -- Address bus width -- C_S_AXI_MIN_SIZE -- Minimum address range of the IP -- C_ARD_ADDR_RANGE_ARRAY-- Base /High Address Pair for each Address Range -- C_ARD_NUM_CE_ARRAY -- Desired number of chip enables for an address range -- C_FAMILY -- Target FPGA family ------------------------------------------------------------------------------- -- Definition of Ports ------------------------------------------------------------------------------- -- Bus_clk -- Clock -- Bus_rst -- Reset -- Address_In_Erly -- Adddress in -- Address_Valid_Erly -- Address is valid -- Bus_RNW -- Read or write registered -- Bus_RNW_Erly -- Read or Write -- CS_CE_ld_enable -- chip select and chip enable registered -- Clear_CS_CE_Reg -- Clear_CS_CE_Reg clear -- RW_CE_ld_enable -- Read or Write Chip Enable -- CS_for_gaps -- CS generation for the gaps between address ranges -- CS_Out -- Chip select -- RdCE_Out -- Read Chip enable -- WrCE_Out -- Write chip enable ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Entity Declaration ------------------------------------------------------------------------------- entity address_decoder is generic ( C_BUS_AWIDTH : integer := 32; C_S_AXI_MIN_SIZE : std_logic_vector(0 to 31) := X"000001FF"; C_ARD_ADDR_RANGE_ARRAY: SLV64_ARRAY_TYPE := ( X"0000_0000_1000_0000", -- IP user0 base address X"0000_0000_1000_01FF", -- IP user0 high address X"0000_0000_1000_0200", -- IP user1 base address X"0000_0000_1000_02FF" -- IP user1 high address ); C_ARD_NUM_CE_ARRAY : INTEGER_ARRAY_TYPE := ( 8, -- User0 CE Number 1 -- User1 CE Number ); C_FAMILY : string := "virtex6" ); port ( Bus_clk : in std_logic; Bus_rst : in std_logic; -- PLB Interface signals Address_In_Erly : in std_logic_vector(0 to C_BUS_AWIDTH-1); Address_Valid_Erly : in std_logic; Bus_RNW : in std_logic; Bus_RNW_Erly : in std_logic; -- Registering control signals CS_CE_ld_enable : in std_logic; Clear_CS_CE_Reg : in std_logic; RW_CE_ld_enable : in std_logic; CS_for_gaps : out std_logic; -- Decode output signals CS_Out : out std_logic_vector (0 to ((C_ARD_ADDR_RANGE_ARRAY'LENGTH)/2)-1); RdCE_Out : out std_logic_vector (0 to calc_num_ce(C_ARD_NUM_CE_ARRAY)-1); WrCE_Out : out std_logic_vector (0 to calc_num_ce(C_ARD_NUM_CE_ARRAY)-1) ); end entity address_decoder; ------------------------------------------------------------------------------- -- Architecture section ------------------------------------------------------------------------------- architecture IMP of address_decoder is ---------------------------------------------------------------------------------- -- below attributes are added to reduce the synth warnings in Vivado tool attribute DowngradeIPIdentifiedWarnings: string; attribute DowngradeIPIdentifiedWarnings of imp : architecture is "yes"; ---------------------------------------------------------------------------------- -- local type declarations ---------------------------------------------------- type decode_bit_array_type is Array(natural range 0 to ( (C_ARD_ADDR_RANGE_ARRAY'LENGTH)/2)-1) of integer; type short_addr_array_type is Array(natural range 0 to C_ARD_ADDR_RANGE_ARRAY'LENGTH-1) of std_logic_vector(0 to C_BUS_AWIDTH-1); ------------------------------------------------------------------------------- -- Function Declarations ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- This function converts a 64 bit address range array to a AWIDTH bit -- address range array. ------------------------------------------------------------------------------- function slv64_2_slv_awidth(slv64_addr_array : SLV64_ARRAY_TYPE; awidth : integer) return short_addr_array_type is variable temp_addr : std_logic_vector(0 to 63); variable slv_array : short_addr_array_type; begin for array_index in 0 to slv64_addr_array'length-1 loop temp_addr := slv64_addr_array(array_index); slv_array(array_index) := temp_addr((64-awidth) to 63); end loop; return(slv_array); end function slv64_2_slv_awidth; ------------------------------------------------------------------------------- --Function Addr_bits --function to convert an address range (base address and an upper address) --into the number of upper address bits needed for decoding a device --select signal. will handle slices and big or little endian ------------------------------------------------------------------------------- function Addr_Bits (x,y : std_logic_vector(0 to C_BUS_AWIDTH-1)) return integer is variable addr_nor : std_logic_vector(0 to C_BUS_AWIDTH-1); begin addr_nor := x xor y; for i in 0 to C_BUS_AWIDTH-1 loop if addr_nor(i)='1' then return i; end if; end loop; --coverage off return(C_BUS_AWIDTH); --coverage on end function Addr_Bits; ------------------------------------------------------------------------------- --Function Get_Addr_Bits --function calculates the array which has the decode bits for the each address --range. ------------------------------------------------------------------------------- function Get_Addr_Bits (baseaddrs : short_addr_array_type) return decode_bit_array_type is variable num_bits : decode_bit_array_type; begin for i in 0 to ((baseaddrs'length)/2)-1 loop num_bits(i) := Addr_Bits (baseaddrs(i*2), baseaddrs(i*2+1)); end loop; return(num_bits); end function Get_Addr_Bits; ------------------------------------------------------------------------------- -- NEEDED_ADDR_BITS -- -- Function Description: -- This function calculates the number of address bits required -- to support the CE generation logic. This is determined by -- multiplying the number of CEs for an address space by the -- data width of the address space (in bytes). Each address -- space entry is processed and the biggest of the spaces is -- used to set the number of address bits required to be latched -- and used for CE decoding. A minimum value of 1 is returned by -- this function. -- ------------------------------------------------------------------------------- function needed_addr_bits (ce_array : INTEGER_ARRAY_TYPE) return integer is constant NUM_CE_ENTRIES : integer := CE_ARRAY'length; variable biggest : integer := 2; variable req_ce_addr_size : integer := 0; variable num_addr_bits : integer := 0; begin for i in 0 to NUM_CE_ENTRIES-1 loop req_ce_addr_size := ce_array(i) * 4; if (req_ce_addr_size > biggest) Then biggest := req_ce_addr_size; end if; end loop; num_addr_bits := clog2(biggest); return(num_addr_bits); end function NEEDED_ADDR_BITS; ----------------------------------------------------------------------------- -- Function calc_high_address -- -- This function is used to calculate the high address of the each address -- range ----------------------------------------------------------------------------- function calc_high_address (high_address : short_addr_array_type; index : integer) return std_logic_vector is variable calc_high_addr : std_logic_vector(0 to C_BUS_AWIDTH-1); begin If (index = (C_ARD_ADDR_RANGE_ARRAY'length/2-1)) Then calc_high_addr := C_S_AXI_MIN_SIZE(32-C_BUS_AWIDTH to 31); else calc_high_addr := high_address(index*2+2); end if; return(calc_high_addr); end function calc_high_address; ---------------------------------------------------------------------------- -- Constant Declarations ------------------------------------------------------------------------------- constant ARD_ADDR_RANGE_ARRAY : short_addr_array_type := slv64_2_slv_awidth(C_ARD_ADDR_RANGE_ARRAY, C_BUS_AWIDTH); constant NUM_BASE_ADDRS : integer := (C_ARD_ADDR_RANGE_ARRAY'length)/2; constant DECODE_BITS : decode_bit_array_type := Get_Addr_Bits(ARD_ADDR_RANGE_ARRAY); constant NUM_CE_SIGNALS : integer := calc_num_ce(C_ARD_NUM_CE_ARRAY); constant NUM_S_H_ADDR_BITS : integer := needed_addr_bits(C_ARD_NUM_CE_ARRAY); ------------------------------------------------------------------------------- -- Signal Declarations ------------------------------------------------------------------------------- signal pselect_hit_i : std_logic_vector (0 to ((C_ARD_ADDR_RANGE_ARRAY'LENGTH)/2)-1); signal cs_out_i : std_logic_vector (0 to ((C_ARD_ADDR_RANGE_ARRAY'LENGTH)/2)-1); signal ce_expnd_i : std_logic_vector(0 to NUM_CE_SIGNALS-1); signal rdce_out_i : std_logic_vector(0 to NUM_CE_SIGNALS-1); signal wrce_out_i : std_logic_vector(0 to NUM_CE_SIGNALS-1); signal ce_out_i : std_logic_vector(0 to NUM_CE_SIGNALS-1); -- signal cs_ce_clr : std_logic; signal addr_out_s_h : std_logic_vector(0 to NUM_S_H_ADDR_BITS-1); signal Bus_RNW_reg : std_logic; ------------------------------------------------------------------------------- -- Begin architecture ------------------------------------------------------------------------------- begin -- architecture IMP -- Register clears cs_ce_clr <= not Bus_rst or Clear_CS_CE_Reg; addr_out_s_h <= Address_In_Erly(C_BUS_AWIDTH-NUM_S_H_ADDR_BITS to C_BUS_AWIDTH-1); ------------------------------------------------------------------------------- -- MEM_DECODE_GEN: Universal Address Decode Block ------------------------------------------------------------------------------- MEM_DECODE_GEN: for bar_index in 0 to NUM_BASE_ADDRS-1 generate --------------- constant CE_INDEX_START : integer := calc_start_ce_index(C_ARD_NUM_CE_ARRAY,bar_index); constant CE_ADDR_SIZE : Integer range 0 to 15 := clog2(C_ARD_NUM_CE_ARRAY(bar_index)); constant OFFSET : integer := 2; constant BASE_ADDR_x : std_logic_vector(0 to C_BUS_AWIDTH-1) := ARD_ADDR_RANGE_ARRAY(bar_index*2+1); constant HIGH_ADDR_X : std_logic_vector(0 to C_BUS_AWIDTH-1) := calc_high_address(ARD_ADDR_RANGE_ARRAY,bar_index); --constant DECODE_BITS_0 : integer:= DECODE_BITS(0); --------- begin --------- -- GEN_FOR_MULTI_CS: Below logic generates the CS for decoded address -- ----------------- GEN_FOR_MULTI_CS : if C_ARD_ADDR_RANGE_ARRAY'length > 2 generate -- Instantiate the basic Base Address Decoders MEM_SELECT_I: entity axi_lite_ipif_v3_0_4.pselect_f generic map ( C_AB => DECODE_BITS(bar_index), C_AW => C_BUS_AWIDTH, C_BAR => ARD_ADDR_RANGE_ARRAY(bar_index*2), C_FAMILY => C_FAMILY ) port map ( A => Address_In_Erly, -- [in] AValid => Address_Valid_Erly, -- [in] CS => pselect_hit_i(bar_index) -- [out] ); end generate GEN_FOR_MULTI_CS; -- GEN_FOR_ONE_CS: below logic decodes the CS for single address range -- --------------- GEN_FOR_ONE_CS : if C_ARD_ADDR_RANGE_ARRAY'length = 2 generate pselect_hit_i(bar_index) <= Address_Valid_Erly; end generate GEN_FOR_ONE_CS; -- Instantate backend registers for the Chip Selects BKEND_CS_REG : process(Bus_Clk) begin if(Bus_Clk'EVENT and Bus_Clk = '1')then if(Bus_Rst='0' or Clear_CS_CE_Reg = '1')then cs_out_i(bar_index) <= '0'; elsif(CS_CE_ld_enable='1')then cs_out_i(bar_index) <= pselect_hit_i(bar_index); end if; end if; end process BKEND_CS_REG; ------------------------------------------------------------------------- -- PER_CE_GEN: Now expand the individual CEs for each base address. ------------------------------------------------------------------------- PER_CE_GEN: for j in natural range 0 to C_ARD_NUM_CE_ARRAY(bar_index) - 1 generate ----------- begin ----------- ---------------------------------------------------------------------- -- CE decoders for multiple CE's ---------------------------------------------------------------------- MULTIPLE_CES_THIS_CS_GEN : if CE_ADDR_SIZE > 0 generate constant BAR : std_logic_vector(0 to CE_ADDR_SIZE-1) := std_logic_vector(to_unsigned(j,CE_ADDR_SIZE)); begin CE_I : entity axi_lite_ipif_v3_0_4.pselect_f generic map ( C_AB => CE_ADDR_SIZE , C_AW => CE_ADDR_SIZE , C_BAR => BAR , C_FAMILY => C_FAMILY ) port map ( A => addr_out_s_h (NUM_S_H_ADDR_BITS-OFFSET-CE_ADDR_SIZE to NUM_S_H_ADDR_BITS - OFFSET - 1) , AValid => pselect_hit_i(bar_index) , CS => ce_expnd_i(CE_INDEX_START+j) ); end generate MULTIPLE_CES_THIS_CS_GEN; -------------------------------------- ---------------------------------------------------------------------- -- SINGLE_CE_THIS_CS_GEN: CE decoders for single CE ---------------------------------------------------------------------- SINGLE_CE_THIS_CS_GEN : if CE_ADDR_SIZE = 0 generate ce_expnd_i(CE_INDEX_START+j) <= pselect_hit_i(bar_index); end generate; ------------- end generate PER_CE_GEN; ------------------------ end generate MEM_DECODE_GEN; -- RNW_REG_P: Register the incoming RNW signal at the time of registering the -- address. This is need to generate the CE's separately. RNW_REG_P:process(Bus_Clk) begin if(Bus_Clk'EVENT and Bus_Clk = '1')then if(RW_CE_ld_enable='1')then Bus_RNW_reg <= Bus_RNW_Erly; end if; end if; end process RNW_REG_P; --------------------------------------------------------------------------- -- GEN_BKEND_CE_REGISTERS -- This ForGen implements the backend registering for -- the CE, RdCE, and WrCE output buses. --------------------------------------------------------------------------- GEN_BKEND_CE_REGISTERS : for ce_index in 0 to NUM_CE_SIGNALS-1 generate signal rdce_expnd_i : std_logic_vector(0 to NUM_CE_SIGNALS-1); signal wrce_expnd_i : std_logic_vector(0 to NUM_CE_SIGNALS-1); ------ begin ------ BKEND_RDCE_REG : process(Bus_Clk) begin if(Bus_Clk'EVENT and Bus_Clk = '1')then if(cs_ce_clr='1')then ce_out_i(ce_index) <= '0'; elsif(RW_CE_ld_enable='1')then ce_out_i(ce_index) <= ce_expnd_i(ce_index); end if; end if; end process BKEND_RDCE_REG; rdce_out_i(ce_index) <= ce_out_i(ce_index) and Bus_RNW_reg; wrce_out_i(ce_index) <= ce_out_i(ce_index) and not Bus_RNW_reg; ------------------------------- end generate GEN_BKEND_CE_REGISTERS; ------------------------------------------------------------------------------- CS_for_gaps <= '0'; -- Removed the GAP adecoder logic --------------------------------- CS_Out <= cs_out_i ; RdCE_Out <= rdce_out_i ; WrCE_Out <= wrce_out_i ; end architecture IMP; ------------------------------------------------------------------- -- (c) Copyright 1984 - 2012 Xilinx, Inc. All rights reserved. -- -- This file contains confidential and proprietary information -- of Xilinx, Inc. and is protected under U.S. and -- international copyright and other intellectual property -- laws. -- -- DISCLAIMER -- This disclaimer is not a license and does not grant any -- rights to the materials distributed herewith. Except as -- otherwise provided in a valid license issued to you by -- Xilinx, and to the maximum extent permitted by applicable -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- (2) Xilinx shall not be liable (whether in contract or tort, -- including negligence, or under any other theory of -- liability) for any loss or damage of any kind or nature -- related to, arising under or in connection with these -- materials, including for any direct, or any indirect, -- special, incidental, or consequential loss or damage -- (including loss of data, profits, goodwill, or any type of -- loss or damage suffered as a result of any action brought -- by a third party) even if such damage or loss was -- reasonably foreseeable or Xilinx had been advised of the -- possibility of the same. -- -- CRITICAL APPLICATIONS -- Xilinx products are not designed or intended to be fail- -- safe, or for use in any application requiring fail-safe -- performance, such as life-support or safety devices or -- systems, Class III medical devices, nuclear facilities, -- applications related to the deployment of airbags, or any -- other applications that could lead to death, personal -- injury, or severe property or environmental damage -- (individually and collectively, "Critical -- Applications"). Customer assumes the sole risk and -- liability of any use of Xilinx products in Critical -- Applications, subject only to applicable laws and -- regulations governing limitations on product liability. -- -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- PART OF THIS FILE AT ALL TIMES. ------------------------------------------------------------------- -- ************************************************************************ -- ------------------------------------------------------------------------------- -- Filename: slave_attachment.vhd -- Version: v2.0 -- Description: AXI slave attachment supporting single transfers ------------------------------------------------------------------------------- -- Structure: This section shows the hierarchical structure of axi_lite_ipif. -- -- --axi_lite_ipif.vhd -- --slave_attachment.vhd -- --address_decoder.vhd ------------------------------------------------------------------------------- -- Author: BSB -- -- History: -- -- BSB 05/20/10 -- First version -- ~~~~~~ -- - Created the first version v1.00.a -- ^^^^^^ -- ~~~~~~ -- SK 06/09/10 -- updated to reduce the utilization -- 1. State machine is re-designed -- 2. R and B channels are registered and AW, AR, W channels are non-registered -- 3. Address decoding is done only for the required address bits and not complete -- 32 bits -- 4. combined the response signals like ip2bus_error in optimzed code to remove the mux -- 5. Added local function "clog2" with "integer" as input in place of proc_common_pkg -- function. -- ^^^^^^ -- ~~~~~~ -- SK 12/16/12 -- v2.0 -- 1. up reved to major version for 2013.1 Vivado release. No logic updates. -- 2. Updated the version of AXI LITE IPIF to v2.0 in X.Y format -- 3. updated the proc common version to proc_common_base_v5_0 -- 4. No Logic Updates -- ^^^^^^ ------------------------------------------------------------------------------- -- Naming Conventions: -- active low signals: "*_n" -- clock signals: "clk", "clk_div#", "clk_#x" -- reset signals: "rst", "rst_n" -- generics: "C_*" -- user defined types: "*_TYPE" -- access_cs machine next state: "*_ns" -- state machine current state: "*_cs" -- combinatorial signals: "*_cmb" -- pipelined or register delay signals: "*_d#" -- counter signals: "*cnt*" -- clock enable signals: "*_ce" -- internal version of output port "*_i" -- device pins: "*_pin" -- ports: - Names begin with Uppercase -- processes: "*_PROCESS" -- component instantiations: "<ENTITY_>I_<#|FUNC> ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_misc.all; --library proc_common_base_v5_0; --use proc_common_base_v5_0.proc_common_pkg.clog2; --use proc_common_base_v5_0.ipif_pkg.all; library axi_lite_ipif_v3_0_4; use axi_lite_ipif_v3_0_4.ipif_pkg.all; ------------------------------------------------------------------------------- -- Definition of Generics ------------------------------------------------------------------------------- -- C_IPIF_ABUS_WIDTH -- IPIF Address bus width -- C_IPIF_DBUS_WIDTH -- IPIF Data Bus width -- C_S_AXI_MIN_SIZE -- Minimum address range of the IP -- C_USE_WSTRB -- Use write strobs or not -- C_DPHASE_TIMEOUT -- Data phase time out counter -- C_ARD_ADDR_RANGE_ARRAY-- Base /High Address Pair for each Address Range -- C_ARD_NUM_CE_ARRAY -- Desired number of chip enables for an address range -- C_FAMILY -- Target FPGA family ------------------------------------------------------------------------------- -- Definition of Ports ------------------------------------------------------------------------------- -- S_AXI_ACLK -- AXI Clock -- S_AXI_ARESET -- AXI Reset -- S_AXI_AWADDR -- AXI Write address -- S_AXI_AWVALID -- Write address valid -- S_AXI_AWREADY -- Write address ready -- S_AXI_WDATA -- Write data -- S_AXI_WSTRB -- Write strobes -- S_AXI_WVALID -- Write valid -- S_AXI_WREADY -- Write ready -- S_AXI_BRESP -- Write response -- S_AXI_BVALID -- Write response valid -- S_AXI_BREADY -- Response ready -- S_AXI_ARADDR -- Read address -- S_AXI_ARVALID -- Read address valid -- S_AXI_ARREADY -- Read address ready -- S_AXI_RDATA -- Read data -- S_AXI_RRESP -- Read response -- S_AXI_RVALID -- Read valid -- S_AXI_RREADY -- Read ready -- Bus2IP_Clk -- Synchronization clock provided to User IP -- Bus2IP_Reset -- Active high reset for use by the User IP -- Bus2IP_Addr -- Desired address of read or write operation -- Bus2IP_RNW -- Read or write indicator for the transaction -- Bus2IP_BE -- Byte enables for the data bus -- Bus2IP_CS -- Chip select for the transcations -- Bus2IP_RdCE -- Chip enables for the read -- Bus2IP_WrCE -- Chip enables for the write -- Bus2IP_Data -- Write data bus to the User IP -- IP2Bus_Data -- Input Read Data bus from the User IP -- IP2Bus_WrAck -- Active high Write Data qualifier from the IP -- IP2Bus_RdAck -- Active high Read Data qualifier from the IP -- IP2Bus_Error -- Error signal from the IP ------------------------------------------------------------------------------- entity slave_attachment is generic ( C_ARD_ADDR_RANGE_ARRAY: SLV64_ARRAY_TYPE := ( X"0000_0000_7000_0000", -- IP user0 base address X"0000_0000_7000_00FF", -- IP user0 high address X"0000_0000_7000_0100", -- IP user1 base address X"0000_0000_7000_01FF" -- IP user1 high address ); C_ARD_NUM_CE_ARRAY : INTEGER_ARRAY_TYPE := ( 1, -- User0 CE Number 8 -- User1 CE Number ); C_IPIF_ABUS_WIDTH : integer := 32; C_IPIF_DBUS_WIDTH : integer := 32; C_S_AXI_MIN_SIZE : std_logic_vector(31 downto 0):= X"000001FF"; C_USE_WSTRB : integer := 0; C_DPHASE_TIMEOUT : integer range 0 to 512 := 16; C_FAMILY : string := "virtex6" ); port( -- AXI signals S_AXI_ACLK : in std_logic; S_AXI_ARESETN : in std_logic; S_AXI_AWADDR : in std_logic_vector (C_IPIF_ABUS_WIDTH-1 downto 0); S_AXI_AWVALID : in std_logic; S_AXI_AWREADY : out std_logic; S_AXI_WDATA : in std_logic_vector (C_IPIF_DBUS_WIDTH-1 downto 0); S_AXI_WSTRB : in std_logic_vector ((C_IPIF_DBUS_WIDTH/8)-1 downto 0); S_AXI_WVALID : in std_logic; S_AXI_WREADY : out std_logic; S_AXI_BRESP : out std_logic_vector(1 downto 0); S_AXI_BVALID : out std_logic; S_AXI_BREADY : in std_logic; S_AXI_ARADDR : in std_logic_vector (C_IPIF_ABUS_WIDTH-1 downto 0); S_AXI_ARVALID : in std_logic; S_AXI_ARREADY : out std_logic; S_AXI_RDATA : out std_logic_vector (C_IPIF_DBUS_WIDTH-1 downto 0); S_AXI_RRESP : out std_logic_vector(1 downto 0); S_AXI_RVALID : out std_logic; S_AXI_RREADY : in std_logic; -- Controls to the IP/IPIF modules Bus2IP_Clk : out std_logic; Bus2IP_Resetn : out std_logic; Bus2IP_Addr : out std_logic_vector (C_IPIF_ABUS_WIDTH-1 downto 0); Bus2IP_RNW : out std_logic; Bus2IP_BE : out std_logic_vector (((C_IPIF_DBUS_WIDTH/8) - 1) downto 0); Bus2IP_CS : out std_logic_vector (((C_ARD_ADDR_RANGE_ARRAY'LENGTH)/2 - 1) downto 0); Bus2IP_RdCE : out std_logic_vector ((calc_num_ce(C_ARD_NUM_CE_ARRAY) - 1) downto 0); Bus2IP_WrCE : out std_logic_vector ((calc_num_ce(C_ARD_NUM_CE_ARRAY) - 1) downto 0); Bus2IP_Data : out std_logic_vector ((C_IPIF_DBUS_WIDTH-1) downto 0); IP2Bus_Data : in std_logic_vector ((C_IPIF_DBUS_WIDTH-1) downto 0); IP2Bus_WrAck : in std_logic; IP2Bus_RdAck : in std_logic; IP2Bus_Error : in std_logic ); end entity slave_attachment; ------------------------------------------------------------------------------- architecture imp of slave_attachment is ---------------------------------------------------------------------------------- -- below attributes are added to reduce the synth warnings in Vivado tool attribute DowngradeIPIdentifiedWarnings: string; attribute DowngradeIPIdentifiedWarnings of imp : architecture is "yes"; ---------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Get_Addr_Bits: Function Declarations ------------------------------------------------------------------------------- function Get_Addr_Bits (y : std_logic_vector(31 downto 0)) return integer is variable i : integer := 0; begin for i in 31 downto 0 loop if y(i)='1' then return (i); end if; end loop; return -1; end function Get_Addr_Bits; ------------------------------------------------------------------------------- -- Constant Declarations ------------------------------------------------------------------------------- constant CS_BUS_SIZE : integer := C_ARD_ADDR_RANGE_ARRAY'length/2; constant CE_BUS_SIZE : integer := calc_num_ce(C_ARD_NUM_CE_ARRAY); constant C_ADDR_DECODE_BITS : integer := Get_Addr_Bits(C_S_AXI_MIN_SIZE); constant C_NUM_DECODE_BITS : integer := C_ADDR_DECODE_BITS +1; constant ZEROS : std_logic_vector((C_IPIF_ABUS_WIDTH-1) downto (C_ADDR_DECODE_BITS+1)) := (others=>'0'); ------------------------------------------------------------------------------- -- Signal and Type Declarations ------------------------------------------------------------------------------- signal s_axi_bvalid_i : std_logic:= '0'; signal s_axi_arready_i : std_logic; signal s_axi_rvalid_i : std_logic:= '0'; signal start : std_logic; signal start2 : std_logic; -- Intermediate IPIC signals signal bus2ip_addr_i : std_logic_vector ((C_IPIF_ABUS_WIDTH-1) downto 0); signal timeout : std_logic; signal rd_done,wr_done : std_logic; signal rd_done1,wr_done1 : std_logic; --signal rd_done2,wr_done2 : std_logic; signal wrack_1,rdack_1 : std_logic; --signal wrack_2,rdack_2 : std_logic; signal rst : std_logic; signal temp_i : std_logic; type BUS_ACCESS_STATES is ( SM_IDLE, SM_READ, SM_WRITE, SM_RESP ); signal state : BUS_ACCESS_STATES; signal cs_for_gaps_i : std_logic; signal bus2ip_rnw_i : std_logic; signal s_axi_bresp_i : std_logic_vector(1 downto 0):=(others => '0'); signal s_axi_rresp_i : std_logic_vector(1 downto 0):=(others => '0'); signal s_axi_rdata_i : std_logic_vector (C_IPIF_DBUS_WIDTH-1 downto 0):=(others => '0'); signal is_read, is_write : std_logic; ------------------------------------------------------------------------------- -- begin the architecture logic ------------------------------------------------------------------------------- begin ------------------------------------------------------------------------------- -- Address registered ------------------------------------------------------------------------------- Bus2IP_Clk <= S_AXI_ACLK; Bus2IP_Resetn <= S_AXI_ARESETN; --bus2ip_rnw_i <= '1' when S_AXI_ARVALID='1' -- else -- '0'; BUS2IP_RNW <= bus2ip_rnw_i; Bus2IP_BE <= S_AXI_WSTRB when ((C_USE_WSTRB = 1) and (bus2ip_rnw_i = '0')) else (others => '1'); Bus2IP_Data <= S_AXI_WDATA; Bus2IP_Addr <= bus2ip_addr_i; -- For AXI Lite interface, interconnect will duplicate the addresses on both the -- read and write channel. so onlyone address is used for decoding as well as -- passing it to IP. --bus2ip_addr_i <= ZEROS & S_AXI_ARADDR(C_ADDR_DECODE_BITS downto 0) -- when (S_AXI_ARVALID='1') -- else -- ZEROS & S_AXI_AWADDR(C_ADDR_DECODE_BITS downto 0); -------------------------------------------------------------------------------- -- start signal will be used to latch the incoming address --start<= (S_AXI_ARVALID or (S_AXI_AWVALID and S_AXI_WVALID)) -- when (state = SM_IDLE) -- else -- '0'; -- x_done signals are used to release the hold from AXI, it will generate "ready" -- signal on the read and write address channels. rd_done <= IP2Bus_RdAck or (timeout and is_read); wr_done <= IP2Bus_WrAck or (timeout and is_write); --wr_done1 <= (not (wrack_1) and IP2Bus_WrAck) or timeout; --rd_done1 <= (not (rdack_1) and IP2Bus_RdAck) or timeout; temp_i <= rd_done or wr_done; ------------------------------------------------------------------------------- -- Address Decoder Component Instance -- -- This component decodes the specified base address pairs and outputs the -- specified number of chip enables and the target bus size. ------------------------------------------------------------------------------- I_DECODER : entity axi_lite_ipif_v3_0_4.address_decoder generic map ( C_BUS_AWIDTH => C_NUM_DECODE_BITS, C_S_AXI_MIN_SIZE => C_S_AXI_MIN_SIZE, C_ARD_ADDR_RANGE_ARRAY=> C_ARD_ADDR_RANGE_ARRAY, C_ARD_NUM_CE_ARRAY => C_ARD_NUM_CE_ARRAY, C_FAMILY => "nofamily" ) port map ( Bus_clk => S_AXI_ACLK, Bus_rst => S_AXI_ARESETN, Address_In_Erly => bus2ip_addr_i(C_ADDR_DECODE_BITS downto 0), Address_Valid_Erly => start2, Bus_RNW => bus2ip_rnw_i, --S_AXI_ARVALID, Bus_RNW_Erly => bus2ip_rnw_i, --S_AXI_ARVALID, CS_CE_ld_enable => start2, Clear_CS_CE_Reg => temp_i, RW_CE_ld_enable => start2, CS_for_gaps => open, -- Decode output signals CS_Out => Bus2IP_CS, RdCE_Out => Bus2IP_RdCE, WrCE_Out => Bus2IP_WrCE ); -- REGISTERING_RESET_P: Invert the reset coming from AXI ----------------------- REGISTERING_RESET_P : process (S_AXI_ACLK) is begin if S_AXI_ACLK'event and S_AXI_ACLK = '1' then rst <= not S_AXI_ARESETN; end if; end process REGISTERING_RESET_P; REGISTERING_RESET_P2 : process (S_AXI_ACLK) is begin if S_AXI_ACLK'event and S_AXI_ACLK = '1' then if (rst = '1') then -- wrack_1 <= '0'; -- rdack_1 <= '0'; -- wrack_2 <= '0'; -- rdack_2 <= '0'; -- wr_done2 <= '0'; -- rd_done2 <= '0'; bus2ip_rnw_i <= '0'; bus2ip_addr_i <= (others => '0'); start2 <= '0'; else -- wrack_1 <= IP2Bus_WrAck; -- rdack_1 <= IP2Bus_RdAck; -- wrack_2 <= wrack_1; -- rdack_2 <= rdack_1; -- wr_done2 <= wr_done1; -- rd_done2 <= rd_done1; if (state = SM_IDLE and S_AXI_ARVALID='1') then bus2ip_addr_i <= ZEROS & S_AXI_ARADDR(C_ADDR_DECODE_BITS downto 0); bus2ip_rnw_i <= '1'; start2 <= '1'; elsif (state = SM_IDLE and (S_AXI_AWVALID = '1' and S_AXI_WVALID = '1')) then bus2ip_addr_i <= ZEROS & S_AXI_AWADDR(C_ADDR_DECODE_BITS downto 0); bus2ip_rnw_i <= '0'; start2 <= '1'; else bus2ip_rnw_i <= bus2ip_rnw_i; bus2ip_addr_i <= bus2ip_addr_i; start2 <= '0'; end if; end if; end if; end process REGISTERING_RESET_P2; ------------------------------------------------------------------------------- -- AXI Transaction Controller ------------------------------------------------------------------------------- -- Access_Control: As per suggestion to optimize the core, the below state machine -- is re-coded. Latches are removed from original suggestions Access_Control : process (S_AXI_ACLK) is begin if S_AXI_ACLK'event and S_AXI_ACLK = '1' then if rst = '1' then state <= SM_IDLE; is_read <= '0'; is_write <= '0'; else case state is when SM_IDLE => if (S_AXI_ARVALID = '1') then -- Read precedence over write state <= SM_READ; is_read <='1'; is_write <= '0'; elsif (S_AXI_AWVALID = '1' and S_AXI_WVALID = '1') then state <= SM_WRITE; is_read <='0'; is_write <= '1'; else state <= SM_IDLE; is_read <='0'; is_write <= '0'; end if; when SM_READ => if rd_done = '1' then state <= SM_RESP; else state <= SM_READ; end if; when SM_WRITE=> if (wr_done = '1') then state <= SM_RESP; else state <= SM_WRITE; end if; when SM_RESP => if ((s_axi_bvalid_i and S_AXI_BREADY) or (s_axi_rvalid_i and S_AXI_RREADY)) = '1' then state <= SM_IDLE; is_read <='0'; is_write <= '0'; else state <= SM_RESP; end if; -- coverage off when others => state <= SM_IDLE; -- coverage on end case; end if; end if; end process Access_Control; ------------------------------------------------------------------------------- -- AXI Transaction Controller signals registered ------------------------------------------------------------------------------- -- S_AXI_RDATA_RESP_P : BElow process generates the RRESP and RDATA on AXI ----------------------- S_AXI_RDATA_RESP_P : process (S_AXI_ACLK) is begin if S_AXI_ACLK'event and S_AXI_ACLK = '1' then if (rst = '1') then s_axi_rresp_i <= (others => '0'); s_axi_rdata_i <= (others => '0'); elsif state = SM_READ then s_axi_rresp_i <= (IP2Bus_Error) & '0'; s_axi_rdata_i <= IP2Bus_Data; end if; end if; end process S_AXI_RDATA_RESP_P; S_AXI_RRESP <= s_axi_rresp_i; S_AXI_RDATA <= s_axi_rdata_i; ----------------------------- -- S_AXI_RVALID_I_P : below process generates the RVALID response on read channel ---------------------- S_AXI_RVALID_I_P : process (S_AXI_ACLK) is begin if S_AXI_ACLK'event and S_AXI_ACLK = '1' then if (rst = '1') then s_axi_rvalid_i <= '0'; elsif ((state = SM_READ) and rd_done = '1') then s_axi_rvalid_i <= '1'; elsif (S_AXI_RREADY = '1') then s_axi_rvalid_i <= '0'; end if; end if; end process S_AXI_RVALID_I_P; -- -- S_AXI_BRESP_P: Below process provides logic for write response -- ----------------- S_AXI_BRESP_P : process (S_AXI_ACLK) is begin if S_AXI_ACLK'event and S_AXI_ACLK = '1' then if (rst = '1') then s_axi_bresp_i <= (others => '0'); elsif (state = SM_WRITE) then s_axi_bresp_i <= (IP2Bus_Error) & '0'; end if; end if; end process S_AXI_BRESP_P; S_AXI_BRESP <= s_axi_bresp_i; --S_AXI_BVALID_I_P: below process provides logic for valid write response signal ------------------- S_AXI_BVALID_I_P : process (S_AXI_ACLK) is begin if S_AXI_ACLK'event and S_AXI_ACLK = '1' then if rst = '1' then s_axi_bvalid_i <= '0'; elsif ((state = SM_WRITE) and wr_done = '1') then s_axi_bvalid_i <= '1'; elsif (S_AXI_BREADY = '1') then s_axi_bvalid_i <= '0'; end if; end if; end process S_AXI_BVALID_I_P; ----------------------------------------------------------------------------- -- INCLUDE_DPHASE_TIMER: Data timeout counter included only when its value is non-zero. -------------- INCLUDE_DPHASE_TIMER: if C_DPHASE_TIMEOUT /= 0 generate constant COUNTER_WIDTH : integer := clog2((C_DPHASE_TIMEOUT)); signal dpto_cnt : std_logic_vector (COUNTER_WIDTH downto 0); -- dpto_cnt is one bit wider then COUNTER_WIDTH, which allows the timeout -- condition to be captured as a carry into this "extra" bit. begin DPTO_CNT_P : process (S_AXI_ACLK) is begin if (S_AXI_ACLK'event and S_AXI_ACLK = '1') then if ((state = SM_IDLE) or (state = SM_RESP)) then dpto_cnt <= (others=>'0'); else dpto_cnt <= dpto_cnt + 1; end if; end if; end process DPTO_CNT_P; timeout <= '1' when (dpto_cnt = C_DPHASE_TIMEOUT) else '0'; end generate INCLUDE_DPHASE_TIMER; EXCLUDE_DPHASE_TIMER: if C_DPHASE_TIMEOUT = 0 generate timeout <= '0'; end generate EXCLUDE_DPHASE_TIMER; ----------------------------------------------------------------------------- S_AXI_BVALID <= s_axi_bvalid_i; S_AXI_RVALID <= s_axi_rvalid_i; ----------------------------------------------------------------------------- S_AXI_ARREADY <= rd_done; S_AXI_AWREADY <= wr_done; S_AXI_WREADY <= wr_done; ------------------------------------------------------------------------------- end imp; ------------------------------------------------------------------- -- (c) Copyright 1984 - 2012 Xilinx, Inc. All rights reserved. -- -- This file contains confidential and proprietary information -- of Xilinx, Inc. and is protected under U.S. and -- international copyright and other intellectual property -- laws. -- -- DISCLAIMER -- This disclaimer is not a license and does not grant any -- rights to the materials distributed herewith. Except as -- otherwise provided in a valid license issued to you by -- Xilinx, and to the maximum extent permitted by applicable -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- (2) Xilinx shall not be liable (whether in contract or tort, -- including negligence, or under any other theory of -- liability) for any loss or damage of any kind or nature -- related to, arising under or in connection with these -- materials, including for any direct, or any indirect, -- special, incidental, or consequential loss or damage -- (including loss of data, profits, goodwill, or any type of -- loss or damage suffered as a result of any action brought -- by a third party) even if such damage or loss was -- reasonably foreseeable or Xilinx had been advised of the -- possibility of the same. -- -- CRITICAL APPLICATIONS -- Xilinx products are not designed or intended to be fail- -- safe, or for use in any application requiring fail-safe -- performance, such as life-support or safety devices or -- systems, Class III medical devices, nuclear facilities, -- applications related to the deployment of airbags, or any -- other applications that could lead to death, personal -- injury, or severe property or environmental damage -- (individually and collectively, "Critical -- Applications"). Customer assumes the sole risk and -- liability of any use of Xilinx products in Critical -- Applications, subject only to applicable laws and -- regulations governing limitations on product liability. -- -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- PART OF THIS FILE AT ALL TIMES. ------------------------------------------------------------------- -- ************************************************************************ -- ------------------------------------------------------------------------------- -- Filename: axi_lite_ipif.vhd -- Version: v2.0 -- Description: This is the top level design file for the axi_lite_ipif -- function. It provides a standardized slave interface -- between the IP and the AXI. This version supports -- single read/write transfers only. It does not provide -- address pipelining or simultaneous read and write -- operations. ------------------------------------------------------------------------------- -- Structure: This section shows the hierarchical structure of axi_lite_ipif. -- -- --axi_lite_ipif.vhd -- --slave_attachment.vhd -- --address_decoder.vhd ------------------------------------------------------------------------------- -- Author: BSB -- -- History: -- -- BSB 05/20/10 -- First version -- ~~~~~~ -- - Created the first version v1.00.a -- ^^^^^^ -- ~~~~~~ -- SK 06/09/10 -- v1.01.a -- 1. updated to reduce the utilization -- Closed CR #574507 -- 2. Optimized the state machine code -- 3. Optimized the address decoder logic to generate the CE's with common logic -- 4. Address GAP decoding logic is removed and timeout counter is made active -- for all transactions. -- ^^^^^^ -- ~~~~~~ -- SK 12/16/12 -- v2.0 -- 1. up reved to major version for 2013.1 Vivado release. No logic updates. -- 2. Updated the version of AXI LITE IPIF to v2.0 in X.Y format -- 3. updated the proc common version to proc_common_base_v5_0 -- 4. No Logic Updates -- ^^^^^^ ------------------------------------------------------------------------------- -- Naming Conventions: -- active low signals: "*_n" -- clock signals: "clk", "clk_div#", "clk_#x" -- reset signals: "rst", "rst_n" -- generics: "C_*" -- user defined types: "*_TYPE" -- state machine next state: "*_ns" -- state machine current state: "*_cs" -- combinatorial signals: "*_cmb" -- pipelined or register delay signals: "*_d#" -- counter signals: "*cnt*" -- clock enable signals: "*_ce" -- internal version of output port "*_i" -- device pins: "*_pin" -- ports: - Names begin with Uppercase -- processes: "*_PROCESS" -- component instantiations: "<ENTITY_>I_<#|FUNC> ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; use ieee.std_logic_misc.all; --library proc_common_base_v5_0; --use proc_common_base_v5_0.ipif_pkg.all; library axi_lite_ipif_v3_0_4; use axi_lite_ipif_v3_0_4.ipif_pkg.all; ------------------------------------------------------------------------------- -- Definition of Generics ------------------------------------------------------------------------------- -- C_S_AXI_DATA_WIDTH -- AXI data bus width -- C_S_AXI_ADDR_WIDTH -- AXI address bus width -- C_S_AXI_MIN_SIZE -- Minimum address range of the IP -- C_USE_WSTRB -- Use write strobs or not -- C_DPHASE_TIMEOUT -- Data phase time out counter -- C_ARD_ADDR_RANGE_ARRAY-- Base /High Address Pair for each Address Range -- C_ARD_NUM_CE_ARRAY -- Desired number of chip enables for an address range -- C_FAMILY -- Target FPGA family ------------------------------------------------------------------------------- -- Definition of Ports ------------------------------------------------------------------------------- -- S_AXI_ACLK -- AXI Clock -- S_AXI_ARESETN -- AXI Reset -- S_AXI_AWADDR -- AXI Write address -- S_AXI_AWVALID -- Write address valid -- S_AXI_AWREADY -- Write address ready -- S_AXI_WDATA -- Write data -- S_AXI_WSTRB -- Write strobes -- S_AXI_WVALID -- Write valid -- S_AXI_WREADY -- Write ready -- S_AXI_BRESP -- Write response -- S_AXI_BVALID -- Write response valid -- S_AXI_BREADY -- Response ready -- S_AXI_ARADDR -- Read address -- S_AXI_ARVALID -- Read address valid -- S_AXI_ARREADY -- Read address ready -- S_AXI_RDATA -- Read data -- S_AXI_RRESP -- Read response -- S_AXI_RVALID -- Read valid -- S_AXI_RREADY -- Read ready -- Bus2IP_Clk -- Synchronization clock provided to User IP -- Bus2IP_Reset -- Active high reset for use by the User IP -- Bus2IP_Addr -- Desired address of read or write operation -- Bus2IP_RNW -- Read or write indicator for the transaction -- Bus2IP_BE -- Byte enables for the data bus -- Bus2IP_CS -- Chip select for the transcations -- Bus2IP_RdCE -- Chip enables for the read -- Bus2IP_WrCE -- Chip enables for the write -- Bus2IP_Data -- Write data bus to the User IP -- IP2Bus_Data -- Input Read Data bus from the User IP -- IP2Bus_WrAck -- Active high Write Data qualifier from the IP -- IP2Bus_RdAck -- Active high Read Data qualifier from the IP -- IP2Bus_Error -- Error signal from the IP ------------------------------------------------------------------------------- entity axi_lite_ipif is generic ( C_S_AXI_DATA_WIDTH : integer range 32 to 32 := 32; C_S_AXI_ADDR_WIDTH : integer := 32; C_S_AXI_MIN_SIZE : std_logic_vector(31 downto 0):= X"000001FF"; C_USE_WSTRB : integer := 0; C_DPHASE_TIMEOUT : integer range 0 to 512 := 8; C_ARD_ADDR_RANGE_ARRAY: SLV64_ARRAY_TYPE := -- not used ( X"0000_0000_7000_0000", -- IP user0 base address X"0000_0000_7000_00FF", -- IP user0 high address X"0000_0000_7000_0100", -- IP user1 base address X"0000_0000_7000_01FF" -- IP user1 high address ); C_ARD_NUM_CE_ARRAY : INTEGER_ARRAY_TYPE := -- not used ( 4, -- User0 CE Number 12 -- User1 CE Number ); C_FAMILY : string := "virtex6" ); port ( --System signals S_AXI_ACLK : in std_logic; S_AXI_ARESETN : in std_logic; S_AXI_AWADDR : in std_logic_vector (C_S_AXI_ADDR_WIDTH-1 downto 0); S_AXI_AWVALID : in std_logic; S_AXI_AWREADY : out std_logic; S_AXI_WDATA : in std_logic_vector (C_S_AXI_DATA_WIDTH-1 downto 0); S_AXI_WSTRB : in std_logic_vector ((C_S_AXI_DATA_WIDTH/8)-1 downto 0); S_AXI_WVALID : in std_logic; S_AXI_WREADY : out std_logic; S_AXI_BRESP : out std_logic_vector(1 downto 0); S_AXI_BVALID : out std_logic; S_AXI_BREADY : in std_logic; S_AXI_ARADDR : in std_logic_vector (C_S_AXI_ADDR_WIDTH-1 downto 0); S_AXI_ARVALID : in std_logic; S_AXI_ARREADY : out std_logic; S_AXI_RDATA : out std_logic_vector (C_S_AXI_DATA_WIDTH-1 downto 0); S_AXI_RRESP : out std_logic_vector(1 downto 0); S_AXI_RVALID : out std_logic; S_AXI_RREADY : in std_logic; -- Controls to the IP/IPIF modules Bus2IP_Clk : out std_logic; Bus2IP_Resetn : out std_logic; Bus2IP_Addr : out std_logic_vector ((C_S_AXI_ADDR_WIDTH-1) downto 0); Bus2IP_RNW : out std_logic; Bus2IP_BE : out std_logic_vector (((C_S_AXI_DATA_WIDTH/8)-1) downto 0); Bus2IP_CS : out std_logic_vector (((C_ARD_ADDR_RANGE_ARRAY'LENGTH)/2-1) downto 0); Bus2IP_RdCE : out std_logic_vector ((calc_num_ce(C_ARD_NUM_CE_ARRAY)-1) downto 0); Bus2IP_WrCE : out std_logic_vector ((calc_num_ce(C_ARD_NUM_CE_ARRAY)-1) downto 0); Bus2IP_Data : out std_logic_vector ((C_S_AXI_DATA_WIDTH-1) downto 0); IP2Bus_Data : in std_logic_vector ((C_S_AXI_DATA_WIDTH-1) downto 0); IP2Bus_WrAck : in std_logic; IP2Bus_RdAck : in std_logic; IP2Bus_Error : in std_logic ); end axi_lite_ipif; ------------------------------------------------------------------------------- -- Architecture ------------------------------------------------------------------------------- architecture imp of axi_lite_ipif is ---------------------------------------------------------------------------------- -- below attributes are added to reduce the synth warnings in Vivado tool attribute DowngradeIPIdentifiedWarnings: string; attribute DowngradeIPIdentifiedWarnings of imp : architecture is "yes"; ---------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Begin architecture logic ------------------------------------------------------------------------------- begin ------------------------------------------------------------------------------- -- Slave Attachment ------------------------------------------------------------------------------- I_SLAVE_ATTACHMENT: entity axi_lite_ipif_v3_0_4.slave_attachment generic map( C_ARD_ADDR_RANGE_ARRAY => C_ARD_ADDR_RANGE_ARRAY, C_ARD_NUM_CE_ARRAY => C_ARD_NUM_CE_ARRAY, C_IPIF_ABUS_WIDTH => C_S_AXI_ADDR_WIDTH, C_IPIF_DBUS_WIDTH => C_S_AXI_DATA_WIDTH, C_USE_WSTRB => C_USE_WSTRB, C_DPHASE_TIMEOUT => C_DPHASE_TIMEOUT, C_S_AXI_MIN_SIZE => C_S_AXI_MIN_SIZE, C_FAMILY => C_FAMILY ) port map( -- AXI signals S_AXI_ACLK => S_AXI_ACLK, S_AXI_ARESETN => S_AXI_ARESETN, S_AXI_AWADDR => S_AXI_AWADDR, S_AXI_AWVALID => S_AXI_AWVALID, S_AXI_AWREADY => S_AXI_AWREADY, S_AXI_WDATA => S_AXI_WDATA, S_AXI_WSTRB => S_AXI_WSTRB, S_AXI_WVALID => S_AXI_WVALID, S_AXI_WREADY => S_AXI_WREADY, S_AXI_BRESP => S_AXI_BRESP, S_AXI_BVALID => S_AXI_BVALID, S_AXI_BREADY => S_AXI_BREADY, S_AXI_ARADDR => S_AXI_ARADDR, S_AXI_ARVALID => S_AXI_ARVALID, S_AXI_ARREADY => S_AXI_ARREADY, S_AXI_RDATA => S_AXI_RDATA, S_AXI_RRESP => S_AXI_RRESP, S_AXI_RVALID => S_AXI_RVALID, S_AXI_RREADY => S_AXI_RREADY, -- IPIC signals Bus2IP_Clk => Bus2IP_Clk, Bus2IP_Resetn => Bus2IP_Resetn, Bus2IP_Addr => Bus2IP_Addr, Bus2IP_RNW => Bus2IP_RNW, Bus2IP_BE => Bus2IP_BE, Bus2IP_CS => Bus2IP_CS, Bus2IP_RdCE => Bus2IP_RdCE, Bus2IP_WrCE => Bus2IP_WrCE, Bus2IP_Data => Bus2IP_Data, IP2Bus_Data => IP2Bus_Data, IP2Bus_WrAck => IP2Bus_WrAck, IP2Bus_RdAck => IP2Bus_RdAck, IP2Bus_Error => IP2Bus_Error ); end imp;