// (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. `timescale 1ps/1ps module av_pma #( //PARAM_LIST_START parameter rx_enable = 1, // (1,0) Enable or disable reciever PMA parameter tx_enable = 1, // (1,0) Enable or disable transmitter PMA parameter bonded_lanes = 1, // Number of bonded lanes parameter bonding_master_ch = 0, // Indicates which channel is master parameter pma_bonding_master= "0", // (List i.e. "0,3,..."), Indicates which channels is master parameter bonding_master_only= "-1", // Indicates bonding_master_channel is MASTER_ONLY parameter channel_number = 0, // parameter plls = 1, // (1+) Number of high-speed serial clocks from TX plls (tx_ser_clk) parameter pll_sel = 0, // (0 - plls-1) // Which PLL clock to use parameter pma_prot_mode = "basic", // (basic,cpri,cpri_rx_tx,disabled_prot_mode,gige, pipe_g1,pipe_g2,srio_2p1,test,xaui) parameter pma_mode = 8, // (8,10,16,20,32,40,64,80) Serialization factor parameter base_data_rate = "1250000000 bps", // Base data rate for CGB parameter pma_data_rate = "1250000000 bps", // Serial data rate in bits-per-second parameter cdr_reconfig = 0, // 1-Enable CDR reconfiguration, 0-Disable CDR reconfiguration parameter cdr_reference_clock_frequency = "100 Mhz", parameter cdr_refclk_cnt = 1, // # of CDR reference clocks parameter cdr_refclk_sel = 0, // Initial CDR reference clock selection parameter deser_enable_bit_slip = "false", parameter auto_negotiation = "", // ("true","false") PCIe Auto-Negotiation (Gen1,2,3) parameter tx_clk_div = 1, // (1,2,4,8) parameter pcie_rst = "normal_reset", parameter fref_vco_bypass = "NORMAL_OPERATION", parameter sd_on = 16, parameter pdb_sd = "true", parameter pma_bonding_mode = "x1", // valid value "x1", "xN" parameter external_master_cgb = 0, // CvP IOCSR control - cvp_update parameter cvp_en_iocsr = "false" // valid values = "true", "false" //PARAM_LIST_END ) ( //PORT_LIST_START // TX/RX ports input wire calclk, // Calibration clock (to aux block) input wire [bonded_lanes - 1: 0] seriallpbken, // 1 = enable serial loopback input wire [bonded_lanes-1: 0] pciesw, // PCIe generation select // RX ports input wire [bonded_lanes - 1 : 0] rx_rstn, // Active low digital reset for (deserializer, CDR, RX buf) input wire [bonded_lanes - 1 : 0] rx_crurstn, // CDR analog reset (active low) input wire [bonded_lanes - 1 : 0] rx_datain, // RX serial data input input wire [bonded_lanes - 1 : 0] rx_bslip, // PMA bitslip. Slips one clock cycle (2 UI of data) input wire [bonded_lanes*cdr_refclk_cnt-1:0] rx_cdr_ref_clk, // Reference clock for CDR input wire [bonded_lanes - 1 : 0] rx_ltr, // Force lock-to_reference clock input wire [bonded_lanes - 1 : 0] rx_ltd, // Force lock-to-data stream input wire [bonded_lanes - 1 : 0] rx_freqlock, // frequency lock detector input (external PPM detector) input wire [bonded_lanes - 1 : 0] rx_earlyeios, // Early electricle idle ordered sequence input wire [bonded_lanes - 1 : 0] rx_hardoccalen, // Enable Offset cancellation output wire [bonded_lanes - 1 : 0] rx_clkdivrx, // RX parallel clock output output wire [((pma_prot_mode == "pma direct") ? (bonded_lanes*80) : (bonded_lanes*20))-1: 0] rx_dataout, // RX parallel data output output wire [bonded_lanes - 1 : 0] rx_sd, // RX signal detect output wire [bonded_lanes - 1 : 0] rx_clklow, // RX low frequency recovered clock output wire [bonded_lanes - 1 : 0] rx_fref, // RX PFD reference clock (rx_cdr_refclk after divider) output wire [bonded_lanes - 1 : 0] rx_is_lockedtodata, // Indicates lock to incoming data rate output wire [bonded_lanes - 1 : 0] rx_is_lockedtoref, // Indicates lock to reference clock output wire [bonded_lanes - 1 : 0] out_pcs_signal_ok, output wire [bonded_lanes - 1 : 0] out_pcs_rx_pll_phase_lock_out, // TX ports //input port for buf input wire [((pma_prot_mode == "pma direct") ? (bonded_lanes*80) : (bonded_lanes*20))-1: 0] tx_datain, // TX parallel data input input wire [bonded_lanes - 1 : 0] tx_txelecidl, // TX force electricle idle input wire tx_rxdetclk, // Clock for detection of downstream receiver (125MHz ?) input wire [bonded_lanes - 1 : 0] tx_txdetrx, // 1 = enable downstream receiver detection //output port for buf output wire [bonded_lanes - 1 : 0] tx_dataout, // TX serial data output output wire [bonded_lanes - 1 : 0] tx_rxdetectvalid, // Indicates corresponding tx_rxfound signal contains valid data output wire [bonded_lanes - 1 : 0] tx_rxfound, // Indicates downnstream receiver is detected (qualify with tx_rxdetectvalid) //input ports for ser input wire tx_rstn, // TODO - Examine resets //output ports for ser output wire [bonded_lanes - 1 : 0] tx_clkdivtx, // TX parallel clock output //input ports for cgb input wire [bonded_lanes*plls-1:0] tx_ser_clk, // High-speed serial clock(s) from PLL input wire tx_pcsrstn, input wire tx_fref, input wire [bonded_lanes*plls-1:0] tx_rstn_cgb_master, input wire [bonded_lanes - 1 : 0] tx_cpulsein, input wire [bonded_lanes - 1 : 0] tx_hclkin, input wire [bonded_lanes - 1 : 0] tx_lfclkin, input wire [bonded_lanes*3-1 : 0] tx_pclkin, //output ports for cgb output wire [bonded_lanes -1 : 0] tx_pcieswdone, // Inidicates PMA has accepted value on pciesw input. // AVMM ports input wire [bonded_lanes-1:0 ] pma_avmmrstn, // one for each lane input wire [bonded_lanes-1:0 ] pma_avmmclk, // one for each lane input wire [bonded_lanes-1:0 ] pma_avmmwrite, // one for each lane input wire [bonded_lanes-1:0 ] pma_avmmread, // one for each lane input wire [(bonded_lanes*2)-1:0 ] pma_avmmbyteen, // two for each lane input wire [(bonded_lanes*11)-1:0 ] pma_avmmaddress, // 11 for each lane input wire [(bonded_lanes*16)-1:0 ] pma_avmmwritedata, // 16 for each lane output wire [(bonded_lanes*16)-1:0 ] pma_avmmreaddata_tx_cgb, // TX AVMM CGB readdata (16 for each lane) output wire [(bonded_lanes*16)-1:0 ] pma_avmmreaddata_tx_ser, // TX AVMM SER readdata (16 for each lane) output wire [(bonded_lanes*16)-1:0 ] pma_avmmreaddata_tx_buf, // TX AVMM BUF readdata (16 for each lane) output wire [(bonded_lanes*16)-1:0 ] pma_avmmreaddata_rx_ser, // RX AVMM SER readdata (16 for each lane) output wire [(bonded_lanes*16)-1:0 ] pma_avmmreaddata_rx_buf, // RX AVMM BUF readdata (16 for each lane) output wire [(bonded_lanes*16)-1:0 ] pma_avmmreaddata_rx_cdr, // RX AVMM CDR readdata (16 for each lane) output wire [(bonded_lanes*16)-1:0 ] pma_avmmreaddata_rx_mux, // RX AVMM CDR MUX readdata (16 for each lane) output wire [bonded_lanes-1:0 ] pma_blockselect_tx_cgb, // TX AVMM CGB blockselect (1 for each lane) output wire [bonded_lanes-1:0 ] pma_blockselect_tx_ser, // TX AVMM SER blockselect (1 for each lane) output wire [bonded_lanes-1:0 ] pma_blockselect_tx_buf, // TX AVMM BUF blockselect (1 for each lane) output wire [bonded_lanes-1:0 ] pma_blockselect_rx_ser, // RX AVMM SER blockselect (1 for each lane) output wire [bonded_lanes-1:0 ] pma_blockselect_rx_buf, // RX AVMM BUF blockselect (1 for each lane) output wire [bonded_lanes-1:0 ] pma_blockselect_rx_cdr, // RX AVMM SER blockselect (1 for each lane) output wire [bonded_lanes-1:0 ] pma_blockselect_rx_mux, // RX AVMM BUF blockselect (1 for each lane) output wire [bonded_lanes-1:0 ] pll_aux_atb_comp_out // Voltage comparator output for DCD (1 for each lane) //PORT_LIST_END ); import altera_xcvr_functions::*; // Useful functions (primarily for rule-checking) localparam rbc_all_prot_mode = "(basic,cpri,cpri_rx_tx,disabled_prot_mode,gige,pipe_g1,pipe_g2,srio_2p1,test,xaui,pma direct)"; localparam rbc_any_prot_mode = "basic"; localparam fnl_prot_mode = (pma_prot_mode == "" || pma_prot_mode == "") ? rbc_any_prot_mode : pma_prot_mode; localparam pipe_mode = (fnl_prot_mode == "pipe_g1" || fnl_prot_mode == "pipe_g2") ? 1 : 0; localparam rbc_all_auto_negotiation = (fnl_prot_mode == "pipe_g1" || fnl_prot_mode == "pipe_g2") ? "(true,false)" : "false"; localparam rbc_any_auto_negotiation = "false"; localparam fnl_auto_negotiation = (auto_negotiation == "" || auto_negotiation == "") ? rbc_any_auto_negotiation : auto_negotiation; // Internal parameters localparam INT_DATA_RATE = str2hz(pma_data_rate); // TODO - may fail due to 32-bit param localparam INT_CDR_OUT_CLOCK_FREQ = INT_DATA_RATE / 2; localparam INT_CDR_OUT_CLOCK_FREQ_STR= hz2str(INT_CDR_OUT_CLOCK_FREQ); localparam pma_width = (pma_prot_mode == "pma direct") ? 80 : 20; localparam FIR_COEFF_CTRL_SEL = (pipe_mode == 1)? "dynamic_ctl" : "ram_ctl"; // Parameter legality checking initial begin if (!is_in_legal_set(pma_prot_mode, rbc_all_prot_mode)) begin $display("Critical Warning: pma_prot_mode value, '%s', not in legal set: '%s'", pma_prot_mode, rbc_all_prot_mode); end if (!is_in_legal_set(auto_negotiation, rbc_all_auto_negotiation)) begin $display("Critical Warning: auto_negotiation value, '%s', not in legal set: '%s'", auto_negotiation, rbc_all_auto_negotiation); end end // Internal signals wire [bonded_lanes - 1: 0] loopback_data; wire [bonded_lanes -1: 0] int_pciesw; // PCIe generation select wire [bonded_lanes-1: 0] int_pcieswdone; // Inidicates PMA has accepted value on pciesw input. wire [bonded_lanes - 1: 0] reverse_loopback_data_p; wire [bonded_lanes - 1: 0] reverse_loopback_data_n; wire [bonded_lanes - 1: 0] seriallpbken_n; assign int_pciesw = (fnl_auto_negotiation == "true") ? pciesw : {bonded_lanes{1'b0}}; assign tx_pcieswdone = (fnl_auto_negotiation == "true" || tx_enable == 0) ? int_pcieswdone : {bonded_lanes{1'b0}}; assign out_pcs_signal_ok = rx_is_lockedtodata; assign out_pcs_rx_pll_phase_lock_out = rx_is_lockedtodata; // We only drive seriallpbken in duplex mode. assign seriallpbken_n = ((rx_enable == 1) && (tx_enable == 1)) ? ~seriallpbken : {bonded_lanes{1'b1}}; //********************************************************************* //************************ Receiver PMA ******************************* generate if(rx_enable == 1) begin av_rx_pma #( .bonded_lanes (bonded_lanes ), .bonding_master_ch_num (pma_bonding_master ), .bonding_master_only (bonding_master_only ), .mode (pma_mode ), //.serial_loopback ("lpbkp_dis" ), .sdclk_enable ("true" ), // TODO Hard-code for now .channel_number (channel_number ), .deser_enable_bit_slip (deser_enable_bit_slip ), .auto_negotiation (fnl_auto_negotiation ), .cdr_refclk_sel (cdr_refclk_sel ), .cdr_reconfig (cdr_reconfig ), .cdr_reference_clock_frequency(cdr_reference_clock_frequency), .cdr_refclk_cnt (cdr_refclk_cnt ), .cdr_output_clock_frequency (INT_CDR_OUT_CLOCK_FREQ_STR ), .rxpll_pd_bw_ctrl ("300" ), // TODO Hard-code for now .sd_on (sd_on ), .pdb_sd (pdb_sd ), .pma_width (pma_width ), .pma_direct ((pma_prot_mode == "pma direct")? "true" : "false"), .cvp_en_iocsr (cvp_en_iocsr ) //Only PCIe CvP designs override this ) av_rx_pma( .rstn (rx_rstn ), .crurstn (rx_crurstn ), .calclk ({bonded_lanes{calclk}} ), .datain (rx_datain ), .seriallpbkin (loopback_data ), .seriallpbken (seriallpbken_n ), .bslip (rx_bslip ), //.adaptcapture (rx_adaptcapture ), //.adcestandby (rx_adcestandby ), .hardoccalen (rx_hardoccalen ), //.eyemonitor (rx_eyemonitor ), //.adaptdone (rx_adaptdone ), //.hardoccaldone (rx_hardoccaldone ), .cdr_ref_clk (rx_cdr_ref_clk ), .pciesw (int_pciesw ), .ltr (rx_ltr ), .ltd (rx_ltd ), .freqlock (rx_freqlock ), .earlyeios (rx_earlyeios ), .clkdivrx (rx_clkdivrx ), .dout (rx_dataout ), .sd (rx_sd ), .clklow (rx_clklow ), .fref (rx_fref ), .rx_is_lockedtodata (rx_is_lockedtodata ), .rx_is_lockedtoref (rx_is_lockedtoref ), .avmmrstn (pma_avmmrstn ), .avmmclk (pma_avmmclk ), .avmmwrite (pma_avmmwrite ), .avmmread (pma_avmmread ), .avmmbyteen (pma_avmmbyteen ), .avmmaddress (pma_avmmaddress ), .avmmwritedata (pma_avmmwritedata ), .avmmreaddata_ser (pma_avmmreaddata_rx_ser), // SER readdata .avmmreaddata_buf (pma_avmmreaddata_rx_buf), // BUF readdata .avmmreaddata_cdr (pma_avmmreaddata_rx_cdr), // CDR readdata .avmmreaddata_mux (pma_avmmreaddata_rx_mux), // CDR MUX readdata .blockselect_ser (pma_blockselect_rx_ser ), // SER blockselect .blockselect_buf (pma_blockselect_rx_buf ), // BUF blockselect .blockselect_cdr (pma_blockselect_rx_cdr ), // CDR blockselect .blockselect_mux (pma_blockselect_rx_mux ), // CDR MUX blockselect .rdlpbkp (reverse_loopback_data_p) //.rdlpbkn (reverse_loopback_data_n) ); end else begin // Default unused outputs assign rx_clkdivrx = {bonded_lanes{1'b0}}; assign rx_dataout = {(bonded_lanes*pma_width){1'b0}}; assign rx_sd = {bonded_lanes{1'b0}}; assign rx_clklow = {bonded_lanes{1'b0}}; assign rx_fref = {bonded_lanes{1'b0}}; assign rx_is_lockedtodata = {bonded_lanes{1'b0}}; assign rx_is_lockedtoref = {bonded_lanes{1'b0}}; //assign rx_adaptdone = {bonded_lanes{1'b0}}; //assign rx_hardoccaldone = {bonded_lanes{1'b0}}; assign pma_avmmreaddata_rx_ser = {bonded_lanes*16{1'b0}}; assign pma_avmmreaddata_rx_buf = {bonded_lanes*16{1'b0}}; assign pma_avmmreaddata_rx_cdr = {bonded_lanes*16{1'b0}}; assign pma_avmmreaddata_rx_mux = {bonded_lanes*16{1'b0}}; assign pma_blockselect_rx_ser = {bonded_lanes{1'b0}}; assign pma_blockselect_rx_buf = {bonded_lanes{1'b0}}; assign pma_blockselect_rx_cdr = {bonded_lanes{1'b0}}; assign pma_blockselect_rx_mux = {bonded_lanes{1'b0}}; assign reverse_loopback_data_p = {bonded_lanes{1'b0}}; end endgenerate //********************** End Receiver PMA ***************************** //********************************************************************* //********************************************************************* //********************** Transmitter PMA ****************************** generate if(tx_enable == 1) begin av_tx_pma #( .bonded_lanes (bonded_lanes ), .bonding_master_ch_num (pma_bonding_master ), .bonding_master_only (bonding_master_only ), .base_data_rate (base_data_rate ), .data_rate (pma_data_rate ), // TODO .mode (pma_mode ), .plls (plls ), .pll_sel (pll_sel ), .channel_number (channel_number ), .ser_loopback ("false" ), .auto_negotiation (fnl_auto_negotiation ), .ht_delay_sel ("false" ), .rx_det_pdb ("false" ), .tx_clk_div (tx_clk_div ), .pcie_rst (pcie_rst ), .fref_vco_bypass (fref_vco_bypass ), .pma_width (pma_width ), .pma_bonding_mode (pma_bonding_mode ), .fir_coeff_ctrl_sel (FIR_COEFF_CTRL_SEL ), .pma_direct ((pma_prot_mode == "pma direct")? "true" : "false"), .external_master_cgb (external_master_cgb ) ) av_tx_pma( //input port for aux .calclk ({bonded_lanes{calclk}} ), //input port for buf .datain (tx_datain ), .txelecidl (tx_txelecidl ), .rxdetclk (tx_rxdetclk ), .txdetrx (tx_txdetrx ), //output port for buf .dataout (tx_dataout ), .rxdetectvalid (tx_rxdetectvalid ), .rxfound (tx_rxfound ), //input ports for ser .rstn (tx_rstn ), .seriallpbken (seriallpbken_n ), //output ports for ser .clkdivtx (tx_clkdivtx ), .seriallpbkout (loopback_data ), //input ports for cgb .clk (tx_ser_clk ), .pcsrstn (tx_pcsrstn ), .fref (tx_fref ), .rstn_cgb_master (tx_rstn_cgb_master ), .pciesw (int_pciesw[bonding_master_ch]), .cpulsein (tx_cpulsein ), .hclkin (tx_hclkin ), .lfclkin (tx_lfclkin ), .pclkin (tx_pclkin ), //output ports for cgb .pcieswdone (int_pcieswdone ), .avmmrstn (pma_avmmrstn ), .avmmclk (pma_avmmclk ), .avmmwrite (pma_avmmwrite ), .avmmread (pma_avmmread ), .avmmbyteen (pma_avmmbyteen ), .avmmaddress (pma_avmmaddress ), .avmmwritedata (pma_avmmwritedata ), .avmmreaddata_cgb (pma_avmmreaddata_tx_cgb), // CGB readdata .avmmreaddata_ser (pma_avmmreaddata_tx_ser), // SER readdata .avmmreaddata_buf (pma_avmmreaddata_tx_buf), // BUF readdata .blockselect_cgb (pma_blockselect_tx_cgb ), // CGB blockselect .blockselect_ser (pma_blockselect_tx_ser ), // SER blockselect .blockselect_buf (pma_blockselect_tx_buf ), // BUF blockselect .atb_comp_out (pll_aux_atb_comp_out ), // pll aux voltage comparator output .vrlpbkp (reverse_loopback_data_p), .vrlpbkn ({bonded_lanes{1'b0}}) ); end else begin // Default the outputs assign tx_dataout = {bonded_lanes{1'b0}}; assign tx_rxdetectvalid = {bonded_lanes{1'b0}}; assign tx_rxfound = {bonded_lanes{1'b0}}; assign tx_clkdivtx = {bonded_lanes{1'b0}}; assign int_pcieswdone = {bonded_lanes{1'b0}}; assign pma_avmmreaddata_tx_cgb = {bonded_lanes*16{1'b0}}; assign pma_avmmreaddata_tx_ser = {bonded_lanes*16{1'b0}}; assign pma_avmmreaddata_tx_buf = {bonded_lanes*16{1'b0}}; assign pma_blockselect_tx_cgb = {bonded_lanes{1'b0}}; assign pma_blockselect_tx_ser = {bonded_lanes{1'b0}}; assign pma_blockselect_tx_buf = {bonded_lanes{1'b0}}; assign pll_aux_atb_comp_out = {bonded_lanes{1'b0}}; assign loopback_data = {bonded_lanes{1'b0}}; end endgenerate //******************** End Transmitter PMA **************************** //********************************************************************* endmodule