// -- (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. //----------------------------------------------------------------------------- // // File name: crossbar_sasd.v // // Description: // This module is a M-master to N-slave AXI axi_crossbar_v2_1_crossbar switch. // Single transaction issuing, single arbiter (both W&R), single data pathways. // The interface of this module consists of a vectored slave and master interface // in which all slots are sized and synchronized to the native width and clock // of the interconnect, and are all AXI4 protocol. // All width, clock and protocol conversions are done outside this block, as are // any pipeline registers or data FIFOs. // This module contains all arbitration, decoders and channel multiplexing logic. // It also contains the diagnostic registers and control interface. // //-------------------------------------------------------------------------- // // Structure: // crossbar_sasd // addr_arbiter_sasd // mux_enc // addr_decoder // comparator_static // splitter // mux_enc // axic_register_slice // decerr_slave // //----------------------------------------------------------------------------- `timescale 1ps/1ps `default_nettype none (* DowngradeIPIdentifiedWarnings="yes" *) module axi_crossbar_v2_1_crossbar_sasd # ( parameter C_FAMILY = "none", parameter integer C_NUM_SLAVE_SLOTS = 1, parameter integer C_NUM_MASTER_SLOTS = 1, parameter integer C_NUM_ADDR_RANGES = 1, parameter integer C_AXI_ID_WIDTH = 1, parameter integer C_AXI_ADDR_WIDTH = 32, parameter integer C_AXI_DATA_WIDTH = 32, parameter integer C_AXI_PROTOCOL = 0, parameter [C_NUM_MASTER_SLOTS*C_NUM_ADDR_RANGES*64-1:0] C_M_AXI_BASE_ADDR = {C_NUM_MASTER_SLOTS*C_NUM_ADDR_RANGES*64{1'b1}}, parameter [C_NUM_MASTER_SLOTS*C_NUM_ADDR_RANGES*64-1:0] C_M_AXI_HIGH_ADDR = {C_NUM_MASTER_SLOTS*C_NUM_ADDR_RANGES*64{1'b0}}, parameter [C_NUM_SLAVE_SLOTS*64-1:0] C_S_AXI_BASE_ID = {C_NUM_SLAVE_SLOTS*64{1'b0}}, parameter [C_NUM_SLAVE_SLOTS*64-1:0] C_S_AXI_HIGH_ID = {C_NUM_SLAVE_SLOTS*64{1'b0}}, parameter integer C_AXI_SUPPORTS_USER_SIGNALS = 0, parameter integer C_AXI_AWUSER_WIDTH = 1, parameter integer C_AXI_ARUSER_WIDTH = 1, parameter integer C_AXI_WUSER_WIDTH = 1, parameter integer C_AXI_RUSER_WIDTH = 1, parameter integer C_AXI_BUSER_WIDTH = 1, parameter [C_NUM_SLAVE_SLOTS-1:0] C_S_AXI_SUPPORTS_WRITE = {C_NUM_SLAVE_SLOTS{1'b1}}, parameter [C_NUM_SLAVE_SLOTS-1:0] C_S_AXI_SUPPORTS_READ = {C_NUM_SLAVE_SLOTS{1'b1}}, parameter [C_NUM_MASTER_SLOTS-1:0] C_M_AXI_SUPPORTS_WRITE = {C_NUM_MASTER_SLOTS{1'b1}}, parameter [C_NUM_MASTER_SLOTS-1:0] C_M_AXI_SUPPORTS_READ = {C_NUM_MASTER_SLOTS{1'b1}}, parameter [C_NUM_SLAVE_SLOTS*32-1:0] C_S_AXI_ARB_PRIORITY = {C_NUM_SLAVE_SLOTS{32'h00000000}}, parameter [C_NUM_MASTER_SLOTS*32-1:0] C_M_AXI_SECURE = {C_NUM_MASTER_SLOTS{32'h00000000}}, parameter [C_NUM_MASTER_SLOTS*32-1:0] C_M_AXI_ERR_MODE = {C_NUM_MASTER_SLOTS{32'h00000000}}, parameter integer C_R_REGISTER = 0, parameter integer C_RANGE_CHECK = 0, parameter integer C_ADDR_DECODE = 0, parameter integer C_DEBUG = 1 ) ( // Global Signals input wire ACLK, input wire ARESETN, // Slave Interface Write Address Ports input wire [C_NUM_SLAVE_SLOTS*C_AXI_ID_WIDTH-1:0] S_AXI_AWID, input wire [C_NUM_SLAVE_SLOTS*C_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR, input wire [C_NUM_SLAVE_SLOTS*8-1:0] S_AXI_AWLEN, input wire [C_NUM_SLAVE_SLOTS*3-1:0] S_AXI_AWSIZE, input wire [C_NUM_SLAVE_SLOTS*2-1:0] S_AXI_AWBURST, input wire [C_NUM_SLAVE_SLOTS*2-1:0] S_AXI_AWLOCK, input wire [C_NUM_SLAVE_SLOTS*4-1:0] S_AXI_AWCACHE, input wire [C_NUM_SLAVE_SLOTS*3-1:0] S_AXI_AWPROT, // input wire [C_NUM_SLAVE_SLOTS*4-1:0] S_AXI_AWREGION, input wire [C_NUM_SLAVE_SLOTS*4-1:0] S_AXI_AWQOS, input wire [C_NUM_SLAVE_SLOTS*C_AXI_AWUSER_WIDTH-1:0] S_AXI_AWUSER, input wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_AWVALID, output wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_AWREADY, // Slave Interface Write Data Ports input wire [C_NUM_SLAVE_SLOTS*C_AXI_ID_WIDTH-1:0] S_AXI_WID, input wire [C_NUM_SLAVE_SLOTS*C_AXI_DATA_WIDTH-1:0] S_AXI_WDATA, input wire [C_NUM_SLAVE_SLOTS*C_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB, input wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_WLAST, input wire [C_NUM_SLAVE_SLOTS*C_AXI_WUSER_WIDTH-1:0] S_AXI_WUSER, input wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_WVALID, output wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_WREADY, // Slave Interface Write Response Ports output wire [C_NUM_SLAVE_SLOTS*C_AXI_ID_WIDTH-1:0] S_AXI_BID, output wire [C_NUM_SLAVE_SLOTS*2-1:0] S_AXI_BRESP, output wire [C_NUM_SLAVE_SLOTS*C_AXI_BUSER_WIDTH-1:0] S_AXI_BUSER, output wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_BVALID, input wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_BREADY, // Slave Interface Read Address Ports input wire [C_NUM_SLAVE_SLOTS*C_AXI_ID_WIDTH-1:0] S_AXI_ARID, input wire [C_NUM_SLAVE_SLOTS*C_AXI_ADDR_WIDTH-1:0] S_AXI_ARADDR, input wire [C_NUM_SLAVE_SLOTS*8-1:0] S_AXI_ARLEN, input wire [C_NUM_SLAVE_SLOTS*3-1:0] S_AXI_ARSIZE, input wire [C_NUM_SLAVE_SLOTS*2-1:0] S_AXI_ARBURST, input wire [C_NUM_SLAVE_SLOTS*2-1:0] S_AXI_ARLOCK, input wire [C_NUM_SLAVE_SLOTS*4-1:0] S_AXI_ARCACHE, input wire [C_NUM_SLAVE_SLOTS*3-1:0] S_AXI_ARPROT, // input wire [C_NUM_SLAVE_SLOTS*4-1:0] S_AXI_ARREGION, input wire [C_NUM_SLAVE_SLOTS*4-1:0] S_AXI_ARQOS, input wire [C_NUM_SLAVE_SLOTS*C_AXI_ARUSER_WIDTH-1:0] S_AXI_ARUSER, input wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_ARVALID, output wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_ARREADY, // Slave Interface Read Data Ports output wire [C_NUM_SLAVE_SLOTS*C_AXI_ID_WIDTH-1:0] S_AXI_RID, output wire [C_NUM_SLAVE_SLOTS*C_AXI_DATA_WIDTH-1:0] S_AXI_RDATA, output wire [C_NUM_SLAVE_SLOTS*2-1:0] S_AXI_RRESP, output wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_RLAST, output wire [C_NUM_SLAVE_SLOTS*C_AXI_RUSER_WIDTH-1:0] S_AXI_RUSER, output wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_RVALID, input wire [C_NUM_SLAVE_SLOTS-1:0] S_AXI_RREADY, // Master Interface Write Address Port output wire [C_NUM_MASTER_SLOTS*C_AXI_ID_WIDTH-1:0] M_AXI_AWID, output wire [C_NUM_MASTER_SLOTS*C_AXI_ADDR_WIDTH-1:0] M_AXI_AWADDR, output wire [C_NUM_MASTER_SLOTS*8-1:0] M_AXI_AWLEN, output wire [C_NUM_MASTER_SLOTS*3-1:0] M_AXI_AWSIZE, output wire [C_NUM_MASTER_SLOTS*2-1:0] M_AXI_AWBURST, output wire [C_NUM_MASTER_SLOTS*2-1:0] M_AXI_AWLOCK, output wire [C_NUM_MASTER_SLOTS*4-1:0] M_AXI_AWCACHE, output wire [C_NUM_MASTER_SLOTS*3-1:0] M_AXI_AWPROT, output wire [C_NUM_MASTER_SLOTS*4-1:0] M_AXI_AWREGION, output wire [C_NUM_MASTER_SLOTS*4-1:0] M_AXI_AWQOS, output wire [C_NUM_MASTER_SLOTS*C_AXI_AWUSER_WIDTH-1:0] M_AXI_AWUSER, output wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_AWVALID, input wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_AWREADY, // Master Interface Write Data Ports output wire [C_NUM_MASTER_SLOTS*C_AXI_ID_WIDTH-1:0] M_AXI_WID, output wire [C_NUM_MASTER_SLOTS*C_AXI_DATA_WIDTH-1:0] M_AXI_WDATA, output wire [C_NUM_MASTER_SLOTS*C_AXI_DATA_WIDTH/8-1:0] M_AXI_WSTRB, output wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_WLAST, output wire [C_NUM_MASTER_SLOTS*C_AXI_WUSER_WIDTH-1:0] M_AXI_WUSER, output wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_WVALID, input wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_WREADY, // Master Interface Write Response Ports input wire [C_NUM_MASTER_SLOTS*C_AXI_ID_WIDTH-1:0] M_AXI_BID, // Unused input wire [C_NUM_MASTER_SLOTS*2-1:0] M_AXI_BRESP, input wire [C_NUM_MASTER_SLOTS*C_AXI_BUSER_WIDTH-1:0] M_AXI_BUSER, input wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_BVALID, output wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_BREADY, // Master Interface Read Address Port output wire [C_NUM_MASTER_SLOTS*C_AXI_ID_WIDTH-1:0] M_AXI_ARID, output wire [C_NUM_MASTER_SLOTS*C_AXI_ADDR_WIDTH-1:0] M_AXI_ARADDR, output wire [C_NUM_MASTER_SLOTS*8-1:0] M_AXI_ARLEN, output wire [C_NUM_MASTER_SLOTS*3-1:0] M_AXI_ARSIZE, output wire [C_NUM_MASTER_SLOTS*2-1:0] M_AXI_ARBURST, output wire [C_NUM_MASTER_SLOTS*2-1:0] M_AXI_ARLOCK, output wire [C_NUM_MASTER_SLOTS*4-1:0] M_AXI_ARCACHE, output wire [C_NUM_MASTER_SLOTS*3-1:0] M_AXI_ARPROT, output wire [C_NUM_MASTER_SLOTS*4-1:0] M_AXI_ARREGION, output wire [C_NUM_MASTER_SLOTS*4-1:0] M_AXI_ARQOS, output wire [C_NUM_MASTER_SLOTS*C_AXI_ARUSER_WIDTH-1:0] M_AXI_ARUSER, output wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_ARVALID, input wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_ARREADY, // Master Interface Read Data Ports input wire [C_NUM_MASTER_SLOTS*C_AXI_ID_WIDTH-1:0] M_AXI_RID, // Unused input wire [C_NUM_MASTER_SLOTS*C_AXI_DATA_WIDTH-1:0] M_AXI_RDATA, input wire [C_NUM_MASTER_SLOTS*2-1:0] M_AXI_RRESP, input wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_RLAST, input wire [C_NUM_MASTER_SLOTS*C_AXI_RUSER_WIDTH-1:0] M_AXI_RUSER, input wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_RVALID, output wire [C_NUM_MASTER_SLOTS-1:0] M_AXI_RREADY ); localparam integer P_AXI4 = 0; localparam integer P_AXI3 = 1; localparam integer P_AXILITE = 2; localparam integer P_NUM_MASTER_SLOTS_DE = C_RANGE_CHECK ? C_NUM_MASTER_SLOTS+1 : C_NUM_MASTER_SLOTS; localparam integer P_NUM_MASTER_SLOTS_LOG = (C_NUM_MASTER_SLOTS>1) ? f_ceil_log2(C_NUM_MASTER_SLOTS) : 1; localparam integer P_NUM_MASTER_SLOTS_DE_LOG = (P_NUM_MASTER_SLOTS_DE>1) ? f_ceil_log2(P_NUM_MASTER_SLOTS_DE) : 1; localparam integer P_NUM_SLAVE_SLOTS_LOG = (C_NUM_SLAVE_SLOTS>1) ? f_ceil_log2(C_NUM_SLAVE_SLOTS) : 1; localparam integer P_AXI_AUSER_WIDTH = (C_AXI_AWUSER_WIDTH > C_AXI_ARUSER_WIDTH) ? C_AXI_AWUSER_WIDTH : C_AXI_ARUSER_WIDTH; localparam integer P_AXI_WID_WIDTH = (C_AXI_PROTOCOL == P_AXI3) ? C_AXI_ID_WIDTH : 1; localparam integer P_AMESG_WIDTH = C_AXI_ID_WIDTH + C_AXI_ADDR_WIDTH + 8+3+2+3+2+4+4 + P_AXI_AUSER_WIDTH + 4; localparam integer P_BMESG_WIDTH = 2 + C_AXI_BUSER_WIDTH; localparam integer P_RMESG_WIDTH = 1+2 + C_AXI_DATA_WIDTH + C_AXI_RUSER_WIDTH; localparam integer P_WMESG_WIDTH = 1 + C_AXI_DATA_WIDTH + C_AXI_DATA_WIDTH/8 + C_AXI_WUSER_WIDTH + P_AXI_WID_WIDTH; localparam [31:0] P_AXILITE_ERRMODE = 32'h00000001; localparam integer P_NONSECURE_BIT = 1; localparam [C_NUM_MASTER_SLOTS-1:0] P_M_SECURE_MASK = f_bit32to1_mi(C_M_AXI_SECURE); // Mask of secure MI-slots localparam [C_NUM_MASTER_SLOTS-1:0] P_M_AXILITE_MASK = f_m_axilite(0); // Mask of axilite rule-check MI-slots localparam [1:0] P_FIXED = 2'b00; localparam integer P_BYPASS = 0; localparam integer P_LIGHTWT = 7; localparam integer P_FULLY_REG = 1; localparam integer P_R_REG_CONFIG = C_R_REGISTER == 8 ? // "Automatic" reg-slice (C_RANGE_CHECK ? ((C_AXI_PROTOCOL == P_AXILITE) ? P_LIGHTWT : P_FULLY_REG) : P_BYPASS) : // Bypass if no R-channel mux C_R_REGISTER; localparam P_DECERR = 2'b11; //--------------------------------------------------------------------------- // Functions //--------------------------------------------------------------------------- // Ceiling of log2(x) function integer f_ceil_log2 ( input integer x ); integer acc; begin acc=0; while ((2**acc) < x) acc = acc + 1; f_ceil_log2 = acc; end endfunction // Isolate thread bits of input S_ID and add to BASE_ID (RNG00) to form MI-side ID value // only for end-point SI-slots function [C_AXI_ID_WIDTH-1:0] f_extend_ID ( input [C_AXI_ID_WIDTH-1:0] s_id, input integer slot ); begin f_extend_ID = C_S_AXI_BASE_ID[slot*64+:C_AXI_ID_WIDTH] | (s_id & (C_S_AXI_BASE_ID[slot*64+:C_AXI_ID_WIDTH] ^ C_S_AXI_HIGH_ID[slot*64+:C_AXI_ID_WIDTH])); end endfunction // Convert Bit32 vector of range [0,1] to Bit1 vector on MI function [C_NUM_MASTER_SLOTS-1:0] f_bit32to1_mi (input [C_NUM_MASTER_SLOTS*32-1:0] vec32); integer mi; begin for (mi=0; mi1) begin : gen_wmux // SI WVALID mux. generic_baseblocks_v2_1_mux_enc # ( .C_FAMILY ("rtl"), .C_RATIO (C_NUM_SLAVE_SLOTS), .C_SEL_WIDTH (P_NUM_SLAVE_SLOTS_LOG), .C_DATA_WIDTH (1) ) si_w_valid_mux_inst ( .S (aa_grant_enc), .A (S_AXI_WVALID), .O (aa_wvalid), .OE (w_transfer_en) ); // SI W-channel payload mux generic_baseblocks_v2_1_mux_enc # ( .C_FAMILY ("rtl"), .C_RATIO (C_NUM_SLAVE_SLOTS), .C_SEL_WIDTH (P_NUM_SLAVE_SLOTS_LOG), .C_DATA_WIDTH (P_WMESG_WIDTH) ) si_w_payload_mux_inst ( .S (aa_grant_enc), .A (si_wmesg), .O (mi_wmesg), .OE (1'b1) ); for (gen_si_slot=0; gen_si_slot