// (C) 2001-2015 Altera Corporation. All rights reserved. // Your use of Altera Corporation's design tools, logic functions and other // software and tools, and its AMPP partner logic functions, and any output // files any of the foregoing (including device programming or simulation // files), and any associated documentation or information are expressly subject // to the terms and conditions of the Altera Program License Subscription // Agreement, Altera MegaCore Function License Agreement, or other applicable // license agreement, including, without limitation, that your use is for the // sole purpose of programming logic devices manufactured by Altera and sold by // Altera or its authorized distributors. Please refer to the applicable // agreement for further details. // This block instantiates a single channel or a number of bonded // channels. The channel numbers are assigned sequentially starting from // the channel_number specifical as a parameter // // Key parameters: // // bonded_lanes = specifies the number of lanes to produce. If bonded_lanes == 1, // only a single chann is produced of type "SINGLE_CHANNEL". // If bonded_lanes > 1, then look at the value of the bonding_master_lane // and bonding_master_only parameters // // // bonding_master_ch_number = uint, must be in the range [channel_number : channel_number + bonded_lanes - 1] // Indicates that channel number that must be the master channel. // All other lanes, with the exception of the master will be of SLAVE_CHANNEL type // There are two scenarious possible: // (1) If the bonding_master_only parameter is set to "true"; A master lane // of type "MASTER_ONLY" will be instantiated. // // (2) If the bonding_master_only parameter is set to "false"; A master lane // of type "MASTER_SINGLE_CHANNEL" will be instantiated. // // bonding_master_only = "true","false", Indicates the lane indicated by bonding_master_ch_number // should by of type "MASTER_ONLY" ("true"), or of type "MASTER_SINGLE_CHANNEL" ("false"). // // channel_number = uint, starting channel number. This module will instantiate channels and will label them // consequitively from (channel_number) to (channnel_number + bonded_lanes - 1) // `timescale 1ps/1ps module av_tx_pma #( parameter bonded_lanes = 1, parameter bonding_master_ch_num = "0", parameter bonding_master_only = "-1", parameter base_data_rate = "0 ps", parameter data_rate = "0 ps", parameter mode = 8, parameter channel_number = 0, parameter ser_loopback = "false", parameter auto_negotiation = "false", parameter plls = 1, parameter pll_sel = 0, parameter pclksel = "local_pclk", parameter ht_delay_sel = "false", parameter rx_det_pdb = "false", parameter tx_clk_div = 1, // (1,2,4,8) parameter pcie_rst = "normal_reset", parameter fref_vco_bypass = "NORMAL_OPERATION", parameter pma_width = 20, parameter pma_bonding_mode = "x1", // valid value "x1", "xN" parameter pma_direct = "false", parameter external_master_cgb = 0, parameter fir_coeff_ctrl_sel = "ram_ctl" ) ( //input port for aux input [bonded_lanes - 1 : 0] calclk, //input port for buf input [(bonded_lanes * pma_width) -1: 0] datain, input [bonded_lanes - 1 : 0] txelecidl, input rxdetclk, input [bonded_lanes - 1 : 0] txdetrx, //output port for buf output [bonded_lanes - 1 : 0] dataout, output [bonded_lanes - 1 : 0] rxdetectvalid, output [bonded_lanes - 1 : 0] rxfound, //input ports for ser input rstn, input [bonded_lanes - 1 : 0] seriallpbken, //output ports for ser output [bonded_lanes - 1 : 0] clkdivtx, output [bonded_lanes - 1 : 0] seriallpbkout, //input ports for cgb input [bonded_lanes*plls-1:0] clk, // High-speed serial clocks from PLLs input pciesw, // to the master channel input pcsrstn, input fref, input [bonded_lanes*plls-1:0] rstn_cgb_master, input [bonded_lanes - 1 : 0] cpulsein, input [bonded_lanes - 1 : 0] hclkin, input [bonded_lanes - 1 : 0] lfclkin, input [bonded_lanes*3-1 : 0] pclkin, //output ports for cgb output [bonded_lanes-1 : 0] pcieswdone, // from the master channel input [bonded_lanes-1:0 ] avmmrstn, // one for each lane input [bonded_lanes-1:0 ] avmmclk, // one for each lane input [bonded_lanes-1:0 ] avmmwrite, // one for each lane input [bonded_lanes-1:0 ] avmmread, // one for each lane input [(bonded_lanes*2)-1:0 ] avmmbyteen, // two for each lane input [(bonded_lanes*11)-1:0 ] avmmaddress, // 11 for each lane input [(bonded_lanes*16)-1:0 ] avmmwritedata, // 16 for each lane output [(bonded_lanes*16)-1:0 ] avmmreaddata_cgb, // CGB readdata output [(bonded_lanes*16)-1:0 ] avmmreaddata_ser, // SER readdata output [(bonded_lanes*16)-1:0 ] avmmreaddata_buf, // BUF readdata output [bonded_lanes-1:0 ] blockselect_cgb, // CGB blockselect output [bonded_lanes-1:0 ] blockselect_ser, // SER blockselect output [bonded_lanes-1:0 ] blockselect_buf, // BUF blockselect output [bonded_lanes-1:0 ] atb_comp_out, // Voltage comparator output for DCD input [bonded_lanes-1:0 ] vrlpbkp, input [bonded_lanes-1:0 ] vrlpbkn ); import altera_xcvr_functions::*; wire [bonded_lanes-1:0] w_hfclkp; wire [bonded_lanes-1:0] w_lfclkp; wire [bonded_lanes-1:0] w_cpulse; wire [2:0] w_pclk [bonded_lanes-1:0]; wire [bonded_lanes*80-1:0] dadtain_padded; localparam integer bonding_master_0 = str2int(get_value_at_index(0,bonding_master_ch_num)); genvar i; generate for(i = 0; i < bonded_lanes; i = i + 1) begin:tx_pma_insts assign dadtain_padded[(i+1)*80 - 1 : i*80] = (pma_width == 20) ? {60'b0 , datain[(i+1)*20 - 1 : i*20]} : datain[(i+1)*pma_width - 1 : i*pma_width]; localparam [MAX_CHARS*8-1:0] str_i = int2str(i); localparam is_single_chan = (bonded_lanes == 1 && pma_bonding_mode == "x1") ? 1 : 0; localparam is_master_only = ( (is_single_chan == 0) && (is_in_legal_set(str_i,bonding_master_ch_num) == 1) && (is_in_legal_set(str_i,bonding_master_only) == 1)) ? 1 : 0; localparam is_master_chan = ( (is_single_chan == 0) && (is_master_only == 0) && (is_in_legal_set(str_i,bonding_master_ch_num) == 1)) ? 1 : 0; localparam is_slave_chan = ( (is_single_chan == 0) && ((is_in_legal_set(str_i,bonding_master_ch_num) == 0) && (is_in_legal_set(str_i,-1) == 0))) ? 1 : 0; //localparam is_fb_comp = ( (is_single_chan == 0) && // (pma_bonding_type == "fb_compensation") && // (is_in_legal_set(str_i,-1) == 0)) // ? 1 : 0; localparam is_fb_comp = 0; // Determine PMA type localparam [MAX_CHARS*8-1:0] tx_pma_type = (is_single_chan == 1) ? "SINGLE_CHANNEL" : (is_fb_comp == 1) ? "FB_COMP_CHANNEL" : (is_master_only == 1) ? "MASTER_ONLY" : (is_master_chan == 1) ? "MASTER_SINGLE_CHANNEL" : (is_slave_chan == 1) ? "SLAVE_CHANNEL" : "EMPTY_CHANNEL" ; // Determine the bonding master for this channel // If only one bonding master was specified, we select it. // If a bonding master per channel was specified, we select the corresponding master localparam [MAX_CHARS*8-1:0] master_sel_str = get_value_at_index(i,bonding_master_ch_num); localparam integer master_sel = (master_sel_str == "NA") ? bonding_master_0 : str2int(master_sel_str); av_tx_pma_ch #( .mode(mode), .auto_negotiation(auto_negotiation), .plls(plls), .pll_sel(pll_sel), .ser_loopback(ser_loopback), .ht_delay_sel(ht_delay_sel), .tx_pma_type(tx_pma_type), .base_data_rate(base_data_rate), .data_rate(data_rate), .rx_det_pdb(rx_det_pdb), .tx_clk_div(tx_clk_div), .pcie_rst(pcie_rst), .fref_vco_bypass(fref_vco_bypass), .pma_bonding_mode(pma_bonding_mode), .bonded_lanes(bonded_lanes), .pma_direct(pma_direct), .external_master_cgb(external_master_cgb), .fir_coeff_ctrl_sel(fir_coeff_ctrl_sel) ) av_tx_pma_ch_inst ( //input port for aux .calclk (calclk [i] ), //input port for buf .datain (dadtain_padded [(i+1)*80 - 1 : i*80]), .txelecidl (txelecidl [i] ), .rxdetclk (rxdetclk ), .txdetrx (txdetrx [i] ), //output port for buf .dataout (dataout [i] ), .rxdetectvalid (rxdetectvalid [i] ), .rxfound (rxfound [i] ), //input ports for ser .rstn (rstn ), .seriallpbken (seriallpbken [i] ), //output ports for ser .clkdivtx (clkdivtx [i] ), .seriallpbkout (seriallpbkout [i] ), //input ports for cgb .clk (clk [i*plls+:plls]), .pciesw (pciesw ), .pcsrstn (pcsrstn ), .fref (fref ), .rstn_cgb_master(rstn_cgb_master [i*plls+:plls]), // bonding clock inputs from master CGB .cpulsein ((external_master_cgb == 1)? cpulsein[i] : w_cpulse [master_sel] ), .hfclkpin ((external_master_cgb == 1)? hclkin[i] : w_hfclkp [master_sel] ), .lfclkpin ((external_master_cgb == 1)? lfclkin[i] : w_lfclkp [master_sel] ), .pclkin ((external_master_cgb == 1)? pclkin[i*3+:3] : w_pclk [master_sel] ), //output ports for cgb .pcieswdone (pcieswdone [i] ), // .cpulseout (w_cpulse [i] ), .hfclkpout (w_hfclkp [i] ), .lfclkpout (w_lfclkp [i] ), .pclkout (w_pclk [i] ), .vrlpbkp (vrlpbkp [i] ), .vrlpbkn (vrlpbkn [i] ), // Avalon-MM interface .avmmrstn (avmmrstn [i] ), .avmmclk (avmmclk [i] ), .avmmwrite (avmmwrite [i] ), .avmmread (avmmread [i] ), .avmmbyteen (avmmbyteen [i*2+:2] ), .avmmaddress (avmmaddress [i*11+:11] ), .avmmwritedata (avmmwritedata[i*16+:16] ), .avmmreaddata_cgb (avmmreaddata_cgb[i*16+:16] ), // CGB readdata .avmmreaddata_ser (avmmreaddata_ser[i*16+:16] ), // SER readdata .avmmreaddata_buf (avmmreaddata_buf[i*16+:16] ), // BUF readdata .blockselect_cgb (blockselect_cgb[i] ), // CGB blockselect .blockselect_ser (blockselect_ser[i] ), // SER blockselect .blockselect_buf (blockselect_buf[i] ), // BUF blockselect .atb_comp_out (atb_comp_out [i] ) ); end endgenerate endmodule