first commit after restructuring

This commit is contained in:
2023-04-13 13:33:41 +08:00
commit 3c2cd0ba29
15090 changed files with 6794217 additions and 0 deletions
@@ -0,0 +1,123 @@
`ifndef sc_util_v1_0_4_constants_GLOBAL_CONSTANTS
`define sc_util_v1_0_4_constants_GLOBAL_CONSTANTS
parameter integer K_MAX_NUM_BYTES = 128;
parameter integer K_MAX_BYTE_SIZE = 7;
parameter integer K_MAX_DATA_WIDTH = 1024;
parameter integer K_MAX_DATA_SIZE = 10;
parameter integer K_MIN_NUM_BYTES = 4;
parameter integer K_MIN_BYTE_SIZE = 2;
parameter integer K_MIN_DATA_WIDTH = 32;
parameter integer K_MIN_DATA_SIZE = 5;
parameter integer K_MAX_NUM_AXI4LITE_BYTES = 8;
parameter integer K_MAX_AXI4LITE_BYTE_SIZE = 3;
parameter integer K_MAX_AXI4LITE_DATA_WIDTH = 64;
parameter integer K_MAX_AXI4LITE_DATA_SIZE = 6;
parameter integer K_DATA_BITS_PER_BYTE = 9;
parameter integer K_MAX_BYTE_FACTOR = 16;
parameter integer K_MAX_BYTE_MAGNITUDE = 5;
parameter integer K_MAX_ADDR_WIDTH = 64;
parameter integer K_MAX_ID_WIDTH = 32;
parameter integer K_MAX_MEP_IDENTIFIER_WIDTH = 8;
parameter integer K_MAX_USER_WIDTH = 1024;
parameter integer K_MAX_USER_PAYLD = 512;
parameter integer K_MAX_NUM_SSC = 16;
parameter integer K_MAX_SSC_SIZE = 4;
parameter integer K_MAX_NUM_MSC = 64;
parameter integer K_MAX_MSC_SIZE = 6;
parameter integer K_MAX_SWBD_PORTS = 16;
parameter integer K_MAX_SWBD_SIZE = 4;
parameter integer K_MAX_CASCADES = 16;
parameter integer K_MAX_TIERS = 4;
parameter integer K_MAX_THREADS = 16;
parameter integer K_MAX_THREAD_SIZE = 4;
parameter integer K_MAX_NUM_SEG = 256;
parameter integer K_MAX_SEG_WIDTH = 8;
parameter integer K_MAX_EP_ROUTE_WIDTH = 64;
parameter integer K_MAX_SC_ROUTE_WIDTH = 64;
parameter integer K_MAX_CMD_PTR = 5;
parameter integer K_MAX_LUTRAM_PTR = 8;
parameter integer K_MAX_BRAM_PTR = 12;
parameter integer K_MIN_BRAM_PTR = 9;
parameter integer K_MAX_SYNC_RATIO = 8;
parameter integer K_MAX_PIPELINES = 8;
parameter integer K_LOG_MAX_PIPELINES = 3;
parameter integer K_MAX_LATENCY = 15;
parameter integer K_LOG_MAX_LATENCY = 4;
parameter integer K_AXIS_ARB_TDATA_NUM_BYTES = 2;
parameter integer K_MAX_USER_BITS_PER_BYTE = 4;
parameter integer K_MAX_INFO_WIDTH = 1;
parameter integer K_MAX_OUTSTANDING_REQ = 3;
parameter integer K_AXI_SIZE_WIDTH = 3;
parameter integer K_AXI_BURST_WIDTH = 2;
parameter integer K_AXI_RESP_WIDTH = 2;
parameter integer K_AXI_LAST_WIDTH = 1;
parameter integer K_AXI_LEN_WIDTH = 8;
parameter integer K_AXI_EXCL_LEN_WIDTH = 4;
parameter integer K_AXI_LOCK_WIDTH = 1;
parameter integer K_AXI3_LEN_WIDTH = 4;
parameter integer K_AXI3_LOCK_WIDTH = 2;
parameter integer K_AXI_PROT_WIDTH = 3;
parameter integer K_AXI_QOS_WIDTH = 4;
parameter integer K_AXI_CACHE_WIDTH = 4;
parameter integer K_MAX_ACCEPTANCE = 256;
parameter integer K_MAX_FANOUT = 200;
parameter integer K_MAX_READ_WATERMARK = 4096;
parameter integer K_MAX_BURST_LENGTH = 256;
parameter integer CH_R = 0;
parameter integer CH_W = 1;
parameter integer CH_AR = 2;
parameter integer CH_AW = 3;
parameter integer CH_B = 4;
parameter integer CLK_DOWN = -2;
parameter integer CLK_SYNC_ALIAS = -1;
parameter integer CLK_ASYNC = 0;
parameter integer CLK_SYNC = 1;
parameter integer CLK_UP = 2;
parameter integer CLKEN_NONE = 0;
parameter integer CLKEN_S = 1;
parameter integer CLKEN_M = 2;
parameter integer CLKEN_S_AND_M = 3;
parameter integer ARB_BYPASS = 0;
parameter integer ARB_ROUNDROBIN = 1;
parameter integer ARB_SLAVE = 2;
parameter integer FIFO_LUTRAM = 0;
parameter integer FIFO_BRAM = 1;
parameter integer FIFO_NONE = 2;
parameter integer FIFO_IP_XPM_MEMORY = 0;
parameter integer FIFO_IP_FG = 1;
parameter integer FIFO_IP_XPM_FIFO = 2;
parameter integer K_T_STRUCT_EXCLUSIVE_WIDTH = 11;
parameter integer K_T_STATIC_ADDR_PAYLD_WIDTH = 102;
parameter integer K_T_STATIC_RDATA_PAYLD_WIDTH = 17;
parameter integer K_T_STATIC_WDATA_PAYLD_WIDTH = 15;
parameter integer K_T_STATIC_BRSP_PAYLD_WIDTH = 2;
parameter integer K_T_EXCLUSIVE_WIDTH = 43;
parameter integer K_T_ADDR_AUGMENT_WIDTH = 114;
parameter integer K_T_DATA_AUGMENT_WIDTH = 14;
parameter integer K_T_BRSP_AUGMENT_WIDTH = 0;
parameter integer K_USABLE_T_ADDR_CASCADE_WIDTH = 626;
parameter integer K_USABLE_T_DATA_CASCADE_WIDTH = 526;
parameter integer K_USABLE_T_BRSP_CASCADE_WIDTH = 512;
parameter integer K_T_CASCADE_WIDTH = 627;
parameter integer K_T_SEG_LEN_WIDTH = 8;
parameter integer K_USABLE_T_ADDR_SIDEBAND_WIDTH = 699;
parameter integer K_USABLE_T_DATA_SIDEBAND_WIDTH = 691;
parameter integer K_USABLE_T_BRSP_SIDEBAND_WIDTH = 691;
parameter integer K_T_SIDEBAND_WIDTH = 700;
parameter integer K_USABLE_T_AXPAYLD_WIDTH = 808;
parameter integer K_USABLE_T_WPAYLD_WIDTH = 1853;
parameter integer K_USABLE_T_RPAYLD_WIDTH = 1759;
parameter integer K_USABLE_T_BPAYLD_WIDTH = 734;
parameter integer K_T_PAYLD_WIDTH = 1854;
parameter integer K_MAX_PAYLD_WIDTH = 1854;
parameter integer K_USABLE_T_AXVECTOR_WIDTH = 1145;
parameter integer K_USABLE_T_WVECTOR_WIDTH = 2177;
parameter integer K_USABLE_T_RVECTOR_WIDTH = 2083;
parameter integer K_USABLE_T_BVECTOR_WIDTH = 1058;
parameter integer K_STATIC_AXVECTOR_WIDTH = 25;
parameter integer K_STATIC_WVECTOR_WIDTH = 1;
parameter integer K_STATIC_RVECTOR_WIDTH = 3;
parameter integer K_STATIC_BVECTOR_WIDTH = 2;
parameter integer K_T_VECTOR_WIDTH = 2178;
parameter integer K_MAX_VECTOR_WIDTH = 2178;
`endif
@@ -0,0 +1,297 @@
// (c) Copyright 2016 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.
//-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cascade parameters and typedefs
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef logic [((T_SC_AWUSER_WIDTH == 0) ? 1 : T_SC_AWUSER_WIDTH)-1:0] t_sc_awuser;
typedef logic [((T_SC_ARUSER_WIDTH == 0) ? 1 : T_SC_ARUSER_WIDTH)-1:0] t_sc_aruser;
typedef logic [((T_SC_BUSER_WIDTH == 0) ? 1 : T_SC_BUSER_WIDTH )-1:0] t_sc_buser;
typedef logic [((T_SC_RUSER_BITS_PER_BYTE == 0) ? 1 : (T_SC_RUSER_BITS_PER_BYTE*(T_SC_RDATA_WIDTH/8)))-1:0] t_sc_ruser;
typedef logic [((T_SC_WUSER_BITS_PER_BYTE == 0) ? 1 : (T_SC_WUSER_BITS_PER_BYTE*(T_SC_WDATA_WIDTH/8)))-1:0] t_sc_wuser;
typedef logic [T_SC_ADDR_WIDTH-1:0] t_sc_addr;
typedef logic [T_SC_MSC_ROUTE_WIDTH-1:0] t_sc_msc_route;
typedef logic [T_SC_SSC_ROUTE_WIDTH-1:0] t_sc_ssc_route;
typedef logic [(T_SC_ID_WIDTH==0?1:T_SC_ID_WIDTH)-1:0] t_sc_id;
typedef logic [(T_SC_WUSER_BITS_PER_BYTE+8)-1:0] t_sc_wuserdata_unit;
typedef logic [(T_SC_RUSER_BITS_PER_BYTE+8)-1:0] t_sc_ruserdata_unit;
typedef logic [T_SC_RDATA_WIDTH -1:0] t_sc_rdata;
typedef logic [T_SC_WDATA_WIDTH-1:0] t_sc_wdata;
typedef logic [(T_SC_WDATA_WIDTH/8)-1:0] t_sc_wstrb;
typedef struct packed {
t_sc_wuserdata_unit userdata;
logic strb;
} t_sc_wdata_unit;
typedef struct packed {
t_sc_ruserdata_unit userdata;
} t_sc_rdata_unit;
typedef struct packed {
t_sc_id id;
t_axi_len len;
t_axi_size size;
} t_sc_addr_exclusive;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// payld parameters and typedefs
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct packed {
t_axi_cache cache;
t_axi_qos qos;
t_axi_prot prot;
t_axi_lock lock;
t_sc_addr addr;
t_sc_id id;
t_sc_aruser user;
t_max_byte_size last_offset;
t_sc_addr_exclusive exclusive;
t_max_ep_route ep_route;
t_axi_len seg_len;
t_sc_msc_route sc_route;
} t_sc_arpayld;
typedef struct packed {
t_axi_cache cache;
t_axi_qos qos;
t_axi_prot prot;
t_axi_lock lock;
t_sc_addr addr;
t_sc_id id;
t_sc_awuser user;
t_max_byte_size last_offset;
t_sc_addr_exclusive exclusive;
t_max_ep_route ep_route;
t_axi_len seg_len;
t_sc_msc_route sc_route;
} t_sc_awpayld;
typedef struct packed {
t_sc_wdata_unit[(T_SC_WDATA_WIDTH/8)-1:0] bytes;
t_axi_last last;
t_max_byte_size last_offset;
t_max_byte_size first_offset;
t_sc_msc_route sc_route;
} t_sc_wpayld;
typedef struct packed {
t_sc_rdata_unit[(T_SC_RDATA_WIDTH/8)-1:0] bytes;
t_axi_last last;
t_axi_resp resp;
t_sc_id id;
t_max_byte_size last_offset;
t_max_byte_size first_offset;
t_sc_ssc_route sc_route;
} t_sc_rpayld;
typedef struct packed {
t_axi_resp resp;
t_sc_id id;
t_sc_buser user;
t_sc_ssc_route sc_route;
} t_sc_bpayld;
//synthesis translate_off
`ifdef MODEL_TECH
function string sprint_sc_addr_exclusive(
input t_sc_addr_exclusive excl
);
string str;
str = "";
str = $sformatf("exclusive.id = 0x%0x\n%s", excl.id,str);
str = $sformatf("exclusive.len = 0x%0x\n%s", excl.len,str);
str = $sformatf("exclusive.size = 0x%0x\n%s", excl.size,str);
return (str);
endfunction
function string sprint_sc_awpayld(
input t_sc_awpayld pay
);
string str;
str = "";
str = sprint_sc_addr_exclusive(pay.exclusive);
str = $sformatf("ep_route = 0x%0x\n%s", pay.ep_route,str);
str = $sformatf("user = 0x%0x\n%s", pay.user,str);
str = $sformatf("sc_route = 0x%0x\n%s", pay.sc_route,str);
str = $sformatf("seg_len = 0x%0x\n%s", pay.seg_len,str);
str = $sformatf("id = 0x%0x\n%s", pay.id,str);
str = $sformatf("addr = 0x%0x\n%s", pay.addr,str);
str = $sformatf("lock = 0x%0x\n%s", pay.lock,str);
str = $sformatf("prot = 0x%0x\n%s", pay.prot,str);
str = $sformatf("qos = 0x%0x\n%s", pay.qos,str);
str = $sformatf("cache = 0x%0x\n%s", pay.cache,str);
str = $sformatf("AWPAYLD\n%s",str);
return (str);
endfunction : sprint_sc_awpayld
function string sprint_sc_arpayld(
input t_sc_arpayld pay
);
string str;
str = "";
str = sprint_sc_addr_exclusive(pay.exclusive);
str = $sformatf("ep_route = 0x%0x\n%s", pay.ep_route,str);
str = $sformatf("user = 0x%0x\n%s", pay.user,str);
str = $sformatf("sc_route = 0x%0x\n%s", pay.sc_route,str);
str = $sformatf("seg_len = 0x%0x\n%s", pay.seg_len,str);
str = $sformatf("id = 0x%0x\n%s", pay.id,str);
str = $sformatf("addr = 0x%0x\n%s", pay.addr,str);
str = $sformatf("lock = 0x%0x\n%s", pay.lock,str);
str = $sformatf("prot = 0x%0x\n%s", pay.prot,str);
str = $sformatf("qos = 0x%0x\n%s", pay.qos,str);
str = $sformatf("cache = 0x%0x\n%s", pay.cache,str);
str = $sformatf("ARPAYLD\n%s",str);
return (str);
endfunction : sprint_sc_arpayld
function string sprint_sc_wpayld(
input t_sc_wpayld pay
);
string str;
string strb;
string data;
str = "";
strb = "";
data = "";
str = $sformatf("first_offset = 0x%0x\n%s", pay.first_offset,str);
str = $sformatf("last_offset = 0x%0x\n%s", pay.last_offset,str);
str = $sformatf("sc_route = 0x%0x\n%S", pay.sc_route,str);
str = $sformatf("last = 0x%0x\n%s", pay.last,str);
for (int i = 0; i < T_SC_WDATA_WIDTH/8;i++) begin
data = $sformatf("%0x%s", pay.bytes[i].userdata, data);
strb = $sformatf("%0x%s", pay.bytes[i].strb, strb);
end
str = $sformatf("WPAYLD\n%sdata:%s\nstrb:%d\n",str,data,strb);
return (str);
endfunction : sprint_sc_wpayld
function string sprint_sc_rpayld(
input t_sc_rpayld pay
);
string str;
string data;
str = "";
data = "";
str = $sformatf("first_offset = 0x%0x\n%s", pay.first_offset,str);
str = $sformatf("last_offset = 0x%0x\n%s", pay.last_offset,str);
str = $sformatf("sc_route = 0x%0x\n%S", pay.sc_route,str);
str = $sformatf("id = 0x%0x\n%s", pay.id,str);
str = $sformatf("resp = 0x%0x\n%s", pay.resp,str);
str = $sformatf("last = 0x%0x\n%s", pay.last,str);
for (int i = 0; i < T_SC_RDATA_WIDTH/8;i++) begin
data = $sformatf("%0x%s", pay.bytes[i].userdata, data);
end
str = $sformatf("RPAYLD\n%sdata:%s\n",str,data);
return (str);
endfunction : sprint_sc_rpayld
function string sprint_sc_bpayld(
input t_sc_bpayld pay
);
string str;
str = "";
str = $sformatf("user = 0x%0x\n%s", pay.user,str);
str = $sformatf("sc_route = 0x%0x\n%s", pay.sc_route,str);
str = $sformatf("id = 0x%0x\n%s", pay.id,str);
str = $sformatf("resp = 0x%0x\n%s", pay.resp,str);
str = $sformatf("BPAYLD\n%s",str);
return (str);
endfunction : sprint_sc_bpayld
`endif
//synthesis translate_on
typedef struct packed {
t_axi_cache cache;
t_axi_qos qos;
t_axi_prot prot;
t_axi_lock lock;
t_axi_len len;
t_sc_addr addr;
t_sc_id id;
t_axi_size size;
t_axi_burst burst;
t_sc_awuser user;
} t_sc_awvector;
typedef struct packed {
t_axi_cache cache;
t_axi_qos qos;
t_axi_prot prot;
t_axi_lock lock;
t_axi_len len;
t_sc_addr addr;
t_sc_id id;
t_axi_size size;
t_axi_burst burst;
t_sc_aruser user;
} t_sc_arvector;
typedef struct packed {
t_sc_wstrb strb;
t_sc_wdata data;
t_axi_last last;
t_sc_wuser user;
} t_sc_wvector;
typedef struct packed {
t_sc_rdata data;
t_axi_last last;
t_axi_resp resp;
t_sc_id id;
t_sc_ruser user;
} t_sc_rvector;
typedef struct packed {
t_axi_resp resp;
t_sc_id id;
t_sc_buser user;
} t_sc_bvector;
@@ -0,0 +1,80 @@
`timescale 1ns / 1ps
/*
-------------------------------------------------------------------------------
-- $Id: util_vector_logic.v 2.0 2017/01/01
-------------------------------------------------------------------------------
--
-- ***************************************************************************
-- ** Copyright(C) 2017 by Xilinx, Inc. All rights reserved. **
-- ** **
-- ** This text contains proprietary, confidential **
-- ** information of Xilinx, Inc. , is distributed by **
-- ** 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. **
-- ** **
-- ** Unmodified source code is guaranteed to place and route, **
-- ** function and run at speed according to the datasheet **
-- ** specification. Source code is provided "as-is", with no **
-- ** obligation on the part of Xilinx to provide support. **
-- ** **
-- ** Xilinx Hotline support of source code IP shall only include **
-- ** standard level Xilinx Hotline support, and will only address **
-- ** issues and questions related to the standard released Netlist **
-- ** version of the core (and thus indirectly, the original core source). **
-- ** **
-- ** The Xilinx Support Hotline does not have access to source **
-- ** code and therefore cannot answer specific questions related **
-- ** to source HDL. The Xilinx Support Hotline will only be able **
-- ** to confirm the problem in the Netlist version of the core. **
-- ** **
-- ** This copyright and support notice must be retained as part **
-- ** of this text at all times. **
-- ***************************************************************************
--
-------------------------------------------------------------------------------
-- Filename: util_vector_logic.v
--
-- Description:
--
-- Verilog-Standard:
-------------------------------------------------------------------------------
*/
module util_vector_logic_v2_0_1_util_vector_logic ( Op1, Op2, Res);
parameter C_OPERATION = "and";
parameter integer C_SIZE = 8;
input [C_SIZE - 1:0] Op1;
input [C_SIZE - 1:0] Op2;
output [C_SIZE - 1:0] Res;
//wire [C_SIZE - 1:0] Res;
//parameter C_Oper = C_OPERATION;
generate if (C_OPERATION == "and") begin: GEN_AND_OP
assign Res = Op1 & Op2;
end
endgenerate
generate if (C_OPERATION == "or") begin: GEN_OR_OP
assign Res = Op1 | Op2;
end
endgenerate
generate if (C_OPERATION == "xor") begin: GEN_XOR_OP
assign Res = Op1 ^ Op2;
end
endgenerate
generate if (C_OPERATION == "not") begin: GEN_NOT_OP
assign Res = ~Op1;
end
endgenerate
endmodule // module util_vector_logic
@@ -0,0 +1,31 @@
//------------------------------------------------------------------------
//--
//-- Filename : xlconstant.v
//--
//-- Date : 06/05/12
//--
//-- Description : VERILOG description of a constant block. This
//-- block does not use a core.
//--
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//--
//-- Module : xlconstant
//--
//-- Architecture : behavior
//--
//-- Description : Top level VERILOG description of constant block
//--
//------------------------------------------------------------------------
`timescale 1ps/1ps
module xlconstant_v1_1_6_xlconstant (dout);
parameter CONST_VAL = 1;
parameter CONST_WIDTH = 1;
output [CONST_WIDTH-1:0] dout;
assign dout = CONST_VAL;
endmodule
@@ -0,0 +1,348 @@
`pragma protect begin_protected
`pragma protect version = 1
`pragma protect encrypt_agent = "XILINX"
`pragma protect encrypt_agent_info = "Xilinx Encryption Tool 2019.1"
`pragma protect key_keyowner = "Cadence Design Systems.", key_keyname = "cds_rsa_key", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 64)
`pragma protect key_block
gELWy08r0jYlAcXRjhPk3hCmplBGOfzhDyTX7hfSyHCRQ60u/LndvfQeYPYn7+2Pe/8PcDH2AIck
KvuEp5D8Cw==
`pragma protect key_keyowner = "Synopsys", key_keyname = "SNPS-VCS-RSA-2", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 128)
`pragma protect key_block
oXUljWB2VoNCDnMxDm+9hyWsrfZtSALGscrEWjDeGL/mndVPo0aJO8IemoL7j7mwLIpdWVW72JYX
gBigUyg9SvWRDlFUhGpSVhqk2uYa0k/eC/WeB6A9qNqHIEIfnTCLnJ6O1Lf4T2X8fBP/BRjkOY0P
1bCLNGNeZo3nuzJkM3w=
`pragma protect key_keyowner = "Aldec", key_keyname = "ALDEC15_001", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
I0UKE7tVnbo3p849NSned7oMnmGg3ZWimKO4fnrFo6RvcZCG/WgvnXzJJZ9Sg/E6LmW7zhK0i8MM
aOl9rK+G7xRx+/E6VBl0ISVCYhg5XJx6wqvOpONPNcoEHzHaHI1svRFNAEBsKheFNy9vF7v9m3nH
A+YHsORVJg8nKbGz9QLTff/qYkGhlXFpxCDvOvfgSOgxAIAYaT98W/ZFKj8cibgg+QYY/z2QuslK
kVB54gjG1aH16A5Xx7KOcs6wraRQJN4dtwjV/qCEtj8LKi14K9IlCQF9DdZlpYaCh2cKbGo4+ZfW
6mxbiweJOor6CxNCrdm164kFywvHD//Dnqls3w==
`pragma protect key_keyowner = "ATRENTA", key_keyname = "ATR-SG-2015-RSA-3", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
SjXcO3ZtEvYLuUTtV2BNTHB88+Oql6gisadEycHFpv9LFnvEwqQp3BbbIZqfjBNUk4TYDy76HFl+
EAguI08JFguiGM6m9t8plAuOJuxwaPKBikeOiqnJ3TUOkAwLdah6jGYS13FpbK+30NXXShuKOqO3
Q0hLSZff8moNz1fVvu/X3rjAJP1v+xrNnlhstYYXG2Yon8oND9WPONGrmV248lX4GGnRiojgQVbR
ZhJTr0mz/16ksIj76od82kPb/EL0D2EJcNoJmXgQm0SzLgm/ck4JlHrQoLlwxTeSF2dlg1fM+JJt
AQ0MX7wNU4OcmbgHOzb7AzX1C8qeVvv7/riOiw==
`pragma protect key_keyowner = "Xilinx", key_keyname = "xilinxt_2019_02", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
go1rqe/JUOcS+cuk4V07+ODXFpS5dYsTB+iDTy94E/F5cauBhqJ+tIeB9NgxcNXhOUIkFJrKbMiJ
03WKjjfQRObFnEzdOR3pVi4C4NcS7RMfgc4c4ES4/78F3XgfhW3MgEFW/rv5WGfC4xyMs6t3I5vb
tsNsNylkoCFdzJ+0/j2hipc7TzssXqesxPfk5wkrfFKrACu8p8ysqZqtlyEib4UmGqR/pRWzz8sh
3DGeGOdxrbLDHmFdxr8E+lYI9+chWEAOjXS5aLW+FDUod3AlKigxw4FGKn23+T0SY+rM28cjePid
/lr6uogwmOj2Vqhfi/hBkqZNZRl85EQg9nXa+Q==
`pragma protect key_keyowner = "Mentor Graphics Corporation", key_keyname = "MGC-VELOCE-RSA", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 128)
`pragma protect key_block
Qx0KrFrdnBmJDn6r2+A3gdZLSn2rm4WfW0qlIdxqefYetE4eyGNEXI8YFt6i/B1px5Yo3NPjJDBs
Oiv7jhb21ztsWlYuLy2jUfS4xj2V9KpjI4XTNNkDED0ahMtdpPSZawgcVFgoAPxTATgMQOvyEHGd
KZ+2Nu4GI7sUi0gUFzw=
`pragma protect key_keyowner = "Mentor Graphics Corporation", key_keyname = "MGC-VERIF-SIM-RSA-2", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
nkj9fRKjRpRMrOLIhAfcfiC10xcoVasx1t3Uv9FqfMKvY4GVVhjW3LTQnYJM5nUTkgCdRPVV3iU5
qfZDBY8e5JUmjk3OT2LK1pAKCLmcubqs7ghhshf1rROzkJ0Qdr2F6ssPOjkxFV3NTlPoixKbhaNT
ggjn39owMjAKuZT6sbCG833tcXNjyK4sCQkDL6C+JjLk8SYLJ4UkgSr9ch8whX1v++dM9jZJV1zo
DN6jHeaUCvai30K+a8mORoQ4CRa+9EWnG5vP6Bj9PDeLEo183uHy3kHXPnYB89Y0il+hCQGQps/S
a8ujlKdosw9/kOA5tJwaGV5Ewja1MaiwpG/loA==
`pragma protect data_method = "AES128-CBC"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 16160)
`pragma protect data_block
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
+umhCHNOJJDxVQsnmEU/KJHb6Hcry3fquwqwN94=
`pragma protect end_protected
@@ -0,0 +1,842 @@
/*****************************************************************************
* File : processing_system7_vip_v1_0_7_apis.v
*
* Date : 2012-11
*
* Description : Set of Zynq VIP APIs that are used for writing tests.
*
*****************************************************************************/
/* API for setting the STOP_ON_ERROR*/
task automatic set_stop_on_error;
input LEVEL;
begin
$display("[%0d] : %0s : Setting Stop On Error as %0b",$time, DISP_INFO, LEVEL);
STOP_ON_ERROR = LEVEL;
// M_AXI_GP0.master.set_stop_on_error(LEVEL);
// M_AXI_GP1.master.set_stop_on_error(LEVEL);
// S_AXI_GP0.slave.set_stop_on_error(LEVEL);
// S_AXI_GP1.slave.set_stop_on_error(LEVEL);
// S_AXI_HP0.slave.set_stop_on_error(LEVEL);
// S_AXI_HP1.slave.set_stop_on_error(LEVEL);
// S_AXI_HP2.slave.set_stop_on_error(LEVEL);
// S_AXI_HP3.slave.set_stop_on_error(LEVEL);
// S_AXI_ACP.slave.set_stop_on_error(LEVEL);
M_AXI_GP0.STOP_ON_ERROR = LEVEL;
M_AXI_GP1.STOP_ON_ERROR = LEVEL;
S_AXI_GP0.STOP_ON_ERROR = LEVEL;
S_AXI_GP1.STOP_ON_ERROR = LEVEL;
S_AXI_HP0.STOP_ON_ERROR = LEVEL;
S_AXI_HP1.STOP_ON_ERROR = LEVEL;
S_AXI_HP2.STOP_ON_ERROR = LEVEL;
S_AXI_HP3.STOP_ON_ERROR = LEVEL;
S_AXI_ACP.STOP_ON_ERROR = LEVEL;
end
endtask
/* API for setting the verbosity for channel level info*/
task automatic set_channel_level_info;
input [1023:0] name;
input LEVEL;
begin
$display("[%0d] : [%0s] : %0s Port/s : Setting Channel Level Info as %0b",$time, DISP_INFO, name , LEVEL);
case(name)
// "M_AXI_GP0" : M_AXI_GP0.master.set_channel_level_info(LEVEL);
// "M_AXI_GP1" : M_AXI_GP1.master.set_channel_level_info(LEVEL);
// "S_AXI_GP0" : S_AXI_GP0.slave.set_channel_level_info(LEVEL);
// "S_AXI_GP1" : S_AXI_GP1.slave.set_channel_level_info(LEVEL);
// "S_AXI_HP0" : S_AXI_HP0.slave.set_channel_level_info(LEVEL);
// "S_AXI_HP1" : S_AXI_HP1.slave.set_channel_level_info(LEVEL);
// "S_AXI_HP2" : S_AXI_HP2.slave.set_channel_level_info(LEVEL);
// "S_AXI_HP3" : S_AXI_HP3.slave.set_channel_level_info(LEVEL);
// "S_AXI_ACP" : S_AXI_ACP.slave.set_channel_level_info(LEVEL);
"ALL" : begin
// M_AXI_GP0.master.set_channel_level_info(LEVEL);
// M_AXI_GP1.master.set_channel_level_info(LEVEL);
// S_AXI_GP0.slave.set_channel_level_info(LEVEL);
// S_AXI_GP1.slave.set_channel_level_info(LEVEL);
// S_AXI_HP0.slave.set_channel_level_info(LEVEL);
// S_AXI_HP1.slave.set_channel_level_info(LEVEL);
// S_AXI_HP2.slave.set_channel_level_info(LEVEL);
// S_AXI_HP3.slave.set_channel_level_info(LEVEL);
// S_AXI_ACP.slave.set_channel_level_info(LEVEL);
end
default : $display("[%0d] : %0s : Invalid Port name (%0s)",$time, DISP_ERR, name);
endcase
end
endtask
/* API for setting the verbosity for function level info*/
task automatic set_function_level_info;
input [1023:0] name;
input LEVEL;
begin
$display("[%0d] : [%0s] : %0s Port/s : Setting Function Level Info as %0b",$time, DISP_INFO, name , LEVEL);
case(name)
// "M_AXI_GP0" : M_AXI_GP0.master.set_function_level_info(LEVEL);
// "M_AXI_GP1" : M_AXI_GP1.master.set_function_level_info(LEVEL);
// "S_AXI_GP0" : S_AXI_GP0.slave.set_function_level_info(LEVEL);
// "S_AXI_GP1" : S_AXI_GP1.slave.set_function_level_info(LEVEL);
// "S_AXI_HP0" : S_AXI_HP0.slave.set_function_level_info(LEVEL);
// "S_AXI_HP1" : S_AXI_HP1.slave.set_function_level_info(LEVEL);
// "S_AXI_HP2" : S_AXI_HP2.slave.set_function_level_info(LEVEL);
// "S_AXI_HP3" : S_AXI_HP3.slave.set_function_level_info(LEVEL);
// "S_AXI_ACP" : S_AXI_ACP.slave.set_function_level_info(LEVEL);
"ALL" : begin
// M_AXI_GP0.master.set_function_level_info(LEVEL);
// M_AXI_GP1.master.set_function_level_info(LEVEL);
// S_AXI_GP0.slave.set_function_level_info(LEVEL);
// S_AXI_GP1.slave.set_function_level_info(LEVEL);
// S_AXI_HP0.slave.set_function_level_info(LEVEL);
// S_AXI_HP1.slave.set_function_level_info(LEVEL);
// S_AXI_HP2.slave.set_function_level_info(LEVEL);
// S_AXI_HP3.slave.set_function_level_info(LEVEL);
// S_AXI_ACP.slave.set_function_level_info(LEVEL);
end
default : $display("[%0d] : %0s : Invalid Port name (%0s)",$time, DISP_ERR, name);
endcase
end
endtask
/* API for setting the Message verbosity */
task automatic set_debug_level_info;
input LEVEL;
begin
$display("[%0d] : %0s : Setting Debug Level Info as %0b",$time, DISP_INFO, LEVEL);
DEBUG_INFO = LEVEL;
M_AXI_GP0.DEBUG_INFO = LEVEL;
M_AXI_GP1.DEBUG_INFO = LEVEL;
S_AXI_GP0.DEBUG_INFO = LEVEL;
S_AXI_GP1.DEBUG_INFO = LEVEL;
S_AXI_HP0.DEBUG_INFO = LEVEL;
S_AXI_HP1.DEBUG_INFO = LEVEL;
S_AXI_HP2.DEBUG_INFO = LEVEL;
S_AXI_HP3.DEBUG_INFO = LEVEL;
S_AXI_ACP.DEBUG_INFO = LEVEL;
end
endtask
/* API for setting ARQos Values */
task automatic set_arqos;
input [1023:0] name;
input [axi_qos_width-1:0] value;
begin
$display("[%0d] : [%0s] : %0s Port/s : Setting AWQOS as %0b",$time, DISP_INFO, name , value);
case(name)
"S_AXI_GP0" : S_AXI_GP0.set_arqos(value);
"S_AXI_GP1" : S_AXI_GP1.set_arqos(value);
"S_AXI_HP0" : S_AXI_HP0.set_arqos(value);
"S_AXI_HP1" : S_AXI_HP1.set_arqos(value);
"S_AXI_HP2" : S_AXI_HP2.set_arqos(value);
"S_AXI_HP3" : S_AXI_HP3.set_arqos(value);
"S_AXI_ACP" : S_AXI_ACP.set_arqos(value);
default : $display("[%0d] : %0s : Invalid Slave Port name (%0s)",$time, DISP_ERR, name);
endcase
end
endtask
/* API for setting AWQos Values */
task automatic set_awqos;
input [1023:0] name;
input [axi_qos_width-1:0] value;
begin
$display("[%0d] : [%0s] : %0s Port/s : Setting ARQOS as %0b",$time, DISP_INFO, name , value);
case(name)
"S_AXI_GP0" : S_AXI_GP0.set_awqos(value);
"S_AXI_GP1" : S_AXI_GP1.set_awqos(value);
"S_AXI_HP0" : S_AXI_HP0.set_awqos(value);
"S_AXI_HP1" : S_AXI_HP1.set_awqos(value);
"S_AXI_HP2" : S_AXI_HP2.set_awqos(value);
"S_AXI_HP3" : S_AXI_HP3.set_awqos(value);
"S_AXI_ACP" : S_AXI_ACP.set_awqos(value);
default : $display("[%0d] : %0s : Invalid Slave Port (%0s)",$time, DISP_ERR, name);
endcase
end
endtask
/* API for soft reset control */
task automatic fpga_soft_reset;
input[data_width-1:0] reset_ctrl;
begin
if(DEBUG_INFO) $display("[%0d] : %0s : FPGA Soft Reset called for 0x%0h",$time, DISP_INFO, reset_ctrl);
gen_rst.fpga_soft_reset(reset_ctrl);
end
endtask
/* API for por and strb reset control */
// task automatic por_srstb_reset;
// input por_reset_ctrl;
// begin
// if(DEBUG_INFO) $display("[%0d] : %0s : POR and STRB Reset called for 0x%0h",$time, DISP_INFO, por_reset_ctrl);
// // gen_rst.por_srstb_reset(por_reset_ctrl);
// gen_rst.por_srstb_reset(por_reset_ctrl);
//
// end
// endtask
/* API for pre-loading memories from (DDR/OCM model) */
task automatic pre_load_mem_from_file;
input [(max_chars*8)-1:0] file_name;
input [addr_width-1:0] start_addr;
input [int_width-1:0] no_of_bytes;
reg [1:0] mem_type;
integer succ;
begin
mem_type = decode_address(start_addr);
succ = $fopen(file_name,"r");
if(succ == 0) begin
$display("[%0d] : %0s : '%0s' doesn't exist. 'pre_load_mem_from_file' call failed ...\n",$time, DISP_ERR, file_name);
if(STOP_ON_ERROR) $stop;
end
else if(check_addr_aligned(start_addr)) begin
case(mem_type)
OCM_MEM : begin
if (!C_HIGH_OCM_EN)
ocmc.ocm.pre_load_mem_from_file(file_name,start_addr,no_of_bytes);
else
ocmc.ocm.pre_load_mem_from_file(file_name,(start_addr - high_ocm_start_addr),no_of_bytes);
if(DEBUG_INFO)
$display("[%0d] : %0s : Starting Address(0x%0h) -> OCM Memory is pre-loaded with %0d bytes of data from file %0s",$time, DISP_INFO, start_addr, no_of_bytes, file_name);
end
DDR_MEM : begin
ddrc.ddr.pre_load_mem_from_file(file_name,start_addr,no_of_bytes);
if(DEBUG_INFO)
$display("[%0d] : %0s : Starting Address(0x%0h) -> DDR Memory is pre-loaded with %0d bytes of data from file %0s",$time, DISP_INFO, start_addr, no_of_bytes, file_name);
end
default : begin
$display("[%0d] : %0s : Address(0x%0h) is out-of-range. 'pre_load_mem_from_file' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end
endcase
end else begin
$display("[%0d] : %0s : Address(0x%0h) has to be 32-bit aligned. 'pre_load_mem_from_file' call failed ...",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR)
$stop;
end
end
endtask
/* API for pre-loading memories (DDR/OCM) */
task automatic pre_load_mem;
input [1:0] data_type;
input [addr_width-1:0] start_addr;
input [int_width-1:0] no_of_bytes;
reg [1:0] mem_type;
begin
mem_type = decode_address(start_addr);
if(check_addr_aligned(start_addr)) begin
case(mem_type)
OCM_MEM : begin
if (!C_HIGH_OCM_EN)
ocmc.ocm.pre_load_mem(data_type,start_addr,no_of_bytes);
else
ocmc.ocm.pre_load_mem(data_type,(start_addr - high_ocm_start_addr),no_of_bytes);
if(DEBUG_INFO)
$display("[%0d] : %0s : Starting Address(0x%0h) -> OCM Memory is pre-loaded with %0d bytes of data",$time, DISP_INFO, start_addr, no_of_bytes);
end
DDR_MEM : begin
ddrc.ddr.pre_load_mem(data_type,start_addr,no_of_bytes);
if(DEBUG_INFO)
$display("[%0d] : %0s : Starting Address(0x%0h) -> DDR Memory is pre-loaded with %0d bytes of data",$time, DISP_INFO, start_addr, no_of_bytes);
end
default : begin
$display("[%0d] : %0s : Address(0x%0h) is out-of-range. 'pre_load_mem' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end
endcase
end else begin
$display("[%0d] : %0s : Address(0x%0h) has to be 32-bit aligned. 'pre_load_mem' call failed ...",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end
end
endtask
/* API for backdoor write to memories (DDR/OCM) */
task automatic write_mem;
input [max_burst_bits-1 :0] data;
input [addr_width-1:0] start_addr;
input [max_burst_bytes_width:0] no_of_bytes;
reg [1:0] mem_type;
integer succ;
begin
mem_type = decode_address(start_addr);
if(check_addr_aligned(start_addr)) begin
case(mem_type)
OCM_MEM : begin
if (!C_HIGH_OCM_EN)
ocmc.ocm.write_mem(data,start_addr,no_of_bytes,all_strb_valid);
else
ocmc.ocm.write_mem(data,(start_addr - high_ocm_start_addr),no_of_bytes,all_strb_valid);
if(DEBUG_INFO)
$display("[%0d] : %0s : Starting Address(0x%0h) -> Write %0d bytes of data to OCM Memory",$time, DISP_INFO, start_addr, no_of_bytes);
end
DDR_MEM : begin
ddrc.ddr.write_mem(data,start_addr,no_of_bytes,all_strb_valid);
if(DEBUG_INFO)
$display("[%0d] : %0s : Starting Address(0x%0h) -> Write %0d bytes of data to DDR Memory",$time, DISP_INFO, start_addr, no_of_bytes);
end
default : begin
$display("[%0d] : %0s : Address(0x%0h) is out-of-range. 'write_mem' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end
endcase
end else begin
$display("[%0d] : %0s : Address(0x%0h) has to be 32-bit aligned. 'write_mem' call failed ...",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR)
$stop;
end
end
endtask
/* read_memory */
task automatic read_mem;
input [addr_width-1:0] start_addr;
input [max_burst_bytes_width :0] no_of_bytes;
output[max_burst_bits-1 :0] data;
reg [1:0] mem_type;
integer succ;
begin
mem_type = decode_address(start_addr);
if(check_addr_aligned(start_addr)) begin
case(mem_type)
OCM_MEM : begin
if (!C_HIGH_OCM_EN)
ocmc.ocm.read_mem(data,start_addr,no_of_bytes);
else
ocmc.ocm.read_mem(data,(start_addr - high_ocm_start_addr),no_of_bytes);
if(DEBUG_INFO)
$display("[%0d] : %0s : Starting Address(0x%0h) -> Read %0d bytes of data from OCM Memory ",$time, DISP_INFO, start_addr, no_of_bytes);
end
DDR_MEM : begin
ddrc.ddr.read_mem(data,start_addr,no_of_bytes);
if(DEBUG_INFO)
$display("[%0d] : %0s : Starting Address(0x%0h) -> Read %0d bytes of data from DDR Memory",$time, DISP_INFO, start_addr, no_of_bytes);
end
default : begin
$display("[%0d] : %0s : Address(0x%0h) is out-of-range. 'read_mem' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end
endcase
end else begin
$display("[%0d] : %0s : Address(0x%0h) has to be 32-bit aligned. 'read_mem' call failed ...",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR)
$stop;
end
end
endtask
/* API for backdoor read to memories (DDR/OCM) */
task automatic peek_mem_to_file;
input [(max_chars*8)-1:0] file_name;
input [addr_width-1:0] start_addr;
input [int_width-1:0] no_of_bytes;
reg [1:0] mem_type;
integer succ;
begin
mem_type = decode_address(start_addr);
if(check_addr_aligned(start_addr)) begin
case(mem_type)
OCM_MEM : begin
if (!C_HIGH_OCM_EN)
ocmc.ocm.peek_mem_to_file(file_name,start_addr,no_of_bytes);
else
ocmc.ocm.peek_mem_to_file(file_name,(start_addr - high_ocm_start_addr),no_of_bytes);
if(DEBUG_INFO)
$display("[%0d] : %0s : Starting Address(0x%0h) -> Peeked %0d bytes of data from OCM Memory to file %0s",$time, DISP_INFO, start_addr, no_of_bytes, file_name);
end
DDR_MEM : begin
ddrc.ddr.peek_mem_to_file(file_name,start_addr,no_of_bytes);
if(DEBUG_INFO)
$display("[%0d] : %0s : Starting Address(0x%0h) -> Peeked %0d bytes of data from DDR Memory to file %0s",$time, DISP_INFO, start_addr, no_of_bytes, file_name);
end
default : begin
$display("[%0d] : %0s : Address(0x%0h) is out-of-range. 'peek_mem_to_file' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end
endcase
end else begin
$display("[%0d] : %0s : Address(0x%0h) has to be 32-bit aligned. 'peek_mem_to_file' call failed ...",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR)
$stop;
end
end
endtask
/* API to read interrupt status */
task automatic read_interrupt;
output[irq_width-1:0] irq_status;
begin
irq_status = IRQ_F2P;
if(DEBUG_INFO) $display("[%0d] : %0s : Reading Interrupt Status as 0x%0h",$time, DISP_INFO, irq_status);
end
endtask
/* API to wait on interrup */
task automatic wait_interrupt;
input [3:0] irq;
output[irq_width-1:0] irq_status;
begin
if(DEBUG_INFO) $display("[%0d] : %0s : Waiting on Interrupt irq[%0d]",$time, DISP_INFO, irq);
case(irq)
0 : wait(IRQ_F2P[0] === 1'b1);
1 : wait(IRQ_F2P[1] === 1'b1);
2 : wait(IRQ_F2P[2] === 1'b1);
3 : wait(IRQ_F2P[3] === 1'b1);
4 : wait(IRQ_F2P[4] === 1'b1);
5 : wait(IRQ_F2P[5] === 1'b1);
6 : wait(IRQ_F2P[6] === 1'b1);
7 : wait(IRQ_F2P[7] === 1'b1);
8 : wait(IRQ_F2P[8] === 1'b1);
9 : wait(IRQ_F2P[9] === 1'b1);
10: wait(IRQ_F2P[10] === 1'b1);
11: wait(IRQ_F2P[11] === 1'b1);
12: wait(IRQ_F2P[12] === 1'b1);
13: wait(IRQ_F2P[13] === 1'b1);
14: wait(IRQ_F2P[14] === 1'b1);
15: wait(IRQ_F2P[15] === 1'b1);
default : $display("[%0d] : %0s : Only 16 Interrupt lines (irq_fp0:irq_fp15) are supported",$time, DISP_ERR);
endcase
if(DEBUG_INFO) $display("[%0d] : %0s : Received Interrupt irq[%0d]",$time, DISP_INFO, irq);
irq_status = IRQ_F2P;
end
endtask
/* API to wait for a certain match pattern*/
task automatic wait_mem_update;
input[addr_width-1:0] address;
input[data_width-1:0] data_in;
output[data_width-1:0] data_out;
reg[data_width-1:0] datao;
begin
if(mem_update_key) begin
mem_update_key = 0;
if(DEBUG_INFO) $display("[%0d] : %0s : 'wait_mem_update' called for Address(0x%0h) , Match Pattern(0x%0h) \n",$time, DISP_INFO, address, data_in);
if(check_addr_aligned(address)) begin
ddrc.ddr.wait_mem_update(address, datao);
if(datao != data_in)begin
$display("[%0d] : %0s : Address(0x%0h) -> DATA PATTERN MATCH FAILED, Expected data = 0x%0h, Received data = 0x%0h \n",$time, DISP_ERR, address, data_in,datao);
$stop;
end else
$display("[%0d] : %0s : Address(0x%0h) -> DATA PATTERN(0x%0h) MATCHED \n",$time, DISP_INFO, address, data_in);
data_out = datao;
end else begin
$display("[%0d] : %0s : Address(0x%0h) has to be 32-bit aligned. 'wait_mem_update' call failed ...\n",$time, DISP_ERR, address);
if(STOP_ON_ERROR) $stop;
end
mem_update_key = 1;
end else
$display("[%0d] : %0s : One instance of 'wait_mem_update' thread is already running.Only one instance can be called at a time ...\n",$time, DISP_WARN);
end
endtask
/* API to initiate a WRITE transaction on one of the AXI-Master ports*/
task automatic write_from_file;
input [(max_chars*8)-1:0] file_name;
input [addr_width-1:0] start_addr;
input [int_width-1:0] wr_size;
output [axi_rsp_width-1:0] response;
integer succ;
begin
succ = $fopen(file_name,"r");
if(succ == 0) begin
$display("[%0d] : %0s : '%0s' doesn't exist. 'write_from_file' call failed ...\n",$time, DISP_ERR, file_name);
if(STOP_ON_ERROR) $stop;
end
else if(!check_master_address(start_addr)) begin
$display("[%0d] : %0s : Master Address(0x%0h) is out of range\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end else if(check_addr_aligned(start_addr)) begin
$fclose(succ);
// case(start_addr[31:30])
if (start_addr[31:30] === 2'b01) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Starting Address(0x%0h) -> AXI Write -> %0d bytes from file %0s",$time, DISP_INFO, start_addr, wr_size, file_name);
M_AXI_GP0.write_from_file(file_name,start_addr,wr_size,response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Done AXI Write for Starting Address(0x%0h)",$time, DISP_INFO, start_addr);
end else if(start_addr[31:30] === 2'b10) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Starting Address(0x%0h) -> AXI Write -> %0d bytes from file %0s",$time, DISP_INFO, start_addr, wr_size, file_name);
M_AXI_GP1.write_from_file(file_name,start_addr,wr_size,response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Done AXI Write for Starting Address(0x%0h)",$time, DISP_INFO, start_addr);
end else begin
$display("[%0d] : %0s : Invalid Address(0x%0h) 'write_from_file' call failed ...\n",$time, DISP_ERR, start_addr);
end
// endcase
end else begin
$display("[%0d] : %0s : Address(0x%0h) has to be 32-bit aligned. 'write_from_file' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end
end
endtask
/* API to initiate a READ transaction on one of the AXI-Master ports*/
task automatic read_to_file;
input [(max_chars*8)-1:0] file_name;
input [addr_width-1:0] start_addr;
input [int_width-1:0] rd_size;
output [axi_rsp_width-1:0] response;
begin
if(!check_master_address(start_addr)) begin
$display("[%0d] : %0s : Master Address(0x%0h) is out of range\n",$time, DISP_ERR , start_addr);
if(STOP_ON_ERROR) $stop;
end else if(check_addr_aligned(start_addr)) begin
// case(start_addr[31:30])
if (start_addr[31:30] === 2'b01) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Starting Address(0x%0h) -> AXI Read -> %0d bytes to file %0s",$time, DISP_INFO, start_addr, rd_size, file_name);
M_AXI_GP0.read_to_file(file_name,start_addr,rd_size,response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Done AXI Read for Starting Address(0x%0h)",$time, DISP_INFO, start_addr);
end else if(start_addr[31:30] === 2'b10) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Starting Address(0x%0h) -> AXI Read -> %0d bytes to file %0s",$time, DISP_INFO, start_addr, rd_size, file_name);
M_AXI_GP1.read_to_file(file_name,start_addr,rd_size,response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Done AXI Read for Starting Address(0x%0h)",$time, DISP_INFO, start_addr);
// end
// default : $display("[%0d] : %0s : Invalid Address(0x%0h) 'read_to_file' call failed ...\n",$time, DISP_ERR, start_addr);
// endcase
end else begin
$display("[%0d] : %0s : Address(0x%0h) has to be 32-bit aligned. 'read_to_file' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end
end
end
endtask
/* API to initiate a WRITE transaction(<= 128 bytes) on one of the AXI-Master ports*/
task automatic write_data;
input [addr_width-1:0] start_addr;
input [max_transfer_bytes_width:0] wr_size;
input [(max_transfer_bytes*8)-1:0] w_data;
output [axi_rsp_width-1:0] response;
reg[511:0] rsp;
begin
if(!check_master_address(start_addr)) begin
$display("[%0d] : %0s : Master Address(0x%0h) is out of range. 'write_data' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end else if(wr_size > max_transfer_bytes) begin
$display("[%0d] : %0s : Byte Size supported is 128 bytes only. 'write_data' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end else if(start_addr[31:30] === GP_M0) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Starting Address(0x%0h) -> AXI Write -> %0d bytes",$time, DISP_INFO, start_addr, wr_size);
M_AXI_GP0.write_data(start_addr,wr_size,w_data,response);
rsp = get_resp(response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Done AXI Write for Starting Address(0x%0h) with Response '%0s'",$time, DISP_INFO, start_addr, rsp);
end else if(start_addr[31:30] === GP_M1) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Starting Address(0x%0h) -> AXI Write -> %0d bytes",$time, DISP_INFO, start_addr, wr_size);
M_AXI_GP1.write_data(start_addr,wr_size,w_data,response);
rsp = get_resp(response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Done AXI Write for Starting Address(0x%0h) with Response '%0s'",$time, DISP_INFO, start_addr, rsp);
end else
$display("[%0d] : %0s : Invalid Address(0x%0h) 'write_data' call failed ...\n",$time, DISP_ERR, start_addr);
end
endtask
/* API to initiate a READ transaction(<= 128 bytes) on one of the AXI-Master ports*/
task automatic read_data;
input [addr_width-1:0] start_addr;
input [max_transfer_bytes_width:0] rd_size;
output[(max_transfer_bytes*8)-1:0] rd_data;
output [axi_rsp_width-1:0] response;
reg[511:0] rsp;
begin
if(!check_master_address(start_addr)) begin
$display("[%0d] : %0s : Master Address(0x%0h) is out of range 'read_data' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end else if(rd_size > max_transfer_bytes) begin
$display("[%0d] : %0s : Byte Size supported is 128 bytes only.'read_data' call failed ... \n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end else if(start_addr[31:30] === GP_M0) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Starting Address(0x%0h) -> AXI Read -> %0d bytes",$time, DISP_INFO, start_addr, rd_size);
M_AXI_GP0.read_data(start_addr,rd_size,rd_data,response);
rsp = get_resp(response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Done AXI Read for Starting Address(0x%0h) with Response '%0s'",$time, DISP_INFO, start_addr, rsp);
end else if(start_addr[31:30] === GP_M1) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Starting Address(0x%0h) -> AXI Read -> %0d bytes",$time, DISP_INFO, start_addr, rd_size);
M_AXI_GP1.read_data(start_addr,rd_size,rd_data,response);
rsp = get_resp(response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Done AXI Read for Starting Address(0x%0h) with Response '%0s'",$time, DISP_INFO, start_addr, rsp);
end else
$display("[%0d] : %0s : Invalid Address(0x%0h) 'read_data' call failed ...\n",$time, DISP_ERR, start_addr);
end
endtask
/* Hooks to call to VIP APIs */
task automatic write_burst(input [addr_width-1:0] start_addr,input [axi_len_width-1:0] len,input [axi_size_width-1:0] siz,input [axi_brst_type_width-1:0] burst,input [axi_lock_width-1:0] lck,input [axi_cache_width-1:0] cache,input [axi_prot_width-1:0] prot,input [(axi_mgp_data_width*axi_burst_len)-1:0] data,input integer datasize, output [axi_rsp_width-1:0] response);
reg[511:0] rsp;
begin
if(!check_master_address(start_addr)) begin
$display("[%0d] : %0s : Master Address(0x%0h) is out of range. 'write_burst' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end else if(start_addr[31:30] === 2'b01) begin
// end else if(start_addr[31:30] === GP_M0) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Starting Address(0x%0h) -> AXI Write -> %0d bytes",$time, DISP_INFO, start_addr, datasize);
M_AXI_GP0.write_burst(start_addr,len,siz,burst,lck,cache,prot,data,datasize,response);
rsp = get_resp(response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Done AXI Write for Starting Address(0x%0h) with Response '%0s'",$time, DISP_INFO, start_addr, rsp);
end else if(start_addr[31:30] === 2'b10) begin
// end else if(start_addr[31:30] === GP_M1) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Starting Address(0x%0h) -> AXI Write -> %0d bytes",$time, DISP_INFO, start_addr, datasize);
M_AXI_GP1.write_burst(start_addr,len,siz,burst,lck,cache,prot,data,datasize,response);
rsp = get_resp(response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Done AXI Write for Starting Address(0x%0h) with Response '%0s'",$time, DISP_INFO, start_addr, rsp);
end else
$display("[%0d] : %0s : Invalid Address(0x%0h) 'write_burst' call failed ... \n",$time, DISP_ERR, start_addr);
end
endtask
task automatic write_burst_concurrent(input [addr_width-1:0] start_addr,input [axi_len_width-1:0] len,input [axi_size_width-1:0] siz,input [axi_brst_type_width-1:0] burst,input [axi_lock_width-1:0] lck,input [axi_cache_width-1:0] cache,input [axi_prot_width-1:0] prot,input [(axi_mgp_data_width*axi_burst_len)-1:0] data,input integer datasize, output [axi_rsp_width-1:0] response);
reg[511:0] rsp; /// string for response
begin
if(!check_master_address(start_addr)) begin
$display("[%0d] : %0s : Master Address(0x%0h) is out of range. 'write_burst_concurrent' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end else if(start_addr[31:30] === 2'b01) begin
// end else if(start_addr[31:30] === GP_M0) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Starting Address(0x%0h) -> AXI Write -> %0d bytes",$time, DISP_INFO, start_addr, datasize);
M_AXI_GP0.write_burst_concurrent(start_addr,len,siz,burst,lck,cache,prot,data,datasize,response);
rsp = get_resp(response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Done AXI Write for Starting Address(0x%0h) with Response '%0s'",$time, DISP_INFO, start_addr, rsp);
end else if(start_addr[31:30] === 2'b10) begin
// end else if(start_addr[31:30] === GP_M1) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Starting Address(0x%0h) -> AXI Write -> %0d bytes",$time, DISP_INFO, start_addr, datasize);
M_AXI_GP1.write_burst_concurrent(start_addr,len,siz,burst,lck,cache,prot,data,datasize,response);
rsp = get_resp(response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Done AXI Write for Starting Address(0x%0h) with Response '%0s'",$time, DISP_INFO, start_addr, rsp);
end else
$display("[%0d] : %0s : Invalid Address(0x%0h) 'write_burst_concurrent' call failed ... \n",$time, DISP_ERR, start_addr);
end
endtask
task automatic read_burst;
input [addr_width-1:0] start_addr;
input [axi_len_width-1:0] len;
input [axi_size_width-1:0] siz;
input [axi_brst_type_width-1:0] burst;
input [axi_lock_width-1:0] lck;
input [axi_cache_width-1:0] cache;
input [axi_prot_width-1:0] prot;
output [(axi_mgp_data_width*axi_burst_len)-1:0] data;
output [(axi_rsp_width*axi_burst_len)-1:0] response;
reg[511:0] rsp;
begin
if(!check_master_address(start_addr)) begin
$display("[%0d] : %0s : Master Address(0x%0h) is out of range. 'read_burst' call failed ...\n",$time, DISP_ERR, start_addr);
if(STOP_ON_ERROR) $stop;
end else if(start_addr[31:30] === 2'b01) begin
// end else if(start_addr[31:30] === GP_M0) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Starting Address(0x%0h) -> AXI Read",$time, DISP_INFO, start_addr);
M_AXI_GP0.read_burst(start_addr,len,siz,burst,lck,cache,prot,data,response);
rsp = get_resp(response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : Done AXI Read for Starting Address(0x%0h) with Response '%0s'",$time, DISP_INFO, start_addr, rsp);
end else if(start_addr[31:30] === 2'b10) begin
// end else if(start_addr[31:30] === GP_M1) begin
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Starting Address(0x%0h) -> AXI Read",$time, DISP_INFO, start_addr);
M_AXI_GP1.read_burst(start_addr,len,siz,burst,lck,cache,prot,data,response);
rsp = get_resp(response);
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : Done AXI Read for Starting Address(0x%0h) with Response '%0s'",$time, DISP_INFO, start_addr, rsp);
end else
$display("[%0d] : %0s : Invalid Address(0x%0h) 'read_burst' call failed ... \n",$time, DISP_ERR, start_addr);
end
endtask
task automatic wait_reg_update;
input [addr_width-1:0] addr;
input [data_width-1:0] data_i;
input [data_width-1:0] mask_i;
input [int_width-1:0] time_interval;
input [int_width-1:0] time_out;
output [data_width-1:0] data_o;
reg upd_done0;
reg upd_done1;
begin
if(!check_master_address(addr)) begin
$display("[%0d] : %0s : Address(0x%0h) is out of range. 'wait_reg_update' call failed ...\n",$time, DISP_ERR, addr);
if(STOP_ON_ERROR) $stop;
end else if(addr[31:30] === 2'b01) begin
// end else if(addr[31:30] === GP_M0) begin
if(reg_update_key_0) begin
reg_update_key_0 = 0;
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP0 : %0s : 'wait_reg_update' called for Address(0x%0h), Mask(0x%0h), Match Pattern(0x%0h) \n ",$time, DISP_INFO, addr, mask_i, data_i);
M_AXI_GP0.wait_reg_update(addr, data_i, mask_i, time_interval, time_out, data_o, upd_done0);
if(DEBUG_INFO && upd_done0)
$display("[%0d] : M_AXI_GP0 : %0s : Register mapped at Address(0x%0h) is updated ",$time, DISP_INFO, addr);
reg_update_key_0 = 1;
end else
$display("[%0d] : M_AXI_GP0 : One instance of 'wait_reg_update' thread is already running.Only one instance can be called at a time ...\n",$time, DISP_WARN);
end else if(addr[31:30] === 2'b10) begin
// end else if(addr[31:30] === GP_M1) begin
if(reg_update_key_1) begin
reg_update_key_1 = 0;
if(DEBUG_INFO)
$display("[%0d] : M_AXI_GP1 : %0s : 'wait_reg_update' called for Address(0x%0h), Mask(0x%0h), Match Pattern(0x%0h) \n ",$time, DISP_INFO, addr, mask_i, data_i);
M_AXI_GP1.wait_reg_update(addr, data_i, mask_i, time_interval, time_out, data_o, upd_done1);
if(DEBUG_INFO && upd_done1)
$display("[%0d] : M_AXI_GP1 : %0s : Register mapped at Address(0x%0h) is updated ",$time, DISP_INFO, addr);
reg_update_key_1 = 1;
end else
$display("[%0d] : M_AXI_GP1 : One instance of 'wait_reg_update' thread is already running.Only one instance can be called at a time ...\n",$time, DISP_WARN);
end else
$display("[%0d] : %0s : Invalid Address(0x%0h) 'wait_reg_update' call failed ... \n",$time, DISP_ERR, addr);
end
endtask
/* API to read register map */
task read_register_map;
input [addr_width-1:0] start_addr;
input [max_regs_width:0] no_of_registers;
output[max_burst_bits-1 :0] data;
reg [max_regs_width:0] no_of_regs;
begin
no_of_regs = no_of_registers;
if(no_of_registers > 32) begin
$display("[%0d] : %0s : No_of_Registers(%0d) exceeds the supported number (32).\n Only 32 registers will be read.",$time, DISP_ERR, start_addr);
no_of_regs = 32;
end
if(check_addr_aligned(start_addr)) begin
if(decode_address(start_addr) == REG_MEM) begin
if(DEBUG_INFO) $display("[%0d] : %0s : Reading Registers starting address (0x%0h) -> %0d registers",$time, DISP_INFO, start_addr,no_of_regs );
regc.regm.read_reg_mem(data,start_addr,no_of_regs*4); /// as each register is of 4 bytes
if(DEBUG_INFO) $display("[%0d] : %0s : DONE -> Reading Registers starting address (0x%0h), Data returned(0x%0h)",$time, DISP_INFO, start_addr, data );
end else begin
$display("[%0d] : %0s : Invalid Address(0x%0h) for Register Read. 'read_register_map' call failed ...",$time, DISP_ERR, start_addr);
end
end else begin
data = 0;
$display("[%0d] : %0s : Address(0x%0h) has to be 32-bit aligned. 'read_register_map' call failed ...",$time, DISP_ERR, start_addr);
end
end
endtask
/* API to read single register */
task read_register;
input [addr_width-1:0] addr;
output[data_width-1:0] data;
begin
if(check_addr_aligned(addr)) begin
if(decode_address(addr) == REG_MEM) begin
if(DEBUG_INFO) $display("[%0d] : %0s : Reading Register (0x%0h) ",$time, DISP_INFO, addr );
regc.regm.get_data(addr >> 2, data);
if(DEBUG_INFO) $display("[%0d] : %0s : DONE -> Reading Register (0x%0h), Data returned(0x%0h)",$time, DISP_INFO, addr, data );
end else begin
$display("[%0d] : %0s : Invalid Address(0x%0h) for Register Read. 'read_register' call failed ...",$time, DISP_ERR, addr);
end
end else begin
data = 0;
$display("[%0d] : %0s : Address(0x%0h) has to be 32-bit aligned. 'read_register' call failed ...",$time, DISP_ERR, addr);
end
end
endtask
/* API to set the AXI-Slave profile*/
task automatic set_slave_profile;
input[1023:0] name;
input[1:0] latency ;
begin
if(DEBUG_INFO) $display("[%0d] : %0s : %0s Port/s : Setting Slave profile",$time, DISP_INFO, name);
case(name)
"S_AXI_GP0" : S_AXI_GP0.set_latency_type(latency);
"S_AXI_GP1" : S_AXI_GP1.set_latency_type(latency);
"S_AXI_HP0" : S_AXI_HP0.set_latency_type(latency);
"S_AXI_HP1" : S_AXI_HP1.set_latency_type(latency);
"S_AXI_HP2" : S_AXI_HP2.set_latency_type(latency);
"S_AXI_HP3" : S_AXI_HP3.set_latency_type(latency);
"S_AXI_ACP" : S_AXI_ACP.set_latency_type(latency);
"ALL" : begin
S_AXI_GP0.set_latency_type(latency);
S_AXI_GP1.set_latency_type(latency);
S_AXI_HP0.set_latency_type(latency);
S_AXI_HP1.set_latency_type(latency);
S_AXI_HP2.set_latency_type(latency);
S_AXI_HP3.set_latency_type(latency);
S_AXI_ACP.set_latency_type(latency);
end
endcase
end
endtask
/*------------------------------ LOCAL APIs ------------------------------------------------ */
/* local API for address decoding*/
function automatic [1:0] decode_address;
input [addr_width-1:0] address;
begin
if(!C_HIGH_OCM_EN && (address < ocm_end_addr || address >= ocm_low_addr ))
decode_address = OCM_MEM; /// OCM
else if(address >= ddr_start_addr && address <= ddr_end_addr)
decode_address = DDR_MEM; /// DDR
else if(C_HIGH_OCM_EN && address >= high_ocm_start_addr)
decode_address = OCM_MEM; /// OCM
else if(address >= reg_start_addr && reg_start_addr <= reg_end_addr)
decode_address = REG_MEM; /// Register Map
else
decode_address = INVALID_MEM_TYPE; /// ERROR in Address
end
endfunction
/* local API for checking address is 32-bit (4-byte) aligned */
function automatic check_addr_aligned;
input [addr_width-1:0] address;
begin
if((address%4) !=0 ) begin //
check_addr_aligned = 0; ///not_aligned
end else
check_addr_aligned = 1;
end
endfunction
/* local API to check address for GP Masters */
function check_master_address;
input [addr_width-1:0] address;
begin
if(address >= m_axi_gp0_baseaddr && address <= m_axi_gp0_highaddr)
check_master_address = 1'b1;
else if(address >= m_axi_gp1_baseaddr && address <= m_axi_gp1_highaddr)
check_master_address = 1'b1;
else
check_master_address = 1'b0; /// ERROR in Address
end
endfunction
/* Response decode */
function automatic [511:0] get_resp;
input[axi_rsp_width-1:0] response;
begin
case(response)
2'b00 : get_resp = "OKAY";
2'b01 : get_resp = "EXOKAY";
2'b10 : get_resp = "SLVERR";
2'b11 : get_resp = "DECERR";
endcase
end
endfunction
@@ -0,0 +1,94 @@
/*****************************************************************************
* File : processing_system7_vip_v1_0_7_axi_acp.v
*
* Date : 2012-11
*
* Description : Connections for ACP port
*
*****************************************************************************/
/* AXI Slave ACP */
processing_system7_vip_v1_0_7_axi_slave_acp #( C_USE_S_AXI_ACP, // enable
axi_acp_name, // name
axi_acp_data_width, // data width
addr_width, /// address width
axi_acp_id_width, // ID width
C_S_AXI_ACP_BASEADDR, // slave base address
C_S_AXI_ACP_HIGHADDR,// slave size
axi_acp_outstanding, // outstanding transactions // 7 Reads and 3 Writes
axi_slv_excl_support, // Exclusive access support
axi_acp_wr_outstanding,
axi_acp_rd_outstanding)
S_AXI_ACP(.S_RESETN (net_axi_acp_rstn),
.S_ACLK (S_AXI_ACP_ACLK),
// Write Address Channel
.S_AWID (S_AXI_ACP_AWID),
.S_AWADDR (S_AXI_ACP_AWADDR),
.S_AWLEN (S_AXI_ACP_AWLEN),
.S_AWSIZE (S_AXI_ACP_AWSIZE),
.S_AWBURST (S_AXI_ACP_AWBURST),
.S_AWLOCK (S_AXI_ACP_AWLOCK),
.S_AWCACHE (S_AXI_ACP_AWCACHE),
.S_AWPROT (S_AXI_ACP_AWPROT),
.S_AWVALID (S_AXI_ACP_AWVALID),
.S_AWREADY (S_AXI_ACP_AWREADY),
// Write Data Channel Signals.
.S_WID (S_AXI_ACP_WID),
.S_WDATA (S_AXI_ACP_WDATA),
.S_WSTRB (S_AXI_ACP_WSTRB),
.S_WLAST (S_AXI_ACP_WLAST),
.S_WVALID (S_AXI_ACP_WVALID),
.S_WREADY (S_AXI_ACP_WREADY),
// Write Response Channel Signals.
.S_BID (S_AXI_ACP_BID),
.S_BRESP (S_AXI_ACP_BRESP),
.S_BVALID (S_AXI_ACP_BVALID),
.S_BREADY (S_AXI_ACP_BREADY),
// Read Address Channel Signals.
.S_ARID (S_AXI_ACP_ARID),
.S_ARADDR (S_AXI_ACP_ARADDR),
.S_ARLEN (S_AXI_ACP_ARLEN),
.S_ARSIZE (S_AXI_ACP_ARSIZE),
.S_ARBURST (S_AXI_ACP_ARBURST),
.S_ARLOCK (S_AXI_ACP_ARLOCK),
.S_ARCACHE (S_AXI_ACP_ARCACHE),
.S_ARPROT (S_AXI_ACP_ARPROT),
.S_ARVALID (S_AXI_ACP_ARVALID),
.S_ARREADY (S_AXI_ACP_ARREADY),
// Read Data Channel Signals.
.S_RID (S_AXI_ACP_RID),
.S_RDATA (S_AXI_ACP_RDATA),
.S_RRESP (S_AXI_ACP_RRESP),
.S_RLAST (S_AXI_ACP_RLAST),
.S_RVALID (S_AXI_ACP_RVALID),
.S_RREADY (S_AXI_ACP_RREADY),
// Side band signals
.S_AWQOS (S_AXI_ACP_AWQOS),
.S_ARQOS (S_AXI_ACP_ARQOS), // Side band signals
.SW_CLK (net_sw_clk),
/* This goes to port 0 of DDR and port 0 of OCM , port 0 of REG*/
.WR_DATA_ACK_DDR (ddr_wr_ack_port0),
.WR_DATA_ACK_OCM (ocm_wr_ack_port0),
.WR_DATA (net_wr_data_acp),
.WR_DATA_STRB (net_wr_strb_acp),
.WR_ADDR (net_wr_addr_acp),
.WR_BYTES (net_wr_bytes_acp),
.WR_DATA_VALID_DDR (ddr_wr_dv_port0),
.WR_DATA_VALID_OCM (ocm_wr_dv_port0),
.WR_QOS (net_wr_qos_acp),
.RD_REQ_DDR (ddr_rd_req_port0),
.RD_REQ_OCM (ocm_rd_req_port0),
.RD_REQ_REG (reg_rd_req_port0),
.RD_ADDR (net_rd_addr_acp),
.RD_DATA_DDR (ddr_rd_data_port0),
.RD_DATA_OCM (ocm_rd_data_port0),
.RD_DATA_REG (reg_rd_data_port0),
.RD_BYTES (net_rd_bytes_acp),
.RD_DATA_VALID_DDR (ddr_rd_dv_port0),
.RD_DATA_VALID_OCM (ocm_rd_dv_port0),
.RD_DATA_VALID_REG (reg_rd_dv_port0),
.RD_QOS (net_rd_qos_acp)
);
@@ -0,0 +1,311 @@
/*****************************************************************************
* File : processing_system7_vip_v1_0_7_axi_gp.v
*
* Date : 2012-11
*
* Description : Connections for AXI GP ports
*
*****************************************************************************/
/* IDs for Masters
// l2m1 (CPU000)
12'b11_000_000_00_00
12'b11_010_000_00_00
12'b11_011_000_00_00
12'b11_100_000_00_00
12'b11_101_000_00_00
12'b11_110_000_00_00
12'b11_111_000_00_00
// l2m1 (CPU001)
12'b11_000_001_00_00
12'b11_010_001_00_00
12'b11_011_001_00_00
12'b11_100_001_00_00
12'b11_101_001_00_00
12'b11_110_001_00_00
12'b11_111_001_00_00
*/
/* AXI -Master GP0 */
processing_system7_vip_v1_0_7_axi_master #(C_USE_M_AXI_GP0, // enable
axi_mgp0_name,// name
axi_mgp_data_width, /// Data Width
addr_width, /// Address width
axi_mgp_id_width, //// ID Width
axi_mgp_outstanding, //// Outstanding transactions
axi_mst_excl_support, // EXCL Access Support
axi_mgp_wr_id, //WR_ID
axi_mgp_rd_id) //RD_ID
M_AXI_GP0(.M_RESETN (net_axi_mgp0_rstn),
.M_ACLK (M_AXI_GP0_ACLK),
// Write Address Channel
.M_AWID (M_AXI_GP0_AWID_FULL),
.M_AWADDR (M_AXI_GP0_AWADDR),
.M_AWLEN (M_AXI_GP0_AWLEN),
.M_AWSIZE (M_AXI_GP0_AWSIZE),
.M_AWBURST (M_AXI_GP0_AWBURST),
.M_AWLOCK (M_AXI_GP0_AWLOCK),
.M_AWCACHE (M_AXI_GP0_AWCACHE),
.M_AWPROT (M_AXI_GP0_AWPROT),
.M_AWVALID (M_AXI_GP0_AWVALID),
.M_AWREADY (M_AXI_GP0_AWREADY),
// Write Data Channel Signals.
.M_WID (M_AXI_GP0_WID_FULL),
.M_WDATA (M_AXI_GP0_WDATA),
.M_WSTRB (M_AXI_GP0_WSTRB),
.M_WLAST (M_AXI_GP0_WLAST),
.M_WVALID (M_AXI_GP0_WVALID),
.M_WREADY (M_AXI_GP0_WREADY),
// Write Response Channel Signals.
.M_BID (M_AXI_GP0_BID_FULL),
.M_BRESP (M_AXI_GP0_BRESP),
.M_BVALID (M_AXI_GP0_BVALID),
.M_BREADY (M_AXI_GP0_BREADY),
// Read Address Channel Signals.
.M_ARID (M_AXI_GP0_ARID_FULL),
.M_ARADDR (M_AXI_GP0_ARADDR),
.M_ARLEN (M_AXI_GP0_ARLEN),
.M_ARSIZE (M_AXI_GP0_ARSIZE),
.M_ARBURST (M_AXI_GP0_ARBURST),
.M_ARLOCK (M_AXI_GP0_ARLOCK),
.M_ARCACHE (M_AXI_GP0_ARCACHE),
.M_ARPROT (M_AXI_GP0_ARPROT),
.M_ARVALID (M_AXI_GP0_ARVALID),
.M_ARREADY (M_AXI_GP0_ARREADY),
// Read Data Channel Signals.
.M_RID (M_AXI_GP0_RID_FULL),
.M_RDATA (M_AXI_GP0_RDATA),
.M_RRESP (M_AXI_GP0_RRESP),
.M_RLAST (M_AXI_GP0_RLAST),
.M_RVALID (M_AXI_GP0_RVALID),
.M_RREADY (M_AXI_GP0_RREADY),
// Side band signals
.M_AWQOS (M_AXI_GP0_AWQOS),
.M_ARQOS (M_AXI_GP0_ARQOS)
);
/* AXI Master GP1 */
processing_system7_vip_v1_0_7_axi_master #(C_USE_M_AXI_GP1, // enable
axi_mgp1_name,// name
axi_mgp_data_width, /// Data Width
addr_width, /// Address width
axi_mgp_id_width, //// ID Width
axi_mgp_outstanding, //// Outstanding transactions
axi_mst_excl_support, // EXCL Access Support
axi_mgp_wr_id, //WR_ID
axi_mgp_rd_id) //RD_ID
M_AXI_GP1(.M_RESETN (net_axi_mgp1_rstn),
.M_ACLK (M_AXI_GP1_ACLK),
// Write Address Channel
.M_AWID (M_AXI_GP1_AWID_FULL),
.M_AWADDR (M_AXI_GP1_AWADDR),
.M_AWLEN (M_AXI_GP1_AWLEN),
.M_AWSIZE (M_AXI_GP1_AWSIZE),
.M_AWBURST (M_AXI_GP1_AWBURST),
.M_AWLOCK (M_AXI_GP1_AWLOCK),
.M_AWCACHE (M_AXI_GP1_AWCACHE),
.M_AWPROT (M_AXI_GP1_AWPROT),
.M_AWVALID (M_AXI_GP1_AWVALID),
.M_AWREADY (M_AXI_GP1_AWREADY),
// Write Data Channel Signals.
.M_WID (M_AXI_GP1_WID_FULL),
.M_WDATA (M_AXI_GP1_WDATA),
.M_WSTRB (M_AXI_GP1_WSTRB),
.M_WLAST (M_AXI_GP1_WLAST),
.M_WVALID (M_AXI_GP1_WVALID),
.M_WREADY (M_AXI_GP1_WREADY),
// Write Response Channel Signals.
.M_BID (M_AXI_GP1_BID_FULL),
.M_BRESP (M_AXI_GP1_BRESP),
.M_BVALID (M_AXI_GP1_BVALID),
.M_BREADY (M_AXI_GP1_BREADY),
// Read Address Channel Signals.
.M_ARID (M_AXI_GP1_ARID_FULL),
.M_ARADDR (M_AXI_GP1_ARADDR),
.M_ARLEN (M_AXI_GP1_ARLEN),
.M_ARSIZE (M_AXI_GP1_ARSIZE),
.M_ARBURST (M_AXI_GP1_ARBURST),
.M_ARLOCK (M_AXI_GP1_ARLOCK),
.M_ARCACHE (M_AXI_GP1_ARCACHE),
.M_ARPROT (M_AXI_GP1_ARPROT),
.M_ARVALID (M_AXI_GP1_ARVALID),
.M_ARREADY (M_AXI_GP1_ARREADY),
// Read Data Channel Signals.
.M_RID (M_AXI_GP1_RID_FULL),
.M_RDATA (M_AXI_GP1_RDATA),
.M_RRESP (M_AXI_GP1_RRESP),
.M_RLAST (M_AXI_GP1_RLAST),
.M_RVALID (M_AXI_GP1_RVALID),
.M_RREADY (M_AXI_GP1_RREADY),
// Side band signals
.M_AWQOS (M_AXI_GP1_AWQOS),
.M_ARQOS (M_AXI_GP1_ARQOS)
);
/* AXI Slave GP0 */
processing_system7_vip_v1_0_7_axi_slave #(C_USE_S_AXI_GP0, /// enable
axi_sgp0_name, //name
axi_sgp_data_width, /// data width
addr_width, /// address width
axi_sgp_id_width, /// ID width
C_S_AXI_GP0_BASEADDR,//// base address
C_S_AXI_GP0_HIGHADDR,/// Memory size (high_addr - base_addr)
axi_sgp_outstanding, // outstanding transactions
axi_slv_excl_support, // exclusive access not supported
axi_sgp_wr_outstanding,
axi_sgp_rd_outstanding)
S_AXI_GP0(.S_RESETN (net_axi_gp0_rstn),
.S_ACLK (S_AXI_GP0_ACLK),
// Write Address Channel
.S_AWID (S_AXI_GP0_AWID),
.S_AWADDR (S_AXI_GP0_AWADDR),
.S_AWLEN (S_AXI_GP0_AWLEN),
.S_AWSIZE (S_AXI_GP0_AWSIZE),
.S_AWBURST (S_AXI_GP0_AWBURST),
.S_AWLOCK (S_AXI_GP0_AWLOCK),
.S_AWCACHE (S_AXI_GP0_AWCACHE),
.S_AWPROT (S_AXI_GP0_AWPROT),
.S_AWVALID (S_AXI_GP0_AWVALID),
.S_AWREADY (S_AXI_GP0_AWREADY),
// Write Data Channel Signals.
.S_WID (S_AXI_GP0_WID),
.S_WDATA (S_AXI_GP0_WDATA),
.S_WSTRB (S_AXI_GP0_WSTRB),
.S_WLAST (S_AXI_GP0_WLAST),
.S_WVALID (S_AXI_GP0_WVALID),
.S_WREADY (S_AXI_GP0_WREADY),
// Write Response Channel Signals.
.S_BID (S_AXI_GP0_BID),
.S_BRESP (S_AXI_GP0_BRESP),
.S_BVALID (S_AXI_GP0_BVALID),
.S_BREADY (S_AXI_GP0_BREADY),
// Read Address Channel Signals.
.S_ARID (S_AXI_GP0_ARID),
.S_ARADDR (S_AXI_GP0_ARADDR),
.S_ARLEN (S_AXI_GP0_ARLEN),
.S_ARSIZE (S_AXI_GP0_ARSIZE),
.S_ARBURST (S_AXI_GP0_ARBURST),
.S_ARLOCK (S_AXI_GP0_ARLOCK),
.S_ARCACHE (S_AXI_GP0_ARCACHE),
.S_ARPROT (S_AXI_GP0_ARPROT),
.S_ARVALID (S_AXI_GP0_ARVALID),
.S_ARREADY (S_AXI_GP0_ARREADY),
// Read Data Channel Signals.
.S_RID (S_AXI_GP0_RID),
.S_RDATA (S_AXI_GP0_RDATA),
.S_RRESP (S_AXI_GP0_RRESP),
.S_RLAST (S_AXI_GP0_RLAST),
.S_RVALID (S_AXI_GP0_RVALID),
.S_RREADY (S_AXI_GP0_RREADY),
// Side band signals
.S_AWQOS (S_AXI_GP0_AWQOS),
.S_ARQOS (S_AXI_GP0_ARQOS),
.SW_CLK (net_sw_clk),
.WR_DATA_ACK_OCM (net_wr_ack_ocm_gp0),
.WR_DATA_ACK_DDR (net_wr_ack_ddr_gp0),
.WR_DATA (net_wr_data_gp0),
.WR_DATA_STRB (net_wr_strb_gp0),
.WR_ADDR (net_wr_addr_gp0),
.WR_BYTES (net_wr_bytes_gp0),
.WR_DATA_VALID_OCM (net_wr_dv_ocm_gp0),
.WR_DATA_VALID_DDR (net_wr_dv_ddr_gp0),
.WR_QOS (net_wr_qos_gp0),
.RD_REQ_DDR (net_rd_req_ddr_gp0),
.RD_REQ_OCM (net_rd_req_ocm_gp0),
.RD_REQ_REG (net_rd_req_reg_gp0),
.RD_ADDR (net_rd_addr_gp0),
.RD_DATA_DDR (net_rd_data_ddr_gp0),
.RD_DATA_OCM (net_rd_data_ocm_gp0),
.RD_DATA_REG (net_rd_data_reg_gp0),
.RD_BYTES (net_rd_bytes_gp0),
.RD_DATA_VALID_DDR (net_rd_dv_ddr_gp0),
.RD_DATA_VALID_OCM (net_rd_dv_ocm_gp0),
.RD_DATA_VALID_REG (net_rd_dv_reg_gp0),
.RD_QOS (net_rd_qos_gp0)
);
/* AXI Slave GP1 */
processing_system7_vip_v1_0_7_axi_slave #(C_USE_S_AXI_GP1, /// enable
axi_sgp1_name, //name
axi_sgp_data_width, /// data width
addr_width, /// address width
axi_sgp_id_width, /// ID width
C_S_AXI_GP1_BASEADDR,//// base address
C_S_AXI_GP1_HIGHADDR,/// HIGh_addr
axi_sgp_outstanding, // outstanding transactions
axi_slv_excl_support, // exclusive access
axi_sgp_wr_outstanding,
axi_sgp_rd_outstanding)
S_AXI_GP1(.S_RESETN (net_axi_gp1_rstn),
.S_ACLK (S_AXI_GP1_ACLK),
// Write Address Channel
.S_AWID (S_AXI_GP1_AWID),
.S_AWADDR (S_AXI_GP1_AWADDR),
.S_AWLEN (S_AXI_GP1_AWLEN),
.S_AWSIZE (S_AXI_GP1_AWSIZE),
.S_AWBURST (S_AXI_GP1_AWBURST),
.S_AWLOCK (S_AXI_GP1_AWLOCK),
.S_AWCACHE (S_AXI_GP1_AWCACHE),
.S_AWPROT (S_AXI_GP1_AWPROT),
.S_AWVALID (S_AXI_GP1_AWVALID),
.S_AWREADY (S_AXI_GP1_AWREADY),
// Write Data Channel Signals.
.S_WID (S_AXI_GP1_WID),
.S_WDATA (S_AXI_GP1_WDATA),
.S_WSTRB (S_AXI_GP1_WSTRB),
.S_WLAST (S_AXI_GP1_WLAST),
.S_WVALID (S_AXI_GP1_WVALID),
.S_WREADY (S_AXI_GP1_WREADY),
// Write Response Channel Signals.
.S_BID (S_AXI_GP1_BID),
.S_BRESP (S_AXI_GP1_BRESP),
.S_BVALID (S_AXI_GP1_BVALID),
.S_BREADY (S_AXI_GP1_BREADY),
// Read Address Channel Signals.
.S_ARID (S_AXI_GP1_ARID),
.S_ARADDR (S_AXI_GP1_ARADDR),
.S_ARLEN (S_AXI_GP1_ARLEN),
.S_ARSIZE (S_AXI_GP1_ARSIZE),
.S_ARBURST (S_AXI_GP1_ARBURST),
.S_ARLOCK (S_AXI_GP1_ARLOCK),
.S_ARCACHE (S_AXI_GP1_ARCACHE),
.S_ARPROT (S_AXI_GP1_ARPROT),
.S_ARVALID (S_AXI_GP1_ARVALID),
.S_ARREADY (S_AXI_GP1_ARREADY),
// Read Data Channel Signals.
.S_RID (S_AXI_GP1_RID),
.S_RDATA (S_AXI_GP1_RDATA),
.S_RRESP (S_AXI_GP1_RRESP),
.S_RLAST (S_AXI_GP1_RLAST),
.S_RVALID (S_AXI_GP1_RVALID),
.S_RREADY (S_AXI_GP1_RREADY),
// Side band signals
.S_AWQOS (S_AXI_GP1_AWQOS),
.S_ARQOS (S_AXI_GP1_ARQOS),
.SW_CLK (net_sw_clk),
.WR_DATA_ACK_DDR (net_wr_ack_ddr_gp1),
.WR_DATA_ACK_OCM (net_wr_ack_ocm_gp1),
.WR_DATA (net_wr_data_gp1),
.WR_DATA_STRB (net_wr_strb_gp1),
.WR_ADDR (net_wr_addr_gp1),
.WR_BYTES (net_wr_bytes_gp1),
.WR_DATA_VALID_OCM (net_wr_dv_ocm_gp1),
.WR_DATA_VALID_DDR (net_wr_dv_ddr_gp1),
.WR_QOS (net_wr_qos_gp1),
.RD_REQ_OCM (net_rd_req_ocm_gp1),
.RD_REQ_DDR (net_rd_req_ddr_gp1),
.RD_REQ_REG (net_rd_req_reg_gp1),
.RD_ADDR (net_rd_addr_gp1),
.RD_DATA_DDR (net_rd_data_ddr_gp1),
.RD_DATA_OCM (net_rd_data_ocm_gp1),
.RD_DATA_REG (net_rd_data_reg_gp1),
.RD_BYTES (net_rd_bytes_gp1),
.RD_DATA_VALID_OCM (net_rd_dv_ocm_gp1),
.RD_DATA_VALID_DDR (net_rd_dv_ddr_gp1),
.RD_DATA_VALID_REG (net_rd_dv_reg_gp1),
.RD_QOS (net_rd_qos_gp1)
);
@@ -0,0 +1,350 @@
/*****************************************************************************
* File : processing_system7_vip_v1_0_7_axi_hp.v
*
* Date : 2012-11
*
* Description : Connections for AXI HP ports
*
*****************************************************************************/
/* AXI Slave HP0 */
processing_system7_vip_v1_0_7_afi_slave #( C_USE_S_AXI_HP0, // enable
axi_hp0_name, // name
C_S_AXI_HP0_DATA_WIDTH, // data width
addr_width, /// address width
axi_hp_id_width, // ID width
C_S_AXI_HP0_BASEADDR, // slave base address
C_S_AXI_HP0_HIGHADDR, // slave size
axi_hp_outstanding, // outstanding transactions // dynamic for AFI ports
axi_slv_excl_support) // Exclusive access support
S_AXI_HP0(.S_RESETN (net_axi_hp0_rstn),
.S_ACLK (S_AXI_HP0_ACLK),
// Write Address channel
.S_AWID (S_AXI_HP0_AWID),
.S_AWADDR (S_AXI_HP0_AWADDR),
.S_AWLEN (S_AXI_HP0_AWLEN),
.S_AWSIZE (S_AXI_HP0_AWSIZE),
.S_AWBURST (S_AXI_HP0_AWBURST),
.S_AWLOCK (S_AXI_HP0_AWLOCK),
.S_AWCACHE (S_AXI_HP0_AWCACHE),
.S_AWPROT (S_AXI_HP0_AWPROT),
.S_AWVALID (S_AXI_HP0_AWVALID),
.S_AWREADY (S_AXI_HP0_AWREADY),
// Write Data channel signals.
.S_WID (S_AXI_HP0_WID),
.S_WDATA (S_AXI_HP0_WDATA),
.S_WSTRB (S_AXI_HP0_WSTRB),
.S_WLAST (S_AXI_HP0_WLAST),
.S_WVALID (S_AXI_HP0_WVALID),
.S_WREADY (S_AXI_HP0_WREADY),
// Write Response channel signals.
.S_BID (S_AXI_HP0_BID),
.S_BRESP (S_AXI_HP0_BRESP),
.S_BVALID (S_AXI_HP0_BVALID),
.S_BREADY (S_AXI_HP0_BREADY),
// Read Address channel signals.
.S_ARID (S_AXI_HP0_ARID),
.S_ARADDR (S_AXI_HP0_ARADDR),
.S_ARLEN (S_AXI_HP0_ARLEN),
.S_ARSIZE (S_AXI_HP0_ARSIZE),
.S_ARBURST (S_AXI_HP0_ARBURST),
.S_ARLOCK (S_AXI_HP0_ARLOCK),
.S_ARCACHE (S_AXI_HP0_ARCACHE),
.S_ARPROT (S_AXI_HP0_ARPROT),
.S_ARVALID (S_AXI_HP0_ARVALID),
.S_ARREADY (S_AXI_HP0_ARREADY),
// Read Data channel signals.
.S_RID (S_AXI_HP0_RID),
.S_RDATA (S_AXI_HP0_RDATA),
.S_RRESP (S_AXI_HP0_RRESP),
.S_RLAST (S_AXI_HP0_RLAST),
.S_RVALID (S_AXI_HP0_RVALID),
.S_RREADY (S_AXI_HP0_RREADY),
// Side band signals
.S_AWQOS (S_AXI_HP0_AWQOS),
.S_ARQOS (S_AXI_HP0_ARQOS),
// these are needed only for HP ports
.S_RDISSUECAP1_EN (S_AXI_HP0_RDISSUECAP1_EN),
.S_WRISSUECAP1_EN (S_AXI_HP0_WRISSUECAP1_EN),
.S_RCOUNT (S_AXI_HP0_RCOUNT),
.S_WCOUNT (S_AXI_HP0_WCOUNT),
.S_RACOUNT (S_AXI_HP0_RACOUNT),
.S_WACOUNT (S_AXI_HP0_WACOUNT),
.SW_CLK (net_sw_clk),
.WR_DATA_ACK_DDR (net_wr_ack_ddr_hp0),
.WR_DATA_ACK_OCM (net_wr_ack_ocm_hp0),
.WR_DATA (net_wr_data_hp0),
.WR_DATA_STRB (net_wr_strb_hp0),
.WR_ADDR (net_wr_addr_hp0),
.WR_BYTES (net_wr_bytes_hp0),
.WR_DATA_VALID_DDR (net_wr_dv_ddr_hp0),
.WR_DATA_VALID_OCM (net_wr_dv_ocm_hp0),
.WR_QOS (net_wr_qos_hp0),
.RD_REQ_DDR (net_rd_req_ddr_hp0),
.RD_REQ_OCM (net_rd_req_ocm_hp0),
.RD_ADDR (net_rd_addr_hp0),
.RD_DATA_DDR (net_rd_data_ddr_hp0),
.RD_DATA_OCM (net_rd_data_ocm_hp0),
.RD_BYTES (net_rd_bytes_hp0),
.RD_DATA_VALID_DDR (net_rd_dv_ddr_hp0),
.RD_DATA_VALID_OCM (net_rd_dv_ocm_hp0),
.RD_QOS (net_rd_qos_hp0)
);
/* AXI Slave HP1 */
processing_system7_vip_v1_0_7_afi_slave #( C_USE_S_AXI_HP1, // enable
axi_hp1_name, // name
C_S_AXI_HP1_DATA_WIDTH, // data width
addr_width, /// address width
axi_hp_id_width, // ID width
C_S_AXI_HP1_BASEADDR, // slave base address
C_S_AXI_HP1_HIGHADDR, // Slave size
axi_hp_outstanding, // outstanding transactions // dynamic for AFI ports
axi_slv_excl_support) // Exclusive access support
S_AXI_HP1(.S_RESETN (net_axi_hp1_rstn),
.S_ACLK (S_AXI_HP1_ACLK),
// Write Address channel
.S_AWID (S_AXI_HP1_AWID),
.S_AWADDR (S_AXI_HP1_AWADDR),
.S_AWLEN (S_AXI_HP1_AWLEN),
.S_AWSIZE (S_AXI_HP1_AWSIZE),
.S_AWBURST (S_AXI_HP1_AWBURST),
.S_AWLOCK (S_AXI_HP1_AWLOCK),
.S_AWCACHE (S_AXI_HP1_AWCACHE),
.S_AWPROT (S_AXI_HP1_AWPROT),
.S_AWVALID (S_AXI_HP1_AWVALID),
.S_AWREADY (S_AXI_HP1_AWREADY),
// Write Data channel signals.
.S_WID (S_AXI_HP1_WID),
.S_WDATA (S_AXI_HP1_WDATA),
.S_WSTRB (S_AXI_HP1_WSTRB),
.S_WLAST (S_AXI_HP1_WLAST),
.S_WVALID (S_AXI_HP1_WVALID),
.S_WREADY (S_AXI_HP1_WREADY),
// Write Response channel signals.
.S_BID (S_AXI_HP1_BID),
.S_BRESP (S_AXI_HP1_BRESP),
.S_BVALID (S_AXI_HP1_BVALID),
.S_BREADY (S_AXI_HP1_BREADY),
// Read Address channel signals.
.S_ARID (S_AXI_HP1_ARID),
.S_ARADDR (S_AXI_HP1_ARADDR),
.S_ARLEN (S_AXI_HP1_ARLEN),
.S_ARSIZE (S_AXI_HP1_ARSIZE),
.S_ARBURST (S_AXI_HP1_ARBURST),
.S_ARLOCK (S_AXI_HP1_ARLOCK),
.S_ARCACHE (S_AXI_HP1_ARCACHE),
.S_ARPROT (S_AXI_HP1_ARPROT),
.S_ARVALID (S_AXI_HP1_ARVALID),
.S_ARREADY (S_AXI_HP1_ARREADY),
// Read Data channel signals.
.S_RID (S_AXI_HP1_RID),
.S_RDATA (S_AXI_HP1_RDATA),
.S_RRESP (S_AXI_HP1_RRESP),
.S_RLAST (S_AXI_HP1_RLAST),
.S_RVALID (S_AXI_HP1_RVALID),
.S_RREADY (S_AXI_HP1_RREADY),
// Side band signals
.S_AWQOS (S_AXI_HP1_AWQOS),
.S_ARQOS (S_AXI_HP1_ARQOS),
// these are needed only for HP ports
.S_RDISSUECAP1_EN (S_AXI_HP1_RDISSUECAP1_EN),
.S_WRISSUECAP1_EN (S_AXI_HP1_WRISSUECAP1_EN),
.S_RCOUNT (S_AXI_HP1_RCOUNT),
.S_WCOUNT (S_AXI_HP1_WCOUNT),
.S_RACOUNT (S_AXI_HP1_RACOUNT),
.S_WACOUNT (S_AXI_HP1_WACOUNT),
.SW_CLK (net_sw_clk),
.WR_DATA_ACK_DDR (net_wr_ack_ddr_hp1),
.WR_DATA_ACK_OCM (net_wr_ack_ocm_hp1),
.WR_DATA (net_wr_data_hp1),
.WR_DATA_STRB (net_wr_strb_hp1),
.WR_ADDR (net_wr_addr_hp1),
.WR_BYTES (net_wr_bytes_hp1),
.WR_DATA_VALID_DDR (net_wr_dv_ddr_hp1),
.WR_DATA_VALID_OCM (net_wr_dv_ocm_hp1),
.WR_QOS (net_wr_qos_hp1),
.RD_REQ_DDR (net_rd_req_ddr_hp1),
.RD_REQ_OCM (net_rd_req_ocm_hp1),
.RD_ADDR (net_rd_addr_hp1),
.RD_DATA_DDR (net_rd_data_ddr_hp1),
.RD_DATA_OCM (net_rd_data_ocm_hp1),
.RD_BYTES (net_rd_bytes_hp1),
.RD_DATA_VALID_DDR (net_rd_dv_ddr_hp1),
.RD_DATA_VALID_OCM (net_rd_dv_ocm_hp1),
.RD_QOS (net_rd_qos_hp1)
);
/* AXI Slave HP2 */
processing_system7_vip_v1_0_7_afi_slave #( C_USE_S_AXI_HP2, // enable
axi_hp2_name, // name
C_S_AXI_HP2_DATA_WIDTH, // data width
addr_width, /// address width
axi_hp_id_width, // ID width
C_S_AXI_HP2_BASEADDR, // slave base address
C_S_AXI_HP2_HIGHADDR, // SLave size
axi_hp_outstanding, // outstanding transactions // dynamic for AFI ports
axi_slv_excl_support) // Exclusive access support
S_AXI_HP2(.S_RESETN (net_axi_hp2_rstn),
.S_ACLK (S_AXI_HP2_ACLK),
// Write Address channel
.S_AWID (S_AXI_HP2_AWID),
.S_AWADDR (S_AXI_HP2_AWADDR),
.S_AWLEN (S_AXI_HP2_AWLEN),
.S_AWSIZE (S_AXI_HP2_AWSIZE),
.S_AWBURST (S_AXI_HP2_AWBURST),
.S_AWLOCK (S_AXI_HP2_AWLOCK),
.S_AWCACHE (S_AXI_HP2_AWCACHE),
.S_AWPROT (S_AXI_HP2_AWPROT),
.S_AWVALID (S_AXI_HP2_AWVALID),
.S_AWREADY (S_AXI_HP2_AWREADY),
// Write Data channel signals.
.S_WID (S_AXI_HP2_WID),
.S_WDATA (S_AXI_HP2_WDATA),
.S_WSTRB (S_AXI_HP2_WSTRB),
.S_WLAST (S_AXI_HP2_WLAST),
.S_WVALID (S_AXI_HP2_WVALID),
.S_WREADY (S_AXI_HP2_WREADY),
// Write Response channel signals.
.S_BID (S_AXI_HP2_BID),
.S_BRESP (S_AXI_HP2_BRESP),
.S_BVALID (S_AXI_HP2_BVALID),
.S_BREADY (S_AXI_HP2_BREADY),
// Read Address channel signals.
.S_ARID (S_AXI_HP2_ARID),
.S_ARADDR (S_AXI_HP2_ARADDR),
.S_ARLEN (S_AXI_HP2_ARLEN),
.S_ARSIZE (S_AXI_HP2_ARSIZE),
.S_ARBURST (S_AXI_HP2_ARBURST),
.S_ARLOCK (S_AXI_HP2_ARLOCK),
.S_ARCACHE (S_AXI_HP2_ARCACHE),
.S_ARPROT (S_AXI_HP2_ARPROT),
.S_ARVALID (S_AXI_HP2_ARVALID),
.S_ARREADY (S_AXI_HP2_ARREADY),
// Read Data channel signals.
.S_RID (S_AXI_HP2_RID),
.S_RDATA (S_AXI_HP2_RDATA),
.S_RRESP (S_AXI_HP2_RRESP),
.S_RLAST (S_AXI_HP2_RLAST),
.S_RVALID (S_AXI_HP2_RVALID),
.S_RREADY (S_AXI_HP2_RREADY),
// Side band signals
.S_AWQOS (S_AXI_HP2_AWQOS),
.S_ARQOS (S_AXI_HP2_ARQOS),
// these are needed only for HP ports
.S_RDISSUECAP1_EN (S_AXI_HP2_RDISSUECAP1_EN),
.S_WRISSUECAP1_EN (S_AXI_HP2_WRISSUECAP1_EN),
.S_RCOUNT (S_AXI_HP2_RCOUNT),
.S_WCOUNT (S_AXI_HP2_WCOUNT),
.S_RACOUNT (S_AXI_HP2_RACOUNT),
.S_WACOUNT (S_AXI_HP2_WACOUNT),
.SW_CLK (net_sw_clk),
.WR_DATA_ACK_DDR (net_wr_ack_ddr_hp2),
.WR_DATA_ACK_OCM (net_wr_ack_ocm_hp2),
.WR_DATA (net_wr_data_hp2),
.WR_DATA_STRB (net_wr_strb_hp2),
.WR_ADDR (net_wr_addr_hp2),
.WR_BYTES (net_wr_bytes_hp2),
.WR_DATA_VALID_DDR (net_wr_dv_ddr_hp2),
.WR_DATA_VALID_OCM (net_wr_dv_ocm_hp2),
.WR_QOS (net_wr_qos_hp2),
.RD_REQ_DDR (net_rd_req_ddr_hp2),
.RD_REQ_OCM (net_rd_req_ocm_hp2),
.RD_ADDR (net_rd_addr_hp2),
.RD_DATA_DDR (net_rd_data_ddr_hp2),
.RD_DATA_OCM (net_rd_data_ocm_hp2),
.RD_BYTES (net_rd_bytes_hp2),
.RD_DATA_VALID_DDR (net_rd_dv_ddr_hp2),
.RD_DATA_VALID_OCM (net_rd_dv_ocm_hp2),
.RD_QOS (net_rd_qos_hp2)
);
/* AXI Slave HP3 */
processing_system7_vip_v1_0_7_afi_slave #( C_USE_S_AXI_HP3, // enable
axi_hp3_name, // name
C_S_AXI_HP3_DATA_WIDTH, // data width
addr_width, /// address width
axi_hp_id_width, // ID width
C_S_AXI_HP3_BASEADDR, // slave base address
C_S_AXI_HP3_HIGHADDR, // SLave size
axi_hp_outstanding, // outstanding transactions // dynamic for AFI ports
axi_slv_excl_support) // Exclusive access support
S_AXI_HP3(.S_RESETN (net_axi_hp3_rstn),
.S_ACLK (S_AXI_HP3_ACLK),
// Write ADDRESS CHANNEL
.S_AWID (S_AXI_HP3_AWID),
.S_AWADDR (S_AXI_HP3_AWADDR),
.S_AWLEN (S_AXI_HP3_AWLEN),
.S_AWSIZE (S_AXI_HP3_AWSIZE),
.S_AWBURST (S_AXI_HP3_AWBURST),
.S_AWLOCK (S_AXI_HP3_AWLOCK),
.S_AWCACHE (S_AXI_HP3_AWCACHE),
.S_AWPROT (S_AXI_HP3_AWPROT),
.S_AWVALID (S_AXI_HP3_AWVALID),
.S_AWREADY (S_AXI_HP3_AWREADY),
// Write Data channel signals.
.S_WID (S_AXI_HP3_WID),
.S_WDATA (S_AXI_HP3_WDATA),
.S_WSTRB (S_AXI_HP3_WSTRB),
.S_WLAST (S_AXI_HP3_WLAST),
.S_WVALID (S_AXI_HP3_WVALID),
.S_WREADY (S_AXI_HP3_WREADY),
// Write Response channel signals.
.S_BID (S_AXI_HP3_BID),
.S_BRESP (S_AXI_HP3_BRESP),
.S_BVALID (S_AXI_HP3_BVALID),
.S_BREADY (S_AXI_HP3_BREADY),
// Read Address channel signals.
.S_ARID (S_AXI_HP3_ARID),
.S_ARADDR (S_AXI_HP3_ARADDR),
.S_ARLEN (S_AXI_HP3_ARLEN),
.S_ARSIZE (S_AXI_HP3_ARSIZE),
.S_ARBURST (S_AXI_HP3_ARBURST),
.S_ARLOCK (S_AXI_HP3_ARLOCK),
.S_ARCACHE (S_AXI_HP3_ARCACHE),
.S_ARPROT (S_AXI_HP3_ARPROT),
.S_ARVALID (S_AXI_HP3_ARVALID),
.S_ARREADY (S_AXI_HP3_ARREADY),
// Read Data channel signals.
.S_RID (S_AXI_HP3_RID),
.S_RDATA (S_AXI_HP3_RDATA),
.S_RRESP (S_AXI_HP3_RRESP),
.S_RLAST (S_AXI_HP3_RLAST),
.S_RVALID (S_AXI_HP3_RVALID),
.S_RREADY (S_AXI_HP3_RREADY),
// Side band signals
.S_AWQOS (S_AXI_HP3_AWQOS),
.S_ARQOS (S_AXI_HP3_ARQOS),
// these are needed only for HP ports
.S_RDISSUECAP1_EN (S_AXI_HP3_RDISSUECAP1_EN),
.S_WRISSUECAP1_EN (S_AXI_HP3_WRISSUECAP1_EN),
.S_RCOUNT (S_AXI_HP3_RCOUNT),
.S_WCOUNT (S_AXI_HP3_WCOUNT),
.S_RACOUNT (S_AXI_HP3_RACOUNT),
.S_WACOUNT (S_AXI_HP3_WACOUNT),
.SW_CLK (net_sw_clk),
.WR_DATA_ACK_DDR (net_wr_ack_ddr_hp3),
.WR_DATA_ACK_OCM (net_wr_ack_ocm_hp3),
.WR_DATA (net_wr_data_hp3),
.WR_DATA_STRB (net_wr_strb_hp3),
.WR_ADDR (net_wr_addr_hp3),
.WR_BYTES (net_wr_bytes_hp3),
.WR_DATA_VALID_DDR (net_wr_dv_ddr_hp3),
.WR_DATA_VALID_OCM (net_wr_dv_ocm_hp3),
.WR_QOS (net_wr_qos_hp3),
.RD_REQ_DDR (net_rd_req_ddr_hp3),
.RD_REQ_OCM (net_rd_req_ocm_hp3),
.RD_ADDR (net_rd_addr_hp3),
.RD_DATA_DDR (net_rd_data_ddr_hp3),
.RD_DATA_OCM (net_rd_data_ocm_hp3),
.RD_BYTES (net_rd_bytes_hp3),
.RD_DATA_VALID_DDR (net_rd_dv_ddr_hp3),
.RD_DATA_VALID_OCM (net_rd_dv_ocm_hp3),
.RD_QOS (net_rd_qos_hp3)
);
@@ -0,0 +1,244 @@
/*****************************************************************************
* File : processing_system7_vip_v1_0_7_local_params.v
*
* Date : 2012-11
*
* Description : Parameters used in Zynq VIP
*
*****************************************************************************/
/* local */
parameter m_axi_gp0_baseaddr = 32'h4000_0000;
parameter m_axi_gp1_baseaddr = 32'h8000_0000;
parameter m_axi_gp0_highaddr = 32'h7FFF_FFFF;
parameter m_axi_gp1_highaddr = 32'hBFFF_FFFF;
parameter addr_width = 32; // maximum address width
parameter data_width = 32; // maximum data width.
parameter max_chars = 128; // max characters for file name
parameter mem_width = data_width/8; /// memory width in bytes
parameter shft_addr_bits = clogb2(mem_width); /// Address to be right shifted
parameter int_width = 32; //integre width
/* for internal read/write APIs used for data transfers */
parameter max_burst_len = 16; /// maximum brst length on axi
parameter max_data_width = 64; // maximum data width for internal AXI bursts
parameter max_burst_bits = (max_data_width * max_burst_len); // maximum data width for internal AXI bursts
parameter max_burst_bytes = (max_burst_bits)/8; // maximum data bytes in each transfer
parameter max_burst_bytes_width = clogb2(max_burst_bytes); // maximum data width for internal AXI bursts
parameter max_registers = 32;
parameter max_regs_width = clogb2(max_registers);
parameter REG_MEM = 2'b00, DDR_MEM = 2'b01, OCM_MEM = 2'b10, INVALID_MEM_TYPE = 2'b11;
/* Interrupt bits supported */
parameter irq_width = 16;
/* GP Master0 & Master1 address decode */
parameter GP_M0 = 2'b01;
parameter GP_M1 = 2'b10;
parameter ALL_RANDOM= 2'b00;
parameter ALL_ZEROS = 2'b01;
parameter ALL_ONES = 2'b10;
parameter ddr_start_addr = 32'h0008_0000;
parameter ddr_end_addr = 32'h7FFF_FFFF;
parameter ocm_start_addr = 32'h0000_0000;
parameter ocm_end_addr = 32'h0003_FFFF;
parameter high_ocm_start_addr = 32'hFFFC_0000;
parameter high_ocm_end_addr = 32'hFFFF_FFFF;
parameter ocm_low_addr = 32'hFFFF_0000;
parameter reg_start_addr = 32'hE000_0000;
parameter reg_end_addr = 32'hF8F0_2F80;
/* for Master port APIs and AXI protocol related signal widths*/
parameter axi_burst_len = 16;
parameter axi_len_width = clogb2(axi_burst_len);
parameter axi_size_width = 3;
parameter axi_brst_type_width = 2;
parameter axi_lock_width = 2;
parameter axi_cache_width = 4;
parameter axi_prot_width = 3;
parameter axi_rsp_width = 2;
parameter axi_mgp_data_width = 32;
parameter axi_mgp_id_width = 12;
parameter axi_mgp_outstanding = 8;
parameter axi_mgp_wr_id = 12'hC00;
parameter axi_mgp_rd_id = 12'hC0C;
parameter axi_mgp0_name = "M_AXI_GP0";
parameter axi_mgp1_name = "M_AXI_GP1";
parameter axi_qos_width = 4;
parameter max_transfer_bytes = 256; // For Master APIs.
parameter max_transfer_bytes_width = clogb2(max_transfer_bytes); // For Master APIs.
/* for GP slave ports*/
parameter axi_sgp_data_width = 32;
parameter axi_sgp_id_width = 6;
parameter axi_sgp_rd_outstanding = 8;
parameter axi_sgp_wr_outstanding = 8;
parameter axi_sgp_outstanding = axi_sgp_rd_outstanding + axi_sgp_wr_outstanding;
parameter axi_sgp0_name = "S_AXI_GP0";
parameter axi_sgp1_name = "S_AXI_GP1";
/* for ACP slave ports*/
parameter axi_acp_data_width = 64;
parameter axi_acp_id_width = 3;
parameter axi_acp_rd_outstanding = 7;
parameter axi_acp_wr_outstanding = 3;
parameter axi_acp_outstanding = axi_acp_rd_outstanding + axi_acp_wr_outstanding;
parameter axi_acp_name = "S_AXI_ACP";
/* for HP slave ports*/
parameter axi_hp_id_width = 6;
parameter axi_hp_outstanding = 256; /// dynamic based on RCOUNT, WCOUNT ..
parameter axi_hp0_name = "S_AXI_HP0";
parameter axi_hp1_name = "S_AXI_HP1";
parameter axi_hp2_name = "S_AXI_HP2";
parameter axi_hp3_name = "S_AXI_HP3";
parameter axi_slv_excl_support = 0; // For Slave ports EXCL access is not supported
parameter axi_mst_excl_support = 1; // For Master ports EXCL access is supported
/* AXI transfer types */
parameter AXI_FIXED = 2'b00;
parameter AXI_INCR = 2'b01;
parameter AXI_WRAP = 2'b10;
/* Exclusive Access */
parameter AXI_NRML = 2'b00;
parameter AXI_EXCL = 2'b01;
parameter AXI_LOCK = 2'b10;
/* AXI Response types */
parameter AXI_OK = 2'b00;
parameter AXI_EXCL_OK = 2'b01;
parameter AXI_SLV_ERR = 2'b10;
parameter AXI_DEC_ERR = 2'b11;
function automatic integer clogb2;
input [31:0] value;
begin
value = value - 1;
for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) begin
value = value >> 1;
end
end
endfunction
/* needed only for AFI modules and axi_slave modules for internal WRITE FIFOs and RESP FIFOs and interconnect fifo models */
/* WR FIFO data */
// parameter wr_fifo_data_bits = axi_qos_width + addr_width + max_burst_bits + (max_burst_bytes_width+1);
// parameter wr_fifo_data_bits = axi_qos_width + addr_width + max_burst_bits + (max_burst_bytes_width+1);
// parameter wr_fifo_data_bits = ((data_bus_width/8)*axi_burst_len) + (data_bus_width*axi_burst_len) + axi_qos_width + addr_width + (max_burst_bytes_width+1);
// parameter wr_bytes_lsb = 0;
// parameter wr_bytes_msb = max_burst_bytes_width;
// parameter wr_addr_lsb = wr_bytes_msb + 1;
// parameter wr_addr_msb = wr_addr_lsb + addr_width-1;
// parameter wr_data_lsb = wr_addr_msb + 1;
// parameter wr_data_msb = wr_data_lsb + max_burst_bits-1;
// parameter wr_data_msb = wr_data_lsb + (data_bus_width*axi_burst_len)-1;
// parameter wr_qos_lsb = wr_data_msb + 1;
// `parameter wr_qos_msb = wr_qos_lsb + axi_qos_width-1;
/* WR AFI FIFO data */
/* ID - 1071:1066
Resp - 1065:1064
data - 1063:40
address - 39:8
valid_bytes - 7:0
*/
// parameter wr_afi_fifo_data_bits = axi_qos_width + axi_len_width + axi_hp_id_width + axi_rsp_width + max_burst_bits + addr_width + (max_burst_bytes_width+1);
// parameter wr_afi_bytes_lsb = 0;
// parameter wr_afi_bytes_msb = max_burst_bytes_width;
// parameter wr_afi_addr_lsb = wr_afi_bytes_msb + 1;
// parameter wr_afi_addr_msb = wr_afi_addr_lsb + addr_width-1;
// parameter wr_afi_data_lsb = wr_afi_addr_msb + 1;
// parameter wr_afi_rsp_msb = wr_afi_rsp_lsb + axi_rsp_width-1;
// parameter wr_afi_id_lsb = wr_afi_rsp_msb + 1;
// parameter wr_afi_id_msb = wr_afi_id_lsb + axi_hp_id_width-1;
// parameter wr_afi_ln_lsb = wr_afi_id_msb + 1;
// parameter wr_afi_ln_msb = wr_afi_ln_lsb + axi_len_width-1;
// parameter wr_afi_qos_lsb = wr_afi_ln_msb + 1;
// parameter wr_afi_qos_msb = wr_afi_qos_lsb + axi_qos_width-1;
parameter afi_fifo_size = 1024; /// AFI FIFO is stored as 1024-bytes
parameter afi_fifo_databits = 64; /// AFI FIFO is stored as 64-bits i.e 8 bytes per location (8 bytes(64-bits) * 128 locations = 1024 bytes)
parameter afi_fifo_locations= afi_fifo_size/(afi_fifo_databits/8); /// AFI FIFO is stored as 128-locations with 8 bytes per location
/* for interconnect fifo models */
parameter intr_max_outstanding = 8;
parameter intr_cnt_width = clogb2(intr_max_outstanding)+1;
parameter rd_info_bits = addr_width + axi_size_width + axi_brst_type_width + axi_len_width + axi_hp_id_width + axi_rsp_width + (max_burst_bytes_width+1);
parameter rd_afi_fifo_bits = max_burst_bits + rd_info_bits ;
//Read Burst Data, addr, size, burst, len, RID, RRESP, valid bytes
parameter rd_afi_bytes_lsb = 0;
parameter rd_afi_bytes_msb = max_burst_bytes_width;
parameter rd_afi_rsp_lsb = rd_afi_bytes_msb + 1;
parameter rd_afi_rsp_msb = rd_afi_rsp_lsb + axi_rsp_width-1;
parameter rd_afi_id_lsb = rd_afi_rsp_msb + 1;
parameter rd_afi_id_msb = rd_afi_id_lsb + axi_hp_id_width-1;
parameter rd_afi_ln_lsb = rd_afi_id_msb + 1;
parameter rd_afi_ln_msb = rd_afi_ln_lsb + axi_len_width-1;
parameter rd_afi_brst_lsb = rd_afi_ln_msb + 1;
parameter rd_afi_brst_msb = rd_afi_brst_lsb + axi_brst_type_width-1;
parameter rd_afi_siz_lsb = rd_afi_brst_msb + 1;
parameter rd_afi_siz_msb = rd_afi_siz_lsb + axi_size_width-1;
parameter rd_afi_addr_lsb = rd_afi_siz_msb + 1;
parameter rd_afi_addr_msb = rd_afi_addr_lsb + addr_width-1;
parameter rd_afi_data_lsb = rd_afi_addr_msb + 1;
parameter rd_afi_data_msb = rd_afi_data_lsb + max_burst_bits-1;
/* Latency types */
parameter BEST_CASE = 0;
parameter AVG_CASE = 1;
parameter WORST_CASE = 2;
parameter RANDOM_CASE = 3;
/* Latency Parameters ACP */
parameter acp_wr_min = 21;
parameter acp_wr_avg = 16;
parameter acp_wr_max = 27;
parameter acp_rd_min = 34;
parameter acp_rd_avg = 125;
parameter acp_rd_max = 130;
/* Latency Parameters GP */
parameter gp_wr_min = 21;
parameter gp_wr_avg = 16;
parameter gp_wr_max = 46;
parameter gp_rd_min = 38;
parameter gp_rd_avg = 125;
parameter gp_rd_max = 130;
/* Latency Parameters HP */
parameter afi_wr_min = 37;
parameter afi_wr_avg = 41;
parameter afi_wr_max = 42;
parameter afi_rd_min = 41;
parameter afi_rd_avg = 221;
parameter afi_rd_max = 229;
/* ID VALID and INVALID */
parameter secure_access_enabled = 0;
parameter id_invalid = 0;
parameter id_valid = 1;
/* Display */
parameter DISP_INFO = "*ZYNQ_VIP_INFO";
parameter DISP_WARN = "*ZYNQ_VIP_WARNING";
parameter DISP_ERR = "*ZYNQ_VIP_ERROR";
parameter DISP_INT_INFO = "ZYNQ_VIP_INT_INFO";
parameter all_strb_valid = 2048'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
@@ -0,0 +1,433 @@
/*****************************************************************************
* File : processing_system7_vip_v1_0_7_unused_ports.v
*
* Date : 2012-11
*
* Description : Semantic checks for unused ports.
*
*****************************************************************************/
/* CAN */
assign CAN0_PHY_TX = 0;
assign CAN1_PHY_TX = 0;
always @(CAN0_PHY_RX or CAN1_PHY_RX)
begin
if(CAN0_PHY_RX | CAN1_PHY_RX)
$display("[%0d] : %0s : CAN Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* ETHERNET */
/* ------------------------------------------- */
assign ENET0_GMII_TX_EN = 0;
assign ENET0_GMII_TX_ER = 0;
assign ENET0_MDIO_MDC = 0;
assign ENET0_MDIO_O = 0; /// confirm
assign ENET0_MDIO_T = 0;
assign ENET0_PTP_DELAY_REQ_RX = 0;
assign ENET0_PTP_DELAY_REQ_TX = 0;
assign ENET0_PTP_PDELAY_REQ_RX = 0;
assign ENET0_PTP_PDELAY_REQ_TX = 0;
assign ENET0_PTP_PDELAY_RESP_RX = 0;
assign ENET0_PTP_PDELAY_RESP_TX = 0;
assign ENET0_PTP_SYNC_FRAME_RX = 0;
assign ENET0_PTP_SYNC_FRAME_TX = 0;
assign ENET0_SOF_RX = 0;
assign ENET0_SOF_TX = 0;
assign ENET0_GMII_TXD = 0;
always@(ENET0_GMII_COL or ENET0_GMII_CRS or ENET0_EXT_INTIN or
ENET0_GMII_RX_CLK or ENET0_GMII_RX_DV or ENET0_GMII_RX_ER or
ENET0_GMII_TX_CLK or ENET0_MDIO_I or ENET0_GMII_RXD)
begin
if(ENET0_GMII_COL | ENET0_GMII_CRS | ENET0_EXT_INTIN |
ENET0_GMII_RX_CLK | ENET0_GMII_RX_DV | ENET0_GMII_RX_ER |
ENET0_GMII_TX_CLK | ENET0_MDIO_I )
$display("[%0d] : %0s : ETHERNET Interface is not supported.",$time, DISP_ERR);
end
assign ENET1_GMII_TX_EN = 0;
assign ENET1_GMII_TX_ER = 0;
assign ENET1_MDIO_MDC = 0;
assign ENET1_MDIO_O = 0;/// confirm
assign ENET1_MDIO_T = 0;
assign ENET1_PTP_DELAY_REQ_RX = 0;
assign ENET1_PTP_DELAY_REQ_TX = 0;
assign ENET1_PTP_PDELAY_REQ_RX = 0;
assign ENET1_PTP_PDELAY_REQ_TX = 0;
assign ENET1_PTP_PDELAY_RESP_RX = 0;
assign ENET1_PTP_PDELAY_RESP_TX = 0;
assign ENET1_PTP_SYNC_FRAME_RX = 0;
assign ENET1_PTP_SYNC_FRAME_TX = 0;
assign ENET1_SOF_RX = 0;
assign ENET1_SOF_TX = 0;
assign ENET1_GMII_TXD = 0;
always@(ENET1_GMII_COL or ENET1_GMII_CRS or ENET1_EXT_INTIN or
ENET1_GMII_RX_CLK or ENET1_GMII_RX_DV or ENET1_GMII_RX_ER or
ENET1_GMII_TX_CLK or ENET1_MDIO_I or ENET1_GMII_RXD)
begin
if(ENET1_GMII_COL | ENET1_GMII_CRS | ENET1_EXT_INTIN |
ENET1_GMII_RX_CLK | ENET1_GMII_RX_DV | ENET1_GMII_RX_ER |
ENET1_GMII_TX_CLK | ENET1_MDIO_I )
$display("[%0d] : %0s : ETHERNET Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* GPIO */
/* ------------------------------------------- */
assign GPIO_O = 0;
assign GPIO_T = 0;
always@(GPIO_I)
begin
// if(GPIO_I !== 0)
// $display("[%0d] : %0s : GPIO Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* I2C */
/* ------------------------------------------- */
assign I2C0_SDA_O = 0;
assign I2C0_SDA_T = 0;
assign I2C0_SCL_O = 0;
assign I2C0_SCL_T = 0;
assign I2C1_SDA_O = 0;
assign I2C1_SDA_T = 0;
assign I2C1_SCL_O = 0;
assign I2C1_SCL_T = 0;
always@(I2C0_SDA_I or I2C0_SCL_I or I2C1_SDA_I or I2C1_SCL_I )
begin
if(I2C0_SDA_I | I2C0_SCL_I | I2C1_SDA_I | I2C1_SCL_I)
$display("[%0d] : %0s : I2C Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* JTAG */
/* ------------------------------------------- */
assign PJTAG_TD_T = 0;
assign PJTAG_TD_O = 0;
always@(PJTAG_TCK or PJTAG_TMS or PJTAG_TD_I)
begin
if(PJTAG_TCK | PJTAG_TMS | PJTAG_TD_I)
$display("[%0d] : %0s : JTAG Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* SDIO */
/* ------------------------------------------- */
assign SDIO0_CLK = 0;
assign SDIO0_CMD_O = 0;
assign SDIO0_CMD_T = 0;
assign SDIO0_DATA_O = 0;
assign SDIO0_DATA_T = 0;
assign SDIO0_LED = 0;
assign SDIO0_BUSPOW = 0;
assign SDIO0_BUSVOLT = 0;
always@(SDIO0_CLK_FB or SDIO0_CMD_I or SDIO0_DATA_I or SDIO0_CDN or SDIO0_WP )
begin
if(SDIO0_CLK_FB | SDIO0_CMD_I | SDIO0_CDN | SDIO0_WP )
$display("[%0d] : %0s : SDIO Interface is not supported.",$time, DISP_ERR);
end
assign SDIO1_CLK = 0;
assign SDIO1_CMD_O = 0;
assign SDIO1_CMD_T = 0;
assign SDIO1_DATA_O = 0;
assign SDIO1_DATA_T = 0;
assign SDIO1_LED = 0;
assign SDIO1_BUSPOW = 0;
assign SDIO1_BUSVOLT = 0;
always@(SDIO1_CLK_FB or SDIO1_CMD_I or SDIO1_DATA_I or SDIO1_CDN or SDIO1_WP )
begin
if(SDIO1_CLK_FB | SDIO1_CMD_I | SDIO1_CDN | SDIO1_WP )
$display("[%0d] : %0s : SDIO Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* SPI */
/* ------------------------------------------- */
assign SPI0_SCLK_O = 0;
assign SPI0_SCLK_T = 0;
assign SPI0_MOSI_O = 0;
assign SPI0_MOSI_T = 0;
assign SPI0_MISO_O = 0;
assign SPI0_MISO_T = 0;
assign SPI0_SS_O = 0; /// confirm
assign SPI0_SS1_O = 0;/// confirm
assign SPI0_SS2_O = 0;/// confirm
assign SPI0_SS_T = 0;
always@(SPI0_SCLK_I or SPI0_MOSI_I or SPI0_MISO_I or SPI0_SS_I)
begin
if(SPI0_SCLK_I | SPI0_MOSI_I | SPI0_MISO_I | SPI0_SS_I)
$display("[%0d] : %0s : SPI Interface is not supported.",$time, DISP_ERR);
end
assign SPI1_SCLK_O = 0;
assign SPI1_SCLK_T = 0;
assign SPI1_MOSI_O = 0;
assign SPI1_MOSI_T = 0;
assign SPI1_MISO_O = 0;
assign SPI1_MISO_T = 0;
assign SPI1_SS_O = 0;
assign SPI1_SS1_O = 0;
assign SPI1_SS2_O = 0;
assign SPI1_SS_T = 0;
always@(SPI1_SCLK_I or SPI1_MOSI_I or SPI1_MISO_I or SPI1_SS_I)
begin
if(SPI1_SCLK_I | SPI1_MOSI_I | SPI1_MISO_I | SPI1_SS_I)
$display("[%0d] : %0s : SPI Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* UART */
/* ------------------------------------------- */
/// confirm
assign UART0_DTRN = 0;
assign UART0_RTSN = 0;
assign UART0_TX = 0;
always@(UART0_CTSN or UART0_DCDN or UART0_DSRN or UART0_RIN or UART0_RX)
begin
if(UART0_CTSN | UART0_DCDN | UART0_DSRN | UART0_RIN | UART0_RX)
$display("[%0d] : %0s : UART Interface is not supported.",$time, DISP_ERR);
end
assign UART1_DTRN = 0;
assign UART1_RTSN = 0;
assign UART1_TX = 0;
always@(UART1_CTSN or UART1_DCDN or UART1_DSRN or UART1_RIN or UART1_RX)
begin
if(UART1_CTSN | UART1_DCDN | UART1_DSRN | UART1_RIN | UART1_RX)
$display("[%0d] : %0s : UART Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* TTC */
/* ------------------------------------------- */
assign TTC0_WAVE0_OUT = 0;
assign TTC0_WAVE1_OUT = 0;
assign TTC0_WAVE2_OUT = 0;
always@(TTC0_CLK0_IN or TTC0_CLK1_IN or TTC0_CLK2_IN)
begin
if(TTC0_CLK0_IN | TTC0_CLK1_IN | TTC0_CLK2_IN)
$display("[%0d] : %0s : TTC Interface is not supported.",$time, DISP_ERR);
end
assign TTC1_WAVE0_OUT = 0;
assign TTC1_WAVE1_OUT = 0;
assign TTC1_WAVE2_OUT = 0;
always@(TTC1_CLK0_IN or TTC1_CLK1_IN or TTC1_CLK2_IN)
begin
if(TTC1_CLK0_IN | TTC1_CLK1_IN | TTC1_CLK2_IN)
$display("[%0d] : %0s : TTC Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* WDT */
/* ------------------------------------------- */
assign WDT_RST_OUT = 0;
always@(WDT_CLK_IN)
begin
if(WDT_CLK_IN)
$display("[%0d] : %0s : WDT Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* TRACE */
/* ------------------------------------------- */
assign TRACE_CTL = 0;
assign TRACE_DATA = 0;
always@(TRACE_CLK)
begin
if(TRACE_CLK)
$display("[%0d] : %0s : TRACE Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* USB */
/* ------------------------------------------- */
assign USB0_PORT_INDCTL = 0;
assign USB0_VBUS_PWRSELECT = 0;
always@(USB0_VBUS_PWRFAULT)
begin
if(USB0_VBUS_PWRFAULT)
$display("[%0d] : %0s : USB Interface is not supported.",$time, DISP_ERR);
end
assign USB1_PORT_INDCTL = 0;
assign USB1_VBUS_PWRSELECT = 0;
always@(USB1_VBUS_PWRFAULT)
begin
if(USB1_VBUS_PWRFAULT)
$display("[%0d] : %0s : USB Interface is not supported.",$time, DISP_ERR);
end
always@(SRAM_INTIN)
begin
if(SRAM_INTIN)
$display("[%0d] : %0s : SRAM_INTIN is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* DMA */
/* ------------------------------------------- */
assign DMA0_DATYPE = 0;
assign DMA0_DAVALID = 0;
assign DMA0_DRREADY = 0;
assign DMA0_RSTN = 0;
always@(DMA0_ACLK or DMA0_DAREADY or DMA0_DRLAST or DMA0_DRVALID or DMA0_DRTYPE)
begin
if(DMA0_ACLK | DMA0_DAREADY | DMA0_DRLAST | DMA0_DRVALID | DMA0_DRTYPE)
$display("[%0d] : %0s : DMA Interface is not supported.",$time, DISP_ERR);
end
assign DMA1_DATYPE = 0;
assign DMA1_DAVALID = 0;
assign DMA1_DRREADY = 0;
assign DMA1_RSTN = 0;
always@(DMA1_ACLK or DMA1_DAREADY or DMA1_DRLAST or DMA1_DRVALID or DMA1_DRTYPE)
begin
if(DMA1_ACLK | DMA1_DAREADY | DMA1_DRLAST | DMA1_DRVALID | DMA1_DRTYPE)
$display("[%0d] : %0s : DMA Interface is not supported.",$time, DISP_ERR);
end
assign DMA2_DATYPE = 0;
assign DMA2_DAVALID = 0;
assign DMA2_DRREADY = 0;
assign DMA2_RSTN = 0;
always@(DMA2_ACLK or DMA2_DAREADY or DMA2_DRLAST or DMA2_DRVALID or DMA2_DRTYPE)
begin
if(DMA2_ACLK | DMA2_DAREADY | DMA2_DRLAST | DMA2_DRVALID | DMA2_DRTYPE)
$display("[%0d] : %0s : DMA Interface is not supported.",$time, DISP_ERR);
end
assign DMA3_DATYPE = 0;
assign DMA3_DAVALID = 0;
assign DMA3_DRREADY = 0;
assign DMA3_RSTN = 0;
always@(DMA3_ACLK or DMA3_DAREADY or DMA3_DRLAST or DMA3_DRVALID or DMA3_DRTYPE)
begin
if(DMA3_ACLK | DMA3_DAREADY | DMA3_DRLAST | DMA3_DRVALID | DMA3_DRTYPE)
$display("[%0d] : %0s : DMA Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* FTM */
/* ------------------------------------------- */
assign FTMT_F2P_TRIGACK = 0;
assign FTMT_P2F_TRIG = 0;
assign FTMT_P2F_DEBUG = 0;
always@(FTMD_TRACEIN_DATA or FTMD_TRACEIN_VALID or FTMD_TRACEIN_CLK or
FTMD_TRACEIN_ATID or FTMT_F2P_TRIG or FTMT_F2P_DEBUG or FTMT_P2F_TRIGACK)
begin
if(FTMD_TRACEIN_DATA | FTMD_TRACEIN_VALID | FTMD_TRACEIN_CLK | FTMD_TRACEIN_ATID | FTMT_F2P_TRIG | FTMT_F2P_DEBUG | FTMT_P2F_TRIGACK)
$display("[%0d] : %0s : FTM Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* EVENT */
/* ------------------------------------------- */
assign EVENT_EVENTO = 0;
assign EVENT_STANDBYWFE = 0;
assign EVENT_STANDBYWFI = 0;
always@(EVENT_EVENTI)
begin
if(EVENT_EVENTI)
$display("[%0d] : %0s : EVENT Interface is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* MIO */
/* ------------------------------------------- */
always@(MIO)
begin
// if(MIO !== 0)
// $display("[%0d] : %0s : MIO is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* FCLK_TRIG */
/* ------------------------------------------- */
always@(FCLK_CLKTRIG3_N or FCLK_CLKTRIG2_N or FCLK_CLKTRIG1_N or FCLK_CLKTRIG0_N )
begin
if(FCLK_CLKTRIG3_N | FCLK_CLKTRIG2_N | FCLK_CLKTRIG1_N | FCLK_CLKTRIG0_N )
$display("[%0d] : %0s : FCLK_TRIG is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* MISC */
/* ------------------------------------------- */
always@(FPGA_IDLE_N)
begin
if(FPGA_IDLE_N)
$display("[%0d] : %0s : FPGA_IDLE_N is not supported.",$time, DISP_ERR);
end
always@(DDR_ARB)
begin
// if(DDR_ARB !== 0)
// $display("[%0d] : %0s : DDR_ARB is not supported.",$time, DISP_ERR);
end
always@(Core0_nFIQ or Core0_nIRQ or Core1_nFIQ or Core1_nIRQ )
begin
if(Core0_nFIQ | Core0_nIRQ | Core1_nFIQ | Core1_nIRQ)
$display("[%0d] : %0s : CORE FIQ,IRQ is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* DDR */
/* ------------------------------------------- */
assign DDR_WEB = 0;
always@(DDR_Clk or DDR_CS_n)
begin
if(!DDR_CS_n)
$display("[%0d] : %0s : EXTERNAL DDR is not supported.",$time, DISP_ERR);
end
/* ------------------------------------------- */
/* IRQ_P2F */
/* ------------------------------------------- */
assign IRQ_P2F_DMAC_ABORT = 0;
assign IRQ_P2F_DMAC0 = 0;
assign IRQ_P2F_DMAC1 = 0;
assign IRQ_P2F_DMAC2 = 0;
assign IRQ_P2F_DMAC3 = 0;
assign IRQ_P2F_DMAC4 = 0;
assign IRQ_P2F_DMAC5 = 0;
assign IRQ_P2F_DMAC6 = 0;
assign IRQ_P2F_DMAC7 = 0;
assign IRQ_P2F_SMC = 0;
assign IRQ_P2F_QSPI = 0;
assign IRQ_P2F_CTI = 0;
assign IRQ_P2F_GPIO = 0;
assign IRQ_P2F_USB0 = 0;
assign IRQ_P2F_ENET0 = 0;
assign IRQ_P2F_ENET_WAKE0 = 0;
assign IRQ_P2F_SDIO0 = 0;
assign IRQ_P2F_I2C0 = 0;
assign IRQ_P2F_SPI0 = 0;
assign IRQ_P2F_UART0 = 0;
assign IRQ_P2F_CAN0 = 0;
assign IRQ_P2F_USB1 = 0;
assign IRQ_P2F_ENET1 = 0;
assign IRQ_P2F_ENET_WAKE1 = 0;
assign IRQ_P2F_SDIO1 = 0;
assign IRQ_P2F_I2C1 = 0;
assign IRQ_P2F_SPI1 = 0;
assign IRQ_P2F_UART1 = 0;
assign IRQ_P2F_CAN1 = 0;
@@ -0,0 +1,409 @@
//-----------------------------------------------------------------------------
//-- (c) Copyright 2010 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.
//-----------------------------------------------------------------------------
//
// Description: ACP Transaction Checker
//
// Check for optimized ACP transactions and flag if they are broken.
//
//
//
// Verilog-standard: Verilog 2001
//--------------------------------------------------------------------------
//
// Structure:
// atc
// aw_atc
// w_atc
// b_atc
//
//--------------------------------------------------------------------------
`timescale 1ps/1ps
`default_nettype none
module processing_system7_v5_5_atc #
(
parameter C_FAMILY = "rtl",
// FPGA Family. Current version: virtex6, spartan6 or later.
parameter integer C_AXI_ID_WIDTH = 4,
// Width of all ID signals on SI and MI side of checker.
// Range: >= 1.
parameter integer C_AXI_ADDR_WIDTH = 32,
// Width of all ADDR signals on SI and MI side of checker.
// Range: 32.
parameter integer C_AXI_DATA_WIDTH = 64,
// Width of all DATA signals on SI and MI side of checker.
// Range: 64.
parameter integer C_AXI_AWUSER_WIDTH = 1,
// Width of AWUSER signals.
// Range: >= 1.
parameter integer C_AXI_ARUSER_WIDTH = 1,
// Width of ARUSER signals.
// Range: >= 1.
parameter integer C_AXI_WUSER_WIDTH = 1,
// Width of WUSER signals.
// Range: >= 1.
parameter integer C_AXI_RUSER_WIDTH = 1,
// Width of RUSER signals.
// Range: >= 1.
parameter integer C_AXI_BUSER_WIDTH = 1
// Width of BUSER signals.
// Range: >= 1.
)
(
// Global Signals
input wire ACLK,
input wire ARESETN,
// Slave Interface Write Address Ports
input wire [C_AXI_ID_WIDTH-1:0] S_AXI_AWID,
input wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR,
input wire [4-1:0] S_AXI_AWLEN,
input wire [3-1:0] S_AXI_AWSIZE,
input wire [2-1:0] S_AXI_AWBURST,
input wire [2-1:0] S_AXI_AWLOCK,
input wire [4-1:0] S_AXI_AWCACHE,
input wire [3-1:0] S_AXI_AWPROT,
input wire [C_AXI_AWUSER_WIDTH-1:0] S_AXI_AWUSER,
input wire S_AXI_AWVALID,
output wire S_AXI_AWREADY,
// Slave Interface Write Data Ports
input wire [C_AXI_ID_WIDTH-1:0] S_AXI_WID,
input wire [C_AXI_DATA_WIDTH-1:0] S_AXI_WDATA,
input wire [C_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB,
input wire S_AXI_WLAST,
input wire [C_AXI_WUSER_WIDTH-1:0] S_AXI_WUSER,
input wire S_AXI_WVALID,
output wire S_AXI_WREADY,
// Slave Interface Write Response Ports
output wire [C_AXI_ID_WIDTH-1:0] S_AXI_BID,
output wire [2-1:0] S_AXI_BRESP,
output wire [C_AXI_BUSER_WIDTH-1:0] S_AXI_BUSER,
output wire S_AXI_BVALID,
input wire S_AXI_BREADY,
// Slave Interface Read Address Ports
input wire [C_AXI_ID_WIDTH-1:0] S_AXI_ARID,
input wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_ARADDR,
input wire [4-1:0] S_AXI_ARLEN,
input wire [3-1:0] S_AXI_ARSIZE,
input wire [2-1:0] S_AXI_ARBURST,
input wire [2-1:0] S_AXI_ARLOCK,
input wire [4-1:0] S_AXI_ARCACHE,
input wire [3-1:0] S_AXI_ARPROT,
input wire [C_AXI_ARUSER_WIDTH-1:0] S_AXI_ARUSER,
input wire S_AXI_ARVALID,
output wire S_AXI_ARREADY,
// Slave Interface Read Data Ports
output wire [C_AXI_ID_WIDTH-1:0] S_AXI_RID,
output wire [C_AXI_DATA_WIDTH-1:0] S_AXI_RDATA,
output wire [2-1:0] S_AXI_RRESP,
output wire S_AXI_RLAST,
output wire [C_AXI_RUSER_WIDTH-1:0] S_AXI_RUSER,
output wire S_AXI_RVALID,
input wire S_AXI_RREADY,
// Master Interface Write Address Port
output wire [C_AXI_ID_WIDTH-1:0] M_AXI_AWID,
output wire [C_AXI_ADDR_WIDTH-1:0] M_AXI_AWADDR,
output wire [4-1:0] M_AXI_AWLEN,
output wire [3-1:0] M_AXI_AWSIZE,
output wire [2-1:0] M_AXI_AWBURST,
output wire [2-1:0] M_AXI_AWLOCK,
output wire [4-1:0] M_AXI_AWCACHE,
output wire [3-1:0] M_AXI_AWPROT,
output wire [C_AXI_AWUSER_WIDTH-1:0] M_AXI_AWUSER,
output wire M_AXI_AWVALID,
input wire M_AXI_AWREADY,
// Master Interface Write Data Ports
output wire [C_AXI_ID_WIDTH-1:0] M_AXI_WID,
output wire [C_AXI_DATA_WIDTH-1:0] M_AXI_WDATA,
output wire [C_AXI_DATA_WIDTH/8-1:0] M_AXI_WSTRB,
output wire M_AXI_WLAST,
output wire [C_AXI_WUSER_WIDTH-1:0] M_AXI_WUSER,
output wire M_AXI_WVALID,
input wire M_AXI_WREADY,
// Master Interface Write Response Ports
input wire [C_AXI_ID_WIDTH-1:0] M_AXI_BID,
input wire [2-1:0] M_AXI_BRESP,
input wire [C_AXI_BUSER_WIDTH-1:0] M_AXI_BUSER,
input wire M_AXI_BVALID,
output wire M_AXI_BREADY,
// Master Interface Read Address Port
output wire [C_AXI_ID_WIDTH-1:0] M_AXI_ARID,
output wire [C_AXI_ADDR_WIDTH-1:0] M_AXI_ARADDR,
output wire [4-1:0] M_AXI_ARLEN,
output wire [3-1:0] M_AXI_ARSIZE,
output wire [2-1:0] M_AXI_ARBURST,
output wire [2-1:0] M_AXI_ARLOCK,
output wire [4-1:0] M_AXI_ARCACHE,
output wire [3-1:0] M_AXI_ARPROT,
output wire [C_AXI_ARUSER_WIDTH-1:0] M_AXI_ARUSER,
output wire M_AXI_ARVALID,
input wire M_AXI_ARREADY,
// Master Interface Read Data Ports
input wire [C_AXI_ID_WIDTH-1:0] M_AXI_RID,
input wire [C_AXI_DATA_WIDTH-1:0] M_AXI_RDATA,
input wire [2-1:0] M_AXI_RRESP,
input wire M_AXI_RLAST,
input wire [C_AXI_RUSER_WIDTH-1:0] M_AXI_RUSER,
input wire M_AXI_RVALID,
output wire M_AXI_RREADY,
output wire ERROR_TRIGGER,
output wire [C_AXI_ID_WIDTH-1:0] ERROR_TRANSACTION_ID
);
/////////////////////////////////////////////////////////////////////////////
// Functions
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Local params
/////////////////////////////////////////////////////////////////////////////
localparam C_FIFO_DEPTH_LOG = 4;
/////////////////////////////////////////////////////////////////////////////
// Internal signals
/////////////////////////////////////////////////////////////////////////////
// Internal reset.
reg ARESET;
// AW->W command queue signals.
wire cmd_w_valid;
wire cmd_w_check;
wire [C_AXI_ID_WIDTH-1:0] cmd_w_id;
wire cmd_w_ready;
// W->B command queue signals.
wire cmd_b_push;
wire cmd_b_error;
wire [C_AXI_ID_WIDTH-1:0] cmd_b_id;
wire cmd_b_full;
wire [C_FIFO_DEPTH_LOG-1:0] cmd_b_addr;
wire cmd_b_ready;
/////////////////////////////////////////////////////////////////////////////
// Handle Internal Reset
/////////////////////////////////////////////////////////////////////////////
always @ (posedge ACLK) begin
ARESET <= !ARESETN;
end
/////////////////////////////////////////////////////////////////////////////
// Handle Write Channels (AW/W/B)
/////////////////////////////////////////////////////////////////////////////
// Write Address Channel.
processing_system7_v5_5_aw_atc #
(
.C_FAMILY (C_FAMILY),
.C_AXI_ID_WIDTH (C_AXI_ID_WIDTH),
.C_AXI_ADDR_WIDTH (C_AXI_ADDR_WIDTH),
.C_AXI_AWUSER_WIDTH (C_AXI_AWUSER_WIDTH),
.C_FIFO_DEPTH_LOG (C_FIFO_DEPTH_LOG)
) write_addr_inst
(
// Global Signals
.ARESET (ARESET),
.ACLK (ACLK),
// Command Interface (Out)
.cmd_w_valid (cmd_w_valid),
.cmd_w_check (cmd_w_check),
.cmd_w_id (cmd_w_id),
.cmd_w_ready (cmd_w_ready),
.cmd_b_addr (cmd_b_addr),
.cmd_b_ready (cmd_b_ready),
// Slave Interface Write Address Ports
.S_AXI_AWID (S_AXI_AWID),
.S_AXI_AWADDR (S_AXI_AWADDR),
.S_AXI_AWLEN (S_AXI_AWLEN),
.S_AXI_AWSIZE (S_AXI_AWSIZE),
.S_AXI_AWBURST (S_AXI_AWBURST),
.S_AXI_AWLOCK (S_AXI_AWLOCK),
.S_AXI_AWCACHE (S_AXI_AWCACHE),
.S_AXI_AWPROT (S_AXI_AWPROT),
.S_AXI_AWUSER (S_AXI_AWUSER),
.S_AXI_AWVALID (S_AXI_AWVALID),
.S_AXI_AWREADY (S_AXI_AWREADY),
// Master Interface Write Address Port
.M_AXI_AWID (M_AXI_AWID),
.M_AXI_AWADDR (M_AXI_AWADDR),
.M_AXI_AWLEN (M_AXI_AWLEN),
.M_AXI_AWSIZE (M_AXI_AWSIZE),
.M_AXI_AWBURST (M_AXI_AWBURST),
.M_AXI_AWLOCK (M_AXI_AWLOCK),
.M_AXI_AWCACHE (M_AXI_AWCACHE),
.M_AXI_AWPROT (M_AXI_AWPROT),
.M_AXI_AWUSER (M_AXI_AWUSER),
.M_AXI_AWVALID (M_AXI_AWVALID),
.M_AXI_AWREADY (M_AXI_AWREADY)
);
// Write Data channel.
processing_system7_v5_5_w_atc #
(
.C_FAMILY (C_FAMILY),
.C_AXI_ID_WIDTH (C_AXI_ID_WIDTH),
.C_AXI_DATA_WIDTH (C_AXI_DATA_WIDTH),
.C_AXI_WUSER_WIDTH (C_AXI_WUSER_WIDTH)
) write_data_inst
(
// Global Signals
.ARESET (ARESET),
.ACLK (ACLK),
// Command Interface (In)
.cmd_w_valid (cmd_w_valid),
.cmd_w_check (cmd_w_check),
.cmd_w_id (cmd_w_id),
.cmd_w_ready (cmd_w_ready),
// Command Interface (Out)
.cmd_b_push (cmd_b_push),
.cmd_b_error (cmd_b_error),
.cmd_b_id (cmd_b_id),
.cmd_b_full (cmd_b_full),
// Slave Interface Write Data Ports
.S_AXI_WID (S_AXI_WID),
.S_AXI_WDATA (S_AXI_WDATA),
.S_AXI_WSTRB (S_AXI_WSTRB),
.S_AXI_WLAST (S_AXI_WLAST),
.S_AXI_WUSER (S_AXI_WUSER),
.S_AXI_WVALID (S_AXI_WVALID),
.S_AXI_WREADY (S_AXI_WREADY),
// Master Interface Write Data Ports
.M_AXI_WID (M_AXI_WID),
.M_AXI_WDATA (M_AXI_WDATA),
.M_AXI_WSTRB (M_AXI_WSTRB),
.M_AXI_WLAST (M_AXI_WLAST),
.M_AXI_WUSER (M_AXI_WUSER),
.M_AXI_WVALID (M_AXI_WVALID),
.M_AXI_WREADY (M_AXI_WREADY)
);
// Write Response channel.
processing_system7_v5_5_b_atc #
(
.C_FAMILY (C_FAMILY),
.C_AXI_ID_WIDTH (C_AXI_ID_WIDTH),
.C_AXI_BUSER_WIDTH (C_AXI_BUSER_WIDTH),
.C_FIFO_DEPTH_LOG (C_FIFO_DEPTH_LOG)
) write_response_inst
(
// Global Signals
.ARESET (ARESET),
.ACLK (ACLK),
// Command Interface (In)
.cmd_b_push (cmd_b_push),
.cmd_b_error (cmd_b_error),
.cmd_b_id (cmd_b_id),
.cmd_b_full (cmd_b_full),
.cmd_b_addr (cmd_b_addr),
.cmd_b_ready (cmd_b_ready),
// Slave Interface Write Response Ports
.S_AXI_BID (S_AXI_BID),
.S_AXI_BRESP (S_AXI_BRESP),
.S_AXI_BUSER (S_AXI_BUSER),
.S_AXI_BVALID (S_AXI_BVALID),
.S_AXI_BREADY (S_AXI_BREADY),
// Master Interface Write Response Ports
.M_AXI_BID (M_AXI_BID),
.M_AXI_BRESP (M_AXI_BRESP),
.M_AXI_BUSER (M_AXI_BUSER),
.M_AXI_BVALID (M_AXI_BVALID),
.M_AXI_BREADY (M_AXI_BREADY),
// Trigger detection
.ERROR_TRIGGER (ERROR_TRIGGER),
.ERROR_TRANSACTION_ID (ERROR_TRANSACTION_ID)
);
/////////////////////////////////////////////////////////////////////////////
// Handle Read Channels (AR/R)
/////////////////////////////////////////////////////////////////////////////
// Read Address Port
assign M_AXI_ARID = S_AXI_ARID;
assign M_AXI_ARADDR = S_AXI_ARADDR;
assign M_AXI_ARLEN = S_AXI_ARLEN;
assign M_AXI_ARSIZE = S_AXI_ARSIZE;
assign M_AXI_ARBURST = S_AXI_ARBURST;
assign M_AXI_ARLOCK = S_AXI_ARLOCK;
assign M_AXI_ARCACHE = S_AXI_ARCACHE;
assign M_AXI_ARPROT = S_AXI_ARPROT;
assign M_AXI_ARUSER = S_AXI_ARUSER;
assign M_AXI_ARVALID = S_AXI_ARVALID;
assign S_AXI_ARREADY = M_AXI_ARREADY;
// Read Data Port
assign S_AXI_RID = M_AXI_RID;
assign S_AXI_RDATA = M_AXI_RDATA;
assign S_AXI_RRESP = M_AXI_RRESP;
assign S_AXI_RLAST = M_AXI_RLAST;
assign S_AXI_RUSER = M_AXI_RUSER;
assign S_AXI_RVALID = M_AXI_RVALID;
assign M_AXI_RREADY = S_AXI_RREADY;
endmodule
`default_nettype wire
@@ -0,0 +1,298 @@
// -- (c) Copyright 2010 - 2011 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.
//-----------------------------------------------------------------------------
//
// Description: Address Write Channel for ATC
//
//
// Verilog-standard: Verilog 2001
//--------------------------------------------------------------------------
//
// Structure:
// aw_atc
//
//--------------------------------------------------------------------------
`timescale 1ps/1ps
module processing_system7_v5_5_aw_atc #
(
parameter C_FAMILY = "rtl",
// FPGA Family. Current version: virtex6, spartan6 or later.
parameter integer C_AXI_ID_WIDTH = 4,
// Width of all ID signals on SI and MI side of checker.
// Range: >= 1.
parameter integer C_AXI_ADDR_WIDTH = 32,
// Width of all ADDR signals on SI and MI side of checker.
// Range: 32.
parameter integer C_AXI_AWUSER_WIDTH = 1,
// Width of AWUSER signals.
// Range: >= 1.
parameter integer C_FIFO_DEPTH_LOG = 4
)
(
// Global Signals
input wire ARESET,
input wire ACLK,
// Command Interface
output reg cmd_w_valid,
output wire cmd_w_check,
output wire [C_AXI_ID_WIDTH-1:0] cmd_w_id,
input wire cmd_w_ready,
input wire [C_FIFO_DEPTH_LOG-1:0] cmd_b_addr,
input wire cmd_b_ready,
// Slave Interface Write Address Port
input wire [C_AXI_ID_WIDTH-1:0] S_AXI_AWID,
input wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR,
input wire [4-1:0] S_AXI_AWLEN,
input wire [3-1:0] S_AXI_AWSIZE,
input wire [2-1:0] S_AXI_AWBURST,
input wire [2-1:0] S_AXI_AWLOCK,
input wire [4-1:0] S_AXI_AWCACHE,
input wire [3-1:0] S_AXI_AWPROT,
input wire [C_AXI_AWUSER_WIDTH-1:0] S_AXI_AWUSER,
input wire S_AXI_AWVALID,
output wire S_AXI_AWREADY,
// Master Interface Write Address Port
output wire [C_AXI_ID_WIDTH-1:0] M_AXI_AWID,
output wire [C_AXI_ADDR_WIDTH-1:0] M_AXI_AWADDR,
output wire [4-1:0] M_AXI_AWLEN,
output wire [3-1:0] M_AXI_AWSIZE,
output wire [2-1:0] M_AXI_AWBURST,
output wire [2-1:0] M_AXI_AWLOCK,
output wire [4-1:0] M_AXI_AWCACHE,
output wire [3-1:0] M_AXI_AWPROT,
output wire [C_AXI_AWUSER_WIDTH-1:0] M_AXI_AWUSER,
output wire M_AXI_AWVALID,
input wire M_AXI_AWREADY
);
/////////////////////////////////////////////////////////////////////////////
// Local params
/////////////////////////////////////////////////////////////////////////////
// Constants for burst types.
localparam [2-1:0] C_FIX_BURST = 2'b00;
localparam [2-1:0] C_INCR_BURST = 2'b01;
localparam [2-1:0] C_WRAP_BURST = 2'b10;
// Constants for size.
localparam [3-1:0] C_OPTIMIZED_SIZE = 3'b011;
// Constants for length.
localparam [4-1:0] C_OPTIMIZED_LEN = 4'b0011;
// Constants for cacheline address.
localparam [4-1:0] C_NO_ADDR_OFFSET = 5'b0;
// Command FIFO settings
localparam C_FIFO_WIDTH = C_AXI_ID_WIDTH + 1;
localparam C_FIFO_DEPTH = 2 ** C_FIFO_DEPTH_LOG;
/////////////////////////////////////////////////////////////////////////////
// Variables for generating parameter controlled instances.
/////////////////////////////////////////////////////////////////////////////
integer index;
/////////////////////////////////////////////////////////////////////////////
// Functions
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Internal signals
/////////////////////////////////////////////////////////////////////////////
// Transaction properties.
wire access_is_incr;
wire access_is_wrap;
wire access_is_coherent;
wire access_optimized_size;
wire incr_addr_boundary;
wire incr_is_optimized;
wire wrap_is_optimized;
wire access_is_optimized;
// Command FIFO.
wire cmd_w_push;
reg cmd_full;
reg [C_FIFO_DEPTH_LOG-1:0] addr_ptr;
wire [C_FIFO_DEPTH_LOG-1:0] all_addr_ptr;
reg [C_FIFO_WIDTH-1:0] data_srl[C_FIFO_DEPTH-1:0];
/////////////////////////////////////////////////////////////////////////////
// Transaction Decode:
//
// Detect if transaction is of correct typ, size and length to qualify as
// an optimized transaction that has to be checked for errors.
//
/////////////////////////////////////////////////////////////////////////////
// Transaction burst type.
assign access_is_incr = ( S_AXI_AWBURST == C_INCR_BURST );
assign access_is_wrap = ( S_AXI_AWBURST == C_WRAP_BURST );
// Transaction has to be Coherent.
assign access_is_coherent = ( S_AXI_AWUSER[0] == 1'b1 ) &
( S_AXI_AWCACHE[1] == 1'b1 );
// Transaction cacheline boundary address.
assign incr_addr_boundary = ( S_AXI_AWADDR[4:0] == C_NO_ADDR_OFFSET );
// Transaction length & size.
assign access_optimized_size = ( S_AXI_AWSIZE == C_OPTIMIZED_SIZE ) &
( S_AXI_AWLEN == C_OPTIMIZED_LEN );
// Transaction is optimized.
assign incr_is_optimized = access_is_incr & access_is_coherent & access_optimized_size & incr_addr_boundary;
assign wrap_is_optimized = access_is_wrap & access_is_coherent & access_optimized_size;
assign access_is_optimized = ( incr_is_optimized | wrap_is_optimized );
/////////////////////////////////////////////////////////////////////////////
// Command FIFO:
//
// Since supported write interleaving is only 1, it is safe to use only a
// simple SRL based FIFO as a command queue.
//
/////////////////////////////////////////////////////////////////////////////
// Determine when transaction infromation is pushed to the FIFO.
assign cmd_w_push = S_AXI_AWVALID & M_AXI_AWREADY & ~cmd_full;
// SRL FIFO Pointer.
always @ (posedge ACLK) begin
if (ARESET) begin
addr_ptr <= {C_FIFO_DEPTH_LOG{1'b1}};
end else begin
if ( cmd_w_push & ~cmd_w_ready ) begin
addr_ptr <= addr_ptr + 1;
end else if ( ~cmd_w_push & cmd_w_ready ) begin
addr_ptr <= addr_ptr - 1;
end
end
end
// Total number of buffered commands.
assign all_addr_ptr = addr_ptr + cmd_b_addr + 2;
// FIFO Flags.
always @ (posedge ACLK) begin
if (ARESET) begin
cmd_full <= 1'b0;
cmd_w_valid <= 1'b0;
end else begin
if ( cmd_w_push & ~cmd_w_ready ) begin
cmd_w_valid <= 1'b1;
end else if ( ~cmd_w_push & cmd_w_ready ) begin
cmd_w_valid <= ( addr_ptr != 0 );
end
if ( cmd_w_push & ~cmd_b_ready ) begin
// Going to full.
cmd_full <= ( all_addr_ptr == C_FIFO_DEPTH-3 );
end else if ( ~cmd_w_push & cmd_b_ready ) begin
// Pop in middle of queue doesn't affect full status.
cmd_full <= ( all_addr_ptr == C_FIFO_DEPTH-2 );
end
end
end
// Infere SRL for storage.
always @ (posedge ACLK) begin
if ( cmd_w_push ) begin
for (index = 0; index < C_FIFO_DEPTH-1 ; index = index + 1) begin
data_srl[index+1] <= data_srl[index];
end
data_srl[0] <= {access_is_optimized, S_AXI_AWID};
end
end
// Get current transaction info.
assign {cmd_w_check, cmd_w_id} = data_srl[addr_ptr];
/////////////////////////////////////////////////////////////////////////////
// Transaction Throttling:
//
// Stall commands if FIFO is full.
//
/////////////////////////////////////////////////////////////////////////////
// Propagate masked valid.
assign M_AXI_AWVALID = S_AXI_AWVALID & ~cmd_full;
// Return ready with push back.
assign S_AXI_AWREADY = M_AXI_AWREADY & ~cmd_full;
/////////////////////////////////////////////////////////////////////////////
// Address Write propagation:
//
// All information is simply forwarded on from the SI- to MI-Side untouched.
//
/////////////////////////////////////////////////////////////////////////////
// 1:1 mapping.
assign M_AXI_AWID = S_AXI_AWID;
assign M_AXI_AWADDR = S_AXI_AWADDR;
assign M_AXI_AWLEN = S_AXI_AWLEN;
assign M_AXI_AWSIZE = S_AXI_AWSIZE;
assign M_AXI_AWBURST = S_AXI_AWBURST;
assign M_AXI_AWLOCK = S_AXI_AWLOCK;
assign M_AXI_AWCACHE = S_AXI_AWCACHE;
assign M_AXI_AWPROT = S_AXI_AWPROT;
assign M_AXI_AWUSER = S_AXI_AWUSER;
endmodule
@@ -0,0 +1,413 @@
// -- (c) Copyright 2010 - 2011 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.
//-----------------------------------------------------------------------------
//
// Description: Write Response Channel for ATC
//
//
// Verilog-standard: Verilog 2001
//--------------------------------------------------------------------------
//
// Structure:
// b_atc
//
//--------------------------------------------------------------------------
`timescale 1ps/1ps
module processing_system7_v5_5_b_atc #
(
parameter C_FAMILY = "rtl",
// FPGA Family. Current version: virtex6, spartan6 or later.
parameter integer C_AXI_ID_WIDTH = 4,
// Width of all ID signals on SI and MI side of checker.
// Range: >= 1.
parameter integer C_AXI_BUSER_WIDTH = 1,
// Width of AWUSER signals.
// Range: >= 1.
parameter integer C_FIFO_DEPTH_LOG = 4
)
(
// Global Signals
input wire ARESET,
input wire ACLK,
// Command Interface
input wire cmd_b_push,
input wire cmd_b_error,
input wire [C_AXI_ID_WIDTH-1:0] cmd_b_id,
output wire cmd_b_ready,
output wire [C_FIFO_DEPTH_LOG-1:0] cmd_b_addr,
output reg cmd_b_full,
// Slave Interface Write Response Ports
output wire [C_AXI_ID_WIDTH-1:0] S_AXI_BID,
output reg [2-1:0] S_AXI_BRESP,
output wire [C_AXI_BUSER_WIDTH-1:0] S_AXI_BUSER,
output wire S_AXI_BVALID,
input wire S_AXI_BREADY,
// Master Interface Write Response Ports
input wire [C_AXI_ID_WIDTH-1:0] M_AXI_BID,
input wire [2-1:0] M_AXI_BRESP,
input wire [C_AXI_BUSER_WIDTH-1:0] M_AXI_BUSER,
input wire M_AXI_BVALID,
output wire M_AXI_BREADY,
// Trigger detection
output reg ERROR_TRIGGER,
output reg [C_AXI_ID_WIDTH-1:0] ERROR_TRANSACTION_ID
);
/////////////////////////////////////////////////////////////////////////////
// Local params
/////////////////////////////////////////////////////////////////////////////
// Constants for packing levels.
localparam [2-1:0] C_RESP_OKAY = 2'b00;
localparam [2-1:0] C_RESP_EXOKAY = 2'b01;
localparam [2-1:0] C_RESP_SLVERROR = 2'b10;
localparam [2-1:0] C_RESP_DECERR = 2'b11;
// Command FIFO settings
localparam C_FIFO_WIDTH = C_AXI_ID_WIDTH + 1;
localparam C_FIFO_DEPTH = 2 ** C_FIFO_DEPTH_LOG;
/////////////////////////////////////////////////////////////////////////////
// Variables for generating parameter controlled instances.
/////////////////////////////////////////////////////////////////////////////
integer index;
/////////////////////////////////////////////////////////////////////////////
// Functions
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Internal signals
/////////////////////////////////////////////////////////////////////////////
// Command Queue.
reg [C_FIFO_DEPTH_LOG-1:0] addr_ptr;
reg [C_FIFO_WIDTH-1:0] data_srl[C_FIFO_DEPTH-1:0];
reg cmd_b_valid;
wire cmd_b_ready_i;
wire inject_error;
wire [C_AXI_ID_WIDTH-1:0] current_id;
// Search command.
wire found_match;
wire use_match;
wire matching_id;
// Manage valid command.
wire write_valid_cmd;
reg [C_FIFO_DEPTH-2:0] valid_cmd;
reg [C_FIFO_DEPTH-2:0] updated_valid_cmd;
reg [C_FIFO_DEPTH-2:0] next_valid_cmd;
reg [C_FIFO_DEPTH_LOG-1:0] search_addr_ptr;
reg [C_FIFO_DEPTH_LOG-1:0] collapsed_addr_ptr;
// Pipelined data
reg [C_AXI_ID_WIDTH-1:0] M_AXI_BID_I;
reg [2-1:0] M_AXI_BRESP_I;
reg [C_AXI_BUSER_WIDTH-1:0] M_AXI_BUSER_I;
reg M_AXI_BVALID_I;
wire M_AXI_BREADY_I;
/////////////////////////////////////////////////////////////////////////////
// Command Queue:
//
// Keep track of depth of Queue to generate full flag.
//
// Also generate valid to mark pressence of commands in Queue.
//
// Maintain Queue and extract data from currently searched entry.
//
/////////////////////////////////////////////////////////////////////////////
// SRL FIFO Pointer.
always @ (posedge ACLK) begin
if (ARESET) begin
addr_ptr <= {C_FIFO_DEPTH_LOG{1'b1}};
end else begin
if ( cmd_b_push & ~cmd_b_ready_i ) begin
// Pushing data increase length/addr.
addr_ptr <= addr_ptr + 1;
end else if ( cmd_b_ready_i ) begin
// Collapse addr when data is popped.
addr_ptr <= collapsed_addr_ptr;
end
end
end
// FIFO Flags.
always @ (posedge ACLK) begin
if (ARESET) begin
cmd_b_full <= 1'b0;
cmd_b_valid <= 1'b0;
end else begin
if ( cmd_b_push & ~cmd_b_ready_i ) begin
cmd_b_full <= ( addr_ptr == C_FIFO_DEPTH-3 );
cmd_b_valid <= 1'b1;
end else if ( ~cmd_b_push & cmd_b_ready_i ) begin
cmd_b_full <= 1'b0;
cmd_b_valid <= ( collapsed_addr_ptr != C_FIFO_DEPTH-1 );
end
end
end
// Infere SRL for storage.
always @ (posedge ACLK) begin
if ( cmd_b_push ) begin
for (index = 0; index < C_FIFO_DEPTH-1 ; index = index + 1) begin
data_srl[index+1] <= data_srl[index];
end
data_srl[0] <= {cmd_b_error, cmd_b_id};
end
end
// Get current transaction info.
assign {inject_error, current_id} = data_srl[search_addr_ptr];
// Assign outputs.
assign cmd_b_addr = collapsed_addr_ptr;
/////////////////////////////////////////////////////////////////////////////
// Search Command Queue:
//
// Search for matching valid command in queue.
//
// A command is found when an valid entry with correct ID is found. The queue
// is search from the oldest entry, i.e. from a high value.
// When new commands are pushed the search address has to be updated to always
// start the search from the oldest available.
//
/////////////////////////////////////////////////////////////////////////////
// Handle search addr.
always @ (posedge ACLK) begin
if (ARESET) begin
search_addr_ptr <= {C_FIFO_DEPTH_LOG{1'b1}};
end else begin
if ( cmd_b_ready_i ) begin
// Collapse addr when data is popped.
search_addr_ptr <= collapsed_addr_ptr;
end else if ( M_AXI_BVALID_I & cmd_b_valid & ~found_match & ~cmd_b_push ) begin
// Skip non valid command.
search_addr_ptr <= search_addr_ptr - 1;
end else if ( cmd_b_push ) begin
search_addr_ptr <= search_addr_ptr + 1;
end
end
end
// Check if searched command is valid and match ID (for existing response on MI side).
assign matching_id = ( M_AXI_BID_I == current_id );
assign found_match = valid_cmd[search_addr_ptr] & matching_id & M_AXI_BVALID_I;
assign use_match = found_match & S_AXI_BREADY;
/////////////////////////////////////////////////////////////////////////////
// Track Used Commands:
//
// Actions that affect Valid Command:
// * When a new command is pushed
// => Shift valid vector one step
// * When a command is used
// => Clear corresponding valid bit
//
/////////////////////////////////////////////////////////////////////////////
// Valid command status is updated when a command is used or a new one is pushed.
assign write_valid_cmd = cmd_b_push | cmd_b_ready_i;
// Update the used command valid bit.
always @ *
begin
updated_valid_cmd = valid_cmd;
updated_valid_cmd[search_addr_ptr] = ~use_match;
end
// Shift valid vector when command is pushed.
always @ *
begin
if ( cmd_b_push ) begin
next_valid_cmd = {updated_valid_cmd[C_FIFO_DEPTH-3:0], 1'b1};
end else begin
next_valid_cmd = updated_valid_cmd;
end
end
// Valid signals for next cycle.
always @ (posedge ACLK) begin
if (ARESET) begin
valid_cmd <= {C_FIFO_WIDTH{1'b0}};
end else if ( write_valid_cmd ) begin
valid_cmd <= next_valid_cmd;
end
end
// Detect oldest available command in Queue.
always @ *
begin
// Default to empty.
collapsed_addr_ptr = {C_FIFO_DEPTH_LOG{1'b1}};
for (index = 0; index < C_FIFO_DEPTH-2 ; index = index + 1) begin
if ( next_valid_cmd[index] ) begin
collapsed_addr_ptr = index;
end
end
end
/////////////////////////////////////////////////////////////////////////////
// Pipe incoming data:
//
// The B channel is piped to improve timing and avoid impact in search
// mechanism due to late arriving signals.
//
/////////////////////////////////////////////////////////////////////////////
// Clock data.
always @ (posedge ACLK) begin
if (ARESET) begin
M_AXI_BID_I <= {C_AXI_ID_WIDTH{1'b0}};
M_AXI_BRESP_I <= 2'b00;
M_AXI_BUSER_I <= {C_AXI_BUSER_WIDTH{1'b0}};
M_AXI_BVALID_I <= 1'b0;
end else begin
if ( M_AXI_BREADY_I | ~M_AXI_BVALID_I ) begin
M_AXI_BVALID_I <= 1'b0;
end
if (M_AXI_BVALID & ( M_AXI_BREADY_I | ~M_AXI_BVALID_I) ) begin
M_AXI_BID_I <= M_AXI_BID;
M_AXI_BRESP_I <= M_AXI_BRESP;
M_AXI_BUSER_I <= M_AXI_BUSER;
M_AXI_BVALID_I <= 1'b1;
end
end
end
// Generate ready to get new transaction.
assign M_AXI_BREADY = M_AXI_BREADY_I | ~M_AXI_BVALID_I;
/////////////////////////////////////////////////////////////////////////////
// Inject Error:
//
// BRESP is modified according to command information.
//
/////////////////////////////////////////////////////////////////////////////
// Inject error in response.
always @ *
begin
if ( inject_error ) begin
S_AXI_BRESP = C_RESP_SLVERROR;
end else begin
S_AXI_BRESP = M_AXI_BRESP_I;
end
end
// Handle interrupt generation.
always @ (posedge ACLK) begin
if (ARESET) begin
ERROR_TRIGGER <= 1'b0;
ERROR_TRANSACTION_ID <= {C_AXI_ID_WIDTH{1'b0}};
end else begin
if ( inject_error & cmd_b_ready_i ) begin
ERROR_TRIGGER <= 1'b1;
ERROR_TRANSACTION_ID <= M_AXI_BID_I;
end else begin
ERROR_TRIGGER <= 1'b0;
end
end
end
/////////////////////////////////////////////////////////////////////////////
// Transaction Throttling:
//
// Response is passed forward when a matching entry has been found in queue.
// Both ready and valid are set when the command is completed.
//
/////////////////////////////////////////////////////////////////////////////
// Propagate masked valid.
assign S_AXI_BVALID = M_AXI_BVALID_I & cmd_b_valid & found_match;
// Return ready with push back.
assign M_AXI_BREADY_I = cmd_b_valid & use_match;
// Command has been handled.
assign cmd_b_ready_i = M_AXI_BVALID_I & cmd_b_valid & use_match;
assign cmd_b_ready = cmd_b_ready_i;
/////////////////////////////////////////////////////////////////////////////
// Write Response Propagation:
//
// All information is simply forwarded on from MI- to SI-Side untouched.
//
/////////////////////////////////////////////////////////////////////////////
// 1:1 mapping.
assign S_AXI_BID = M_AXI_BID_I;
assign S_AXI_BUSER = M_AXI_BUSER_I;
endmodule
@@ -0,0 +1,310 @@
// -- (c) Copyright 2009 - 2011 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: trace_buffer.v
// Description: Trace port buffer
//-----------------------------------------------------------------------------
// Structure: This section shows the hierarchical structure of
// pss_wrapper.
//
// --processing_system7
// |
// --trace_buffer
//-----------------------------------------------------------------------------
module processing_system7_v5_5_trace_buffer #
(
parameter integer FIFO_SIZE = 128,
parameter integer USE_TRACE_DATA_EDGE_DETECTOR = 0,
parameter integer C_DELAY_CLKS = 12
)
(
input wire TRACE_CLK,
input wire RST,
input wire TRACE_VALID_IN,
input wire [3:0] TRACE_ATID_IN,
input wire [31:0] TRACE_DATA_IN,
output wire TRACE_VALID_OUT,
output wire [3:0] TRACE_ATID_OUT,
output wire [31:0] TRACE_DATA_OUT
);
//------------------------------------------------------------
// Architecture section
//------------------------------------------------------------
// function called clogb2 that returns an integer which has the
// value of the ceiling of the log base 2.
function integer clogb2 (input integer bit_depth);
integer i;
integer temp_log;
begin
temp_log = 0;
for(i=bit_depth; i > 0; i = i>>1)
clogb2 = temp_log;
temp_log=temp_log+1;
end
endfunction
localparam DEPTH = clogb2(FIFO_SIZE-1);
wire [31:0] reset_zeros;
reg [31:0] trace_pedge; // write enable for FIFO
reg [31:0] ti;
reg [31:0] tom;
reg [3:0] atid;
reg [31:0] trace_fifo [FIFO_SIZE-1:0];//Memory
reg [4:0] dly_ctr;
reg [DEPTH-1:0] fifo_wp;
reg [DEPTH-1:0] fifo_rp;
reg fifo_re;
wire fifo_empty;
wire fifo_full;
reg fifo_full_reg;
assign reset_zeros = 32'h0;
// Pipeline Stage for Traceport ATID ports
always @(posedge TRACE_CLK) begin
// process pedge_ti
// rising clock edge
if((RST == 1'b1)) begin
atid <= reset_zeros;
end
else begin
atid <= TRACE_ATID_IN;
end
end
assign TRACE_ATID_OUT = atid;
/////////////////////////////////////////////
// Generate FIFO data based on TRACE_VALID_IN
/////////////////////////////////////////////
generate
if (USE_TRACE_DATA_EDGE_DETECTOR == 0) begin : gen_no_data_edge_detector
/////////////////////////////////////////////
// memory update process
// Update memory when positive edge detected and FIFO not full
always @(posedge TRACE_CLK) begin
if (TRACE_VALID_IN == 1'b1 && fifo_full_reg != 1'b1) begin
trace_fifo[fifo_wp] <= TRACE_DATA_IN;
end
end
// fifo write pointer
always @(posedge TRACE_CLK) begin
// process
if(RST == 1'b1) begin
fifo_wp <= {DEPTH{1'b0}};
end
else if(TRACE_VALID_IN ) begin
if(fifo_wp == (FIFO_SIZE - 1)) begin
if (fifo_empty) begin
fifo_wp <= {DEPTH{1'b0}};
end
end
else begin
fifo_wp <= fifo_wp + 1;
end
end
end
/////////////////////////////////////////////
// Generate FIFO data based on data edge
/////////////////////////////////////////////
end else begin : gen_data_edge_detector
/////////////////////////////////////////////
// purpose: check for pos edge on any trace input
always @(posedge TRACE_CLK) begin
// process pedge_ti
// rising clock edge
if((RST == 1'b1)) begin
ti <= reset_zeros;
trace_pedge <= reset_zeros;
end
else begin
ti <= TRACE_DATA_IN;
trace_pedge <= (~ti & TRACE_DATA_IN);
//trace_pedge <= ((~ti ^ TRACE_DATA_IN)) & ~ti;
// posedge only
end
end
// memory update process
// Update memory when positive edge detected and FIFO not full
always @(posedge TRACE_CLK) begin
if(|(trace_pedge) == 1'b1 && fifo_full_reg != 1'b1) begin
trace_fifo[fifo_wp] <= trace_pedge;
end
end
// fifo write pointer
always @(posedge TRACE_CLK) begin
// process
if(RST == 1'b1) begin
fifo_wp <= {DEPTH{1'b0}};
end
else if(|(trace_pedge) == 1'b1) begin
if(fifo_wp == (FIFO_SIZE - 1)) begin
if (fifo_empty) begin
fifo_wp <= {DEPTH{1'b0}};
end
end
else begin
fifo_wp <= fifo_wp + 1;
end
end
end
end
endgenerate
always @(posedge TRACE_CLK) begin
tom <= trace_fifo[fifo_rp] ;
end
// // fifo write pointer
// always @(posedge TRACE_CLK) begin
// // process
// if(RST == 1'b1) begin
// fifo_wp <= {DEPTH{1'b0}};
// end
// else if(|(trace_pedge) == 1'b1) begin
// if(fifo_wp == (FIFO_SIZE - 1)) begin
// fifo_wp <= {DEPTH{1'b0}};
// end
// else begin
// fifo_wp <= fifo_wp + 1;
// end
// end
// end
// fifo read pointer update
always @(posedge TRACE_CLK) begin
if(RST == 1'b1) begin
fifo_rp <= {DEPTH{1'b0}};
fifo_re <= 1'b0;
end
else if(fifo_empty != 1'b1 && dly_ctr == 5'b00000 && fifo_re == 1'b0) begin
fifo_re <= 1'b1;
if(fifo_rp == (FIFO_SIZE - 1)) begin
fifo_rp <= {DEPTH{1'b0}};
end
else begin
fifo_rp <= fifo_rp + 1;
end
end
else begin
fifo_re <= 1'b0;
end
end
// delay counter update
always @(posedge TRACE_CLK) begin
if(RST == 1'b1) begin
dly_ctr <= 5'h0;
end
else if (fifo_re == 1'b1) begin
dly_ctr <= C_DELAY_CLKS-1;
end
else if(dly_ctr != 5'h0) begin
dly_ctr <= dly_ctr - 1;
end
end
// fifo empty update
assign fifo_empty = (fifo_wp == fifo_rp) ? 1'b1 : 1'b0;
// fifo full update
assign fifo_full = (fifo_wp == FIFO_SIZE-1)? 1'b1 : 1'b0;
always @(posedge TRACE_CLK) begin
if(RST == 1'b1) begin
fifo_full_reg <= 1'b0;
end
else if (fifo_empty) begin
fifo_full_reg <= 1'b0;
end else begin
fifo_full_reg <= fifo_full;
end
end
// always @(posedge TRACE_CLK) begin
// if(RST == 1'b1) begin
// fifo_full_reg <= 1'b0;
// end
// else if ((fifo_wp == FIFO_SIZE-1) && (|(trace_pedge) == 1'b1)) begin
// fifo_full_reg <= 1'b1;
// end
// else begin
// fifo_full_reg <= 1'b0;
// end
// end
//
assign TRACE_DATA_OUT = tom;
assign TRACE_VALID_OUT = fifo_re;
endmodule
@@ -0,0 +1,244 @@
// -- (c) Copyright 2010 - 2011 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.
//-----------------------------------------------------------------------------
//
// Description: Write Channel for ATC
//
//
// Verilog-standard: Verilog 2001
//--------------------------------------------------------------------------
//
// Structure:
// w_atc
//
//--------------------------------------------------------------------------
`timescale 1ps/1ps
module processing_system7_v5_5_w_atc #
(
parameter C_FAMILY = "rtl",
// FPGA Family. Current version: virtex6, spartan6 or later.
parameter integer C_AXI_ID_WIDTH = 4,
// Width of all ID signals on SI and MI side of checker.
// Range: >= 1.
parameter integer C_AXI_DATA_WIDTH = 64,
// Width of all DATA signals on SI and MI side of checker.
// Range: 64.
parameter integer C_AXI_WUSER_WIDTH = 1
// Width of AWUSER signals.
// Range: >= 1.
)
(
// Global Signals
input wire ARESET,
input wire ACLK,
// Command Interface (In)
input wire cmd_w_valid,
input wire cmd_w_check,
input wire [C_AXI_ID_WIDTH-1:0] cmd_w_id,
output wire cmd_w_ready,
// Command Interface (Out)
output wire cmd_b_push,
output wire cmd_b_error,
output reg [C_AXI_ID_WIDTH-1:0] cmd_b_id,
input wire cmd_b_full,
// Slave Interface Write Port
input wire [C_AXI_ID_WIDTH-1:0] S_AXI_WID,
input wire [C_AXI_DATA_WIDTH-1:0] S_AXI_WDATA,
input wire [C_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB,
input wire S_AXI_WLAST,
input wire [C_AXI_WUSER_WIDTH-1:0] S_AXI_WUSER,
input wire S_AXI_WVALID,
output wire S_AXI_WREADY,
// Master Interface Write Address Port
output wire [C_AXI_ID_WIDTH-1:0] M_AXI_WID,
output wire [C_AXI_DATA_WIDTH-1:0] M_AXI_WDATA,
output wire [C_AXI_DATA_WIDTH/8-1:0] M_AXI_WSTRB,
output wire M_AXI_WLAST,
output wire [C_AXI_WUSER_WIDTH-1:0] M_AXI_WUSER,
output wire M_AXI_WVALID,
input wire M_AXI_WREADY
);
/////////////////////////////////////////////////////////////////////////////
// Local params
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Variables for generating parameter controlled instances.
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Functions
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Internal signals
/////////////////////////////////////////////////////////////////////////////
// Detecttion.
wire any_strb_deasserted;
wire incoming_strb_issue;
reg first_word;
reg strb_issue;
// Data flow.
wire data_pop;
wire cmd_b_push_blocked;
reg cmd_b_push_i;
/////////////////////////////////////////////////////////////////////////////
// Detect error:
//
// Detect and accumulate error when a transaction shall be scanned for
// potential issues.
// Accumulation of error is restarted for each ne transaction.
//
/////////////////////////////////////////////////////////////////////////////
// Check stobe information
assign any_strb_deasserted = ( S_AXI_WSTRB != {C_AXI_DATA_WIDTH/8{1'b1}} );
assign incoming_strb_issue = cmd_w_valid & S_AXI_WVALID & cmd_w_check & any_strb_deasserted;
// Keep track of first word in a transaction.
always @ (posedge ACLK) begin
if (ARESET) begin
first_word <= 1'b1;
end else if ( data_pop ) begin
first_word <= S_AXI_WLAST;
end
end
// Keep track of error status.
always @ (posedge ACLK) begin
if (ARESET) begin
strb_issue <= 1'b0;
cmd_b_id <= {C_AXI_ID_WIDTH{1'b0}};
end else if ( data_pop ) begin
if ( first_word ) begin
strb_issue <= incoming_strb_issue;
end else begin
strb_issue <= incoming_strb_issue | strb_issue;
end
cmd_b_id <= cmd_w_id;
end
end
assign cmd_b_error = strb_issue;
/////////////////////////////////////////////////////////////////////////////
// Control command queue to B:
//
// Push command to B queue when all data for the transaction has flowed
// through.
// Delay pipelined command until there is room in the Queue.
//
/////////////////////////////////////////////////////////////////////////////
// Detect when data is popped.
assign data_pop = S_AXI_WVALID & M_AXI_WREADY & cmd_w_valid & ~cmd_b_full & ~cmd_b_push_blocked;
// Push command when last word in transfered (pipelined).
always @ (posedge ACLK) begin
if (ARESET) begin
cmd_b_push_i <= 1'b0;
end else begin
cmd_b_push_i <= ( S_AXI_WLAST & data_pop ) | cmd_b_push_blocked;
end
end
// Detect if pipelined push is blocked.
assign cmd_b_push_blocked = cmd_b_push_i & cmd_b_full;
// Assign output.
assign cmd_b_push = cmd_b_push_i & ~cmd_b_full;
/////////////////////////////////////////////////////////////////////////////
// Transaction Throttling:
//
// Stall commands if FIFO is full or there is no valid command information
// from AW.
//
/////////////////////////////////////////////////////////////////////////////
// Propagate masked valid.
assign M_AXI_WVALID = S_AXI_WVALID & cmd_w_valid & ~cmd_b_full & ~cmd_b_push_blocked;
// Return ready with push back.
assign S_AXI_WREADY = M_AXI_WREADY & cmd_w_valid & ~cmd_b_full & ~cmd_b_push_blocked;
// End of burst.
assign cmd_w_ready = S_AXI_WVALID & M_AXI_WREADY & cmd_w_valid & ~cmd_b_full & ~cmd_b_push_blocked & S_AXI_WLAST;
/////////////////////////////////////////////////////////////////////////////
// Write propagation:
//
// All information is simply forwarded on from the SI- to MI-Side untouched.
//
/////////////////////////////////////////////////////////////////////////////
// 1:1 mapping.
assign M_AXI_WID = S_AXI_WID;
assign M_AXI_WDATA = S_AXI_WDATA;
assign M_AXI_WSTRB = S_AXI_WSTRB;
assign M_AXI_WLAST = S_AXI_WLAST;
assign M_AXI_WUSER = S_AXI_WUSER;
endmodule
@@ -0,0 +1,71 @@
// (c) Copyright 2015 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.
//-----------------------------------------------------------------------------
// Begin sc_node_v1_0_10_structs.svh
//-----------------------------------------------------------------------------
typedef logic [C_NUM_MI-1:0] t_route;
typedef logic [C_INFO_WIDTH-1:0] t_info;
typedef logic [C_LOG_MAX_DOWNSIZER_RATIO-1:0] t_downsizer_count;
typedef logic [C_LOG_NUM_SI-1:0] t_source;
typedef struct packed {
t_max_byte_size end_pntr;
t_max_byte_size start_pntr;
t_downsizer_count repeat_count;
} t_send;
typedef struct packed {
t_source source;
t_route sc_route;
t_info info;
} t_req;
typedef struct packed {
t_send send;
t_req req;
} t_reqsend;
//-----------------------------------------------------------------------------
// end sc_node_v1_0_10_structs.svh
//-----------------------------------------------------------------------------
@@ -0,0 +1,348 @@
`pragma protect begin_protected
`pragma protect version = 1
`pragma protect encrypt_agent = "XILINX"
`pragma protect encrypt_agent_info = "Xilinx Encryption Tool 2019.1"
`pragma protect key_keyowner = "Cadence Design Systems.", key_keyname = "cds_rsa_key", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 64)
`pragma protect key_block
Mj0RVcXMxOogac077GgRE7idHNUaqqDFsZ45pjDVSkamRDu9d++Qiwj11vZvvO4/t7/5BqZ5y9ey
xTDzpPchxA==
`pragma protect key_keyowner = "Synopsys", key_keyname = "SNPS-VCS-RSA-2", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 128)
`pragma protect key_block
YPIJz8TpEoAGpd6XFvm2fi5IfUn2rqXbVwmQCHkg6WJLfYJNuyMDjNl53GpdL8zxPAStJgwCtbOi
lFGCu8c3Q5LWH97lPdnGFTaj/abNPV//53KGl3vVFabPoKJHg+D2Cv98tztXnl7fcj0Ta6P7FgwR
6k1oxzAvSlzXi9FWgmQ=
`pragma protect key_keyowner = "Aldec", key_keyname = "ALDEC15_001", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
OhLi1snBaVkX2Z1qjaYw/YfuWnrGuq/ERpLAsJovfcbjwdVBjK/mcEu/iIntsApzVKRHEwMM2Fzq
D4b+HrMzt2C8ODXu2xD6iJ1VZdxnEfJ64N/gnf/m1c7aTraaEKyFvlc2O3YJnRgP+ig00SDvvGvX
9dAdaCeGA/EmiNGdxG4+/ADMfIFM+BgygwzjyVAPm7Mtz1M/qqvvqrM3OgQHWPTbphlNoqRcLl9k
lFqmsSsk2QUI4TldOYXhWnKiTRwmXhr389e1vTVr02VVQ1/Let3jBW+ARHqFmlvy1NMz3jy7AQFy
piCItp2FylfmJ3tHkf2xqQOFqhcq7oOa4NSI5A==
`pragma protect key_keyowner = "ATRENTA", key_keyname = "ATR-SG-2015-RSA-3", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
SWtAy33EA0+wdNeop42WcOSlh/dJs+iER936x5Q5TLxqyKlgNru+2VcQF1Jln9BLMkKXesKfNPXZ
pF2ChNo/aD0feEmPIgkuujIvUtnVWcWcIzhR0YAz9EUeT+zmhAnlP0YjkSwNEW7Ns94vqGGd4WIE
9Ckr++xDMGCd2wxRK6Znf+4dGqMawPqbTHQWCmAZ3CFq5jSbVv09bZ01Xfv+64Wl8g6P3xwwZEI4
HNUOCnndshSxfx/yzU8htD2iJypN4dmZD/B3odcWgdDkHp+6iztjBeeL9vto7k77WOircD9G4fFA
sOVTPiB9llg1f0WSPS8Mhet6sWLEBq0SyZpMlw==
`pragma protect key_keyowner = "Xilinx", key_keyname = "xilinxt_2019_02", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
EscYaFmJuxpHSuXnAhPm1uJR5v8WXi7Wa/ExVIGQJOKsTPfO7Fs4j4N/G5zNOrSnPgdjEUPmA9iU
MM+RHuoVGBEIcm1u+7E23vzlpZWGdSjF0pw8MCjwg2WkY3sT/jHZq2t34QmUI5744wk8xgWXxDRF
IFIz/As4FSnWoRKWMHPaw0QAH8+A1PgdLlLK7ybme2dzw27rNvZcibJfMgnZQgVAGcWKrwGhnsdK
uvNUXShTsrqf71d5wr05byYl48u31MGwSYFcacXi3UIuu6XKUkYsyf8I8vKlujJeDN1xbfZrlBqO
92PDI9Gi5BB7LXb2cIBfliC0K3E2Cp2bO/BEmg==
`pragma protect key_keyowner = "Mentor Graphics Corporation", key_keyname = "MGC-VELOCE-RSA", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 128)
`pragma protect key_block
Vzxkc99KauSK0thoPrJgY9FLTR2xcYXojTXoLMUDcHBEXzvkzgijQUNskf25BNhd/bIGQMgo6sYX
+XN42PDNR9j9zY6VEemVXHz+0C5eXVuS30bIryOmjyXpM37oOZIEPAjd8BaFmbq9U22hpSyqKOdO
Tomi4k/wVMA+Xblrdq0=
`pragma protect key_keyowner = "Mentor Graphics Corporation", key_keyname = "MGC-VERIF-SIM-RSA-2", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
ViO/Eqyl9+cA33Ade0wDFrUKNwN79/SmqZl6stZNLtm2PJVu2M98FiS1DBpbGcKoFrV75UfzITOu
g8xX/NOdTZeje2VROP1A25hbr/PusUsorFAqmii+W3loS2PnEv9R1Ja47IvWWfq20oP43MwP8iGi
2CYf6hFGN0nAMPUXBM1wDbtq6CWicdAp7BSBw9XhOTClZOt5fJ+stCx3eKZk/HldZZ7XKahsq253
vOcp+MqYfmxxNO1/xBEaQDDFW65t7tPIMW3CnyronuVlmYzQgoQRYxbhxvD//bt8dzX5up8dEn9G
1UhqygjLY36OebidaZvuwoX7lc22G6/tNh8h4w==
`pragma protect data_method = "AES128-CBC"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 16176)
`pragma protect data_block
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
`pragma protect end_protected
@@ -0,0 +1,225 @@
`pragma protect begin_protected
`pragma protect version = 1
`pragma protect encrypt_agent = "XILINX"
`pragma protect encrypt_agent_info = "Xilinx Encryption Tool 2019.1"
`pragma protect key_keyowner = "Cadence Design Systems.", key_keyname = "cds_rsa_key", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 64)
`pragma protect key_block
au1Iysai0YW4J0IAU/EIu0GzZRTJFc6zfCStTNmqiPD16m01BRnYyUamS7tNL49OTb8oyaIiAsMx
qXX/K8xOuQ==
`pragma protect key_keyowner = "Synopsys", key_keyname = "SNPS-VCS-RSA-2", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 128)
`pragma protect key_block
bZWnM/1ZCwr1YwTX/h4i42JgGZwO2TRr7ugf0imUE4dE6df4moPkvH0k4DcxXV1noNmI8Ys55Ptq
VtuCOapRGQZLsYWIur0LFEysKOqkbzyjQKj3BaqnJNxgGjFCyQauCHGMh02MwF1TF3UhEap2LAsX
DCgcXIbKRBreCq4f89o=
`pragma protect key_keyowner = "Aldec", key_keyname = "ALDEC15_001", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
e2IQR/qFMEiJJOh2aKZaJ1O3HWol6UrtvpfH00iqEbyvPNC0FDNKl0Nf2QxyXyJtrqncnLKI8jUK
Ie1RrlYSTrbXBZtnj34aPvXvvZqrGgwCqPXGIXzlvIvnWTWqPj8JP461TRpfef1/Ilt9r98QyXP6
sBOku54BuS5LL2NXIOVSkGjuzfiHBiUInkkeNKJZUgKVyMwgpbkkTx8YiWckT35DAxVZu0hqU7xr
/5ol8YCpNuyT8nd9951szOAKQKgIOEr0K5reSYgsnkKsAJFLoniIOXT990zljz6rTnKTcQfSDz57
9ezImbWfJ4w7FbQsZTMC2uytZYWq2KOV9cD/iA==
`pragma protect key_keyowner = "ATRENTA", key_keyname = "ATR-SG-2015-RSA-3", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
XHkAz8Dq96Nt0BK/KkwweLJRv0BIFSye9ADK1mptMNKG4SnzqZJN3Ihs5o2V95jVmzVkOjbglTXA
io8qbLBXC31BMgoJ+mnKS11CYESJAc19hQ1Cbp+dum22PybVxg4bqxl3NUHoK2BAEVPcPPilsofG
8VhG/B/n+EtLuJP+dNeXrBYV2SuZ8hhHELs5X4hoiB8nU5AhmjkCM/kqKXrl2dRpUTOryCPAacHr
1mRslrALw8UjtRNF73x/ojfBQ54KTI/bsY9B7doxldEG693cOkaU7cZrAFmFmuvpz7y9alMyXgYW
t0QkxhBhwgmp7RAupHm12whYj3Qh2rhIrNbRIQ==
`pragma protect key_keyowner = "Xilinx", key_keyname = "xilinxt_2019_02", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
nsvWpC8k/frHaqb3MXUQVLSgMQIvxXDAQABHgeqbrSY0ExpV+t4R3NLPTyYLDahTKtcAGfM1V3JP
M4WuiJROLdAfULQBuelzrG0gB58qHFTuVBRGU/P2nzrQtzOvPGH0F54P7xiyFF7iM0Vk+BsZm5oi
tR3ZvgpO8XGwdm+4Ic29xlgMip5ail3tKX/8v84u+ek28LR5DjvQSff7no6bAGCQUlRRhQMx5aYk
M9mkBN06L3/ylG3HM2s3SX/PTKdVX4apWaa52nD9yispxDWRee0h3/79knHjGiaakpp9aZ8YMkeH
HYU+v88ybyVUiLo+gxAVe5YHfB5BiV3UEvFuRw==
`pragma protect key_keyowner = "Mentor Graphics Corporation", key_keyname = "MGC-VELOCE-RSA", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 128)
`pragma protect key_block
KEVSPugxPEqjTfSeDZc8uI6muR0KjImETPeDL9j76ei1PxGBrZGgYfszuMVU+gljAnRuxlJ3f9vp
wH+aYq6HKcOgbkLsYgWygq3vPuGbnWB7F2onUWPbJRdEF6WoeN+P4B/E7k1dRr22gRvUQ5O00ss8
Q3VuJYLKc8FoOFviMio=
`pragma protect key_keyowner = "Mentor Graphics Corporation", key_keyname = "MGC-VERIF-SIM-RSA-2", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
eca4fJdLUhkHuw55x4FT23/il3sCTxPxhXd7vTcmGhKwxqEGHChbm3RaJbLyJQ1VDcf7d4jLDmnu
865XmDZRvgVN74ubtDM7CWx3mkCUzo1prWG2/JOoOzoCRN1+/iBZA0fSPk76lNOULVODEIEnV6Ia
PKlFTA49EPWK3hRMbXV5jplcU+AzyqyW6BP/IvIIAPX77sSfm5V7Np6YgGtydKNXNbRYwyfG3UkF
FfNieEAwVKyzHLFdHYs2PuclbqJq8KOswbU9yq6AtpqKGBYQnIqiID7Wfo7PM8QNp+wrA3pPE7mB
0OeDdt5chXsg9Ybujf24v4hyNZEgSoI439vZtw==
`pragma protect data_method = "AES128-CBC"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 9136)
`pragma protect data_block
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
4mvHKxDMbWpAfkYR+tO9Ag==
`pragma protect end_protected
@@ -0,0 +1,671 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa, Karl Kurbjun and Carl Ribbing
// Date: 7/30/2014
// Design Name: MMCME2 DRP
// Module Name: mmcme2_drp_func.h
// Version: 1.04
// Target Devices: 7 Series || MMCM
// Tool versions: 2014.3
// Description: This header provides the functions necessary to
// calculate the DRP register values for the V6 MMCM.
//
// Revision Notes: 3/12 - Updating lookup_low/lookup_high (CR)
// 4/13 - Fractional divide function in mmcm_frac_count_calc function. CRS610807
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. 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, AND 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 AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2010 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages durring elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development
// only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("mmcm_pll_phase-divide:%d,phase:%d",
divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [6:0] divide // Max divide is 64
);
reg [2559:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001,
40'b00110_00110_1111101000_1111101001_0000000001,
40'b01000_01000_1111101000_1111101001_0000000001,
40'b01011_01011_1111101000_1111101001_0000000001,
40'b01110_01110_1111101000_1111101001_0000000001,
40'b10001_10001_1111101000_1111101001_0000000001,
40'b10011_10011_1111101000_1111101001_0000000001,
40'b10110_10110_1111101000_1111101001_0000000001,
40'b11001_11001_1111101000_1111101001_0000000001,
40'b11100_11100_1111101000_1111101001_0000000001,
40'b11111_11111_1110000100_1111101001_0000000001,
40'b11111_11111_1100111001_1111101001_0000000001,
40'b11111_11111_1011101110_1111101001_0000000001,
40'b11111_11111_1010111100_1111101001_0000000001,
40'b11111_11111_1010001010_1111101001_0000000001,
40'b11111_11111_1001110001_1111101001_0000000001,
40'b11111_11111_1000111111_1111101001_0000000001,
40'b11111_11111_1000100110_1111101001_0000000001,
40'b11111_11111_1000001101_1111101001_0000000001,
40'b11111_11111_0111110100_1111101001_0000000001,
40'b11111_11111_0111011011_1111101001_0000000001,
40'b11111_11111_0111000010_1111101001_0000000001,
40'b11111_11111_0110101001_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0101110111_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((64-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", mmcm_pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the MMCM
// and outputs the digital filter settings necessary.
function [9:0] mmcm_pll_filter_lookup
(
input [6:0] divide, // Max divide is 64
input [8*9:0] BANDWIDTH
);
reg [639:0] lookup_low;
reg [639:0] lookup_high;
reg [9:0] lookup_entry;
begin
lookup_low = {
// CP_RES_LFHF
10'b0010_1111_00,
10'b0010_1111_00,
10'b0010_1111_00,
10'b0010_1111_00,
10'b0010_0111_00,
10'b0010_1011_00,
10'b0010_1101_00,
10'b0010_0011_00,
10'b0010_0101_00,
10'b0010_0101_00,
10'b0010_1001_00,
10'b0010_1110_00,
10'b0010_1110_00,
10'b0010_1110_00,
10'b0010_1110_00,
10'b0010_0001_00,
10'b0010_0001_00,
10'b0010_0001_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00
};
lookup_high = {
// CP_RES_LFHF
10'b0010_1111_00,
10'b0100_1111_00,
10'b0101_1011_00,
10'b0111_0111_00,
10'b1101_0111_00,
10'b1110_1011_00,
10'b1110_1101_00,
10'b1111_0011_00,
10'b1110_0101_00,
10'b1111_0101_00,
10'b1111_1001_00,
10'b1101_0001_00,
10'b1111_1001_00,
10'b1111_1001_00,
10'b1111_1001_00,
10'b1111_1001_00,
10'b1111_0101_00,
10'b1111_0101_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b0101_1100_00,
10'b0101_1100_00,
10'b0101_1100_00,
10'b0101_1100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0111_0001_00,
10'b0111_0001_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0110_0001_00,
10'b0110_0001_00,
10'b0101_0110_00,
10'b0101_0110_00,
10'b0101_0110_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0100_1010_00,
10'b0011_1100_00,
10'b0011_1100_00
};
// Set lookup_entry with the explicit bits from lookup with a part select
if(BANDWIDTH == "LOW") begin
// Low Bandwidth
mmcm_pll_filter_lookup = lookup_low[ ((64-divide)*10) +: 10];
end else begin
// High or optimized bandwidth
mmcm_pll_filter_lookup = lookup_high[ ((64-divide)*10) +: 10];
end
`ifdef DEBUG
$display("filter_lookup: %b", mmcm_pll_filter_lookup);
`endif
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
// for fractional multiply/divide functions.
//
//
function [37:0] mmcm_frac_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle, // Multiplied by 1,000
input [9:0] frac // Multiplied by 1000
);
//Required for fractional divide calculations
reg [7:0] lt_frac;
reg [7:0] ht_frac;
reg /*[7:0]*/ wf_fall_frac;
reg /*[7:0]*/ wf_rise_frac;
reg [31:0] a;
reg [7:0] pm_rise_frac_filtered ;
reg [7:0] pm_fall_frac_filtered ;
reg [7:0] clkout0_divide_int;
reg [2:0] clkout0_divide_frac;
reg [7:0] even_part_high;
reg [7:0] even_part_low;
reg [7:0] odd;
reg [7:0] odd_and_frac;
reg [7:0] pm_fall;
reg [7:0] pm_rise;
reg [7:0] dt;
reg [7:0] dt_int;
reg [63:0] dt_calc;
reg [7:0] pm_rise_frac;
reg [7:0] pm_fall_frac;
reg [31:0] a_per_in_octets;
reg [31:0] a_phase_in_cycles;
parameter precision = 0.125;
reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
reg [31: 0] phase_pos;
reg [31: 0] phase_vco;
reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
//convert phase to fixed
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// Return value is
// Transfer data
// RESERVED [37:36]
// FRAC_TIME [35:33]
// FRAC_WF_FALL [32]
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
clkout0_divide_frac = frac / 125;
clkout0_divide_int = divide;
even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
even_part_low = even_part_high;
odd = clkout0_divide_int - even_part_high - even_part_low;
odd_and_frac = (8*odd) + clkout0_divide_frac;
lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
pm_rise = 0; //0
wf_fall_frac = ((odd_and_frac >=2) && (odd_and_frac <=9)) || ((clkout0_divide_frac == 1) && (clkout0_divide_int == 2));//CRS610807
wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
//Calculate phase in fractional cycles
a_per_in_octets = (8 * divide) + (frac / 125) ;
a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
pm_rise_frac = (a_phase_in_cycles[7:0] ==8'h00)?8'h00:a_phase_in_cycles[7:0] - {a_phase_in_cycles[7:3],3'b000};
dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
dt = dt_calc[7:0];
pm_rise_frac_filtered = (pm_rise_frac >=8) ? (pm_rise_frac ) - 8: pm_rise_frac ; //((phase_fixed * (divide + frac / 1000)) / 360) - {pm_rise_frac[7:3],3'b000};//$rtoi(clkout0_phase * clkout0_divide / 45);//a;
dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
pm_fall_frac = pm_fall + pm_rise_frac;
pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
mmcm_frac_count_calc[37:0] =
{ 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5:0],
pm_rise_frac_filtered[2], pm_rise_frac_filtered[1], pm_rise_frac_filtered[0], 1'b0, ht_frac[5:0], lt_frac[5:0]
} ;
`ifdef DEBUG
$display("-%d.%d p%d>> :DADDR_9_15 frac30to28.frac_en.wf_r_frac.dt:%b%d%d_%b:DADDR_7_13 pm_f_frac_filtered_29to27.wf_f_frac_26:%b%d:DADDR_8_14.pm_r_frac_filt_15to13.ht_frac.lt_frac:%b%b%b:", divide, frac, phase, clkout0_divide_frac, 1, wf_rise_frac, dt, pm_fall_frac_filtered, wf_fall_frac, pm_rise_frac_filtered, ht_frac, lt_frac);
`endif
end
endfunction
@@ -0,0 +1,531 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa, Karl Kurbjun and Carl Ribbing
// Date: 7/30/2014
// Design Name: PLLE2 DRP
// Module Name: plle2_drp_func.h
// Version: 2.00
// Target Devices: 7 Series || PLL
// Tool versions: 2014.3
// Description: This header provides the functions necessary to
// calculate the DRP register values for the V6 PLL.
// Updated for CR663854.
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. 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, AND 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 AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2010 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages durring elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development
// only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("mmcm_pll_phase-divide:%d,phase:%d",
divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [6:0] divide // Max divide is 64
);
reg [2559:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001,
40'b00110_00110_1111101000_1111101001_0000000001,
40'b01000_01000_1111101000_1111101001_0000000001,
40'b01011_01011_1111101000_1111101001_0000000001,
40'b01110_01110_1111101000_1111101001_0000000001,
40'b10001_10001_1111101000_1111101001_0000000001,
40'b10011_10011_1111101000_1111101001_0000000001,
40'b10110_10110_1111101000_1111101001_0000000001,
40'b11001_11001_1111101000_1111101001_0000000001,
40'b11100_11100_1111101000_1111101001_0000000001,
40'b11111_11111_1110000100_1111101001_0000000001,
40'b11111_11111_1100111001_1111101001_0000000001,
40'b11111_11111_1011101110_1111101001_0000000001,
40'b11111_11111_1010111100_1111101001_0000000001,
40'b11111_11111_1010001010_1111101001_0000000001,
40'b11111_11111_1001110001_1111101001_0000000001,
40'b11111_11111_1000111111_1111101001_0000000001,
40'b11111_11111_1000100110_1111101001_0000000001,
40'b11111_11111_1000001101_1111101001_0000000001,
40'b11111_11111_0111110100_1111101001_0000000001,
40'b11111_11111_0111011011_1111101001_0000000001,
40'b11111_11111_0111000010_1111101001_0000000001,
40'b11111_11111_0110101001_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0101110111_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((64-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", mmcm_pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the PLL
// and outputs the digital filter settings necessary.
function [9:0] mmcm_pll_filter_lookup
(
input [6:0] divide, // Max divide is 64
input [8*9:0] BANDWIDTH
);
reg [639:0] lookup_low;
reg [639:0] lookup_high;
reg [9:0] lookup_entry;
begin
lookup_low = {
// CP_RES_LFHF
10'b0010_1111_00,
10'b0010_1111_00,
10'b0010_0111_00,
10'b0010_1101_00,
10'b0010_0101_00,
10'b0010_0101_00,
10'b0010_1001_00,
10'b0010_1110_00,
10'b0010_1110_00,
10'b0010_0001_00,
10'b0010_0001_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00
};
lookup_high = {
// CP_RES_LFHF
10'b0011_0111_00,
10'b0011_0111_00,
10'b0101_1111_00,
10'b0111_1111_00,
10'b0111_1011_00,
10'b1101_0111_00,
10'b1110_1011_00,
10'b1110_1101_00,
10'b1111_1101_00,
10'b1111_0111_00,
10'b1111_1011_00,
10'b1111_1101_00,
10'b1111_0011_00,
10'b1110_0101_00,
10'b1111_0101_00,
10'b1111_0101_00,
10'b1111_0101_00,
10'b1111_0101_00,
10'b0111_0110_00,
10'b0111_0110_00,
10'b0111_0110_00,
10'b0111_0110_00,
10'b0101_1100_00,
10'b0101_1100_00,
10'b0101_1100_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b0100_0010_00,
10'b0100_0010_00,
10'b0100_0010_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0011_0100_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00
};
// Set lookup_entry with the explicit bits from lookup with a part select
if(BANDWIDTH == "LOW") begin
// Low Bandwidth
mmcm_pll_filter_lookup = lookup_low[ ((64-divide)*10) +: 10];
end else begin
// High or optimized bandwidth
mmcm_pll_filter_lookup = lookup_high[ ((64-divide)*10) +: 10];
end
`ifdef DEBUG
$display("filter_lookup: %b", mmcm_pll_filter_lookup);
`endif
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
@@ -0,0 +1,671 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa
// Date: 7/30/2014
// Design Name: MMCME2 DRP
// Module Name: mmcme2_drp_func.h
// Version: 1.04
// Target Devices: UltraScale Architecture || MMCM
// Tool versions: 2014.3
// Description: This header provides the functions necessary to
// calculate the DRP register values for the V6 MMCM.
//
// Revision Notes: 3/22 - Updating lookup_low/lookup_high (CR)
// 4/13 - Fractional divide function in mmcm_frac_count_calc function. CRS610807
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. 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, AND 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 AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2010 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages durring elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development
// only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("mmcm_pll_phase-divide:%d,phase:%d",
divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [6:0] divide // Max divide is 64
);
reg [2559:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001,
40'b00110_00110_1111101000_1111101001_0000000001,
40'b01000_01000_1111101000_1111101001_0000000001,
40'b01011_01011_1111101000_1111101001_0000000001,
40'b01110_01110_1111101000_1111101001_0000000001,
40'b10001_10001_1111101000_1111101001_0000000001,
40'b10011_10011_1111101000_1111101001_0000000001,
40'b10110_10110_1111101000_1111101001_0000000001,
40'b11001_11001_1111101000_1111101001_0000000001,
40'b11100_11100_1111101000_1111101001_0000000001,
40'b11111_11111_1110000100_1111101001_0000000001,
40'b11111_11111_1100111001_1111101001_0000000001,
40'b11111_11111_1011101110_1111101001_0000000001,
40'b11111_11111_1010111100_1111101001_0000000001,
40'b11111_11111_1010001010_1111101001_0000000001,
40'b11111_11111_1001110001_1111101001_0000000001,
40'b11111_11111_1000111111_1111101001_0000000001,
40'b11111_11111_1000100110_1111101001_0000000001,
40'b11111_11111_1000001101_1111101001_0000000001,
40'b11111_11111_0111110100_1111101001_0000000001,
40'b11111_11111_0111011011_1111101001_0000000001,
40'b11111_11111_0111000010_1111101001_0000000001,
40'b11111_11111_0110101001_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0101110111_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((64-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", mmcm_pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the MMCM
// and outputs the digital filter settings necessary.
function [9:0] mmcm_pll_filter_lookup
(
input [6:0] divide, // Max divide is 64
input [8*9:0] BANDWIDTH
);
reg [639:0] lookup_low;
reg [639:0] lookup_high;
reg [9:0] lookup_entry;
begin
lookup_low = {
// CP_RES_LFHF
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_0111_11,
10'b0010_0111_11,
10'b0010_0111_11,
10'b0010_1101_11,
10'b0010_1101_11,
10'b0010_1101_11,
10'b0010_0011_11,
10'b0010_0101_11,
10'b0010_0101_11,
10'b0010_0101_11,
10'b0010_1001_11,
10'b0010_1001_11,
10'b0010_1110_11,
10'b0010_1110_11,
10'b0010_1110_11,
10'b0010_1110_11,
10'b0010_1110_11,
10'b0010_1110_11,
10'b0010_0001_11,
10'b0010_0001_11,
10'b0010_0001_11,
10'b0010_0001_11,
10'b0010_0001_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11
};
lookup_high = {
// CP_RES_LFHF
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_1011_11,
10'b0011_1111_11,
10'b0100_1111_11,
10'b0100_1111_11,
10'b0101_1111_11,
10'b0110_1111_11,
10'b0111_1111_11,
10'b0111_1111_11,
10'b1100_1111_11,
10'b1101_1111_11,
10'b1110_1111_11,
10'b1111_1111_11,
10'b1111_1111_11,
10'b1110_0111_11,
10'b1110_1011_11,
10'b1111_0111_11,
10'b1111_1011_11,
10'b1111_1011_11,
10'b1110_1101_11,
10'b1111_1101_11,
10'b1111_1101_11,
10'b1111_0011_11,
10'b1111_0011_11,
10'b1111_0011_11,
10'b1110_0101_11,
10'b1110_0101_11,
10'b1110_0101_11,
10'b1111_0101_11,
10'b1111_0101_11,
10'b1111_0101_11,
10'b1111_1001_11,
10'b1111_1001_11,
10'b1111_1001_11,
10'b1111_1001_11,
10'b1111_1001_11,
10'b1110_1110_11,
10'b1110_1110_11,
10'b1110_1110_11,
10'b1110_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1110_0001_11,
10'b1110_0001_11,
10'b1110_0001_11,
10'b1110_0001_11,
10'b1110_0001_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_1010_11,
10'b1100_1010_11,
10'b1100_1010_11,
10'b1100_1010_11
};
// Set lookup_entry with the explicit bits from lookup with a part select
if(BANDWIDTH == "LOW") begin
// Low Bandwidth
mmcm_pll_filter_lookup = lookup_low[ ((64-divide)*10) +: 10];
end else begin
// High or optimized bandwidth
mmcm_pll_filter_lookup = lookup_high[ ((64-divide)*10) +: 10];
end
`ifdef DEBUG
$display("filter_lookup: %b", mmcm_pll_filter_lookup);
`endif
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
// for fractional multiply/divide functions.
//
//
function [37:0] mmcm_frac_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle, // Multiplied by 1,000
input [9:0] frac // Multiplied by 1000
);
//Required for fractional divide calculations
reg [7:0] lt_frac;
reg [7:0] ht_frac;
reg /*[7:0]*/ wf_fall_frac;
reg /*[7:0]*/ wf_rise_frac;
reg [31:0] a;
reg [7:0] pm_rise_frac_filtered ;
reg [7:0] pm_fall_frac_filtered ;
reg [7:0] clkout0_divide_int;
reg [2:0] clkout0_divide_frac;
reg [7:0] even_part_high;
reg [7:0] even_part_low;
reg [7:0] odd;
reg [7:0] odd_and_frac;
reg [7:0] pm_fall;
reg [7:0] pm_rise;
reg [7:0] dt;
reg [7:0] dt_int;
reg [63:0] dt_calc;
reg [7:0] pm_rise_frac;
reg [7:0] pm_fall_frac;
reg [31:0] a_per_in_octets;
reg [31:0] a_phase_in_cycles;
parameter precision = 0.125;
reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
reg [31: 0] phase_pos;
reg [31: 0] phase_vco;
reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
//convert phase to fixed
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// Return value is
// Transfer data
// RESERVED [37:36]
// FRAC_TIME [35:33]
// FRAC_WF_FALL [32]
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
clkout0_divide_frac = frac / 125;
clkout0_divide_int = divide;
even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
even_part_low = even_part_high;
odd = clkout0_divide_int - even_part_high - even_part_low;
odd_and_frac = (8*odd) + clkout0_divide_frac;
lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
pm_rise = 0; //0
wf_fall_frac = ((odd_and_frac >=2) && (odd_and_frac <=9)) || ((clkout0_divide_frac == 1) && (clkout0_divide_int == 2));//CRS610807
wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
//Calculate phase in fractional cycles
a_per_in_octets = (8 * divide) + (frac / 125) ;
a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
pm_rise_frac = (a_phase_in_cycles[7:0] ==8'h00)?8'h00:a_phase_in_cycles[7:0] - {a_phase_in_cycles[7:3],3'b000};
dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
dt = dt_calc[7:0];
pm_rise_frac_filtered = (pm_rise_frac >=8) ? (pm_rise_frac ) - 8: pm_rise_frac ; //((phase_fixed * (divide + frac / 1000)) / 360) - {pm_rise_frac[7:3],3'b000};//$rtoi(clkout0_phase * clkout0_divide / 45);//a;
dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
pm_fall_frac = pm_fall + pm_rise_frac;
pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
mmcm_frac_count_calc[37:0] =
{ 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5:0],
pm_rise_frac_filtered[2], pm_rise_frac_filtered[1], pm_rise_frac_filtered[0], 1'b0, ht_frac[5:0], lt_frac[5:0]
} ;
`ifdef DEBUG
$display("-%d.%d p%d>> :DADDR_9_15 frac30to28.frac_en.wf_r_frac.dt:%b%d%d_%b:DADDR_7_13 pm_f_frac_filtered_29to27.wf_f_frac_26:%b%d:DADDR_8_14.pm_r_frac_filt_15to13.ht_frac.lt_frac:%b%b%b:", divide, frac, phase, clkout0_divide_frac, 1, wf_rise_frac, dt, pm_fall_frac_filtered, wf_fall_frac, pm_rise_frac_filtered, ht_frac, lt_frac);
`endif
end
endfunction
@@ -0,0 +1,530 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa
// Date: 6/15/2015
// Design Name: PLLE3 DRP
// Module Name: plle3_drp_func.h
// Version: 1.10
// Target Devices: UltraScale Architecture
// Tool versions: 2015.1
// Description: This header provides the functions necessary to
// calculate the DRP register values for the V6 PLL.
//
// Revision Notes: 8/11 - PLLE3 updated for PLLE3 file 4564419
// Revision Notes: 6/15 - pll_filter_lookup fixed for max M of 19
// PM_Rise bits have been removed for PLLE3
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. 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, AND 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 AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2010 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages durring elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development
// only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("mmcm_pll_phase-divide:%d,phase:%d",
divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [6:0] divide // Max divide is 64
);
reg [759:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001, //1
40'b00110_00110_1111101000_1111101001_0000000001, //2
40'b01000_01000_1111101000_1111101001_0000000001, //3
40'b01011_01011_1111101000_1111101001_0000000001, //4
40'b01110_01110_1111101000_1111101001_0000000001, //5
40'b10001_10001_1111101000_1111101001_0000000001, //6
40'b10011_10011_1111101000_1111101001_0000000001, //7
40'b10110_10110_1111101000_1111101001_0000000001, //8
40'b11001_11001_1111101000_1111101001_0000000001, //9
40'b11100_11100_1111101000_1111101001_0000000001, //10
40'b11111_11111_1110000100_1111101001_0000000001, //11
40'b11111_11111_1100111001_1111101001_0000000001, //12
40'b11111_11111_1011101110_1111101001_0000000001, //13
40'b11111_11111_1010111100_1111101001_0000000001, //14
40'b11111_11111_1010001010_1111101001_0000000001, //15
40'b11111_11111_1001110001_1111101001_0000000001, //16
40'b11111_11111_1000111111_1111101001_0000000001, //17
40'b11111_11111_1000100110_1111101001_0000000001, //18
40'b11111_11111_1000001101_1111101001_0000000001 //19
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((19-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", mmcm_pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the PLL
// and outputs the digital filter settings necessary. Removing bandwidth setting for PLLE3.
function [9:0] mmcm_pll_filter_lookup
(
input [6:0] divide // Max divide is 19
);
reg [639:0] lookup;
reg [9:0] lookup_entry;
begin
lookup = {
// CP_RES_LFHF
10'b0010_1111_01, //1
10'b0010_0011_11, //2
10'b0011_0011_11, //3
10'b0010_0001_11, //4
10'b0010_0110_11, //5
10'b0010_1010_11, //6
10'b0010_1010_11, //7
10'b0011_0110_11, //8
10'b0010_1100_11, //9
10'b0010_1100_11, //10
10'b0010_1100_11, //11
10'b0010_0010_11, //12
10'b0011_1100_11, //13
10'b0011_1100_11, //14
10'b0011_1100_11, //15
10'b0011_1100_11, //16
10'b0011_0010_11, //17
10'b0011_0010_11, //18
10'b0011_0010_11 //19
};
mmcm_pll_filter_lookup = lookup [ ((19-divide)*10) +: 10];
`ifdef DEBUG
$display("filter_lookup: %b", mmcm_pll_filter_lookup);
`endif
end
endfunction
// This function set the CLKOUTPHY divide settings to match
// the desired CLKOUTPHY_MODE setting. To create VCO_X2, then
// the CLKOUTPHY will be set to 2'b00 since the VCO is internally
// doubled and 2'b00 will represent divide by 1. Similarly "VCO" // will need to divide the doubled clock VCO clock frequency by // 2 therefore 2'b01 will match a divide by 2.And VCO_HALF will // need to divide the doubled VCO by 4, therefore 2'b10
function [9:0] mmcm_pll_clkoutphy_calc
(
input [8*9:0] CLKOUTPHY_MODE
);
if(CLKOUTPHY_MODE == "VCO_X2") begin
mmcm_pll_clkoutphy_calc= 2'b00;
end else if(CLKOUTPHY_MODE == "VCO") begin
mmcm_pll_clkoutphy_calc= 2'b01;
end else if(CLKOUTPHY_MODE == "CLKIN") begin
mmcm_pll_clkoutphy_calc= 2'b11;
end else begin // Assume "VCO_HALF"
mmcm_pll_clkoutphy_calc= 2'b10;
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], 3'b000);//Removed PM_Rise bits
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
// for fractional multiply/divide functions.
//
//
function [37:0] mmcm_pll_frac_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle, // Multiplied by 1,000
input [9:0] frac // Multiplied by 1000
);
//Required for fractional divide calculations
reg [7:0] lt_frac;
reg [7:0] ht_frac;
reg /*[7:0]*/ wf_fall_frac;
reg /*[7:0]*/ wf_rise_frac;
reg [31:0] a;
reg [7:0] pm_rise_frac_filtered ;
reg [7:0] pm_fall_frac_filtered ;
reg [7:0] clkout0_divide_int;
reg [2:0] clkout0_divide_frac;
reg [7:0] even_part_high;
reg [7:0] even_part_low;
reg [7:0] odd;
reg [7:0] odd_and_frac;
reg [7:0] pm_fall;
reg [7:0] pm_rise;
reg [7:0] dt;
reg [7:0] dt_int;
reg [63:0] dt_calc;
reg [7:0] pm_rise_frac;
reg [7:0] pm_fall_frac;
reg [31:0] a_per_in_octets;
reg [31:0] a_phase_in_cycles;
parameter precision = 0.125;
reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
reg [31: 0] phase_pos;
reg [31: 0] phase_vco;
reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
//convert phase to fixed
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// Return value is
// Transfer data
// RESERVED [37:36]
// FRAC_TIME [35:33]
// FRAC_WF_FALL [32]
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
clkout0_divide_frac = frac / 125;
clkout0_divide_int = divide;
even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
even_part_low = even_part_high;
odd = clkout0_divide_int - even_part_high - even_part_low;
odd_and_frac = (8*odd) + clkout0_divide_frac;
lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
pm_rise = 0; //0
wf_fall_frac = (odd_and_frac >=2) && (odd_and_frac <=9);//IF(odd_and_frac>=2,IF(odd_and_frac <= 9,1,0),0)
wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
//Calculate phase in fractional cycles
a_per_in_octets = (8 * divide) + (frac / 125) ;
a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
pm_rise_frac = (a_phase_in_cycles[7:0] ==8'h00)?8'h00:a_phase_in_cycles[7:0] - {a_phase_in_cycles[7:3],3'b000};
dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
dt = dt_calc[7:0];
pm_rise_frac_filtered = (pm_rise_frac >=8) ? (pm_rise_frac ) - 8: pm_rise_frac ; //((phase_fixed * (divide + frac / 1000)) / 360) - {pm_rise_frac[7:3],3'b000};//$rtoi(clkout0_phase * clkout0_divide / 45);//a;
dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
pm_fall_frac = pm_fall + pm_rise_frac;
pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
mmcm_pll_frac_count_calc[37:0] =
{ 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5:0],
3'b000, 1'b0, ht_frac[5:0], lt_frac[5:0] //Removed PM_Rise bits
// pm_rise_frac_filtered[2], pm_rise_frac_filtered[1], pm_rise_frac_filtered[0], 1'b0, ht_frac[5:0], lt_frac[5:0]
} ;
`ifdef DEBUG
$display("-%d.%d p%d>> :DADDR_9_15 frac30to28.frac_en.wf_r_frac.dt:%b%d%d_%b:DADDR_7_13 pm_f_frac_filtered_29to27.wf_f_frac_26:%b%d:DADDR_8_14.pm_r_frac_filt_15to13.ht_frac.lt_frac:%b%b%b:", divide, frac, phase, clkout0_divide_frac, 1, wf_rise_frac, dt, pm_fall_frac_filtered, wf_fall_frac, 3'b000, ht_frac, lt_frac);
`endif
end
endfunction
@@ -0,0 +1,861 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa. Updated by Ralf Krueger
// Date: 7/30/2014
// Design Name: MMCME4 DRP
// Module Name: mmcme4_drp_func.h
// Version: 1.31
// Target Devices: UltraScale Plus Architecture
// Tool versions: 2017.1
// Description: This header provides the functions necessary to
// calculate the DRP register values for UltraScal+ MMCM.
//
// Revision Notes: 3/22 - Updating lookup_low/lookup_high (CR)
// 4/13 - Fractional divide function in mmcm_frac_count_calc function
// 2/28/17 - Updated for Ultrascale Plus
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. 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, AND 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 AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2017 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages during elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("mmcm_phase-divide:%d,phase:%d", divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [7:0] divide // Max M divide is 128 in UltrascalePlus
);
reg [5119:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001, // M=1 (not allowed)
40'b00110_00110_1111101000_1111101001_0000000001, // M=2
40'b01000_01000_1111101000_1111101001_0000000001, // M=3
40'b01011_01011_1111101000_1111101001_0000000001, // M=4
40'b01110_01110_1111101000_1111101001_0000000001, // M=5
40'b10001_10001_1111101000_1111101001_0000000001, // M=6
40'b10011_10011_1111101000_1111101001_0000000001, // M=7
40'b10110_10110_1111101000_1111101001_0000000001,
40'b11001_11001_1111101000_1111101001_0000000001,
40'b11100_11100_1111101000_1111101001_0000000001,
40'b11111_11111_1110000100_1111101001_0000000001,
40'b11111_11111_1100111001_1111101001_0000000001,
40'b11111_11111_1011101110_1111101001_0000000001,
40'b11111_11111_1010111100_1111101001_0000000001,
40'b11111_11111_1010001010_1111101001_0000000001,
40'b11111_11111_1001110001_1111101001_0000000001,
40'b11111_11111_1000111111_1111101001_0000000001,
40'b11111_11111_1000100110_1111101001_0000000001,
40'b11111_11111_1000001101_1111101001_0000000001,
40'b11111_11111_0111110100_1111101001_0000000001,
40'b11111_11111_0111011011_1111101001_0000000001,
40'b11111_11111_0111000010_1111101001_0000000001,
40'b11111_11111_0110101001_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0101110111_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001, // M=127
40'b11111_11111_0011111010_1111101001_0000000001 // M=128
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((128-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", mmcm_pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the MMCM
// and outputs the digital filter settings necessary.
function [9:0] mmcm_pll_filter_lookup
(
input [7:0] divide, // input [7:0] divide // Max M divide is 128 in UltraScalePlus
input [8*9:0] BANDWIDTH
);
reg [1279:0] lookup_low;
reg [1279:0] lookup_high;
reg [9:0] lookup_entry;
begin
lookup_low = {
// CP_RES_LFHF
10'b0011_1111_11, // M=1 - not legal
10'b0011_1111_11, // M=2
10'b0011_1101_11, // M=3
10'b0011_0101_11, // M=4
10'b0011_1001_11, // M=5
10'b0011_1110_11, // M=6
10'b0011_1110_11, // M=7
10'b0011_0001_11,
10'b0011_0110_11,
10'b0011_0110_11,
10'b0011_0110_11,
10'b0011_1010_11,
10'b0011_1010_11,
10'b0011_1010_11,
10'b0100_0110_11,
10'b0011_1100_11,
10'b1110_0110_11,
10'b1111_0110_11,
10'b1110_1010_11,
10'b1110_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1101_1100_11,
10'b1101_1100_11,
10'b1101_1100_11,
10'b1110_1100_11,
10'b1110_1100_11,
10'b1110_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11, // M=127
10'b1101_1000_11 // M=128
};
lookup_high = {
// CP_RES_LFHF
10'b0111_1111_11, // M=1 - not legal
10'b0111_1111_11, // M=2
10'b1110_1111_11, // M=3
10'b1111_1111_11, // M=4
10'b1111_1011_11, // M=5
10'b1111_1101_11, // M=6
10'b1111_0011_11, // M=7
10'b1110_0101_11,
10'b1111_1001_11,
10'b1111_1001_11,
10'b1110_1110_11,
10'b1111_1110_11,
10'b1111_0001_11,
10'b1111_0001_11,
10'b1111_0001_11,
10'b1110_0110_11,
10'b1110_0110_11,
10'b1111_0110_11,
10'b1110_1010_11,
10'b1110_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1101_1100_11,
10'b1101_1100_11,
10'b1101_1100_11,
10'b1110_1100_11,
10'b1110_1100_11,
10'b1110_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11 // M=128
};
// Set lookup_entry with the explicit bits from lookup with a part select
if(BANDWIDTH == "LOW") begin
// Low Bandwidth
mmcm_pll_filter_lookup = lookup_low[ ((128-divide)*10) +: 10];
end else begin
// High or optimized bandwidth
mmcm_pll_filter_lookup = lookup_high[ ((128-divide)*10) +: 10];
end
`ifdef DEBUG
$display("filter_lookup: %b", mmcm_pll_filter_lookup);
`endif
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
// for fractional multiply/divide functions.
//
//
function [37:0] mmcm_frac_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle, // Multiplied by 100,000. Not programmable in fractional
input [9:0] frac // Multiplied by 1000
);
//Required for fractional divide calculations
reg [7:0] lt_frac;
reg [7:0] ht_frac;
reg /*[7:0]*/ wf_fall_frac;
reg /*[7:0]*/ wf_rise_frac;
reg [31:0] a;
reg [7:0] pm_rise_frac_filtered ;
reg [7:0] pm_fall_frac_filtered ;
reg [7:0] clkout0_divide_int;
reg [2:0] clkout0_divide_frac;
reg [7:0] even_part_high;
reg [7:0] even_part_low;
reg [7:0] odd;
reg [7:0] odd_and_frac;
reg [7:0] pm_fall;
reg [7:0] pm_rise;
reg [7:0] dt;
reg [7:0] dt_int;
reg [63:0] dt_calc;
reg [7:0] pm_rise_frac;
reg [7:0] pm_fall_frac;
reg [31:0] a_per_in_octets;
reg [31:0] a_phase_in_cycles;
parameter precision = 0.125;
reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
reg [31: 0] phase_pos;
reg [31: 0] phase_vco;
reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
//convert phase to fixed
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// Return value is
// Transfer data
// RESERVED [37:36]
// FRAC_TIME [35:33]
// FRAC_WF_FALL [32]
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
clkout0_divide_frac = frac / 125;
clkout0_divide_int = divide;
even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
even_part_low = even_part_high;
odd = clkout0_divide_int - even_part_high - even_part_low;
odd_and_frac = (8*odd) + clkout0_divide_frac;
lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
pm_rise = 0; //0
wf_fall_frac = ((odd_and_frac >=2) && (odd_and_frac <=9)) || (clkout0_divide_int == 2 && clkout0_divide_frac == 1); //IF(odd_and_frac>=2,IF(odd_and_frac <= 9,1,0),0)
wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8); //IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
//Calculate phase in fractional cycles
a_per_in_octets = (8 * divide) + (frac / 125) ;
a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
pm_rise_frac = (a_phase_in_cycles[7:0] ==8'h00)?8'h00:a_phase_in_cycles[7:0] - {a_phase_in_cycles[7:3],3'b000};
dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
dt = dt_calc[7:0];
pm_rise_frac_filtered = (pm_rise_frac >=8) ? (pm_rise_frac ) - 8: pm_rise_frac ; //((phase_fixed * (divide + frac / 1000)) / 360) - {pm_rise_frac[7:3],3'b000};//$rtoi(clkout0_phase * clkout0_divide / 45);//a;
dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
pm_fall_frac = pm_fall + pm_rise_frac;
pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
mmcm_frac_count_calc[37:0] =
{ 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], 2'b00, dt[5:0],
pm_rise_frac_filtered[2], pm_rise_frac_filtered[1], pm_rise_frac_filtered[0], 1'b0, ht_frac[5:0], lt_frac[5:0]
} ;
`ifdef DEBUG
$display("-%d.%d p%d>> :DADDR_9_15 frac30to28.frac_en.wf_r_frac.dt:%b%d%d_%b:DADDR_7_13 pm_f_frac_filtered_29to27.wf_f_frac_26:%b%d:DADDR_8_14.pm_r_frac_filt_15to13.ht_frac.lt_frac:%b%b%b:", divide, frac, phase, clkout0_divide_frac, 1, wf_rise_frac, dt, pm_fall_frac_filtered, wf_fall_frac, pm_rise_frac_filtered, ht_frac, lt_frac);
`endif
end
endfunction
@@ -0,0 +1,536 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa, Ralf Krueger, updated for Ultrascale+
// Date: 6/15/2015
// Design Name: PLLE4 DRP
// Module Name: plle4_drp_func.h
// Version: 2.0
// Target Devices: UltraScale+ Architecture
// Tool versions: 2017.1
// Description: This header provides the functions necessary to
// calculate the DRP register values for the V6 PLL.
//
// Revision Notes: 8/11 - PLLE3 updated for PLLE3 file 4564419
// Revision Notes: 6/15 - pll_filter_lookup fixed for max M of 19
// M_Rise bits have been removed for PLLE3
// Revision Notes: 2/28/17 - pll_filter_lookup and CPRES updated for
// Ultrascale+ and for max M of 21
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. 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, AND 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 AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2017 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages durring elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development
// only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("pll_phase-divide:%d,phase:%d",
divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [6:0] divide // Max divide is 21
);
reg [839:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001, //1 illegal in Ultrascale+
40'b00110_00110_1111101000_1111101001_0000000001, //2
40'b01000_01000_1111101000_1111101001_0000000001, //3
40'b01011_01011_1111101000_1111101001_0000000001, //4
40'b01110_01110_1111101000_1111101001_0000000001, //5
40'b10001_10001_1111101000_1111101001_0000000001, //6
40'b10011_10011_1111101000_1111101001_0000000001, //7
40'b10110_10110_1111101000_1111101001_0000000001, //8
40'b11001_11001_1111101000_1111101001_0000000001, //9
40'b11100_11100_1111101000_1111101001_0000000001, //10
40'b11111_11111_1110000100_1111101001_0000000001, //11
40'b11111_11111_1100111001_1111101001_0000000001, //12
40'b11111_11111_1011101110_1111101001_0000000001, //13
40'b11111_11111_1010111100_1111101001_0000000001, //14
40'b11111_11111_1010001010_1111101001_0000000001, //15
40'b11111_11111_1001110001_1111101001_0000000001, //16
40'b11111_11111_1000111111_1111101001_0000000001, //17
40'b11111_11111_1000100110_1111101001_0000000001, //18
40'b11111_11111_1000001101_1111101001_0000000001, //19
40'b11111_11111_0111110100_1111101001_0000000001, //20
40'b11111_11111_0111011011_1111101001_0000000001 //21
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((21-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the PLL
// and outputs the digital filter settings necessary. Removing bandwidth setting for PLLE3.
function [9:0] mmcm_pll_filter_lookup
(
input [6:0] divide // Max divide is 21
);
reg [209:0] lookup;
reg [9:0] lookup_entry;
begin
lookup = {
// CP_RES_LFHF
10'b0011_0111_11, //1 not legal in Ultrascale+
10'b0011_0111_11, //2
10'b0011_0011_11, //3
10'b0011_1001_11, //4
10'b0011_0001_11, //5
10'b0100_1110_11, //6
10'b0011_0110_11, //7
10'b0011_1010_11, //8
10'b0111_1001_11, //9
10'b0111_1001_11, //10
10'b0101_0110_11, //11
10'b1100_0101_11, //12
10'b0101_1010_11, //13
10'b0110_0110_11, //14
10'b0110_1010_11, //15
10'b0111_0110_11, //16
10'b1111_0101_11, //17
10'b1100_0110_11, //18
10'b1110_0001_11, //19
10'b1101_0110_11, //20
10'b1111_0001_11 //21
};
mmcm_pll_filter_lookup = lookup [ ((21-divide)*10) +: 10];
`ifdef DEBUG
$display("filter_lookup: %b", pll_filter_lookup);
`endif
end
endfunction
// This function set the CLKOUTPHY divide settings to match
// the desired CLKOUTPHY_MODE setting. To create VCO_X2, then
// the CLKOUTPHY will be set to 2'b00 since the VCO is internally
// doubled and 2'b00 will represent divide by 1. Similarly "VCO"
// will need to divide the doubled clock VCO clock frequency by
// 2 therefore 2'b01 will match a divide by 2.And VCO_HALF will
// need to divide the doubled VCO by 4, therefore 2'b10
function [9:0] mmcm_pll_clkoutphy_calc
(
input [8*9:0] CLKOUTPHY_MODE
);
if(CLKOUTPHY_MODE == "VCO_X2") begin
mmcm_pll_clkoutphy_calc= 2'b00;
end else if(CLKOUTPHY_MODE == "VCO") begin
mmcm_pll_clkoutphy_calc= 2'b01;
end else if(CLKOUTPHY_MODE == "CLKIN") begin
mmcm_pll_clkoutphy_calc= 2'b11;
end else begin // Assume "VCO_HALF"
mmcm_pll_clkoutphy_calc= 2'b10;
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], 3'b000); //Removed PM_Rise bits
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
// for fractional multiply/divide functions.
//
//
function [37:0] mmcm_pll_frac_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle, // Multiplied by 1,000
input [9:0] frac // Multiplied by 1000
);
//Required for fractional divide calculations
reg [7:0] lt_frac;
reg [7:0] ht_frac;
reg /*[7:0]*/ wf_fall_frac;
reg /*[7:0]*/ wf_rise_frac;
reg [31:0] a;
reg [7:0] pm_rise_frac_filtered ;
reg [7:0] pm_fall_frac_filtered ;
reg [7:0] clkout0_divide_int;
reg [2:0] clkout0_divide_frac;
reg [7:0] even_part_high;
reg [7:0] even_part_low;
reg [7:0] odd;
reg [7:0] odd_and_frac;
reg [7:0] pm_fall;
reg [7:0] pm_rise;
reg [7:0] dt;
reg [7:0] dt_int;
reg [63:0] dt_calc;
reg [7:0] pm_rise_frac;
reg [7:0] pm_fall_frac;
reg [31:0] a_per_in_octets;
reg [31:0] a_phase_in_cycles;
parameter precision = 0.125;
reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
reg [31: 0] phase_pos;
reg [31: 0] phase_vco;
reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("pll_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
//convert phase to fixed
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// Return value is
// Transfer data
// RESERVED [37:36]
// FRAC_TIME [35:33]
// FRAC_WF_FALL [32]
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
clkout0_divide_frac = frac / 125;
clkout0_divide_int = divide;
even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
even_part_low = even_part_high;
odd = clkout0_divide_int - even_part_high - even_part_low;
odd_and_frac = (8*odd) + clkout0_divide_frac;
lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
pm_rise = 0; //0
wf_fall_frac = (odd_and_frac >=2) && (odd_and_frac <=9);//IF(odd_and_frac>=2,IF(odd_and_frac <= 9,1,0),0)
wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
//Calculate phase in fractional cycles
a_per_in_octets = (8 * divide) + (frac / 125) ;
a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
pm_rise_frac = (a_phase_in_cycles[7:0] ==8'h00)?8'h00:a_phase_in_cycles[7:0] - {a_phase_in_cycles[7:3],3'b000};
dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
dt = dt_calc[7:0];
pm_rise_frac_filtered = (pm_rise_frac >=8) ? (pm_rise_frac ) - 8: pm_rise_frac ; //((phase_fixed * (divide + frac / 1000)) / 360) - {pm_rise_frac[7:3],3'b000};//$rtoi(clkout0_phase * clkout0_divide / 45);//a;
dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
pm_fall_frac = pm_fall + pm_rise_frac;
pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
mmcm_pll_frac_count_calc[37:0] =
{ 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5:0],
3'b000, 1'b0, ht_frac[5:0], lt_frac[5:0] //Removed PM_Rise bits
} ;
`ifdef DEBUG
$display("-%d.%d p%d>> :DADDR_9_15 frac30to28.frac_en.wf_r_frac.dt:%b%d%d_%b:DADDR_7_13 pm_f_frac_filtered_29to27.wf_f_frac_26:%b%d:DADDR_8_14.pm_r_frac_filt_15to13.ht_frac.lt_frac:%b%b%b:", divide, frac, phase, clkout0_divide_frac, 1, wf_rise_frac, dt, pm_fall_frac_filtered, wf_fall_frac, 3'b000, ht_frac, lt_frac);
`endif
end
endfunction
@@ -0,0 +1,633 @@
// (c) Copyright 2016 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.
//-----------------------------------------------------------------------------
//
// AXI VIP wrapper
//
// Verilog-standard: Verilog 2001
//--------------------------------------------------------------------------
//
// Structure:
// axi_vip
//
//--------------------------------------------------------------------------
`timescale 1ps/1ps
(* DowngradeIPIdentifiedWarnings="yes" *)
module axi_vip_v1_1_5_top #
(
parameter C_AXI_PROTOCOL = 0,
parameter C_AXI_INTERFACE_MODE = 1, //master, slave and bypass
parameter integer C_AXI_ADDR_WIDTH = 32,
parameter integer C_AXI_WDATA_WIDTH = 32,
parameter integer C_AXI_RDATA_WIDTH = 32,
parameter integer C_AXI_WID_WIDTH = 0,
parameter integer C_AXI_RID_WIDTH = 0,
parameter integer C_AXI_AWUSER_WIDTH = 0,
parameter integer C_AXI_ARUSER_WIDTH = 0,
parameter integer C_AXI_WUSER_WIDTH = 0,
parameter integer C_AXI_RUSER_WIDTH = 0,
parameter integer C_AXI_BUSER_WIDTH = 0,
parameter integer C_AXI_SUPPORTS_NARROW = 1,
parameter integer C_AXI_HAS_BURST = 1,
parameter integer C_AXI_HAS_LOCK = 1,
parameter integer C_AXI_HAS_CACHE = 1,
parameter integer C_AXI_HAS_REGION = 1,
parameter integer C_AXI_HAS_PROT = 1,
parameter integer C_AXI_HAS_QOS = 1,
parameter integer C_AXI_HAS_WSTRB = 1,
parameter integer C_AXI_HAS_BRESP = 1,
parameter integer C_AXI_HAS_RRESP = 1,
parameter integer C_AXI_HAS_ARESETN = 1
)
(
//NOTE: C_AXI_INTERFACE_MODE =0 means MASTER MODE, 1 means PASS-THROUGH MODE and 2 means SLAVE MODE
//Please refer xgui tcl and coreinfo.yml
// System Signals
input wire aclk,
input wire aclken,
input wire aresetn,
// Slave Interface Write Address Ports
input wire [C_AXI_WID_WIDTH==0?0:C_AXI_WID_WIDTH-1:0] s_axi_awid,
input wire [C_AXI_ADDR_WIDTH-1:0] s_axi_awaddr,
input wire [((C_AXI_PROTOCOL == 1) ? 4 : 8)-1:0] s_axi_awlen,
input wire [3-1:0] s_axi_awsize,
input wire [2-1:0] s_axi_awburst,
input wire [((C_AXI_PROTOCOL == 1) ? 2 : 1)-1:0] s_axi_awlock,
input wire [4-1:0] s_axi_awcache,
input wire [3-1:0] s_axi_awprot,
input wire [4-1:0] s_axi_awregion,
input wire [4-1:0] s_axi_awqos,
input wire [C_AXI_AWUSER_WIDTH==0?0:C_AXI_AWUSER_WIDTH-1:0] s_axi_awuser,
input wire s_axi_awvalid,
output wire s_axi_awready,
// Slave Interface Write Data Ports
input wire [C_AXI_WID_WIDTH==0?0:C_AXI_WID_WIDTH-1:0] s_axi_wid,
input wire [C_AXI_WDATA_WIDTH-1:0] s_axi_wdata,
input wire [C_AXI_WDATA_WIDTH/8==0 ?0:C_AXI_WDATA_WIDTH/8-1:0] s_axi_wstrb,
input wire s_axi_wlast,
input wire [C_AXI_WUSER_WIDTH==0?0:C_AXI_WUSER_WIDTH-1:0] s_axi_wuser,
input wire s_axi_wvalid,
output wire s_axi_wready,
// Slave Interface Write Response Ports
output wire [C_AXI_WID_WIDTH==0?0:C_AXI_WID_WIDTH-1:0] s_axi_bid,
output wire [2-1:0] s_axi_bresp,
output wire [C_AXI_BUSER_WIDTH==0?0:C_AXI_BUSER_WIDTH-1:0] s_axi_buser,
output wire s_axi_bvalid,
input wire s_axi_bready,
// Slave Interface Read Address Ports
input wire [C_AXI_RID_WIDTH==0?0:C_AXI_RID_WIDTH-1:0] s_axi_arid,
input wire [C_AXI_ADDR_WIDTH-1:0] s_axi_araddr,
input wire [((C_AXI_PROTOCOL == 1) ? 4 : 8)-1:0] s_axi_arlen,
input wire [3-1:0] s_axi_arsize,
input wire [2-1:0] s_axi_arburst,
input wire [((C_AXI_PROTOCOL == 1) ? 2 : 1)-1:0] s_axi_arlock,
input wire [4-1:0] s_axi_arcache,
input wire [3-1:0] s_axi_arprot,
input wire [4-1:0] s_axi_arregion,
input wire [4-1:0] s_axi_arqos,
input wire [C_AXI_ARUSER_WIDTH==0?0:C_AXI_ARUSER_WIDTH-1:0] s_axi_aruser,
input wire s_axi_arvalid,
output wire s_axi_arready,
// Slave Interface Read Data Ports
output wire [C_AXI_RID_WIDTH==0?0:C_AXI_RID_WIDTH-1:0] s_axi_rid,
output wire [C_AXI_RDATA_WIDTH-1:0] s_axi_rdata,
output wire [2-1:0] s_axi_rresp,
output wire s_axi_rlast,
output wire [C_AXI_RUSER_WIDTH==0?0:C_AXI_RUSER_WIDTH-1:0] s_axi_ruser,
output wire s_axi_rvalid,
input wire s_axi_rready,
// Master Interface Write Address Port
output wire [C_AXI_WID_WIDTH==0?0:C_AXI_WID_WIDTH-1:0] m_axi_awid,
output wire [C_AXI_ADDR_WIDTH-1:0] m_axi_awaddr,
output wire [((C_AXI_PROTOCOL == 1) ? 4 : 8)-1:0] m_axi_awlen,
output wire [3-1:0] m_axi_awsize,
output wire [2-1:0] m_axi_awburst,
output wire [((C_AXI_PROTOCOL == 1) ? 2 : 1)-1:0] m_axi_awlock,
output wire [4-1:0] m_axi_awcache,
output wire [3-1:0] m_axi_awprot,
output wire [4-1:0] m_axi_awregion,
output wire [4-1:0] m_axi_awqos,
output wire [C_AXI_AWUSER_WIDTH==0?0:C_AXI_AWUSER_WIDTH-1:0] m_axi_awuser,
output wire m_axi_awvalid,
input wire m_axi_awready,
// Master Interface Write Data Ports
output wire [C_AXI_WID_WIDTH==0?0:C_AXI_WID_WIDTH-1:0] m_axi_wid,
output wire [C_AXI_WDATA_WIDTH-1:0] m_axi_wdata,
output wire [C_AXI_WDATA_WIDTH/8 ==0?0:C_AXI_WDATA_WIDTH/8-1:0] m_axi_wstrb,
output wire m_axi_wlast,
output wire [C_AXI_WUSER_WIDTH==0?0:C_AXI_WUSER_WIDTH-1:0] m_axi_wuser,
output wire m_axi_wvalid,
input wire m_axi_wready,
// Master Interface Write Response Ports
input wire [C_AXI_WID_WIDTH==0?0:C_AXI_WID_WIDTH-1:0] m_axi_bid,
input wire [2-1:0] m_axi_bresp,
input wire [C_AXI_BUSER_WIDTH==0?0:C_AXI_BUSER_WIDTH-1:0] m_axi_buser,
input wire m_axi_bvalid,
output wire m_axi_bready,
// Master Interface Read Address Port
output wire [C_AXI_RID_WIDTH==0?0:C_AXI_RID_WIDTH-1:0] m_axi_arid,
output wire [ C_AXI_ADDR_WIDTH-1:0] m_axi_araddr,
output wire [((C_AXI_PROTOCOL == 1) ? 4 : 8)-1:0] m_axi_arlen,
output wire [3-1:0] m_axi_arsize,
output wire [2-1:0] m_axi_arburst,
output wire [((C_AXI_PROTOCOL == 1) ? 2 : 1)-1:0] m_axi_arlock,
output wire [4-1:0] m_axi_arcache,
output wire [3-1:0] m_axi_arprot,
output wire [4-1:0] m_axi_arregion,
output wire [4-1:0] m_axi_arqos,
output wire [C_AXI_ARUSER_WIDTH==0?0:C_AXI_ARUSER_WIDTH-1:0] m_axi_aruser,
output wire m_axi_arvalid,
input wire m_axi_arready,
// Master Interface Read Data Ports
input wire [C_AXI_RID_WIDTH==0?0:C_AXI_RID_WIDTH-1:0] m_axi_rid,
input wire [C_AXI_RDATA_WIDTH-1:0] m_axi_rdata,
input wire [2-1:0] m_axi_rresp,
input wire m_axi_rlast,
input wire [C_AXI_RUSER_WIDTH==0?0:C_AXI_RUSER_WIDTH-1:0] m_axi_ruser,
input wire m_axi_rvalid,
output wire m_axi_rready
);
/**********************************************************************************************
* NOTE:
* C_AXI_INTERFACE_MODE =0 -- MASTER MODE,
* C_AXI_INTERFACE_MODE =1 -- PASS-THROUGH MODE
* C_AXI_INTERFACE_MODE =2 -- SLAVE MODE
* Please refer xgui tcl and coreinfo.yml
* User can change PASS_THROUGH VIP to run time master mode or run time slave mode during
* the simulation
*********************************************************************************************/
/**********************************************************************************************
* Master_mode means that either the dut is statically being configured to be in master mode
* or it statically being configured to be pass-through mode and switched to be in master mode
* in run time.
* Slave mode means that either the dut is statically being configured to be in slave mode
* or it statically being configured to be pass-through mode and switched to be in slave mode
* in run time.
* Pass-through mode means that either the dut is statically being configured to be in
* pass-through mode or it statically being configured to be pass-through mode and switched
* to be in master/slave mode and then switch back to be in pass-through mode in run time
*********************************************************************************************/
logic runtime_master =0;
logic runtime_slave =0;
wire run_slave_mode;
wire run_master_mode;
wire run_passth_mode;
wire compile_master_mode;
wire compile_slave_mode;
wire master_mode;
wire slave_mode;
assign run_master_mode = (C_AXI_INTERFACE_MODE ==1 && runtime_master ==1 &&runtime_slave ==0);
assign run_slave_mode = C_AXI_INTERFACE_MODE ==1 && runtime_slave ==1 && runtime_master ==0;
assign run_passth_mode = (runtime_slave ==0 && runtime_master ==0);
assign compile_master_mode = (C_AXI_INTERFACE_MODE ==0 || C_AXI_INTERFACE_MODE ==1 )&& run_passth_mode ;
assign compile_slave_mode = (C_AXI_INTERFACE_MODE ==2 || C_AXI_INTERFACE_MODE ==1) && run_passth_mode ;
assign master_mode = compile_master_mode || run_master_mode;
assign slave_mode = compile_slave_mode || run_slave_mode;
// Slave Interface Write Address Ports Internal
assign IF.AWID = slave_mode? s_axi_awid : {C_AXI_WID_WIDTH==0?1:C_AXI_WID_WIDTH{1'bz}};
assign IF.AWADDR = slave_mode? s_axi_awaddr : {C_AXI_ADDR_WIDTH{1'bz}};
assign IF.AWLEN = slave_mode? s_axi_awlen : {((C_AXI_PROTOCOL == 1) ? 4 : 8){1'bz}};
assign IF.AWSIZE = slave_mode? (C_AXI_SUPPORTS_NARROW==0 ? $clog2(C_AXI_WDATA_WIDTH/8): s_axi_awsize): {3{1'bz}};
assign IF.AWBURST = slave_mode? s_axi_awburst : {2{1'bz}};
assign IF.AWLOCK = slave_mode? s_axi_awlock : {((C_AXI_PROTOCOL == 1) ? 2 : 1){1'bz}};
assign IF.AWCACHE = slave_mode? s_axi_awcache : {4{1'bz}};
assign IF.AWPROT = slave_mode? s_axi_awprot : {3{1'bz}};
assign IF.AWREGION = slave_mode? s_axi_awregion : {4{1'bz}};
assign IF.AWQOS = slave_mode? s_axi_awqos : {4{1'bz}};
assign IF.AWUSER = slave_mode? s_axi_awuser : {C_AXI_AWUSER_WIDTH==0?1:C_AXI_AWUSER_WIDTH{1'bz}};
assign IF.AWVALID = slave_mode? s_axi_awvalid : {1'bz};
assign s_axi_awready = slave_mode? IF.AWREADY : {1'b0};
// Slave Interface Write Data Ports
assign IF.WID = slave_mode? s_axi_wid : {C_AXI_WID_WIDTH==0?1:C_AXI_WID_WIDTH{1'bz}};
assign IF.WDATA = slave_mode? s_axi_wdata : {C_AXI_WDATA_WIDTH{1'bz}};
assign IF.WSTRB = slave_mode? s_axi_wstrb : {(C_AXI_WDATA_WIDTH/8){1'bz}};
assign IF.WLAST = slave_mode? s_axi_wlast: {1'bz};
assign IF.WUSER = slave_mode? s_axi_wuser : {C_AXI_WUSER_WIDTH==0?1:C_AXI_WUSER_WIDTH{1'bz}};
assign IF.WVALID = slave_mode? s_axi_wvalid : {1'bz};
assign s_axi_wready = slave_mode? IF.WREADY : {1'b0};
// Slave Interface Write Response Ports
assign s_axi_bid = slave_mode? IF.BID : {C_AXI_WID_WIDTH==0?1:C_AXI_WID_WIDTH{1'b0}};
assign s_axi_bresp = slave_mode? IF.BRESP : {2{1'b0}};
assign s_axi_buser = slave_mode? IF.BUSER : {C_AXI_BUSER_WIDTH==0?1:C_AXI_BUSER_WIDTH{1'b0}};
assign s_axi_bvalid = slave_mode? IF.BVALID : {1{1'b0}};
assign IF.BREADY = slave_mode? s_axi_bready :{1{1'bz}};
// Slave Interface Read Address Ports
assign IF.ARID = slave_mode? s_axi_arid :{C_AXI_RID_WIDTH==0?1:C_AXI_RID_WIDTH{1'bz}};
assign IF.ARADDR = slave_mode? s_axi_araddr : {C_AXI_ADDR_WIDTH{1'bz}} ;
assign IF.ARLEN = slave_mode? s_axi_arlen: {((C_AXI_PROTOCOL == 1) ? 4 : 8){1'bz}};
assign IF.ARSIZE = slave_mode? (C_AXI_SUPPORTS_NARROW==0 ? $clog2(C_AXI_WDATA_WIDTH/8): s_axi_arsize) : {3{1'bz}};
assign IF.ARBURST = slave_mode? s_axi_arburst : {2{1'bz}};
assign IF.ARLOCK = slave_mode? s_axi_arlock : {((C_AXI_PROTOCOL == 1) ? 2 : 1){1'bz}};
assign IF.ARCACHE = slave_mode? s_axi_arcache : {4{1'bz}};
assign IF.ARPROT = slave_mode? s_axi_arprot : {3{1'bz}};
assign IF.ARREGION = slave_mode? s_axi_arregion :{4{1'bz}} ;
assign IF.ARQOS = slave_mode? s_axi_arqos : {4{1'bz}};
assign IF.ARUSER = slave_mode? s_axi_aruser :{C_AXI_ARUSER_WIDTH==0?1:C_AXI_ARUSER_WIDTH{1'bz}};
assign IF.ARVALID = slave_mode? s_axi_arvalid : {1'bz};
assign s_axi_arready = slave_mode? IF.ARREADY : {1'b0};
//Slave Interface Read Data Ports
assign s_axi_rid = slave_mode? IF.RID: {C_AXI_RID_WIDTH==0?1:C_AXI_RID_WIDTH{1'b0}};
assign s_axi_rdata = slave_mode? IF.RDATA : {C_AXI_RDATA_WIDTH{1'b0}};
assign s_axi_rresp = slave_mode? IF.RRESP : {2{1'b0}};
assign s_axi_rlast = slave_mode? IF.RLAST : {{1'b0}};
assign s_axi_ruser = slave_mode? IF.RUSER : {C_AXI_RUSER_WIDTH==0?1:C_AXI_RUSER_WIDTH{1'b0}};
assign s_axi_rvalid = slave_mode? IF.RVALID : {{1'b0}};
assign IF.RREADY = slave_mode? s_axi_rready:{{1'bz}};
// Master Interface Write Address Port
assign m_axi_awid = master_mode? IF.AWID : {C_AXI_WID_WIDTH==0?1:C_AXI_WID_WIDTH{1'b0}};
assign m_axi_awaddr = master_mode? IF.AWADDR : {C_AXI_ADDR_WIDTH{1'b0}};
assign m_axi_awlen = master_mode? IF.AWLEN : {((C_AXI_PROTOCOL == 1) ? 4 : 8){1'b0}};
assign m_axi_awsize = master_mode? IF.AWSIZE : {3{1'b0}};
assign m_axi_awburst = master_mode? IF.AWBURST : {2{1'b0}};
assign m_axi_awlock = master_mode? IF.AWLOCK : {((C_AXI_PROTOCOL == 1) ? 2 : 1){1'b0}};
assign m_axi_awcache = master_mode? IF.AWCACHE : {4{1'b0}};
assign m_axi_awprot = master_mode? IF.AWPROT : {3{1'b0}};
assign m_axi_awregion = master_mode? IF.AWREGION : {4{1'b0}};
assign m_axi_awqos = master_mode? IF.AWQOS : {4{1'b0}};
assign m_axi_awuser = master_mode? IF.AWUSER : {C_AXI_AWUSER_WIDTH==0?1:C_AXI_AWUSER_WIDTH{1'b0}};
assign m_axi_awvalid = master_mode? IF.AWVALID :{1'b0};
assign IF.AWREADY = master_mode? m_axi_awready :{1'bz};
// Master Interface Write Data Ports Internal
assign m_axi_wid = master_mode? IF.WID : {C_AXI_WID_WIDTH==0?1:C_AXI_WID_WIDTH{1'b0}};
assign m_axi_wdata = master_mode? IF.WDATA : {C_AXI_WDATA_WIDTH{1'b0}};
assign m_axi_wstrb = master_mode? IF.WSTRB : {(C_AXI_WDATA_WIDTH/8){1'b0}};
assign m_axi_wlast = master_mode? IF.WLAST : {1'b0};
assign m_axi_wuser = master_mode? IF.WUSER : {C_AXI_WUSER_WIDTH==0?1:C_AXI_WUSER_WIDTH{1'b0}};
assign m_axi_wvalid = master_mode? IF.WVALID : {1'b0};
assign IF.WREADY = master_mode? m_axi_wready : {1'bz};
// Master Interface Write Response Ports Internal
assign IF.BID = master_mode? m_axi_bid : {C_AXI_WID_WIDTH==0?1:C_AXI_WID_WIDTH{1'bz}};
assign IF.BRESP = master_mode? m_axi_bresp : {2{1'bz}};
assign IF.BUSER = master_mode? m_axi_buser : {C_AXI_BUSER_WIDTH==0?1:C_AXI_BUSER_WIDTH{1'bz}};
assign IF.BVALID = master_mode? m_axi_bvalid : 1'bz;
assign m_axi_bready = master_mode? IF.BREADY : 1'b0;
// Master Interface Read Address Port Internal
assign m_axi_arid = master_mode? IF.ARID : {C_AXI_RID_WIDTH==0?1:C_AXI_RID_WIDTH{1'b0}};
assign m_axi_araddr = master_mode? IF.ARADDR : {C_AXI_ADDR_WIDTH{1'b0}};
assign m_axi_arlen = master_mode? IF.ARLEN : {((C_AXI_PROTOCOL == 1) ? 4 : 8){1'b0}};
assign m_axi_arsize = master_mode? IF.ARSIZE : {3{1'b0}};
assign m_axi_arburst = master_mode? IF.ARBURST : {2{1'b0}};
assign m_axi_arlock = master_mode? IF.ARLOCK : {((C_AXI_PROTOCOL == 1) ? 2 : 1){1'b0}};
assign m_axi_arcache = master_mode?IF.ARCACHE : {4{1'b0}};
assign m_axi_arprot = master_mode? IF.ARPROT : {3{1'b0}};
assign m_axi_arregion = master_mode? IF.ARREGION : {4{1'b0}};
assign m_axi_arqos = master_mode? IF.ARQOS : {4{1'b0}};
assign m_axi_aruser = master_mode? IF.ARUSER : {C_AXI_ARUSER_WIDTH==0?1:C_AXI_ARUSER_WIDTH{1'b0}};
assign m_axi_arvalid = master_mode? IF.ARVALID :{1'b0};
assign IF.ARREADY = master_mode? m_axi_arready : {1{1'bz}};
// Master Interface Read Data Ports Internal
assign IF.RID = master_mode? m_axi_rid : {C_AXI_RID_WIDTH==0?1:C_AXI_RID_WIDTH{1'bz}};
assign IF.RDATA = master_mode? m_axi_rdata : {C_AXI_RDATA_WIDTH{1'bz}};
assign IF.RRESP = master_mode? m_axi_rresp : {2{1'bz}};
assign IF.RLAST = master_mode? m_axi_rlast : {1{1'bz}};
assign IF.RUSER = master_mode? m_axi_ruser : {C_AXI_RUSER_WIDTH==0?1:C_AXI_RUSER_WIDTH{1'bz}};
assign IF.RVALID = master_mode? m_axi_rvalid : {1{1'bz}};
assign m_axi_rready = master_mode? IF.RREADY : {1{1'b0}};
axi_vip_if #(
.C_AXI_PROTOCOL(C_AXI_PROTOCOL),
.C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH ),
.C_AXI_WDATA_WIDTH(C_AXI_WDATA_WIDTH ),
.C_AXI_RDATA_WIDTH(C_AXI_RDATA_WIDTH ),
.C_AXI_WID_WIDTH(C_AXI_WID_WIDTH ),
.C_AXI_RID_WIDTH(C_AXI_RID_WIDTH ),
.C_AXI_AWUSER_WIDTH(C_AXI_AWUSER_WIDTH ),
.C_AXI_WUSER_WIDTH(C_AXI_WUSER_WIDTH ),
.C_AXI_BUSER_WIDTH(C_AXI_BUSER_WIDTH ),
.C_AXI_ARUSER_WIDTH(C_AXI_ARUSER_WIDTH ),
.C_AXI_RUSER_WIDTH(C_AXI_RUSER_WIDTH ),
.C_AXI_SUPPORTS_NARROW(C_AXI_SUPPORTS_NARROW),
.C_AXI_HAS_BURST(C_AXI_HAS_BURST),
.C_AXI_HAS_LOCK(C_AXI_HAS_LOCK),
.C_AXI_HAS_CACHE(C_AXI_HAS_CACHE),
.C_AXI_HAS_REGION(C_AXI_HAS_REGION),
.C_AXI_HAS_PROT(C_AXI_HAS_PROT),
.C_AXI_HAS_QOS(C_AXI_HAS_QOS),
.C_AXI_HAS_WSTRB(C_AXI_HAS_WSTRB),
.C_AXI_HAS_BRESP(C_AXI_HAS_BRESP),
.C_AXI_HAS_RRESP(C_AXI_HAS_RRESP),
.C_AXI_HAS_ARESETN(C_AXI_HAS_ARESETN)
) IF (
.ACLK(aclk),
.ARESET_N(aresetn),
.ACLKEN(aclken)
);
//synthesis translate_off
initial begin
$display("XilinxAXIVIP: Found at Path: %m");
end
//set IF mode to be in the correct mode according to C_AXI_INTERFACE_MODE,Default is monitor mode
generate
initial begin
if(C_AXI_INTERFACE_MODE ==0) begin
IF.set_intf_master;
end else if(C_AXI_INTERFACE_MODE ==2) begin
IF.set_intf_slave;
end else if(C_AXI_INTERFACE_MODE ==1) begin
$display("This AXI VIP is in passthrough mode");
end else begin
$fatal(0,"This AXI VIP's mode is out of range");
end
end
endgenerate
/*
Function: set_passthrough_mode
Sets AXI VIP passthrough into run time passthrough mode
*/
function void set_passthrough_mode();
if (C_AXI_INTERFACE_MODE == 1) begin
runtime_master = 0;
runtime_slave = 0;
IF.set_intf_monitor();
end else begin
$fatal(0,"XilinxAXIVIP: VIP was not initially configured as Pass-through. Cannot change mode.Delete non-Passthrough VIP's API call of set_passthrough_mode in the testbench. Refer PG267 section about Useful Coding Guidelines and Example for how to use master/slave/passthrough VIP");
end
endfunction: set_passthrough_mode
/*
Function: set_master_mode
Sets AXI VIP passthrough into run time master mode
*/
function void set_master_mode();
if (C_AXI_INTERFACE_MODE == 1) begin
runtime_master = 1;
runtime_slave = 0;
IF.set_intf_master();
end else begin
$fatal(0,"XilinxAXIVIP: VIP was not initially configured as Pass-through. Cannot change mode.Delete non-Passthrough VIP's API call of set_master_mode in the testbench .Refer PG267 section about Useful Coding Guidelines and Example for how to use master/slave/passthrough VIP ");
end
endfunction : set_master_mode
/*
Function: set_slave_mode
Sets AXI VIP passthrough into run time slave mode
*/
function void set_slave_mode();
if (C_AXI_INTERFACE_MODE == 1) begin
runtime_master = 0;
runtime_slave = 1;
IF.set_intf_slave();
end else begin
$fatal(0,"XilinxAXIVIP: VIP was not initially configured as Pass-through. Cannot change mode.Delete non-Passthrough VIP's API call of set_slave_mode in the testbench.Refer PG267 section about Useful Coding Guidelines and Example for how to use master/slave/passthrough VIP");
end
endfunction : set_slave_mode
/*
Function: set_xilinx_slave_ready_check
Sets xilinx_slave_ready_check_enable of IF to be 1
*/
function void set_xilinx_slave_ready_check();
IF.xilinx_slave_ready_check_enable = 1;
endfunction
/*
Function: clr_xilinx_slave_ready_check
Sets xilinx_slave_ready_check_enable of IF to be 0
*/
function void clr_xilinx_slave_ready_check();
IF.xilinx_slave_ready_check_enable = 0;
endfunction
/*
Function: set_max_aw_wait_cycles (not available in VIVADO Simulator)
Sets max_aw_wait_cycles of PC(ARM Protocol Checker)
*/
function void set_max_aw_wait_cycles(input integer unsigned new_num);
IF.PC.max_aw_wait_cycles = new_num;
endfunction : set_max_aw_wait_cycles
/*
Function: set_max_ar_wait_cycles (not available in VIVADO Simulator)
Sets max_ar_wait_cycles of PC(ARM Protocol Checker)
*/
function void set_max_ar_wait_cycles(input integer unsigned new_num);
IF.PC.max_ar_wait_cycles = new_num;
endfunction : set_max_ar_wait_cycles
/*
Function: set_max_r_wait_cycles (not available in VIVADO Simulator)
Sets max_r_wait_cycles of PC(ARM Protocol Checker)
*/
function void set_max_r_wait_cycles(input integer unsigned new_num);
IF.PC.max_r_wait_cycles = new_num;
endfunction : set_max_r_wait_cycles
/*
Function: set_max_b_wait_cycles (not available in VIVADO Simulator)
Sets max_b_wait_cycles of PC(ARM Protocol Checker)
*/
function void set_max_b_wait_cycles(input integer unsigned new_num);
IF.PC.max_b_wait_cycles = new_num;
endfunction : set_max_b_wait_cycles
/*
Function: set_max_w_wait_cycles (not available in VIVADO Simulator)
Sets max_w_wait_cycles of PC(ARM Protocol Checker)
*/
function void set_max_w_wait_cycles(input integer unsigned new_num);
IF.PC.max_w_wait_cycles = new_num;
endfunction : set_max_w_wait_cycles
/*
Function: set_max_wlast_wait_cycles (not available in VIVADO Simulator)
Sets max_wlast_to_awvalid_wait_cycles of PC(ARM Protocol Checker)
*/
function void set_max_wlast_wait_cycles(input integer unsigned new_num);
IF.PC.max_wlast_to_awvalid_wait_cycles = new_num;
endfunction : set_max_wlast_wait_cycles
/*
Function: set_max_rtransfer_wait_cycles (not available in VIVADO Simulator)
Sets max_rtransfer_wait_cycles of PC(ARM Protocol Checker)
*/
function void set_max_rtransfers_wait_cycles(input integer unsigned new_num);
IF.PC.max_rtransfers_wait_cycles = new_num;
endfunction : set_max_rtransfers_wait_cycles
/*
Function: set_max_wtransfer_wait_cycles (not available in VIVADO Simulator)
Sets max_wtransfer_wait_cycles of PC(ARM Protocol Checker)
*/
function void set_max_wtransfers_wait_cycles(input integer unsigned new_num);
IF.PC.max_wtransfers_wait_cycles = new_num;
endfunction : set_max_wtransfers_wait_cycles
/*
Function: set_max_wlcmd_wait_cycles (not available in VIVADO Simulator)
Sets max_wlcmd_wait_cycles of PC(ARM Protocol Checker)
*/
function void set_max_wlcmd_wait_cycles(input integer unsigned new_num);
IF.PC.max_wlcmd_wait_cycles = new_num;
endfunction : set_max_wlcmd_wait_cycles
/*
Function: get_max_aw_wait_cycles (not available in VIVADO Simulator)
Returns max_aw_wait_cycles of PC(ARM Protocol Checker)
*/
function integer unsigned get_max_aw_wait_cycles();
return(IF.PC.max_aw_wait_cycles);
endfunction : get_max_aw_wait_cycles
/*
Function: get_max_ar_wait_cycles (not available in VIVADO Simulator)
Returns max_ar_wait_cycles of PC(ARM Protocol Checker)
*/
function integer unsigned get_max_ar_wait_cycles();
return(IF.PC.max_ar_wait_cycles);
endfunction : get_max_ar_wait_cycles
/*
Function: get_max_r_wait_cycles (not available in VIVADO Simulator)
Returns max_r_wait_cycles of PC(ARM Protocol Checker)
*/
function integer unsigned get_max_r_wait_cycles();
return(IF.PC.max_r_wait_cycles);
endfunction : get_max_r_wait_cycles
/*
Function: get_max_b_wait_cycles (not available in VIVADO Simulator)
Returns max_b_wait_cycles of PC(ARM Protocol Checker)
*/
function integer unsigned get_max_b_wait_cycles();
return(IF.PC.max_b_wait_cycles);
endfunction : get_max_b_wait_cycles
/*
Function: get_max_w_wait_cycles (not available in VIVADO Simulator)
Returns max_w_wait_cycles of PC(ARM Protocol Checker)
*/
function integer unsigned get_max_w_wait_cycles();
return(IF.PC.max_w_wait_cycles);
endfunction :get_max_w_wait_cycles
/*
Function: get_max_wlast_wait_cycles (not available in VIVADO Simulator)
Returns max_wlast_to_awvalid_wait_cycles of PC(ARM Protocol Checker)
*/
function integer unsigned get_max_wlast_wait_cycles();
return(IF.PC.max_wlast_to_awvalid_wait_cycles);
endfunction :get_max_wlast_wait_cycles
/*
Function: get_max_rtransfer_wait_cycles (not available in VIVADO Simulator)
Returns max_rtransfer_wait_cycles of PC(ARM Protocol Checker)
*/
function integer unsigned get_max_rtransfers_wait_cycles();
return(IF.PC.max_rtransfers_wait_cycles);
endfunction :get_max_rtransfers_wait_cycles
/*
Function: get_max_wtransfer_wait_cycles (not available in VIVADO Simulator)
Returns max_wtransfer_wait_cycles of PC(ARM Protocol Checker)
*/
function integer unsigned get_max_wtransfers_wait_cycles();
return(IF.PC.max_wtransfers_wait_cycles);
endfunction :get_max_wtransfers_wait_cycles
/*
Function: get_max_wlcmd_wait_cycles (not available in VIVADO Simulator)
Returns max_wlcmd_wait_cycles of PC(ARM Protocol Checker)
*/
function integer unsigned get_max_wlcmd_wait_cycles();
return(IF.PC.max_wlcmd_wait_cycles);
endfunction :get_max_wlcmd_wait_cycles
/*
Function: set_fatal_to_warnings (not available in VIVADO Simulator)
Sets fatal_to_warnings of PC(ARM Protocol Checker) to be 1
*/
function void set_fatal_to_warnings();
IF.PC.fatal_to_warnings = 1;
endfunction : set_fatal_to_warnings
/*
Function: clr_fatal_to_warnings (not available in VIVADO Simulator)
Sets fatal_to_warnings of PC(ARM Protocol Checker) to be 0
*/
function void clr_fatal_to_warnings();
IF.PC.fatal_to_warnings = 0;
endfunction : clr_fatal_to_warnings
//synthesis translate_on
endmodule // axi_vip_v1_1_5_top
@@ -0,0 +1,138 @@
// (c) Copyright 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.
//-----------------------------------------------------------------------------
//
// Generic Functions used by AXI Infrastructure Modules
//
// Verilog-standard: Verilog 2001
//--------------------------------------------------------------------------
// Global Parameters:
//
// Functions:
//
// Tasks:
//--------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
// BEGIN Global Parameters
///////////////////////////////////////////////////////////////////////////////
localparam G_AXI_AWADDR_INDEX = 0;
localparam G_AXI_AWADDR_WIDTH = C_AXI_ADDR_WIDTH;
localparam G_AXI_AWPROT_INDEX = G_AXI_AWADDR_INDEX + G_AXI_AWADDR_WIDTH;
localparam G_AXI_AWPROT_WIDTH = 3;
localparam G_AXI_AWSIZE_INDEX = G_AXI_AWPROT_INDEX + G_AXI_AWPROT_WIDTH;
localparam G_AXI_AWSIZE_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : 3;
localparam G_AXI_AWBURST_INDEX = G_AXI_AWSIZE_INDEX + G_AXI_AWSIZE_WIDTH;
localparam G_AXI_AWBURST_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : 2;
localparam G_AXI_AWCACHE_INDEX = G_AXI_AWBURST_INDEX + G_AXI_AWBURST_WIDTH;
localparam G_AXI_AWCACHE_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : 4;
localparam G_AXI_AWLEN_INDEX = G_AXI_AWCACHE_INDEX + G_AXI_AWCACHE_WIDTH;
localparam G_AXI_AWLEN_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_PROTOCOL == 1) ? 4 : 8;
localparam G_AXI_AWLOCK_INDEX = G_AXI_AWLEN_INDEX + G_AXI_AWLEN_WIDTH;
localparam G_AXI_AWLOCK_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_PROTOCOL == 1) ? 2 : 1;
localparam G_AXI_AWID_INDEX = G_AXI_AWLOCK_INDEX + G_AXI_AWLOCK_WIDTH;
localparam G_AXI_AWID_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : C_AXI_ID_WIDTH;
localparam G_AXI_AWQOS_INDEX = G_AXI_AWID_INDEX + G_AXI_AWID_WIDTH;
localparam G_AXI_AWQOS_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : 4;
localparam G_AXI_AWREGION_INDEX = G_AXI_AWQOS_INDEX + G_AXI_AWQOS_WIDTH;
localparam G_AXI_AWREGION_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_SUPPORTS_REGION_SIGNALS == 0) ? 0 : 4;
localparam G_AXI_AWUSER_INDEX = G_AXI_AWREGION_INDEX + G_AXI_AWREGION_WIDTH;
localparam G_AXI_AWUSER_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_SUPPORTS_USER_SIGNALS == 0) ? 0 : C_AXI_AWUSER_WIDTH;
localparam G_AXI_AWPAYLOAD_WIDTH = G_AXI_AWUSER_INDEX + G_AXI_AWUSER_WIDTH;
localparam G_AXI_ARADDR_INDEX = 0;
localparam G_AXI_ARADDR_WIDTH = C_AXI_ADDR_WIDTH;
localparam G_AXI_ARPROT_INDEX = G_AXI_ARADDR_INDEX + G_AXI_ARADDR_WIDTH;
localparam G_AXI_ARPROT_WIDTH = 3;
localparam G_AXI_ARSIZE_INDEX = G_AXI_ARPROT_INDEX + G_AXI_ARPROT_WIDTH;
localparam G_AXI_ARSIZE_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : 3;
localparam G_AXI_ARBURST_INDEX = G_AXI_ARSIZE_INDEX + G_AXI_ARSIZE_WIDTH;
localparam G_AXI_ARBURST_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : 2;
localparam G_AXI_ARCACHE_INDEX = G_AXI_ARBURST_INDEX + G_AXI_ARBURST_WIDTH;
localparam G_AXI_ARCACHE_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : 4;
localparam G_AXI_ARLEN_INDEX = G_AXI_ARCACHE_INDEX + G_AXI_ARCACHE_WIDTH;
localparam G_AXI_ARLEN_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_PROTOCOL == 1) ? 4 : 8;
localparam G_AXI_ARLOCK_INDEX = G_AXI_ARLEN_INDEX + G_AXI_ARLEN_WIDTH;
localparam G_AXI_ARLOCK_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_PROTOCOL == 1) ? 2 : 1;
localparam G_AXI_ARID_INDEX = G_AXI_ARLOCK_INDEX + G_AXI_ARLOCK_WIDTH;
localparam G_AXI_ARID_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : C_AXI_ID_WIDTH;
localparam G_AXI_ARQOS_INDEX = G_AXI_ARID_INDEX + G_AXI_ARID_WIDTH;
localparam G_AXI_ARQOS_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : 4;
localparam G_AXI_ARREGION_INDEX = G_AXI_ARQOS_INDEX + G_AXI_ARQOS_WIDTH;
localparam G_AXI_ARREGION_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_SUPPORTS_REGION_SIGNALS == 0) ? 0 : 4;
localparam G_AXI_ARUSER_INDEX = G_AXI_ARREGION_INDEX + G_AXI_ARREGION_WIDTH;
localparam G_AXI_ARUSER_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_SUPPORTS_USER_SIGNALS == 0) ? 0 : C_AXI_ARUSER_WIDTH;
localparam G_AXI_ARPAYLOAD_WIDTH = G_AXI_ARUSER_INDEX + G_AXI_ARUSER_WIDTH;
// Write channel widths
localparam G_AXI_WDATA_INDEX = 0;
localparam G_AXI_WDATA_WIDTH = C_AXI_DATA_WIDTH;
localparam G_AXI_WSTRB_INDEX = G_AXI_WDATA_INDEX + G_AXI_WDATA_WIDTH;
localparam G_AXI_WSTRB_WIDTH = C_AXI_DATA_WIDTH / 8;
localparam G_AXI_WLAST_INDEX = G_AXI_WSTRB_INDEX + G_AXI_WSTRB_WIDTH;
localparam G_AXI_WLAST_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : 1;
localparam G_AXI_WID_INDEX = G_AXI_WLAST_INDEX + G_AXI_WLAST_WIDTH;
localparam G_AXI_WID_WIDTH = (C_AXI_PROTOCOL != 1) ? 0 : C_AXI_ID_WIDTH;
localparam G_AXI_WUSER_INDEX = G_AXI_WID_INDEX + G_AXI_WID_WIDTH;
localparam G_AXI_WUSER_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_SUPPORTS_USER_SIGNALS == 0) ? 0 : C_AXI_WUSER_WIDTH;
localparam G_AXI_WPAYLOAD_WIDTH = G_AXI_WUSER_INDEX + G_AXI_WUSER_WIDTH;
// Write Response channel Widths
localparam G_AXI_BRESP_INDEX = 0;
localparam G_AXI_BRESP_WIDTH = 2;
localparam G_AXI_BID_INDEX = G_AXI_BRESP_INDEX + G_AXI_BRESP_WIDTH;
localparam G_AXI_BID_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : C_AXI_ID_WIDTH;
localparam G_AXI_BUSER_INDEX = G_AXI_BID_INDEX + G_AXI_BID_WIDTH;
localparam G_AXI_BUSER_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_SUPPORTS_USER_SIGNALS == 0) ? 0 : C_AXI_BUSER_WIDTH;
localparam G_AXI_BPAYLOAD_WIDTH = G_AXI_BUSER_INDEX + G_AXI_BUSER_WIDTH;
// Read channel widths
localparam G_AXI_RDATA_INDEX = 0;
localparam G_AXI_RDATA_WIDTH = C_AXI_DATA_WIDTH;
localparam G_AXI_RRESP_INDEX = G_AXI_RDATA_INDEX + G_AXI_RDATA_WIDTH;
localparam G_AXI_RRESP_WIDTH = 2;
localparam G_AXI_RLAST_INDEX = G_AXI_RRESP_INDEX + G_AXI_RRESP_WIDTH;
localparam G_AXI_RLAST_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : 1;
localparam G_AXI_RID_INDEX = G_AXI_RLAST_INDEX + G_AXI_RLAST_WIDTH;
localparam G_AXI_RID_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : C_AXI_ID_WIDTH;
localparam G_AXI_RUSER_INDEX = G_AXI_RID_INDEX + G_AXI_RID_WIDTH;
localparam G_AXI_RUSER_WIDTH = (C_AXI_PROTOCOL == 2) ? 0 : (C_AXI_SUPPORTS_USER_SIGNALS == 0) ? 0 : C_AXI_RUSER_WIDTH;
localparam G_AXI_RPAYLOAD_WIDTH = G_AXI_RUSER_INDEX + G_AXI_RUSER_WIDTH;
@@ -0,0 +1,670 @@
// (c) Copyright 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.
//-----------------------------------------------------------------------------
//
// axis to vector
// A generic module to merge all axi signals into one signal called payload.
// This is strictly wires, so no clk, reset, aclken, valid/ready are required.
//
// Verilog-standard: Verilog 2001
//--------------------------------------------------------------------------
//
`timescale 1ps/1ps
`default_nettype none
(* DowngradeIPIdentifiedWarnings="yes" *)
module axi_infrastructure_v1_1_0_axi2vector #
(
///////////////////////////////////////////////////////////////////////////////
// Parameter Definitions
///////////////////////////////////////////////////////////////////////////////
parameter integer C_AXI_PROTOCOL = 0,
parameter integer C_AXI_ID_WIDTH = 4,
parameter integer C_AXI_ADDR_WIDTH = 32,
parameter integer C_AXI_DATA_WIDTH = 32,
parameter integer C_AXI_SUPPORTS_USER_SIGNALS = 0,
parameter integer C_AXI_SUPPORTS_REGION_SIGNALS = 0,
parameter integer C_AXI_AWUSER_WIDTH = 1,
parameter integer C_AXI_WUSER_WIDTH = 1,
parameter integer C_AXI_BUSER_WIDTH = 1,
parameter integer C_AXI_ARUSER_WIDTH = 1,
parameter integer C_AXI_RUSER_WIDTH = 1,
parameter integer C_AWPAYLOAD_WIDTH = 61,
parameter integer C_WPAYLOAD_WIDTH = 73,
parameter integer C_BPAYLOAD_WIDTH = 6,
parameter integer C_ARPAYLOAD_WIDTH = 61,
parameter integer C_RPAYLOAD_WIDTH = 69
)
(
///////////////////////////////////////////////////////////////////////////////
// Port Declarations
///////////////////////////////////////////////////////////////////////////////
// Slave Interface Write Address Ports
input wire [C_AXI_ID_WIDTH-1:0] s_axi_awid,
input wire [C_AXI_ADDR_WIDTH-1:0] s_axi_awaddr,
input wire [((C_AXI_PROTOCOL == 1) ? 4 : 8)-1:0] s_axi_awlen,
input wire [3-1:0] s_axi_awsize,
input wire [2-1:0] s_axi_awburst,
input wire [((C_AXI_PROTOCOL == 1) ? 2 : 1)-1:0] s_axi_awlock,
input wire [4-1:0] s_axi_awcache,
input wire [3-1:0] s_axi_awprot,
input wire [4-1:0] s_axi_awregion,
input wire [4-1:0] s_axi_awqos,
input wire [C_AXI_AWUSER_WIDTH-1:0] s_axi_awuser,
// Slave Interface Write Data Ports
input wire [C_AXI_ID_WIDTH-1:0] s_axi_wid,
input wire [C_AXI_DATA_WIDTH-1:0] s_axi_wdata,
input wire [C_AXI_DATA_WIDTH/8-1:0] s_axi_wstrb,
input wire s_axi_wlast,
input wire [C_AXI_WUSER_WIDTH-1:0] s_axi_wuser,
// Slave Interface Write Response Ports
output wire [C_AXI_ID_WIDTH-1:0] s_axi_bid,
output wire [2-1:0] s_axi_bresp,
output wire [C_AXI_BUSER_WIDTH-1:0] s_axi_buser,
// Slave Interface Read Address Ports
input wire [C_AXI_ID_WIDTH-1:0] s_axi_arid,
input wire [C_AXI_ADDR_WIDTH-1:0] s_axi_araddr,
input wire [((C_AXI_PROTOCOL == 1) ? 4 : 8)-1:0] s_axi_arlen,
input wire [3-1:0] s_axi_arsize,
input wire [2-1:0] s_axi_arburst,
input wire [((C_AXI_PROTOCOL == 1) ? 2 : 1)-1:0] s_axi_arlock,
input wire [4-1:0] s_axi_arcache,
input wire [3-1:0] s_axi_arprot,
input wire [4-1:0] s_axi_arregion,
input wire [4-1:0] s_axi_arqos,
input wire [C_AXI_ARUSER_WIDTH-1:0] s_axi_aruser,
// Slave Interface Read Data Ports
output wire [C_AXI_ID_WIDTH-1:0] s_axi_rid,
output wire [C_AXI_DATA_WIDTH-1:0] s_axi_rdata,
output wire [2-1:0] s_axi_rresp,
output wire s_axi_rlast,
output wire [C_AXI_RUSER_WIDTH-1:0] s_axi_ruser,
// payloads
output wire [C_AWPAYLOAD_WIDTH-1:0] s_awpayload,
output wire [C_WPAYLOAD_WIDTH-1:0] s_wpayload,
input wire [C_BPAYLOAD_WIDTH-1:0] s_bpayload,
output wire [C_ARPAYLOAD_WIDTH-1:0] s_arpayload,
input wire [C_RPAYLOAD_WIDTH-1:0] s_rpayload
);
////////////////////////////////////////////////////////////////////////////////
// Functions
////////////////////////////////////////////////////////////////////////////////
`include "axi_infrastructure_v1_1_0.vh"
////////////////////////////////////////////////////////////////////////////////
// Local parameters
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Wires/Reg declarations
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// BEGIN RTL
////////////////////////////////////////////////////////////////////////////////
// AXI4, AXI4LITE, AXI3 packing
assign s_awpayload[G_AXI_AWADDR_INDEX+:G_AXI_AWADDR_WIDTH] = s_axi_awaddr;
assign s_awpayload[G_AXI_AWPROT_INDEX+:G_AXI_AWPROT_WIDTH] = s_axi_awprot;
assign s_wpayload[G_AXI_WDATA_INDEX+:G_AXI_WDATA_WIDTH] = s_axi_wdata;
assign s_wpayload[G_AXI_WSTRB_INDEX+:G_AXI_WSTRB_WIDTH] = s_axi_wstrb;
assign s_axi_bresp = s_bpayload[G_AXI_BRESP_INDEX+:G_AXI_BRESP_WIDTH];
assign s_arpayload[G_AXI_ARADDR_INDEX+:G_AXI_ARADDR_WIDTH] = s_axi_araddr;
assign s_arpayload[G_AXI_ARPROT_INDEX+:G_AXI_ARPROT_WIDTH] = s_axi_arprot;
assign s_axi_rdata = s_rpayload[G_AXI_RDATA_INDEX+:G_AXI_RDATA_WIDTH];
assign s_axi_rresp = s_rpayload[G_AXI_RRESP_INDEX+:G_AXI_RRESP_WIDTH];
generate
if (C_AXI_PROTOCOL == 0 || C_AXI_PROTOCOL == 1) begin : gen_axi4_or_axi3_packing
assign s_awpayload[G_AXI_AWSIZE_INDEX+:G_AXI_AWSIZE_WIDTH] = s_axi_awsize;
assign s_awpayload[G_AXI_AWBURST_INDEX+:G_AXI_AWBURST_WIDTH] = s_axi_awburst;
assign s_awpayload[G_AXI_AWCACHE_INDEX+:G_AXI_AWCACHE_WIDTH] = s_axi_awcache;
assign s_awpayload[G_AXI_AWLEN_INDEX+:G_AXI_AWLEN_WIDTH] = s_axi_awlen;
assign s_awpayload[G_AXI_AWLOCK_INDEX+:G_AXI_AWLOCK_WIDTH] = s_axi_awlock;
assign s_awpayload[G_AXI_AWID_INDEX+:G_AXI_AWID_WIDTH] = s_axi_awid;
assign s_awpayload[G_AXI_AWQOS_INDEX+:G_AXI_AWQOS_WIDTH] = s_axi_awqos;
assign s_wpayload[G_AXI_WLAST_INDEX+:G_AXI_WLAST_WIDTH] = s_axi_wlast;
if (C_AXI_PROTOCOL == 1) begin : gen_axi3_wid_packing
assign s_wpayload[G_AXI_WID_INDEX+:G_AXI_WID_WIDTH] = s_axi_wid;
end
else begin : gen_no_axi3_wid_packing
end
assign s_axi_bid = s_bpayload[G_AXI_BID_INDEX+:G_AXI_BID_WIDTH];
assign s_arpayload[G_AXI_ARSIZE_INDEX+:G_AXI_ARSIZE_WIDTH] = s_axi_arsize;
assign s_arpayload[G_AXI_ARBURST_INDEX+:G_AXI_ARBURST_WIDTH] = s_axi_arburst;
assign s_arpayload[G_AXI_ARCACHE_INDEX+:G_AXI_ARCACHE_WIDTH] = s_axi_arcache;
assign s_arpayload[G_AXI_ARLEN_INDEX+:G_AXI_ARLEN_WIDTH] = s_axi_arlen;
assign s_arpayload[G_AXI_ARLOCK_INDEX+:G_AXI_ARLOCK_WIDTH] = s_axi_arlock;
assign s_arpayload[G_AXI_ARID_INDEX+:G_AXI_ARID_WIDTH] = s_axi_arid;
assign s_arpayload[G_AXI_ARQOS_INDEX+:G_AXI_ARQOS_WIDTH] = s_axi_arqos;
assign s_axi_rlast = s_rpayload[G_AXI_RLAST_INDEX+:G_AXI_RLAST_WIDTH];
assign s_axi_rid = s_rpayload[G_AXI_RID_INDEX+:G_AXI_RID_WIDTH];
if (C_AXI_SUPPORTS_REGION_SIGNALS == 1 && G_AXI_AWREGION_WIDTH > 0) begin : gen_region_signals
assign s_awpayload[G_AXI_AWREGION_INDEX+:G_AXI_AWREGION_WIDTH] = s_axi_awregion;
assign s_arpayload[G_AXI_ARREGION_INDEX+:G_AXI_ARREGION_WIDTH] = s_axi_arregion;
end
else begin : gen_no_region_signals
end
if (C_AXI_SUPPORTS_USER_SIGNALS == 1 && C_AXI_PROTOCOL != 2) begin : gen_user_signals
assign s_awpayload[G_AXI_AWUSER_INDEX+:G_AXI_AWUSER_WIDTH] = s_axi_awuser;
assign s_wpayload[G_AXI_WUSER_INDEX+:G_AXI_WUSER_WIDTH] = s_axi_wuser;
assign s_axi_buser = s_bpayload[G_AXI_BUSER_INDEX+:G_AXI_BUSER_WIDTH];
assign s_arpayload[G_AXI_ARUSER_INDEX+:G_AXI_ARUSER_WIDTH] = s_axi_aruser;
assign s_axi_ruser = s_rpayload[G_AXI_RUSER_INDEX+:G_AXI_RUSER_WIDTH];
end
else begin : gen_no_user_signals
assign s_axi_buser = 'b0;
assign s_axi_ruser = 'b0;
end
end
else begin : gen_axi4lite_packing
assign s_axi_bid = 'b0;
assign s_axi_buser = 'b0;
assign s_axi_rlast = 1'b1;
assign s_axi_rid = 'b0;
assign s_axi_ruser = 'b0;
end
endgenerate
endmodule
`default_nettype wire
// (c) Copyright 2012-2013 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.
//-----------------------------------------------------------------------------
// Description: SRL based FIFO for AXIS/AXI Channels.
//--------------------------------------------------------------------------
`timescale 1ps/1ps
`default_nettype none
(* DowngradeIPIdentifiedWarnings="yes" *)
module axi_infrastructure_v1_1_0_axic_srl_fifo #(
///////////////////////////////////////////////////////////////////////////////
// Parameter Definitions
///////////////////////////////////////////////////////////////////////////////
parameter C_FAMILY = "virtex7",
parameter integer C_PAYLOAD_WIDTH = 1,
parameter integer C_FIFO_DEPTH = 16 // Range: 4-16.
)
(
///////////////////////////////////////////////////////////////////////////////
// Port Declarations
///////////////////////////////////////////////////////////////////////////////
input wire aclk, // Clock
input wire aresetn, // Reset
input wire [C_PAYLOAD_WIDTH-1:0] s_payload, // Input data
input wire s_valid, // Input data valid
output reg s_ready, // Input data ready
output wire [C_PAYLOAD_WIDTH-1:0] m_payload, // Output data
output reg m_valid, // Output data valid
input wire m_ready // Output data ready
);
////////////////////////////////////////////////////////////////////////////////
// Functions
////////////////////////////////////////////////////////////////////////////////
// ceiling logb2
function integer f_clogb2 (input integer size);
integer s;
begin
s = size;
s = s - 1;
for (f_clogb2=1; s>1; f_clogb2=f_clogb2+1)
s = s >> 1;
end
endfunction // clogb2
////////////////////////////////////////////////////////////////////////////////
// Local parameters
////////////////////////////////////////////////////////////////////////////////
localparam integer LP_LOG_FIFO_DEPTH = f_clogb2(C_FIFO_DEPTH);
////////////////////////////////////////////////////////////////////////////////
// Wires/Reg declarations
////////////////////////////////////////////////////////////////////////////////
reg [LP_LOG_FIFO_DEPTH-1:0] fifo_index;
wire [4-1:0] fifo_addr;
wire push;
wire pop ;
reg areset_r1;
////////////////////////////////////////////////////////////////////////////////
// BEGIN RTL
////////////////////////////////////////////////////////////////////////////////
always @(posedge aclk) begin
areset_r1 <= ~aresetn;
end
always @(posedge aclk) begin
if (~aresetn) begin
fifo_index <= {LP_LOG_FIFO_DEPTH{1'b1}};
end
else begin
fifo_index <= push & ~pop ? fifo_index + 1'b1 :
~push & pop ? fifo_index - 1'b1 :
fifo_index;
end
end
assign push = s_valid & s_ready;
always @(posedge aclk) begin
if (~aresetn) begin
s_ready <= 1'b0;
end
else begin
s_ready <= areset_r1 ? 1'b1 :
push & ~pop && (fifo_index == (C_FIFO_DEPTH - 2'd2)) ? 1'b0 :
~push & pop ? 1'b1 :
s_ready;
end
end
assign pop = m_valid & m_ready;
always @(posedge aclk) begin
if (~aresetn) begin
m_valid <= 1'b0;
end
else begin
m_valid <= ~push & pop && (fifo_index == {LP_LOG_FIFO_DEPTH{1'b0}}) ? 1'b0 :
push & ~pop ? 1'b1 :
m_valid;
end
end
generate
if (LP_LOG_FIFO_DEPTH < 4) begin : gen_pad_fifo_addr
assign fifo_addr[0+:LP_LOG_FIFO_DEPTH] = fifo_index[LP_LOG_FIFO_DEPTH-1:0];
assign fifo_addr[LP_LOG_FIFO_DEPTH+:(4-LP_LOG_FIFO_DEPTH)] = {4-LP_LOG_FIFO_DEPTH{1'b0}};
end
else begin : gen_fifo_addr
assign fifo_addr[LP_LOG_FIFO_DEPTH-1:0] = fifo_index[LP_LOG_FIFO_DEPTH-1:0];
end
endgenerate
generate
genvar i;
for (i = 0; i < C_PAYLOAD_WIDTH; i = i + 1) begin : gen_data_bit
SRL16E
u_srl_fifo(
.Q ( m_payload[i] ) ,
.A0 ( fifo_addr[0] ) ,
.A1 ( fifo_addr[1] ) ,
.A2 ( fifo_addr[2] ) ,
.A3 ( fifo_addr[3] ) ,
.CE ( push ) ,
.CLK ( aclk ) ,
.D ( s_payload[i] )
);
end
endgenerate
endmodule
`default_nettype wire
// (c) Copyright 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.
//-----------------------------------------------------------------------------
//
// axi to vector
// A generic module to merge all axi signals into one signal called payload.
// This is strictly wires, so no clk, reset, aclken, valid/ready are required.
//
// Verilog-standard: Verilog 2001
//--------------------------------------------------------------------------
//
`timescale 1ps/1ps
`default_nettype none
(* DowngradeIPIdentifiedWarnings="yes" *)
module axi_infrastructure_v1_1_0_vector2axi #
(
///////////////////////////////////////////////////////////////////////////////
// Parameter Definitions
///////////////////////////////////////////////////////////////////////////////
parameter integer C_AXI_PROTOCOL = 0,
parameter integer C_AXI_ID_WIDTH = 4,
parameter integer C_AXI_ADDR_WIDTH = 32,
parameter integer C_AXI_DATA_WIDTH = 32,
parameter integer C_AXI_SUPPORTS_USER_SIGNALS = 0,
parameter integer C_AXI_SUPPORTS_REGION_SIGNALS = 0,
parameter integer C_AXI_AWUSER_WIDTH = 1,
parameter integer C_AXI_WUSER_WIDTH = 1,
parameter integer C_AXI_BUSER_WIDTH = 1,
parameter integer C_AXI_ARUSER_WIDTH = 1,
parameter integer C_AXI_RUSER_WIDTH = 1,
parameter integer C_AWPAYLOAD_WIDTH = 61,
parameter integer C_WPAYLOAD_WIDTH = 73,
parameter integer C_BPAYLOAD_WIDTH = 6,
parameter integer C_ARPAYLOAD_WIDTH = 61,
parameter integer C_RPAYLOAD_WIDTH = 69
)
(
///////////////////////////////////////////////////////////////////////////////
// Port Declarations
///////////////////////////////////////////////////////////////////////////////
// Slave Interface Write Address Ports
output wire [C_AXI_ID_WIDTH-1:0] m_axi_awid,
output wire [C_AXI_ADDR_WIDTH-1:0] m_axi_awaddr,
output wire [((C_AXI_PROTOCOL == 1) ? 4 : 8)-1:0] m_axi_awlen,
output wire [3-1:0] m_axi_awsize,
output wire [2-1:0] m_axi_awburst,
output wire [((C_AXI_PROTOCOL == 1) ? 2 : 1)-1:0] m_axi_awlock,
output wire [4-1:0] m_axi_awcache,
output wire [3-1:0] m_axi_awprot,
output wire [4-1:0] m_axi_awregion,
output wire [4-1:0] m_axi_awqos,
output wire [C_AXI_AWUSER_WIDTH-1:0] m_axi_awuser,
// Slave Interface Write Data Ports
output wire [C_AXI_ID_WIDTH-1:0] m_axi_wid,
output wire [C_AXI_DATA_WIDTH-1:0] m_axi_wdata,
output wire [C_AXI_DATA_WIDTH/8-1:0] m_axi_wstrb,
output wire m_axi_wlast,
output wire [C_AXI_WUSER_WIDTH-1:0] m_axi_wuser,
// Slave Interface Write Response Ports
input wire [C_AXI_ID_WIDTH-1:0] m_axi_bid,
input wire [2-1:0] m_axi_bresp,
input wire [C_AXI_BUSER_WIDTH-1:0] m_axi_buser,
// Slave Interface Read Address Ports
output wire [C_AXI_ID_WIDTH-1:0] m_axi_arid,
output wire [C_AXI_ADDR_WIDTH-1:0] m_axi_araddr,
output wire [((C_AXI_PROTOCOL == 1) ? 4 : 8)-1:0] m_axi_arlen,
output wire [3-1:0] m_axi_arsize,
output wire [2-1:0] m_axi_arburst,
output wire [((C_AXI_PROTOCOL == 1) ? 2 : 1)-1:0] m_axi_arlock,
output wire [4-1:0] m_axi_arcache,
output wire [3-1:0] m_axi_arprot,
output wire [4-1:0] m_axi_arregion,
output wire [4-1:0] m_axi_arqos,
output wire [C_AXI_ARUSER_WIDTH-1:0] m_axi_aruser,
// Slave Interface Read Data Ports
input wire [C_AXI_ID_WIDTH-1:0] m_axi_rid,
input wire [C_AXI_DATA_WIDTH-1:0] m_axi_rdata,
input wire [2-1:0] m_axi_rresp,
input wire m_axi_rlast,
input wire [C_AXI_RUSER_WIDTH-1:0] m_axi_ruser,
// payloads
input wire [C_AWPAYLOAD_WIDTH-1:0] m_awpayload,
input wire [C_WPAYLOAD_WIDTH-1:0] m_wpayload,
output wire [C_BPAYLOAD_WIDTH-1:0] m_bpayload,
input wire [C_ARPAYLOAD_WIDTH-1:0] m_arpayload,
output wire [C_RPAYLOAD_WIDTH-1:0] m_rpayload
);
////////////////////////////////////////////////////////////////////////////////
// Functions
////////////////////////////////////////////////////////////////////////////////
`include "axi_infrastructure_v1_1_0.vh"
////////////////////////////////////////////////////////////////////////////////
// Local parameters
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Wires/Reg declarations
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// BEGIN RTL
////////////////////////////////////////////////////////////////////////////////
// AXI4, AXI4LITE, AXI3 packing
assign m_axi_awaddr = m_awpayload[G_AXI_AWADDR_INDEX+:G_AXI_AWADDR_WIDTH];
assign m_axi_awprot = m_awpayload[G_AXI_AWPROT_INDEX+:G_AXI_AWPROT_WIDTH];
assign m_axi_wdata = m_wpayload[G_AXI_WDATA_INDEX+:G_AXI_WDATA_WIDTH];
assign m_axi_wstrb = m_wpayload[G_AXI_WSTRB_INDEX+:G_AXI_WSTRB_WIDTH];
assign m_bpayload[G_AXI_BRESP_INDEX+:G_AXI_BRESP_WIDTH] = m_axi_bresp;
assign m_axi_araddr = m_arpayload[G_AXI_ARADDR_INDEX+:G_AXI_ARADDR_WIDTH];
assign m_axi_arprot = m_arpayload[G_AXI_ARPROT_INDEX+:G_AXI_ARPROT_WIDTH];
assign m_rpayload[G_AXI_RDATA_INDEX+:G_AXI_RDATA_WIDTH] = m_axi_rdata;
assign m_rpayload[G_AXI_RRESP_INDEX+:G_AXI_RRESP_WIDTH] = m_axi_rresp;
generate
if (C_AXI_PROTOCOL == 0 || C_AXI_PROTOCOL == 1) begin : gen_axi4_or_axi3_packing
assign m_axi_awsize = m_awpayload[G_AXI_AWSIZE_INDEX+:G_AXI_AWSIZE_WIDTH] ;
assign m_axi_awburst = m_awpayload[G_AXI_AWBURST_INDEX+:G_AXI_AWBURST_WIDTH];
assign m_axi_awcache = m_awpayload[G_AXI_AWCACHE_INDEX+:G_AXI_AWCACHE_WIDTH];
assign m_axi_awlen = m_awpayload[G_AXI_AWLEN_INDEX+:G_AXI_AWLEN_WIDTH] ;
assign m_axi_awlock = m_awpayload[G_AXI_AWLOCK_INDEX+:G_AXI_AWLOCK_WIDTH] ;
assign m_axi_awid = m_awpayload[G_AXI_AWID_INDEX+:G_AXI_AWID_WIDTH] ;
assign m_axi_awqos = m_awpayload[G_AXI_AWQOS_INDEX+:G_AXI_AWQOS_WIDTH] ;
assign m_axi_wlast = m_wpayload[G_AXI_WLAST_INDEX+:G_AXI_WLAST_WIDTH] ;
if (C_AXI_PROTOCOL == 1) begin : gen_axi3_wid_packing
assign m_axi_wid = m_wpayload[G_AXI_WID_INDEX+:G_AXI_WID_WIDTH] ;
end
else begin : gen_no_axi3_wid_packing
assign m_axi_wid = 1'b0;
end
assign m_bpayload[G_AXI_BID_INDEX+:G_AXI_BID_WIDTH] = m_axi_bid;
assign m_axi_arsize = m_arpayload[G_AXI_ARSIZE_INDEX+:G_AXI_ARSIZE_WIDTH] ;
assign m_axi_arburst = m_arpayload[G_AXI_ARBURST_INDEX+:G_AXI_ARBURST_WIDTH];
assign m_axi_arcache = m_arpayload[G_AXI_ARCACHE_INDEX+:G_AXI_ARCACHE_WIDTH];
assign m_axi_arlen = m_arpayload[G_AXI_ARLEN_INDEX+:G_AXI_ARLEN_WIDTH] ;
assign m_axi_arlock = m_arpayload[G_AXI_ARLOCK_INDEX+:G_AXI_ARLOCK_WIDTH] ;
assign m_axi_arid = m_arpayload[G_AXI_ARID_INDEX+:G_AXI_ARID_WIDTH] ;
assign m_axi_arqos = m_arpayload[G_AXI_ARQOS_INDEX+:G_AXI_ARQOS_WIDTH] ;
assign m_rpayload[G_AXI_RLAST_INDEX+:G_AXI_RLAST_WIDTH] = m_axi_rlast;
assign m_rpayload[G_AXI_RID_INDEX+:G_AXI_RID_WIDTH] = m_axi_rid ;
if (C_AXI_SUPPORTS_REGION_SIGNALS == 1 && G_AXI_AWREGION_WIDTH > 0) begin : gen_region_signals
assign m_axi_awregion = m_awpayload[G_AXI_AWREGION_INDEX+:G_AXI_AWREGION_WIDTH];
assign m_axi_arregion = m_arpayload[G_AXI_ARREGION_INDEX+:G_AXI_ARREGION_WIDTH];
end
else begin : gen_no_region_signals
assign m_axi_awregion = 'b0;
assign m_axi_arregion = 'b0;
end
if (C_AXI_SUPPORTS_USER_SIGNALS == 1 && C_AXI_PROTOCOL != 2) begin : gen_user_signals
assign m_axi_awuser = m_awpayload[G_AXI_AWUSER_INDEX+:G_AXI_AWUSER_WIDTH];
assign m_axi_wuser = m_wpayload[G_AXI_WUSER_INDEX+:G_AXI_WUSER_WIDTH] ;
assign m_bpayload[G_AXI_BUSER_INDEX+:G_AXI_BUSER_WIDTH] = m_axi_buser ;
assign m_axi_aruser = m_arpayload[G_AXI_ARUSER_INDEX+:G_AXI_ARUSER_WIDTH];
assign m_rpayload[G_AXI_RUSER_INDEX+:G_AXI_RUSER_WIDTH] = m_axi_ruser ;
end
else begin : gen_no_user_signals
assign m_axi_awuser = 'b0;
assign m_axi_wuser = 'b0;
assign m_axi_aruser = 'b0;
end
end
else begin : gen_axi4lite_packing
assign m_axi_awsize = (C_AXI_DATA_WIDTH == 32) ? 3'd2 : 3'd3;
assign m_axi_awburst = 'b0;
assign m_axi_awcache = 'b0;
assign m_axi_awlen = 'b0;
assign m_axi_awlock = 'b0;
assign m_axi_awid = 'b0;
assign m_axi_awqos = 'b0;
assign m_axi_wlast = 1'b1;
assign m_axi_wid = 'b0;
assign m_axi_arsize = (C_AXI_DATA_WIDTH == 32) ? 3'd2 : 3'd3;
assign m_axi_arburst = 'b0;
assign m_axi_arcache = 'b0;
assign m_axi_arlen = 'b0;
assign m_axi_arlock = 'b0;
assign m_axi_arid = 'b0;
assign m_axi_arqos = 'b0;
assign m_axi_awregion = 'b0;
assign m_axi_arregion = 'b0;
assign m_axi_awuser = 'b0;
assign m_axi_wuser = 'b0;
assign m_axi_aruser = 'b0;
end
endgenerate
endmodule
`default_nettype wire