Commit 78020ea3 authored by A. Hahn's avatar A. Hahn

ftm4: removed pcie core generated files

parent 735d0f96
# (C) 2001-2018 Intel Corporation. All rights reserved.
# Your use of Intel Corporation's design tools, logic functions and other
# software and tools, and its AMPP partner logic functions, and any output
# files from 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 Intel Program License Subscription
# Agreement, Intel FPGA IP License Agreement, or other applicable
# license agreement, including, without limitation, that your use is for the
# sole purpose of programming logic devices manufactured by Intel and sold by
# Intel or its authorized distributors. Please refer to the applicable
# agreement for further details.
# derive_pll_clock is used to calculate all clock derived from PCIe refclk
# the derive_pll_clocks and derive clock_uncertainty should only
# be applied once across all of the SDC files used in a project
derive_pll_clocks -create_base_clocks
derive_clock_uncertainty
set testin_size_collection_pcie 0
set testin_collection_pcie [get_registers -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|altpcie_test_in_static_signal_to_be_false_path[*]}]
set testin_size_collection_pcie [get_collection_size $testin_collection_pcie]
if {$testin_size_collection_pcie > 0} {
set_false_path -from [get_registers {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|altpcie_test_in_static_signal_to_be_false_path[*]}]
set_false_path -to [get_registers {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|altpcie_test_in_static_signal_to_be_false_path[*]}]
}
#set_false_path -from [get_registers -nowarn {*|altpcie_a10_hip_pipen1b|wys~hd_altpe*_hip_core_top_hd_altpe*_hip_core_u_clkmux_core_clk_cnt_reg_*_Q.reg}] -to [get_registers -nowarn {*|tl_cfg_ctl_r[*]}]
#set_false_path -from [get_registers -nowarn {*|altpcie_a10_hip_pipen1b|wys~hd_altpe*_hip_core_top_hd_altpe*_hip_core_u_clkmux_core_clk_cnt_reg_*_Q.reg}] -to [get_registers -nowarn {*|tl_cfg_add_r[*]}]
set_max_skew -from [get_registers -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|wys~pld_clk.reg}] -to [get_registers -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|dbg_rx_data_reg[*] *|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|dbg_rx_datak_reg[*] }] 6.500
set_max_skew -from [get_registers -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|wys~pld_clk.reg}] -to [get_registers -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|dbg_rx_data_reg_1[*] *|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|dbg_rx_datak_reg_1[*] }] 6.500
set_max_delay -from [get_registers -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|wys~pld_clk.reg}] -to [get_registers -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|dbg_rx_data_reg[*] *|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|dbg_rx_data_reg_1[*] *|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|dbg_rx_datak_reg[*] *|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|dbg_rx_datak_reg_1[*] }] 10.000
set_false_path -from {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|wys~pld_clk.reg} -to {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|altpcie_sc_bitsync_node:rx_polinv_dbg.dbg_rx_valid_altpcie_sc_bitsync_1|altpcie_sc_bitsync:altpcie_sc_bitsync|altpcie_sc_bitsync_meta_dff[0]}
set_false_path -from {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|wys~pld_clk.reg} -to {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|altpcie_sc_bitsync_node:rx_polinv_dbg.dbg_rx_valid_altpcie_sc_bitsync|altpcie_sc_bitsync:altpcie_sc_bitsync|altpcie_sc_bitsync_meta_dff[0]}
set_multicycle_path -setup -through [get_pins -compatibility_mode -nocase -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|wys|tl_cfg_add[*]}] 2
set_multicycle_path -hold -through [get_pins -compatibility_mode -nocase -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|wys|tl_cfg_add[*]}] 2
set_multicycle_path -setup -through [get_pins -compatibility_mode -nocase -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|wys|tl_cfg_ctl[*]}] 2
set_multicycle_path -hold -through [get_pins -compatibility_mode -nocase -nowarn {*|altpcie_a10_hip_pipen1b:altpcie_a10_hip_pipen1b|wys|tl_cfg_ctl[*]}] 2
################################################ Applying Constraints ################################################
#derive_pll_clocks -create_base_clocks ;# derive_pll_clocks needs to be called before calling parent_of_clock
#derive_clock_uncertainty ;# in order to generate proper hierarchy.
set all_clk_parent_list {}
set clk_parent_list {}
set clk_parent_list_length {}
set pll_pcie_clock [get_clocks *pll_pcie_clk]
set num_matched_clocks [get_collection_size $pll_pcie_clock]
################################################ Find Clock Prefix ################################################
if {[get_collection_size $pll_pcie_clock] == 1} { ;# single instance
set clk_prefix [join [lrange [split [query_collection $pll_pcie_clock] {|}] 0 {end-1}] {|}]
set clk_parent_list_length 1
} elseif {[get_collection_size $pll_pcie_clock] > 1} { ;# multiple instances
set clk_prefix [query_collection $pll_pcie_clock -list_format]
foreach clk $clk_prefix { ;# store each unique parent to all_clk_parent_list
set removed_child_clk [join [lrange [split $clk {|}] 0 {end-1}] {|}]
lappend all_clk_parent_list $removed_child_clk
}
set clk_parent_list [lsort -unique $all_clk_parent_list] ;# only unique elements in list
set clk_parent_list_length [llength $clk_parent_list]
} else {
#puts "Clock pll_pcie_clk does not exist"
#puts "Ensure derive_pll_clocks -create_base_clocks is run"
set clk_parent_list_length 0
}
################################################ Find Clock Prefix End ################################################
################################################ Find Clock Pin Prefix ################################################
set byte_ser_clk_pins [get_pins -compatibility_mode *altpcie_a10_hip_pipen1b*|byte_deserializer_pcs_clk_div_by_4_txclk_reg]
set hip_presence {}
set all_pin_prefix_list {}
set byte_ser_clk_pin0 {}
set clk_pin_prefix {}
set clk_pin_prefix_list {}
set clk_pin_prefix_list_length {}
if {[get_collection_size $pll_pcie_clock] == 1} { ;# single instance
set byte_ser_clk_pin0 [lindex [query_collection $byte_ser_clk_pins] 0] ;# one type of pin prefix
set hip_presence [regexp {(^.*)\|altpcie_a10_hip_pipen1b} $byte_ser_clk_pin0 all clk_pin_prefix]
set clk_pin_prefix_list_length 1
} elseif {[get_collection_size $pll_pcie_clock] > 1} { ;# multiple instances
set byte_ser_clk_pin0 [query_collection $byte_ser_clk_pins] ;# two or more type of pin prefix
foreach clk $byte_ser_clk_pin0 {
set hip_presence [regexp {(^.*)\|altpcie_a10_hip_pipen1b} $clk all clk_pin_prefix]
lappend all_pin_prefix_list $clk_pin_prefix
}
set clk_pin_prefix_list [lsort -unique $all_pin_prefix_list]
set clk_pin_prefix_list_length [llength $clk_pin_prefix_list]
} else {
#puts "Clock pin *altpcie_a10_hip_pipen1b*|byte_deserializer_pcs_clk_div_by_4_txclk_reg does not exist"
#puts "Error: possibly a timing model issue"
set clk_pin_prefix_list_length 0
}
################################################ Find Clock Pin Prefix End ################################################
global subsequent_sdc_flag
#check whether bypass_flag exists in order to skip the multiple parent clocks constraints block
set get_clk_prefix {}
set get_pin_prefix {}
if {[get_collection_size $pll_pcie_clock] > 1 && [info exists subsequent_sdc_flag] == 0 && $clk_parent_list_length == $clk_pin_prefix_list_length } { ;# only for multiple parent clocks constraints
for {set j 0} {$j != [llength $clk_parent_list]} {incr j} {
for {set k 0} {$k != [llength $clk_pin_prefix_list]} {incr k} {
if {$j == $k} { ;#constraints applied only if indices are matching
set get_clk_prefix [lindex $clk_parent_list $j]
set get_pin_prefix [lindex $clk_pin_prefix_list $k]
set phy_lane0_size 0 ;#Gen 3x1
set phy_lane1_size 0 ;#Gen 3x2
set phy_lane3_size 0 ;#Gen 3x4
set phy_lane7_size 0 ;#Gen 3x8
set phy_lane0 [get_registers -nowarn "*$get_pin_prefix*phy_g3x*|g_xcvr_native_insts[0]*"]
set phy_lane1 [get_registers -nowarn "*$get_pin_prefix*phy_g3x*|g_xcvr_native_insts[1]*"]
set phy_lane3 [get_registers -nowarn "*$get_pin_prefix*phy_g3x*|g_xcvr_native_insts[3]*"]
set phy_lane7 [get_registers -nowarn "*$get_pin_prefix*phy_g3x*|g_xcvr_native_insts[7]*"]
set phy_lane0_size [get_collection_size $phy_lane0]
set phy_lane1_size [get_collection_size $phy_lane1]
set phy_lane3_size [get_collection_size $phy_lane3]
set phy_lane7_size [get_collection_size $phy_lane7]
if {$phy_lane7_size > 0} {
set stop 8
} elseif {$phy_lane3_size > 0} {
set stop 4
} elseif {$phy_lane1_size > 0} {
set stop 2
} elseif {$phy_lane0_size > 0} {
set stop 1
} else {
set stop 0
}
for {set i 0} {$i != $stop} {incr i} {
create_generated_clock -divide_by 1 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|byte_deserializer_pcs_clk_div_by_2_txclk_reg" \
-name "$get_clk_prefix|rx_pcs_clk_div_by_4[$i]" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|sta_rx_clk2_by2_1" ;# target
create_generated_clock -multiply_by 1 -divide_by 1 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_tx_pcs.inst_twentynm_hssi_8g_tx_pcs|byte_serializer_pcs_clk_div_by_2_reg" \
-name "$get_clk_prefix|tx_pcs_clk_div_by_4[$i]" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_tx_pcs.inst_twentynm_hssi_8g_tx_pcs|sta_tx_clk2_by2_1" ;# target
}
remove_clock "$get_clk_prefix|tx_bonding_clocks[0]"
# Constraint for Gen 3x2 and up
if {$phy_lane1_size > 0} {
create_generated_clock -multiply_by 1 -divide_by 5 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_pll.g_pll_g3n.lcpll_g3xn|lcpll_g3xn|a10_xcvr_atx_pll_inst|twentynm_hssi_pma_cgb_master_inst|clk_fpll_*" \
-master_clock "$get_clk_prefix|tx_serial_clk" \
-name "$get_clk_prefix|tx_bonding_clocks[0]" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_pll.g_pll_g3n.lcpll_g3xn|lcpll_g3xn|a10_xcvr_atx_pll_inst|twentynm_hssi_pma_cgb_master_inst|cpulse_out_bus[0]"
set_false_path -from {*|altpcie_a10_hip_pipen1b|wys~ch*_pcs_chnl_hip_clk_out[0].reg} -to {*|altpcie_a10_hip_pipen1b|*altpcie_a10_hip_pllnphy|*g_xcvr_native_insts[*].twentynm_xcvr_native_inst|*twentynm_xcvr_native_inst|*gen_twentynm_hssi_common_pld_pcs_interface.inst_twentynm_hssi_common_pld_pcs_interface~pld_rate_reg.reg}
set_false_path -from {*|altpcie_a10_hip_pipen1b|wys~ch*_pcs_chnl_hip_clk_out[0].reg} -to {*|altpcie_a10_hip_pipen1b|*altpcie_a10_hip_pllnphy|*g_xcvr_native_insts[*].twentynm_xcvr_native_inst|*twentynm_xcvr_native_inst|*gen_twentynm_hssi_8g_tx_pcs.inst_twentynm_hssi_8g_tx_pcs~tx_clk2_by2_1.reg}
set_false_path -from {*|altpcie_a10_hip_pipen1b|wys~ch*_pcs_chnl_hip_clk_out[0].reg} -to {*|altpcie_a10_hip_pipen1b|*altpcie_a10_hip_pllnphy|*g_xcvr_native_insts[*].twentynm_xcvr_native_inst|*twentynm_xcvr_native_inst|*gen_twentynm_hssi_8g_tx_pcs.inst_twentynm_hssi_8g_tx_pcs~tx_clk2_by4_1.reg}
set_false_path -from {*|altpcie_a10_hip_pipen1b|wys~ch*_pcs_chnl_hip_clk_out[0].reg} -to {*|altpcie_a10_hip_pipen1b|*altpcie_a10_hip_pllnphy|*g_xcvr_native_insts[*].twentynm_xcvr_native_inst|*twentynm_xcvr_native_inst|*gen_twentynm_hssi_common_pld_pcs_interface.inst_twentynm_hssi_common_pld_pcs_interface~pld_8g_eidleinfersel_reg.reg}
}
# END Constraint for Gen 3x2 and up
#create_generated_clock -multiply_by 1 -divide_by 10 \
-source "$clk_pin_prefix_loop|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_pll.g_pll_g3n.lcpll_g3xn|lcpll_g3xn|a10_xcvr_atx_pll_inst|twentynm_hssi_pma_cgb_master_inst|clk_fpll_b" \
-master_clock "$get_clk_prefix|tx_serial_clk" \
-name "$get_clk_prefix|tx_bonding_clocks[0]" \
"$clk_pin_prefix_loop|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_pll.g_pll_g3n.lcpll_g3xn|lcpll_g3xn|a10_xcvr_atx_pll_inst|twentynm_hssi_pma_cgb_master_inst|cpulse_out_bus[0]"
#set_multicycle_path -setup -through [get_pins -compatibility_mode {*pld_rx_data*}] 0
foreach_in_collection mpin [get_pins -compatibility_mode {*pld_rx_data*}] {
set mpin_name [get_pin_info -name $mpin]
if [string match "*altpcie_a10_hip_pipen1b*" $mpin_name] {
set_multicycle_path -setup -through $mpin 0
}
}
set rx_clkouts [list]
for {set i 0} {$i != $stop} {incr i} {
remove_clock "$get_clk_prefix|g_xcvr_native_insts[$i]|rx_clk"
remove_clock "$get_clk_prefix|g_xcvr_native_insts[$i]|rx_clkout"
create_generated_clock -multiply_by 1 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|byte_deserializer_pcs_clk_div_by_4_txclk_reg" \
-master_clock "$get_clk_prefix|tx_bonding_clocks[0]" \
-name "$get_clk_prefix|g_xcvr_native_insts[$i]|rx_clk" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|sta_rx_clk2_by4_1" ;# target
create_generated_clock -multiply_by 1 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|byte_deserializer_pld_clk_div_by_4_txclk_reg" \
-master_clock "$get_clk_prefix|tx_bonding_clocks[0]" \
-name "$get_clk_prefix|g_xcvr_native_insts[$i]|rx_clkout" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|sta_rx_clk2_by4_1_out"
set_clock_groups -exclusive \
-group "$get_clk_prefix|tx_bonding_clocks[0]" \
-group "$get_clk_prefix|g_xcvr_native_insts[$i]|rx_clkout"
set_clock_groups -exclusive \
-group "$get_clk_prefix|tx_bonding_clocks[0]" \
-group "$get_clk_prefix|rx_pcs_clk_div_by_4[$i]"
}
}
}
}
set subsequent_sdc_flag 1 ;#disables subsequent runs of this if-block in other SDCs
} elseif {[get_collection_size $pll_pcie_clock] == 1} { ;#single parent clock
#set prefix [parent_of_clock {tx_serial_clk}]
#set prefix $prefix_checker
set phy_lane0_size 0 ;#Gen 3x1
set phy_lane1_size 0 ;#Gen 3x2
set phy_lane3_size 0 ;#Gen 3x4
set phy_lane7_size 0 ;#Gen 3x8
set phy_lane0 [get_registers -nowarn {*phy_g3x*|g_xcvr_native_insts[0]*}]
set phy_lane1 [get_registers -nowarn {*phy_g3x*|g_xcvr_native_insts[1]*}]
set phy_lane3 [get_registers -nowarn {*phy_g3x*|g_xcvr_native_insts[3]*}]
set phy_lane7 [get_registers -nowarn {*phy_g3x*|g_xcvr_native_insts[7]*}]
set phy_lane0_size [get_collection_size $phy_lane0]
set phy_lane1_size [get_collection_size $phy_lane1]
set phy_lane3_size [get_collection_size $phy_lane3]
set phy_lane7_size [get_collection_size $phy_lane7]
if {$phy_lane7_size > 0} {
set stop 8
} elseif {$phy_lane3_size > 0} {
set stop 4
} elseif {$phy_lane1_size > 0} {
set stop 2
} elseif {$phy_lane0_size > 0} {
set stop 1
} else {
set stop 0
}
set get_clk_prefix $clk_prefix
set get_pin_prefix $clk_pin_prefix
for {set i 0} {$i != $stop} {incr i} {
create_generated_clock -divide_by 1 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|byte_deserializer_pcs_clk_div_by_2_txclk_reg" \
-name "$get_clk_prefix|rx_pcs_clk_div_by_4[$i]" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|sta_rx_clk2_by2_1" ;# target
create_generated_clock -multiply_by 1 -divide_by 1 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_tx_pcs.inst_twentynm_hssi_8g_tx_pcs|byte_serializer_pcs_clk_div_by_2_reg" \
-name "$get_clk_prefix|tx_pcs_clk_div_by_4[$i]" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_tx_pcs.inst_twentynm_hssi_8g_tx_pcs|sta_tx_clk2_by2_1" ;# target
}
remove_clock "$get_clk_prefix|tx_bonding_clocks[0]"
# Constraint for Gen 3x2 and up
if {$phy_lane1_size > 0} {
create_generated_clock -multiply_by 1 -divide_by 5 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_pll.g_pll_g3n.lcpll_g3xn|lcpll_g3xn|a10_xcvr_atx_pll_inst|twentynm_hssi_pma_cgb_master_inst|clk_fpll_*" \
-master_clock "$get_clk_prefix|tx_serial_clk" \
-name "$get_clk_prefix|tx_bonding_clocks[0]" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_pll.g_pll_g3n.lcpll_g3xn|lcpll_g3xn|a10_xcvr_atx_pll_inst|twentynm_hssi_pma_cgb_master_inst|cpulse_out_bus[0]"
set_false_path -from {*|altpcie_a10_hip_pipen1b|wys~ch*_pcs_chnl_hip_clk_out[0].reg} -to {*|altpcie_a10_hip_pipen1b|*altpcie_a10_hip_pllnphy|*g_xcvr_native_insts[*].twentynm_xcvr_native_inst|*twentynm_xcvr_native_inst|*gen_twentynm_hssi_common_pld_pcs_interface.inst_twentynm_hssi_common_pld_pcs_interface~pld_rate_reg.reg}
set_false_path -from {*|altpcie_a10_hip_pipen1b|wys~ch*_pcs_chnl_hip_clk_out[0].reg} -to {*|altpcie_a10_hip_pipen1b|*altpcie_a10_hip_pllnphy|*g_xcvr_native_insts[*].twentynm_xcvr_native_inst|*twentynm_xcvr_native_inst|*gen_twentynm_hssi_8g_tx_pcs.inst_twentynm_hssi_8g_tx_pcs~tx_clk2_by2_1.reg}
set_false_path -from {*|altpcie_a10_hip_pipen1b|wys~ch*_pcs_chnl_hip_clk_out[0].reg} -to {*|altpcie_a10_hip_pipen1b|*altpcie_a10_hip_pllnphy|*g_xcvr_native_insts[*].twentynm_xcvr_native_inst|*twentynm_xcvr_native_inst|*gen_twentynm_hssi_8g_tx_pcs.inst_twentynm_hssi_8g_tx_pcs~tx_clk2_by4_1.reg}
set_false_path -from {*|altpcie_a10_hip_pipen1b|wys~ch*_pcs_chnl_hip_clk_out[0].reg} -to {*|altpcie_a10_hip_pipen1b|*altpcie_a10_hip_pllnphy|*g_xcvr_native_insts[*].twentynm_xcvr_native_inst|*twentynm_xcvr_native_inst|*gen_twentynm_hssi_common_pld_pcs_interface.inst_twentynm_hssi_common_pld_pcs_interface~pld_8g_eidleinfersel_reg.reg}
}
# END Constraint for Gen 3x2 and up
#create_generated_clock -multiply_by 1 -divide_by 10 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_pll.g_pll_g3n.lcpll_g3xn|lcpll_g3xn|a10_xcvr_atx_pll_inst|twentynm_hssi_pma_cgb_master_inst|clk_fpll_b" \
-master_clock "$get_clk_prefix|tx_serial_clk" \
-name "$get_clk_prefix|tx_bonding_clocks[0]" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_pll.g_pll_g3n.lcpll_g3xn|lcpll_g3xn|a10_xcvr_atx_pll_inst|twentynm_hssi_pma_cgb_master_inst|cpulse_out_bus[0]"
#set_multicycle_path -setup -through [get_pins -compatibility_mode {*pld_rx_data*}] 0
foreach_in_collection mpin [get_pins -compatibility_mode {*pld_rx_data*}] {
set mpin_name [get_pin_info -name $mpin]
if [string match "*altpcie_a10_hip_pipen1b*" $mpin_name] {
set_multicycle_path -setup -through $mpin 0
}
}
set rx_clkouts [list]
for {set i 0} {$i != $stop} {incr i} {
remove_clock "$get_clk_prefix|g_xcvr_native_insts[$i]|rx_clk"
remove_clock "$get_clk_prefix|g_xcvr_native_insts[$i]|rx_clkout"
create_generated_clock -multiply_by 1 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|byte_deserializer_pcs_clk_div_by_4_txclk_reg" \
-master_clock "$get_clk_prefix|tx_bonding_clocks[0]" \
-name "$get_clk_prefix|g_xcvr_native_insts[$i]|rx_clk" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|sta_rx_clk2_by4_1" ;# target
create_generated_clock -multiply_by 1 \
-source "$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|byte_deserializer_pld_clk_div_by_4_txclk_reg" \
-master_clock "$get_clk_prefix|tx_bonding_clocks[0]" \
-name "$get_clk_prefix|g_xcvr_native_insts[$i]|rx_clkout" \
"$get_pin_prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x*.phy_g3x*|phy_g3x*|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|sta_rx_clk2_by4_1_out"
set_clock_groups -exclusive \
-group "$get_clk_prefix|tx_bonding_clocks[0]" \
-group "$get_clk_prefix|g_xcvr_native_insts[$i]|rx_clkout"
set_clock_groups -exclusive \
-group "$get_clk_prefix|tx_bonding_clocks[0]" \
-group "$get_clk_prefix|rx_pcs_clk_div_by_4[$i]"
}
} elseif {[get_collection_size $pll_pcie_clock] == 0} {
puts "Could not find a legal PCIe IP Core in the design"
} elseif {$clk_parent_list_length != $clk_pin_prefix_list_length} {
puts "Prefix list from get_clocks does not match prefix list from get_pins"
} else {
puts "No additional clock constraints were added"
}
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
//
// Common functions for transceiver PHY IP
//
// $Header$
//
// PACKAGE DECLARATION
package altera_xcvr_functions;
localparam integer MAX_CHARS = 86; // To accomodate LONG parameter lists.
localparam integer MAX_STRS = 16;
localparam integer MAX_XCVR_CHANNELS = 64;
// Reconfiguration bundle widths per family
localparam integer W_S5_RECONFIG_BUNDLE_TO_XCVR = 70;
localparam integer W_S5_RECONFIG_BUNDLE_FROM_XCVR = 46;
localparam integer W_A5_RECONFIG_BUNDLE_TO_XCVR = 70;
localparam integer W_A5_RECONFIG_BUNDLE_FROM_XCVR = 46;
localparam integer W_S4_RECONFIG_BUNDLE_TO_XCVR = 4;
localparam integer W_S4_RECONFIG_BUNDLE_FROM_XCVR = 17;
localparam integer W_C4_RECONFIG_BUNDLE_TO_XCVR = 4;
localparam integer W_C4_RECONFIG_BUNDLE_FROM_XCVR = 17;
// Reconfiguration bundle widths per family
localparam integer W_S5_RECONFIG_BUNDLE_TO_GXB = W_S5_RECONFIG_BUNDLE_TO_XCVR;
localparam integer W_S5_RECONFIG_BUNDLE_FROM_GXB = W_S5_RECONFIG_BUNDLE_FROM_XCVR;
localparam integer W_A5_RECONFIG_BUNDLE_TO_GXB = W_A5_RECONFIG_BUNDLE_TO_XCVR;
localparam integer W_A5_RECONFIG_BUNDLE_FROM_GXB = W_A5_RECONFIG_BUNDLE_FROM_XCVR;
localparam integer W_S4_RECONFIG_BUNDLE_TO_GXB = W_S4_RECONFIG_BUNDLE_TO_XCVR;
localparam integer W_S4_RECONFIG_BUNDLE_FROM_GXB = W_S4_RECONFIG_BUNDLE_FROM_XCVR;
localparam integer W_C4_RECONFIG_BUNDLE_TO_GXB = W_C4_RECONFIG_BUNDLE_TO_XCVR;
localparam integer W_C4_RECONFIG_BUNDLE_FROM_GXB = W_C4_RECONFIG_BUNDLE_FROM_XCVR;
// convert frequency string into integer Hz. Fractional Hz are truncated
// Must remain a constant function - can't use string.atoi().
function time str2hz (
input [8*MAX_CHARS:1] s
);
integer i;
integer c; // temp char storage for frequency conversion
integer unit_tens; // assume already Hz
integer is_numeric;
integer saw_dot;
reg [8:1] c_dot; // = ".";
reg [8:1] c_space; // = " ";
reg [8:1] c_a; // = 8'h61; //"a";
reg [8:1] c_z; // = 8'h7a; //"z";
reg [8*4:1] s_unit;
reg [8*MAX_CHARS:1] s_shift;
begin
// frequency ratio calculations
str2hz = 0;
unit_tens = 0; // assume already Hz
is_numeric = 1;
saw_dot = 0;
s_unit = "";
// Modelsim optimizer bug forces us to initialize these non-statically
c_dot = ".";
c_space = " ";
c_a = "a";
c_z = "z";
for (i=(MAX_CHARS-1); i>=0; i=i-1) begin
s_shift = (s >> (i*8));
c = s_shift[8:1] & 8'hff;
if (c > 0) begin
//$display("[%d] => '%1s',", i, c);
if (c >= 8'h30 && c <= 8'h39 && is_numeric) begin
str2hz = (str2hz * 10) + (c & 8'h0f);
if (saw_dot) unit_tens = unit_tens - 1; // count digits after decimal point
end else if (c == c_dot) saw_dot = 1;
else if (c != c_space) begin
is_numeric = 0; // stop accepting new numeric digits in value
// if it's a-z, convert to upper case A-Z
if (c >= c_a && c <= c_z) c = (c & 8'h5f); // convert a-z (lower) to A-Z (upper)
s_unit = (s_unit << 8) | c;
end
end
end
//$display("numeric = %d x 10**(%2d), unit = '%0s'", str2hz, unit_tens, s_unit);
// account for frequency unit
if (s_unit == "GHZ" || s_unit == "GBPS") unit_tens = unit_tens + 9; // 10**9
else if (s_unit == "MHZ" || s_unit == "MBPS") unit_tens = unit_tens + 6; // 10**6
else if (s_unit == "KHZ" || s_unit == "KBPS") unit_tens = unit_tens + 3; // 10**3
else if (s_unit != "HZ" && s_unit != "BPS") begin
$display("Invalid frequency unit '%0s', assuming %d x 10**(%2d) 'Hz'", s_unit, str2hz, unit_tens);
end
//$display("numeric in Hz = %d x 10**(%2d)", str2hz, unit_tens);
// align numeric to Hz
if (unit_tens < 0) begin
//str2hz = str2hz / (10**(-unit_tens));
for (i=0; i>unit_tens; i=i-1) begin
str2hz = str2hz / 10;
end
end else begin
//str2hz = str2hz * (10**unit_tens);
for (i=0; i<unit_tens; i=i+1) begin
str2hz = str2hz * 10;
end
end
//$display("%d Hz", str2hz);
end
endfunction
// convert integer Hz to a frequency string
// integer Hz as type time, and the frequency string will use MHz units
// Must remain a constant function - can't use $sformat or string.itoa().
function [MAX_CHARS*8-1:0] hz2str (
input time hz
);
integer pos;
integer f_unit; // 10**f_unit is offset from Hz for larger unit
time hz_mod_10;
begin
hz2str = "0.000000 MHz"; // minimum string value
f_unit = 6; // MHz offsets Hz value by 6 decimal digits
// convert time back to string with frequency units
// char positions 3 to 0 are used by " MHz", so start with digits at pos 4
for (pos = 4; pos < MAX_CHARS && hz > 0; pos = pos + 1) begin
if (f_unit == 0) begin
hz2str[pos*8 +: 8] = 8'h2e; // add "." character
pos = pos + 1;
end
f_unit = f_unit - 1;
hz_mod_10 = (hz % 10);
hz2str[pos*8 +: 8] = hz_mod_10[7:0] | 8'h30;
hz = hz / 10;
//$display("hz2str() => so far '%s', pos (%d), f_unit(%d) ", hz2str, pos, f_unit);
end
//$display("hz2str() returns '%s'", hz2str);
end
endfunction
// Convert a string to an integer
// Uses pre-existing str2hz function
function integer str2int(
input [MAX_CHARS*8-1:0] instring
);
time temp;
temp = str2hz(instring); // str2hz assume Hertz as default unit. Don't need to add 'Hz' to input.
str2int = temp[31:0];
endfunction
// Convert an integer to a string
function [MAX_CHARS*8-1:0] int2str(
input integer in_int
);
integer i;
integer this_char;
i = 0;
int2str = "";
do
begin
this_char = (in_int % 10) + 48;
int2str[i*8+:8] = this_char[7:0];
i=i+1;
in_int = in_int / 10;
end
while(in_int > 0);
endfunction
// function to convert at most 40-bit long string to binary
function [39 : 0] m_str_to_bin;
input [40*8 : 1] s;
reg [40*8 : 1] reg_s;
reg [40:1] res;
integer m;
begin
reg_s = s;
for (m = 40; m > 0; m = m-1 )
begin
res[m] = reg_s[313];
reg_s = reg_s << 8;
end
m_str_to_bin = res;
end
endfunction
//////////////////////////////
// Convert the argument string to a 64-bit binary value
// @hex_str The string to be converted specified as an ASCII hexadecimal string
function [63:0] m_hex_to_bin (
input [8*MAX_CHARS-1:0] hex_str
);
integer i;
reg [63:0] out; // = 64'h0000_0000_0000_0000;
reg [7:0] this_char;
begin
out = 64'h0000_0000_0000_0000;
for(i=0; i<16; i=i+1) begin
this_char = hex_str[i*8+:8];
if(this_char >= 48 && this_char <= 57)
out[i*4+:4] = this_char - 48;
else if(this_char >= 65 && this_char <= 70)
out[i*4+:4] = this_char - 55;
else if(this_char >= 97 && this_char <= 102)
out[i*4+:4] = this_char - 87;
else begin
out[i*4+:4] = 0;
end
end
end
m_hex_to_bin = out;
endfunction
////////////////////////////////////////////////////////////////////
// Verify that the string value is contained in the legal set.
//
// The 'set' can consist of a single string with no delimiters, e.g. "individual",
// or multiple values, separated by commas, and surrounded by parens, e.g. "(one,two,three,four,five)"
//
// Returns 1 if the value is in the set, and 0 otherwise
function integer is_in_legal_set(
input [MAX_CHARS*8-1:0] value,
input [MAX_STRS*MAX_CHARS*8-1:0] set
);
if (value == "<auto_any>")
is_in_legal_set = 1;
else if (value == "<auto_single>")
is_in_legal_set = (set[7:0] == 8'h29) ? 0 : 1; // 8'h29 is closing parenthesis char
else if (value == set)
is_in_legal_set = 1; // value matches single value in set
else begin
// check value against each in set
integer close_pos; // end of string marker can be comma or closing paren
integer open_pos; // open paren is start of set, if appropriate
reg [MAX_STRS*MAX_CHARS*8-1:0] legalstr;
is_in_legal_set = 0;
open_pos = MAX_STRS*MAX_CHARS-1;
// Remove closing parenthesis if exists
if(set[7:0] == 8'h29) begin
set = (set >> 8);
set[(MAX_STRS*MAX_CHARS*8-1)-:8] = 8'h00;
end
// look for first non-null and non open paren character
while (open_pos > 0 && (set[open_pos*8 +: 8] == 8'h00 || set[open_pos*8 +: 8] == 8'h28)) // look for first non-null
open_pos = open_pos - 1;
while (is_in_legal_set == 0 && open_pos >= 0) begin
close_pos = open_pos;
while (close_pos > 0
&& set[close_pos*8 +: 8] != 8'h2c) // look for comma (8'h2c)
close_pos = close_pos - 1;
if (close_pos >= 0) begin
close_pos = close_pos == 0 ? 0 : close_pos + 1;
legalstr = ((set & ((1'b1 << open_pos*8+8)-1)) >> close_pos*8);
if (value == legalstr)
is_in_legal_set = 1;
end
open_pos = close_pos-2; // prepare to look for next legal string
end
end
//$display("is_in_legal_set(): returns %d", is_in_legal_set);
endfunction
// Accepts a string list of comma seperated numbers and returns a binary
// field where each bit indicates whether the index corresponding to that bit
// was found in the legal set.
//
// @param count - The number of integer indexes to check for in the set
// or the highest integer minus 1.
// @param set - The list containing the integer values to search for
// @return - A bitfield where each bit indicates whether the corresponding
// integer was found in the legal set.
function [MAX_XCVR_CHANNELS-1:0] map_numerical_is_in_legal_set(
input integer count,
input [MAX_STRS*MAX_CHARS*8-1:0] set
);
integer index;
reg [MAX_XCVR_CHANNELS-1:0] retval;
// Validate count parameter
if(count > MAX_XCVR_CHANNELS)
$display("Error: [map_numerical_is_in_legal_set]: Invalid value for count: %0d",count);
map_numerical_is_in_legal_set = {MAX_XCVR_CHANNELS{1'b0}};
retval = {MAX_XCVR_CHANNELS{1'b0}};
for(index = 0; index < count; index = index + 1) begin
if(is_in_legal_set(int2str(index),set))
retval = retval | (({MAX_XCVR_CHANNELS{1'b0}} | 1'b1) << index);
end
map_numerical_is_in_legal_set = retval;
endfunction
// Accepts a string list of comma seperated numbers and returns a binary
// field where each byte contains the corresponding number found in the
// list.
//
// @param count - The number of elements in the list.
// @param set - The list containing the integer values.
// @return - A bitfield where each byte contains the corresponding number found
// at that location in the list.
function [MAX_XCVR_CHANNELS*8-1:0] map_numerical_legal_set(
input integer count,
input [MAX_STRS*MAX_CHARS*8-1:0] set
);
integer index;
reg [MAX_XCVR_CHANNELS-1:0] retval;
reg [MAX_CHARS*8-1:0] str_val;
reg [7:0] int_val;
// Validate count parameter
if(count > MAX_XCVR_CHANNELS || count > 256)
$display("Error: [map_numerical_legal_set]: Invalid value for count: %0d",count);
map_numerical_legal_set = {MAX_XCVR_CHANNELS{8'd0}};
retval = {MAX_XCVR_CHANNELS{8'd0}};
for(index = 0; index < count; index = index + 1) begin
str_val = get_value_at_index(index,set);
if(str_val != "NA") begin
int_val = str2int(str_val);
if(int_val > 255)
$display("Error: [map_numerical_legal_set]: Invalid string contains non-numerical item or value:%0d",int_val);
else begin
retval = retval | ( ( {MAX_XCVR_CHANNELS{8'd0}} | int_val ) << (index * 8));
end
end
end
map_numerical_legal_set = retval;
endfunction
// Accepts a comma separated list of string values and returns the element
// found at the specified index. If the index is invalid, "NA" is returned
//
// @param index - The index of the value to return within "set"
// @param set - A comma separated list of string values. The entire list may
// be surrounded by parenthesis("(item0,item1,item2)")
function [MAX_CHARS*8-1:0] get_value_at_index(
input integer index,
input [MAX_STRS*MAX_CHARS*8-1:0] set
);
// check value against each in set
integer close_pos; // end of string marker can be comma or closing paren
integer open_pos; // open paren is start of set, if appropriate
reg [MAX_STRS*MAX_CHARS*8-1:0] legalstr;
integer cur_index;
get_value_at_index = "";
legalstr = "NA";
cur_index = 0;
open_pos = MAX_STRS*MAX_CHARS-1;
// Remove closing parenthesis if exists
if(set[7:0] == 8'h29) begin
set = (set >> 8);
set[(MAX_STRS*MAX_CHARS*8-1)-:8] = 8'h00;
end
// Find the start of the string
while (open_pos >= 1 && (set[open_pos*8 +: 8] == 8'h00 || set[open_pos*8 +: 8] == 8'h28)) // look for first non-null
open_pos = open_pos - 1;
// Iterate through list until the string is found or we've reached the end of the list
while (legalstr == "NA" && open_pos >= 0 && cur_index <= index) begin
close_pos = open_pos;
// Move the close iterator to the end of the current value (or end of string)
while (close_pos > 0
&& set[close_pos*8 +: 8] != 8'h2c) // look for comma (8'h2c)
close_pos = close_pos - 1;
if (close_pos >= 0) begin
close_pos = close_pos == 0 ? 0 : close_pos + 1;
if(index == cur_index) begin
legalstr = ((set & ((1'b1 << open_pos*8+8)-1)) >> close_pos*8);
end
open_pos = close_pos-2; // prepare to look for next legal string
end
cur_index = cur_index + 1;
end
cur_index = 0;
while(legalstr[cur_index*8+:8] != 0) begin
get_value_at_index[cur_index*8+:8] = legalstr[cur_index*8+:8];
cur_index = cur_index + 1;
end
//$display("is_in_legal_set(): returns %d", is_in_legal_set);
endfunction
// The goal was to return one of the values, does not matter which one.
// ~45 times faster than get_value_at_index( 0, set );
function [MAX_CHARS*8-1:0] get_first_enum_value( input [MAX_STRS*MAX_CHARS*8-1:0] set );
int start_pos, cur_idx;
bit [7:0] cur_set_char;
// Ensure null-terminating the string.
// MODIFIED: Work around for a QuestaSim vopt bug: set[(MAX_STRS*MAX_CHARS*8-8) +: 8 ] = 8'h00;
set [ ( MAX_STRS * MAX_CHARS * 8 -1) : ( MAX_STRS * MAX_CHARS * 8 - 8) ] = 8 'h00 ;
start_pos = set[7:0] == 8'h29 ? 8 : 0;
cur_idx = 0;
get_first_enum_value = "";
forever
begin
cur_set_char = set[ cur_idx + start_pos +: 8 ];
// comma, par or 0
if ( cur_set_char == 8'h2c || cur_set_char == 8'h28 || cur_set_char == 8'h00 )
break;
get_first_enum_value[ cur_idx +: 8 ] = cur_set_char;
cur_idx = cur_idx + 8;
end
// get_first_enum_value = get_value_at_index( 0, set );
endfunction
// This functions is ~12 times faster than is_in_legal_set
function integer is_enum_in_legal_set( input [MAX_CHARS*8-1:0] value, input [MAX_STRS*MAX_CHARS*8-1:0] set );
if ( value == "<auto_any>" )
return 1;
else if (value == "<auto_single>")
return (set[7:0] == 8'h29) ? 0 : 1; // 8'h29 is closing parenthesis char
else if (value == set)
return 1; // value matches single value in set
else
begin
// ')'
int set_pos;
set_pos = 0;
if ( set[7:0] == 8'h29 )
set_pos = 8;
// Ensure null-terminating the string.
set[(MAX_STRS*MAX_CHARS*8-8) +: 8 ] = 8'h00;
forever
begin
int cur_cmp_len;
cur_cmp_len = 0;
// $display( "set_pos ", set_pos/8 );
forever
begin
int cur_val_char, cur_set_char;
cur_val_char = value[ cur_cmp_len +: 8 ];
cur_set_char = set[ set_pos +: 8 ];
// $display( "comparing ", set_pos/8, cur_cmp_len/8, " " , value[ cur_cmp_len +: 8 ], " ", set[ set_pos +: 8 ] );
if ( cur_val_char == 0 )
// The end of value reached, check whether set has comma, par or 0
if ( cur_set_char == 8'h2c || cur_set_char == 8'h28 || cur_set_char == 8'h00 )
return 1;
if ( cur_val_char != cur_set_char )
break;
cur_cmp_len = cur_cmp_len + 8;
set_pos = set_pos + 8;
end
forever
begin
int cur_set_char;
cur_set_char = set[ set_pos +: 8 ];
// $display( "skipping ", set_pos/8 );
// ','
if ( cur_set_char == 8'h2c )
begin
set_pos = set_pos + 8;
break;
end
if ( cur_set_char == 8'h00 )
return 0;
set_pos = set_pos + 8;
end
end
end
endfunction
// The first parameter is just a number, NOT a string
function integer is_numeric_in_legal_set( input [MAX_CHARS*8-1:0] value, input [MAX_STRS*MAX_CHARS*8-1:0] set );
is_numeric_in_legal_set = 1;
endfunction
// AP stubs --- end
////////////////////////////////////////////////////////////////////////
// Returns ceil_log2() value
localparam integer MAX_PRECISION = 32; // VCS requires this declaration outside the function
function integer ceil_log2;
input [MAX_PRECISION-1:0] input_num;
integer i;
reg [MAX_PRECISION-1:0] try_result;
begin
i = 0;
try_result = 1;
while ((try_result << i) < input_num && i < MAX_PRECISION)
i = i + 1;
ceil_log2 = i;
end
endfunction
////////////////////////////////////////////////////////////////////
// Return the number of bits required to represent an integer
// E.g. 0->1; 1->1; 2->2; 3->2 ... 31->5; 32->6
//
function integer clogb2;
input [MAX_PRECISION-1:0] input_num;
begin
for (clogb2=0; input_num>0 && clogb2<MAX_PRECISION; clogb2=clogb2+1)
input_num = input_num >> 1;
if(clogb2 == 0)
clogb2 = 1;
end
endfunction
////////////////////////////////////////////////////////////////////
// Return current device family string for display purposes
`ifndef XCVR_DEV_FAM
`ifdef ALTERA_RESERVED_QIS_FAMILY
`define XCVR_DEV_FAM `ALTERA_RESERVED_QIS_FAMILY // synthesis: use QIS-defined value
`else
`define XCVR_DEV_FAM device_family // simulation: use passed-in value
`endif
`endif
function [MAX_CHARS*8-1:0] current_device_family (
input [MAX_CHARS*8-1:0] device_family
);
current_device_family = `XCVR_DEV_FAM;
endfunction
////////////////////////////////////////////////////////////////////
// Match device family against standard family name strings
//
// Returns 1 if the names feature is present in the given device family
function integer has_s4_style_hssi (
input [MAX_CHARS*8-1:0] device_family
);
has_s4_style_hssi = ( (`XCVR_DEV_FAM == "Stratix IV")
|| (`XCVR_DEV_FAM == "Arria II")
|| (`XCVR_DEV_FAM == "Cyclone IV GX") // not exact, but close enough
|| (`XCVR_DEV_FAM == "Arria II GX")
|| (`XCVR_DEV_FAM == "Arria II GZ")
|| (`XCVR_DEV_FAM == "HardCopy IV")
) ? 1 : 0;
endfunction
////////////////////////////////////////////////////////////////////
// Match device family against standard family name strings
//
// Returns 1 if the names feature is present in the given device family
function integer has_s5_style_hssi (
input [MAX_CHARS*8-1:0] device_family
);
has_s5_style_hssi = ( (`XCVR_DEV_FAM == "Stratix V") || (`XCVR_DEV_FAM == "Arria V GZ")
) ? 1 : 0;
endfunction
////////////////////////////////////////////////////////////////////
// Match device family against standard family name strings
//
// Returns 1 if the names feature is present in the given device family
function integer has_a5_style_hssi (
input [MAX_CHARS*8-1:0] device_family
);
has_a5_style_hssi = ( (`XCVR_DEV_FAM == "Arria V")
) ? 1 : 0;
endfunction
////////////////////////////////////////////////////////////////////
// Match device family against standard family name strings
//
// Returns 1 if the names feature is present in the given device family
function integer has_c5_style_hssi (
input [MAX_CHARS*8-1:0] device_family
);
has_c5_style_hssi = ( (`XCVR_DEV_FAM == "Cyclone V")
) ? 1 : 0;
endfunction
////////////////////////////////////////////////////////////////////
// Match device family against standard family name strings
//
// Returns 1 if the names feature is present in the given device family
function integer has_c4_style_hssi (
input [MAX_CHARS*8-1:0] device_family
);
has_c4_style_hssi = ( (`XCVR_DEV_FAM == "Cyclone IV GX")
) ? 1 : 0;
endfunction
////////////////////////////////////////////////////////////////////
// Get reconfig_to_gxb bundle width for specified device family
//
// Returns 0 if the device_family argument is invalid, otherwise
// it returns the width of the reconfig_to_gxb bundle for that family
function integer get_reconfig_to_gxb_width (
input [MAX_CHARS*8-1:0] device_family
);
if (has_s5_style_hssi(device_family) || has_a5_style_hssi(device_family) || has_c5_style_hssi(device_family))
get_reconfig_to_gxb_width = W_S5_RECONFIG_BUNDLE_TO_XCVR;
else if (has_s4_style_hssi(device_family))
get_reconfig_to_gxb_width = W_S4_RECONFIG_BUNDLE_TO_XCVR;
else if (has_c4_style_hssi(device_family))
get_reconfig_to_gxb_width = W_C4_RECONFIG_BUNDLE_TO_XCVR;
else
get_reconfig_to_gxb_width = 0;
endfunction
////////////////////////////////////////////////////////////////////
// Get reconfig_from_gxb bundle width for specified device family
//
// Returns 0 if the device_family argument is invalid, otherwise
// it returns the width of the reconfig_from_gxb bundle for that family
function integer get_reconfig_from_gxb_width (
input [MAX_CHARS*8-1:0] device_family
);
if (has_s5_style_hssi(device_family) || has_a5_style_hssi(device_family) || has_c5_style_hssi(device_family))
get_reconfig_from_gxb_width = W_S5_RECONFIG_BUNDLE_FROM_XCVR;
else if (has_s4_style_hssi(device_family))
get_reconfig_from_gxb_width = W_S4_RECONFIG_BUNDLE_FROM_XCVR;
else if (has_c4_style_hssi(device_family))
get_reconfig_from_gxb_width = W_C4_RECONFIG_BUNDLE_FROM_XCVR;
else
get_reconfig_from_gxb_width = 0;
endfunction
////////////////////////////////////////////////////////////////////
// Get reconfig_to_xcvr total port width for specified device family
//
// Returns 0 if the device_family argument is invalid, otherwise
// it returns the width of the reconfig_to_xcvr port for that family
function integer get_reconfig_to_width (
input [MAX_CHARS*8-1:0] device_family,
input integer reconfig_interfaces
);
if (has_s5_style_hssi(device_family) || has_a5_style_hssi(device_family) || has_c5_style_hssi(device_family))
get_reconfig_to_width = get_s5_reconfig_to_width(reconfig_interfaces);
else if (has_s4_style_hssi(device_family))
get_reconfig_to_width = W_S4_RECONFIG_BUNDLE_TO_XCVR;
else if (has_c4_style_hssi(device_family))
get_reconfig_to_width = W_C4_RECONFIG_BUNDLE_TO_XCVR;
else
get_reconfig_to_width = 0;
endfunction
////////////////////////////////////////////////////////////////////
// Get reconfig_to_xcvr total port width for Stratix V device family
//
function integer get_s5_reconfig_to_width (
input integer reconfig_interfaces
);
get_s5_reconfig_to_width = reconfig_interfaces * get_reconfig_to_gxb_width("Stratix V");
endfunction
////////////////////////////////////////////////////////////////////
// Get reconfig_from_xcvr total port width for specified device family
//
// Returns 0 if the device_family argument is invalid, otherwise
// it returns the width of the reconfig_from_xcvr port for that family
function integer get_reconfig_from_width (
input [MAX_CHARS*8-1:0] device_family,
input integer reconfig_interfaces
);
if (has_s5_style_hssi(device_family) || has_a5_style_hssi(device_family) || has_c5_style_hssi(device_family))
get_reconfig_from_width = reconfig_interfaces * get_reconfig_from_gxb_width(device_family);
else if (has_s4_style_hssi(device_family))
get_reconfig_from_width = reconfig_interfaces * get_reconfig_from_gxb_width(device_family);
else if (has_c4_style_hssi(device_family))
get_reconfig_from_width = reconfig_interfaces * get_reconfig_from_gxb_width(device_family);
else
get_reconfig_from_width = 0;
endfunction
////////////////////////////////////////////////////////////////////
// Get reconfig_from_xcvr total port width for Stratix V device family
//
function integer get_s5_reconfig_from_width (
input integer reconfig_interfaces
);
get_s5_reconfig_from_width = reconfig_interfaces * get_reconfig_from_gxb_width("Stratix V");
endfunction
////////////////////////////////////////////////////////////////////
// Get number of reconfig interfaces for Custom PHY
// NOTE - !!Has since been used by other PHY IP!!
//
// @param device_family - Desired device family
// @param operation_mode - "Duplex","Rx","Tx" or "duplex", "rx_only", "tx_only" in 10gbaser
// @param lanes - Number of channels
// @param plls - Number of TX plls (per channel)
// @param bonded_group_size - Size of bonded group (1 or lanes)
// @param data_path_type - Abuse of function by overloading for ATT support
// - Carry on the abuse
//
// @return 0 if the device_family argument is invalid, otherwise
// it returns the width of the reconfig_from_xcvr port for that family
function integer get_custom_reconfig_interfaces(
input [MAX_CHARS*8-1:0] device_family,
input [MAX_CHARS*8-1:0] operation_mode,
input integer lanes,
input integer plls,
input integer bonded_group_size,
input [MAX_CHARS*8-1:0] data_path_type = "",
input [MAX_CHARS*8-1:0] bonded_mode = "xN"
);
integer reconfig_interfaces;
reconfig_interfaces = 0;
if (has_s5_style_hssi(device_family) || has_a5_style_hssi(device_family) || has_c5_style_hssi(device_family)) begin
// ATT specific calculations
if( data_path_type == "ATT" ) begin
if((operation_mode == "RX_ONLY") || (operation_mode == "rx_only") || (operation_mode == "Rx") || (operation_mode == "RX") || (operation_mode == "rx")) begin
reconfig_interfaces = lanes;
end else if((operation_mode == "TX_ONLY") || (operation_mode == "tx_only") || (operation_mode == "Tx") || (operation_mode == "TX") || (operation_mode == "tx")) begin
reconfig_interfaces = 2*lanes;
end else begin
reconfig_interfaces = 3*lanes;
end
end else begin
// Custom PHY calculations
if((operation_mode == "RX") || (operation_mode == "Rx") || (operation_mode == "rx_only"))
reconfig_interfaces = lanes;
else begin
bonded_group_size = (bonded_mode == "fb_compensation") ? 1 :
(bonded_mode == "non_bonded") ? 1 : bonded_group_size;
reconfig_interfaces = lanes+(plls*(lanes/bonded_group_size));
end
end
end
get_custom_reconfig_interfaces = reconfig_interfaces;
endfunction
////////////////////////////////////////////////////////////////////
// Get reconfig_to_xcvr total port width for Custom PHY
//
// @param device_family - Desired device family
// @param operation_mode - "Duplex","Rx","Tx" or "duplex", "rx_only", "tx_only" in 10gbaser
// @param lanes - Number of transceiver channels
// @param plls - Number of plls per bonded group
// @param bonded_group_size - Size of bonded group (1 or lanes)
// @param data_path_type - Abuse of function to support ATT
//
// @return - 0 if the device_family argument is invalid, otherwise
// it returns the width of the reconfig_from_xcvr port for that family
function integer get_custom_reconfig_to_width(
input [MAX_CHARS*8-1:0] device_family,
input [MAX_CHARS*8-1:0] operation_mode,
input integer lanes,
input integer plls,
input integer bonded_group_size,
input [MAX_CHARS*8-1:0] data_path_type = "",
input [MAX_CHARS*8-1:0] bonded_mode = "xN"
);
integer reconfig_interfaces;
reconfig_interfaces = get_custom_reconfig_interfaces(device_family,operation_mode,lanes,plls,bonded_group_size, data_path_type, bonded_mode );
get_custom_reconfig_to_width = get_s5_reconfig_to_width(reconfig_interfaces);
endfunction
////////////////////////////////////////////////////////////////////
// Get reconfig_from_xcvr total port width for Custom PHY
//
// @param device_family - Desired device family
// @param operation_mode - "Duplex","Rx","Tx" or "duplex", "rx_only", "tx_only" in 10gbaser
// @param lanes - Number of transceiver channels
// @param plls - Number of plls per bonded group
// @param bonded_group_size - Size of bonded group (1 or lanes)
// @param data_path_type - Abuse of function to support ATT
//
// @return - 0 if the device_family argument is invalid, otherwise
// it returns the width of the reconfig_from_xcvr port for that family
function integer get_custom_reconfig_from_width(
input [MAX_CHARS*8-1:0] device_family,
input [MAX_CHARS*8-1:0] operation_mode,
input integer lanes,
input integer plls,
input integer bonded_group_size,
input [MAX_CHARS*8-1:0] data_path_type = "",
input [MAX_CHARS*8-1:0] bonded_mode = "xN"
);
integer reconfig_interfaces;
reconfig_interfaces = get_custom_reconfig_interfaces(device_family,operation_mode,lanes,plls,bonded_group_size, data_path_type, bonded_mode);
get_custom_reconfig_from_width = get_s5_reconfig_from_width(reconfig_interfaces);
endfunction
////////////////////////////////////////////////////////////////////
// Start Interlaken Specific functions for calculating reconfig interfaces
// and reconfig_to_gxb, reconfig_from_gxb widths
////////////////////////////////////////////////////////////////////
// Get number of reconfig interfaces for Interlaken PHY
//
// @param device_family - Desired device family
// @param operation_mode - "Duplex","Rx","Tx" or "duplex", "rx_only", "tx_only" in 10gbaser
// Returns 0 if the device_family argument is invalid, otherwise
// it returns the width of the reconfig_from_xcvr port for that family
function integer get_interlaken_reconfig_interfaces(
input [MAX_CHARS*8-1:0] device_family,
input [MAX_CHARS*8-1:0] operation_mode,
input integer bonded_group_size,
input integer lanes
);
integer reconfig_interfaces;
integer xslices;
integer xremain;
integer totalplls;
reconfig_interfaces = 0;
if (has_s5_style_hssi(device_family) || has_a5_style_hssi(device_family) || has_c5_style_hssi(device_family)) begin
if((operation_mode == "RX") || (operation_mode == "Rx") || (operation_mode == "rx_only"))
reconfig_interfaces = lanes;
else begin
xslices = lanes/bonded_group_size;
xremain = lanes % bonded_group_size;
if (xremain >0)
totalplls = xslices +1;
else
totalplls = xslices;
reconfig_interfaces = lanes+totalplls;
end // else: !if((operation_mode == "RX") || (operation_mode == "Rx") || (operation_mode == "rx_only"))
end // if (has_s5_style_hssi(device_family))
get_interlaken_reconfig_interfaces = reconfig_interfaces;
endfunction
////////////////////////////////////////////////////////////////////
// Get reconfig_to_xcvr total port width for Interlaken PHY
//
// @param device_family - Desired device family
// @param operation_mode - "Duplex","Rx","Tx" or "duplex", "rx_only", "tx_only" in 10gbaser
// @param lanes - Number of transceiver channels
// Returns 0 if the device_family argument is invalid, otherwise
// it returns the width of the reconfig_from_xcvr port for that family
function integer get_interlaken_reconfig_to_width(
input [MAX_CHARS*8-1:0] device_family,
input [MAX_CHARS*8-1:0] operation_mode,
input integer bonded_group_size,
input integer lanes
);
integer reconfig_interfaces;
reconfig_interfaces = get_interlaken_reconfig_interfaces(device_family,operation_mode,bonded_group_size,lanes);
get_interlaken_reconfig_to_width = get_s5_reconfig_to_width(reconfig_interfaces);
endfunction
////////////////////////////////////////////////////////////////////
// Get reconfig_from_xcvr total port width for Custom PHY
//
// @param device_family - Desired device family
// @param operation_mode - "Duplex","Rx","Tx" or "duplex", "rx_only", "tx_only" in 10gbaser
// Returns 0 if the device_family argument is invalid, otherwise
// it returns the width of the reconfig_from_xcvr port for that family
function integer get_interlaken_reconfig_from_width(
input [MAX_CHARS*8-1:0] device_family,
input [MAX_CHARS*8-1:0] operation_mode,
input integer bonded_group_size,
input integer lanes
);
integer reconfig_interfaces;
reconfig_interfaces = get_interlaken_reconfig_interfaces(device_family,operation_mode,bonded_group_size,lanes);
get_interlaken_reconfig_from_width = get_s5_reconfig_from_width(reconfig_interfaces);
endfunction
// End Interlaken specific functions
////////////////////////////////////////////////////////////////////
endpackage
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// DESCRIPTION
//
// This is a single clock version of dcfifo_mlab. It is suitable for replacing smaller instances of LPM SCFIFO.
// The maximum depth is 31. The implementation follows dcfifo_mlab very closely, with the cross
// domain hardening removed.
//
// Where possible connect the "used words" outputs to create partial full and empty signals. These can be
// pipelined and facilitate easy timing closure better than the full and empty which have tighter functional
// requirements.
//
//
//
// Where possible set these parameters to 0 to improve read and write request speed.
//
// parameter PREVENT_OVERFLOW = 1'b1, // ignore requests that would cause overflow
//
// parameter PREVENT_UNDERFLOW = 1'b1, // ignore requests that would cause underflow
//
// With prevention disabled the FIFO will wrap during an underflow or overflow, and then resume
// coherent operation from that illegally entered state.
//
// CONFIDENCE
// This has been used successfully in multiple Altera wireline projects
//
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_a10_gbfifo #(
parameter TARGET_CHIP = 5, // 1 S4, 2 S5,
parameter SIM_EMULATE = 1'b0, // simulation equivalent, only for S5 right now
parameter WIDTH = 80, // typical 20,40,60,80
parameter PREVENT_OVERFLOW = 1'b1, // ignore requests that would cause overflow
parameter PREVENT_UNDERFLOW = 1'b1, // ignore requests that would cause underflow
parameter RAM_GROUPS = (WIDTH < 20) ? 1 : (WIDTH / 20), // min 1, WIDTH must be divisible by RAM_GROUPS
parameter GROUP_RADDR = (WIDTH < 20) ? 1'b0 : 1'b1, // 1 to duplicate RADDR per group as well as WADDR
parameter FLAG_DUPES = 1, // if > 1 replicate full / empty flags for fanout balancing
parameter ADDR_WIDTH = 5, // 4 or 5
parameter DISABLE_USED = 1'b0
)(
input clk,
input sclr,
input [WIDTH-1:0] wdata,
input wreq,
output [FLAG_DUPES-1:0] full, // optional duplicates for loading
output [WIDTH-1:0] rdata,
input rreq,
output [FLAG_DUPES-1:0] empty, // optional duplicates for loading
output [ADDR_WIDTH-1:0] used
);
// synthesis translate off
initial begin
if (WIDTH > 20 && (RAM_GROUPS * 20 != WIDTH)) begin
$display ("Error in scfifo_mlab parameters - the physical width is a multiple of 20, this needs to match");
$stop();
end
end
// synthesis translate on
////////////////////////////////////
// rereg sclr
////////////////////////////////////
reg sclr_int = 1'b1 /* synthesis preserve */;
always @(posedge clk) begin
sclr_int <= sclr;
end
////////////////////////////////////
// addr pointers
////////////////////////////////////
wire winc;
wire rinc;
wire [RAM_GROUPS*ADDR_WIDTH-1:0] rptr;
reg [ADDR_WIDTH-1:0] wcntr = {ADDR_WIDTH{1'b0}} /* synthesis preserve */;
reg [ADDR_WIDTH-1:0] rcntr = {ADDR_WIDTH{1'b0}} /* synthesis preserve */;
always @(posedge clk) begin
if (sclr_int) wcntr <= {ADDR_WIDTH{1'b0}} | 1'b1;
else if (winc) wcntr <= wcntr + 1'b1;
if (sclr_int) rcntr <= {ADDR_WIDTH{1'b0}} | (GROUP_RADDR ? 2'd2 : 2'd1);
else if (rinc) rcntr <= rcntr + 1'b1;
end
// optional duplication of the read address
generate
if (GROUP_RADDR) begin : gr
reg [RAM_GROUPS*ADDR_WIDTH-1:0] rptr_r = {RAM_GROUPS{{ADDR_WIDTH{1'b0}} | 1'b1}}
/* synthesis preserve */;
always @(posedge clk) begin
if (sclr_int) rptr_r <= {RAM_GROUPS{{ADDR_WIDTH{1'b0}} | 1'b1}} ;
else if (rinc) rptr_r <= {RAM_GROUPS{rcntr}};
end
assign rptr = rptr_r;
end
else begin : ngr
assign rptr = {RAM_GROUPS{rcntr}};
end
endgenerate
//////////////////////////////////////////////////
// adjust pointers for RAM latency
//////////////////////////////////////////////////
reg [ADDR_WIDTH-1:0] rptr_completed = {ADDR_WIDTH{1'b0}};
always @(posedge clk) begin
if (sclr_int) begin
rptr_completed <= {ADDR_WIDTH{1'b0}};
end
else begin
if (rinc) rptr_completed <= rptr[ADDR_WIDTH-1:0];
end
end
reg [ADDR_WIDTH-1:0] wptr_d = {ADDR_WIDTH{1'b0}};
reg [ADDR_WIDTH-1:0] wptr_completed = {ADDR_WIDTH{1'b0}};
wire [ADDR_WIDTH-1:0] wptr_d_w = winc ? wcntr : wptr_d /* synthesis keep */;
always @(posedge clk) begin
if (sclr_int) begin
wptr_d <= {ADDR_WIDTH{1'b0}};
wptr_completed <= {ADDR_WIDTH{1'b0}};
end
else begin
wptr_d <= wptr_d_w;
wptr_completed <= wptr_d;
end
end
//////////////////////////////////////////////////
// compare pointers
//////////////////////////////////////////////////
genvar i;
generate
for (i=0; i<FLAG_DUPES; i=i+1) begin : fg
//assign full[i] = ~|(rptr_completed ^ wcntr);
//assign empty[i] = ~|(rptr_completed ^ wptr_completed);
altpcie_a10_gbfifo_eq_5_ena eq0 (
.da(5'h0 | rptr_completed),
.db(5'h0 | wcntr),
.ena(1'b1),
.eq(full[i])
);
defparam eq0 .TARGET_CHIP = TARGET_CHIP; // 0 generic, 1 S4, 2 S5
altpcie_a10_gbfifo_eq_5_ena eq1 (
.da(5'h0 | rptr_completed),
.db(5'h0 | wptr_completed),
.ena(1'b1),
.eq(empty[i])
);
defparam eq1 .TARGET_CHIP = TARGET_CHIP; // 0 generic, 1 S4, 2 S5
end
endgenerate
//////////////////////////////////////////////////
// storage array - split in addr reg groups
//////////////////////////////////////////////////
reg [ADDR_WIDTH*RAM_GROUPS-1:0] waddr_reg = {(RAM_GROUPS*ADDR_WIDTH){1'b0}} /* synthesis preserve */;
reg [WIDTH-1:0] wdata_reg = {WIDTH{1'b0}} /* synthesis preserve */;
wire [WIDTH-1:0] ram_q;
reg [WIDTH-1:0] rdata_reg = {WIDTH{1'b0}};
wire [ADDR_WIDTH-1:0] wptr_inv = wcntr ^ 1'b1;
always @(posedge clk) begin
waddr_reg <= {RAM_GROUPS{wptr_inv}};
wdata_reg <= wdata;
end
generate
for (i=0; i<RAM_GROUPS;i=i+1) begin : sm
if (TARGET_CHIP == 1) begin : tc1
alt_s4mlab sm0 (
.wclk(clk),
.wena(1'b1),
.waddr_reg(waddr_reg[((i+1)*ADDR_WIDTH)-1:i*ADDR_WIDTH]),
.wdata_reg(wdata_reg[(i+1)*(WIDTH/RAM_GROUPS)-1:i*(WIDTH/RAM_GROUPS)]),
.raddr(rptr[((i+1)*ADDR_WIDTH)-1:i*ADDR_WIDTH] ^ 1'b1),
.rdata(ram_q[(i+1)*(WIDTH/RAM_GROUPS)-1:i*(WIDTH/RAM_GROUPS)])
);
defparam sm0 .WIDTH = WIDTH / RAM_GROUPS;
defparam sm0 .ADDR_WIDTH = ADDR_WIDTH;
end
else if (TARGET_CHIP == 2 || TARGET_CHIP == 0) begin : tc2
altpcie_a10mlab sm0 (
.wclk(clk),
.wena(1'b1),
.waddr_reg(waddr_reg[((i+1)*ADDR_WIDTH)-1:i*ADDR_WIDTH]),
.wdata_reg(wdata_reg[(i+1)*(WIDTH/RAM_GROUPS)-1:i*(WIDTH/RAM_GROUPS)]),
.raddr(rptr[((i+1)*ADDR_WIDTH)-1:i*ADDR_WIDTH] ^ 1'b1),
.rdata(ram_q[(i+1)*(WIDTH/RAM_GROUPS)-1:i*(WIDTH/RAM_GROUPS)])
);
defparam sm0 .WIDTH = WIDTH / RAM_GROUPS;
defparam sm0 .ADDR_WIDTH = ADDR_WIDTH;
defparam sm0 .SIM_EMULATE = SIM_EMULATE;
end
else if (TARGET_CHIP == 5) begin : tc5
altpcie_a10mlab sm0 (
.wclk(clk),
.wena(1'b1),
.waddr_reg(waddr_reg[((i+1)*ADDR_WIDTH)-1:i*ADDR_WIDTH]),
.wdata_reg(wdata_reg[(i+1)*(WIDTH/RAM_GROUPS)-1:i*(WIDTH/RAM_GROUPS)]),
.raddr(rptr[((i+1)*ADDR_WIDTH)-1:i*ADDR_WIDTH] ^ 1'b1),
.rdata(ram_q[(i+1)*(WIDTH/RAM_GROUPS)-1:i*(WIDTH/RAM_GROUPS)])
);
defparam sm0 .WIDTH = WIDTH / RAM_GROUPS;
defparam sm0 .ADDR_WIDTH = ADDR_WIDTH;
defparam sm0 .SIM_EMULATE = SIM_EMULATE;
end
else begin : tc66
// synthesis translate off
initial begin
$display ("Error - Unsure how to make mlab cells for this target chip");
$stop();
end
// synthesis translate on
end
end
endgenerate
// output reg - don't defeat clock enable (?) Works really well on S5
wire [WIDTH-1:0] rdata_mx = rinc ? ram_q: rdata_reg ;
always @(posedge clk) begin
rdata_reg <= rdata_mx;
end
assign rdata = rdata_reg;
//////////////////////////////////////////////////
// used words
//////////////////////////////////////////////////
generate
if (DISABLE_USED) begin : nwu
assign used = {ADDR_WIDTH{1'b0}};
end
else begin : wu
reg [ADDR_WIDTH-1:0] used_r = {ADDR_WIDTH{1'b0}} /* synthesis preserve */;
always @(posedge clk) begin
used_r <= wptr_completed - rptr_completed;
end
assign used = used_r;
end
endgenerate
////////////////////////////////////
// qualified requests
////////////////////////////////////
//wire winc = wreq & (~full[0] | ~PREVENT_OVERFLOW);
//wire rinc = rreq & (~empty[0] | ~PREVENT_UNDERFLOW);
generate
if (PREVENT_OVERFLOW) begin
altpcie_a10_gbfifo_neq_5_ena eq2 (
.da(5'h0 | rptr_completed),
.db(5'h0 | wcntr),
.ena(wreq),
.eq(winc)
);
defparam eq2 .TARGET_CHIP = TARGET_CHIP; // 0 generic, 1 S4, 2 S5
end
else assign winc = wreq;
endgenerate
generate
if (PREVENT_UNDERFLOW) begin
altpcie_a10_gbfifo_neq_5_ena eq3 (
.da(5'h0 | rptr_completed),
.db(5'h0 | wptr_completed),
.ena(rreq),
.eq(rinc)
);
defparam eq3 .TARGET_CHIP = TARGET_CHIP; // 0 generic, 1 S4, 2 S5
end
else assign rinc = rreq;
endgenerate
endmodule
// BENCHMARK INFO : 10AX115R3F40I2SGES
// BENCHMARK INFO : Quartus II 64-Bit Version 14.0.0 Internal Build 160 03/13/2014 SJ Full Version
// BENCHMARK INFO : Uses helper file : alt_scfifo_mlab.v
// BENCHMARK INFO : Uses helper file : alt_eq_5_ena.v
// BENCHMARK INFO : Uses helper file : alt_wys_lut.v
// BENCHMARK INFO : Uses helper file : altpcie_a10mlab.v
// BENCHMARK INFO : Uses helper file : altpcie_a10_gbfifo_neq_5_ena.v
// BENCHMARK INFO : Max depth : 3.0 LUTs
// BENCHMARK INFO : Total registers : 231
// BENCHMARK INFO : Total pins : 171
// BENCHMARK INFO : Total virtual pins : 0
// BENCHMARK INFO : Total block memory bits : 0
// BENCHMARK INFO : Comb ALUTs : 37
// BENCHMARK INFO : ALMs : 87 / 427,200 ( < 1 % )
// BENCHMARK INFO : Worst setup path @ 468.75MHz : -0.066 ns, From waddr_reg[13], To altpcie_a10mlab:sm[2].tc5.sm0|ml[19].lrm~reg1}
// DESCRIPTION
//
// This is a single clock version of dcfifo_mlab. It is suitable for replacing smaller instances of LPM SCFIFO.
// The maximum depth is 31. The implementation follows dcfifo_mlab very closely, with the cross
// domain hardening removed.
//
// Where possible connect the "used words" outputs to create partial full and empty signals. These can be
// pipelined and facilitate easy timing closure better than the full and empty which have tighter functional
// requirements.
//
//
//
// Where possible set these parameters to 0 to improve read and write request speed.
//
// parameter PREVENT_OVERFLOW = 1'b1, // ignore requests that would cause overflow
//
// parameter PREVENT_UNDERFLOW = 1'b1, // ignore requests that would cause underflow
//
// With prevention disabled the FIFO will wrap during an underflow or overflow, and then resume
// coherent operation from that illegally entered state.
//
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_a10_gbfifo_neq_5_ena #(
parameter TARGET_CHIP = 2 // 0 generic, 1 S4, 2 S5
)(
input [4:0] da,
input [4:0] db,
input ena,
output eq
);
wire w0_o;
altpcie_a10_gbfifo_wys_lut w0 (
.a(da[0]),
.b(da[1]),
.c(da[2]),
.d(db[0]),
.e(db[1]),
.f(db[2]),
.out (w0_o)
);
defparam w0 .TARGET_CHIP = 5;
defparam w0 .MASK = 64'h8040201008040201; // {a,b,c} == {d,e,f}
altpcie_a10_gbfifo_wys_lut w1 (
.a(ena),
.b(da[3]),
.c(da[4]),
.d(db[3]),
.e(db[4]),
.f(w0_o),
.out (eq)
);
defparam w1 .TARGET_CHIP = 5;
defparam w1 .MASK = 64'h2a8aa2a8aaaaaaaa; // (!({b,c} == {d,e}) || !f) && a;
endmodule
// baeckler - 01-16-2012
// DESCRIPTION
//
// This is a low level instantiation of the Stratix 5 MLAB. Note that the inputs with _reg in the name need to
// be directly driven by registers to pass legality checking.
//
// CONFIDENCE
// This is a key low level wrapper used in many places
//
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_a10_gbfifo_s5mlab #(
parameter WIDTH = 20,
parameter ADDR_WIDTH = 5,
parameter SIM_EMULATE = 1'b0 // this may not be exactly the same at the fine grain timing level
)
(
input wclk,
input wena,
input [ADDR_WIDTH-1:0] waddr_reg,
input [WIDTH-1:0] wdata_reg,
input [ADDR_WIDTH-1:0] raddr,
output [WIDTH-1:0] rdata
);
localparam NUM_WORDS = (1 << ADDR_WIDTH);
genvar i;
generate
if (!SIM_EMULATE) begin
/////////////////////////////////////////////
// hardware cells
for (i=0; i<WIDTH; i=i+1) begin : ml
wire wclk_w = wclk; // workaround strange modelsim warning due to cell model tristate
twentynm_mlab_cell lrm (
.clk0(wclk_w),
.ena0(wena),
// synthesis translate off
.clk1(1'b0),
.ena1(1'b1),
.ena2(1'b1),
.clr(1'b0),
.devclrn(1'b1),
.devpor(1'b1),
// synthesis translate on
.portabyteenamasks(1'b1),
.portadatain(wdata_reg[i]),
.portaaddr(waddr_reg),
.portbaddr(raddr),
.portbdataout(rdata[i])
);
defparam lrm .mixed_port_feed_through_mode = "dont_care";
defparam lrm .logical_ram_name = "lrm";
defparam lrm .logical_ram_depth = 1 << ADDR_WIDTH;
defparam lrm .logical_ram_width = WIDTH;
defparam lrm .first_address = 0;
defparam lrm .last_address = (1 << ADDR_WIDTH)-1;
defparam lrm .first_bit_number = i;
defparam lrm .data_width = 1;
defparam lrm .address_width = ADDR_WIDTH;
end
end
else begin
/////////////////////////////////////////////
// sim equivalent
reg [WIDTH-1:0] storage [0:NUM_WORDS-1];
integer k = 0;
initial begin
for (k=0; k<NUM_WORDS; k=k+1) begin
storage[k] = 0;
end
end
always @(posedge wclk) begin
if (wena) storage [waddr_reg] <= wdata_reg;
end
reg [WIDTH-1:0] rdata_b = 0;
always @(*) begin
rdata_b = storage[raddr];
end
assign rdata = rdata_b;
end
endgenerate
endmodule
// BENCHMARK INFO : 5SGXEA7N2F45C2
// BENCHMARK INFO : Quartus II 64-Bit Version 13.1.0 Build 162 10/23/2013 SJ Full Version
// BENCHMARK INFO : Uses helper file : altpcie_a10_gbfifo_s5mlab.v
// BENCHMARK INFO : Max depth : 0.0 LUTs
// BENCHMARK INFO : Total registers : 0
// BENCHMARK INFO : Total pins : 52
// BENCHMARK INFO : Total virtual pins : 0
// BENCHMARK INFO : Total block memory bits : 0
// BENCHMARK INFO : Comb ALUTs : 1
// BENCHMARK INFO : ALMs : 11 / 234,720 ( < 1 % )
// BENCHMARK INFO : Worst setup path @ 468.75MHz : 2.063 ns, From wclk~inputCLKENA0FMAX_CAP_FF0, To wclk~inputCLKENA0FMAX_CAP_FF1}
// BENCHMARK INFO : Worst setup path @ 468.75MHz : 2.063 ns, From wclk~inputCLKENA0FMAX_CAP_FF0, To wclk~inputCLKENA0FMAX_CAP_FF1}
// BENCHMARK INFO : Worst setup path @ 468.75MHz : 2.063 ns, From wclk~inputCLKENA0FMAX_CAP_FF0, To wclk~inputCLKENA0FMAX_CAP_FF1}
// baeckler - 01-25-2012
// force the decomposition of 5 bit FIFO pointer compare with enable
// DESCRIPTION
//
// This is a WYSIWYG cell implementation of equality comparison of two 5 bit busses with an enable signal.
//
// CONFIDENCE
// This is a small equality circuit. Any problems should be easily spotted in simulation.
//
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_a10_gbfifo_eq_5_ena #(
parameter TARGET_CHIP = 2 // 0 generic, 1 S4, 2 S5
)(
input [4:0] da,
input [4:0] db,
input ena,
output eq
);
wire w0_o;
altpcie_a10_gbfifo_wys_lut w0 (
.a(da[0]),
.b(da[1]),
.c(da[2]),
.d(db[0]),
.e(db[1]),
.f(db[2]),
.out (w0_o)
);
defparam w0 .TARGET_CHIP = 5;
defparam w0 .MASK = 64'h8040201008040201; // {a,b,c} == {d,e,f}
altpcie_a10_gbfifo_wys_lut w1 (
.a(ena),
.b(da[3]),
.c(da[4]),
.d(db[3]),
.e(db[4]),
.f(w0_o),
.out (eq)
);
defparam w1 .TARGET_CHIP = 5;
defparam w1 .MASK = 64'h8020080200000000; // ({b,c} == {d,e}) && a && f
endmodule
// BENCHMARK INFO : 5SGXEA7N2F45C2
// BENCHMARK INFO : Quartus II 64-Bit Version 13.1.0 Build 162 10/23/2013 SJ Full Version
// BENCHMARK INFO : Uses helper file : altpcie_a10_gbfifo_eq_5_ena.v
// BENCHMARK INFO : Uses helper file : altpcie_a10_gbfifo_wys_lut.v
// BENCHMARK INFO : Max depth : 2.0 LUTs
// BENCHMARK INFO : Total registers : 0
// BENCHMARK INFO : Total pins : 12
// BENCHMARK INFO : Total virtual pins : 0
// BENCHMARK INFO : Total block memory bits : 0
// BENCHMARK INFO : Comb ALUTs : 3
// BENCHMARK INFO : ALMs : 3 / 234,720 ( < 1 % )
// DESCRIPTION
//
//
// This is a multiple chip family WYSIWYG LUT. WYSIWYG cells are cumbersome, but the only way to
// guarantee that complex LUT decompositions are implemented exactly as desired. It has a generic mode
// for comparing against a simple truth table implementation.
//
// CONFIDENCE
// This component is simple, and used absolutely everywhere.
//
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_a10_gbfifo_wys_lut #(
parameter MASK = 64'h6996966996696996, // xor6
parameter TARGET_CHIP = 5 // 0 generic, 1=S4, 2=S5, 3=A5, 4=C5, 5=A10
)
(
input a,b,c,d,e,f,
output out
);
// Handy masks -
// 64'h8040201008040201 {a,b,c} == {d,e,f}
// 64'h6996966996696996 xor 6
// 64'h8020080200000000 ({b,c} == {d,e}) && a && f
generate
if (TARGET_CHIP == 0) begin : c0
// family neutral / simulation version
wire [5:0] addr = {f,e,d,c,b,a};
wire [63:0] tmp = MASK >> addr;
assign out = tmp[0];
end
else if (TARGET_CHIP == 1) begin : c1
stratixiv_lcell_comb s4c (
.dataa (a),.datab (b),.datac (c),.datad (d),.datae (e),.dataf (f),.datag(1'b1),
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
.combout(out));
defparam s4c .lut_mask = MASK;
defparam s4c .shared_arith = "off";
defparam s4c .extended_lut = "off";
end
else if (TARGET_CHIP == 2) begin : c2
stratixv_lcell_comb s5c (
.dataa (a),.datab (b),.datac (c),.datad (d),.datae (e),.dataf (f),.datag(1'b1),
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
.combout(out));
defparam s5c .lut_mask = MASK;
defparam s5c .shared_arith = "off";
defparam s5c .extended_lut = "off";
end
else if (TARGET_CHIP == 3) begin : c3
arriav_lcell_comb a5c (
.dataa (a),.datab (b),.datac (c),.datad (d),.datae (e),.dataf (f),.datag(1'b1),
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
.combout(out));
defparam a5c .lut_mask = MASK;
defparam a5c .shared_arith = "off";
defparam a5c .extended_lut = "off";
end
else if (TARGET_CHIP == 4) begin : c4
cyclonev_lcell_comb c5c (
.dataa (a),.datab (b),.datac (c),.datad (d),.datae (e),.dataf (f),.datag(1'b1),
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
.combout(out));
defparam c5c .lut_mask = MASK;
defparam c5c .shared_arith = "off";
defparam c5c .extended_lut = "off";
end
else if (TARGET_CHIP == 5) begin : a10
twentynm_lcell_comb a10c (
.dataa (a),.datab (b),.datac (c),.datad (d),.datae (e),.dataf (f),.datag(1'b1),
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
.combout(out));
defparam a10c .lut_mask = MASK;
defparam a10c .shared_arith = "off";
defparam a10c .extended_lut = "off";
end
else begin
// synthesis translate off
initial begin
$display ("ERROR: Illegal TARGET_CHIP");
$stop();
end
// synthesis translate on
assign out = 1'b0;
end
endgenerate
endmodule
// BENCHMARK INFO : 5SGXEA7N2F45C2
// BENCHMARK INFO : Quartus II 64-Bit Version 13.1.0 Build 162 10/23/2013 SJ Full Version
// BENCHMARK INFO : Uses helper file : altpcie_a10_gbfifo_wys_lut.v
// BENCHMARK INFO : Max depth : 1.0 LUTs
// BENCHMARK INFO : Total registers : 0
// BENCHMARK INFO : Total pins : 7
// BENCHMARK INFO : Total virtual pins : 0
// BENCHMARK INFO : Total block memory bits : 0
// BENCHMARK INFO : Comb ALUTs : 2
// BENCHMARK INFO : ALMs : 2 / 234,720 ( < 1 % )
// baeckler - 10-12-2013
// DESCRIPTION
//
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_a10mlab #(
parameter WIDTH = 20,
parameter ADDR_WIDTH = 5,
parameter SIM_EMULATE = 1'b0 // this may not be exactly the same at the fine grain timing level
)
(
input wclk,
input wena,
input [ADDR_WIDTH-1:0] waddr_reg,
input [WIDTH-1:0] wdata_reg,
input [ADDR_WIDTH-1:0] raddr,
output [WIDTH-1:0] rdata
);
localparam NUM_WORDS = (1 << ADDR_WIDTH);
genvar i;
generate
if (!SIM_EMULATE) begin
/////////////////////////////////////////////
// hardware cells
for (i=0; i<WIDTH; i=i+1) begin : ml
wire wclk_w = wclk; // workaround strange modelsim warning due to cell model tristate
twentynm_mlab_cell lrm (
.clk0(wclk_w),
.ena0(wena),
// synthesis translate off
.clk1(1'b0),
.ena1(1'b1),
.ena2(1'b1),
.clr(1'b0),
.devclrn(1'b1),
.devpor(1'b1),
// synthesis translate on
.portabyteenamasks(1'b1),
.portadatain(wdata_reg[i]),
.portaaddr(waddr_reg),
.portbaddr(raddr),
.portbdataout(rdata[i])
);
defparam lrm .mixed_port_feed_through_mode = "dont_care";
defparam lrm .logical_ram_name = "lrm";
defparam lrm .logical_ram_depth = 1 << ADDR_WIDTH;
defparam lrm .logical_ram_width = WIDTH;
defparam lrm .first_address = 0;
defparam lrm .last_address = (1 << ADDR_WIDTH)-1;
defparam lrm .first_bit_number = i;
defparam lrm .data_width = 1;
defparam lrm .address_width = ADDR_WIDTH;
end
end
else begin
/////////////////////////////////////////////
// sim equivalent
reg [WIDTH-1:0] storage [0:NUM_WORDS-1];
integer k = 0;
initial begin
for (k=0; k<NUM_WORDS; k=k+1) begin
storage[k] = 0;
end
end
always @(posedge wclk) begin
if (wena) storage [waddr_reg] <= wdata_reg;
end
reg [WIDTH-1:0] rdata_b = 0;
always @(*) begin
rdata_b = storage[raddr];
end
assign rdata = rdata_b;
end
endgenerate
endmodule
// BENCHMARK INFO : 10AX115R3F40I2SGES
// BENCHMARK INFO : Quartus II 64-Bit Version 14.0.0 Internal Build 145 02/20/2014 SJ Full Version
// BENCHMARK INFO : Uses helper file : altpcie_a10mlab.v
// BENCHMARK INFO : Max depth : 0.0 LUTs
// BENCHMARK INFO : Total registers : 0
// BENCHMARK INFO : Total pins : 52
// BENCHMARK INFO : Total virtual pins : 0
// BENCHMARK INFO : Total block memory bits : 0
// BENCHMARK INFO : Comb ALUTs : 1
// BENCHMARK INFO : ALMs : 11 / 427,200 ( < 1 % )
// BENCHMARK INFO : Worst setup path @ 468.75MHz : 2.133 ns, From (primary), To ml[0].lrm~register_clock0}
// BENCHMARK INFO : Worst setup path @ 468.75MHz : 2.133 ns, From (primary), To ml[0].lrm~register_clock0}
// BENCHMARK INFO : Worst setup path @ 468.75MHz : 2.133 ns, From (primary), To ml[0].lrm~register_clock0}
`timescale 1 ps / 1 ps
// other product not provided by Altera.
/////////////////////////////////////////////////////////////////////////////
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
// turn off superfluous verilog processor warnings
// altera message_level Level1
// altera message_off 10034 10035 10036 10037 10230 10240 10030
module altpcie_a10_hip_pllnphy # (
parameter protocol_version = "Gen 1",
parameter LANES = 1,
parameter export_phy_input_to_top_level_hwtcl = 0,
parameter reconfig_address_width_integer_hwtcl = 11
) (
//Native PHY Ports
input wire [LANES-1 :0] tx_analogreset, // tx_analogreset.tx_analogreset
input wire [LANES-1 :0] tx_digitalreset, // tx_digitalreset.tx_digitalreset
input wire [LANES-1 :0] rx_analogreset, // rx_analogreset.rx_analogreset
input wire [LANES-1 :0] rx_digitalreset, // rx_digitalreset.rx_digitalreset
output wire [LANES-1 :0] tx_cal_busy, // tx_cal_busy.tx_cal_busy
output wire [LANES-1 :0] rx_cal_busy, // rx_cal_busy.rx_cal_busy
input wire rx_cdr_refclk0, // rx_cdr_refclk0.clk
output wire [LANES-1 :0] tx_serial_data, // tx_serial_data.tx_serial_data
input wire [LANES-1 :0] rx_serial_data, // rx_serial_data.rx_serial_data
input wire [LANES-1 :0] rx_set_locktodata, // rx_set_locktodata.rx_set_locktodata
input wire [LANES-1 :0] rx_set_locktoref, // rx_set_locktoref.rx_set_locktoref
output wire [LANES-1 :0] rx_is_lockedtoref, // rx_is_lockedtoref.rx_is_lockedtoref
output wire [LANES-1 :0] rx_is_lockedtodata, // rx_is_lockedtodata.rx_is_lockedtodata
input wire [LANES-1 :0] pipe_rx_polarity, // pipe_rx_polarity.pipe_rx_polarity
input wire [64*LANES-1:0] tx_hip_data, // tx_hip_data.tx_hip_data
output wire [51*LANES-1:0] rx_hip_data, // rx_hip_data.rx_hip_data
output wire hip_pipe_pclk, // hip_pipe_pclk.hip_pipe_pclk
output wire hip_fixedclk, // hip_fixedclk.hip_fixedclk
output wire [LANES-1 :0] hip_frefclk, // hip_frefclk.hip_frefclk
output wire [8*LANES-1 :0] hip_ctrl, // hip_ctrl.hip_ctrl
output wire [LANES-1 :0] chnl_cal_done, // chnl_cal_done.hip_cal_done
input wire [2*LANES-1 :0] pipe_rate, // pipe_rate.pipe_rate
input wire [3*LANES-1 :0] pipe_rx_eidleinfersel, // pipe_rx_eidleinfersel.pipe_rx_eidleinfersel
output wire [LANES-1 :0] pipe_rx_elecidle, // pipe_rx_elecidle.pipe_rx_elecidle
input wire [18*LANES-1:0] pipe_g3_txdeemph,
input wire [3*LANES-1:0] pipe_g3_rxpresethint,
// Reconfig interface
input wire reconfig_clk, // reconfig_clk.clk
input wire reconfig_reset, // reconfig_reset.reset
input wire reconfig_write, // reconfig_avmm.write
input wire reconfig_read, // reconfig_avmm.read
input wire [reconfig_address_width_integer_hwtcl-1:0] reconfig_address, // reconfig_avmm.address
input wire [31:0] reconfig_writedata, // reconfig_avmm.writedata
output wire [31:0] reconfig_readdata, // reconfig_avmm.readdata
output wire reconfig_waitrequest, // reconfig_avmm.waitrequest
input wire reconfig_pll0_clk, // reconfig_clk.clk
input wire reconfig_pll0_reset, // reconfig_reset.reset
input wire reconfig_pll0_write, // reconfig_avmm.write
input wire reconfig_pll0_read, // .read
input wire [9:0] reconfig_pll0_address, // .address
input wire [31:0] reconfig_pll0_writedata, // .writedata
output wire [31:0] reconfig_pll0_readdata, // .readdata
output wire reconfig_pll0_waitrequest, // .waitrequest
input wire reconfig_pll1_clk, // reconfig_clk.clk
input wire reconfig_pll1_reset, // reconfig_reset.reset
input wire reconfig_pll1_write, // reconfig_avmm.write
input wire reconfig_pll1_read, // .read
input wire [9:0] reconfig_pll1_address, // .address
input wire [31:0] reconfig_pll1_writedata, // .writedata
output wire [31:0] reconfig_pll1_readdata, // .readdata
output wire reconfig_pll1_waitrequest, // .waitrequest
//DFE interface
input wire hip_reduce_counters,
input wire [1:0] current_rate, // PCIe generation
input wire ltssm_eq_phase2, // LTSSM equalization Phase2
input wire ltssm_detect_active, // LTSSM Detect Active state
input wire ltssm_detect_quiet, // LTSSM Detect Quiet state
//LC PLL ports
input wire pll_powerdown_lcpll, // pll_powerdown.pll_powerdown //TODO for Gen3 with LC n FF PLL
output wire pll_locked_lcpll, // pll_locked.pll_locked
output wire pll_cal_done_lcpll, // pll_cal_done.hip_cal_done
//FPLL ports
input wire pll_powerdown_fpll, // pll_powerdown.pll_powerdown //TODO for Gen3 with LC n FF PLL
output wire pll_locked_fpll, // pll_locked.pll_locked
output wire pll_cal_done_fpll, // pll_cal_done.hip_cal_done
// Master CGB reset port
input wire mcgb_rst, // reset to the MST CGB
input wire pll_refclk0, // pll_refclk0.clk
input wire pipe_hclk_in,
output wire pll_pcie_clk,
// rx_polinv from the the fabric. pld_rx_polinv soft logic
input wire [LANES-1:0] rx_polinv,
//add for false skp detection
output wire [LANES-1 :0] rx_clkout,
output wire [128*LANES-1:0] rx_parallel_data
);
localparam xn_design = (LANES==1)? 0:1;
localparam [255:0] ONES = 256'HFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF;
localparam [255:0] ZEROS = 256'H0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
wire tx_serial_clk0;
wire tx_serial_clk1;
wire [5:0] tx_bonding_clocks;
wire pll_pcie_clk_int;
wire [1:0] pcie_sw;
wire [1:0] pcie_sw_done;
assign pll_pcie_clk_int = (export_phy_input_to_top_level_hwtcl == 1)? pipe_hclk_in : pll_pcie_clk;
///////////////////////////////////////
/////////// NATIVE PHY ////////////
///////////////////////////////////////
generate begin : g_xcvr
///////// X1 ///////////////////////////////////////////////
if (LANES==1) begin
if (protocol_version=="Gen 1") begin :g_phy_g1x1
phy_g1x1 phy_g1x1 (
.tx_analogreset (tx_analogreset ), // input wire [0:0] tx_analogreset,
.tx_digitalreset (tx_digitalreset ), // input wire [0:0] tx_digitalreset,
.rx_analogreset (rx_analogreset ), // input wire [0:0] rx_analogreset,
.rx_digitalreset (rx_digitalreset ), // input wire [0:0] rx_digitalreset,
.tx_cal_busy (tx_cal_busy ), // output wire [0:0] tx_cal_busy,
.rx_cal_busy (rx_cal_busy ), // output wire [0:0] rx_cal_busy,
.tx_serial_clk0 (tx_serial_clk0 ), // input wire [0:0] tx_serial_clk0,
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0,
.tx_serial_data (tx_serial_data ), // output wire [0:0] tx_serial_data,
.rx_serial_data (rx_serial_data ), // input wire [0:0] rx_serial_data,
.rx_set_locktodata (rx_set_locktodata ), // input wire [0:0] rx_set_locktodata,
.rx_set_locktoref (rx_set_locktoref ), // input wire [0:0] rx_set_locktoref,
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [0:0] rx_is_lockedtoref,
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [0:0] rx_is_lockedtodata,
.tx_hip_data (tx_hip_data ), // input wire [63:0] tx_hip_data,
.rx_hip_data (rx_hip_data ), // output wire [50:0] rx_hip_data,
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk,
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk,
.hip_frefclk (hip_frefclk ), // output wire [0:0] hip_frefclk,
.hip_ctrl (hip_ctrl ), // output wire [7:0] hip_ctrl,
.hip_cal_done (chnl_cal_done ), // output wire [0:0] hip_cal_done,
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in,
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [2:0] pipe_rx_eidleinfersel,
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [0:0] pipe_rx_elecidle,
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [0:0] pipe_rx_polarity
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [0:0] rx_polinv
);
end
else if (protocol_version=="Gen 2") begin :g_phy_g2x1
phy_g2x1 phy_g2x1 (
.tx_analogreset (tx_analogreset ), // input wire [0:0] tx_analogreset,
.tx_digitalreset (tx_digitalreset ), // input wire [0:0] tx_digitalreset,
.rx_analogreset (rx_analogreset ), // input wire [0:0] rx_analogreset,
.rx_digitalreset (rx_digitalreset ), // input wire [0:0] rx_digitalreset,
.tx_cal_busy (tx_cal_busy ), // output wire [0:0] tx_cal_busy,
.rx_cal_busy (rx_cal_busy ), // output wire [0:0] rx_cal_busy,
.tx_serial_clk0 (tx_serial_clk0 ), // input wire [0:0] tx_serial_clk0,
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0,
.tx_serial_data (tx_serial_data ), // output wire [0:0] tx_serial_data,
.rx_serial_data (rx_serial_data ), // input wire [0:0] rx_serial_data,
.rx_set_locktodata (rx_set_locktodata ), // input wire [0:0] rx_set_locktodata,
.rx_set_locktoref (rx_set_locktoref ), // input wire [0:0] rx_set_locktoref,
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [0:0] rx_is_lockedtoref,
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [0:0] rx_is_lockedtodata,
.tx_hip_data (tx_hip_data ), // input wire [63:0] tx_hip_data,
.rx_hip_data (rx_hip_data ), // output wire [50:0] rx_hip_data,
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk,
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk,
.hip_frefclk (hip_frefclk ), // output wire [0:0] hip_frefclk,
.hip_ctrl (hip_ctrl ), // output wire [7:0] hip_ctrl,
.hip_cal_done (chnl_cal_done ), // output wire [0:0] hip_cal_done,
.pipe_rate (pipe_rate ), // input wire [1:0] pipe_rate,
.pipe_sw_done (pcie_sw_done ), // input wire [1:0] pipe_sw_done,
.pipe_sw (pcie_sw ), // output wire [1:0] pipe_sw,
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in,
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [2:0] pipe_rx_eidleinfersel,
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [0:0] pipe_rx_elecidle,
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [0:0] pipe_rx_polarity
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [0:0] rx_polinv
);
end
else begin :g_phy_g3x1
phy_g3x1 phy_g3x1 (
.tx_analogreset (tx_analogreset ), //input wire [0:0] tx_analogreset,
.tx_digitalreset (tx_digitalreset ), //input wire [0:0] tx_digitalreset,
.rx_analogreset (rx_analogreset ), //input wire [0:0] rx_analogreset,
.rx_digitalreset (rx_digitalreset ), //input wire [0:0] rx_digitalreset,
.tx_cal_busy (tx_cal_busy ), //output wire [0:0] tx_cal_busy,
.rx_cal_busy (rx_cal_busy ), //output wire [0:0] rx_cal_busy,
.tx_serial_clk0 (tx_serial_clk0 ), //input wire [0:0] tx_serial_clk0,
.tx_serial_clk1 (tx_serial_clk1 ), //input wire [0:0] tx_serial_clk1,
.rx_cdr_refclk0 (rx_cdr_refclk0 ), //input wire rx_cdr_refclk0,
.tx_serial_data (tx_serial_data ), //output wire [0:0] tx_serial_data,
.rx_serial_data (rx_serial_data ), //input wire [0:0] rx_serial_data,
.rx_set_locktodata (rx_set_locktodata ), //input wire [0:0] rx_set_locktodata,
.rx_set_locktoref (rx_set_locktoref ), //input wire [0:0] rx_set_locktoref,
.rx_is_lockedtoref (rx_is_lockedtoref ), //output wire [0:0] rx_is_lockedtoref,
.rx_is_lockedtodata (rx_is_lockedtodata ), //output wire [0:0] rx_is_lockedtodata,
.tx_hip_data (tx_hip_data ), //input wire [63:0] tx_hip_data,
.rx_hip_data (rx_hip_data ), //output wire [50:0] rx_hip_data,
.hip_pipe_pclk (hip_pipe_pclk ), //output wire hip_pipe_pclk,
.hip_fixedclk (hip_fixedclk ), //output wire hip_fixedclk,
.hip_frefclk (hip_frefclk ), //output wire [0:0] hip_frefclk,
.hip_ctrl (hip_ctrl ), //output wire [7:0] hip_ctrl,
.hip_cal_done (chnl_cal_done ), //output wire [0:0] hip_cal_done,
.pipe_rate (pipe_rate ), //input wire [1:0] pipe_rate,
.pipe_sw_done (pcie_sw_done ), //input wire [1:0] pipe_sw_done,
.pipe_sw (pcie_sw ), //output wire [1:0] pipe_sw,
.pipe_hclk_in (pll_pcie_clk_int ), //input wire pipe_hclk_in,
.pipe_g3_txdeemph (pipe_g3_txdeemph ), //input wire [17:0] pipe_g3_txdeemph,
.pipe_g3_rxpresethint (pipe_g3_rxpresethint ), //input wire [2:0] pipe_g3_rxpresethint,
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), //input wire [2:0] pipe_rx_eidleinfersel,
.pipe_rx_elecidle (pipe_rx_elecidle ), //output wire [0:0] pipe_rx_elecidle,
.pipe_rx_polarity (pipe_rx_polarity ), //input wire [0:0] pipe_rx_polarity
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [0:0] rx_polinv
);
end
///////// X2 ///////////////////////////////////////////////
end
else if (LANES==2) begin
if (protocol_version=="Gen 1") begin :g_phy_g2x2
phy_g1x2 phy_g1x2 (
.tx_analogreset (tx_analogreset ), // input wire [1:0] tx_analogreset,
.tx_digitalreset (tx_digitalreset ), // input wire [1:0] tx_digitalreset,
.rx_analogreset (rx_analogreset ), // input wire [1:0] rx_analogreset,
.rx_digitalreset (rx_digitalreset ), // input wire [1:0] rx_digitalreset,
.tx_cal_busy (tx_cal_busy ), // output wire [1:0] tx_cal_busy,
.rx_cal_busy (rx_cal_busy ), // output wire [1:0] rx_cal_busy,
.tx_bonding_clocks ({LANES{tx_bonding_clocks}} ), // input wire [11:0] tx_bonding_clocks,
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0,
.tx_serial_data (tx_serial_data ), // output wire [1:0] tx_serial_data,
.rx_serial_data (rx_serial_data ), // input wire [1:0] rx_serial_data,
.rx_set_locktodata (rx_set_locktodata ), // input wire [1:0] rx_set_locktodata,
.rx_set_locktoref (rx_set_locktoref ), // input wire [1:0] rx_set_locktoref,
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [1:0] rx_is_lockedtoref,
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [1:0] rx_is_lockedtodata,
.tx_hip_data (tx_hip_data ), // input wire [127:0] tx_hip_data,
.rx_hip_data (rx_hip_data ), // output wire [101:0] rx_hip_data,
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk,
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk,
.hip_frefclk (hip_frefclk ), // output wire [1:0] hip_frefclk,
.hip_ctrl (hip_ctrl ), // output wire [15:0] hip_ctrl,
.hip_cal_done (chnl_cal_done ), // output wire [1:0] hip_cal_done,
.pipe_rate (pipe_rate ), // input wire [1:0] pipe_rate,
.pipe_sw_done (pcie_sw_done ), // input wire [1:0] pipe_sw_done,
.pipe_sw (pcie_sw ), // output wire [1:0] pipe_sw,
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in,
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [5:0] pipe_rx_eidleinfersel,
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [1:0] pipe_rx_elecidle,
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [1:0] pipe_rx_polarity
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [1:0] rx_polinv
);
end
else if (protocol_version=="Gen 2") begin :g_phy_g2x2
phy_g2x2 phy_g2x2 (
.tx_analogreset (tx_analogreset ), // input wire [1:0] tx_analogreset,
.tx_digitalreset (tx_digitalreset ), // input wire [1:0] tx_digitalreset,
.rx_analogreset (rx_analogreset ), // input wire [1:0] rx_analogreset,
.rx_digitalreset (rx_digitalreset ), // input wire [1:0] rx_digitalreset,
.tx_cal_busy (tx_cal_busy ), // output wire [1:0] tx_cal_busy,
.rx_cal_busy (rx_cal_busy ), // output wire [1:0] rx_cal_busy,
.tx_bonding_clocks ({LANES{tx_bonding_clocks}} ), // input wire [11:0] tx_bonding_clocks,
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0,
.tx_serial_data (tx_serial_data ), // output wire [1:0] tx_serial_data,
.rx_serial_data (rx_serial_data ), // input wire [1:0] rx_serial_data,
.rx_set_locktodata (rx_set_locktodata ), // input wire [1:0] rx_set_locktodata,
.rx_set_locktoref (rx_set_locktoref ), // input wire [1:0] rx_set_locktoref,
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [1:0] rx_is_lockedtoref,
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [1:0] rx_is_lockedtodata,
.tx_hip_data (tx_hip_data ), // input wire [127:0] tx_hip_data,
.rx_hip_data (rx_hip_data ), // output wire [101:0] rx_hip_data,
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk,
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk,
.hip_frefclk (hip_frefclk ), // output wire [1:0] hip_frefclk,
.hip_ctrl (hip_ctrl ), // output wire [15:0] hip_ctrl,
.hip_cal_done (chnl_cal_done ), // output wire [1:0] hip_cal_done,
.pipe_rate (pipe_rate ), // input wire [3:0] pipe_rate,
.pipe_sw_done (pcie_sw_done ), // input wire [1:0] pipe_sw_done,
.pipe_sw (pcie_sw ), // output wire [1:0] pipe_sw,
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in,
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [5:0] pipe_rx_eidleinfersel,
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [1:0] pipe_rx_elecidle,
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [1:0] pipe_rx_polarity
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [1:0] rx_polinv
);
end
else begin :g_phy_g3x2
phy_g3x2 phy_g3x2 (
.tx_analogreset (tx_analogreset ), // input wire [1:0] tx_analogreset, //
.tx_digitalreset (tx_digitalreset ), // input wire [1:0] tx_digitalreset, //
.rx_analogreset (rx_analogreset ), // input wire [1:0] rx_analogreset, //
.rx_digitalreset (rx_digitalreset ), // input wire [1:0] rx_digitalreset, //
.tx_cal_busy (tx_cal_busy ), // output wire [1:0] tx_cal_busy, //
.rx_cal_busy (rx_cal_busy ), // output wire [1:0] rx_cal_busy, //
.tx_bonding_clocks ({LANES{tx_bonding_clocks}} ), // input wire [11:0] tx_bonding_clocks, //
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0, //
.tx_serial_data (tx_serial_data ), // output wire [1:0] tx_serial_data, //
.rx_serial_data (rx_serial_data ), // input wire [1:0] rx_serial_data, //
.rx_set_locktodata (rx_set_locktodata ), // input wire [1:0] rx_set_locktodata, //
.rx_set_locktoref (rx_set_locktoref ), // input wire [1:0] rx_set_locktoref, //
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [1:0] rx_is_lockedtoref, //
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [1:0] rx_is_lockedtodata, //
.tx_hip_data (tx_hip_data ), // input wire [127:0] tx_hip_data, //
.rx_hip_data (rx_hip_data ), // output wire [101:0] rx_hip_data, //
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk, //
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk, //
.hip_frefclk (hip_frefclk ), // output wire [1:0] hip_frefclk, //
.hip_ctrl (hip_ctrl ), // output wire [15:0] hip_ctrl, //
.hip_cal_done (chnl_cal_done ), // output wire [1:0] hip_cal_done, //
.pipe_rate (pipe_rate ), // input wire [3:0] pipe_rate, //
.pipe_sw_done (pcie_sw_done ), // input wire [1:0] pipe_sw_done, //
.pipe_sw (pcie_sw ), // output wire [1:0] pipe_sw, //
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in, //
.pipe_g3_txdeemph (pipe_g3_txdeemph ), // input wire [35:0] pipe_g3_txdeemph, //
.pipe_g3_rxpresethint (pipe_g3_rxpresethint ), // input wire [5:0] pipe_g3_rxpresethint, //
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [5:0] pipe_rx_eidleinfersel, //
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [1:0] pipe_rx_elecidle, //
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [1:0] pipe_rx_polarity //
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [1:0] rx_polinv
);
end
end
///////// X4 ///////////////////////////////////////////////
else if (LANES==4) begin
if (protocol_version=="Gen 1") begin :g_phy_g1x4
phy_g1x4 phy_g1x4 (
.tx_analogreset (tx_analogreset ), // input wire [3:0] tx_analogreset,
.tx_digitalreset (tx_digitalreset ), // input wire [3:0] tx_digitalreset,
.rx_analogreset (rx_analogreset ), // input wire [3:0] rx_analogreset,
.rx_digitalreset (rx_digitalreset ), // input wire [3:0] rx_digitalreset,
.tx_cal_busy (tx_cal_busy ), // output wire [3:0] tx_cal_busy,
.rx_cal_busy (rx_cal_busy ), // output wire [3:0] rx_cal_busy,
.tx_bonding_clocks ({LANES{tx_bonding_clocks}} ), // input wire [23:0] tx_bonding_clocks,
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0,
.tx_serial_data (tx_serial_data ), // output wire [3:0] tx_serial_data,
.rx_serial_data (rx_serial_data ), // input wire [3:0] rx_serial_data,
.rx_set_locktodata (rx_set_locktodata ), // input wire [3:0] rx_set_locktodata,
.rx_set_locktoref (rx_set_locktoref ), // input wire [3:0] rx_set_locktoref,
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [3:0] rx_is_lockedtoref,
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [3:0] rx_is_lockedtodata,
.tx_hip_data (tx_hip_data ), // input wire [255:0] tx_hip_data,
.rx_hip_data (rx_hip_data ), // output wire [203:0] rx_hip_data,
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk,
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk,
.hip_frefclk (hip_frefclk ), // output wire [3:0] hip_frefclk,
.hip_ctrl (hip_ctrl ), // output wire [31:0] hip_ctrl,
.hip_cal_done (chnl_cal_done ), // output wire [3:0] hip_cal_done,
.pipe_rate (pipe_rate ), // input wire [1:0] pipe_rate,
.pipe_sw_done (pcie_sw_done ), // input wire [1:0] pipe_sw_done,
.pipe_sw (pcie_sw ), // output wire [1:0] pipe_sw,
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in,
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [11:0] pipe_rx_eidleinfersel,
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [3:0] pipe_rx_elecidle,
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [3:0] pipe_rx_polarity
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [3:0] rx_polinv
);
end
else if (protocol_version=="Gen 2") begin :g_phy_g2x4
phy_g2x4 phy_g2x4 (
.tx_analogreset (tx_analogreset ), // input wire [3:0] tx_analogreset, //
.tx_digitalreset (tx_digitalreset ), // input wire [3:0] tx_digitalreset, //
.rx_analogreset (rx_analogreset ), // input wire [3:0] rx_analogreset, //
.rx_digitalreset (rx_digitalreset ), // input wire [3:0] rx_digitalreset, //
.tx_cal_busy (tx_cal_busy ), // output wire [3:0] tx_cal_busy, //
.rx_cal_busy (rx_cal_busy ), // output wire [3:0] rx_cal_busy, //
.tx_bonding_clocks ({LANES{tx_bonding_clocks}} ), // input wire [23:0] tx_bonding_clocks, //
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0, //
.tx_serial_data (tx_serial_data ), // output wire [3:0] tx_serial_data, //
.rx_serial_data (rx_serial_data ), // input wire [3:0] rx_serial_data, //
.rx_set_locktodata (rx_set_locktodata ), // input wire [3:0] rx_set_locktodata, //
.rx_set_locktoref (rx_set_locktoref ), // input wire [3:0] rx_set_locktoref, //
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [3:0] rx_is_lockedtoref, //
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [3:0] rx_is_lockedtodata, //
.tx_hip_data (tx_hip_data ), // input wire [255:0] tx_hip_data, //
.rx_hip_data (rx_hip_data ), // output wire [203:0] rx_hip_data, //
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk, //
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk, //
.hip_frefclk (hip_frefclk ), // output wire [3:0] hip_frefclk, //
.hip_ctrl (hip_ctrl ), // output wire [31:0] hip_ctrl, //
.hip_cal_done (chnl_cal_done ), // output wire [3:0] hip_cal_done, //
.pipe_rate (pipe_rate ), // input wire [7:0] pipe_rate, //
.pipe_sw_done (pcie_sw_done ), // input wire [1:0] pipe_sw_done, //
.pipe_sw (pcie_sw ), // output wire [1:0] pipe_sw, //
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in, //
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [11:0] pipe_rx_eidleinfersel, //
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [3:0] pipe_rx_elecidle, //
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [3:0] pipe_rx_polarity //
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [3:0] rx_polinv
);
end
else begin :g_phy_g3x4
phy_g3x4 phy_g3x4 (
.tx_analogreset (tx_analogreset ), // input wire [3:0] tx_analogreset, //
.tx_digitalreset (tx_digitalreset ), // input wire [3:0] tx_digitalreset, //
.rx_analogreset (rx_analogreset ), // input wire [3:0] rx_analogreset, //
.rx_digitalreset (rx_digitalreset ), // input wire [3:0] rx_digitalreset, //
.tx_cal_busy (tx_cal_busy ), // output wire [3:0] tx_cal_busy, //
.rx_cal_busy (rx_cal_busy ), // output wire [3:0] rx_cal_busy, //
.tx_bonding_clocks ({LANES{tx_bonding_clocks}} ), // input wire [23:0] tx_bonding_clocks, //
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0, //
.tx_serial_data (tx_serial_data ), // output wire [3:0] tx_serial_data, //
.rx_serial_data (rx_serial_data ), // input wire [3:0] rx_serial_data, //
.rx_set_locktodata (rx_set_locktodata ), // input wire [3:0] rx_set_locktodata, //
.rx_set_locktoref (rx_set_locktoref ), // input wire [3:0] rx_set_locktoref, //
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [3:0] rx_is_lockedtoref, //
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [3:0] rx_is_lockedtodata, //
.tx_hip_data (tx_hip_data ), // input wire [255:0] tx_hip_data, //
.rx_hip_data (rx_hip_data ), // output wire [203:0] rx_hip_data, //
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk, //
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk, //
.hip_frefclk (hip_frefclk ), // output wire [3:0] hip_frefclk, //
.hip_ctrl (hip_ctrl ), // output wire [31:0] hip_ctrl, //
.hip_cal_done (chnl_cal_done ), // output wire [3:0] hip_cal_done, //
.pipe_rate (pipe_rate ), // input wire [7:0] pipe_rate, //
.pipe_sw_done (pcie_sw_done ), // input wire [1:0] pipe_sw_done, //
.pipe_sw (pcie_sw ), // output wire [1:0] pipe_sw, //
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in, //
.pipe_g3_txdeemph (pipe_g3_txdeemph ), // input wire [71:0] pipe_g3_txdeemph, //
.pipe_g3_rxpresethint (pipe_g3_rxpresethint ), // input wire [11:0] pipe_g3_rxpresethint, //
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [11:0] pipe_rx_eidleinfersel, //
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [3:0] pipe_rx_elecidle, //
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [3:0] pipe_rx_polarity //
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [3:0] rx_polinv
);
end
end
///////// X8 ///////////////////////////////////////////////
else begin
if (protocol_version=="Gen 1") begin :g_phy_g1x8
phy_g1x8 phy_g1x8 (
.tx_analogreset (tx_analogreset ), // input wire [7:0] tx_analogreset, //
.tx_digitalreset (tx_digitalreset ), // input wire [7:0] tx_digitalreset, //
.rx_analogreset (rx_analogreset ), // input wire [7:0] rx_analogreset, //
.rx_digitalreset (rx_digitalreset ), // input wire [7:0] rx_digitalreset, //
.tx_cal_busy (tx_cal_busy ), // output wire [7:0] tx_cal_busy, //
.rx_cal_busy (rx_cal_busy ), // output wire [7:0] rx_cal_busy, //
.tx_bonding_clocks ({LANES{tx_bonding_clocks}} ), // input wire [47:0] tx_bonding_clocks, //
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0, //
.tx_serial_data (tx_serial_data ), // output wire [7:0] tx_serial_data, //
.rx_serial_data (rx_serial_data ), // input wire [7:0] rx_serial_data, //
.rx_set_locktodata (rx_set_locktodata ), // input wire [7:0] rx_set_locktodata, //
.rx_set_locktoref (rx_set_locktoref ), // input wire [7:0] rx_set_locktoref, //
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [7:0] rx_is_lockedtoref, //
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [7:0] rx_is_lockedtodata, //
.tx_hip_data (tx_hip_data ), // input wire [511:0] tx_hip_data, //
.rx_hip_data (rx_hip_data ), // output wire [407:0] rx_hip_data, //
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk, //
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk, //
.hip_frefclk (hip_frefclk ), // output wire [7:0] hip_frefclk, //
.hip_ctrl (hip_ctrl ), // output wire [63:0] hip_ctrl, //
.hip_cal_done (chnl_cal_done ), // output wire [7:0] hip_cal_done, //
.pipe_rate (pipe_rate ), // input wire [1:0] pipe_rate,
.pipe_sw_done (pcie_sw_done ), // input wire [1:0] pipe_sw_done,
.pipe_sw (pcie_sw ), // output wire [1:0] pipe_sw,
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in, //
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [23:0] pipe_rx_eidleinfersel, //
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [7:0] pipe_rx_elecidle, //
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [7:0] pipe_rx_polarity //
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [7:0] rx_polinv
);
end
else if (protocol_version=="Gen 2") begin :g_phy_g2x8
phy_g2x8 phy_g2x8 (
.tx_analogreset (tx_analogreset ), // input wire [7:0] tx_analogreset, //
.tx_digitalreset (tx_digitalreset ), // input wire [7:0] tx_digitalreset, //
.rx_analogreset (rx_analogreset ), // input wire [7:0] rx_analogreset, //
.rx_digitalreset (rx_digitalreset ), // input wire [7:0] rx_digitalreset, //
.tx_cal_busy (tx_cal_busy ), // output wire [7:0] tx_cal_busy, //
.rx_cal_busy (rx_cal_busy ), // output wire [7:0] rx_cal_busy, //
.tx_bonding_clocks ({LANES{tx_bonding_clocks}} ), // input wire [47:0] tx_bonding_clocks, //
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0, //
.tx_serial_data (tx_serial_data ), // output wire [7:0] tx_serial_data, //
.rx_serial_data (rx_serial_data ), // input wire [7:0] rx_serial_data, //
.rx_set_locktodata (rx_set_locktodata ), // input wire [7:0] rx_set_locktodata, //
.rx_set_locktoref (rx_set_locktoref ), // input wire [7:0] rx_set_locktoref, //
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [7:0] rx_is_lockedtoref, //
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [7:0] rx_is_lockedtodata, //
.tx_hip_data (tx_hip_data ), // input wire [511:0] tx_hip_data, //
.rx_hip_data (rx_hip_data ), // output wire [407:0] rx_hip_data, //
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk, //
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk, //
.hip_frefclk (hip_frefclk ), // output wire [7:0] hip_frefclk, //
.hip_ctrl (hip_ctrl ), // output wire [63:0] hip_ctrl, //
.hip_cal_done (chnl_cal_done ), // output wire [7:0] hip_cal_done, //
.pipe_rate (pipe_rate ), // input wire [15:0] pipe_rate, //
.pipe_sw_done (pcie_sw_done ), // input wire [1:0] pipe_sw_done, //
.pipe_sw (pcie_sw ), // output wire [1:0] pipe_sw, //
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in, //
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [23:0] pipe_rx_eidleinfersel, //
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [7:0] pipe_rx_elecidle, //
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [7:0] pipe_rx_polarity //
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [7:0] rx_polinv
);
end
else begin :g_phy_g3x8
phy_g3x8 phy_g3x8 (
.rx_parallel_data (rx_parallel_data ),
.rx_clkout (rx_clkout ),
.tx_analogreset (tx_analogreset ), // input wire [7:0] tx_analogreset, //
.tx_digitalreset (tx_digitalreset ), // input wire [7:0] tx_digitalreset, //
.rx_analogreset (rx_analogreset ), // input wire [7:0] rx_analogreset, //
.rx_digitalreset (rx_digitalreset ), // input wire [7:0] rx_digitalreset, //
.tx_cal_busy (tx_cal_busy ), // output wire [7:0] tx_cal_busy, //
.rx_cal_busy (rx_cal_busy ), // output wire [7:0] rx_cal_busy, //
.tx_bonding_clocks ({LANES{tx_bonding_clocks}} ), // input wire [47:0] tx_bonding_clocks, //
.rx_cdr_refclk0 (rx_cdr_refclk0 ), // input wire rx_cdr_refclk0, //
.tx_serial_data (tx_serial_data ), // output wire [7:0] tx_serial_data, //
.rx_serial_data (rx_serial_data ), // input wire [7:0] rx_serial_data, //
.rx_set_locktodata (rx_set_locktodata ), // input wire [7:0] rx_set_locktodata, //
.rx_set_locktoref (rx_set_locktoref ), // input wire [7:0] rx_set_locktoref, //
.rx_is_lockedtoref (rx_is_lockedtoref ), // output wire [7:0] rx_is_lockedtoref, //
.rx_is_lockedtodata (rx_is_lockedtodata ), // output wire [7:0] rx_is_lockedtodata, //
.tx_hip_data (tx_hip_data ), // input wire [511:0] tx_hip_data, //
.rx_hip_data (rx_hip_data ), // output wire [407:0] rx_hip_data, //
.hip_pipe_pclk (hip_pipe_pclk ), // output wire hip_pipe_pclk, //
.hip_fixedclk (hip_fixedclk ), // output wire hip_fixedclk, //
.hip_frefclk (hip_frefclk ), // output wire [7:0] hip_frefclk, //
.hip_ctrl (hip_ctrl ), // output wire [63:0] hip_ctrl, //
.hip_cal_done (chnl_cal_done ), // output wire [7:0] hip_cal_done, //
.pipe_rate (pipe_rate ), // input wire [15:0] pipe_rate, //
.pipe_sw_done (pcie_sw_done ), // input wire [1:0] pipe_sw_done, //
.pipe_sw (pcie_sw ), // output wire [1:0] pipe_sw, //
.pipe_hclk_in (pll_pcie_clk_int ), // input wire pipe_hclk_in, //
.pipe_g3_txdeemph (pipe_g3_txdeemph ), // input wire [143:0] pipe_g3_txdeemph, //
.pipe_g3_rxpresethint (pipe_g3_rxpresethint ), // input wire [23:0] pipe_g3_rxpresethint, //
.pipe_rx_eidleinfersel (pipe_rx_eidleinfersel ), // input wire [23:0] pipe_rx_eidleinfersel, //
.pipe_rx_elecidle (pipe_rx_elecidle ), // output wire [7:0] pipe_rx_elecidle, //
.pipe_rx_polarity (pipe_rx_polarity ), // input wire [7:0] pipe_rx_polarity //
.hip_reduce_counters (hip_reduce_counters ),
.pcie_rate (current_rate ), // PCIe generation
.ltssm_rcvr_phase_two (ltssm_eq_phase2 ), // LTSSM equalization Phase2
.ltssm_detect_active (ltssm_detect_active ), // LTSSM Detect Active state
.ltssm_detect_quiet (ltssm_detect_quiet ), // LTSSM Detect Quiet state
.reconfig_clk (reconfig_clk ), // input wire [0:0] reconfig_clk,
.reconfig_reset (reconfig_reset ), // input wire [0:0] reconfig_reset,
.reconfig_write (reconfig_write ), // input wire [0:0] reconfig_write,
.reconfig_read (reconfig_read ), // input wire [0:0] reconfig_read,
.reconfig_address (reconfig_address ), // input wire [9:0] reconfig_address,
.reconfig_writedata (reconfig_writedata ), // input wire [31:0] reconfig_writedata,
.reconfig_readdata (reconfig_readdata ), // output wire [31:0] reconfig_readdata,
.reconfig_waitrequest (reconfig_waitrequest ), // output wire [0:0] reconfig_waitrequest
.rx_polinv (rx_polinv ) // input wire [7:0] rx_polinv
);
end
end
end
endgenerate
////////////////////////////////////
/////////// ATX PLL ////////////
////////////////////////////////////
generate begin : g_pll
// TODO
wire OPEN_hip_cal_done;
wire OPEN_pll_locked;
if ((protocol_version=="Gen 1") || (protocol_version=="Gen 2")) begin
if (xn_design==0) begin : g_pll_g1g2x1
fpll_g1g2x1 fpll_g1g2x1 (
.pll_powerdown (pll_powerdown_fpll ), // input wire pll_powerdown, //
.pll_refclk0 (pll_refclk0 ), // input wire pll_refclk0, //
.tx_serial_clk (tx_serial_clk0 ), // output wire tx_serial_clk, //
.pll_locked (pll_locked_fpll ), // output wire pll_locked, //
.pll_pcie_clk (pll_pcie_clk ), // output wire pll_pcie_clk, //
.hip_cal_done (pll_cal_done_fpll ), // output wire hip_cal_done //
.reconfig_clk0 (reconfig_pll0_clk ), // reconfig_clk0.clk
.reconfig_reset0 (reconfig_pll0_reset ), // reconfig_reset0.reset
.reconfig_write0 (reconfig_pll0_write ), // reconfig_avmm0.write
.reconfig_read0 (reconfig_pll0_read ), // .read
.reconfig_address0 (reconfig_pll0_address ), // .address
.reconfig_writedata0 (reconfig_pll0_writedata ), // .writedata
.reconfig_readdata0 (reconfig_pll0_readdata ), // .readdata
.reconfig_waitrequest0 (reconfig_pll0_waitrequest ) // .waitrequest
);
end
else begin : g_pll_g12n
fpll_g1g2xn fpll_g1g2xn (
.pll_powerdown (pll_powerdown_fpll ), // input wire pll_powerdown,
.pll_refclk0 (pll_refclk0 ), // input wire pll_refclk0,
.pll_locked (pll_locked_fpll ), // output wire pll_locked,
.pll_pcie_clk (pll_pcie_clk ), // output wire pll_pcie_clk,
.mcgb_hip_cal_done (pll_cal_done_fpll ), // output wire mcgb_hip_cal_done,
.mcgb_rst (mcgb_rst ), // input wire mcgb_rst,
.tx_bonding_clocks (tx_bonding_clocks ), // output wire [5:0] tx_bonding_clocks,
.pcie_sw (pcie_sw ), // input wire [1:0] pcie_sw,
.pcie_sw_done (pcie_sw_done ), // output wire [1:0] pcie_sw_done,
.reconfig_clk0 (reconfig_pll0_clk ), // reconfig_clk0.clk
.reconfig_reset0 (reconfig_pll0_reset ), // reconfig_reset0.reset
.reconfig_write0 (reconfig_pll0_write ), // reconfig_avmm0.write
.reconfig_read0 (reconfig_pll0_read ), // .read
.reconfig_address0 (reconfig_pll0_address ), // .address
.reconfig_writedata0 (reconfig_pll0_writedata ), // .writedata
.reconfig_readdata0 (reconfig_pll0_readdata ), // .readdata
.reconfig_waitrequest0 (reconfig_pll0_waitrequest ) // .waitrequest
);
end
end
else begin // protocol_version=="Gen 3"
fpll_g3 fpll_g3 (
.pll_refclk0 (pll_refclk0 ), // input wire pll_refclk0,
.pll_powerdown (pll_powerdown_fpll ), // input wire pll_powerdown,
.pll_locked (pll_locked_fpll ), // output wire pll_locked, // TODO Connect to something
.tx_serial_clk (tx_serial_clk0 ), // output wire ,
.pll_pcie_clk (pll_pcie_clk ),
.hip_cal_done (pll_cal_done_fpll ), // output wire hip_cal_done // TODO Connect to something
.reconfig_clk0 (reconfig_pll0_clk ), // reconfig_clk0.clk
.reconfig_reset0 (reconfig_pll0_reset ), // reconfig_reset0.reset
.reconfig_write0 (reconfig_pll0_write ), // reconfig_avmm0.write
.reconfig_read0 (reconfig_pll0_read ), // .read
.reconfig_address0 (reconfig_pll0_address ), // .address
.reconfig_writedata0 (reconfig_pll0_writedata ), // .writedata
.reconfig_readdata0 (reconfig_pll0_readdata ), // .readdata
.reconfig_waitrequest0 (reconfig_pll0_waitrequest ) // .waitrequest
);
if (xn_design==0) begin : g_pll_g3x1
lcpll_g3x1 lcpll_g3x1 (
.pll_powerdown (pll_powerdown_lcpll ),// input wire pll_powerdown, //
.pll_refclk0 (pll_refclk0 ),// input wire pll_refclk0, //
.tx_serial_clk (tx_serial_clk1 ),// output wire tx_serial_clk, //
.pll_locked (pll_locked_lcpll ),// output wire pll_locked,
.hip_cal_done (pll_cal_done_lcpll ),// output wire hip_cal_done //
.reconfig_clk0 (reconfig_pll1_clk ), // reconfig_clk0.clk
.reconfig_reset0 (reconfig_pll1_reset ), // reconfig_reset0.reset
.reconfig_write0 (reconfig_pll1_write ), // reconfig_avmm0.write
.reconfig_read0 (reconfig_pll1_read ), // .read
.reconfig_address0 (reconfig_pll1_address ), // .address
.reconfig_writedata0 (reconfig_pll1_writedata ), // .writedata
.reconfig_readdata0 (reconfig_pll1_readdata ), // .readdata
.reconfig_waitrequest0 (reconfig_pll1_waitrequest ) // .waitrequest
);
end
else begin : g_pll_g3n
lcpll_g3xn lcpll_g3xn (
.pll_powerdown (pll_powerdown_lcpll ), // input wire pll_powerdown, // pll_powerdown.pll_powerdown
.pll_refclk0 (pll_refclk0 ), // input wire pll_refclk0, // pll_refclk0.clk
.pll_locked (pll_locked_lcpll ), // output wire pll_locked, // pll_locked.pll_locked
.hip_cal_done (pll_cal_done_lcpll ), // output wire hip_cal_done, // hip_cal_done.hip_cal_done
.mcgb_rst (mcgb_rst ), // input wire mcgb_rst, // mcgb_rst.mcgb_rst
.mcgb_aux_clk0 (tx_serial_clk0 ),
.tx_bonding_clocks (tx_bonding_clocks ), // output wire [5:0] mcgb_bonding_clk, // mcgb_bonding_clk.mcgb_bonding_clk
.pcie_sw (pcie_sw ), // input wire [1:0] pcie_sw, // pcie_sw.pcie_sw // ONLY used in bonded mode, for X1 phy_ip has internal CGB
.pcie_sw_done (pcie_sw_done ), // output wire [1:0] pcie_sw_done, // pcie_sw_done.pcie_sw_done //
.reconfig_clk0 (reconfig_pll1_clk ), // reconfig_clk0.clk
.reconfig_reset0 (reconfig_pll1_reset ), // reconfig_reset0.reset
.reconfig_write0 (reconfig_pll1_write ), // reconfig_avmm0.write
.reconfig_read0 (reconfig_pll1_read ), // .read
.reconfig_address0 (reconfig_pll1_address ), // .address
.reconfig_writedata0 (reconfig_pll1_writedata ), // .writedata
.reconfig_readdata0 (reconfig_pll1_readdata ), // .readdata
.reconfig_waitrequest0 (reconfig_pll1_waitrequest ) // .waitrequest
);
end
end
end
endgenerate
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_a10_scfifo_ext ( data,
clock,
wrreq,
rdreq,
aclr,
sclr,
q,
usedw,
full,
empty,
almost_full,
almost_empty);
// GLOBAL PARAMETER DECLARATION
parameter lpm_width = 1;
parameter lpm_widthu = 1;
parameter lpm_numwords = 2;
parameter lpm_showahead = "OFF";
parameter lpm_type = "scfifo";
parameter lpm_hint = "USE_EAB=ON";
parameter intended_device_family = "Stratix V";
parameter underflow_checking = "ON";
parameter overflow_checking = "ON";
parameter allow_rwcycle_when_full = "OFF";
parameter use_eab = "ON";
parameter add_ram_output_register = "OFF";
parameter almost_full_value = 0;
parameter almost_empty_value = 0;
parameter maximum_depth = 0;
// LOCAL_PARAMETERS_BEGIN
parameter showahead_area = ((lpm_showahead == "ON") && (add_ram_output_register == "OFF"));
parameter showahead_speed = ((lpm_showahead == "ON") && (add_ram_output_register == "ON"));
parameter legacy_speed = ((lpm_showahead == "OFF") && (add_ram_output_register == "ON"));
// LOCAL_PARAMETERS_END
// INPUT PORT DECLARATION
input [lpm_width-1:0] data;
input clock;
input wrreq;
input rdreq;
input aclr;
input sclr;
// OUTPUT PORT DECLARATION
output [lpm_width-1:0] q;
output [lpm_widthu-1:0] usedw;
output full;
output empty;
output almost_full;
output almost_empty;
localparam [511:0] ZER0S=512'h0;
localparam NUM_FIFO32=(lpm_numwords<33)?1:lpm_numwords>>5;
wire [4:0] usedw_int;
assign almost_full =1'b0;
assign almost_empty =1'b0;
reg [2:0] aclr_s2_clock;
always @ (posedge clock or posedge aclr) begin
if(aclr) begin
aclr_s2_clock[2:0]<=3'h7;
end
else begin
aclr_s2_clock[2]<=aclr_s2_clock[1];
aclr_s2_clock[1]<=aclr_s2_clock[0];
aclr_s2_clock[0]<=1'b0;
end
end
altpcie_scfifo_aa_deep #(
.WIDTH (lpm_width), // typical 20,40,60,80
.NUM_FIFO32 (NUM_FIFO32) // Number of 32 DEEP FIFO; Valid Range 1,2,3,4 // When 0 only 16 deep
) pmfifo (
.clk (clock) , // input
.sclr (sclr|aclr_s2_clock[2]) , // input
.wdata (data) , // input [WIDTH-1:0]
.wreq (wrreq) , // input
.full (full) , // output
.rdata (q) , // output [WIDTH-1:0]
.rreq (rdreq) , // input
.empty (empty) , // output
.used (usedw_int) // output [4:0]
);
generate begin : g_depth
if (lpm_widthu<6) begin : g_depth1
assign usedw[lpm_widthu-1:0] = usedw_int[4:0];
end
else begin : g_depth2
assign usedw[lpm_widthu-1:0] = {ZER0S[lpm_widthu-6:0],usedw_int[4:0]};
end
end
endgenerate
endmodule
// Cascaded 32 Deep paramerizable single clock FIFOs
// Width parameterizable FIFO
// optimized for SV
// Depth 32 words blocks
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_scfifo_aa_deep #(
parameter WIDTH = 20, // typical 20,40,60,80
parameter NUM_FIFO32 = 1 // Number of 32 DEEP FIFO; Valid Range 1,2,3,4
// When 0 only 16 deep
)(
input clk , // input
input sclr , // input
input [WIDTH-1:0] wdata , // input [WIDTH-1:0]
input wreq , // input
output full , // output
output [WIDTH-1:0] rdata , // output [WIDTH-1:0]
input rreq , // input
output empty , // output
output [4:0] used // output [4:0]
);
localparam ZEROS = 512'h0;
localparam TARGET_CHIP = 2; // 1 S4, 2 S5,
localparam SIM_EMULATE = 1'b0; // simulation equivalent, only for S5 right now
localparam PREVENT_OVERFLOW = 1'b1; // ignore requests that would cause overflow
localparam PREVENT_UNDERFLOW = 1'b1; // ignore requests that would cause underflow
localparam RAM_GROUPS = (WIDTH < 20) ? 1 : (WIDTH / 20); // min 1, WIDTH must be divisible by RAM_GROUPS
localparam GROUP_RADDR = (WIDTH < 20) ? 1'b0 : 1'b1; // 1 to duplicate RADDR per group as well as WADDR
localparam FLAG_DUPES = 1; // if > 1 replicate full / empty flags for fanout balancing
localparam ADDR_WIDTH = (NUM_FIFO32==0)?4:5; // 4 or 5
localparam DISABLE_USED = 1'b0;
wire [WIDTH-1:0] wdata0 ; // input [WIDTH-1:0]
wire wreq0 ; // input
wire full0 ; // output
wire [WIDTH-1:0] rdata0 ; // output [WIDTH-1:0]
wire rreq0 ; // input
wire empty0 ; // output
wire [4:0] used0 ; // output [4:0]
altpcie_scfifo_a10 #(
.WIDTH (WIDTH ),
.NUM_FIFO32 ((NUM_FIFO32<4)?NUM_FIFO32:4)
) gb0fifo (
.clk (clk ), // input
.sclr (sclr ), // input
.wdata (wdata0 ), // input [WIDTH-1:0]
.wreq (wreq0 & !full0 ), // input
.full (full0 ), // output [FLAG_DUPES-1:0]
.rdata (rdata0 ), // output [WIDTH-1:0]
.rreq (rreq0 ), // input
.empty (empty0 ), // output [FLAG_DUPES-1:0]
.used (used0[ADDR_WIDTH-1:0]) // output [ADDR_WIDTH-1:0]
);
assign wdata0 = wdata;
assign full = full0;
assign wreq0 = wreq;
generate begin : g_scfifo
if (NUM_FIFO32>4) begin : g_scfifo1
wire [WIDTH-1:0] wdata1 ;
wire wreq1 ;
wire full1 ;
wire [WIDTH-1:0] rdata1 ;
wire rreq1 ;
wire empty1 ;
wire [4:0] used1 ;
reg wreq1_d ;
reg full1_d ;
reg rreq0_d ;
reg rreq0_l ;
altpcie_scfifo_a10 #(
.WIDTH (WIDTH ),
.NUM_FIFO32 ((NUM_FIFO32<8)?NUM_FIFO32-4:4)
) gb1fifo (
.clk (clk ),
.sclr (sclr ),
.wdata (wdata1 ),
.wreq (wreq1 & !full1 ),
.full (full1 ),
.rdata (rdata1 ),
.rreq (rreq1 ),
.empty (empty1 ),
.used (used1 )
);
assign wdata1 = rdata0;
assign rreq0 = ((empty0==1'b0)&&(full1==1'b0))?1'b1:1'b0;
assign wreq1 = wreq1_d || ((rreq0_l == 1'b1) && (full1 == 1'b0));
always @(posedge clk) begin : p_wreq1
if (sclr == 1'b1 ) begin
wreq1_d <= 1'b0;
full1_d <= 1'b0;
rreq0_d <= 1'b0;
end
else begin
wreq1_d <= ((empty0==1'b0)&&(full1==1'b0))?1'b1:1'b0;
full1_d <= full1;
rreq0_d <= rreq0;
end
end
always @(posedge clk) begin : p_rreq0_l
if (sclr == 1'b1 ) begin
rreq0_l <= 1'b0;
end
else begin
if (full1 == 1'b0)
rreq0_l <= 1'b0;
else if ((full1 == 1'b1) && (rreq0_d == 1'b1))
rreq0_l <= 1'b1;
end
end
if (NUM_FIFO32>8) begin : g_scfifo2
wire [WIDTH-1:0] wdata2 ;
wire wreq2 ;
wire full2 ;
wire [WIDTH-1:0] rdata2 ;
wire rreq2 ;
wire empty2 ;
wire [4:0] used2 ;
reg wreq2_d ;
reg full2_d ;
reg rreq1_d ;
reg rreq1_l ;
altpcie_scfifo_a10 #(
.WIDTH (WIDTH ),
.NUM_FIFO32 ((NUM_FIFO32<12)?NUM_FIFO32-8:4)
) gb2fifo (
.clk (clk ),
.sclr (sclr ),
.wdata (wdata2 ),
.wreq (wreq2 & !full2 ),
.full (full2 ),
.rdata (rdata2 ),
.rreq (rreq2 ),
.empty (empty2 ),
.used (used2 )
);
assign wdata2 = rdata1;
assign rreq1 = ((empty1==1'b0)&&(full2==1'b0))?1'b1:1'b0;
assign wreq2 = wreq2_d || ((rreq1_l == 1'b1) && (full2 == 1'b0));
always @(posedge clk) begin : p_wreq2
if (sclr == 1'b1 ) begin
wreq2_d <= 1'b0;
full2_d <= 1'b0;
rreq1_d <= 1'b0;
end
else begin
wreq2_d <= ((empty1==1'b0)&&(full2==1'b0))?1'b1:1'b0;
full2_d <= full2;
rreq1_d <= rreq1;
end
end
always @(posedge clk) begin : p_rreq1_latch
if (sclr == 1'b1 ) begin
rreq1_l <= 1'b0;
end
else begin
if (full2 == 1'b0)
rreq1_l <= 1'b0;
else if ((full2 == 1'b1) && (rreq1_d == 1'b1))
rreq1_l <= 1'b1;
end
end
if (NUM_FIFO32>12) begin : g_scfifo6
wire [WIDTH-1:0] wdata3 ;
wire wreq3 ;
wire full3 ;
wire [WIDTH-1:0] rdata3 ;
wire rreq3 ;
wire empty3 ;
wire [4:0] used3 ;
reg wreq3_d ;
reg full3_d ;
reg rreq2_d ;
reg rreq2_l ;
altpcie_scfifo_a10 #(
.WIDTH (WIDTH ),
.NUM_FIFO32 ((NUM_FIFO32<16)?NUM_FIFO32-12:4)
) gb3fifo (
.clk (clk ),
.sclr (sclr ),
.wdata (wdata3 ),
.wreq (wreq3 & !full3 ),
.full (full3 ),
.rdata (rdata3 ),
.rreq (rreq3 ),
.empty (empty3 ),
.used (used3 )
);
assign wdata3 = rdata2;
assign rreq2 = ((empty2==1'b0)&&(full3==1'b0))?1'b1:1'b0;
assign wreq3 = wreq3_d || ((rreq2_l == 1'b1) && (full3 == 1'b0));
always @(posedge clk) begin : p_wreq3
if (sclr == 1'b1 ) begin
wreq3_d <= 1'b0;
full3_d <= 1'b0;
rreq2_d <= 1'b0;
end
else begin
wreq3_d <= ((empty2==1'b0)&&(full3==1'b0))?1'b1:1'b0;
full3_d <= full3;
rreq2_d <= rreq2;
end
end
always @(posedge clk) begin : p_rreq2_latch
if (sclr == 1'b1 ) begin
rreq2_l <= 1'b0;
end
else begin
if (full3 == 1'b0)
rreq2_l <= 1'b0;
else if ((full3 == 1'b1) && (rreq2_d == 1'b1))
rreq2_l <= 1'b1;
end
end
assign empty = empty3 ;
//assign full = full2 & full1 & full0 & full3;
assign rdata = rdata3 ;
assign used = used3 ;
assign rreq3 = rreq ;
end
else begin : g_scfifo3
assign empty = empty2 ;
//assign full = full2 & full1 & full0 ;
assign rdata = rdata2 ;
assign used = used2 ;
assign rreq2 = rreq ;
end
end
else begin : g_scfifo4
assign empty = empty1 ;
//assign full = full1 & full0 ;
assign rdata = rdata1 ;
assign used = used1 ;
assign rreq1 = rreq ;
end
end
else begin : g_scfifo5
assign rreq0 = rreq ;
assign empty = empty0 ;
//assign full = full0 ;
assign rdata = rdata0 ;
assign used = (NUM_FIFO32==0)?{1'b0,used0[3:0]}:used0[4:0] ;
end
end
endgenerate
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_reset_delay_sync #(
parameter ACTIVE_RESET = 0,
parameter WIDTH_RST = 1,
parameter NODENAME = "altpcie_reset_delay_sync",// Expecting Instance name
parameter LOCK_TIME_CNT_WIDTH = 1
) (
input clk,
input async_rst,
output reg [WIDTH_RST-1:0] sync_rst /* synthesis preserve */
);
wire sync_rst_clk;
localparam SDC={"-name SDC_STATEMENT \"set_false_path -from [get_fanins -async *", NODENAME ,"*rs_meta\[*\]] -to [get_keepers *", NODENAME ,"*rs_meta\[*\]]\" "};
(* altera_attribute = SDC *)
reg [2:0] rs_meta = (ACTIVE_RESET==0)?3'b000:3'b111 /* synthesis preserve dont_replicate */;
// synthesis translate_off
initial begin
sync_rst[WIDTH_RST-1:0]={WIDTH_RST{1'b0}};
$display("INFO: altpcie_reset_delay_sync::---------------------------------------------------------------------------------------------");
$display("INFO: altpcie_reset_delay_sync:: NODENAME is %s", NODENAME);
$display("INFO: altpcie_reset_delay_sync:: SDC is %s", SDC);
rs_meta = (ACTIVE_RESET==0)?3'b000:3'b111;
end
// synthesis translate_on
always @(posedge clk) begin
sync_rst[WIDTH_RST-1:0] <= {WIDTH_RST{sync_rst_clk}};
end
generate begin : g_rstsync
if (ACTIVE_RESET==0) begin : g_rstsync
always @(posedge clk or negedge async_rst) begin
if (!async_rst) rs_meta <= 3'b000;
else rs_meta <= {rs_meta[1:0],1'b1};
end
if (LOCK_TIME_CNT_WIDTH>1) begin : g_rstsync1
wire ready_sync = rs_meta[2];
reg [LOCK_TIME_CNT_WIDTH-1:0] cntr = {LOCK_TIME_CNT_WIDTH{1'b0}} /* synthesis preserve */;
assign sync_rst_clk = cntr[LOCK_TIME_CNT_WIDTH-1];
always @(posedge clk) begin
sync_rst[WIDTH_RST-1:0] <= {WIDTH_RST{sync_rst_clk}};
end
always @(posedge clk or negedge ready_sync) begin
if (!ready_sync) cntr <= {LOCK_TIME_CNT_WIDTH{1'b0}};
else if (!sync_rst_clk) cntr <= cntr + 1'b1;
end
end
else begin : g_rstsync2
assign sync_rst_clk = rs_meta[2];
end
end
else begin : g_rstsync3 // ACTIVE_RESET=1
always @(posedge clk or posedge async_rst) begin
if (async_rst) rs_meta <= 3'b111;
else rs_meta <= {rs_meta[1:0],1'b0};
end
if (LOCK_TIME_CNT_WIDTH>1) begin : g_rstsync4
wire ready_sync = rs_meta[2];
wire sync_rst_clkn ;
reg [LOCK_TIME_CNT_WIDTH-1:0] cntr = {LOCK_TIME_CNT_WIDTH{1'b0}} /* synthesis preserve */;
assign sync_rst_clk=~sync_rst_clk;
assign sync_rst_clkn = cntr[LOCK_TIME_CNT_WIDTH-1];
always @(posedge clk or posedge ready_sync) begin
if (ready_sync) cntr <= {LOCK_TIME_CNT_WIDTH{1'b0}};
else if (!sync_rst_clkn) cntr <= cntr + 1'b1;
end
end
else begin : g_rstsync5
assign sync_rst_clk = rs_meta[2];
end
end
end
endgenerate
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// Complementary HIP reset logic (hiprst) used along with the
// HIP hard reset controller
//
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_rs_a10_hip (
input pld_clk,
input dlup_exit,
input hotrst_exit,
input l2_exit,
input npor_core,
input [4: 0] ltssm,
output reg hiprst
);
localparam [4:0] LTSSM_POL = 5'b00010;
localparam [4:0] LTSSM_CPL = 5'b00011;
localparam [4:0] LTSSM_DET = 5'b00000;
localparam [4:0] LTSSM_RCV = 5'b01100;
localparam [4:0] LTSSM_DIS = 5'b10000;
localparam [4:0] LTSSM_DETA = 5'b00001;
localparam [4:0] LTSSM_DETQ = 5'b00000;
reg hiprst_r;
wire npor_sync ;
reg dlup_exit_r;
reg exits_r;
reg hotrst_exit_r;
reg l2_exit_r;
reg [4: 0] rsnt_cntn;
reg [4: 0] ltssm_r;
reg [4: 0] ltssm_rr;
//reset Synchronizer
altpcie_reset_delay_sync #(
.ACTIVE_RESET (0),
.WIDTH_RST (1),
.NODENAME ("npor_sync_altpcie_reset_delay_sync_altpcie_rs_a10_hip"),
.LOCK_TIME_CNT_WIDTH (1)
) npor_sync_altpcie_reset_delay_sync_altpcie_rs_a10_hip(
.clk (pld_clk),
.async_rst (npor_core),
.sync_rst (npor_sync)
);
//Reset delay
always @(posedge pld_clk or negedge npor_sync) begin
if (npor_sync == 1'b0) begin
rsnt_cntn <= 5'h0;
end
else if (exits_r == 1'b1) begin
rsnt_cntn <= 5'd10;
end
else if (rsnt_cntn != 5'd20) begin
rsnt_cntn <= rsnt_cntn + 5'h1;
end
end
//sync and config reset
always @(posedge pld_clk or negedge npor_sync) begin
if (npor_sync == 1'b0) begin
hiprst_r <= 1'b1;
end
else begin
if (exits_r == 1'b1) begin
hiprst_r <= 1'b1;
end
else if (rsnt_cntn == 5'd20) begin
hiprst_r <= 1'b0;
end
end
end
always @(posedge pld_clk or negedge npor_sync) begin
if (npor_sync == 1'b0) begin
dlup_exit_r <= 1'b1;
hotrst_exit_r <= 1'b1;
l2_exit_r <= 1'b1;
exits_r <= 1'b0;
hiprst <= 1'b1;
ltssm_r <= LTSSM_DETQ;
ltssm_rr <= LTSSM_DETQ;
end
else begin
ltssm_r <= ltssm;
ltssm_rr <= ltssm_r;
hiprst <= hiprst_r;
dlup_exit_r <= dlup_exit;
hotrst_exit_r <= hotrst_exit;
l2_exit_r <= l2_exit;
exits_r <= ((l2_exit_r == 1'b0)||(hotrst_exit_r == 1'b0)||(dlup_exit_r == 1'b0)||(ltssm_r == LTSSM_DIS))?1'b1:1'b0;
end
end
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_sc_bitsync
#(
parameter DWIDTH = 1, // Sync Data input
parameter NODENAME = "altpcie_sc_bitsync", // Expecting Instance name
parameter SYNCSTAGE = 2, // Sync stages
parameter SDC_TYPE = 0, // 0: Multi Cycle=3, 1:Multi Cycle=2, 2: Set False Path
parameter RESET_VAL = 0 // Reset value
)
(
input wire clk, // clock
input wire rst_n, // async reset
input wire [DWIDTH-1:0] data_in, // data in
output wire [DWIDTH-1:0] data_out // data out
);
localparam SYNCSTAGE_INT=SYNCSTAGE-1;
// set of handy SDC constraints
localparam MULTI_2 = {"-name SDC_STATEMENT \"set_multicycle_path -to [get_keepers *" , NODENAME , "*altpcie_sc_bitsync_meta_dff\[*\]] 2\" "};
localparam MULTI_3 = {"-name SDC_STATEMENT \"set_multicycle_path -to [get_keepers *" , NODENAME , "*altpcie_sc_bitsync_meta_dff\[*\]] 3\" "};
localparam FPATH = {"-name SDC_STATEMENT \"set_false_path -to [get_keepers *" , NODENAME , "*altpcie_sc_bitsync_meta_dff\[*\]]\" "};
localparam FHOLD = {"-name SDC_STATEMENT \"set_false_path -hold -to [get_keepers *", NODENAME , "*altpcie_sc_bitsync_meta_dff\[*\]]\" "};
localparam SDC = (SDC_TYPE==0)?{MULTI_3,";",FHOLD}:(SDC_TYPE==1)?{MULTI_2,";",FHOLD}:{FPATH ,";",FHOLD};
// synthesis translate_off
initial begin
$display("INFO: altpcie_sc_bitsync::---------------------------------------------------------------------------------------------");
$display("INFO: altpcie_sc_bitsync:: NODENAME is %s", NODENAME);
$display("INFO: altpcie_sc_bitsync:: SDC is %s", SDC);
end
// synthesis translate_on
// Define wires/regs
(* altera_attribute = SDC *)
reg [DWIDTH-1:0] altpcie_sc_bitsync_meta_dff;
wire reset_value;
assign reset_value = (RESET_VAL == 1) ? 1'b1 : 1'b0; // To eliminate truncating warning
generate begin : g_bitsync
if (SYNCSTAGE==2) begin : g_bitsync2
// Sync Always block
// Sync Always block
reg [DWIDTH-1:0] sync_regs;
reg [DWIDTH-1:0] sync_regsb;
always @(negedge rst_n or posedge clk) begin
if (rst_n == 1'b0) begin
sync_regs[DWIDTH-1:0] <= {(DWIDTH){reset_value}};
sync_regsb[DWIDTH-1:0] <= {(DWIDTH){reset_value}};
end
else begin
sync_regs[DWIDTH-1:0] <= altpcie_sc_bitsync_meta_dff;
sync_regsb[DWIDTH-1:0] <= sync_regs[DWIDTH-1:0] ;
end
end
assign data_out[DWIDTH-1:0] = sync_regsb[DWIDTH-1:0];
end
else if (SYNCSTAGE==3) begin : g_bitsync3
// Sync Always block
// Sync Always block
reg [DWIDTH-1:0] sync_regs;
reg [DWIDTH-1:0] sync_regsb;
reg [DWIDTH-1:0] sync_regsc;
always @(negedge rst_n or posedge clk) begin
if (rst_n == 1'b0) begin
sync_regs[DWIDTH-1:0] <= {(DWIDTH){reset_value}};
sync_regsb[DWIDTH-1:0] <= {(DWIDTH){reset_value}};
sync_regsc[DWIDTH-1:0] <= {(DWIDTH){reset_value}};
end
else begin
sync_regs[DWIDTH-1:0] <= altpcie_sc_bitsync_meta_dff;
sync_regsb[DWIDTH-1:0] <= sync_regs[DWIDTH-1:0] ;
sync_regsc[DWIDTH-1:0] <= sync_regsb[DWIDTH-1:0] ;
end
end
assign data_out[DWIDTH-1:0] = sync_regsc[DWIDTH-1:0];
end
else begin : g_bitsync4
// Sync Always block
reg [DWIDTH-1:0] sync_regs;
always @(negedge rst_n or posedge clk) begin
if (rst_n == 1'b0) begin
sync_regs[DWIDTH-1:0] <= {(DWIDTH){reset_value}};
end
else begin
sync_regs[DWIDTH-1:0] <= altpcie_sc_bitsync_meta_dff;
end
end
assign data_out[DWIDTH-1:0] = sync_regs[DWIDTH-1:0];
end
end
endgenerate
// Separated out the first stage of FFs without reset
always @(posedge clk) begin
altpcie_sc_bitsync_meta_dff[DWIDTH-1:0] <= data_in;
end
endmodule // altpcie_sc_bitsync
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_sc_bitsync_node
#(
parameter DWIDTH = 1, // Sync Data input
parameter NODENAME = "altpcie_sc_bitsync_node", // Instance name
parameter SYNCSTAGE = 2, // Sync stages
parameter SDC_TYPE = 0, // 0: Multi Cycle=3, 1:Multi Cycle=2, 2: Set False Path
parameter RESET_VAL = 0 // Reset value
)
(
input wire clk, // clock
input wire rst_n, // async reset
input wire [DWIDTH-1:0] data_in, // data in
output wire [DWIDTH-1:0] data_out // data out
);
altpcie_sc_bitsync #(
.DWIDTH ( DWIDTH ),// Sync Data input
.NODENAME ( NODENAME ),// Sync stages
.SYNCSTAGE ( SYNCSTAGE ),// 0: Multi Cycle=3, 1:Multi Cycle=2, 2: Set False Path
.SDC_TYPE ( SDC_TYPE ),// Instance name
.RESET_VAL ( RESET_VAL ) // Reset value
) altpcie_sc_bitsync (
.clk (clk ),// clock
.rst_n (rst_n ),// async reset
.data_in (data_in ),// data in
.data_out (data_out ) // data out
);
endmodule //altpcie_sc_bitsync_node
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// Cascaded 32 Deep paramerizable single clock FIFOs
// Width parameterizable FIFO
// optimized for SV
// Depth 32 words blocks
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_scfifo_a10 #(
parameter WIDTH = 20, // typical 20,40,60,80
parameter NUM_FIFO32 = 1 // Number of 32 DEEP FIFO; Valid Range 1,2,3,4
// When 0 only 16 deep
)(
input clk , // input
input sclr , // input
input [WIDTH-1:0] wdata , // input [WIDTH-1:0]
input wreq , // input
output full , // output
output [WIDTH-1:0] rdata , // output [WIDTH-1:0]
input rreq , // input
output empty , // output
output [4:0] used // output [4:0]
);
localparam ZEROS = 512'h0;
localparam TARGET_CHIP = 5; // 1 S4, 2 S5,
localparam SIM_EMULATE = 1'b0; // simulation equivalent, only for S5 right now
localparam PREVENT_OVERFLOW = 1'b1; // ignore requests that would cause overflow
localparam PREVENT_UNDERFLOW = 1'b1; // ignore requests that would cause underflow
localparam RAM_GROUPS = (WIDTH < 20) ? 1 : (WIDTH / 20); // min 1, WIDTH must be divisible by RAM_GROUPS
localparam GROUP_RADDR = (WIDTH < 20) ? 1'b0 : 1'b1; // 1 to duplicate RADDR per group as well as WADDR
localparam FLAG_DUPES = 1; // if > 1 replicate full / empty flags for fanout balancing
localparam ADDR_WIDTH = (NUM_FIFO32==0)?4:5; // 4 or 5
localparam DISABLE_USED = 1'b0;
wire [WIDTH-1:0] wdata0 ; // input [WIDTH-1:0]
wire wreq0 ; // input
wire full0 ; // output
wire [WIDTH-1:0] rdata0 ; // output [WIDTH-1:0]
wire rreq0 ; // input
wire empty0 ; // output
wire [4:0] used0 ; // output [4:0]
altpcie_a10_gbfifo #(
.TARGET_CHIP (TARGET_CHIP ),
.SIM_EMULATE (SIM_EMULATE ),
.WIDTH (WIDTH ),
.PREVENT_OVERFLOW (PREVENT_OVERFLOW ),
.PREVENT_UNDERFLOW (PREVENT_UNDERFLOW ),
.RAM_GROUPS (RAM_GROUPS ),
.GROUP_RADDR (GROUP_RADDR ),
.FLAG_DUPES (FLAG_DUPES ),
.ADDR_WIDTH (ADDR_WIDTH ),
.DISABLE_USED (DISABLE_USED )
) gb0fifo (
.clk (clk ), // input
.sclr (sclr ), // input
.wdata (wdata0 ), // input [WIDTH-1:0]
.wreq (wreq0 & !full0 ), // input
.full (full0 ), // output [FLAG_DUPES-1:0]
.rdata (rdata0 ), // output [WIDTH-1:0]
.rreq (rreq0 ), // input
.empty (empty0 ), // output [FLAG_DUPES-1:0]
.used (used0[ADDR_WIDTH-1:0]) // output [ADDR_WIDTH-1:0]
);
assign wdata0 = wdata;
assign full = full0;
assign wreq0 = wreq;
generate begin : g_scfifo
if (NUM_FIFO32>1) begin
wire [WIDTH-1:0] wdata1 ;
wire wreq1 ;
wire full1 ;
wire [WIDTH-1:0] rdata1 ;
wire rreq1 ;
wire empty1 ;
wire [4:0] used1 ;
reg wreq1_d ;
reg full1_d ;
reg rreq0_d ;
reg rreq0_l ;
altpcie_a10_gbfifo #(
.TARGET_CHIP (TARGET_CHIP ),
.SIM_EMULATE (SIM_EMULATE ),
.WIDTH (WIDTH ),
.PREVENT_OVERFLOW (PREVENT_OVERFLOW ),
.PREVENT_UNDERFLOW (PREVENT_UNDERFLOW ),
.RAM_GROUPS (RAM_GROUPS ),
.GROUP_RADDR (GROUP_RADDR ),
.FLAG_DUPES (FLAG_DUPES ),
.ADDR_WIDTH (ADDR_WIDTH ),
.DISABLE_USED (DISABLE_USED )
) gb1fifo (
.clk (clk ),
.sclr (sclr ),
.wdata (wdata1 ),
.wreq (wreq1 & !full1 ),
.full (full1 ),
.rdata (rdata1 ),
.rreq (rreq1 ),
.empty (empty1 ),
.used (used1 )
);
assign wdata1 = rdata0;
assign rreq0 = ((empty0==1'b0)&&(full1==1'b0))?1'b1:1'b0;
assign wreq1 = wreq1_d || ((rreq0_l == 1'b1) && (full1 == 1'b0));
always @(posedge clk) begin : p_wreq1
if (sclr == 1'b1 ) begin
wreq1_d <= 1'b0;
full1_d <= 1'b0;
rreq0_d <= 1'b0;
end
else begin
wreq1_d <= ((empty0==1'b0)&&(full1==1'b0))?1'b1:1'b0;
full1_d <= full1;
rreq0_d <= rreq0;
end
end
always @(posedge clk) begin : p_rreq0_l
if (sclr == 1'b1 ) begin
rreq0_l <= 1'b0;
end
else begin
if (full1 == 1'b0)
rreq0_l <= 1'b0;
else if ((full1 == 1'b1) && (rreq0_d == 1'b1))
rreq0_l <= 1'b1;
end
end
if (NUM_FIFO32>2) begin
wire [WIDTH-1:0] wdata2 ;
wire wreq2 ;
wire full2 ;
wire [WIDTH-1:0] rdata2 ;
wire rreq2 ;
wire empty2 ;
wire [4:0] used2 ;
reg wreq2_d ;
reg full2_d ;
reg rreq1_d ;
reg rreq1_l ;
altpcie_a10_gbfifo #(
.TARGET_CHIP (TARGET_CHIP ),
.SIM_EMULATE (SIM_EMULATE ),
.WIDTH (WIDTH ),
.PREVENT_OVERFLOW (PREVENT_OVERFLOW ),
.PREVENT_UNDERFLOW (PREVENT_UNDERFLOW ),
.RAM_GROUPS (RAM_GROUPS ),
.GROUP_RADDR (GROUP_RADDR ),
.FLAG_DUPES (FLAG_DUPES ),
.ADDR_WIDTH (ADDR_WIDTH ),
.DISABLE_USED (DISABLE_USED )
) gb2fifo (
.clk (clk ),
.sclr (sclr ),
.wdata (wdata2 ),
.wreq (wreq2 & !full2 ),
.full (full2 ),
.rdata (rdata2 ),
.rreq (rreq2 ),
.empty (empty2 ),
.used (used2 )
);
assign wdata2 = rdata1;
assign rreq1 = ((empty1==1'b0)&&(full2==1'b0))?1'b1:1'b0;
assign wreq2 = wreq2_d || ((rreq1_l == 1'b1) && (full2 == 1'b0));
always @(posedge clk) begin : p_wreq2
if (sclr == 1'b1 ) begin
wreq2_d <= 1'b0;
full2_d <= 1'b0;
rreq1_d <= 1'b0;
end
else begin
wreq2_d <= ((empty1==1'b0)&&(full2==1'b0))?1'b1:1'b0;
full2_d <= full2;
rreq1_d <= rreq1;
end
end
always @(posedge clk) begin : p_rreq1_latch
if (sclr == 1'b1 ) begin
rreq1_l <= 1'b0;
end
else begin
if (full2 == 1'b0)
rreq1_l <= 1'b0;
else if ((full2 == 1'b1) && (rreq1_d == 1'b1))
rreq1_l <= 1'b1;
end
end
if (NUM_FIFO32>3) begin
wire [WIDTH-1:0] wdata3 ;
wire wreq3 ;
wire full3 ;
wire [WIDTH-1:0] rdata3 ;
wire rreq3 ;
wire empty3 ;
wire [4:0] used3 ;
reg wreq3_d ;
reg full3_d ;
reg rreq2_d ;
reg rreq2_l ;
altpcie_a10_gbfifo #(
.TARGET_CHIP (TARGET_CHIP ),
.SIM_EMULATE (SIM_EMULATE ),
.WIDTH (WIDTH ),
.PREVENT_OVERFLOW (PREVENT_OVERFLOW ),
.PREVENT_UNDERFLOW (PREVENT_UNDERFLOW ),
.RAM_GROUPS (RAM_GROUPS ),
.GROUP_RADDR (GROUP_RADDR ),
.FLAG_DUPES (FLAG_DUPES ),
.ADDR_WIDTH (ADDR_WIDTH ),
.DISABLE_USED (DISABLE_USED )
) gb3fifo (
.clk (clk ),
.sclr (sclr ),
.wdata (wdata3 ),
.wreq (wreq3 & !full3 ),
.full (full3 ),
.rdata (rdata3 ),
.rreq (rreq3 ),
.empty (empty3 ),
.used (used3 )
);
assign wdata3 = rdata2;
assign rreq2 = ((empty2==1'b0)&&(full3==1'b0))?1'b1:1'b0;
assign wreq3 = wreq3_d || ((rreq2_l == 1'b1) && (full3 == 1'b0));
always @(posedge clk) begin : p_wreq3
if (sclr == 1'b1 ) begin
wreq3_d <= 1'b0;
full3_d <= 1'b0;
rreq2_d <= 1'b0;
end
else begin
wreq3_d <= ((empty2==1'b0)&&(full3==1'b0))?1'b1:1'b0;
full3_d <= full3;
rreq2_d <= rreq2;
end
end
always @(posedge clk) begin : p_rreq2_latch
if (sclr == 1'b1 ) begin
rreq2_l <= 1'b0;
end
else begin
if (full3 == 1'b0)
rreq2_l <= 1'b0;
else if ((full3 == 1'b1) && (rreq2_d == 1'b1))
rreq2_l <= 1'b1;
end
end
assign empty = empty3 ;
//assign full = full2 & full1 & full0 & full3;
assign rdata = rdata3 ;
assign used = used3 ;
assign rreq3 = rreq ;
end
else begin
assign empty = empty2 ;
//assign full = full2 & full1 & full0 ;
assign rdata = rdata2 ;
assign used = used2 ;
assign rreq2 = rreq ;
end
end
else begin
assign empty = empty1 ;
//assign full = full1 & full0 ;
assign rdata = rdata1 ;
assign used = used1 ;
assign rreq1 = rreq ;
end
end
else begin
assign rreq0 = rreq ;
assign empty = empty0 ;
//assign full = full0 ;
assign rdata = rdata0 ;
assign used = (NUM_FIFO32==0)?{1'b0,used0[3:0]}:used0[4:0] ;
end
end
endgenerate
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// ALTPCIE_TLP_INSPECTOR : Optional module to monitor TLP Performances on AvalonTream HIP Bus, added to ALTPCIE_HIP_256_PIPEn1B //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// ____________________________________________________________________________________________________________________________________________ //
// | | //
// | PCIe TLP Header | //
// |__________________________________________________________________________________________________________________________________________| //
// |31 30 29 |28 27 26 25 24 |23 |22 21 20 |19 |18 |17 |16 |15 |14 |13 12 |11 10 |9 8 7 6 5 4 3 2 1 0 | //
// |7 6 5 |4 3 2 1 0 |7 |6 5 4 |3 |2 |1 |0 |7 |6 |5 4 |3 2 |1 0 7 6 5 4 3 2 1 0 | //
// h1 |FMT |TYPE |R |TC |R |A |R |TH |TD |EP |Attr |ATT |Length | //
// h2 | | Last BE |First BE | //
// h3 | | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// | | //
// | MEMORY TLP | //
// |__________________________________________________________________________________________________________________________________________| //
// h2 | Requester ID | TAG | Last BE |First BE | //
// h3 | Address | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// | | //
// | COMPLETION TLP | //
// |__________________________________________________________________________________________________________________________________________| //
// h2 | Completer ID |Cpl Status | | Byte Count | //
// h3 | Requester ID | TAG | R | Lower Address | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Trigger OP Codes input trigger [127:0] // //
// //
// ---------------Trigger First Dword : 31:0 : Opcode----------------------------------------- //
// //
// trigger [0] | SOP : When 1 trigger on first SOP //
// [1] | TX/RX : When 1 trigger on RX AST, When 0 Trigger on TX AST //
// [2] | FMT_TLP : When check trigger FMT_TLP //
// [3] | TAG : When check trigger TAG //
// [5:4] | Address : When check trigger Address Lower 24 bits //
// | 5:4 =2'b01, 8-bit addr LSB //
// | 5:4 =2'b10, 16-bit addr LSB //
// | 5:4 =2'b11, 32-bit addr LSB //
// [6] | First BE : When check trigger first BE //
// [7] | Last BE : When check trigger last BE //
// [8] | Attr : When check trigger Attr //
// [9] | Reset trigger only //
// [10] | Reset reset Inspector //
// [11] | Enable Trigger ON : When set activate trigger logic - //
// [31:12] | RESERVED //
// | //
// ---------------Trigger Second Dword : 63:32 : Data Compare----------------------------------------- //
// | //
// trigger [39:32] | FMT TYPE: When trigger[2] set, trigger on //
// | _________________________________________ /
// | | | | //
// | | {FMT,TYPE} | | //
// | |_______________________________|________| //
// | | 8'b0000_0000 8'h0 8'd0 | MRd | //
// | | 8'b0010_0000 8'h20 8'd32 | MRd | //
// | | 8'b0000_0001 8'h1 8'd1 | MRdLk | //
// | | 8'b0010_0001 8'h21 8'd33 | MRdLk | //
// | | 8'b0100_0000 8'h40 8'd64 | MWr | //
// | | 8'b0110_0000 8'h60 8'd96 | MWr | //
// | | 8'b0000_0010 8'h2 8'd2 | IORd | //
// | | 8'b0100_0010 8'h42 8'd66 | IOWr | //
// | | 8'b0000_0100 8'h4 8'd4 | CfgRd0 | //
// | | 8'b0100_0100 8'h44 8'd68 | CfgWr0 | //
// | | 8'b0000_0101 8'h5 8'd5 | CfgRd1 | //
// | | 8'b0100_0101 8'h45 8'd69 | CfgWr1 | //
// | | 8'b0011_0XXX 8'h30 8'd48 | Msg | //
// | | 8'b0111_0XXX 8'h70 8'd112| MsgD | //
// | | 8'b0000_1010 8'hA 8'd10 | Cpl | //
// | | 8'b0100_1010 8'h4A 8'd74 | CplD | //
// | | 8'b0000_1011 8'hB 8'd11 | CplLk | //
// | | 8'b0100_1011 8'h4B 8'd75 | CplDLk | //
// | |________________________________________| //
// | //
// | //
// [47:40] | TAG : When trigger[3] set, trigger on TAG value //
// [51:48] | First BE : When trigger[6] set, trigger on Last BE //
// [51:48] | Last BE : When trigger[7] set, trigger on Last BE //
// [63:52] | RESERVED //
// [95:64] | when trigger[5:4]>0 32 bit lower address trigger //
// | //
// ---------------Stop Trigger [127:96]-----TODO---------------------------------------------------------------------------------------------------- //
// | //
// [96] | When set no stop trigger //
// [97] | TX/RX : When 1 stop-trigger on RX AST, When 0 Trigger on TX AST //
// [98] | FMT_TLP : When check stop-trigger FMT_TLP //
// [99] | TAG : When check stop-trigger TAG //
// [101:100]| Address : When check stop-trigger Address Lower 24 bits //
// | [101:100] =2'b01, 8-bit addr LSB //
// | [101:100] =2'b10, 16-bit addr LSB //
// | [101:100] =2'b11, 32-bit addr LSB //
// [109:102]| FMT TYPE: When stop-trigger[98] set, //
// [117:110]| TAG : When stop-trigger[99] //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// CSEB Bus Info //
// //
// |-----------------------------------------------------------------------| //
// | CSEB address Space | //
// |-----------------------------------------------------------------------| //
// | PCI/PCIe config space | Address value | //
// |-----------------------------------------------------------------------| //
// |Type0 or Type1 Configuration Registers (PCI Header) | 32'h000-32'h03Ch | //
// |Reserved | 32'h040 | //
// |Reserved | 32'h044 | //
// |Reserved | 32'h048-32'h04Ch | //
// |MSI Capability Structure | 32'h050-32'h05Ch | //
// |Reserved | 32'h060-32'h064h | //
// |MSI-X Capability Structure | 32'h068-32'h070h | //
// |Power Management Capability Structure | 32'h078-32'h07Ch | //
// |PCI Express Capability Structure | 32'h080-32'h0BCh | //
// |SSID/SSVID Capability Structure | 32'h0C0-32'h0C4h | //
// |PCI Extensions (CSEB)*** | 32'h0C8-32'h0FCh | //
// |Virtual Channel Capability Structure | 32'h100-32'h16Ch | //
// |Reserved | 32'h170-32'h1FCh | //
// |Vendor Specific Extended Capability Structure | 32'h200-32'h240h | //
// |Secondary PciE Extended Capability Structure | 32'h300-32'h318h | //
// |Reserved | 32'h31C-32'h7FCh | //
// |AER | 32'h800-32'h834h | //
// |PCI-E Extensions (CSEB) | 32'h900-32'hFFFh | //
// |-----------------------------------------------------------------------| //
// //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_tlp_inspector_a10 # (
parameter ST_DATA_WIDTH = 64,
parameter ST_BE_WIDTH = 8,
parameter LANES = 8,
parameter ST_CTRL_WIDTH = 1,
parameter USE_SIGNAL_PROBE = 0, //When 1 The SignalProbe module drives the trigger inputs
parameter POWER_UP_TRIGGER = 1,
parameter SIMPLE_TRIGGER = 0,
parameter USE_ADME = 0,
parameter PLD_CLK_IS_250MHZ = 0,
// CSEB Parameters
parameter CSEB_ENA = 1,
parameter CSEB_VSEC_BYTE_LEN = 12'h40,
parameter CSEB_VSEC_REV = 4'h1,
parameter CSEB_VSEC_ID = 16'hFACE,
//VSEC_HIPDRV
parameter VSEC_HIPDRV = 0,
parameter VSEC_HIPDRV_SIGNAL_PWR = 0,
parameter VSEC_HIPDRV_SIGNAL_PAR = 0,
// MONITOR Parameters
parameter MON_EN_INSP_ADDRNUM_WORD = 16,
parameter MON_EN_MONITOR_READYVALID_RATIO = 1,
parameter MON_EN_UPSTREAM_READ_LATENCY = 1,
parameter MON_EN_UPSTREAM_THROUGHPUT_MEASUREMENT= 1,
parameter MON_EN_BLACKBOX_LTSSM = 1,
parameter MON_EN_BLACKBOX_LTSSM_DEPTH32_BLOCK = 4 // Number of 32 Deep FIFO
) (
// Single clock domain clk (which is pld_clk in the level above)
// - All Inputs are synchronized to clk
// - All Outputs are synchronized to clk
input [127:0] trigger,
input [ST_BE_WIDTH-1 : 0] rx_st_be,
input [ST_DATA_WIDTH-1 : 0] rx_st_data,
input [1 : 0] rx_st_empty,
input [ST_CTRL_WIDTH-1 : 0] rx_st_eop,
input [ST_CTRL_WIDTH-1 : 0] rx_st_sop,
input [ST_CTRL_WIDTH-1 : 0] rx_st_valid,
input rx_st_ready,
input [ST_DATA_WIDTH-1 : 0] tx_st_data,
input [1 :0] tx_st_empty,
input [ST_CTRL_WIDTH-1 :0] tx_st_eop,
input [ST_CTRL_WIDTH-1 :0] tx_st_sop,
input tx_st_valid,
input tx_st_ready,
input [3 : 0] lane_act,
input [4 : 0] ltssmstate,
input [1 : 0] rate,
input [LANES-1:0] signaldetect,
input [LANES-1:0] is_lockedtodata,
input npor_perstn,
// Interface to HIP CSEB bus which is an extension of configuration space
output [31 : 0] csebrddata,
output [4 : 0] csebrdresponse,
output csebwaitrequest,
output [4 : 0] csebwrresponse,
output csebwrrespvalid,
input [31 : 0] csebaddr,
input [3 : 0] csebbe,
input csebisshadow,
input csebrden,
input [31 : 0] csebwrdata,
input csebwren,
input csebwrrespreq,
// Hijack the HIP application
output [4 : 0] vsec_drv_aer_msi_num,
output vsec_drv_app_int_sts,
output [4 : 0] vsec_drv_app_msi_num,
output vsec_drv_app_msi_req,
output [2 : 0] vsec_drv_app_msi_tc,
output [4 : 0] vsec_drv_pex_msi_num,
output vsec_drv_pm_auxpwr,
output [9 : 0] vsec_drv_pm_data,
output vsec_drv_pme_to_cr,
output vsec_drv_pm_event,
output vsec_drv_rxstmask,
output vsec_drv_rxstready,
output [255 : 0] vsec_drv_txstdata,
output [1 :0] vsec_drv_txstempty,
output [3 :0] vsec_drv_txsteop,
output [3 :0] vsec_drv_txsterr,
output [31:0] vsec_drv_txstparity,
output [3 :0] vsec_drv_txstsop,
output vsec_drv_txstvalid,
output [6 :0] vsec_drv_cpl_err,
output vsec_drv_cpl_pending,
// TLP Analysis output
output [31:0] monitor_data ,
input [7:0] monitor_addr ,
input monitor_fifo_pop , // To retrieve data from a FIFO at a fix address monitor_addr
output avmm_thinmaster_write, // | _______________________________|//
output [7:0] avmm_thinmaster_address, // | | Offset 48h |//
output [15:0] avmm_thinmaster_writedata, // | AVMM thin Master |____________|//
output [1:0] avmm_thinmaster_byteenable, // | [15:0] data |//
output avmm_thinmaster_read, // | [23:16] Address |//
input avmm_thinmaster_waitrequest, // | [24] ReadReq |//
input [15:0] avmm_thinmaster_readdata, // | [25] WriteReq |//
input avmm_thinmaster_readdatavalid, // | [31:26] Reserved |//
input ev128ns,
input ev1us,
input clk,
input sclr
);
localparam ZEROS = 512'h0;
reg [ST_BE_WIDTH-1 : 0] rx_ast_be;
reg [ST_DATA_WIDTH-1 : 0] rx_ast_data;
reg [1 : 0] rx_ast_empty;
reg [ST_CTRL_WIDTH-1 : 0] rx_ast_eop;
reg [ST_CTRL_WIDTH-1 : 0] rx_ast_sop;
reg [ST_CTRL_WIDTH-1 : 0] rx_ast_valid;
reg rx_ast_ready;
wire rx_h_val;
wire [31:0] rx_h1;
wire [31:0] rx_h2;
wire [31:0] rx_h3;
wire [31:0] rx_h4;
reg [ST_DATA_WIDTH-1 : 0] tx_ast_data;
reg [1 :0] tx_ast_empty;
reg [ST_CTRL_WIDTH-1 :0] tx_ast_eop;
reg [ST_CTRL_WIDTH-1 :0] tx_ast_sop;
reg tx_ast_valid;
reg tx_ast_ready;
wire tx_h_val;
wire [31:0] tx_h1;
wire [31:0] tx_h2;
wire [31:0] tx_h3;
wire [31:0] tx_h4;
wire trigger_on; // Global Trigger
wire reset_inspector;
wire reset_trigger;
wire [31:0] cseb_trigger;
wire [1:0] cseb_trigger_dw;
wire use_cseb_trigger;
wire [7:0] monitor_addr_cseb ;
wire [127:0] trigger_signal_probe;
reg [127:0] trigger_ast;
wire monitor_rd_pulse;
wire pcsig_wr_pulse_op ; // In Wr Pulse 0x50
wire pcsig_wr_pulse_dt ; // In Wr Pulse 0x54
wire [31:0] pcsig_wrdata ; // in [31:0]
wire [31:0] pcsig_opcode ; // in [31:0]
wire pcsig_rd_pulse_dt ; // In Rd Pulse
wire pcsig_rd_pulse_st ; // In Rd Pulse
wire [31:0] pcsig_rddata ; // out [31:0]
// synthesis translate_off
initial begin
$display("Info: altpcie_tlp_inspector_a10 :: ---------------------------------------------------------------------------------------------");
$display("Info: altpcie_tlp_inspector_a10 :: ");
$display("Info: altpcie_tlp_inspector_a10 :: Instantiating TLP Inspector ");
$display("Info: altpcie_tlp_inspector_a10 :: ");
$display("Info: altpcie_tlp_inspector_a10 ::--------------------------------------------------------------------------------------------- ");
end
// synthesis translate_on
//////////////////////////////////////////////////////////////////////////////////
//
// Registering inputs
// Naming convention
// Inputs _st_ --> registered _ast_
//
always @(posedge clk) begin : p_rast
if (sclr == 1'b1 ) begin
rx_ast_be <= ZEROS[ST_BE_WIDTH-1 : 0] ;
rx_ast_data <= ZEROS[ST_DATA_WIDTH-1 : 0];
rx_ast_empty <= ZEROS[1 : 0] ;
rx_ast_eop <= ZEROS[ST_CTRL_WIDTH-1 : 0];
rx_ast_sop <= ZEROS[ST_CTRL_WIDTH-1 : 0];
rx_ast_valid <= ZEROS[ST_CTRL_WIDTH-1 : 0];
rx_ast_ready <= 1'b0 ;
tx_ast_data <= ZEROS[ST_DATA_WIDTH-1 : 0];
tx_ast_empty <= ZEROS[1 :0] ;
tx_ast_eop <= ZEROS[ST_CTRL_WIDTH-1 :0] ;
tx_ast_sop <= ZEROS[ST_CTRL_WIDTH-1 :0] ;
tx_ast_valid <= 1'b0 ;
tx_ast_ready <= 1'b0 ;
trigger_ast <= 128'h0;
end
else begin
rx_ast_be <= rx_st_be ;
rx_ast_data <= rx_st_data ;
rx_ast_empty <= rx_st_empty ;
rx_ast_eop <= rx_st_eop ;
rx_ast_sop <= rx_st_sop ;
rx_ast_valid <= rx_st_valid ;
rx_ast_ready <= rx_st_ready ;
tx_ast_data <= tx_st_data ;
tx_ast_empty <= tx_st_empty ;
tx_ast_eop <= tx_st_eop ;
tx_ast_sop <= tx_st_sop ;
tx_ast_valid <= tx_st_valid ;
tx_ast_ready <= tx_st_ready ;
if (use_cseb_trigger==1'b1) begin
case (cseb_trigger_dw)
2'b00 : trigger_ast<={trigger_ast[127:32],cseb_trigger[31:0] };
2'b01 : trigger_ast<={trigger_ast[127:64],cseb_trigger[31:0], trigger_ast[31:0] };
2'b10 : trigger_ast<={trigger_ast[127:96],cseb_trigger[31:0], trigger_ast[63:0] };
2'b11 : trigger_ast<={cseb_trigger[31:0] ,trigger_ast[95:0] };
default : trigger_ast<={trigger_ast[127:32],cseb_trigger[31:0] };
endcase
end
else begin
trigger_ast <= (USE_SIGNAL_PROBE==1)?trigger_signal_probe:trigger;
end
end
end
assign reset_inspector = trigger_ast[10]|sclr;
assign reset_trigger = trigger_ast[9]|sclr|reset_inspector;
//////////////////////////////////////////////////////////////////////////////////
//
// Trigger Section
//
altpcie_tlp_inspector_trigger_a10 # (
.ST_DATA_WIDTH (ST_DATA_WIDTH ),
.ST_BE_WIDTH (ST_BE_WIDTH ),
.ST_CTRL_WIDTH (ST_CTRL_WIDTH ),
.POWER_UP_TRIGGER (POWER_UP_TRIGGER ),
.SIMPLE_TRIGGER (SIMPLE_TRIGGER )
) altpcie_tlp_inspector_trigger (
.trigger_ast (trigger_ast ), // In
.rx_ast_be (rx_ast_be ), // In
.rx_ast_data (rx_ast_data ), // In
.rx_ast_empty (rx_ast_empty ), // In
.rx_ast_eop (rx_ast_eop ), // In
.rx_ast_sop (rx_ast_sop ), // In
.rx_ast_valid (rx_ast_valid ), // In
.rx_ast_ready (rx_ast_ready ), // In
.tx_ast_data (tx_ast_data ), // In
.tx_ast_empty (tx_ast_empty ), // In
.tx_ast_eop (tx_ast_eop ), // In
.tx_ast_sop (tx_ast_sop ), // In
.tx_ast_valid (tx_ast_valid ), // In
.tx_ast_ready (tx_ast_ready ), // In
.trigger_on (trigger_on ), // Out trigger Enable result of triggering logic
.rx_h_val (rx_h_val ), // Out
.rx_h1 (rx_h1 ), // Out
.rx_h2 (rx_h2 ), // Out
.rx_h3 (rx_h3 ), // Out
.rx_h4 (rx_h4 ), // Out
.tx_h_val (tx_h_val ), // Out
.tx_h1 (tx_h1 ), // Out
.tx_h2 (tx_h2 ), // Out
.tx_h3 (tx_h3 ), // Out
.tx_h4 (tx_h4 ), // Out
.clk (clk ), // Out
.sclr (reset_trigger ) // Out
);
altpcie_tlp_inspector_monitor_a10 # (
.ST_DATA_WIDTH (ST_DATA_WIDTH ),
.ST_BE_WIDTH (ST_BE_WIDTH ),
.ST_CTRL_WIDTH (ST_CTRL_WIDTH ),
.PLD_CLK_IS_250MHZ (PLD_CLK_IS_250MHZ ),
.LANES (LANES ),
.INSP_ADDRNUM_WORD (MON_EN_INSP_ADDRNUM_WORD ),
.MONITOR_READYVALID_RATIO (MON_EN_MONITOR_READYVALID_RATIO ),
.UPSTREAM_READ_LATENCY (MON_EN_UPSTREAM_READ_LATENCY ),
.UPSTREAM_THROUGHPUT_MEASUREMENT(MON_EN_UPSTREAM_THROUGHPUT_MEASUREMENT),
.BLACKBOX_LTSSM (MON_EN_BLACKBOX_LTSSM ),
.BLACKBOX_LTSSM_DEPTH32_BLOCK (MON_EN_BLACKBOX_LTSSM_DEPTH32_BLOCK ) // Number of 32 Deep FIFO
) altpcie_tlp_inspector_monitor (
.trigger_ast (trigger_ast ), // In [127:0]
.trigger_on (trigger_on ), // In
.rx_ast_be (rx_ast_be ), // In [ST_BE_WIDTH-1 : 0]
.rx_ast_data (rx_ast_data ), // In [ST_DATA_WIDTH-1 : 0]
.rx_ast_empty (rx_ast_empty ), // In [1 : 0]
.rx_ast_eop (rx_ast_eop ), // In [ST_CTRL_WIDTH-1 : 0]
.rx_ast_sop (rx_ast_sop ), // In [ST_CTRL_WIDTH-1 : 0]
.rx_ast_valid (rx_ast_valid ), // In [ST_CTRL_WIDTH-1 : 0]
.rx_ast_ready (rx_ast_ready ), // In
.tx_ast_data (tx_ast_data ), // In
.tx_ast_empty (tx_ast_empty ), // In [31:0]
.tx_ast_eop (tx_ast_eop ), // In [31:0]
.tx_ast_sop (tx_ast_sop ), // In [31:0]
.tx_ast_valid (tx_ast_valid ), // In [31:0]
.tx_ast_ready (tx_ast_ready ), // In [ST_DATA_WIDTH-1 : 0]
.rx_h_val (rx_h_val ), // In [1 :0]
.rx_h1 (rx_h1 ), // In [ST_CTRL_WIDTH-1 :0]
.rx_h2 (rx_h2 ), // In [ST_CTRL_WIDTH-1 :0]
.rx_h3 (rx_h3 ), // In
.rx_h4 (rx_h4 ), // In
.tx_h_val (tx_h_val ), // In
.tx_h1 (tx_h1 ), // In [31:0]
.tx_h2 (tx_h2 ), // In [31:0]
.tx_h3 (tx_h3 ), // In [31:0]
.tx_h4 (tx_h4 ), // In [31:0]
.rate (rate ), // In [3 : 0]
.lane_act (lane_act ), // In [3 : 0]
.ltssmstate (ltssmstate ), // In [4 : 0]
.signaldetect (signaldetect ), // In [LANES-1:0]
.is_lockedtodata (is_lockedtodata ), // In [LANES-1:0]
.npor_perstn (npor_perstn ), // In
.monitor_addr (((USE_ADME==0)||(use_cseb_trigger==1'b1))?monitor_addr_cseb:monitor_addr ),
.monitor_rd_pulse (((USE_ADME==0)||(use_cseb_trigger==1'b1))?monitor_rd_pulse:monitor_fifo_pop ),
.monitor_data (monitor_data ),
.clk (clk ), // In
.sclr (reset_trigger ) // In
);
altpcie_tlp_inspector_cseb_a10 # (
.CSEB_ENA (CSEB_ENA ),
.VSEC_BYTE_LENGTH (CSEB_VSEC_BYTE_LEN),
.VSEC_REV (CSEB_VSEC_REV ),
.VSEC_ID (CSEB_VSEC_ID )
) altpcie_tlp_inspector_cseb (
.csebaddr (csebaddr ),
.csebbe (csebbe ),
.csebisshadow (csebisshadow ),
.csebrden (csebrden ),
.csebwrdata (csebwrdata ),
.csebwren (csebwren ),
.csebwrrespreq (csebwrrespreq ),
// Outputs
.csebrddata (csebrddata ),
.csebrdresponse (csebrdresponse ),
.csebwaitrequest (csebwaitrequest ),
.csebwrresponse (csebwrresponse ),
.csebwrrespvalid (csebwrrespvalid ),
.use_cseb_trigger (use_cseb_trigger ),
.cseb_trigger (cseb_trigger ),
.cseb_trigger_dw (cseb_trigger_dw ),
.monitor_addr (monitor_addr_cseb ),
.monitor_data (monitor_data ),
.monitor_rd_pulse (monitor_rd_pulse ),
.pcsig_wr_pulse_op (pcsig_wr_pulse_op ),
.pcsig_wr_pulse_dt (pcsig_wr_pulse_dt ),
.pcsig_wrdata (pcsig_wrdata ),
.pcsig_opcode (pcsig_opcode ),
.pcsig_rd_pulse_st (pcsig_rd_pulse_st ),
.pcsig_rd_pulse_dt (pcsig_rd_pulse_dt ),
.pcsig_rddata (pcsig_rddata ),
.avmm_thinmaster_write (avmm_thinmaster_write ), // | _______________________________|//
.avmm_thinmaster_address (avmm_thinmaster_address ), // | | Offset 48h |//
.avmm_thinmaster_writedata (avmm_thinmaster_writedata ), // | AVMM thin Master |____________|//
.avmm_thinmaster_byteenable (avmm_thinmaster_byteenable ), // | [15:0] data |//
.avmm_thinmaster_read (avmm_thinmaster_read ), // | [23:16] Address |//
.avmm_thinmaster_waitrequest (avmm_thinmaster_waitrequest ), // | [24] ReadReq |//
.avmm_thinmaster_readdata (avmm_thinmaster_readdata ), // | [25] WriteReq |//
.avmm_thinmaster_readdatavalid (avmm_thinmaster_readdatavalid ), // | [31:26] Reserved |//
//Input
.clk (clk ),
.sclr (sclr )
);
generate begin :g_pc_hijack
if (VSEC_HIPDRV==0) begin
assign vsec_drv_aer_msi_num = ZEROS[4 : 0] ;
assign vsec_drv_app_int_sts = ZEROS[0] ;
assign vsec_drv_app_msi_num = ZEROS[4 : 0] ;
assign vsec_drv_app_msi_req = ZEROS[0] ;
assign vsec_drv_app_msi_tc = ZEROS[2 : 0] ;
assign vsec_drv_pex_msi_num = ZEROS[4 : 0] ;
assign vsec_drv_pm_auxpwr = ZEROS[0] ;
assign vsec_drv_pm_data = ZEROS[9 : 0] ;
assign vsec_drv_pme_to_cr = ZEROS[0] ;
assign vsec_drv_pm_event = ZEROS[0] ;
assign vsec_drv_rxstmask = ZEROS[0] ;
assign vsec_drv_rxstready = ZEROS[0] ;
assign vsec_drv_txstdata = ZEROS[255 : 0];
assign vsec_drv_txstempty = ZEROS[1 :0] ;
assign vsec_drv_txsteop = ZEROS[3 :0] ;
assign vsec_drv_txsterr = ZEROS[3 :0] ;
assign vsec_drv_txstparity = ZEROS[31:0] ;
assign vsec_drv_txstsop = ZEROS[3 :0] ;
assign vsec_drv_txstvalid = ZEROS[0] ;
assign vsec_drv_cpl_err = ZEROS[6 :0] ;
assign vsec_drv_cpl_pending = ZEROS[0] ;
end
else begin
altpcie_tlp_inspector_pcsig_drive_a10 # (
.VSEC_HIPDRV_SIGNAL_PWR (VSEC_HIPDRV_SIGNAL_PWR ),
.VSEC_HIPDRV_SIGNAL_PAR (VSEC_HIPDRV_SIGNAL_PAR ),
.ST_DATA_WIDTH (ST_DATA_WIDTH ),
.ST_BE_WIDTH (ST_BE_WIDTH ),
.ST_CTRL_WIDTH (ST_CTRL_WIDTH ),
.PLD_CLK_IS_250MHZ (PLD_CLK_IS_250MHZ ),
.LANES (LANES )
) altpcie_tlp_inspector_pcsig_drive_a10 (
.pcsig_wr_pulse_op (pcsig_wr_pulse_op ),
.pcsig_wr_pulse_dt (pcsig_wr_pulse_dt ),
.pcsig_wrdata (pcsig_wrdata ),
.pcsig_opcode (pcsig_opcode ),
.pcsig_rd_pulse_st (pcsig_rd_pulse_st ),
.pcsig_rd_pulse_dt (pcsig_rd_pulse_dt ),
.pcsig_rddata (pcsig_rddata ),
.rx_ast_be (rx_ast_be ),// In [ST_BE_WIDTH-1 : 0]
.rx_ast_data (rx_ast_data ),// In [ST_DATA_WIDTH-1 : 0]
.rx_ast_empty (rx_ast_empty ),// In [1 : 0]
.rx_ast_eop (rx_ast_eop ),// In [ST_CTRL_WIDTH-1 : 0]
.rx_ast_sop (rx_ast_sop ),// In [ST_CTRL_WIDTH-1 : 0]
.rx_ast_valid (rx_ast_valid ),// In [ST_CTRL_WIDTH-1 : 0]
.rx_st_mask (vsec_drv_rxstmask ), //Out
.rx_st_ready (vsec_drv_rxstready ), //Out
.tx_ast_ready (tx_ast_ready ), // In
.tx_st_data (vsec_drv_txstdata ), //Out [255 : 0]
.tx_st_empty (vsec_drv_txstempty ), //Out [1 :0]
.tx_st_eop (vsec_drv_txsteop ), //Out [3 :0]
.tx_st_err (vsec_drv_txsterr ), //Out [3 :0]
.tx_st_parity (vsec_drv_txstparity ), //Out [31:0]
.tx_st_sop (vsec_drv_txstsop ), //Out [3 :0]
.tx_st_valid (vsec_drv_txstvalid ), //Out
.aer_msi_num (vsec_drv_aer_msi_num ), //Out [4 : 0]
.app_int_sts (vsec_drv_app_int_sts ), //Out
.app_msi_num (vsec_drv_app_msi_num ), //Out [4 : 0]
.app_msi_req (vsec_drv_app_msi_req ), //Out
.app_msi_tc (vsec_drv_app_msi_tc ), //Out [2 : 0]
.pex_msi_num (vsec_drv_pex_msi_num ), //Out [4 : 0]
.pm_auxpwr (vsec_drv_pm_auxpwr ), //Out
.pm_data (vsec_drv_pm_data ), //Out [9 : 0]
.pme_to_cr (vsec_drv_pme_to_cr ), //Out
.pm_event (vsec_drv_pm_event ), //Out
.cpl_err (vsec_drv_cpl_err ), //Out [6 :0]
.cpl_pending (vsec_drv_cpl_pending ), //Out
.clk (clk ), // In
.sclr (sclr ) // In
);
end
end
endgenerate
//////////////// SIMULATION-ONLY CONTENTS
//synthesis translate_off
assign trigger_signal_probe = trigger;
//////////////// END SIMULATION-ONLY CONTENTS
//synthesis translate_on
//////////////// SYNTHESIS-ONLY CONTENTS
// The section bellow is for synthesis only and is not used for simulation
// When reserved_debug_hwtcl=1, set SignalProbe access point to
// reservein and testin pins
//synthesis read_comments_as_HDL on
//generate begin : g_reserved_debug
// if (USE_SIGNAL_PROBE==1) begin
// sld_mod_ram_rom #(
// .cvalue (128'h1 ),
// .is_data_in_ram (0),
// .is_readable (0),
// .node_name (1397641039),
// .numwords (1),
// .shift_count_bits (8),
// .width_word (128),
// .widthad (1)
// ) signalprobe_test_in_lsb ( .data_write(trigger_signal_probe[31:0]) );
//
// end
// else begin
// assign trigger_signal_probe=128'h0;
// end
//end
//endgenerate
//synthesis read_comments_as_HDL off
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// altpcie_tlp_inspector_cseb : Extended config space to access TLP Inspector //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// CSEB Bus Info Overview //
// //
// |-------------------------------------------------------------------------| //
// | CSEB address Space | //
// |-------------------------------------------------------------------------| //
// | PCI/PCIe config space | Address value | //
// |-------------------------------------------------------------------------| //
// | Type0 or Type1 Configuration Registers (PCI Header) | 32'h000-32'h03Ch | //
// | Reserved | 32'h040 | //
// | Reserved | 32'h044 | //
// | Reserved | 32'h048-32'h04Ch | //
// | MSI Capability Structure | 32'h050-32'h05Ch | //
// | Reserved | 32'h060-32'h064h | //
// | MSI-X Capability Structure | 32'h068-32'h070h | //
// | Power Management Capability Structure | 32'h078-32'h07Ch | //
// | PCI Express Capability Structure | 32'h080-32'h0BCh | //
// | SSID/SSVID Capability Structure | 32'h0C0-32'h0C4h | //
// | PCI Extensions (CSEB)*** | 32'h0C8-32'h0FCh | //
// | Virtual Channel Capability Structure | 32'h100-32'h16Ch | //
// | Reserved | 32'h170-32'h1FCh | //
// | Vendor Specific Extended Capability Structure | 32'h200-32'h240h | //
// | Secondary PciE Extended Capability Structure | 32'h300-32'h318h | //
// | Reserved | 32'h31C-32'h7FCh | //
// | AER | 32'h800-32'h834h | //
// | PCI-E Extensions (CSEB) | 32'h900-32'hFFFh | //
// |-------------------------------------------------------------------------| //
// //
// __________________________________________________________________________________________________________________ //
// | | //
// | PCI Express Extended Capability Header Offset 8'h0 | //
// | _______________________________________________________________________________________________________________| //
// | | //
// | 31 20 | 16| 0 | //
// | Next Capability Offset | Capability Version |PCI Express Extended Capability ID | //
// | | //
// | 15:0 PCI Express Extended Capability ID : This field is a PCI-SIG defined ID number that indicates the nature | //
// | and format of the Extended Capability. | //
// | Extended Capability ID for the Vendor-Specific Capability is 000Bh. | //
// | RO | //
// | 19:16 Capability Version : This field is a PCI-SIG defined version number that indicates | //
// | the version of the Capability structure present. | //
// | Must be 1h for this version of the specification | //
// | 31:20 Next Capability Offset : This field contains the offset to the next PCI Express | //
// | Capability structure or 000h if no other items exist in | //
// | the linked list of Capabilities. | //
// | For Extended Capabilities implemented in Configuration Space, | //
// | this offset is relative to the beginning of PCI-compatible | //
// | Configuration Space and thus must always be either 000h | //
// | (for terminating list of Capabilities) or greater than 0FFh. | //
// | | //
// |________________________________________________________________________________________________________________| //
// | | //
// | Vendor-Specific Header Offset 04h | //
// | _______________________________________________________________________________________________________________| //
// | | //
// | 31 20 | 16| 0 | //
// | VSEC Length | VSEC Rev | VSEC ID | //
// | | //
// | 15:0 VSEC ID : This field is a vendor-defined ID number that indicates the nature | //
// | and format of the VSEC structure. Software must qualify the Vendor | //
// | ID before interpreting this field. | //
// | 19:16 VSEC Rec : This field is a vendor-defined ID number that indicates | //
// | the nature and format of theVSEC structure. | //
// | Software must qualify the Vendor ID before interpreting this field. | //
// | This field is a PCI-SIG defined version number that indicates | //
// | 31:20 VSEC Length : This field indicates the number of bytes in the entire VSEC | //
// | structure, including the PCI Express Extended Capability header, | //
// | the Vendor- Specific header, and the Vendor-Specific registers | //
// | | //
// |________________________________________________________________________________________________________________| //
// | | //
// | Vendor-Specific Register - TLP Inspector Registers | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 08h | //
// | TRIGGER DWORD 1 |____________| //
// | | //
// | trigger [0] | SOP : When 1 trigger on first SOP | //
// | [1] | TX/RX : When 1 trigger on RX AST, When 0 Trigger on TX AST | //
// | [2] | FMT_TLP : When check trigger FMT_TLP | //
// | [3] | TAG : When check trigger TAG | //
// | [5:4] | Address : When check trigger Address Lower 24 bits | //
// | | 5:4 =2'b01, 8-bit addr LSB | //
// | | 5:4 =2'b10, 16-bit addr LSB | //
// | | 5:4 =2'b11, 32-bit addr LSB | //
// | [6] | First BE : When check trigger first BE | //
// | [7] | Last BE : When check trigger last BE | //
// | [8] | Attr : When check trigger Attr | //
// | [9] | Reset trigger only | //
// | [10] | Reset reset Inspector | //
// | [11] | Enable Trigger ON : When set activate trigger logic | //
// | [12 ] | Use CSEB trigger | //
// | [31:13] | RESERVED | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 0Ch | //
// | TRIGGER DWORD 2 |____________| //
// | | //
// | [ 7: 0] | [39:32] | FMT TYPE: When trigger[2] set, trigger on | //
// | | | _______________________________ | //
// | | | | | | | //
// | | | | {FMT,TYPE} | | | //
// | | | |____________________|________| | //
// | | | | 8'b0000_0000 | MRd | | //
// | | | | 8'b0010_0000 | MRd | | //
// | | | | 8'b0000_0001 | MRdLk | | //
// | | | | 8'b0010_0001 | MRdLk | | //
// | | | | 8'b0100_0000 | MWr | | //
// | | | | 8'b0110_0000 | MWr | | //
// | | | | 8'b0000_0010 | IORd | | //
// | | | | 8'b0100_0010 | IOWr | | //
// | | | | 8'b0000_0100 | CfgRd0 | | //
// | | | | 8'b0100_0100 | CfgWr0 | | //
// | | | | 8'b0000_0101 | CfgRd1 | | //
// | | | | 8'b0100_0101 | CfgWr1 | | //
// | | | | 8'b0011_0XXX | Msg | | //
// | | | | 8'b0111_0XXX | MsgD | | //
// | | | | 8'b0000_1010 | Cpl | | //
// | | | | 8'b0100_1010 | CplD | | //
// | | | | 8'b0000_1011 | CplLk | | //
// | | | | 8'b0100_1011 | CplDLk | | //
// | | | |_____________________________| | //
// | | | | //
// | | | | //
// | [15: 8] | [47:40] | TAG : When trigger[3] set, trigger on TAG value | //
// | [19:16] | [51:48] | First BE : When trigger[6] set, trigger on Last BE | //
// | [23:20] | [55:52] | Last BE : When trigger[7] set, trigger on Last BE | //
// | [31:24] | [63:55] | RESERVED | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 10h | //
// | TRIGGER DWORD 3 |____________| //
// | | //
// | [31:0] | [95:64] | when trigger[5:4]>0 32 bit lower address trigger | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 14h | //
// | TRIGGER DWORD 4 |____________| //
// | | //
// | [0] | [96] | When unset no stop trigger | //
// | [1] | [97] | TX/RX : When 1 stop-trigger on RX AST, When 0 Trigger on TX AST | //
// | [2] | [98] | FMT_TLP : When check stop-trigger FMT_TLP | //
// | [3] | [99] | TAG : When check stop-trigger TAG | //
// | [5:4] | [101:100]| Address : When check stop-trigger Address Lower 24 bits | //
// | | | [101:100] =2'b01, 8-bit addr LSB | //
// | | | [101:100] =2'b10, 16-bit addr LSB | //
// | | | [101:100] =2'b11, 32-bit addr LSB | //
// | [13:6] | [109:102]| FMT TYPE: When stop-trigger[98] set, | //
// | [21:14] | [117:110]| TAG : When stop-trigger[99] | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 18h | //
// | |____________| //
// | INSP_ADDRREADY_SOP_RX {ast_cnt_rx_ready, ast_cnt_rx_sop} | //
// | 31 16| 0 | //
// | Number of times rx_ready de-assert on rx_valid | Number of of RX SOP | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 1Ch | //
// | INSP_ADDRREADY_SOP_TX {ast_cnt_tx_ready, ast_cnt_tx_sop} |___________ | //
// | 31 16| 0 | //
// | Number of times tx_ready de-assert on tx_valid | Number of of TX SOP | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 20h | //
// | INSP_ADDRLATENCY_MRD_UPSTREAM {PLD_CLK_IS_250MHZ,ast_max_read_latency, ast_min_read_latency} |____________| //
// | 31 30 | 15| 0 | //
// | When 1 pld clk is 250 MHz | Max read upstream | Min read upstream latency | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 24h | //
// | INSP_ADDRMWR_THROUGHPUT_CLK {PLD_CLK_IS_250MHZ,10'h0,ast_cnt_mwr_clk} |____________| //
// | 31 30 | 20| 0 | //
// | When 1 pld clk is 250 MHz | RESERVED | Number of clock cycles for MWr upstream transfer | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 28h | //
// | INSP_ADDRMWR_THROUGHPUT_DWORD {12'h0 ,ast_cnt_mwr_dword} |____________| //
// | 31 20| 0 | //
// | RESERVED | Number of DWORD MWr upstream transfer | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 2Ch | //
// | INSP_ADDRMRD_THROUGHPUT_CLK {(PLD_CLK_IS_250MHZ==1)?2'b01:2'b00,10'h0,ast_cnt_mrd_clk} |____________| //
// | 31 30 | 20| 0 | //
// | When 1 pld clk is 250 MHz | RESERVED | Number of clock cycles for MRd upstream transfer | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 30h | //
// | INSP_ADDRMRD_THROUGHPUT_DWORD {12'h0 ,ast_cnt_mrd_dword} |____________| //
// | 31 20| 0 | //
// | RESERVED | Number of DWORD MRd upstream transfer | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 34h | //
// | LTSSM BLACK BOX Recording Retrieval |____________| //
// | | //
// | [4:0] : LTSSM Transition | //
// | [5] : perstn|npor | //
// | [13:6]: Is lock to data | //
// | [14] : signaldetect | //
// | [16:15]: rate 1->G1, 2 -->G2, 3:G3 | //
// | [18:17]: Lanes : 0 ->x1, 0 ->x2, 0 ->x4, 0 ->x8, | //
// | [19 ]: RESERVED | //
// | [27:20]: Number of word in the black box | //
// | [31:28]: RESERVED | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 38h | //
// | TLP BLACK BOX Recording Retrieval |____________| //
// | | //
// | Pop FIFO | //
// | [0] RX Tlp when 1 else TX TLP | //
// | [8:1] TLP CNT | //
// | [21:10] RESERVED | //
// | [26:22] fifo_used | //
// | [27] fifo_empty | //
// | [28] fifo_full | //
// | [31:29] RESERVED | //
// | | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 3Ch | //
// | Retrieve H1 TLP |____________| //
// | [31:0] Header 1 TLP | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 40h | //
// | Retrieve H2 TLP |____________| //
// | [31:0] Header 2 TLP | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 44h | //
// | Retrieve H3 TLP |____________| //
// | [31:0] Header 3 TLP | //
// | _______________________________________________________________________________________________________________| //
// | | Offset 48h | //
// | AVMM thin Master TODO |____________| //
// | [15:0] data | //
// | [23:16] Address | //
// | [24] ReadReq | //
// | [25] WriteReq | //
// | [31:26] Reserved WriteReq | //
// | _______________________________________________________________________________________________________________| //
// | | //
// | RESERVED RESERVED | //
// | | //
// | _______________________________________________________________________________________________________________| //
// //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_tlp_inspector_cseb_a10 # (
parameter CSEB_ENA = 1,
parameter RD2CPL_DLY = 4,
parameter CSEB_CAPABILITY_INFO = 1,
parameter VSEC_BYTE_LENGTH = 12'h40,
parameter VSEC_REV = 4'h1,
parameter VSEC_ID = 16'hFACE
) (
// Interface to HIP CSEB bus which is an extension of configuration space
output reg [31 : 0] csebrddata,
output reg [4 : 0] csebrdresponse,
// CSEB Response Codes
// 3'h0; - Successful completion
// 3'h1; - Access to undefined location:
// User should only use this if the CFG
// request addresses an unimplemented function
// (cfg bypass).
// 3'h2; - Fatal and permanent problem
// 3'h3; - Slave response timeout
// 3'h4; - Temporary problem - retry:
// Will map to CRS if k_temp_busy_crs is 1
// (useful for Cfg Bypass -- user needs to
// follow PCIe rules on using CRS).
// Else it will map to CA.
// 3'h5; - Parity Error
output csebwaitrequest,
output reg [4 : 0] csebwrresponse,
output reg csebwrrespvalid,
input [31 : 0] csebaddr,
input [3 : 0] csebbe,
input csebisshadow,
input csebrden,
input [31 : 0] csebwrdata,
input csebwren,
input csebwrrespreq,
input [31:0] monitor_data ,
output [7:0] monitor_addr ,
output monitor_rd_pulse ,
output reg use_cseb_trigger ,
output reg [31:0] cseb_trigger ,
output reg [1:0] cseb_trigger_dw ,
output reg pcsig_wr_pulse_op , // In Wr Pulse
output reg pcsig_wr_pulse_dt , // In Wr Pulse
output reg [31:0] pcsig_wrdata , // in [31:0]
output reg [31:0] pcsig_opcode , // in [31:0]
output reg pcsig_rd_pulse_dt , // In Rd Pulse
output reg pcsig_rd_pulse_st , // In Rd Pulse
input [31:0] pcsig_rddata , // out [31:0]
output reg avmm_thinmaster_write,
output reg [7:0] avmm_thinmaster_address,
output reg [15:0] avmm_thinmaster_writedata,
output reg [1:0] avmm_thinmaster_byteenable,
output reg avmm_thinmaster_read,
input avmm_thinmaster_waitrequest,
input [15:0] avmm_thinmaster_readdata,
input avmm_thinmaster_readdatavalid,
input clk,
input sclr
);
localparam ZEROS = 512'h0;
// | 31 20 | 16| 0
// | Next Capability Offset | Capability Version |PCI Express Extended Capability ID
localparam NEXT_CAPABILITY_OFFSET = 12'h0,
CAPABILITY_VERSION = 4'h1 ,
VSEC_PCIE_EXTENDED_CAPABILITY_ID = 16'hB;
localparam MAX_VSEC_ADDR = 16'h904+{4'h0, VSEC_BYTE_LENGTH};
reg csebwren_p1 ;
reg csebrden_p1 ;
reg csebaddr_0h ;
reg csebaddr_4h ;
reg csebaddr_8h ;
reg csebaddr_Ch ;
reg csebaddr_10h ;
reg csebaddr_14h ;
reg csebaddr_48h ;
reg csebaddr_gt_917h ;
reg csebaddr_gt_maxvsec_len ;
reg [31:0] csebwrdata_p1 ;
reg [15:0] requester_id ;
reg csebwaitrequest_r;
reg [RD2CPL_DLY-3:0] cfgrd2cpl_dly ;
reg csebresp_ready;
reg [31:0] cseb_thinmaster ;
reg [31:0] avmm_thinmaster_pipe ;
assign csebwaitrequest = csebisshadow ? (csebwaitrequest_r|(csebrden&(~csebrden_p1))) : ~csebresp_ready;
assign monitor_addr = csebaddr[7:0];
assign monitor_rd_pulse = ((csebrden==1'b1)&&(csebrden_p1==1'b0))?1'b1:1'b0;
always @(posedge clk) begin : p_cseb
if ((sclr == 1'b1 )||(CSEB_ENA==0)) begin
csebrddata <= 32'h0;
csebrdresponse <= 5'h0;
csebwaitrequest_r <= 1'h0;
csebwrresponse <= 5'h0;
csebwrrespvalid <= 1'h0;
use_cseb_trigger <= 1'b0;
cseb_trigger <= 32'h0;
cseb_trigger_dw <= 2'h0;
cfgrd2cpl_dly <= ZEROS[RD2CPL_DLY-3:0];
csebwren_p1 <= 1'b0;
csebwrdata_p1 <= 32'h0;
csebaddr_0h <= 1'b0;
csebaddr_4h <= 1'b0;
csebaddr_8h <= 1'b0;
csebaddr_Ch <= 1'b0;
csebaddr_10h <= 1'b0;
csebaddr_14h <= 1'b0;
csebaddr_48h <= 1'b0;
csebrden_p1 <= 1'b0;
csebaddr_gt_917h <= 1'b0;
csebaddr_gt_maxvsec_len <= 1'b0;
requester_id <= 16'h0;
pcsig_wr_pulse_op <= ZEROS[0] ;
pcsig_wr_pulse_dt <= ZEROS[0] ;
pcsig_wrdata <= ZEROS[31:0];
pcsig_opcode <= ZEROS[31:0];
pcsig_rd_pulse_dt <= ZEROS[0] ;
pcsig_rd_pulse_st <= ZEROS[0] ;
csebresp_ready <= 1'b1;
end
else begin
requester_id <= csebaddr[31:16];
csebwren_p1 <= (~csebisshadow) & csebwren;
csebrden_p1 <= (~csebisshadow) & csebrden;
csebaddr_0h <= (csebaddr[15:0]==16'h900)?1'b1:1'b0;
csebaddr_4h <= (csebaddr[15:0]==16'h904)?1'b1:1'b0;
csebaddr_8h <= (csebaddr[15:0]==16'h908)?1'b1:1'b0;
csebaddr_Ch <= (csebaddr[15:0]==16'h90C)?1'b1:1'b0;
csebaddr_10h <= (csebaddr[15:0]==16'h910)?1'b1:1'b0;
csebaddr_14h <= (csebaddr[15:0]==16'h914)?1'b1:1'b0;
csebaddr_48h <= (csebaddr[15:0]==16'h948)?1'b1:1'b0;
csebaddr_gt_917h <= (csebaddr[15:0] >16'h917)?1'b1:1'b0;
csebaddr_gt_maxvsec_len <= (csebaddr[15:0] > MAX_VSEC_ADDR)?1'b1:1'b0;
csebwrdata_p1 <= csebwrdata;
csebresp_ready <= 1'b0;
if (csebwren_p1==1'b1) begin
cseb_trigger <= (csebaddr_8h|csebaddr_Ch|csebaddr_10h|csebaddr_14h)?csebwrdata_p1:cseb_trigger;
cseb_trigger_dw <= (csebaddr_8h ==1'b1)?2'h0:
(csebaddr_Ch ==1'b1)?2'h1:
(csebaddr_10h==1'b1)?2'h2:
(csebaddr_14h==1'b1)?2'h3:cseb_trigger_dw;
csebwrrespvalid <= 1'b1;
csebresp_ready <= 1'b1;
end
else begin
csebwrrespvalid <= 1'b0;
end
cfgrd2cpl_dly <= {cfgrd2cpl_dly[RD2CPL_DLY-4:0], ((csebrden==1'b1) && (csebrden_p1==1'b0))?1'b1:1'b0};
csebwaitrequest_r <= ((csebrden==1'b1)&&(csebrden_p1==1'b0))?1'b1:(cfgrd2cpl_dly>ZEROS[RD2CPL_DLY-3:0])?1'b1:1'b0;
if (csebrden_p1==1'b1) begin
if (csebaddr_0h==1'b1) begin
csebrddata <= {NEXT_CAPABILITY_OFFSET, CAPABILITY_VERSION, VSEC_PCIE_EXTENDED_CAPABILITY_ID};
csebrdresponse <= 5'h0;
csebresp_ready <= (cfgrd2cpl_dly>ZEROS[RD2CPL_DLY-3:0])?1'b0:1'b1;
end
else if (csebaddr_4h==1'b1) begin
csebrddata <= {VSEC_BYTE_LENGTH, VSEC_REV, VSEC_ID};
csebrdresponse <= 5'h0;
csebresp_ready <= (cfgrd2cpl_dly>ZEROS[RD2CPL_DLY-3:0])?1'b0:1'b1;
end
else if (csebaddr_48h==1'b1) begin
csebrddata <= cseb_thinmaster;
csebrdresponse <= 5'h0;
csebresp_ready <= (cfgrd2cpl_dly>ZEROS[RD2CPL_DLY-3:0])?1'b0:1'b1;
end
else if ((csebaddr_gt_917h==1'b1)&&(csebaddr_gt_maxvsec_len==1'b0)) begin
csebrddata <= monitor_data;
csebrdresponse <= 5'h0;
csebresp_ready <= (cfgrd2cpl_dly>ZEROS[RD2CPL_DLY-3:0])?1'b0:1'b1;
end
else begin
csebrdresponse <= 5'h1; // Undefined location UR
csebresp_ready <= (cfgrd2cpl_dly>ZEROS[RD2CPL_DLY-3:0])?1'b0:1'b1;
end
end
end
end // p_cseb
reg [2:0] avmm_master_state;
localparam [2:0] S_IDLE = 3'h0;
localparam [2:0] S_CSEB_WRITE = 3'h1;
localparam [2:0] S_AVMM_WRITE_REQ = 3'h2;
localparam [2:0] S_AVMM_READ_REQ = 3'h3;
localparam [2:0] S_AVMM_CPL = 3'h4;
////////////////////////////////////////////////////////////////
//
// Create thin AVMM RX Mster from etyh CSEB register 'h948
//
always @(posedge clk) begin : p_thinmaster
if ((sclr == 1'b1 )||(CSEB_ENA==0)) begin
cseb_thinmaster <= 32'h0;
avmm_thinmaster_write <= 1'b0;
avmm_thinmaster_address <= 8'h0;
avmm_thinmaster_writedata <= 16'h0;
avmm_thinmaster_byteenable <= 2'b11;
avmm_thinmaster_read <= 1'h0;
avmm_master_state <= 3'h0;
end
else begin
avmm_thinmaster_byteenable <= 2'b11;
case (avmm_master_state)
S_IDLE : begin
if ((csebwren_p1==1'b1)&& (csebaddr_48h == 1'b1 )) begin
cseb_thinmaster <= csebwrdata_p1;
avmm_thinmaster_write <= 1'b0;
avmm_thinmaster_read <= 1'b0;
avmm_master_state <= S_CSEB_WRITE;
end
else begin
avmm_master_state <= S_IDLE;
end
end
S_CSEB_WRITE : begin
avmm_thinmaster_address <= cseb_thinmaster[23:16];
avmm_thinmaster_writedata <= cseb_thinmaster[15:0 ];
if (cseb_thinmaster[24] == 1'b1 ) begin
avmm_thinmaster_write <= 1'b0;
avmm_thinmaster_read <= 1'b1;
avmm_master_state <= S_AVMM_READ_REQ;
end
else if (cseb_thinmaster[25] == 1'b1 ) begin
avmm_thinmaster_write <= 1'b1;
avmm_thinmaster_read <= 1'b0;
avmm_master_state <= S_AVMM_WRITE_REQ;
end
end
S_AVMM_WRITE_REQ : begin
if (avmm_thinmaster_waitrequest==1'b0) begin
avmm_thinmaster_write <= 1'b0;
cseb_thinmaster[25] <= 1'b0;
avmm_thinmaster_read <= 1'b0;
avmm_master_state <= S_IDLE;
end
else begin
avmm_master_state <= S_AVMM_WRITE_REQ;
end
end
S_AVMM_READ_REQ : begin
if (avmm_thinmaster_waitrequest==1'b0) begin
avmm_thinmaster_write <= 1'b0;
avmm_thinmaster_read <= 1'b0;
avmm_master_state <= S_AVMM_CPL;
end
else begin
avmm_master_state <= S_AVMM_READ_REQ;
end
end
S_AVMM_CPL : begin
if (avmm_thinmaster_readdatavalid==1'b1) begin
cseb_thinmaster[24] <= 1'b0;
cseb_thinmaster[15:0] <= avmm_thinmaster_readdata[15:0];
avmm_thinmaster_write <= 1'b0;
avmm_thinmaster_read <= 1'b0;
avmm_master_state <= S_IDLE;
end
else begin
avmm_master_state <= S_AVMM_CPL;
end
end
default : begin
avmm_master_state <= S_IDLE;
end
endcase
end
end // p_thinmaster
endmodule
// ////////////////////////////////////////////ALTERA BFM TASK to cut and paste in altpcietb_bfm_driver_chaining
// //
// //
// function [64*8:1] DisplayTLP ;
// input [31:0] h1 ;
// input [31:0] h2 ;
// input [31:0] h3 ;
// input rx ;
// //input [31:0] h4 ;
// reg [7*8:1] tlp_type;
// reg [8*5:1] tag;
// begin
// casex (h1[31:24])
// 8'b0000_0000 : begin
// tlp_type = "MRd" ;
// tag = {" (",dimage2(h2[15:8]),")"};
// end
// 8'b0010_0000 : begin
// tlp_type = "MRd" ;
// tag = {" (",dimage2(h2[15:8]),")"};
// end
// 8'b0000_0001 : begin
// tlp_type = "MRdLk" ;
// tag = {" (",dimage2(h2[15:8]),")"};
// end
// 8'b0010_0001 : begin
// tlp_type = "MRdLk" ;
// tag = {" (",dimage2(h2[15:8]),")"};
// end
// 8'b0100_0000 : begin
// tlp_type = "MWr" ;
// tag = " ";
// end
// 8'b0110_0000 : begin
// tlp_type = "MWr" ;
// tag = " ";
// end
// 8'b0000_0010 : begin
// tlp_type = "IORd" ;
// tag = {" (",dimage2(h2[15:8]),")"};
// end
// 8'b0100_0010 : begin
// tlp_type = "IOWr" ;
// tag = {" (",dimage2(h2[15:8]),")"};
// end
// 8'b0000_0100 : begin
// tlp_type = "CfgRd0";
// tag = {" (",dimage2(h2[15:8]),")"};
// end
// 8'b0100_0100 : begin
// tlp_type = "CfgWr0";
// tag = {" (",dimage2(h2[15:8]),")"};
// end
// 8'b0000_0101 : begin
// tlp_type = "CfgRd1";
// tag = {" (",dimage2(h2[15:8]),")"};
// end
// 8'b0100_0101 : begin
// tlp_type = "CfgWr1";
// tag = {" (",dimage2(h2[15:8]),")"};
// end
// 8'b0011_0XXX : begin
// tlp_type = "Msg" ; //TODO Complete all Msg Cases
// tag = " ";
// end
// 8'b0111_0XXX : begin
// tlp_type = "MsgD" ;
// tag = " " ;
// end
// 8'b0000_1010 : begin
// tlp_type = "Cpl" ;
// tag = {" (",dimage2(h3[15:8]),")"};
// end
// 8'b0100_1010 : begin
// tlp_type = "CplD" ;
// tag = {" (",dimage2(h3[15:8]),")"};
// end
// 8'b0000_1011 : begin
// tlp_type = "CplLk" ;
// tag = {" (",dimage2(h3[15:8]),")"};
// end
// 8'b0100_1011 : begin
// tlp_type = "CplDLk";
// tag = {" (",dimage2(h3[15:8]),")"};
// end
// default : begin
// tlp_type = "TDB" ;
// tag = " ";
// end
// endcase
// DisplayTLP={ tlp_type, tag, " | ", dimage4({h1[9:0],2'b00}) , " | ", himage8(h1), "_", himage8(h2), "_", himage8(h3)};
// end
// endfunction
// task inspector_config_space ;
//
// reg [31:0] dword;
// reg [2:0] compl_status;
// reg unused_result ;
// reg [15:0] addr;
// reg pld_clk_is_250MHz;
// reg [19:0] nclk;
// reg [19:0] ndword;
// reg [31:0] nbytes;
// reg [31:0] ellapse_timens;
// reg [31:0] throughputMBps;
// reg [7:0] ltssmfifo_used;
// reg empty;
// reg full;
// reg ast_rx;
// reg [31:0] tlp_h1;
// reg [31:0] tlp_h2;
// reg [31:0] tlp_h3;
//
// begin
// addr = 16'h900;
//
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// $display("___________________________________________________________________________________________________________________________________");
// $display("| | ");
// $display("| PCI Express Extended Capability Header Offset 8'h0 | 0x%s ", himage4(addr));
// $display("| ________________________________________________________________________________________________________________|________________");
// $display("| | ");
// $display("| 31 20 | 16| 0 | ");
// $display("| Next Capability Offset | Capability Version |PCI Express Extended Capability ID | ");
// $display("| | ");
// $display("| 15:0 PCI Express Extended Capability ID : This field is a PCI-SIG defined ID number that indicates the nature | 0x%s ", himage4(dword[15:0]));
// $display("| and format of the Extended Capability. | ");
// $display("| Extended Capability ID for the Vendor-Specific Capability is 000Bh. | ");
// $display("| RO | ");
// $display("| 19:16 Capability Version : This field is a PCI-SIG defined version number that indicates | 0x%s ", himage4(dword[19:16]));
// $display("| the version of the Capability structure present. | ");
// $display("| Must be 1h for this version of the specification | ");
// $display("| 31:20 Next Capability Offset : This field contains the offset to the next PCI Express | 0x%s ", himage4(dword[31:20]));
// $display("| Capability structure or 000h if no other items exist in | ");
// $display("| the linked list of Capabilities. | ");
// $display("| For Extended Capabilities implemented in Configuration Space, | ");
// $display("| this offset is relative to the beginning of PCI-compatible | ");
// $display("| Configuration Space and thus must always be either 000h | ");
// $display("| (for terminating list of Capabilities) or greater than 0FFh. | ");
//
// addr = 16'h904;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// $display("|_________________________________________________________________________________________________________________|_________________");
// $display("| | ");
// $display("| Vendor-Specific Header Offset 04h | 0x%s ", himage4(addr));
// $display("| ________________________________________________________________________________________________________________|_________________");
// $display("| | ");
// $display("| 31 20 | 16| 0 | ");
// $display("| VSEC Length | VSEC Rev | VSEC ID | ");
// $display("| | ");
// $display("| 15:0 VSEC ID : This field is a vendor-defined ID number that indicates the nature | 0x%s ", himage4(dword[15:0]));
// $display("| and format of the VSEC structure. Software must qualify the Vendor | ");
// $display("| ID before interpreting this field. | ");
// $display("| 19:16 VSEC Rec : This field is a vendor-defined ID number that indicates | 0x%s ", himage4(dword[19:16]));
// $display("| the nature and format of theVSEC structure. | ");
// $display("| Software must qualify the Vendor ID before interpreting this field. | ");
// $display("| This field is a PCI-SIG defined version number that indicates | ");
// $display("| 31:20 VSEC Length : This field indicates the number of bytes in the entire VSEC | %s ", dimage4(dword[31:20]));
// $display("| structure, including the PCI Express Extended Capability header, | ");
// $display("| the Vendor- Specific header, and the Vendor-Specific registers | ");
// $display("| | ");
//
// addr = 16'h918;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// $display("| ________________________________________________________________________________________________________________|_________________");
// $display("| | Offset 18h | 0x%s ", himage4(addr));
// $display("| |_____________|_________________");
// $display("| | ");
// $display("| [15:0] Number of of RX SOP | %s ", dimage4(dword[15:0]));
// $display("| [31:16] Number of times that HIP Avalon-St rx_ready de-assert when rx_valid is set | %s ", dimage4(dword[31:16]));
//
// addr = 16'h91C;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// $display("| ________________________________________________________________________________________________________________|_________________");
// $display("| | Offset 1Ch | 0x%s ", himage4(addr));
// $display("| |_____________|_________________");
// $display("| [15:0] Number of of TX SOP | %s ", dimage4(dword[15:0]));
// $display("| [31:16] Number of times that HIP Avalon St tx_ready de-assert when tx_valid is set | %s ", dimage4(dword[31:16]));
//
// addr = 16'h920;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// $display("| ________________________________________________________________________________________________________________|_________________");
// $display("| | Offset 20h | 0x%s ", himage4(addr));
// $display("| Upstream read to completion latency |_____________|_________________");
// $display("| pld clk is : | %d MHz ", (dword[31:30]>2'b00)?250:125);
// $display("| [14:0] Min Mrd to Cpl upstream latency : number of clock cycles | %s ", dimage4(dword[14:0]));
// $display("| [29:15] Max Mrd to Cpl upstream latency : number of clock cycles | %s ", dimage4(dword[29:15]));
//
// pld_clk_is_250MHz = (dword[31:30]>2'b00)?1:0;
//
// addr = 16'h924;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// $display("| ________________________________________________________________________________________________________________|_________________");
// $display("| | Offset 24h | 0x%s ", himage4(addr));
// $display("| |_____________|_________________");
// $display("| [19:0] Number of clock cycles for MWr upstream transfer | %s ", dimage4(dword[19:0]));
// nclk = dword[19:0];
//
// addr = 16'h928;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// $display("| ________________________________________________________________________________________________________________|_________________");
// $display("| | Offset 28h | 0x%s ", himage4(addr));
// $display("| |_____________|_________________");
// $display("| [19:0] Number of DWORD MWr upstream transfer | %s ", dimage4(dword[19:0]));
// $display("| | ");
// ndword = dword[19:0];
//
// ellapse_timens = (pld_clk_is_250MHz==1'b1)?nclk*4:nclk*8;
// nbytes = ndword*4;
// throughputMBps = (nclk>0)? (nbytes*1000) / ellapse_timens :0;
// $display("| | ");
// $display("| Write throughput | %s MBps ", dimage4(throughputMBps));
// $display("| | ");
//
// addr = 16'h92C;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// $display("| ________________________________________________________________________________________________________________|_________________");
// $display("| | Offset 2Ch | 0x%s ", himage4(addr));
// $display("| |_____________|_________________");
// $display("| [19:0] Number of clock cycles for MRd upstream transfer | %s ", dimage4(dword[19:0]));
// $display("| | ");
// nclk = dword[19:0];
//
// addr = 16'h930;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// $display("| ________________________________________________________________________________________________________________|_________________");
// $display("| | Offset 30h | 0x%s ", himage4(addr));
// $display("| |_____________|_________________");
// $display("| [19:0] Number of DWORD MRd upstream transfer | %s ", dimage4(dword[19:0]));
// $display("| | ");
// ndword = dword[19:0];
//
// ellapse_timens = (pld_clk_is_250MHz==1'b1)?nclk*4:nclk*8;
// nbytes = ndword*4;
// throughputMBps = (nclk>0)? (nbytes*1000) / ellapse_timens :0;
// $display("| | ");
// $display("| Read throughput | %s MBps ", dimage4(throughputMBps));
// $display("| | ");
//
// addr = 16'h934;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// nclk = (dword[18:17]==2'b00)?32'h1:
// (dword[18:17]==2'b01)?32'h2:
// (dword[18:17]==2'b10)?32'h4:32'h8;
// $display("| ________________________________________________________________________________________________________________|_________________");
// $display("| | Offset 34h | 0x%s ", himage4(addr));
// $display("| LTSSM BLACK BOX Recording Retrieval |_____________|_________________");
// $display("| | ");
// $display("| [4:0] : LTSSM Transition | 0x%s ", himage4(dword[4:0]));
// $display("| [5] : perstn|npor | %s ", dimage4(dword[5]));
// $display("| [13:6]: Is lock to data | 0x%s ", himage4(dword[13:6]));
// $display("| [14] : signaldetect | %s ", (dword[16:15]==2'b11)?"8.0Gb":(dword[16:15]==2'b10)?"5.0Gb":"2.5Gb");
// $display("| [16:15]: rate 1->G1, 2 -->G2, 3:G3 | %s ", dimage4(dword[16:15]));
// $display("| [18:17]: Number of lanes | %s ", dimage4(nclk[7:0]));
// $display("| [19 ]: RESERVED | ");
// $display("| [27:20]: Number of word in the black box | %s ", dimage4(dword[27:20]));
// $display("| [31:28]: RESERVED | ");
// $display("| | ");
// nbytes=0;
// nbytes[7:0]=dword[27:20];
// if (nbytes>0) begin
// $display("| --------------------------------------------------------------------------------------------------------------- | ");
// $display("| | ");
// $display("| LTSSM[4:0] | Perstn | Locktodata[7:0] | Signaldetect | rate | lane |");
// $display("| | | | | | |");
// while (nbytes > 0) begin
// addr = 16'h934;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// nclk = (dword[18:17]==2'b00)?32'h1:
// (dword[18:17]==2'b01)?32'h2:
// (dword[18:17]==2'b10)?32'h4: 32'h8;
// $display("| %s | %s | %s | %s | %s | %s |", himage4(dword[4:0]),
// dimage4(dword[5]),
// himage4(dword[13:6]),
// dimage4(dword[14]),
// (dword[16:15]==2'b11)?"8.0Gb":
// (dword[16:15]==2'b10)?"5.0Gb":"2.5Gb",
// dimage4(nclk[7:0] ));
// nbytes=0;
// nbytes[7:0]=dword[27:20];
// end
// end
// $display("| | ");
// $display("| ________________________________________________________________________________________________________________| ");
// addr = 16'h938;
// $display("| | Offset 38h | 0x%s ", himage4(addr));
// $display("| TLP Dump |_____________|_________________");
// $display("| | ");
// $display("| | TLP Type (Tag) | Bytes | H1_H2_H3 | ");
// empty=0;
// full=0;
// ast_rx=0;
// while (empty == 0) begin
// addr = 16'h938;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// dword = shmem_read(SCR_MEMSLAVE,4) ;
// empty = dword[31];
// ast_rx = dword[0];
// addr = 16'h93C;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// tlp_h1 = shmem_read(SCR_MEMSLAVE,4) ;
// addr = 16'h940;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// tlp_h2 = shmem_read(SCR_MEMSLAVE,4) ;
// addr = 16'h944;
// ebfm_cfgrd_wait( 1, 1, 0, addr, 4, SCR_MEMSLAVE, compl_status);
// tlp_h3 = shmem_read(SCR_MEMSLAVE,4) ;
// $display("| %s %s | 0x%s ", (ast_rx==1'b0)?"TX |":"RX |",DisplayTLP(tlp_h1, tlp_h2,tlp_h3, ast_rx), himage8(dword) );
//
// end
// $display("| | ");
// $display("| ________________________________________________________________________________________________________________| ");
// end
// endtask
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// altpcie_tlp_monitor : Miscellaneous TLP analysis //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// ____________________________________________________________________________________________________________________________________________ //
// | | //
// | PCIe TLP Header | //
// |__________________________________________________________________________________________________________________________________________| //
// |31 30 29 |28 27 26 25 24 |23 |22 21 20 |19 |18 |17 |16 |15 |14 |13 12 |11 10 |9 8 7 6 5 4 3 2 1 0 | //
// |7 6 5 |4 3 2 1 0 |7 |6 5 4 |3 |2 |1 |0 |7 |6 |5 4 |3 2 |1 0 7 6 5 4 3 2 1 0 | //
// h1 |FMT |TYPE |R |TC |R |A |R |TH |TD |EP |Attr |ATT |Length | //
// h2 | | Last BE |First BE | //
// h3 | | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// | | //
// | MEMORY TLP | //
// |__________________________________________________________________________________________________________________________________________| //
// h2 | Requester ID | TAG | Last BE |First BE | //
// h3 | Address | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// | | //
// | COMPLETION TLP | //
// |__________________________________________________________________________________________________________________________________________| //
// h2 | Completer ID |Cpl Status | | Byte Count | //
// h3 | Requester ID | TAG | R | Lower Address | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// //
// _______________________________ //
// | | | //
// | {FMT,TYPE} | | //
// |____________________|________| //
// | 8'b0000_0000 | MRd | //
// | 8'b0010_0000 | MRd | //
// | 8'b0000_0001 | MRdLk | //
// | 8'b0010_0001 | MRdLk | //
// | 8'b0100_0000 | MWr | //
// | 8'b0110_0000 | MWr | //
// | 8'b0000_0010 | IORd | //
// | 8'b0100_0010 | IOWr | //
// | 8'b0000_0100 | CfgRd0 | //
// | 8'b0100_0100 | CfgWr0 | //
// | 8'b0000_0101 | CfgRd1 | //
// | 8'b0100_0101 | CfgWr1 | //
// | 8'b0011_0XXX | Msg | //
// | 8'b0111_0XXX | MsgD | //
// | 8'b0000_1010 | Cpl | //
// | 8'b0100_1010 | CplD | //
// | 8'b0000_1011 | CplLk | //
// | 8'b0100_1011 | CplDLk | //
// |_____________________________| //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// INSPECTOR MONITOR ADDRESS MAP //
// _________________________________________________ ___________________________________________________________________________________________ //
// | | | | //
// | VSEC_ADDR | VSEC_DATA | Description | //
// |_____________|__________________________________|___________________________________________________________________________________________| //
// | 8'h18 | INSP_ADDRREADY_SOP_RX | {ast_cnt_rx_ready, ast_cnt_rx_sop} | //
// | 8'h1C | INSP_ADDRREADY_SOP_TX | {ast_cnt_tx_ready, ast_cnt_tx_sop} | //
// | 8'h20 | INSP_ADDRLATENCY_MRD_UPSTREAM | {(PLD_CLK_IS_250MHZ==1)?2'b01:2'b00,ast_max_read_latency_cnt, ast_min_read_latency_cnt} | //
// | 8'h24 | INSP_ADDRMWR_THROUGHPUT_CLK | {(PLD_CLK_IS_250MHZ==1)?2'b01:2'b00,10'h0,ast_cnt_mwr_clk} | //
// | 8'h28 | INSP_ADDRMWR_THROUGHPUT_DWORD | {12'h0 ,ast_cnt_mwr_dword} | //
// | 8'h2C | INSP_ADDRMRD_THROUGHPUT_CLK | {(PLD_CLK_IS_250MHZ==1)?2'b01:2'b00,10'h0,ast_cnt_mrd_clk} | //
// | 8'h30 | INSP_ADDRMRD_THROUGHPUT_DWORD | {12'h0 ,ast_cnt_mrd_dword} | //
// | 8'h34 | Read LTSSM FIFO | Push output LTSSM Black Box FIFO DWORD | //
// | | | lane_act[1:0], rate[1:0], signaldetect, is_lockedtodata[7:0],npor_perstn, ltssmstate[4:0] | //
// | | | 10'h0, ltssm_blackbox_used[7:0] | //
// | 8'hFF:07 | RESERVED | RESERVED | //
// |_____________|__________________________________|___________________________________________________________________________________________| //
// //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_tlp_inspector_monitor_a10 # (
parameter ST_DATA_WIDTH = 64,
parameter ST_BE_WIDTH = 8,
parameter ST_CTRL_WIDTH = 1,
parameter LANES = 8,
parameter INSP_ADDRNUM_WORD = 20,
parameter PLD_CLK_IS_250MHZ = 0,
parameter MONITOR_READYVALID_RATIO = 1,
parameter UPSTREAM_READ_LATENCY = 1,
parameter UPSTREAM_THROUGHPUT_MEASUREMENT= 1,
parameter BLACKBOX_LTSSM = 1,
parameter BLACKBOX_LTSSM_DEPTH32_BLOCK = 2, // Number of 32 Deep FIFO
parameter BLACKBOX_AST_TLP = 1,
parameter BLACKBOX_AST_TLP_DEPTH32_BLOCK = 4, // Number of 32 Deep FIFO
parameter BLACKBOX_AST_TLP_WIDTH_FIFO = 100 // 3 32 bit TLP
) (
input [127:0] trigger_ast,
input [ST_BE_WIDTH-1 : 0] rx_ast_be,
input [ST_DATA_WIDTH-1 : 0] rx_ast_data,
input [1 : 0] rx_ast_empty,
input [ST_CTRL_WIDTH-1 : 0] rx_ast_eop,
input [ST_CTRL_WIDTH-1 : 0] rx_ast_sop,
input [ST_CTRL_WIDTH-1 : 0] rx_ast_valid,
input rx_ast_ready,
input [ST_DATA_WIDTH-1 : 0] tx_ast_data,
input [1 :0] tx_ast_empty,
input [ST_CTRL_WIDTH-1 :0] tx_ast_eop,
input [ST_CTRL_WIDTH-1 :0] tx_ast_sop,
input tx_ast_valid,
input tx_ast_ready,
input trigger_on,
input rx_h_val,
input [31:0] rx_h1,
input [31:0] rx_h2,
input [31:0] rx_h3,
input [31:0] rx_h4,
input tx_h_val,
input [31:0] tx_h1,
input [31:0] tx_h2,
input [31:0] tx_h3,
input [31:0] tx_h4,
input [3 : 0] lane_act,
input [4 : 0] ltssmstate,
input [1 : 0] rate,
input [LANES-1:0] signaldetect,
input [LANES-1:0] is_lockedtodata,
input npor_perstn,
// TLP Analysis output
input [7:0] monitor_addr /* synthesis preserve */,
input monitor_rd_pulse ,
output reg [31:0] monitor_data,
input clk,
input sclr
);
localparam ZEROS = 512'h0;
//////////////////////////////////////////////////////////////////////////////////
//
// Inspector Info Result (TDM)
//
wire [15:0] ast_cnt_rx_sop; // Count the number of SOP
wire [15:0] ast_cnt_rx_ready; // Count the number of times when ready goes to 0 when valid goes to 0
wire [15:0] ast_cnt_tx_sop; // Count the number of SOP
wire [15:0] ast_cnt_tx_ready; // Count the number of times when ready goes to 0 when valid goes to 0
wire [19:0] ast_cnt_mwr_clk ; // Number of clock cycles required during the transfer
wire [19:0] ast_cnt_mwr_dword; // Number of DWORD transfered
wire [19:0] ast_cnt_mrd_clk ; // Number of clock cycles required during the transfer
wire [19:0] ast_cnt_mrd_dword; // Number of DWORD transfered
wire [14:0] ast_min_read_latency_cnt;
wire [14:0] ast_max_read_latency_cnt;
wire [19:0] ltssm_blackbox /* synthesis keep */;
wire [7:0] ltssm_blackbox_used /* synthesis keep */;
wire [127:0] tlp_blackbox;
wire [7:0] tlp_blackbox_used;
wire [127:0] tlp_h1h2;
reg [31:0] monitor_data_bb;
localparam INSP_ADDRREADY_SOP_RX = 0,
INSP_ADDRREADY_SOP_TX = 1,
INSP_ADDRLATENCY_MRD_UPSTREAM = 2,
INSP_ADDRMWR_THROUGHPUT_CLK = 3,
INSP_ADDRMWR_THROUGHPUT_DWORD = 4,
INSP_ADDRMRD_THROUGHPUT_CLK = 5,
INSP_ADDRMRD_THROUGHPUT_DWORD = 6,
INSP_ADDR_LTSSM_BLACKBOX = 7,
INSP_ADDR_TLP_BB = 8,
INSP_ADDR_TLP_BB_H1 = 9,
INSP_ADDR_TLP_BB_H2 = 10,
INSP_ADDR_TLP_BB_H3 = 11;
reg [INSP_ADDRNUM_WORD-1:0] monitor_addr_predec; //Pre-decode VSEC ADDR
localparam LTSSM_BB_USED_WIDTH = (BLACKBOX_LTSSM_DEPTH32_BLOCK==1)?5:
(BLACKBOX_LTSSM_DEPTH32_BLOCK==2)?6:
(BLACKBOX_LTSSM_DEPTH32_BLOCK==3)?7:
(BLACKBOX_LTSSM_DEPTH32_BLOCK==4)?8:8;
always @(posedge clk) begin : p_insp_vsec
if (sclr==1'b1) begin
monitor_data <= 32'h0;
monitor_data_bb <= 32'h0;
monitor_addr_predec <= ZEROS[INSP_ADDRNUM_WORD-1:0];
end
else begin
monitor_addr_predec[INSP_ADDRREADY_SOP_RX ] <= (monitor_addr==8'h18)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDRREADY_SOP_TX ] <= (monitor_addr==8'h1C)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDRLATENCY_MRD_UPSTREAM] <= (monitor_addr==8'h20)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDRMWR_THROUGHPUT_CLK ] <= (monitor_addr==8'h24)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDRMWR_THROUGHPUT_DWORD] <= (monitor_addr==8'h28)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDRMRD_THROUGHPUT_CLK ] <= (monitor_addr==8'h2C)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDRMRD_THROUGHPUT_DWORD] <= (monitor_addr==8'h30)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDR_LTSSM_BLACKBOX ] <= (monitor_addr==8'h34)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDR_TLP_BB ] <= (monitor_addr==8'h38)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDR_TLP_BB_H1 ] <= (monitor_addr==8'h3C)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDR_TLP_BB_H2 ] <= (monitor_addr==8'h40)?1'b1:1'b0;
monitor_addr_predec[INSP_ADDR_TLP_BB_H3 ] <= (monitor_addr==8'h44)?1'b1:1'b0;
if (monitor_addr_predec[INSP_ADDRREADY_SOP_RX]==1'b1) begin
monitor_data <= {ast_cnt_rx_ready, ast_cnt_rx_sop};
end
else if (monitor_addr_predec[INSP_ADDRREADY_SOP_TX]==1'b1) begin
monitor_data <= {ast_cnt_tx_ready, ast_cnt_tx_sop};
end
else if (monitor_addr_predec[INSP_ADDRLATENCY_MRD_UPSTREAM]==1'b1) begin
monitor_data <= {(PLD_CLK_IS_250MHZ==1)?2'b01:2'b00 , ast_max_read_latency_cnt, ast_min_read_latency_cnt};
end
else if (monitor_addr_predec[INSP_ADDRMWR_THROUGHPUT_CLK]==1'b1) begin
monitor_data <= {(PLD_CLK_IS_250MHZ==1)?2'b01:2'b00, 10'h0 , ast_cnt_mwr_clk};
end
else if (monitor_addr_predec[INSP_ADDRMWR_THROUGHPUT_DWORD]==1'b1) begin
monitor_data <= {12'h0 , ast_cnt_mwr_dword};
end
else if (monitor_addr_predec[INSP_ADDRMRD_THROUGHPUT_CLK]==1'b1) begin
monitor_data <= {(PLD_CLK_IS_250MHZ==1)?2'b01:2'b00, 10'h0 , ast_cnt_mrd_clk};
end
else if (monitor_addr_predec[INSP_ADDRMRD_THROUGHPUT_DWORD]==1'b1) begin
monitor_data <= {12'h0 , ast_cnt_mrd_dword};
end
else begin
monitor_data <= monitor_data_bb;
end
if (monitor_addr_predec[INSP_ADDR_LTSSM_BLACKBOX]==1'b1) begin
monitor_data_bb <= {4'h0, ltssm_blackbox_used , ltssm_blackbox};
end
else if (monitor_addr_predec[INSP_ADDR_TLP_BB]==1'b1) begin
monitor_data_bb <= tlp_h1h2[127:96];
end
else if (monitor_addr_predec[INSP_ADDR_TLP_BB_H1]==1'b1) begin
monitor_data_bb <= tlp_h1h2[31:0];
end
else if (monitor_addr_predec[INSP_ADDR_TLP_BB_H2]==1'b1) begin
monitor_data_bb <= tlp_h1h2[63:32];
end
else if (monitor_addr_predec[INSP_ADDR_TLP_BB_H3]==1'b1) begin
monitor_data_bb <= tlp_h1h2[95:64];
end
end
end
//
// END Inspector Info Result (TDM)
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//
// Testbench display only
//
// synthesis translate_off
function integer throughputMBps;
input [19:0] nclk;
input [19:0] ndword;
reg [31:0] nbytes;
reg [31:0] ellapse_timens;
begin
ellapse_timens = (PLD_CLK_IS_250MHZ==1)?nclk*4:nclk*8;
nbytes = ndword*4;
throughputMBps = (ellapse_timens>32'h0)? (nbytes*1000) / ellapse_timens :0;
end
endfunction
reg [31:0] write_troughtput, read_troughtput;
initial begin
write_troughtput = 32'h0;
read_troughtput = 32'h0;
end
always @(posedge clk) begin : p_sim_tpwr
write_troughtput <= ((ast_cnt_mwr_clk>20'h0)&&(ast_cnt_mwr_dword>20'h0))?throughputMBps(ast_cnt_mwr_clk,ast_cnt_mwr_dword):32'h0;
read_troughtput <= ((ast_cnt_mrd_clk>20'h0)&&(ast_cnt_mrd_dword>20'h0))?throughputMBps(ast_cnt_mrd_clk,ast_cnt_mrd_dword):32'h0;
end
final begin
if (UPSTREAM_THROUGHPUT_MEASUREMENT==1) begin
$display("INFO: altpcie_tlp_inspector_monitor ::---------------------------------------------------------------------------------------------");
$display("INFO: altpcie_tlp_inspector_monitor :: Upstream memory Write Throughput ");
$display("INFO: altpcie_tlp_inspector_monitor ::---------------------------------------------------------------------------------------------");
$display("INFO: altpcie_tlp_inspector_monitor :: Throughput : %d MBytes/s ",write_troughtput);
$display("INFO: altpcie_tlp_inspector_monitor :: %d bytes have been sent within %d clock cycles at %s" ,ast_cnt_mwr_dword*4,ast_cnt_mwr_clk, (PLD_CLK_IS_250MHZ==1)?"250 Mhz":"125 Mhz");
$display("INFO: altpcie_tlp_inspector_monitor ::---------------------------------------------------------------------------------------------");
$display("INFO: altpcie_tlp_inspector_monitor :: Upstream memory Read Throughput ");
$display("INFO: altpcie_tlp_inspector_monitor ::---------------------------------------------------------------------------------------------");
$display("INFO: altpcie_tlp_inspector_monitor :: Throughput : %d MBytes/s ",read_troughtput);
$display("INFO: altpcie_tlp_inspector_monitor :: %d bytes have been sent within %d clock cycles at %s" ,ast_cnt_mrd_dword*4,ast_cnt_mrd_clk, (PLD_CLK_IS_250MHZ==1)?"250 Mhz":"125 Mhz");
end
if (UPSTREAM_READ_LATENCY==1) begin
$display("INFO: altpcie_tlp_inspector_monitor ::---------------------------------------------------------------------------------------------");
$display("INFO: altpcie_tlp_inspector_monitor :: Upstream read to completion latency ");
$display("INFO: altpcie_tlp_inspector_monitor ::---------------------------------------------------------------------------------------------");
$display("INFO: altpcie_tlp_inspector_monitor :: Minimum measured latency : %d ns" ,(PLD_CLK_IS_250MHZ==1)?ast_min_read_latency_cnt*4:ast_min_read_latency_cnt*8 );
$display("INFO: altpcie_tlp_inspector_monitor :: Maximum measured latency : %d ns" ,(PLD_CLK_IS_250MHZ==1)?ast_max_read_latency_cnt*4:ast_max_read_latency_cnt*8 );
end
end
// synthesis translate_on
//
// END TB Display only
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//
// Analyze ready_valid
//
generate begin : g_monitor_ready
if (MONITOR_READYVALID_RATIO==1) begin
reg [15:0] count_rx_sop; // Count the number of SOP
reg [15:0] count_rx_ready;// Count the number of times when ready goes to 0 when valid goes to 0
reg [15:0] count_tx_sop; // Count the number of SOP
reg [15:0] count_tx_ready; // Count the number of times when ready goes to 0 when valid goes to 0
always @(posedge clk) begin : p_readyvalid
if (sclr==1'b1) begin
count_tx_ready <=16'h0; // Count how many times HIP de-assert ready when Valid Asserted
count_tx_sop <=16'h0; // Count how many SOP
count_rx_ready <=16'h0; // Count how many times HIP de-assert ready when Valid Asserted
count_rx_sop <=16'h0; // Count how many SOP
end
else if (trigger_on == 1'b1) begin
if (tx_ast_sop[ST_CTRL_WIDTH-1:0]>ZEROS[ST_CTRL_WIDTH-1:0]) begin
count_tx_sop <= count_tx_sop+16'h1;
end
if ((tx_ast_valid==1'b1)&&(tx_ast_ready==1'b0)) begin
count_tx_ready <= count_tx_ready+16'h1;
end
if (rx_ast_sop[ST_CTRL_WIDTH-1:0]>ZEROS[ST_CTRL_WIDTH-1:0]) begin
count_rx_sop <= count_rx_sop+16'h1;
end
if ((rx_ast_valid[ST_CTRL_WIDTH-1:0]>ZEROS[ST_CTRL_WIDTH-1:0])&&(rx_ast_ready==1'b0)) begin
count_rx_ready <= count_rx_ready+16'h1;
end
end
end
assign ast_cnt_rx_sop = count_rx_sop ;
assign ast_cnt_rx_ready = count_rx_ready;
assign ast_cnt_tx_sop = count_tx_sop ;
assign ast_cnt_tx_ready = count_tx_ready;
end
if (MONITOR_READYVALID_RATIO==0) begin
assign ast_cnt_rx_sop = 16'h0;
assign ast_cnt_rx_ready = 16'h0;
assign ast_cnt_tx_sop = 16'h0;
assign ast_cnt_tx_ready = 16'h0;
end
end
endgenerate
//
// END Analyze ready_valid
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//
// Analyze upstream_latency
//
generate begin : g_monitor_upstream_latency
if (UPSTREAM_READ_LATENCY==1) begin
reg [14:0] latency_cnt;
reg [14:0] max_read_latency_cnt;
reg [14:0] min_read_latency_cnt;
reg [7:0] mrdtag;
always @(posedge clk) begin : p_latency
if (sclr==1'b1) begin
latency_cnt <= 15'h0;
max_read_latency_cnt <= 15'h0;
min_read_latency_cnt <= 15'h0;
mrdtag <= 8'h0;
end
else if (trigger_on == 1'b1) begin
// Check for AST TX MRd
if ((tx_h_val==1'b1)&&((tx_h1[31:24]==8'h0)||(tx_h1[31:24]==8'b0010_0000))&&(latency_cnt==15'h0)) begin
mrdtag <= tx_h2[15:8];
latency_cnt <= latency_cnt+15'h1;
end
// Check for AST RX CPL
else if ((rx_h_val==1'b1)&&(rx_h1[28:24]==5'b01010)&&(mrdtag==rx_h3[15:8])) begin
latency_cnt <= 15'h0;
if (min_read_latency_cnt==15'h0) begin
min_read_latency_cnt<= latency_cnt;
end
else if (min_read_latency_cnt>latency_cnt) begin
min_read_latency_cnt<= latency_cnt;
end
if (max_read_latency_cnt==15'h0) begin
max_read_latency_cnt<= latency_cnt;
end
else if (max_read_latency_cnt<latency_cnt) begin
max_read_latency_cnt<= latency_cnt;
end
end
else if (latency_cnt>15'h0) begin
latency_cnt <= latency_cnt+15'h1;
end
end
end
assign ast_min_read_latency_cnt = min_read_latency_cnt;
assign ast_max_read_latency_cnt = max_read_latency_cnt;
end
if (UPSTREAM_READ_LATENCY==0) begin
assign ast_min_read_latency_cnt = 15'h0;
assign ast_max_read_latency_cnt = 15'h0;
end
end
endgenerate
//
// END Analyze upstream_latency
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//
// Analyze upstream_throughput
//
generate begin : g_monitor_upstream_throughput
if (UPSTREAM_THROUGHPUT_MEASUREMENT==1) begin
//
// Write Throughput
//
reg [19:0] cnt_mwr_clk; // Number of clock cycles required during the transfer
reg [19:0] cnt_mwr_dword; // Number of DWORD transfered
reg [7:0] cnt_mwr_inactive;
reg [7:0] cnt_tx_mwr_to_tx_eop;
reg cnt_mwr_dword_eq_zero;
reg cnt_mwr_dword_max;
reg cnt_mwr_clk_eq_zero;
reg cnt_mwr_inactive_eq_FE;
reg cnt_mwr_inactive_eq_FF;
reg tx_mwr_pulse;
reg tx_eop_on_h;
reg tx_eop_txmwr;
reg tx_ast_valid_on_h;
reg [19:0] cnt_mrd_clk; // Number of clock cycles required during the transfer
reg cnt_mrd_clk_eq_zero;
reg [19:0] cnt_mrd_dword; // Number of DWORD transfered
reg cnt_mrd_dword_eq_zero;
reg cnt_mrd_dword_max;
reg [7:0] cnt_rx_cpl_to_eop;
reg [7:0] cnt_cpl_inactive;
reg cnt_cpl_inactive_eq_FE;
reg cnt_cpl_inactive_eq_FF;
reg tx_mrd_pulse;
reg rx_eop_on_h;
reg rx_eop_cpl;
reg rx_ast_valid_on_h;
reg rx_cpl_pulse ;
always @(posedge clk) begin : p_mwr_throughput
if (sclr==1'b1) begin
rx_eop_on_h <= 1'b0;
rx_ast_valid_on_h <= 1'b0;
tx_eop_on_h <= 1'b0;
tx_ast_valid_on_h <= 1'b0;
cnt_mwr_clk <= 20'h0;
cnt_mwr_clk_eq_zero <= 1'b0;
cnt_mwr_dword <= 20'h0;
cnt_mwr_dword_max <= 1'b0;
cnt_mwr_dword_eq_zero <= 1'b0;
cnt_mwr_inactive <= 8'h0;
cnt_mwr_inactive_eq_FE <= 1'b0;
cnt_mwr_inactive_eq_FF <= 1'b0;
tx_mwr_pulse <= 1'b0;
cnt_tx_mwr_to_tx_eop <= 8'h0;
tx_eop_txmwr <= 1'b0;
cnt_mrd_clk <= 20'h0;
cnt_mrd_clk_eq_zero <= 1'b0;
cnt_mrd_dword <= 20'h0;
cnt_mrd_dword_max <= 1'b0;
cnt_mrd_dword_eq_zero <= 1'b0;
tx_mrd_pulse <= 1'b0;
cnt_cpl_inactive <= 8'h0;
cnt_cpl_inactive_eq_FE <= 1'b0;
cnt_cpl_inactive_eq_FF <= 1'b0;
cnt_rx_cpl_to_eop <= 8'h0;
rx_eop_cpl <= 1'b1;
rx_cpl_pulse <= 1'b0;
end
else if (trigger_on == 1'b1) begin
tx_eop_on_h <= (tx_ast_eop[ST_CTRL_WIDTH-1 :0]>ZEROS[ST_CTRL_WIDTH-1 :0])?1'b1:1'b0;
tx_ast_valid_on_h <= tx_ast_valid;
rx_eop_on_h <= (rx_ast_eop[ST_CTRL_WIDTH-1 :0]>ZEROS[ST_CTRL_WIDTH-1 :0])?1'b1:1'b0;
rx_ast_valid_on_h <= (rx_ast_valid[ST_CTRL_WIDTH-1 : 0]>ZEROS[ST_CTRL_WIDTH-1 : 0])?1'b1:1'b0 ;
// Compute MRd throughput
cnt_mrd_dword_eq_zero <= (cnt_mrd_dword == 20'h0)?1'b1:1'b0;
cnt_mrd_dword_max <= (cnt_mrd_dword>20'hF_FF00 )?1'b1:1'b0;
cnt_mrd_clk_eq_zero <= (cnt_mrd_clk == 20'h0)?1'b1:1'b0;
cnt_cpl_inactive_eq_FE <= (cnt_cpl_inactive == 8'hFE)?1'b1:1'b0;
cnt_cpl_inactive_eq_FF <= (cnt_cpl_inactive == 8'hFF)?1'b1:1'b0;
tx_mrd_pulse <= ((tx_h_val==1'b1)&&((tx_h1[31:24]==8'b0000_0000)||(tx_h1[31:24]==8'b0010_0000))&&(tx_h1[9:0]>10'h1))?1'b1: 1'b0;
rx_cpl_pulse <= ((rx_h_val==1'b1)&&((rx_h1[31:24]==8'b0000_1010)||(rx_h1[31:24]==8'b0100_1010)) )?1'b1: 1'b0;
// Count DWORD starting first TX MRd with a payload>2
if ((cnt_mrd_dword_max==1'b0)&&(tx_h_val==1'b1)&&((tx_h1[31:24]==8'b0000_0000)||(tx_h1[31:24]==8'b0010_0000))&&(tx_h1[9:0]>10'h1)) begin
cnt_mrd_dword <= cnt_mrd_dword+{10'h0, tx_h1[9:0]};
end
// Count Clock cycles, stop counting if inactive rx_valid for more than 256 cycles
if ((cnt_mrd_dword_max==1'b0)&&(cnt_mrd_dword_eq_zero==1'b0)&&(cnt_cpl_inactive_eq_FF==1'b0)&&(cnt_cpl_inactive_eq_FE==1'b0)) begin
cnt_mrd_clk <= cnt_mrd_clk+20'h1;
end
else if ((cnt_cpl_inactive_eq_FE==1'b1)&&(cnt_mrd_clk>20'hFD)) begin
cnt_mrd_clk <= cnt_mrd_clk-cnt_rx_cpl_to_eop;
end
if ((tx_mrd_pulse==1'b1)||(rx_cpl_pulse==1'b1)) begin
cnt_cpl_inactive <= 8'h0;
end
else if ((cnt_cpl_inactive<8'hFF)&&(cnt_mrd_dword_eq_zero==1'b0)) begin
cnt_cpl_inactive <= cnt_cpl_inactive+8'h1;
end
if (rx_cpl_pulse==1'b1) begin
cnt_rx_cpl_to_eop <= 8'hFE;
end
else if ((rx_eop_cpl==1'b0)&&(rx_ast_valid_on_h==1'b1)) begin
cnt_rx_cpl_to_eop <= cnt_rx_cpl_to_eop-8'h1;
end
if (rx_eop_on_h==1'b1) begin
rx_eop_cpl <= 1'b1;
end
else if ((rx_h_val==1'b1)&&((rx_h1[31:24]==8'b0000_1010)||(rx_h1[31:24]==8'b0100_1010)) ) begin
rx_eop_cpl <= 1'b0;
end
// Compute Mwr throughput
// Check for AST TX MWr
cnt_mwr_dword_eq_zero <= (cnt_mwr_dword == 20'h0)?1'b1:1'b0;
cnt_mwr_dword_max <= (cnt_mwr_dword>20'hF_FF00 )?1'b1:1'b0;
cnt_mwr_clk_eq_zero <= (cnt_mwr_clk == 20'h0)?1'b1:1'b0;
cnt_mwr_inactive_eq_FE <= (cnt_mwr_inactive == 8'hFE)?1'b1:1'b0;
cnt_mwr_inactive_eq_FF <= (cnt_mwr_inactive == 8'hFF)?1'b1:1'b0;
tx_mwr_pulse <= ((tx_h_val==1'b1)&&((tx_h1[31:24]==8'b0100_0000)||(tx_h1[31:24]==8'b0110_0000))&& (tx_h1[9:0]>10'h2))?1'b1: 1'b0;
// Count DWORD starting first TX MWr with a payload>2
if ((cnt_mwr_dword_max==1'b0)&&(tx_h_val==1'b1)&&((tx_h1[31:24]==8'b0100_0000)||(tx_h1[31:24]==8'b0110_0000)) && (tx_h1[9:0]>10'h2)) begin
cnt_mwr_dword <= cnt_mwr_dword+{10'h0, tx_h1[9:0]};
end
// Count Clock cycles, stop counting if inactive tx_valid for more than 256 cycles
if ((cnt_mwr_dword_max==1'b0)&&(cnt_mwr_dword_eq_zero==1'b0)&&(cnt_mwr_inactive_eq_FF==1'b0)&&(cnt_mwr_inactive_eq_FE==1'b0)) begin
cnt_mwr_clk <= cnt_mwr_clk+20'h1;
end
else if ((cnt_mwr_inactive_eq_FE==1'b1)&&(cnt_mwr_clk>20'hFD)) begin
cnt_mwr_clk <= cnt_mwr_clk-cnt_tx_mwr_to_tx_eop;
end
if (tx_mwr_pulse==1'b1) begin
cnt_mwr_inactive <= 8'h0;
end
else if ((cnt_mwr_inactive<8'hFF)&&(cnt_mwr_dword_eq_zero==1'b0)&&(tx_ast_valid_on_h==1'b0)) begin
cnt_mwr_inactive <= cnt_mwr_inactive+8'h1;
end
if (tx_mwr_pulse==1'b1) begin
cnt_tx_mwr_to_tx_eop <= 8'hFE;
end
else if ((tx_eop_txmwr==1'b0)&&(tx_ast_valid_on_h==1'b1)) begin
cnt_tx_mwr_to_tx_eop <= cnt_tx_mwr_to_tx_eop-8'h1;
end
if (tx_eop_on_h==1'b1) begin
tx_eop_txmwr <= 1'b1;
end
else if ((tx_h_val==1'b1)&&((tx_h1[31:24]==8'b0100_0000)||(tx_h1[31:24]==8'b0110_0000))) begin
tx_eop_txmwr <= 1'b0;
end
end
end
assign ast_cnt_mwr_clk = cnt_mwr_clk ; // Number of clock cycles required during the transfer
assign ast_cnt_mwr_dword= cnt_mwr_dword; // Number of DWORD transfered
assign ast_cnt_mrd_clk = cnt_mrd_clk ; // Number of clock cycles required during the transfer
assign ast_cnt_mrd_dword= cnt_mrd_dword; // Number of DWORD transfered
end
if (UPSTREAM_THROUGHPUT_MEASUREMENT==0) begin
assign ast_cnt_mwr_clk = 20'h0; // Number of clock cycles required during the transfer
assign ast_cnt_mwr_dword= 20'h0; // Number of DWORD transfered
assign ast_cnt_mrd_clk = 20'h0; // Number of clock cycles required during the transfer
assign ast_cnt_mrd_dword= 20'h0; // Number of DWORD transfered
end
end
endgenerate
//
// END Analyze upstream_throughput
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//
// LTSSM Blackbox
//
generate begin : g_blackbox_ltssm
if (BLACKBOX_LTSSM==1) begin
reg [1 : 0] lane_act_r;
reg [4 : 0] ltssmstate_r;
reg [1 : 0] rate_r;
reg signaldetect_r;
reg [7:0] is_lockedtodata_r;
reg npor_perstn_r;
reg ltssm_transit;
wire ltssmfifo_full /* synthesis keep*/;
wire ltssmfifo_empty /* synthesis keep*/;
wire [19:0] ltssmfifo_rddata /* synthesis keep*/;
wire [LTSSM_BB_USED_WIDTH-1:0] ltssmfifo_used /* synthesis keep*/;
reg ltssmfifo_rreq;
always @(posedge clk) begin : p_bb_ltssm
if (sclr==1'b1) begin
lane_act_r <= ZEROS[1 : 0];
ltssmstate_r <= ZEROS[4 : 0];
rate_r <= ZEROS[1 : 0];
signaldetect_r <= 1'b0 ;
is_lockedtodata_r <= ZEROS[7:0] ;
npor_perstn_r <= 1'b0 ;
ltssm_transit <= 1'b0;
ltssmfifo_rreq <= 1'b0;
end
else begin
lane_act_r <= (lane_act==4'b1000)?2'h3:
(lane_act==4'b0100)?2'h2:
(lane_act==4'b0010)?2'h1:2'h0;
ltssmstate_r <= ltssmstate;
rate_r <= rate ;
signaldetect_r <= (signaldetect[LANES-1:0]>0)?1'b1:1'b0;
is_lockedtodata_r[LANES-1:0] <= is_lockedtodata[LANES-1:0];
npor_perstn_r <= npor_perstn ;
ltssm_transit <= ((ltssmstate_r < 5'h02) | (ltssmstate==ltssmstate_r))?1'b0:(ltssmfifo_full==1'b1)?1'b0:1'b1;
ltssmfifo_rreq <= ((monitor_addr==8'h34) && (monitor_rd_pulse==1'b1) && (ltssmfifo_empty==1'b0))?1'b1:1'b0;
end
end
altpcie_scfifo_a10 #(
.WIDTH (20),// typical 20,40,60,80
.NUM_FIFO32 (BLACKBOX_LTSSM_DEPTH32_BLOCK )// Number of 32 DEEP FIFO
) ltssmfifo (
.clk (clk) , // input
.sclr (sclr) , // input
// 2 2 1 8 1 5
.wdata ({1'b0, lane_act_r[1:0], rate_r[1:0], signaldetect_r, is_lockedtodata_r[7:0],npor_perstn_r, ltssmstate_r[4:0]}) , // input [WIDTH-1:0]
.wreq (ltssm_transit) , // input
.full (ltssmfifo_full) , // output
.rdata (ltssmfifo_rddata) , // output [WIDTH-1:0]
.rreq (ltssmfifo_rreq) , // input
.empty (ltssmfifo_empty) , // output
.used (ltssmfifo_used[LTSSM_BB_USED_WIDTH-1:0]) // output [4:0]
);
assign ltssm_blackbox = ltssmfifo_rddata;
assign ltssm_blackbox_used = (BLACKBOX_LTSSM_DEPTH32_BLOCK==1)?{3'h0, ltssmfifo_used[LTSSM_BB_USED_WIDTH-1:0]}:
(BLACKBOX_LTSSM_DEPTH32_BLOCK==2)?{2'h0, ltssmfifo_used[LTSSM_BB_USED_WIDTH-1:0]}:
(BLACKBOX_LTSSM_DEPTH32_BLOCK==3)?{1'h0, ltssmfifo_used[LTSSM_BB_USED_WIDTH-1:0]}:
ltssmfifo_used[LTSSM_BB_USED_WIDTH-1:0];
end
if (BLACKBOX_LTSSM==0) begin
assign ltssm_blackbox = 20'h0;
assign ltssm_blackbox_used = 8'h0;
end
end
endgenerate
//
// END Analyze LTSSM Blackbox
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//
// AST TLP Blackbox
//
generate begin : g_bb_tlp
if (BLACKBOX_AST_TLP==1) begin
reg [3:0] tlp_cnt ;
wire full_tx ;
wire [BLACKBOX_AST_TLP_WIDTH_FIFO-1:0] rdata_tx ;
reg rreq_tx ;
wire empty_tx ;
wire [4:0] used_tx ;
wire full_rx ;
wire[BLACKBOX_AST_TLP_WIDTH_FIFO-1:0] rdata_rx ;
reg rreq_rx ;
wire empty_rx ;
wire [4:0] used_rx ;
reg txrxrreq;
reg wreq_ast_r ;
reg txtlp_sel ;
wire full_ast ;
wire [BLACKBOX_AST_TLP_WIDTH_FIFO-1:0] wdata_ast ;
wire [BLACKBOX_AST_TLP_WIDTH_FIFO-1:0] rdata_ast ;
reg rreq_ast ;
wire empty_ast ;
wire [4:0] used_ast ;
always @(posedge clk) begin : p_bb_ltssm
if (sclr==1'b1) begin
tlp_cnt <= 4'h0;
wreq_ast_r <= 1'b0;
rreq_rx <= 1'b0;
rreq_tx <= 1'b0;
rreq_ast <= 1'b0;
txtlp_sel <= 1'b0;
txrxrreq <= 1'b0;
end
else begin
if ((rx_h_val==1'b1) || (tx_h_val==1'b1)) begin
tlp_cnt <= (tlp_cnt<4'hF)?tlp_cnt+4'h1:4'h0;
end
if (full_ast==1'b0) begin
if ((empty_tx==1'b0)&&(empty_rx==1'b1)) begin
rreq_tx <= 1'b1;
rreq_rx <= 1'b0;
end
else if ((empty_tx==1'b1)&&(empty_rx==1'b0)) begin
rreq_tx <= 1'b0;
rreq_rx <= 1'b1;
end
else if ((empty_tx==1'b1)&&(empty_rx==1'b0)) begin
txrxrreq <= (txrxrreq==1'b1)?1'b0:1'b1;
rreq_tx <= txrxrreq;
rreq_rx <= ~txrxrreq;
//TODO Read Counter to re-order RX/TX Fifo
end
else begin
rreq_tx <= 1'b0;
rreq_rx <= 1'b0;
end
wreq_ast_r <= ((rreq_tx==1'b1)&&(empty_tx==1'b0))?1'b1:
((rreq_rx==1'b1)&&(empty_rx==1'b0))?1'b1:1'b0;
txtlp_sel <= rreq_tx;
end
rreq_ast <= ((monitor_addr==8'h38) && (monitor_rd_pulse==1'b1) && (empty_ast==1'b0))?1'b1:1'b0;
end
end
altpcie_scfifo_a10 #(
.WIDTH (BLACKBOX_AST_TLP_WIDTH_FIFO),
.NUM_FIFO32 (0 ) // 16 Deep only
) tlprxfifo (
.clk (clk) , // input
.sclr (sclr) , // input
.wdata ({tlp_cnt[2:0],1'b1, rx_h3, rx_h2, rx_h1}),//
.wreq (((full_rx==1'b0)&&(trigger_on==1'b1))?rx_h_val:1'b0) , // input
.full (full_rx) , // output
.rdata (rdata_rx) , // output [WIDTH-1:0]
.rreq ((empty_rx==1'b0)?rreq_rx:1'b0) , // input
.empty (empty_rx) , // output
.used (used_rx ) // output [4:0]
);
altpcie_scfifo_a10 #(
.WIDTH (BLACKBOX_AST_TLP_WIDTH_FIFO),
.NUM_FIFO32 (0 ) // 16 Deep only
) tlptxfifo (
.clk (clk) ,
.sclr (sclr) ,
.wdata ({tlp_cnt[2:0],1'b0, tx_h3, tx_h2, tx_h1}) ,
.wreq ((full_tx==1'b0)?tx_h_val:1'b0) ,
.full (full_tx ) ,
.rdata (rdata_tx ) ,
.rreq ((empty_tx==1'b0)?rreq_tx:1'b0 ) ,
.empty (empty_tx ) ,
.used (used_tx )
);
altpcie_scfifo_a10 #(
.WIDTH (BLACKBOX_AST_TLP_WIDTH_FIFO),
.NUM_FIFO32 (4 ) // 128 deep
) tlpastfifo (
.clk (clk ),
.sclr (sclr ),
.wdata (wdata_ast),
.wreq (wreq_ast_r ),
.full (full_ast ),
.rdata (rdata_ast),
.rreq (rreq_ast ),
.empty (empty_ast),
.used (used_ast )
);
assign wdata_ast = (txtlp_sel==1'b1)?rdata_tx:rdata_rx;
// 106 105 104:100 , 99:0
assign tlp_h1h2 = { empty_ast, full_ast, used_ast[4:0], 21'h0, rdata_ast};
end
if (BLACKBOX_AST_TLP==0) begin
assign tlp_h1h2 = 128'h0;
end
end
endgenerate
//
// END Analyze upstream_throughput
//////////////////////////////////////////////////////////////////////////////////
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// ALTPCIE_TLP_INSPECTOR : Optional module to monitor TLP Performances on AvalonTream HIP Bus, added to ALTPCIE_HIP_256_PIPEn1B //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// ____________________________________________________________________________________________________________________________________________ //
// | | //
// | PCIe TLP Header | //
// |__________________________________________________________________________________________________________________________________________| //
// |31 30 29 |28 27 26 25 24 |23 |22 21 20 |19 |18 |17 |16 |15 |14 |13 12 |11 10 |9 8 7 6 5 4 3 2 1 0 | //
// |7 6 5 |4 3 2 1 0 |7 |6 5 4 |3 |2 |1 |0 |7 |6 |5 4 |3 2 |1 0 7 6 5 4 3 2 1 0 | //
// h1 |FMT |TYPE |R |TC |R |A |R |TH |TD |EP |Attr |ATT |Length | //
// h2 | | Last BE |First BE | //
// h3 | | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// | | //
// | MEMORY TLP | //
// |__________________________________________________________________________________________________________________________________________| //
// h2 | Requester ID | TAG | Last BE |First BE | //
// h3 | Address | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// | | //
// | COMPLETION TLP | //
// |__________________________________________________________________________________________________________________________________________| //
// h2 | Completer ID |Cpl Status | | Byte Count | //
// h3 | Requester ID | TAG | R | Lower Address | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_tlp_inspector_pcsig_drive_a10 # (
parameter ST_DATA_WIDTH = 64,
parameter VSEC_HIPDRV_SIGNAL_PAR = 0,
parameter VSEC_HIPDRV_SIGNAL_PWR = 0,
parameter ST_BE_WIDTH = 8,
parameter LANES = 8,
parameter ST_CTRL_WIDTH = 1,
parameter PLD_CLK_IS_250MHZ = 0
) (
// Single clock domain clk (which is pld_clk in the level above)
// - All Inputs are synchronized to clk
// - All Outputs are synchronized to clk
// CSEB Signals
input pcsig_wr_pulse_op , // In Wr Pulse 0x50
input pcsig_wr_pulse_dt , // In Wr Pulse 0x54
input [31:0] pcsig_wrdata , // in [31:0]
input [31:0] pcsig_opcode , // in [31:0]
input pcsig_rd_pulse_dt , // In Rd Pulse - Read Data Register
input pcsig_rd_pulse_st , // In Rd Pulse - Read Status Register
output reg [31:0] pcsig_rddata , // out [31:0]
// HIP.AST Interface
input [ST_BE_WIDTH-1 : 0] rx_ast_be ,
input [ST_DATA_WIDTH-1 : 0] rx_ast_data ,
input [1 : 0] rx_ast_empty ,
input [ST_CTRL_WIDTH-1 : 0] rx_ast_eop ,
input [ST_CTRL_WIDTH-1 : 0] rx_ast_sop ,
input [ST_CTRL_WIDTH-1 : 0] rx_ast_valid ,
output reg rx_st_mask ,
output reg rx_st_ready ,
input tx_ast_ready ,
output reg [255 : 0] tx_st_data ,
output reg [1 :0] tx_st_empty ,
output reg [3 :0] tx_st_eop ,
output reg [3 :0] tx_st_err ,
output reg [3 :0] tx_st_sop ,
output reg tx_st_valid ,
output reg [4 : 0] aer_msi_num ,
output reg app_int_sts ,
output reg [4 : 0] app_msi_num ,
output reg app_msi_req ,
output reg [2 : 0] app_msi_tc ,
output reg [4 : 0] pex_msi_num ,
output reg [31:0] tx_st_parity ,
output reg pm_auxpwr ,
output reg [9 : 0] pm_data ,
output reg pme_to_cr ,
output reg pm_event ,
output reg [6 :0] cpl_err ,
output reg cpl_pending ,
input clk ,
input sclr
);
localparam ZEROS = 512'h0;
localparam TLP_TXFIFO_WIDTH = ST_DATA_WIDTH + // output reg [255|127|64 : 0] tx_st_data
2 + // output reg [1 :0] tx_st_empty
4 + // output reg [3 :0] tx_st_eop
4 + // output reg [3 :0] tx_st_err
4 + // output reg [3 :0] tx_st_sop
1 + // output reg tx_st_valid
5 + // output reg [4 : 0] aer_msi_num
1 + // output reg app_int_sts
5 + // output reg [4 : 0] app_msi_num
1 + // output reg app_msi_req
3 + // output reg [2 : 0] app_msi_tc
(ST_DATA_WIDTH==64)? 6:
(ST_DATA_WIDTH==128)? 2: 14;
localparam TLP_TXFIFO_WIDTH_DW = (ST_DATA_WIDTH/32)+1; // Number of DWORD
// synthesis translate_off
initial begin
pcsig_rddata = ZEROS[31:0] ; // out [31:0]
aer_msi_num = ZEROS [4 : 0] ; //Out [4 : 0]
app_int_sts = ZEROS [0] ; //Out
app_msi_num = ZEROS [4 : 0] ; //Out [4 : 0]
app_msi_req = ZEROS [0] ; //Out
app_msi_tc = ZEROS [2 : 0] ; //Out [2 : 0]
pex_msi_num = ZEROS [4 : 0] ; //Out [4 : 0]
pm_auxpwr = ZEROS [0] ; //Out
pm_data = ZEROS [9 : 0] ; //Out [9 : 0]
pme_to_cr = ZEROS [0] ; //Out
pm_event = ZEROS [0] ; //Out
rx_st_mask = ZEROS [0] ; //Out
rx_st_ready = ZEROS [0] ; //Out
tx_st_data = ZEROS [255 : 0]; //Out [255 : 0]
tx_st_empty = ZEROS [1 :0] ; //Out [1 :0]
tx_st_eop = ZEROS [3 :0] ; //Out [3 :0]
tx_st_err = ZEROS [3 :0] ; //Out [3 :0]
tx_st_parity = ZEROS [31:0] ; //Out [31:0]
tx_st_sop = ZEROS [3 :0] ; //Out [3 :0]
tx_st_valid = ZEROS [0] ; //Out
cpl_err = ZEROS [6 :0] ; //Out [6 :0]
cpl_pending = ZEROS [0] ; //Out
end
// synthesis translate_on
reg [4:0] tlp_txfifo_cntwr ;
reg [TLP_TXFIFO_WIDTH-1:0] tlp_txfifo_wdata ;
reg tlp_txfifo_wreq ;
reg tlp_txfifo_rreq ;
wire tlp_txfifo_full ;
wire [TLP_TXFIFO_WIDTH-1:0] tlp_txfifo_rdata ;
wire tlp_txfifo_empty ;
wire [4:0] tlp_txfifo_used ;
always @(posedge clk) begin : p_cseb
if (sclr == 1'b1 ) begin
pcsig_rddata <= ZEROS[31:0] ; // out [31:0]
aer_msi_num <= ZEROS [4 : 0] ; //Out [4 : 0]
app_int_sts <= ZEROS [0] ; //Out
app_msi_num <= ZEROS [4 : 0] ; //Out [4 : 0]
app_msi_req <= ZEROS [0] ; //Out
app_msi_tc <= ZEROS [2 : 0] ; //Out [2 : 0]
pex_msi_num <= ZEROS [4 : 0] ; //Out [4 : 0]
pm_auxpwr <= ZEROS [0] ; //Out
pm_data <= ZEROS [9 : 0] ; //Out [9 : 0]
pme_to_cr <= ZEROS [0] ; //Out
pm_event <= ZEROS [0] ; //Out
rx_st_mask <= ZEROS [0] ; //Out
rx_st_ready <= ZEROS [0] ; //Out
tx_st_data <= ZEROS [255 : 0]; //Out [255 : 0]
tx_st_empty <= ZEROS [1 :0] ; //Out [1 :0]
tx_st_eop <= ZEROS [3 :0] ; //Out [3 :0]
tx_st_err <= ZEROS [3 :0] ; //Out [3 :0]
tx_st_parity <= ZEROS [31:0] ; //Out [31:0]
tx_st_sop <= ZEROS [3 :0] ; //Out [3 :0]
tx_st_valid <= ZEROS [0] ; //Out
cpl_err <= ZEROS [6 :0] ; //Out [6 :0]
cpl_pending <= ZEROS [0] ; //Out
tlp_txfifo_cntwr <= ZEROS [4:0] ;
tlp_txfifo_wdata <= ZEROS [TLP_TXFIFO_WIDTH-1:0];
tlp_txfifo_wreq <= ZEROS [0] ;
tlp_txfifo_rreq <= ZEROS [0] ;
end
else begin
if (VSEC_HIPDRV_SIGNAL_PAR==0) begin
tx_st_parity <= ZEROS [31:0] ; //Out [31:0]
end
if (VSEC_HIPDRV_SIGNAL_PWR==0) begin
pex_msi_num <= ZEROS [4 : 0] ; //Out [4 : 0]
pm_auxpwr <= ZEROS [0] ; //Out
pm_data <= ZEROS [9 : 0] ; //Out [9 : 0]
pme_to_cr <= ZEROS [0] ; //Out
pm_event <= ZEROS [0] ; //Out
cpl_err <= ZEROS [6 :0] ; //Out [6 :0]
cpl_pending <= ZEROS [0] ; //Out
end
// Read FIFO
if (tlp_txfifo_rdata==1'b1) begin
tx_st_data [ST_DATA_WIDTH-1 : 0] <= tlp_txfifo_rdata[ST_DATA_WIDTH-1 : 0];//
tx_st_empty [1 :0] <= tlp_txfifo_rdata[ST_DATA_WIDTH+1 :ST_DATA_WIDTH+ 0];//
tx_st_eop [3 :0] <= tlp_txfifo_rdata[ST_DATA_WIDTH+5 :ST_DATA_WIDTH+ 2];//
tx_st_err [3 :0] <= tlp_txfifo_rdata[ST_DATA_WIDTH+9 :ST_DATA_WIDTH+ 6];//
tx_st_sop [3 :0] <= tlp_txfifo_rdata[ST_DATA_WIDTH+13 :ST_DATA_WIDTH+10];//
tx_st_valid <= tlp_txfifo_rdata[ST_DATA_WIDTH+14 :ST_DATA_WIDTH+14];//
aer_msi_num [4 : 0] <= tlp_txfifo_rdata[ST_DATA_WIDTH+19 :ST_DATA_WIDTH+15];//
app_int_sts <= tlp_txfifo_rdata[ST_DATA_WIDTH+20 :ST_DATA_WIDTH+20];//
app_msi_num [4 : 0] <= tlp_txfifo_rdata[ST_DATA_WIDTH+25 :ST_DATA_WIDTH+21];//
app_msi_req <= tlp_txfifo_rdata[ST_DATA_WIDTH+26 :ST_DATA_WIDTH+26];//
app_msi_tc <= tlp_txfifo_rdata[ST_DATA_WIDTH+29 :ST_DATA_WIDTH+27];//
end
end
end
altpcie_scfifo #(
.WIDTH (TLP_TXFIFO_WIDTH),
.NUM_FIFO32 (4 )
) tlp_txfifo (
.clk (clk ),
.sclr (sclr ),
.wdata (tlp_txfifo_wdata ),
.wreq (tlp_txfifo_wreq ),
.full (tlp_txfifo_full ),
.rdata (tlp_txfifo_rdata ),
.rreq (tlp_txfifo_rreq ),
.empty (tlp_txfifo_empty ),
.used (tlp_txfifo_used )
);
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// altpcie_tlp_inspector_trigger : Submodule of altpcie_tlp_inspector managing trigger logic //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// ____________________________________________________________________________________________________________________________________________ //
// | | //
// | PCIe TLP Header | //
// |__________________________________________________________________________________________________________________________________________| //
// |31 30 29 |28 27 26 25 24 |23 |22 21 20 |19 |18 |17 |16 |15 |14 |13 12 |11 10 |9 8 7 6 5 4 3 2 1 0 | //
// |7 6 5 |4 3 2 1 0 |7 |6 5 4 |3 |2 |1 |0 |7 |6 |5 4 |3 2 |1 0 7 6 5 4 3 2 1 0 | //
// h1 |FMT |TYPE |R |TC |R |A |R |TH |TD |EP |Attr |ATT |Length | //
// h2 | | Last BE |First BE | //
// h3 | | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// | | //
// | MEMORY TLP | //
// |__________________________________________________________________________________________________________________________________________| //
// h2 | Requester ID | TAG | Last BE |First BE | //
// h3 | Address | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// | | //
// | COMPLETION TLP | //
// |__________________________________________________________________________________________________________________________________________| //
// h2 | Completer ID |Cpl Status | | Byte Count | //
// h3 | Requester ID | TAG | R | Lower Address | //
// h4 |__________________________________________________________________________________________________________________________________________| //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Trigger OP Codes input trigger [127:0] // //
// //
// ---------------Trigger First Dword : 31:0 : Opcode----------------------------------------- //
// //
// trigger [0] | SOP : When 1 trigger on first SOP //
// [1] | TX/RX : When 1 trigger on RX AST, When 0 Trigger on TX AST //
// [2] | FMT_TLP : When check trigger FMT_TLP //
// [3] | TAG : When check trigger TAG //
// [5:4] | Address : When check trigger Address Lower 24 bits //
// | 5:4 =2'b01, 8-bit addr LSB //
// | 5:4 =2'b10, 16-bit addr LSB //
// | 5:4 =2'b11, 32-bit addr LSB //
// [6] | First BE : When check trigger first BE //
// [7] | Last BE : When check trigger last BE //
// [8] | Attr : When check trigger Attr //
// [9] | Reset trigger only //
// [10] | Reset reset Inspector //
// [11] | Enable Trigger ON : When set activate trigger logic //
// [12 ] | Use CSEB trigger //
// [31:13] | RESERVED //
// | //
// ---------------Trigger Second Dword : 63:32 : Data Compare----------------------------------------- //
// | //
// trigger [39:32] | FMT TYPE: When trigger[2] set, trigger on //
// | _______________________________ //
// | | | | //
// | | {FMT,TYPE} | | //
// | |____________________|________| //
// | | 8'b0000_0000 | MRd | //
// | | 8'b0010_0000 | MRd | //
// | | 8'b0000_0001 | MRdLk | //
// | | 8'b0010_0001 | MRdLk | //
// | | 8'b0100_0000 | MWr | //
// | | 8'b0110_0000 | MWr | //
// | | 8'b0000_0010 | IORd | //
// | | 8'b0100_0010 | IOWr | //
// | | 8'b0000_0100 | CfgRd0 | //
// | | 8'b0100_0100 | CfgWr0 | //
// | | 8'b0000_0101 | CfgRd1 | //
// | | 8'b0100_0101 | CfgWr1 | //
// | | 8'b0011_0XXX | Msg | //
// | | 8'b0111_0XXX | MsgD | //
// | | 8'b0000_1010 | Cpl | //
// | | 8'b0100_1010 | CplD | //
// | | 8'b0000_1011 | CplLk | //
// | | 8'b0100_1011 | CplDLk | //
// | |_____________________________| //
// | //
// | //
// [47:40] | TAG : When trigger[3] set, trigger on TAG value //
// [51:48] | First BE : When trigger[6] set, trigger on Last BE //
// [51:48] | Last BE : When trigger[7] set, trigger on Last BE //
// [63:52] | RESERVED //
// [95:64] | when trigger[5:4]>0 32 bit lower address trigger //
// | //
// ---------------Stop Trigger [127:96]------------------------------------------------------------------------------------------------------------- //
// | //
// [96] | When set no stop trigger //
// [97] | TX/RX : When 1 stop-trigger on RX AST, When 0 Trigger on TX AST //
// [98] | FMT_TLP : When check stop-trigger FMT_TLP //
// [99] | TAG : When check stop-trigger TAG //
// [101:100]| Address : When check stop-trigger Address Lower 24 bits //
// | [101:100] =2'b01, 8-bit addr LSB //
// | [101:100] =2'b10, 16-bit addr LSB //
// | [101:100] =2'b11, 32-bit addr LSB //
// [109:102]| FMT TYPE: When stop-trigger[98] set, //
// [117:110]| TAG : When stop-trigger[99] //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
module altpcie_tlp_inspector_trigger_a10 # (
parameter ST_DATA_WIDTH = 64,
parameter ST_BE_WIDTH = 8,
parameter ST_CTRL_WIDTH = 1,
parameter POWER_UP_TRIGGER = 1,
parameter SIMPLE_TRIGGER = 0
) (
input [127:0] trigger_ast,
input [ST_BE_WIDTH-1 : 0] rx_ast_be,
input [ST_DATA_WIDTH-1 : 0] rx_ast_data,
input [1 : 0] rx_ast_empty,
input [ST_CTRL_WIDTH-1 : 0] rx_ast_eop,
input [ST_CTRL_WIDTH-1 : 0] rx_ast_sop,
input [ST_CTRL_WIDTH-1 : 0] rx_ast_valid,
input rx_ast_ready,
input [ST_DATA_WIDTH-1 : 0] tx_ast_data,
input [1 :0] tx_ast_empty,
input [ST_CTRL_WIDTH-1 :0] tx_ast_eop,
input [ST_CTRL_WIDTH-1 :0] tx_ast_sop,
input tx_ast_valid,
input tx_ast_ready,
output reg trigger_on,
output reg rx_h_val,
output reg [31:0] rx_h1,
output reg [31:0] rx_h2,
output reg [31:0] rx_h3,
output reg [31:0] rx_h4,
output reg tx_h_val,
output reg [31:0] tx_h1,
output reg [31:0] tx_h2,
output reg [31:0] tx_h3,
output reg [31:0] tx_h4,
input clk,
input sclr
);
localparam ZEROS = 512'h0;
localparam TRIGGER_BIT_FIRST_SOP = 0,
TRIGGER_BIT_RXTX = 1,
TRIGGER_BIT_FMTTLP = 2,
TRIGGER_BIT_TAG = 3,
TRIGGER_BIT_RESET_TRIGGER = 9,
TRIGGER_BIT_RESET_INSPECTOR = 10,
TRIGGER_BIT_ENABLE_TRIGGER = 11;
wire rx_mem_tlp;
wire rx_4dw_tlp;
wire tx_mem_tlp;
wire tx_4dw_tlp;
reg trigger_lastbe;
reg trigger_firstbe;
reg trigger_addr_rx;
reg trigger_fmttype_rx;
reg trigger_tag_rx;
reg trigger_addr_tx;
reg trigger_fmttype_tx;
reg trigger_tag_tx;
assign rx_mem_tlp = (rx_ast_data[28:25]==4'h0)?1'b1:1'b0;
assign rx_4dw_tlp = (rx_ast_data[29]==1'b1) ?1'b1:1'b0;
assign tx_mem_tlp = (tx_ast_data[28:25]==4'h0)?1'b1:1'b0;
assign tx_4dw_tlp = (tx_ast_data[29]==1'b1) ?1'b1:1'b0;
always @(posedge clk) begin : p_trigger
if (sclr == 1'b1 ) begin
trigger_on <= 1'b0;
end
else begin
if ((trigger_ast[0]==1'b1)||(SIMPLE_TRIGGER==1)) begin
if (trigger_ast[1] == 1'b0) begin // Trigger on TX
if (tx_ast_sop[ST_CTRL_WIDTH-1:0]>ZEROS[ST_CTRL_WIDTH-1:0]) begin
// Start counting on the first TX SOP
trigger_on <=1'b1;
end
end
else begin // Trigger on Rx
if (rx_ast_sop[ST_CTRL_WIDTH-1:0]>ZEROS[ST_CTRL_WIDTH-1:0]) begin
// Start counting on the first RX SOP
trigger_on <=1'b1;
end
end
end
else begin
trigger_on <= trigger_tag_rx |
trigger_addr_rx |
trigger_fmttype_rx |
trigger_tag_tx |
trigger_addr_tx |
trigger_fmttype_tx |
trigger_lastbe |
trigger_firstbe ;
end
end
end
generate begin : g_trg
if ((ST_DATA_WIDTH==256)||(ST_DATA_WIDTH==128)) begin : gp_trg128
always @(posedge clk) begin : p_trg
if (sclr == 1'b1 ) begin
rx_h_val <= 1'b0;
rx_h1 <= 32'h0;
rx_h2 <= 32'h0;
rx_h3 <= 32'h0;
rx_h4 <= 32'h0;
tx_h_val <= 1'b0;
tx_h1 <= 32'h0;
tx_h2 <= 32'h0;
tx_h3 <= 32'h0;
tx_h4 <= 32'h0;
trigger_tag_rx <= 1'b0;
trigger_addr_rx <= 1'b0;
trigger_fmttype_rx <= 1'b0;
trigger_tag_tx <= 1'b0;
trigger_addr_tx <= 1'b0;
trigger_fmttype_tx <= 1'b0;
trigger_lastbe <= 1'b0;
trigger_firstbe <= 1'b0;
end
else begin
rx_h_val <= rx_ast_sop[0]&rx_ast_valid[0];
if (rx_ast_valid[0]==1'b1) begin
if (rx_ast_sop[0]==1'b1) begin
rx_h1 <=rx_ast_data[31:0];
rx_h2 <=rx_ast_data[63:32];
rx_h3 <=rx_ast_data[96:64];
rx_h4 <=rx_ast_data[127:96];
if ((trigger_ast[TRIGGER_BIT_ENABLE_TRIGGER]==1'b1)&&(trigger_ast[TRIGGER_BIT_RXTX]==1'b1)&&(trigger_on==1'b0)) begin // Trigger on RX
//FMT-TYPE
if ((trigger_ast[TRIGGER_BIT_FMTTLP]==1'b1)&&
((trigger_ast[39:32]==rx_ast_data[31:24]))) begin
trigger_fmttype_rx <=1'b1;
end
//TAG
if ((trigger_ast[TRIGGER_BIT_TAG]==1'b1)&&
((rx_ast_data[31:30]==2'b00)&&(trigger_ast[47:40]==rx_ast_data[47:40]))) begin
trigger_tag_rx <=1'b1;
end
//Address LSB
if ((trigger_ast[5:4]>2'b00)&&(rx_mem_tlp==1'b1)) begin //trigger memory TLP
if (rx_4dw_tlp==1'b1) begin
if ((trigger_ast[5:4]==2'b11)&&(rx_ast_data[127:96]==trigger_ast[95:64])) begin
trigger_addr_rx <= 1'b1;
end
else if ((trigger_ast[5:4]==2'b10)&&(rx_ast_data[111:96]==trigger_ast[79:64])) begin
trigger_addr_rx <= 1'b1;
end
else if ((rx_ast_data[105:96]==trigger_ast[72:64])) begin
trigger_addr_rx <= 1'b1;
end
end
else begin
if ((trigger_ast[5:4]==2'b11)&&(rx_ast_data[95:64]==trigger_ast[95:64])) begin
trigger_addr_rx <= 1'b1;
end
else if ((trigger_ast[5:4]==2'b10)&&(rx_ast_data[79:64]==trigger_ast[79:64])) begin
trigger_addr_rx <= 1'b1;
end
else if ((rx_ast_data[72:64]==trigger_ast[72:64])) begin
trigger_addr_rx <= 1'b1;
end
end
end
end
end
end
tx_h_val <= tx_ast_sop[0]&tx_ast_valid;
if (tx_ast_valid==1'b1) begin
if (tx_ast_sop[0]==1'b1) begin
tx_h1 <=tx_ast_data[31:0];
tx_h2 <=tx_ast_data[63:32];
tx_h3 <=tx_ast_data[96:64];
tx_h4 <=tx_ast_data[127:96];
if ((trigger_ast[TRIGGER_BIT_ENABLE_TRIGGER]==1'b1)&&(trigger_ast[TRIGGER_BIT_RXTX]==1'b0)&&(trigger_on==1'b0)) begin // Trigger on RX
//FMT-TYPE
if ((trigger_ast[TRIGGER_BIT_FMTTLP]==1'b1)&&
((trigger_ast[39:32]==tx_ast_data[31:24]))) begin
trigger_fmttype_tx <=1'b1;
end
//TAG
if ((trigger_ast[TRIGGER_BIT_TAG]==1'b1)&&
((tx_ast_data[31:30]==2'b00)&&(trigger_ast[47:40]==tx_ast_data[47:40]))) begin
trigger_tag_tx <=1'b1;
end
//Address LSB
if ((trigger_ast[5:4]>2'b00)&&(tx_mem_tlp==1'b1)) begin //trigger memory TLP
if (tx_4dw_tlp==1'b1) begin
if ((trigger_ast[5:4]==2'b11)&&(tx_ast_data[127:96]==trigger_ast[95:64])) begin
trigger_addr_tx <= 1'b1;
end
else if ((trigger_ast[5:4]==2'b10)&&(tx_ast_data[111:96]==trigger_ast[79:64])) begin
trigger_addr_tx <= 1'b1;
end
else if ((tx_ast_data[105:96]==trigger_ast[72:64])) begin
trigger_addr_tx <= 1'b1;
end
end
else begin
if ((trigger_ast[5:4]==2'b11)&&(tx_ast_data[95:64]==trigger_ast[95:64])) begin
trigger_addr_tx <= 1'b1;
end
else if ((trigger_ast[5:4]==2'b10)&&(tx_ast_data[79:64]==trigger_ast[79:64])) begin
trigger_addr_tx <= 1'b1;
end
else if ((tx_ast_data[72:64]==trigger_ast[72:64])) begin
trigger_addr_tx <= 1'b1;
end
end
end
end
end
end
end
end
end
else begin : gp_trg64
reg rx_mem_tlp_r;
reg rx_4dw_tlp_r;
reg tx_mem_tlp_r;
reg tx_4dw_tlp_r;
reg rx_ast_nsop ;
reg tx_ast_nsop ;
always @(posedge clk) begin : p_64_trg
if (sclr == 1'b1 ) begin
rx_h_val <= 1'b0;
rx_h1 <= 32'h0;
rx_h2 <= 32'h0;
rx_h3 <= 32'h0;
rx_h4 <= 32'h0;
tx_h_val <= 1'b0;
tx_h1 <= 32'h0;
tx_h2 <= 32'h0;
tx_h3 <= 32'h0;
tx_h4 <= 32'h0;
rx_ast_nsop <= 1'b0; //next cycle after rx_ast_nsop
tx_ast_nsop <= 1'b0; //next cycle after tx_ast_nsop
trigger_tag_rx <= 1'b0;
trigger_addr_rx <= 1'b0;
trigger_fmttype_rx <= 1'b0;
trigger_tag_tx <= 1'b0;
trigger_addr_tx <= 1'b0;
trigger_fmttype_tx <= 1'b0;
trigger_lastbe <= 1'b0;
trigger_firstbe <= 1'b0;
tx_mem_tlp_r <= 1'b0;
tx_4dw_tlp_r <= 1'b0;
rx_mem_tlp_r <= 1'b0;
rx_4dw_tlp_r <= 1'b0;
end
else begin
rx_h_val <= rx_ast_nsop&rx_ast_valid[0];
if (rx_ast_valid[0]==1'b1) begin
if (rx_ast_sop[0]==1'b1) begin
rx_h1 <= rx_ast_data[31:0];
rx_h2 <= rx_ast_data[63:32];
rx_mem_tlp_r <= rx_mem_tlp;
rx_4dw_tlp_r <= rx_4dw_tlp;
rx_ast_nsop <= 1'b1;
if ((trigger_ast[TRIGGER_BIT_ENABLE_TRIGGER]==1'b1)&&(trigger_ast[TRIGGER_BIT_RXTX]==1'b1)&&(trigger_on==1'b0)) begin // Trigger on RX
//FMT-TYPE
if ((trigger_ast[TRIGGER_BIT_FMTTLP]==1'b1)&&
((trigger_ast[39:32]==rx_ast_data[31:24]))) begin
trigger_fmttype_rx <=1'b1;
end
//TAG
if ((trigger_ast[TRIGGER_BIT_TAG]==1'b1)&&
((rx_ast_data[31:30]==2'b00)&&(trigger_ast[47:40]==rx_ast_data[47:40]))) begin
trigger_tag_rx <=1'b1;
end
end
end
if (rx_ast_nsop==1'b1) begin
rx_h3 <= rx_ast_data[31:0];
rx_h4 <= rx_ast_data[63:32];
rx_mem_tlp_r <= 1'b0;
rx_4dw_tlp_r <= 1'b0;
rx_ast_nsop <= 1'b0;
if ((trigger_ast[TRIGGER_BIT_ENABLE_TRIGGER]==1'b1)&&(trigger_ast[TRIGGER_BIT_RXTX]==1'b1)&&(trigger_on==1'b0)) begin // Trigger on RX
//Address LSB
if ((trigger_ast[5:4]>2'b00)&&(rx_mem_tlp_r==1'b1)) begin //trigger memory TLP
if (rx_4dw_tlp==1'b1) begin
if ((trigger_ast[5:4]==2'b11)&&(rx_ast_data[63:32]==trigger_ast[95:64])) begin
trigger_addr_rx <= 1'b1;
end
else if ((trigger_ast[5:4]==2'b10)&&(rx_ast_data[47:32]==trigger_ast[79:64])) begin
trigger_addr_rx <= 1'b1;
end
else if ((rx_ast_data[39:32]==trigger_ast[71:64])) begin
trigger_addr_rx <= 1'b1;
end
end
else begin
if ((trigger_ast[5:4]==2'b11)&&(rx_ast_data[31:0]==trigger_ast[95:64])) begin
trigger_addr_rx <= 1'b1;
end
else if ((trigger_ast[5:4]==2'b10)&&(rx_ast_data[15:0]==trigger_ast[79:64])) begin
trigger_addr_rx <= 1'b1;
end
else if ((rx_ast_data[7:0]==trigger_ast[72:64])) begin
trigger_addr_rx <= 1'b1;
end
end
end
end
end
end
tx_h_val <= tx_ast_nsop&tx_ast_valid;
if (tx_ast_valid==1'b1) begin
if (tx_ast_sop[0]==1'b1) begin
tx_h1 <=tx_ast_data[31:0];
tx_h2 <=tx_ast_data[63:32];
tx_mem_tlp_r <= tx_mem_tlp;
tx_4dw_tlp_r <= tx_4dw_tlp;
tx_ast_nsop <= 1'b1;
if ((trigger_ast[TRIGGER_BIT_ENABLE_TRIGGER]==1'b1)&&(trigger_ast[TRIGGER_BIT_RXTX]==1'b0)&&(trigger_on==1'b0)) begin // Trigger on RX
//FMT-TYPE
if ((trigger_ast[TRIGGER_BIT_FMTTLP]==1'b1)&&
((trigger_ast[39:32]==tx_ast_data[31:24]))) begin
trigger_fmttype_tx <=1'b1;
end
//TAG
if ((trigger_ast[TRIGGER_BIT_TAG]==1'b1)&&
((tx_ast_data[31:30]==2'b00)&&(trigger_ast[47:40]==tx_ast_data[47:40]))) begin
trigger_tag_tx <=1'b1;
end
end
end
if (tx_ast_nsop==1'b1) begin
tx_h3 <= tx_ast_data[31:0];
tx_h4 <= tx_ast_data[63:32];
tx_ast_nsop <= 1'b0;
tx_mem_tlp_r <= 1'b0;
tx_4dw_tlp_r <= 1'b0;
if ((trigger_ast[TRIGGER_BIT_ENABLE_TRIGGER]==1'b1)&&(trigger_ast[TRIGGER_BIT_RXTX]==1'b0)&&(trigger_on==1'b0)) begin // Trigger on TX
//Address LSB
if ((trigger_ast[5:4]>2'b00)&&(tx_mem_tlp_r==1'b1)) begin //trigger memory TLP
if (tx_4dw_tlp==1'b1) begin
if ((trigger_ast[5:4]==2'b11)&&(tx_ast_data[63:32]==trigger_ast[95:64])) begin
trigger_addr_tx <= 1'b1;
end
else if ((trigger_ast[5:4]==2'b10)&&(tx_ast_data[47:32]==trigger_ast[79:64])) begin
trigger_addr_tx <= 1'b1;
end
else if ((tx_ast_data[39:32]==trigger_ast[71:64])) begin
trigger_addr_tx <= 1'b1;
end
end
else begin
if ((trigger_ast[5:4]==2'b11)&&(tx_ast_data[31:0]==trigger_ast[95:64])) begin
trigger_addr_tx <= 1'b1;
end
else if ((trigger_ast[5:4]==2'b10)&&(tx_ast_data[15:0]==trigger_ast[79:64])) begin
trigger_addr_tx <= 1'b1;
end
else if ((tx_ast_data[7:0]==trigger_ast[72:64])) begin
trigger_addr_tx <= 1'b1;
end
end
end
end
end
end
end
end
end
end
endgenerate
endmodule
# (C) 2001-2018 Intel Corporation. All rights reserved.
# Your use of Intel Corporation's design tools, logic functions and other
# software and tools, and its AMPP partner logic functions, and any output
# files from 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 Intel Program License Subscription
# Agreement, Intel FPGA IP License Agreement, or other applicable
# license agreement, including, without limitation, that your use is for the
# sole purpose of programming logic devices manufactured by Intel and sold by
# Intel or its authorized distributors. Please refer to the applicable
# agreement for further details.
package require cmdline
package require dom::tcl
load_package report
# If no input file specified, pop UI
# After the DOM has been read, work on the replacement
# Set up a replacement dict, check for validity, then run the replacement
# If anything is specified on the command line, use that
# If the replacement dict is not 1:1, post as messages or set up the GUI
# When the user runs convert in the GUI, do the validation
# July 2016
# - Update get_ip_info to work in Standard and Pro
################################################################################
# Clean out <session jtag_chain and jtag_device attributes
# Store register fanout of clock in <instance element
################################################################################
proc main { args } {
set options {
{ "stp_file.arg" "" "STP File name" }
{ "xml_file.arg" "" "XML File name" }
{ "mode.arg" "build" "Build or strip hierarchies" }
}
array set opts [::cmdline::getKnownOptions args $options]
# Verify the values for -mode
switch -exact -- $opts(mode) {
"build" {
set input_file $opts(xml_file)
set output_file $opts(stp_file)
# Take the rest of the inputs as placeholder to replacement instance maps
# If there's not an even number of remaining args, error out
set manual_map [dict create]
if { 0 != ([llength $args] % 2) } {
post_message -type error "Specify <placeholder> <replacement instance>\
space-separated pairs"
return
} elseif { 1 < [llength $args] } {
foreach { p r } $args
dict set manual_map $p $r
}
}
"strip" {
set input_file $opts(stp_file)
set output_file $opts(xml_file)
# The list of things to adjust comes in the rest of the args
set num_args [llength $args]
if { $num_args == 0 } {
post_message -type error "Specify at least one hierarchy to change"
return
}
}
default {
post_message -type error "Specify build or strip for -mode <mode>"
return
}
}
# Read in whatever file we're starting with
post_message "reading $input_file"
if { [catch { read_xml -file $input_file } dom] } {
post_message -type error $dom
return
}
post_message "read xml"
switch -exact -- $opts(mode) {
"build" {
# Get the things that need to be updated in the STP
# Keys are the placeholder strings for replacement, values are the ip core
# names
set placeholder_to_ip_core_name [get_name_replacement_dict -dom $dom]
# Invert the dict so the keys are the ip core names and the values
# are a list of the placeholder(s) for that core instance.
set ip_core_name_to_placeholders [dict create]
dict for { placeholder ip_core_name } $placeholder_to_ip_core_name {
dict lappend ip_core_name_to_placeholders $ip_core_name $placeholder
}
# Match up the ip core names with what is in the design
set ip_core_name_to_instances [dict create]
foreach ip_core_name [dict keys $ip_core_name_to_placeholders] {
set instances_of_ip_core [get_ip_info -instances_from_name $ip_core_name]
dict set ip_core_name_to_instances $ip_core_name $instances_of_ip_core
}
# Validate that there are instances in this design for all the cores
# in the STP
set missing_cores [list]
dict for { ip_core_name instances } $ip_core_name_to_instances {
if {0 == [llength $instances] } {
lappend missing_cores $ip_core_name
}
}
# In the first version of the script, there can be some cores that
# misreport their ip core names and instance paths. Override this check
if { 0 } {
if { 0 < [llength $missing_cores] } {
post_message -type error "The SignalTap II file could not be generated\
because some IP cores in it were not found in your design" \
-submsgs $missing_cores
return
}
}
# The number of values per key in ip_core_name_to_instances must be
# greater than or equal to the number of values per same key in
# ip_core_name_to_placeholder
# If that is not true, the target design has fewer instances of a core
# than were put into the original STP file
# This is never an issue with the first batch of STP/XML files, by
# inspection
if { 0 } {
set bad_cores [list]
dict for { ip_core_name instances } $ip_core_name_to_instances {
set placeholders [dict get $ip_core_name_to_placeholders $ip_core_name]
if { [llength $placeholders] > [llength $instances] } {
lappend bad_cores $ip_core_name
}
}
if { 0 < [llength $bad_cores] } {
post_message -type error "The SignalTap II file could not be generated\
because it includes more instances of some IP cores than are in your\
design" -submsgs $bad_cores
return
}
}
# If every ip core name maps to one placeholder, and every ip core name
# maps to one instance, we can create the stp automatically, replacing
# each placeholder with the corresponding instance.
# Otherwise we need user intervention.
set show_gui 0
set mapping_widget_options [list]
# actual_replacements is the 1:1 mapping of placeholders to instance
# strings. Populate it from the command line manual map, then automatically
# if possible, then pop the GUI and fill remaining entries
set actual_replacements [dict create]
# Say where we got the various maps for reporting purposes
set reporting_info [list]
dict for { placeholder ip_core_name } $placeholder_to_ip_core_name {
# If we specified something on the command line for manual_map, always
# use that
if { [dict exists $manual_map $placeholder] } {
dict set actual_replacements $placeholder [dict get $manual_map $placeholder]
lappend reporting_info $ip_core_name $placeholder \
[dict get $manual_map $placeholder] "command-line entry"
continue
}
# This placeholder was not specified on the command line. Try to match
# automatically
set new_ip_core_instances [dict get $ip_core_name_to_instances $ip_core_name]
set num_instances [llength $new_ip_core_instances]
if { 1 == $num_instances } {
# This is the expected situation; nothing special to do
dict set actual_replacements $placeholder [lindex $new_ip_core_instances 0]
lappend reporting_info $ip_core_name $placeholder \
[lindex $new_ip_core_instances 0] "single instance in design"
} else {
# 0, 2 or more
set show_gui 1
lappend mapping_widget_options [list -ip_core_name $ip_core_name \
-candidate_instances $new_ip_core_instances \
-hier_replacement $placeholder]
}
}
# End of dict for - we've walked through all the things to replace
# Maybe pop the GUI if necessary
if { $show_gui } {
ui::assemble_picker_only
ui::init_data
foreach temp $mapping_widget_options {
ui::add_core_mapping_widget {*}$temp
}
set done 0
while { ! $done } {
# Draw the dialog, get the index of the button the user pushed
set dialog_response [ui::display]
# User pressed cancel
if { 1 == $dialog_response } { return }
# Validate user selections. Assume we'll be valid
set is_valid 1
catch { array unset user_ip_map }
# These are the selections from the dialog
array set user_ip_map [ui::get_user_ip_map]
# Go through each placeholder and corresponding replacement string
# Keep track of which ones are not valid, to tell the user
set invalid_entries [list]
foreach user_replace_placeholder [array names user_ip_map] {
# First do a sanity check that the user made a selection/entry
set user_replace_instance $user_ip_map($user_replace_placeholder)
if { 0 == [string length $user_replace_instance] } {
set is_valid 0
continue
}
# Yup, user selected/entered something.
set name_col [get_names -filter $user_ip_map($user_replace_placeholder) -node_type hierarchy]
if { 1 != [get_collection_size $name_col] } {
# Didn't match only one thing. Redo.
set is_valid 0
lappend invalid_entries $user_ip_map($user_replace_placeholder)
} else {
foreach_in_collection name_id $name_col {
set user_ip_map($user_replace_placeholder) [get_name_info -info full_path $name_id]
}
}
}
if { ! $is_valid } {
tk_messageBox -type ok -title "Instance not found" -message \
[join [linsert $invalid_entries 0 "The following instance(s) could not be found in the design:"] "\n"]
}
set done $is_valid
}
# Now go through the validated user_ip_map and put into actual_replacements,
# and the report structure
foreach { placeholder new_ip_core_instance } [array get user_ip_map] {
set ip_core_name [dict get $placeholder_to_ip_core_name $placeholder]
dict set actual_replacements $placeholder $new_ip_core_instance
lappend reporting_info $ip_core_name $placeholder \
$new_ip_core_instance "specified in GUI"
}
}
set signal_sets [dict create]
dict for { placeholder new_ip_core_instance } $actual_replacements {
# What are we replacing with?
set foo [list]
set num_replaced [adjust_hier -dom $dom -remove $placeholder \
-insert $new_ip_core_instance -unreplaced_var foo]
set num_clocks_replaced [adjust_hier_for_clock -dom $dom -remove $placeholder \
-insert $new_ip_core_instance -unreplaced_var foo \
-signal_set_var signal_sets]
remove_hier_replacement_entry -dom $dom -placeholder $placeholder
if { 0 < [llength $foo] } {
post_message -type warning "Some node names in the SignalTap II file\
do not exist in this design." -submsgs $foo
}
if { 0 < [dict size $signal_sets] } {
post_message -type warning "You must set the acquisition clock in the\
following signal sets" -submsgs [dict keys $signal_sets]
}
}
# Write the file
if { [catch { write_xml -file $output_file -dom $dom } res] } {
post_message -type error $res
return
}
}
"strip" {
foreach instance $args {
set ip_core_name [get_ip_info -name_from_instance $instance]
if { 1 != [llength $ip_core_name] } {
post_message -type warning "Could not find instance $instance in\
the list of IP cores in this project"
continue
}
# Save the tap point driven by the acquisition clock
if { 0 } {
if { [catch { store_clock_dest_tap_points -dom $dom } res] } {
foreach msg $res {
post_message -type error $msg
}
return
}
}
set placeholder [clock clicks]
set unreplaced [list]
set signal_sets [dict create]
set num_replaced [adjust_hier -dom $dom -remove $instance \
-insert $placeholder -unreplaced_var unreplaced]
set num_clocks_replaced [adjust_hier_for_clock -dom $dom \
-remove $instance -insert $placeholder \
-unreplaced_var unreplaced -signal_set_var signal_sets]
if { 0 < $num_replaced } {
mark_stp_with_hierarchy_replacement \
-dom $dom -placeholder $placeholder \
-ip_name [lindex $ip_core_name 0]
} else {
post_message -type warning "No nodes found in instance ${instance}\
in file ${input_file}"
}
if { 0 < [llength $unreplaced] } {
post_message -type warning "Some node names in the SignalTap II file\
did not match the IP core you specified." -submsgs $unreplaced
}
}
# Done walking the instances to strip
# Write the file
if { [catch { write_xml -file $output_file -dom $dom } res] } {
post_message -type error $res
return
}
# End of strip
}
}
# End of switch $opts(mode)
post_message "Finished processing file"
}
################################################################################
# Call read_xml whenever user chooses an input file
# If it comes back with an error, the dom has to be invalidated
# Pop return errors as dialog box in GUI mode or post_messages in script mode
proc read_xml { args } {
set options {
{ "file.arg" "" "XML File name" }
}
array set opts [::cmdline::getoptions args $options]
if { [string equal "" $opts(file)] } {
return -code error "A file name is required"
}
if { ! [file exists $opts(file)] } {
return -code error "File not found: ${opts(file)}"
}
if { [catch { open $opts(file)} fh] } {
return -code error "Error opening file: ${fh}"
}
if { [catch {read $fh} xml_content] } {
catch { close $fh }
return -code error "Error reading file: ${xml_content}"
}
catch { close $fh }
if { [catch {::dom::parse $xml_content} xml_dom] } {
return -code error "Error parsing ${opts(file)}: ${xml_dom}"
}
return $xml_dom
}
##############################################################################
# Write the in-memory tasks list object to the specified file.
# The name must be staw_tasks.xml to be recognized by TimeQuest
proc write_xml { args } {
set options {
{ "file.arg" "" "File name of the tasks list" }
{ "dom.arg" "" "The DOM to serialize" }
}
array set opts [::cmdline::getoptions args $options]
if { [string equal "" $opts(file)] } {
return -code error "A file name is required for write_xml -file"
}
if { [catch { open $opts(file) w} fh] } {
return -code error "Error opening file for writing: ${fh}"
}
if { [catch { puts $fh [clean_xml -dom $opts(dom)] } res] } {
return -code error "Error writing XML: ${res}"
}
catch { close $fh }
return -code ok
}
##############################################################################
# Returns a string with the serialized DOM.
proc clean_xml { args } {
set options {
{ "dom.arg" "" "The DOM to serialize" }
}
array set opts [::cmdline::getoptions args $options]
if { [catch { dom::serialize $opts(dom) -indent 1 } res] } {
return -code error "Error serializing DOM: ${res}"
}
# Not sure why the DOCTYPE causes problems here.
regsub {^.*<!DOCTYPE session>\s*} $res {} res
return $res
}
################################################################################
# Process the STP to generate the XML file
proc process_stp_to_xml { args } {
set options {
{ "dom.arg" "" "DOM" }
}
array set opts [::cmdline::getoptions args $options]
# Save the clock connectivity
set hier_replacement [generate_and_mark_stp_with_hierarchy_replacement \
-dom $opts(dom)]
adjust_hier -dom $opts(dom) -remove $ip_core_hier -insert $hier_replacement
}
################################################################################
proc process_xml_to_stp { args } {
set options {
{ "dom.arg" "" "DOM" }
}
array set opts [::cmdline::getoptions args $options]
set hier_replacement [get_and_remove_hierarchy_replacement -dom $opts(dom)]
adjust_hier -dom $opts(dom) -remove $hier_replacement -insert $ip_core_hier
# Set the clock name
}
################################################################################
# wire, node, net, clock
# post_message "Checking that all names in SignalTap II file exist in design"
# set missing_names [check_names -dom $dom]
# if { 0 < [llength $missing_names] } {
# post_message -type error "The SignalTap II file has names that don't exist\
# in this design" -submsgs $missing_names
# return
# }
proc check_names { args } {
set options {
{ "dom.arg" "" "DOM" }
}
array set opts [::cmdline::getoptions args $options]
set missing [dict create]
foreach type [list "wire" "node" "net" "clock"] {
set dom_nodes_of_type [dom::selectNode $opts(dom) "//${type}"]
foreach dom_node_of_type $dom_nodes_of_type {
set name [dom::element getAttribute $dom_node_of_type "name"]
if { ! [string equal "" $name] } {
if { 0 == [get_collection_size [get_nodes -nowarn $name]] } {
dict set missing $name 1
}
}
}
}
return [dict keys $missing]
}
################################################################################
# Returns the name of an IP given an instance path, or the instances given
# a name
proc get_ip_info { args } {
set options {
{ "name_from_instance.arg" "" "Instantiation path of the IP core" }
{ "instances_from_name.arg" "" "Name of the IP core" }
}
array set opts [::cmdline::getoptions args $options]
load_report
# Walk through the report, checking whether the IP core name asked for
# matches each row
set to_return [list]
# Make sure the report exists
# Walk through all the panels because there can be multiple IP Cores panels
# with one per partition
foreach report_panel_name [get_report_panel_names] {
# Match both Analysis & Synthesis||Analysis & Synthesis IP Cores Summary
# in Quartus Prime Standard, and *||Spectra-Q Synthesis IP Cores Summary
# in Quartus Prime Pro
if { ! [regexp {Synthesis IP Cores Summary$} $report_panel_name] } { continue }
set id [get_report_panel_id $report_panel_name]
if { -1 == $id } {
# This would be highly unusual.
post_message -type error "Can not find report panel ${report_panel_name}"
continue
}
# Make sure the columns exist
set ip_core_col [get_report_panel_column_index -id $id "IP Core Name"]
set entity_instance_col [get_report_panel_column_index -id $id "Entity Instance"]
if { -1 == $ip_core_col } {
post_message -type error "Can not find IP Core Name column"
}
if { -1 == $entity_instance_col } {
post_message -type error "Can not find Entity Instance column"
}
if { -1 == $ip_core_col || -1 == $entity_instance_col } { return -code error }
# prev_match must start with a space - something that will not match.
# The zero-length string will match in the regexp below
set prev_match " "
set num_rows [get_number_of_rows -id $id]
for { set row 1 } { $row < $num_rows } { incr row } {
set data [get_report_panel_row -id $id -row $row]
set ip_core_name [lindex $data $ip_core_col]
set entity_instance [lindex $data $entity_instance_col]
# Take off the top-level entity name
# This will not match in Pro, which does not have a leading |
regsub {^\|.*?\|} $entity_instance {} entity_instance
if { ! [string equal "" $opts(name_from_instance)] } {
# We're asking for the IP name given the instance
if { [string equal $entity_instance $opts(name_from_instance)] } {
lappend to_return $ip_core_name
# Only one instance will ever match
break
}
} elseif { ! [string equal "" $opts(instances_from_name)] } {
# We're asking for the instances given the IP name
if { [string equal $ip_core_name $opts(instances_from_name)] } {
# Sub-cores of an IP can have the same IP core name.
if { [regexp $prev_match $entity_instance] } {
# This entity instance is a sub-core of our core.
# Don't save it for return, and don't update prev_match
} else {
# This entity instance does not match the previous,
# so it's a new core; save it, and update prev_match to avoid
# sub-cores of _this_ core
lappend to_return $entity_instance
set prev_match [string map { \[ \\\[ \] \\\] \| \\\| \\ \\\\ } \
$entity_instance]
}
# Don't break - there may be multiple instances of a core
}
}
}
}
unload_report
return $to_return
}
################################################################################
# Remove the specified hierarchy from design names in the DOM or
# put in a new hierarchy
# Have one proc for inserting and removing, so two procs can't get out of
# sync. Everywhere we remove, we will have to insert.
proc adjust_hier { args } {
set options {
{ "dom.arg" "" "DOM" }
{ "remove.arg" "" "What to remove" }
{ "insert.arg" "" "What to insert" }
{ "unreplaced_var.arg" "" "Var name for unreplaced list" }
}
array set opts [::cmdline::getoptions args $options]
set num_replaced 0
upvar $opts(unreplaced_var) unreplaced
# Escape the hierarchy name
regsub -all {\|} $opts(remove) "\\\|" pattern
regsub -all {\[} $pattern "\\\]" pattern
regsub -all {\]} $pattern "\\\[" pattern
# wire name, bus name
set wire_nodes [dom::selectNode $opts(dom) "//wire"]
foreach wire_node $wire_nodes {
set wire_name [dom::element getAttribute $wire_node "name"]
if { 1 == [regsub ^$pattern $wire_name $opts(insert) without_hier] } {
set without_hier [string map [list \{ "" \} ""] $without_hier]
dom::element setAttribute $wire_node "name" $without_hier
incr num_replaced
} elseif { ! [regexp {^\d+\|} $wire_name] } {
lappend unreplaced $wire_name
}
}
set bus_nodes [dom::selectNode $opts(dom) "//bus"]
foreach bus_node $bus_nodes {
set bus_name [dom::element getAttribute $bus_node "name"]
if { 1 == [regsub ^$pattern $bus_name $opts(insert) without_hier] } {
set without_hier [string map [list \{ "" \} ""] $without_hier]
dom::element setAttribute $bus_node "name" $without_hier
incr num_replaced
} elseif { ! [regexp {^\d+\|} $bus_name] } {
lappend unreplaced $bus_name
}
}
set node_nodes [dom::selectNode $opts(dom) "//node"]
foreach node_node $node_nodes {
set node_name [dom::element getAttribute $node_node "name"]
if { 1 == [regsub ^$pattern $node_name $opts(insert) without_hier] } {
set without_hier [string map [list \{ "" \} ""] $without_hier]
dom::element setAttribute $node_node "name" $without_hier
incr num_replaced
} elseif { ! [regexp {^\d+\|} $node_name] } {
lappend unreplaced $node_name
}
}
set net_nodes [dom::selectNode $opts(dom) "//net"]
foreach net_node $net_nodes {
set net_name [dom::element getAttribute $net_node "name"]
if { 1 == [regsub ^$pattern $net_name $opts(insert) without_hier] } {
set without_hier [string map [list \{ "" \} ""] $without_hier]
dom::element setAttribute $net_node "name" $without_hier
incr num_replaced
} elseif { ! [regexp {^\d+\|} $net_name] } {
lappend unreplaced $net_name
}
}
set level_nodes [dom::selectNode $opts(dom) "//level"]
foreach level_node $level_nodes {
set trigger_expr [dom::node cget $level_node -nodeValue]
set num_regsub [regsub -all $pattern $trigger_expr $opts(insert) \
trigger_expr]
incr num_replaced $num_regsub
set trigger_expr [string map [list \{ "" \} ""] $trigger_expr]
dom::node configure $level_node -nodeValue $trigger_expr
}
return $num_replaced
}
################################################################################
# Set the sof name
proc set_sof { args } {
set options {
{ "dom.arg" "" "DOM" }
{ "sof_name.arg" "" "Override the default SOF name" }
}
array set opts [::cmdline::getoptions args $options]
# Get the revision name of the sof through quartus(revision)
global quartus
# Allow a forcible specification of the SOF, or look for it in the output
# files directory
if { ! [string equal "" $opts(sof_name)] } {
set sof_name $opts(sof_name)
} else {
# The SOF will be in the output files directory if it is specified
set sof_path [list]
set output_dir [get_global_assignment -name OUTPUT_FILES_DIRECTORY]
if { ! [string equal "" $output_dir] } { lappend sof_path $output_dir }
lappend sof_path ${quartus(revision)}.sof
set sof_name [file join {*}$sof_path]
}
# Warn if it wasn't found, but continue anyway
if { ! [file exists $sof_name] } {
post_message "Could not find SOF ${sof_name}; generating STP file\
anyway."
}
set root [dom::selectNode $opts(dom) "session"]
dom::element setAttribute $root "sof_file" $sof_name
}
################################################################################
# Generate a string that will be an invalid Verilog/VHDL identifier
# that will be a placeholder for swapping in the new design names
# Returns the placeholder for
proc mark_stp_with_hierarchy_replacement { args } {
set options {
{ "dom.arg" "" "DOM" }
{ "placeholder.arg" "" "Place holder for hierarchy replacement" }
{ "ip_name.arg" "" "Name of the IP core" }
}
array set opts [::cmdline::getoptions args $options]
set root [dom::selectNode $opts(dom) "session"]
set new_replacement_el [dom::document createElement $root \
"hier_replacement"]
dom::document createTextNode $new_replacement_el $opts(ip_name)
dom::element setAttribute $new_replacement_el "placeholder" $opts(placeholder)
}
################################################################################
proc get_name_replacement_dict { args } {
set options {
{ "dom.arg" "" "DOM" }
}
array set opts [::cmdline::getoptions args $options]
set to_return [dict create]
set root [dom::selectNode $opts(dom) "session"]
set name_replacements [dom::selectNode $root "//hier_replacement"]
foreach name_replacement $name_replacements {
set ip_core_name [dom::node cget [dom::node cget $name_replacement -firstChild] \
-nodeValue]
set placeholder [dom::element getAttribute $name_replacement "placeholder"]
dict set to_return $placeholder $ip_core_name
}
return $to_return
}
################################################################################
# Removes an element from the session tag
# Do this before serializing the STP file
# Returns nothing
proc remove_hier_replacement_entry { args } {
set options {
{ "dom.arg" "" "DOM" }
{ "placeholder.arg" "" "Placeholder for entry to remove" }
}
array set opts [::cmdline::getoptions args $options]
set root [dom::selectNode $opts(dom) "session"]
set hier_replacements [dom::selectNode $root "//hier_replacement"]
foreach hier_replacement $hier_replacements {
set placeholder [dom::element getAttribute $hier_replacement "placeholder"]
if { [string equal $placeholder $opts(placeholder)] } {
dom::node removeChild $root $hier_replacement
}
}
}
################################################################################
# clock has special behavior to replace
proc adjust_hier_for_clock { args } {
set options {
{ "dom.arg" "" "DOM" }
{ "remove.arg" "" "What to remove" }
{ "insert.arg" "" "What to insert" }
{ "unreplaced_var.arg" "" "Var name for unreplaced list" }
{ "signal_set_var.arg" "" "Var name for signal sets" }
}
array set opts [::cmdline::getoptions args $options]
set num_replaced 0
upvar $opts(unreplaced_var) unreplaced
upvar $opts(signal_set_var) signal_sets
# Process each signal set separately
set signal_set_dom_nodes [dom::selectNode $opts(dom) "session/instance/signal_set"]
foreach signal_set_dom_node $signal_set_dom_nodes {
set signal_set_name [dom::element getAttribute $signal_set_dom_node "name"]
# Get the name of the acquisition clock for this signal set
set clock_dom_node [dom::selectNode $signal_set_dom_node "clock"]
set clock_name [dom::element getAttribute $clock_dom_node "name"]
# If the name is blank, do nothing to it
# If the remove matches, do the replacement
# Escape the hierarchy name
regsub -all {\|} $opts(remove) "\\\|" pattern
regsub -all {\[} $pattern "\\\]" pattern
regsub -all {\]} $pattern "\\\[" pattern
if { 1 == [regsub ^$pattern $clock_name $opts(insert) without_hier] } {
set without_hier [string map [list \{ "" \} ""] $without_hier]
dom::element setAttribute $clock_dom_node "name" $without_hier
incr num_replaced
} elseif { [regexp {^\d+\|} $clock_name] } {
# The clock name was already replaced with the numeric string
} else {
# The clock name did not match and was not a numeric string
# Blank it
dom::element setAttribute $clock_dom_node "name" ""
lappend unreplaced $clock_name
# On the build, keep track of signal sets that will need user attention
dict set signal_sets $signal_set_name 1
}
}
return $num_replaced
}
################################################################################
# In each clock element, save the data_index of a tap point it fans out to,
# so the appropriate connection can be made later
# Returns an error if a clock can't be traced to any tap points
# Returns nothing if successful, but modifies the DOM
proc store_clock_dest_tap_points { args } {
set options {
{ "dom.arg" "" "DOM" }
}
array set opts [::cmdline::getoptions args $options]
set problems [list]
set to_do [list]
# Process each signal set separately
set signal_set_dom_nodes [dom::selectNode $opts(dom) "session/instance/signal_set"]
foreach signal_set_dom_node $signal_set_dom_nodes {
set signal_set_name [dom::element getAttribute $signal_set_dom_node "name"]
post_message $signal_set_name
# Get the name of the acquisition clock for this signal set
set clock_dom_node [dom::selectNode $signal_set_dom_node "clock"]
set clock_name [dom::element getAttribute $clock_dom_node "name"]
# Do preliminary checking of the acquisition clock existence
set clock_node_collection [get_nodes -nowarn $clock_name]
if { 0 == [get_collection_size $clock_node_collection] } {
lappend problems "No acquisition clock source named ${clock_name} found\
in this design, but it is used in signal set ${signal_set_name}"
continue
}
post_message $clock_name
# Get all the node nodes, which are in data and setup views
set node_dom_nodes [dom::selectNode $signal_set_dom_node "//node"]
# Verify one of these tap points is driven by the clock
set has_connection 0
foreach node_dom_node $node_dom_nodes {
set data_index [dom::element getAttribute $node_dom_node "data_index"]
set tap_point_name [dom::element getAttribute $node_dom_node "name"]
post_message "checking data index $data_index tap point $tap_point_name"
if { [string equal "" $data_index] || [string equal "" $tap_point_name] } {
# Make sure the XML node has a name and a data index
# post_message [dom::node stringValue $node_dom_node]
continue
}
# Make sure the tap point node exists in the design
# set tap_point_name [dom::element getAttribute $wire_node "name"]
set path_col [get_path -from $clock_node_collection -through [get_pins -hier *|clk] \
-to $tap_point_name]
if { 1 == [get_collection_size $path_col] } {
# Good - we have a path from the clock to the register
set has_connection 1
break
}
}
post_message "has connection $has_connection"
if { ! $has_connection } {
# No paths found? Highly unlikely. Regardless, it's catastrophic.
lappend problems "Could not verify connections from acquisition clock\
${clock_name} in signal set ${signal_set_name}"
continue
}
lappend to_do $clock_dom_node $data_index
}
# Report on all problems at the end
if { 0 < [llength $problems] } {
return -code error $problems
}
# No problems? Update the XML all at once
foreach { clock_dom_node data_index } $to_do {
dom::element setAttribute $clock_dom_node "drives_tap_point_with_data_index" \
$data_index
}
return -code ok
}
################################################################################
# Put in appropriate names for the clock elements
# There are all kinds of ways this could require manual updates after the fact.
# When this runs, always remove the data_index pointer in the clock element
# so it's valid STP. Update the clock name if the tap point exists in the
# target design, if it has only one clock path to it
# I think there is more benefit to leaving a clock name in and unreplaced,
# than there is risk. At worst, the compilation will fail or the name will
# possibly collide with another clock in the design (unlikely). At best, the
# user can extract some useful information from the old name about what to
# connect to now
proc update_clock_names { args } {
set options {
{ "dom.arg" "" "DOM" }
}
array set opts [::cmdline::getoptions args $options]
set problems [list]
set to_do [list]
# Process each signal set separately
set signal_set_dom_nodes [dom::selectNode $opts(dom) "//signal_set"]
foreach signal_set_dom_node $signal_set_dom_nodes {
set signal_set_name [dom::element getAttribute $signal_set_dom_node "name"]
# Get the data_index driven by the acquisition clock for this signal set
set clock_dom_node [dom::selectNode $signal_set_dom_node "./clock"]
lappend to_do $clock_dom_node
set desired_data_index [dom::element getAttribute $clock_dom_node "drives_tap_point_with_data_index"]
# Get all the node nodes, which are in data and setup views
set node_dom_nodes [dom::selectNode $signal_set_dom_node ".//node"]
# Find the node with the specified data_index
set found_node 0
foreach node_dom_node $node_dom_nodes {
set data_index [dom::element getAttribute $node_dom_node "data_index"]
set tap_point_name [dom::element getAttribute $node_dom_node "name"]
if { [string equal $desired_data_index $data_index] || ![string equal "" $tap_point_name] } {
# We found the node
set found_node 1
break
}
}
if { ! $found_node } {
# Can't find the node? Highly unlikely. Regardless, it's catastrophic.
lappend problems "Internal error finding a node with data_index ${desired_data_index}"
# No clock name replacement to do
lappend to_do ""
continue
}
# Does the tap point exist in the new design?
if { 0 == [get_collection_size -nowarn [get_names $tap_point_name]] } {
lappend problems "You must choose an acquisition clock for signal set\
${signal_set_name}. The tap point used to automatically choose the\
acquisition clock was not found: ${tap_point_name}"
# No clock name replacement to do
lappend to_do ""
continue
}
# We did find the tap point. Make sure it's driven by one clock
set path_col [get_paths -through [get_pins -hier *|clk] -to $tap_point_name -npaths 1000]
set num_paths [get_collection_size $path_col]
if { 0 == $num_paths } {
# Catastrophic.
lappend problems "You must choose an acquisition clock for signal set\
${signal_set_name}. No clock was found driving the tap point used to\
automatically choose the clock: ${tap_point_name}"
# No clock name replacement to do
lappend to_do ""
continue
} elseif { 1 > $num_paths } {
# There was more than one path to the clock
# Could happen with clock switchover
lappend problems "You must choose an acquisition clock for signal set\
${signal_set_name}. Multiple clocks were found."
# No clock name replacement to do
lappend to_do ""
continue
}
foreach_in_collection path_id $path_col {
set from [get_path_info -from $path_id]
set from_name [get_node_info -name $from]
lappend to_do $from_name
}
}
# We always want to remove the data_index pointer so the STP file is valid
foreach { clock_dom_node clock_node_name } $to_do {
dom::element removeAttribute $clock_dom_node "drives_tap_point_with_data_index"
if { ! [string equal "" $clock_node_name] } {
dom::element setAttribute $clock_dom_node $name $clock_node_name
}
}
if { 0 < [llength $problems] } {
return -code error $problems
}
return -code ok
}
################################################################################
# Returns a list of clock signals driving a collection of registers
proc get_clock_signals_driving_registers { args } {
}
################################################################################
# Helper proc to return a dict mapping clock targets to clock names
proc get_clock_target_mapping { args } {
set target_map [dict create]
foreach_in_collection clock_id [get_clocks] {
set clock_name [get_clock_info -name $clock_id]
set target_col [get_clock_info -targets $clock_id]
foreach_in_collection target_id $target_col {
set target_name [get_node_info -name $target_id]
dict lappend target_map $target_name $clock_name
}
}
return $target_map
}
namespace eval ui {
variable dom
variable stp_dialog
variable core_list_display_num
variable stp_dialog_vars
variable core_frame
variable user_ip_map
variable stp_dialog_vars
namespace export init_data add_core_mapping_widget assemble display \
get_user_ip_map
################################################################################
proc init_data { args } {
set options {
{ "dialog_vars.arg" "" "List of any dialog vars to init" }
{ "ip_map.arg" "" "List of any IP mappings to init" }
}
array set opts [::cmdline::getoptions args $options]
# Initialize the var that is used to uniquify each item in the core
# list scrolled window. It's also used in the GUI label
# Things that use it are responsible for incr'ing it
variable core_list_display_num
set core_list_display_num 1
# Clear all child widgets out of the core_frame
variable core_frame
foreach w [winfo children $core_frame] {
destroy $w
}
# Clear out all textvariables for the dialog
variable stp_dialog_vars
array unset stp_dialog_vars
array set stp_dialog_vars [list \
"input_file" "" \
"output_file" ""]
# Clear out all IP core mappings
variable user_ip_map
array unset user_ip_map
# Initialize with anything that came in
array set stp_dialog_vars $opts(dialog_vars)
array set user_ip_map $opts(ip_map)
}
################################################################################
#
proc get_user_ip_map { args } {
variable user_ip_map
return [array get user_ip_map]
}
################################################################################
# Add an item to the core_frame
proc add_core_mapping_widget { args } {
set options {
{ "ip_core_name.arg" "" "IP core name" }
{ "hier_replacement.arg" "" "String for hierarchy replacement" }
{ "tap_points.arg" "" "List of tap points to show" }
{ "candidate_instances.arg" "" "List of instances of IP core in user design" }
}
array set opts [::cmdline::getoptions args $options]
variable core_list_display_num
variable core_frame
variable user_ip_map
set tf [TitleFrame ${core_frame}.tf${core_list_display_num} -text "IP Core ${core_list_display_num}"]
set f [$tf getframe]
set cnl [label ${f}.cnl${core_list_display_num} -text "IP core name:"]
set cne [Entry ${f}.cne${core_list_display_num} -text $opts(ip_core_name)]
set cnil [label ${f}.cnil${core_list_display_num} -text "IP core instance:"]
set cncb [ComboBox ${f}.cncb${core_list_display_num} -values $opts(candidate_instances) \
-textvariable [namespace which -variable user_ip_map](${opts(hier_replacement)})]
# bind ${cncb}.e <1> [namespace code [list paste_in %W]]
#{ paste_in %W }
# Grid the component widgets
grid $cnl $cne
grid $cnl -sticky w
grid $cne -sticky we
grid $cnil $cncb
grid $cnil -sticky w
grid $cncb -sticky we
grid columnconfigure $f 1 -weight 1
# Pack the frame into the scrolled window
pack $tf -side top -fill x -expand true
incr core_list_display_num
}
##############################################################################
proc paste_in { entry_widget } {
$entry_widget delete 0 end
post_message "Widget contents is [$entry_widget cget -text]"
if { [catch { selection get -selection PRIMARY } cc] } {
if { [catch { selection get -selection CLIPBOARD } cc] } {
return
}
}
post_message "clipboard contents is $cc"
$entry_widget configure -text $cc
post_message "widget contents is [$entry_widget cget -text]"
}
################################################################################
# TODO - enable paste
# bind $efil <Control-v> { paste_in %W }
# $cbcol setvalue first
proc assemble { args } {
variable stp_dialog
variable stp_dialog_vars
variable core_frame
variable core_list_display_num
variable stp_dialog_vars
package require BWidget
init_tk
set stp_dialog [Dialog .stp_dialog -modal local -side bottom -anchor e \
-title "Generate SignalTap II File" -cancel 1 -transient yes -parent .]
$stp_dialog add -name close -width 10
set f [$stp_dialog getframe]
# The XML input file widget
set ifl [label $f.ifl -text "XML Template File:"]
set ife [Entry $f.ife -textvariable [namespace which -variable stp_dialog_vars](input_file)]
set ifb [Button $f.ifb -text "..." -command [namespace code pop_open]]
grid $ifl $ife $ifb
grid $ife -sticky ew
# The IP core mapping
set iptf [TitleFrame $f.iptf -text "IP Core Mapping"]
grid $iptf - - -sticky ewns
set ipf [$iptf getframe]
pack $ipf -fill both -expand true
set ipfl [label $ipf.l -text "The SignalTap II instance you generate\
will tap signals in the following IP cores.\
\nChoose the appropriate instance for each IP core name."]
pack $ipfl -side top -anchor nw
set ipsw [ScrolledWindow $ipf.sw]
pack $ipsw -side top -fill both -expand true
set core_sf [ScrollableFrame $ipsw.f -constrainedwidth true]
$ipsw setwidget $core_sf
set core_frame [$core_sf getframe]
# $core_frame config -bg yellow
# The STP output file widget
set ofl [label $f.ofl -text "SignalTap II File:"]
set ofe [Entry $f.ofe -textvariable [namespace which -variable stp_dialog_vars](output_file)]
set ofb [Button $f.ofb -text "..." -command [namespace code pop_save]]
grid $ofl $ofe $ofb
grid $ofe -sticky ew
grid [frame $f.bottom] - -
# pack [frame $f.bottom] -side top -fill both -expand true
grid columnconfigure $f 1 -weight 1
grid rowconfigure $f 1 -weight 1
wm protocol .stp_dialog WM_DELETE_WINDOW [list $stp_dialog enddialog 0]
}
##############################################################################
proc assemble_picker_only { args } {
variable stp_dialog
variable core_frame
variable core_list_display_num
package require BWidget
init_tk
catch { destroy .stp_dialog }
set stp_dialog [Dialog .stp_dialog -modal local -side bottom -anchor e \
-title "Choose IP Core Instances for SignalTap II File" -default 0 \
-cancel 1 -transient yes -parent .]
$stp_dialog add -text OK -width 10
$stp_dialog add -text Cancel -width 10
set f [$stp_dialog getframe]
# The IP core mapping
set iptf [TitleFrame $f.iptf -text "IP Core Mapping"]
grid $iptf - - -sticky ewns
set ipf [$iptf getframe]
pack $ipf -fill both -expand true
set ipfl [label $ipf.l -text "The SignalTap II instance you generate\
will tap signals in the following IP cores.\
\nChoose the appropriate instance for each IP core name."]
pack $ipfl -side top -anchor nw
set ipsw [ScrolledWindow $ipf.sw]
pack $ipsw -side top -fill both -expand true
set core_sf [ScrollableFrame $ipsw.f -constrainedwidth true]
$ipsw setwidget $core_sf
set core_frame [$core_sf getframe]
# $core_frame config -bg yellow
grid [frame $f.bottom] - -
# pack [frame $f.bottom] -side top -fill both -expand true
grid columnconfigure $f 1 -weight 1
grid rowconfigure $f 1 -weight 1
wm protocol .stp_dialog WM_DELETE_WINDOW [list $stp_dialog enddialog 1]
}
################################################################################
proc display { args } {
return [.stp_dialog draw]
}
################################################################################
proc pop_open { args } {
variable stp_dialog_vars
set result [tk_getOpenFile -filetypes {{"XML Files" {".xml" ".XML"}}} \
-initialfile $stp_dialog_vars(input_file) -parent .stp_dialog]
if { ! [string equal "" $result] } {
set stp_dialog_vars(input_file) $result
# Read the XML file and update the success/error status
if { [catch { read_xml } res] } {
# Pop an error dialog or post a message
# Can't continue after this
}
}
}
################################################################################
proc pop_save { args } {
variable stp_dialog_vars
set result [tk_getSaveFile -filetypes {{"SignalTap II Files" {".stp" ".STP"}}} \
-initialfile $stp_dialog_vars(output_file) -parent .stp_dialog]
if { ! [string equal "" $result] } {
set stp_dialog_vars(output_file) $result
}
}
################################################################################
# Call read_xml whenever user chooses an input file
# If it comes back with an error, the dom has to be invalidated
# Pop return errors as dialog box in GUI mode or post_messages in script mode
proc read_xml { args } {
variable stp_dialog_vars
variable dom
if { [string equal "" $stp_dialog_vars(input_file)] } {
return -code error "A file name is required"
}
if { ! [file exists $stp_dialog_vars(input_file)] } {
return -code error "File not found: ${stp_dialog_vars(input_file)}"
}
if { [catch { open $stp_dialog_vars(input_file)} fh] } {
return -code error "Error opening file: ${fh}"
}
if { [catch {read $fh} xml_content] } {
catch { close $fh }
return -code error "Error reading file: ${xml_content}"
}
catch { close $fh }
if { [catch {::dom::parse $xml_content} xml_dom] } {
return -code error "Error parsing ${stp_dialog_vars(input_file)}: ${xml_dom}"
}
set dom $xml_dom
}
##############################################################################
proc build_map { args } {
variable dom
# Get the things that need to be updated in the STP
# Keys are the placeholder strings for replacement, values are the ip core
# names
set placeholder_to_ip_core_name [get_name_replacement_dict -dom $dom]
# Invert the dict so the keys are the ip core names and the values
# are a list of the placeholder(s) for that core instance.
set ip_core_name_to_placeholders [dict create]
dict for { placeholder ip_core_name } $placeholder_to_ip_core_name {
dict lappend ip_core_name_to_placeholders $ip_core_name $placeholder
}
# Match up the ip core names with what is in the design
# Key is an ip core name, value is a list of the instances of that core
# in this design
set ip_core_name_to_instances [dict create]
foreach ip_core_name [dict keys $ip_core_name_to_placeholders] {
set instances_of_ip_core [get_ip_info -instances_from_name $ip_core_name]
dict set ip_core_name_to_instances $ip_core_name $instances_of_ip_core
}
# Validate that there are instances in this design for all the cores
# in the STP
# Sometimes, the IP core name is wrong
set missing_cores [list]
dict for { ip_core_name instances } $ip_core_name_to_instances {
if {0 == [llength $instances] } {
lappend missing_cores $ip_core_name
}
}
if { 0 < [llength $missing_cores] } {
post_message -type error "The SignalTap II file could not be generated\
because some IP cores in it were not found in your design" \
-submsgs $missing_cores
return
}
# The number of values per key in ip_core_name_to_instances must be
# greater than or equal to the number of values per same key in
# ip_core_name_to_placeholder
# If that is not true, the target design has fewer instances of a core
# than were put into the original STP file
set bad_cores [list]
dict for { ip_core_name instances } $ip_core_name_to_instances {
set placeholders [dict get $ip_core_name_to_placeholders $ip_core_name]
if { [llength $placeholders] > [llength $instances] } {
lappend bad_cores $ip_core_name
}
}
if { 0 < [llength $bad_cores] } {
post_message -type error "The SignalTap II file could not be generated\
because it includes more instances of some IP cores than are in your\
design" -submsgs $bad_cores
return
}
# If every ip core name maps to one placeholder, and every ip core name
# maps to one instance, we can create the stp automatically, replacing
# each placeholder with the corresponding instance.
# Otherwise we need user intervention.
catch { array unset temp_vars; array unset temp_map }
# array set temp_vars [list "input_file" $opts(input_file) "output_file" \
# $opts(output_file)]
dict for { placeholder ip_core_name } $placeholder_to_ip_core_name {
# What are we replacing with?
set new_ip_core_instance [dict get $ip_core_name_to_instances $ip_core_name]
# ui::add_core_mapping_widget -ip_core_name $ip_core_name \
# -hier_replacement $placeholder -candidate_instances $new_ip_core_instance
set foo [list]
set num_replaced [adjust_hier -dom $dom -remove $placeholder \
-insert $new_ip_core_instance -unreplaced_var foo]
set num_clocks_replaced [adjust_hier_for_clock -dom $dom -remove $placeholder \
-insert $new_ip_core_instance -unreplaced_var foo]
remove_hier_replacement_entry -dom $dom -placeholder $placeholder
if { 0 < [llength $foo] } {
post_message -type warning "Some node names in the SignalTap II file\
do not exist in this design." -submsgs $foo
}
}
}
}
# end of ui namespace
################################################################################
proc find_toplevel_cores { args } {
load_package report
load_report
# Make sure the report exists
set ip_cores_full_panel_name "Analysis & Synthesis||Analysis & Synthesis IP Cores Summary"
set id [get_report_panel_id $ip_cores_full_panel_name]
if { -1 == $id } {
post_message -type error "Can not find report panel ${ip_cores_full_panel_name}"
return -code error
}
# Make sure the columns exist
set ip_core_col [get_report_panel_column_index -id $id "IP Core Name"]
set entity_instance_col [get_report_panel_column_index -id $id "Entity Instance"]
if { -1 == $ip_core_col } {
post_message -type error "Can not find IP Core Name column"
}
if { -1 == $entity_instance_col } {
post_message -type error "Can not find Entity Instance column"
}
if { -1 == $ip_core_col || -1 == $entity_instance_col } { return -code error }
# Walk through the report, checking whether the IP core name asked for
# matches each row
set to_return [list]
# prev_match must start with a space - something that will not match.
# The zero-length string will match in the regexp below
set prev_match " "
set num_rows [get_number_of_rows -id $id]
for { set row 1 } { $row < $num_rows } { incr row } {
set data [get_report_panel_row -id $id -row $row]
set ip_core_name [lindex $data $ip_core_col]
set entity_instance [lindex $data $entity_instance_col]
# Take off the top-level entity name
regsub {^\|.*?\|} $entity_instance {} entity_instance
if { [regexp $prev_match $entity_instance] } {
# This line is a sub-core of the previous match
} else {
lappend to_return $entity_instance
set prev_match [string map { \[ \\\[ \] \\\] \| \\\| \\ \\\\ } \
$entity_instance]
}
}
unload_report
return $to_return
}
#main {*}$quartus(args)
if { 0 } {
if { [string equal "" $opts(stp_file)] } {
# If there is no file specified, prompt for one
init_tk
set result [tk_getSaveFile -filetypes {{"SignalTap II Files" {".stp" ".STP"}}}]
if { [string equal "" $result] } {
# The user cancelled, return with no action
return
} else {
set output_file $result
}
} else {
set output_file $opts(stp_file)
}
}
proc test { args } {
destroy .stp_dialog
ui::assemble
ui::init_data
ui::add_core_mapping_widget -ip_core_name alt_e100 -hier_replacement 0101010101 -candidate_instances { top|fiddle top|biz top|bar|fiddle }
ui::add_core_mapping_widget -ip_core_name alt_pcie_hip -hier_replacement 01010101010 -candidate_instances { top|fiddle top|biz top|bar|fiddle }
ui::display
}
\ No newline at end of file
config fpll_g1g2xn_cfg;
design fpll_g1g2xn;
instance fpll_g1g2xn.fpll_g1g2xn use arria10gx_ftm4_pcie_hip_altera_xcvr_fpll_a10_181.altera_xcvr_fpll_a10;
endconfig
config phy_g1x4_cfg;
design phy_g1x4;
instance phy_g1x4.phy_g1x4 use arria10gx_ftm4_pcie_hip_altera_xcvr_native_a10_181.arria10gx_ftm4_pcie_hip_altera_xcvr_native_a10_181_7zb32zq;
endconfig
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
module skp_det_g3 (
input [31:0] rxdata,
input rxstartblock,
input [1:0] rxsynchdr,
input rxvalid,
input rxdatavalid,
input rate_g3,
input core_clk,
input core_rst_n,
output reg skp_pat_det_g3_ps //pulse stretched SKP pattern detect indicator
);
wire skp_pat_det_g3_sb;
wire skp_pat_det_g3_d;
wire skp_end_det_g3;
wire false_skp_det;
reg [1:0] skp_pat_det_g3;
//reg skp_pat_det_g3_ps;
reg skp_pat_det_g3_sb_dly;
reg skp_pat_det_g3_d_dly;
reg [1:0] rxsynchdr_ext;
//detect Arria 10 Gen3 block aligner SKP error pattern. SKP pattern detected during data block
assign skp_pat_det_g3_sb = ((rxdata[31:0] == 32'haaaa_aaaa) & rxstartblock & (rxsynchdr[1:0] == 2'b10) & rxvalid); //Detect start of SKP in scrambled data when syn header is datablk
assign skp_pat_det_g3_d = ((rxdata[31:0] == 32'haaaa_aaaa) & (rxsynchdr_ext[1:0] == 2'b10) & rxvalid & rxdatavalid); //Detect next cycle of scrambled data looking like a SKP
assign skp_end_det_g3 = (rxdata[7:0] == 8'he1) & (rxsynchdr_ext[1:0] == 2'b10) & rxvalid & rxdatavalid;
//assign false_skp_det = ~(k_g3_skp_det_dis) & (skp_pat_det_g3_sb_dly & skp_pat_det_g3_d) | (skp_pat_det_g3_d_dly & skp_end_det_g3); //first two cycles of a 32-bit SKP OS detected in a datablock
//assign false_skp_det = (skp_pat_det_g3_sb_dly & skp_pat_det_g3_d) | (skp_pat_det_g3_d_dly & skp_end_det_g3); //first two cycles of a 32-bit SKP OS detected in a datablock
assign false_skp_det = (skp_pat_det_g3_sb_dly & skp_pat_det_g3_d) | (skp_pat_det_g3_sb_dly & skp_end_det_g3); //first two cycles of a 32-bit SKP OS detected in a datablock
always @ (posedge core_clk or negedge core_rst_n) begin
if(!core_rst_n) begin
skp_pat_det_g3[1:0] <= 2'b00;
skp_pat_det_g3_ps <= 1'b0;
skp_pat_det_g3_sb_dly <= 1'b0;
skp_pat_det_g3_d_dly <= 1'b0;
rxsynchdr_ext <= 2'b00;
end
else begin
skp_pat_det_g3_sb_dly <= rxvalid ? skp_pat_det_g3_sb : skp_pat_det_g3_sb_dly;
skp_pat_det_g3_d_dly <= skp_pat_det_g3_d;
skp_pat_det_g3[1:0] <= {skp_pat_det_g3[0], false_skp_det};
skp_pat_det_g3_ps <= (skp_pat_det_g3[1] | skp_pat_det_g3[0] | false_skp_det ); //pulse stretch output for 3 cycles (6ns worst case @ 500MHz)
rxsynchdr_ext[1:0] <= (rxstartblock==1'b1) ? rxsynchdr[1:0] : rxsynchdr_ext[1:0];
end
end
endmodule
\ No newline at end of file
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1 ps/1 ps
package a10_avmm_h;
// localparam to define unused bus
localparam RD_UNUSED = 8'h0;
// localparams for common capability registers
localparam A10_XR_ADDR_ID_0 = 9'h0;
localparam A10_XR_ADDR_ID_1 = 9'h1;
localparam A10_XR_ADDR_ID_2 = 9'h2;
localparam A10_XR_ADDR_ID_3 = 9'h3;
localparam A10_XR_ADDR_STATUS_EN = 9'h4;
localparam A10_XR_ADDR_CONTROL_EN = 9'h5;
// Reserve Address 9'h6 to 9'hF for common capablities
// native phy capability
localparam A10_XR_ADDR_NAT_CHNLS = 9'h10;
localparam A10_XR_ADDR_NAT_CHNL_NUM = 9'h11;
localparam A10_XR_ADDR_NAT_DUPLEX = 9'h12;
localparam A10_XR_ADDR_NAT_PRBS_EN = 9'h13;
localparam A10_XR_ADDR_NAT_ODI_EN = 9'h14;
// pll ip capability
localparam A10_XR_ADDR_PLL_MCGB_EN = 9'h10;
// localparams for csr for pll locked and cal busy
localparam A10_XR_ADDR_GP_PLL_LOCK = 9'h80;
localparam A10_XR_OFFSET_GP_LOCK = 0;
localparam A10_XR_OFFSET_GP_CAL_BUSY = 1;
localparam A10_XR_OFFSET_GP_AVMM_BUSY = 2;
localparam A10_XR_OFFSET_LOCK_UNUSED = 3;
localparam A10_XR_LOCK_UNUSED_LEN = 5;
// localparams for pll powerdown
localparam A10_XR_ADDR_GP_PLL_RST = 9'hE0;
localparam A10_XR_OFFSET_PLL_RST = 0;
localparam A10_XR_OFFSET_PLL_RST_OVR = 1;
localparam A10_XR_OFFSET_PLL_RST_UNUSED = 2;
localparam A10_XR_PLL_RST_UNUSED_LEN = 6;
// localparams for csr for lock to ref and lock to data
localparam A10_XR_ADDR_GP_RD_LTR = 9'h80;
localparam A10_XR_OFFSET_RD_LTD = 0;
localparam A10_XR_OFFSET_RD_LTR = 1;
localparam A10_XR_OFFSET_LTR_UNUSED = 2;
localparam A10_XR_LTR_UNUSED_LEN = 6;
// localparams for csr for cal busy
localparam A10_XR_ADDR_GP_CAL_BUSY = 9'h81;
localparam A10_XR_OFFSET_TX_CAL_BUSY = 0;
localparam A10_XR_OFFSET_RX_CAL_BUSY = 1;
localparam A10_XR_OFFSET_AVMM_BUSY = 2;
localparam A10_XR_OFFSET_CAL_DUMMY = 3;
localparam A10_XR_OFFSET_TX_CAL_MASK = 4;
localparam A10_XR_OFFSET_RX_CAL_MASK = 5;
localparam A10_XR_OFFSET_CAL_UNUSED = 6;
localparam A10_XR_CAL_UNUSED_LEN = 2;
// localparams for setting lock to ref and lock to data
localparam A10_XR_ADDR_GP_SET_LTR = 9'hE0;
localparam A10_XR_OFFSET_SET_LTD = 0;
localparam A10_XR_OFFSET_SET_LTR = 1;
localparam A10_XR_OFFSET_SET_LTD_OVR = 2;
localparam A10_XR_OFFSET_SET_LTR_OVR = 3;
localparam A10_XR_OFFSET_SET_LTR_UNUSED = 4;
localparam A10_XR_SET_LTR_UNUSED_LEN = 4;
// localparams for setting loopback
localparam A10_XR_ADDR_GP_LPBK = 9'hE1;
localparam A10_XR_OFFSET_LPBK = 0;
localparam A10_XR_OFFSET_LPBK_UNUSED = 1;
localparam A10_XR_LPBK_UNUSED_LEN = 7;
// localparams for setting channel resets
localparam A10_XR_ADDR_CHNL_RESET = 9'hE2;
localparam A10_XR_OFFSET_RX_ANA = 0;
localparam A10_XR_OFFSET_RX_DIG = 1;
localparam A10_XR_OFFSET_TX_ANA = 2;
localparam A10_XR_OFFSET_TX_DIG = 3;
localparam A10_XR_OFFSET_RX_ANA_OVR = 4;
localparam A10_XR_OFFSET_RX_DIG_OVR = 5;
localparam A10_XR_OFFSET_TX_ANA_OVR = 6;
localparam A10_XR_OFFSET_TX_DIG_OVR = 7;
// localparams for prbs addresses
localparam A10_XR_ADDR_PRBS_CTRL = 9'h100;
localparam A10_XR_ADDR_PRBS_ERR_0 = 9'h101;
localparam A10_XR_ADDR_PRBS_ERR_1 = 9'h102;
localparam A10_XR_ADDR_PRBS_ERR_2 = 9'h103;
localparam A10_XR_ADDR_PRBS_ERR_3 = 9'h104;
localparam A10_XR_ADDR_PRBS_ERR_4 = 9'h105;
localparam A10_XR_ADDR_PRBS_ERR_5 = 9'h106;
localparam A10_XR_ADDR_PRBS_ERR_6 = 9'h107;
localparam A10_XR_ADDR_PRBS_BIT_0 = 9'h10D;
localparam A10_XR_ADDR_PRBS_BIT_1 = 9'h10E;
localparam A10_XR_ADDR_PRBS_BIT_2 = 9'h10F;
localparam A10_XR_ADDR_PRBS_BIT_3 = 9'h110;
localparam A10_XR_ADDR_PRBS_BIT_4 = 9'h111;
localparam A10_XR_ADDR_PRBS_BIT_5 = 9'h112;
localparam A10_XR_ADDR_PRBS_BIT_6 = 9'h113;
// localparams for prbs bit offsets
localparam A10_XR_OFFSET_PRBS_EN = 0;
localparam A10_XR_OFFSET_PRBS_RESET = 1;
localparam A10_XR_OFFSET_PRBS_SNAP = 2;
localparam A10_XR_OFFSET_PRBS_DONE = 3;
localparam A10_XR_OFFSET_PRBS_UNUSED = 4;
localparam A10_XR_PRBS_UNUSED_LEN = 4;
// localparams for odi addresses
localparam A10_XR_ADDR_ODI_CTRL = 9'h120;
localparam A10_XR_ADDR_ODI_ERR_0 = 9'h121;
localparam A10_XR_ADDR_ODI_ERR_1 = 9'h122;
localparam A10_XR_ADDR_ODI_ERR_2 = 9'h123;
localparam A10_XR_ADDR_ODI_ERR_3 = 9'h124;
localparam A10_XR_ADDR_ODI_ERR_4 = 9'h125;
localparam A10_XR_ADDR_ODI_ERR_5 = 9'h126;
localparam A10_XR_ADDR_ODI_ERR_6 = 9'h127;
localparam A10_XR_ADDR_ODI_BIT_0 = 9'h12D;
localparam A10_XR_ADDR_ODI_BIT_1 = 9'h12E;
localparam A10_XR_ADDR_ODI_BIT_2 = 9'h12F;
localparam A10_XR_ADDR_ODI_BIT_3 = 9'h130;
localparam A10_XR_ADDR_ODI_BIT_4 = 9'h131;
localparam A10_XR_ADDR_ODI_BIT_5 = 9'h132;
localparam A10_XR_ADDR_ODI_BIT_6 = 9'h133;
// localparams for odi bit offsets
localparam A10_XR_OFFSET_ODI_EN = 0;
localparam A10_XR_OFFSET_ODI_RESET = 1;
localparam A10_XR_OFFSET_ODI_SNAP = 2;
localparam A10_XR_OFFSET_ODI_DONE = 3;
localparam A10_XR_OFFSET_ODI_UNUSED = 4;
localparam A10_XR_ODI_UNUSED_LEN = 4;
// localparams for embedded reconfig addresses
// Control reg and offsets
localparam A10_XR_ADDR_EMBED_RCFG_CTRL = 9'h140;
localparam A10_XR_OFFSET_EMBED_RCFG_CFG_SEL = 0;
localparam A10_XR_EMBED_RCFG_CFG_SEL_LEN = 6; //bits [5:0] are alloted for cfg_sel even though GUI currently only supports upto 8 profiles.
localparam A10_XR_OFFSET_EMBED_RCFG_BCAST_EN = 6;
localparam A10_XR_OFFSET_EMBED_RCFG_CFG_LOAD = 7;
// Status reg and offsets
localparam A10_XR_ADDR_EMBED_RCFG_STATUS = 9'h141;
localparam A10_XR_OFFSET_EMBED_RCFG_STRM_BUSY = 0;
endpackage
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1 ps/1 ps
module alt_xcvr_native_avmm_nf #(
parameter CHANNELS = 1,
parameter RECONFIG_SHARED = 0,
parameter JTAG_ENABLED = 0,
parameter ADME_SLAVE_MAP = "altera_xcvr_native_a10",
parameter ADME_ASSGN_MAP = " ",
// The following are not intended to be directly set
parameter IFACES = RECONFIG_SHARED ? 1 : CHANNELS,
parameter ADDR_BITS = 9,
parameter SEL_BITS = (RECONFIG_SHARED ? clogb2(CHANNELS-1) : 0)
) (
// Reconfig interface ports
input wire [IFACES-1:0] reconfig_clk,
input wire [IFACES-1:0] reconfig_reset,
input wire [IFACES-1:0] reconfig_write,
input wire [IFACES-1:0] reconfig_read,
input wire [IFACES*(ADDR_BITS+SEL_BITS)-1:0] reconfig_address,
input wire [IFACES*32-1:0] reconfig_writedata,
output wire [IFACES*32-1:0] reconfig_readdata,
output wire [IFACES-1:0] reconfig_waitrequest,
// AVMM ports to transceiver
output wire [CHANNELS-1:0] avmm_clk,
output wire [CHANNELS-1:0] avmm_reset,
output wire [CHANNELS-1:0] avmm_write,
output wire [CHANNELS-1:0] avmm_read,
output wire [CHANNELS*ADDR_BITS-1:0] avmm_address,
output wire [CHANNELS*8-1:0] avmm_writedata,
input wire [CHANNELS*8-1:0] avmm_readdata,
input wire [CHANNELS-1:0] avmm_waitrequest
);
// AVMM connections from the interface sharing logic to the JTAG arbitration
wire [IFACES-1:0] arb_write;
wire [IFACES-1:0] arb_read;
wire [IFACES*(ADDR_BITS+SEL_BITS)-1:0] arb_address;
wire [IFACES*32-1:0] arb_writedata;
wire [IFACES*32-1:0] arb_readdata;
wire [IFACES-1:0] arb_waitrequest;
// Set the slave type for the ADME. Since the span neesd to be a string, 2^(total addr_bits) will
// give the max value, however since the adme uses byte alignment, shift the span by two bits.
localparam set_slave_span = int2str(2**(ADDR_BITS+SEL_BITS+2));
localparam set_slave_map = {"{typeName ",ADME_SLAVE_MAP," address 0x0 span ",set_slave_span," hpath {}",ADME_ASSGN_MAP,"}"};
genvar ig;
//***************************************************************************
//********************** Embedded JTAG Debug Master *************************
generate
if(!JTAG_ENABLED) begin : g_no_jtag
assign arb_address = reconfig_address;
assign arb_write = reconfig_write;
assign arb_read = reconfig_read;
assign arb_writedata = reconfig_writedata;
assign reconfig_readdata = arb_readdata;
assign reconfig_waitrequest= arb_waitrequest;
end else begin : g_jtag
reg sel; // Arbitration bit
wire [(ADDR_BITS+SEL_BITS)-1:0] jtag_address;
wire [31:0] jtag_readdata;
wire jtag_read;
wire jtag_write;
wire [31:0] jtag_writedata;
wire jtag_waitrequest;
wire jtag_readdatavalid;
// When doing RTL sims, remove the altera_debug_master_endpoint, as
// there is no RTL simulation model. Pre and Post Fit sims are ok.
`ifdef ALTERA_RESERVED_QIS
altera_debug_master_endpoint
#(
.ADDR_WIDTH ( (ADDR_BITS+SEL_BITS) ),
.DATA_WIDTH ( 32 ),
.HAS_RDV ( 0 ),
.SLAVE_MAP ( set_slave_map ),
.PREFER_HOST ( " " ),
.CLOCK_RATE_CLK ( 0 )
) adme (
.clk (reconfig_clk),
.reset (reconfig_reset),
.master_write (jtag_write),
.master_read (jtag_read),
.master_address (jtag_address),
.master_writedata (jtag_writedata),
.master_waitrequest (jtag_waitrequest),
.master_readdatavalid (jtag_readdatavalid),
.master_readdata (jtag_readdata)
);
`else
assign jtag_write = 1'b0;
assign jtag_read = 1'b0;
assign jtag_writedata = 32'b0;
assign jtag_address = {ADDR_BITS+SEL_BITS{1'b0}};
`endif
//************************************************************************
//*********************** JTAG<->Reconfig Arbitration ********************
// Drop the lower two address bits from the jtag master (byte addressed)
assign arb_address = sel ? jtag_address[(ADDR_BITS+SEL_BITS-1):0] : reconfig_address;
assign arb_write = sel ? jtag_write : reconfig_write;
assign arb_read = sel ? jtag_read : reconfig_read;
assign arb_writedata = sel ? jtag_writedata : reconfig_writedata;
assign reconfig_readdata = arb_readdata;
assign jtag_readdata = arb_readdata;
assign reconfig_waitrequest= arb_waitrequest | sel;
assign jtag_waitrequest = arb_waitrequest | ~sel;
// Arbitration
always @(posedge reconfig_clk or posedge reconfig_reset)
if(reconfig_reset) sel <= 1'b0;
else begin
if(sel) sel <= arb_waitrequest;
else sel <= (jtag_write|jtag_read) & ~(reconfig_write|reconfig_read);
end
//********************* End JTAG<->Reconfig Arbitration ******************
//************************************************************************
end
endgenerate
//******************** End Embedded JTAG Debug Master ***********************
//***************************************************************************
//***************************************************************************
//********************** AVMM Reconfig Connections **************************
generate
if(!RECONFIG_SHARED) begin : g_not_shared
// We wire straight between the interfaces if there is no sharing logic
assign avmm_clk = reconfig_clk;
assign avmm_reset = reconfig_reset;
assign avmm_write = arb_write;
assign avmm_read = arb_read;
assign avmm_address = arb_address;
assign arb_waitrequest = avmm_waitrequest;
for(ig=0;ig<CHANNELS;ig=ig+1) begin : g_shared
assign avmm_writedata[ig*8 +:8] = arb_writedata[ig*32 +: 8];
assign arb_readdata [ig*32 +:32] = {24'd0,avmm_readdata[ig*8 +: 8]};
end
end else begin : g_shared
wire [SEL_BITS-1:0] arb_sel;
assign arb_sel = arb_address[ADDR_BITS+:SEL_BITS];
for(ig=0;ig<CHANNELS;ig=ig+1) begin : g_shared
assign avmm_clk [ig] = reconfig_clk;
assign avmm_reset [ig] = reconfig_reset;
// Use the upper address bits as the interface select if shared
assign avmm_write [ig] = arb_write & (arb_sel == ig);
assign avmm_read [ig] = arb_read & (arb_sel == ig);
assign avmm_address [ig*ADDR_BITS +: ADDR_BITS] = arb_address[0+:ADDR_BITS];
assign avmm_writedata[ig*8 +: 8] = arb_writedata[7:0];
end
assign arb_readdata = {24'd0,avmm_readdata[arb_sel*8 +: 8]};
assign arb_waitrequest = avmm_waitrequest[arb_sel];
end
endgenerate
//********************** AVMM Reconfig Connections **************************
//***************************************************************************
////////////////////////////////////////////////////////////////////
// Return the number of bits required to represent an integer
// E.g. 0->1; 1->1; 2->2; 3->2 ... 31->5; 32->6
//
function integer clogb2;
input integer input_num;
begin
for (clogb2=0; input_num>0; clogb2=clogb2+1)
input_num = input_num >> 1;
if(clogb2 == 0)
clogb2 = 1;
end
endfunction
// Returns an inst as a string for using string concatenation
function [30*8-1:0] int2str(
input integer in_int
);
integer i;
integer this_char;
i = 0;
int2str = "";
do
begin
this_char = (in_int % 10) + 48;
int2str[i*8+:8] = this_char[7:0];
i=i+1;
in_int = in_int / 10;
end
while(in_int > 0);
endfunction
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
module alt_xcvr_pll_avmm_csr #(
parameter dbg_capability_reg_enable = 0,
parameter dbg_user_identifier = 0,
parameter dbg_stat_soft_logic_enable = 0,
parameter dbg_ctrl_soft_logic_enable = 0,
parameter en_master_cgb = 0,
parameter rcfg_emb_strm_enable = 0,
parameter rcfg_emb_strm_cfg_sel_width = 2
) (
// avmm signals
input avmm_clk,
input avmm_reset,
input [8:0] avmm_address,
input [7:0] avmm_writedata,
input avmm_write,
input avmm_read,
output reg [7:0] avmm_readdata,
output avmm_waitrequest,
// PLL Status signal
input pll_powerdown,
input pll_locked,
input pll_cal_busy,
input avmm_busy,
// embedded reconfig signals
input rcfg_emb_strm_busy,
input rcfg_emb_strm_chan_sel,
output [rcfg_emb_strm_cfg_sel_width-1:0] rcfg_emb_strm_cfg_sel,
output rcfg_emb_strm_bcast_en,
output rcfg_emb_strm_cfg_load,
// PLL Control Signals
output csr_pll_powerdown
);
// Import package with parameters for the soft addresses and offsets
import a10_avmm_h::*;
// Reg for generating waitrequest and data valid
reg avmm_valid;
/**********************************************************************/
// wires and bus declaration
/**********************************************************************/
wire [7:0] rd_system_id;
wire [7:0] rd_status_en;
wire [7:0] rd_control_en;
wire [7:0] rd_mcgb_en;
wire [7:0] rd_ctrl_pll_lock;
wire [7:0] rd_pll_reset;
wire [7:0] rd_rcfg_emb_ctrl;
wire [7:0] rd_rcfg_emb_status;
/**********************************************************************/
//generate waitrequest
/**********************************************************************/
assign avmm_waitrequest = (~avmm_valid & avmm_read);
/**********************************************************************/
// soft CSRs for embedded debug
/**********************************************************************/
always@(posedge avmm_clk) begin
if(~avmm_read) begin
avmm_valid <= 1'b0;
avmm_readdata <= RD_UNUSED;
end else begin
avmm_valid <= avmm_waitrequest;
case(avmm_address)
A10_XR_ADDR_ID_0: avmm_readdata <= rd_system_id;
A10_XR_ADDR_STATUS_EN: avmm_readdata <= rd_status_en;
A10_XR_ADDR_CONTROL_EN: avmm_readdata <= rd_control_en;
A10_XR_ADDR_PLL_MCGB_EN:avmm_readdata <= rd_mcgb_en;
A10_XR_ADDR_GP_PLL_LOCK:avmm_readdata <= rd_ctrl_pll_lock;
A10_XR_ADDR_GP_PLL_RST: avmm_readdata <= rd_pll_reset;
//Embedded reconfig
A10_XR_ADDR_EMBED_RCFG_CTRL: avmm_readdata <= rd_rcfg_emb_ctrl;
A10_XR_ADDR_EMBED_RCFG_STATUS: avmm_readdata <= rd_rcfg_emb_status;
default: avmm_readdata <= RD_UNUSED;
endcase
end
end
/**********************************************************************/
// Capability Registers
/**********************************************************************/
generate if(dbg_capability_reg_enable == 1) begin: enable_pll_capability_reg
assign rd_system_id = dbg_user_identifier[7:0];
assign rd_status_en = dbg_stat_soft_logic_enable[7:0];
assign rd_control_en = dbg_ctrl_soft_logic_enable[7:0];
assign rd_mcgb_en = en_master_cgb[7:0];
end else begin
assign rd_system_id = RD_UNUSED;
assign rd_status_en = RD_UNUSED;
assign rd_control_en = RD_UNUSED;
assign rd_mcgb_en = RD_UNUSED;
end
endgenerate
/**********************************************************************/
// Generate registers for status signals
/**********************************************************************/
generate if(dbg_stat_soft_logic_enable == 1) begin: en_stat_reg
/**********************************************************************/
// wires for synchronizers
/**********************************************************************/
wire pll_cal_busy_sync;
wire pll_locked_sync;
reg r_avmm_busy;
/**********************************************************************/
// readback data at OFFSET synchronize the incoming signals
/**********************************************************************/
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 2 ) // two bits, one for locktodata and one for locktoref
) rx_is_locked_sync (
.clk (avmm_clk),
.reset (avmm_reset),
.d ({pll_cal_busy, pll_locked}),
.q ({pll_cal_busy_sync, pll_locked_sync})
);
assign rd_ctrl_pll_lock[A10_XR_OFFSET_GP_LOCK] = pll_locked_sync;
assign rd_ctrl_pll_lock[A10_XR_OFFSET_GP_CAL_BUSY] = pll_cal_busy_sync;
assign rd_ctrl_pll_lock[A10_XR_OFFSET_GP_AVMM_BUSY] = r_avmm_busy;
assign rd_ctrl_pll_lock[A10_XR_OFFSET_LOCK_UNUSED+:A10_XR_LOCK_UNUSED_LEN] = {A10_XR_LOCK_UNUSED_LEN{1'b0}};
always@(posedge avmm_clk) begin
r_avmm_busy <= avmm_busy;
end
end else begin
assign rd_ctrl_pll_lock = RD_UNUSED;
end
endgenerate
/**********************************************************************/
// Generate registers for control signals
/**********************************************************************/
generate if(dbg_ctrl_soft_logic_enable == 1) begin: en_ctrl_reg
// register for embedded debug-driven powerdown
reg r_pll_reset;
reg r_pll_reset_override;
// readback control signals for the pll powerdown
assign rd_pll_reset[A10_XR_OFFSET_PLL_RST] = r_pll_reset;
assign rd_pll_reset[A10_XR_OFFSET_PLL_RST_OVR] = r_pll_reset_override;
assign rd_pll_reset[A10_XR_OFFSET_PLL_RST_UNUSED+:A10_XR_PLL_RST_UNUSED_LEN] = {A10_XR_PLL_RST_UNUSED_LEN{1'b0}};
// assign the output control signal to the pll
assign csr_pll_powerdown = (rd_pll_reset[A10_XR_OFFSET_PLL_RST_OVR]) ? rd_pll_reset[A10_XR_OFFSET_PLL_RST] : pll_powerdown;
// write control registers for pll_powerodwn
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
r_pll_reset <= 1'b0;
r_pll_reset_override <= 1'b0;
end else if(avmm_write && avmm_address == A10_XR_ADDR_GP_PLL_RST) begin
r_pll_reset <= avmm_writedata[A10_XR_OFFSET_PLL_RST];
r_pll_reset_override <= avmm_writedata[A10_XR_OFFSET_PLL_RST_OVR];
end
end
end else begin
// assign pll powerdown when the ctrl registers arn't used
assign rd_pll_reset = RD_UNUSED;
assign csr_pll_powerdown = (pll_powerdown);
end
endgenerate
/**********************************************************************/
// Embedded reconfig registers
/**********************************************************************/
generate if(rcfg_emb_strm_enable) begin: en_rcfg_reg
/**********************************************************************/
// Generate registers and wires for the reconfig soft logic
/**********************************************************************/
reg [rcfg_emb_strm_cfg_sel_width-1:0] r_rcfg_emb_strm_cfg_sel;
reg r_rcfg_emb_strm_cfg_load;
reg r_rcfg_emb_strm_bcast_en;
reg rcfg_emb_strm_cfg_load_lock = 1'b0;
// readback the embedded reconfig control
assign rd_rcfg_emb_ctrl = {r_rcfg_emb_strm_cfg_load, r_rcfg_emb_strm_bcast_en, {(A10_XR_EMBED_RCFG_CFG_SEL_LEN-rcfg_emb_strm_cfg_sel_width){1'b0}}, r_rcfg_emb_strm_cfg_sel};
assign rd_rcfg_emb_status = {7'b0, rcfg_emb_strm_busy};
// assign the output signals to the channel
assign rcfg_emb_strm_cfg_sel = r_rcfg_emb_strm_cfg_sel;
assign rcfg_emb_strm_cfg_load = r_rcfg_emb_strm_cfg_load;
assign rcfg_emb_strm_bcast_en = r_rcfg_emb_strm_bcast_en;
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
r_rcfg_emb_strm_cfg_sel <= {rcfg_emb_strm_cfg_sel_width{1'b0}};
r_rcfg_emb_strm_cfg_load <= 1'b0;
r_rcfg_emb_strm_bcast_en <= 1'b0;
rcfg_emb_strm_cfg_load_lock <= 1'b0;
end else if(avmm_write && avmm_address == A10_XR_ADDR_EMBED_RCFG_CTRL) begin
// Write to this register
r_rcfg_emb_strm_cfg_sel <= avmm_writedata[A10_XR_OFFSET_EMBED_RCFG_CFG_SEL +: rcfg_emb_strm_cfg_sel_width ];
r_rcfg_emb_strm_cfg_load <= avmm_writedata[A10_XR_OFFSET_EMBED_RCFG_CFG_LOAD];
r_rcfg_emb_strm_bcast_en <= avmm_writedata[A10_XR_OFFSET_EMBED_RCFG_BCAST_EN];
end else if(rcfg_emb_strm_chan_sel & rcfg_emb_strm_busy & ~rcfg_emb_strm_cfg_load_lock) begin
// Reset the cfg_load bit when the streaming has started
r_rcfg_emb_strm_cfg_load <= 1'b0;
rcfg_emb_strm_cfg_load_lock <= 1'b1;
end else if(~rcfg_emb_strm_busy & rcfg_emb_strm_cfg_load_lock)
rcfg_emb_strm_cfg_load_lock <= 1'b0;
end
end else begin: g_rcfg_reg_dis
assign rd_rcfg_emb_ctrl = RD_UNUSED;
assign rd_rcfg_emb_status = RD_UNUSED;
assign rcfg_emb_strm_cfg_sel = 1'b0;
assign rcfg_emb_strm_bcast_en = 1'b0;
assign rcfg_emb_strm_cfg_load = 1'b0;
end
endgenerate //End generate g_rcfg_reg
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
module alt_xcvr_pll_embedded_debug #(
parameter dbg_capability_reg_enable = 0,
parameter dbg_user_identifier = 0,
parameter dbg_stat_soft_logic_enable = 0,
parameter dbg_ctrl_soft_logic_enable = 0,
parameter en_master_cgb = 0
) (
// avmm signals
input avmm_clk,
input avmm_reset,
input [8:0] avmm_address,
input [7:0] avmm_writedata,
input avmm_write,
input avmm_read,
output [7:0] avmm_readdata,
output avmm_waitrequest,
// input signals from the core
input in_pll_powerdown,
input in_pll_locked,
input in_pll_cal_busy,
input in_avmm_busy,
// output signals to the ip
output out_pll_powerdown
);
wire prbs_done_sync;
wire csr_prbs_snapshot;
wire csr_prbs_count_en;
wire csr_prbs_reset;
wire [47:0] prbs_err_count;
wire [47:0] prbs_bit_count;
alt_xcvr_pll_avmm_csr #(
.dbg_capability_reg_enable ( dbg_capability_reg_enable ),
.dbg_user_identifier ( dbg_user_identifier ),
.dbg_stat_soft_logic_enable ( dbg_stat_soft_logic_enable ),
.dbg_ctrl_soft_logic_enable ( dbg_ctrl_soft_logic_enable ),
.en_master_cgb ( en_master_cgb)
) embedded_debug_soft_csr (
// avmm signals
.avmm_clk (avmm_clk),
.avmm_reset (avmm_reset),
.avmm_address (avmm_address),
.avmm_writedata (avmm_writedata),
.avmm_write (avmm_write),
.avmm_read (avmm_read),
.avmm_readdata (avmm_readdata),
.avmm_waitrequest (avmm_waitrequest),
// input status signals from the channel
.pll_powerdown (in_pll_powerdown),
.pll_locked (in_pll_locked),
.pll_cal_busy (in_pll_cal_busy),
.avmm_busy (in_avmm_busy),
// output control signals
.csr_pll_powerdown (out_pll_powerdown)
);
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// Module: alt_xcvr_resync
//
// Description:
// A general purpose resynchronization module.
//
// Parameters:
// SYNC_CHAIN_LENGTH
// - Specifies the length of the synchronizer chain for metastability
// retiming.
// WIDTH
// - Specifies the number of bits you want to synchronize. Controls the width of the
// d and q ports.
// SLOW_CLOCK - USE WITH CAUTION.
// - Leaving this setting at its default will create a standard resynch circuit that
// merely passes the input data through a chain of flip-flops. This setting assumes
// that the input data has a pulse width longer than one clock cycle sufficient to
// satisfy setup and hold requirements on at least one clock edge.
// - By setting this to 1 (USE CAUTION) you are creating an asynchronous
// circuit that will capture the input data regardless of the pulse width and
// its relationship to the clock. However it is more difficult to apply static
// timing constraints as it ties the data input to the clock input of the flop.
// This implementation assumes the data rate is slow enough
// INIT_VALUE
// - Specifies the initial values of the synchronization registers.
//
// Apply embedded false path timing constraint
(* altera_attribute = "-name SDC_STATEMENT \"set regs [get_registers -nowarn *alt_xcvr_resync*sync_r[0]]; if {[llength [query_collection -report -all $regs]] > 0} {set_false_path -to $regs}\"" *)
`timescale 1ps/1ps
module alt_xcvr_resync #(
parameter SYNC_CHAIN_LENGTH = 2, // Number of flip-flops for retiming. Must be >1
parameter WIDTH = 1, // Number of bits to resync
parameter SLOW_CLOCK = 0, // See description above
parameter INIT_VALUE = 0
) (
input wire clk,
input wire reset,
input wire [WIDTH-1:0] d,
output wire [WIDTH-1:0] q
);
localparam INT_LEN = (SYNC_CHAIN_LENGTH > 1) ? SYNC_CHAIN_LENGTH : 2;
localparam [INT_LEN-1:0] L_INIT_VALUE = (INIT_VALUE == 1) ? {INT_LEN{1'b1}} : {INT_LEN{1'b0}};
genvar ig;
// Generate a synchronizer chain for each bit
generate begin
for(ig=0;ig<WIDTH;ig=ig+1) begin : resync_chains
wire d_in; // Input to sychronization chain.
(* altera_attribute = "disable_da_rule=D103" *)
reg [INT_LEN-1:0] sync_r = L_INIT_VALUE;
assign q[ig] = sync_r[INT_LEN-1]; // Output signal
always @(posedge clk or posedge reset)
if(reset)
sync_r <= L_INIT_VALUE;
else
sync_r <= {sync_r[INT_LEN-2:0],d_in};
// Generate asynchronous capture circuit if specified.
if(SLOW_CLOCK == 0) begin
assign d_in = d[ig];
end else begin
wire d_clk;
reg d_r = L_INIT_VALUE[0];
wire clr_n;
assign d_clk = d[ig];
assign d_in = d_r;
assign clr_n = ~q[ig] | d_clk; // Clear when output is logic 1 and input is logic 0
// Asynchronously latch the input signal.
always @(posedge d_clk or negedge clr_n)
if(!clr_n) d_r <= 1'b0;
else if(d_clk) d_r <= 1'b1;
end // SLOW_CLOCK
end // for loop
end // generate
endgenerate
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
//------------------------------------------------------------------
// filename: altera_xcvr_fpll_a10.sv
//
// Description : instantiates avmm and cmu_fpll
//
// Limitation : Intended for NightFury
//
// Copyright (c) Altera Corporation 1997-2012
// All rights reserved
//-------------------------------------------------------------------
`timescale 1ps/1ps
module altera_xcvr_fpll_a10
#(
// This has been modified
parameter [4:0] cmu_fpll_pll_vco_freq_band_0_fix = 5'b00000,
parameter [2:0] cmu_fpll_pll_vco_freq_band_0_dyn_low_bits = 3'b011,
parameter [1:0] cmu_fpll_pll_vco_freq_band_0_dyn_high_bits = 2'b00,
parameter cmu_fpll_pll_vco_freq_band_0_fix_high = "pll_vco_freq_band_0_fix_high_0",
parameter [4:0] cmu_fpll_pll_vco_freq_band_1_fix = 5'b00000,
parameter [4:0] cmu_fpll_pll_vco_freq_band_1_dyn_low_bits = 3'b011,
parameter [1:0] cmu_fpll_pll_vco_freq_band_1_dyn_high_bits = 2'b00,
parameter cmu_fpll_pll_vco_freq_band_1_fix_high = "pll_vco_freq_band_1_fix_high_0",
parameter cmu_fpll_xpm_cmu_fpll_core_cal_vco_count_length = "sel_8b_count",
parameter cmu_fpll_xpm_cmu_fpll_core_pfd_pulse_width = "pulse_width_setting0",
parameter cmu_fpll_xpm_cmu_fpll_core_pfd_delay_compensation = "normal_delay",
parameter cmu_fpll_xpm_cmu_fpll_core_xpm_cpvco_fpll_xpm_chgpmplf_fpll_cp_current_boost = "normal_setting",
// Virtual parameters
parameter enable_debug_info = "true",
parameter cmu_fpll_bw_sel = "low",
parameter cmu_fpll_side = "side_unknown",
parameter cmu_fpll_top_or_bottom = "tb_unknown",
parameter cmu_fpll_compensation_mode = "direct",
parameter cmu_fpll_datarate = "0 ps",
parameter cmu_fpll_pll_c0_pllcout_enable = "disable",
parameter cmu_fpll_pll_c1_pllcout_enable = "disable",
parameter cmu_fpll_pll_c2_pllcout_enable = "disable",
parameter cmu_fpll_pll_c3_pllcout_enable = "disable",
parameter cmu_fpll_fpll_cas_out_enable = "fpll_cas_out_disable",
parameter cmu_fpll_fpll_hclk_out_enable = "disable",
parameter cmu_fpll_fpll_iqtxrxclk_out_enable = "disable",
parameter cmu_fpll_duty_cycle_0 = 50,
parameter cmu_fpll_duty_cycle_1 = 50,
parameter cmu_fpll_duty_cycle_2 = 50,
parameter cmu_fpll_duty_cycle_3 = 50,
parameter cmu_fpll_hssi_output_clock_frequency = "0 ps",
parameter cmu_fpll_is_cascaded_pll = "false",
parameter cmu_fpll_is_otn = "false",
parameter cmu_fpll_is_sdi = "false",
parameter cmu_fpll_output_clock_frequency_0 = "0 ps",
parameter cmu_fpll_output_clock_frequency_1 = "0 ps",
parameter cmu_fpll_output_clock_frequency_2 = "0 ps",
parameter cmu_fpll_output_clock_frequency_3 = "0 ps",
parameter cmu_fpll_phase_shift_0 = "0 ps",
parameter cmu_fpll_phase_shift_1 = "0 ps",
parameter cmu_fpll_phase_shift_2 = "0 ps",
parameter cmu_fpll_phase_shift_3 = "0 ps",
parameter cmu_fpll_prot_mode = "basic",
parameter cmu_fpll_reference_clock_frequency = "100.0 MHz",
parameter cmu_fpll_reference_clock_frequency_scratch = "0 Hz",
parameter cmu_fpll_vco_frequency = "100.0 MHz",
parameter cmu_fpll_reconfig_en = "0",
parameter cmu_fpll_dps_en = "false",
parameter cmu_fpll_is_pa_core = "false",
// Added parameters
parameter cmu_fpll_primary_use = "tx",
parameter cmu_fpll_feedback = "normal",
// Additional parameters for Rev D
parameter cmu_fpll_vco_freq_hz = "0",
parameter cmu_fpll_out_freq_hz = "0",
parameter cmu_fpll_f_out_c0_hz = "0",
parameter cmu_fpll_f_out_c1_hz = "0",
parameter cmu_fpll_f_out_c2_hz = "0",
parameter cmu_fpll_f_out_c3_hz = "0",
parameter cmu_fpll_f_min_vco = "0",
parameter cmu_fpll_f_max_vco = "0",
// Bitvec parameters
parameter cmu_fpll_refclk_freq = "000000000000000000000000000000000001",
parameter cmu_fpll_vco_freq = "000000000000000000000000000000000001",
parameter cmu_fpll_pfd_freq = "000000000000000000000000000000000001",
parameter cmu_fpll_out_freq = "000000000000000000000000000000000001",
parameter cmu_fpll_f_out_c0 = "000000000000000000000000000000000001",
parameter cmu_fpll_f_out_c1 = "000000000000000000000000000000000001",
parameter cmu_fpll_f_out_c2 = "000000000000000000000000000000000001",
parameter cmu_fpll_f_out_c3 = "000000000000000000000000000000000001",
parameter [4:0] cmu_fpll_l_counter = 5'b00001,
parameter [7:0] cmu_fpll_m_counter = 8'b00000001,
parameter [5:0] cmu_fpll_n_counter = 6'b000001,
parameter [8:0] cmu_fpll_m_counter_c0 = 9'b000000001,
parameter [8:0] cmu_fpll_m_counter_c1 = 9'b000000001,
parameter [8:0] cmu_fpll_m_counter_c2 = 9'b000000001,
parameter [8:0] cmu_fpll_m_counter_c3 = 9'b000000001,
parameter [7:0] cmu_fpll_set_fpll_input_freq_range = 8'b11111111,
parameter cmu_fpll_pma_width = 8,
parameter cmu_fpll_cgb_div = 1,
// twentynm_cmu_fpll_refclk_select parameters
parameter cmu_fpll_refclk_select_mux_pll_clkin_0_src = "pll_clkin_0_src_vss",
parameter cmu_fpll_refclk_select_mux_pll_clkin_1_src = "pll_clkin_1_src_vss",
parameter cmu_fpll_refclk_select_mux_pll_auto_clk_sw_en = "false",
parameter cmu_fpll_refclk_select_mux_pll_clk_loss_edge = "pll_clk_loss_both_edges",
parameter cmu_fpll_refclk_select_mux_pll_clk_loss_sw_en = "false",
parameter cmu_fpll_refclk_select_mux_pll_clk_sw_dly = 0,
parameter cmu_fpll_refclk_select_mux_pll_manu_clk_sw_en = "false",
parameter cmu_fpll_refclk_select_mux_pll_sw_refclk_src = "pll_sw_refclk_src_clk_0",
parameter cmu_fpll_refclk_select_mux_mux0_inclk0_logical_to_physical_mapping = "power_down",
parameter cmu_fpll_refclk_select_mux_mux0_inclk1_logical_to_physical_mapping = "power_down",
parameter cmu_fpll_refclk_select_mux_mux0_inclk2_logical_to_physical_mapping = "power_down",
parameter cmu_fpll_refclk_select_mux_mux0_inclk3_logical_to_physical_mapping = "power_down",
parameter cmu_fpll_refclk_select_mux_mux0_inclk4_logical_to_physical_mapping = "power_down",
parameter cmu_fpll_refclk_select_mux_mux1_inclk0_logical_to_physical_mapping = "power_down",
parameter cmu_fpll_refclk_select_mux_mux1_inclk1_logical_to_physical_mapping = "power_down",
parameter cmu_fpll_refclk_select_mux_mux1_inclk2_logical_to_physical_mapping = "power_down",
parameter cmu_fpll_refclk_select_mux_mux1_inclk3_logical_to_physical_mapping = "power_down",
parameter cmu_fpll_refclk_select_mux_mux1_inclk4_logical_to_physical_mapping = "power_down",
parameter cmu_fpll_refclk_select_mux_refclk_select0 = "power_down",
parameter cmu_fpll_refclk_select_mux_refclk_select1 = "power_down",
parameter cmu_fpll_refclk_select_mux_pll_clk_sel_override = "normal",
parameter cmu_fpll_refclk_select_mux_pll_clk_sel_override_value = "select_clk0",
parameter cmu_fpll_refclk_select_mux_silicon_rev = "20nm5es",
// twentynm_cmu_fpll parameters
parameter cmu_fpll_xpm_cmu_fpll_core_fpll_refclk_source = "normal_refclk",//Valid values: normal_refclk, lc_dedicated_refclk
parameter cmu_fpll_pll_a_csr_bufin_posedge = "zero",
parameter cmu_fpll_pll_atb = "atb_selectdisable",
parameter cmu_fpll_pll_bw_mode = "low_bw",
parameter cmu_fpll_pll_c_counter_0 = 1,
parameter cmu_fpll_pll_c_counter_0_coarse_dly = "0 ps",
parameter cmu_fpll_pll_c_counter_0_fine_dly = "0 ps",
parameter cmu_fpll_pll_c_counter_0_in_src = "c_cnt_in_src_test_clk",
parameter cmu_fpll_pll_c_counter_0_min_tco_enable = "true",
parameter cmu_fpll_pll_c_counter_0_ph_mux_prst = 0,
parameter cmu_fpll_pll_c_counter_0_prst = 1,
parameter cmu_fpll_pll_c_counter_1 = 1,
parameter cmu_fpll_pll_c_counter_1_coarse_dly = "0 ps",
parameter cmu_fpll_pll_c_counter_1_fine_dly = "0 ps",
parameter cmu_fpll_pll_c_counter_1_in_src = "c_cnt_in_src_test_clk",
parameter cmu_fpll_pll_c_counter_1_min_tco_enable = "true",
parameter cmu_fpll_pll_c_counter_1_ph_mux_prst = 0,
parameter cmu_fpll_pll_c_counter_1_prst = 1,
parameter cmu_fpll_pll_c_counter_2 = 1,
parameter cmu_fpll_pll_c_counter_2_coarse_dly = "0 ps",
parameter cmu_fpll_pll_c_counter_2_fine_dly = "0 ps",
parameter cmu_fpll_pll_c_counter_2_in_src = "c_cnt_in_src_test_clk",
parameter cmu_fpll_pll_c_counter_2_min_tco_enable = "true",
parameter cmu_fpll_pll_c_counter_2_ph_mux_prst = 0,
parameter cmu_fpll_pll_c_counter_2_prst = 1,
parameter cmu_fpll_pll_c_counter_3 = 1,
parameter cmu_fpll_pll_c_counter_3_coarse_dly = "0 ps",
parameter cmu_fpll_pll_c_counter_3_fine_dly = "0 ps",
parameter cmu_fpll_pll_c_counter_3_in_src = "c_cnt_in_src_test_clk",
parameter cmu_fpll_pll_c_counter_3_min_tco_enable = "true",
parameter cmu_fpll_pll_c_counter_3_ph_mux_prst = 0,
parameter cmu_fpll_pll_c_counter_3_prst = 1,
parameter cmu_fpll_pll_cal_status = "false",
parameter cmu_fpll_pll_calibration = "true",
parameter cmu_fpll_pll_cmp_buf_dly = "0 ps",
parameter cmu_fpll_pll_cp_compensation = "true",
parameter cmu_fpll_pll_cp_current_setting = "cp_current_setting0",
parameter cmu_fpll_pll_cp_testmode = "cp_normal",
parameter cmu_fpll_pll_cp_lf_3rd_pole_freq = "lf_3rd_pole_setting0",
parameter cmu_fpll_pll_cp_lf_4th_pole_freq = "lf_4th_pole_setting0",
parameter cmu_fpll_pll_cp_lf_order = "lf_2nd_order",
parameter cmu_fpll_pll_ctrl_override_setting = "true",
parameter cmu_fpll_pll_ctrl_plniotri_override = "false",
parameter cmu_fpll_pll_device_variant = "device1",
parameter cmu_fpll_pll_dprio_base_addr = 256,
parameter cmu_fpll_pll_dprio_broadcast_en = "true",
parameter cmu_fpll_pll_dprio_clk_vreg_boost = "clk_fpll_vreg_no_voltage_boost",
parameter cmu_fpll_pll_dprio_cvp_inter_sel = "true",
parameter cmu_fpll_pll_dprio_force_inter_sel = "true",
parameter cmu_fpll_pll_dprio_fpll_vreg_boost = "fpll_vreg_no_voltage_boost",
parameter cmu_fpll_pll_dprio_fpll_vreg1_boost = "fpll_vreg1_no_voltage_boost",
parameter cmu_fpll_pll_dprio_power_iso_en = "true",
parameter cmu_fpll_pll_dprio_status_select = "dprio_normal_status",
parameter cmu_fpll_pll_dsm_ecn_bypass = "false",
parameter cmu_fpll_pll_dsm_ecn_test_en = "false",
parameter cmu_fpll_pll_dsm_fractional_division = "1",
parameter cmu_fpll_pll_dsm_fractional_value_ready = "pll_k_ready",
parameter cmu_fpll_pll_dsm_mode = "dsm_mode_integer",
parameter cmu_fpll_pll_dsm_out_sel = "pll_dsm_disable",
parameter cmu_fpll_pll_enable = "true",
parameter cmu_fpll_pll_extra_csr = 0,
parameter cmu_fpll_pll_fbclk_mux_1 = "pll_fbclk_mux_1_glb",
parameter cmu_fpll_pll_fbclk_mux_2 = "pll_fbclk_mux_2_m_cnt",
parameter cmu_fpll_initial_settings = "true",
parameter cmu_fpll_pll_iqclk_mux_sel = "power_down",
parameter cmu_fpll_pll_l_counter = 1,
parameter cmu_fpll_pll_l_counter_bypass = "false",
parameter cmu_fpll_pll_l_counter_enable = "true",
parameter cmu_fpll_pll_lf_resistance = "lf_res_setting0",
parameter cmu_fpll_pll_lf_cbig = "lf_cbig_setting4",
parameter cmu_fpll_pll_lf_ripplecap = "lf_ripple_enabled_0",
parameter cmu_fpll_pll_lock_fltr_cfg = 1,
parameter cmu_fpll_pll_lock_fltr_test = "pll_lock_fltr_nrm",
parameter cmu_fpll_pll_lpf_rstn_value = "lpf_normal",
parameter cmu_fpll_pll_m_counter = 1,
parameter cmu_fpll_pll_m_counter_coarse_dly = "0 ps",
parameter cmu_fpll_pll_m_counter_fine_dly = "0 ps",
parameter cmu_fpll_pll_m_counter_in_src = "m_cnt_in_src_test_clk",
parameter cmu_fpll_pll_m_counter_min_tco_enable = "true",
parameter cmu_fpll_pll_m_counter_ph_mux_prst = 0,
parameter cmu_fpll_pll_m_counter_prst = 1,
parameter cmu_fpll_pll_n_counter = 1,
parameter cmu_fpll_pll_n_counter_coarse_dly = "0 ps",
parameter cmu_fpll_pll_n_counter_fine_dly = "0 ps",
parameter cmu_fpll_pll_nreset_invert = "false",
parameter cmu_fpll_pll_op_mode = "false",
parameter cmu_fpll_pll_optimal = "true",
parameter cmu_fpll_pll_overrange_underrange_voltage_coarse_sel = "vreg_setting_coarse1",
parameter cmu_fpll_pll_overrange_voltage = "over_setting3",
parameter cmu_fpll_power_mode = "low_power",
parameter cmu_fpll_pll_powerdown_mode = "false",
parameter cmu_fpll_pll_ppm_clk0_src = "ppm_clk0_vss",
parameter cmu_fpll_pll_ppm_clk1_src = "ppm_clk1_vss",
parameter cmu_fpll_pll_ref_buf_dly = "0 ps",
parameter cmu_fpll_pll_rstn_override = "false",
parameter cmu_fpll_pll_self_reset = "false",
parameter cmu_fpll_pll_cmu_rstn_value = "true",
parameter cmu_fpll_silicon_rev = "20nm5es",
parameter cmu_fpll_pm_speed_grade = "e2",
parameter cmu_fpll_pll_sup_mode = "user_mode",
parameter cmu_fpll_pll_tclk_mux_en = "false",
parameter cmu_fpll_pll_tclk_sel = "pll_tclk_m_src",
parameter cmu_fpll_pll_test_enable = "false",
parameter cmu_fpll_pll_underrange_voltage = "under_setting3",
parameter cmu_fpll_pll_unlock_fltr_cfg = 0,
parameter cmu_fpll_pll_vccr_pd_en = "true",
parameter cmu_fpll_pll_vco_freq_band_0 = "pll_freq_band0",
parameter cmu_fpll_pll_vco_freq_band_1 = "pll_freq_band0_1",
parameter cmu_fpll_pll_vco_freq_band = "pll_freq_band0",
parameter cmu_fpll_pll_vco_ph0_en = "false",
parameter cmu_fpll_pll_vco_ph0_value = "pll_vco_ph0_vss",
parameter cmu_fpll_pll_vco_ph1_en = "false",
parameter cmu_fpll_pll_vco_ph1_value = "pll_vco_ph1_vss",
parameter cmu_fpll_pll_vco_ph2_en = "false",
parameter cmu_fpll_pll_vco_ph2_value = "pll_vco_ph2_vss",
parameter cmu_fpll_pll_vco_ph3_en = "false",
parameter cmu_fpll_pll_vco_ph3_value = "pll_vco_ph3_vss",
parameter cmu_fpll_pll_vreg0_output = "vccdreg_nominal",
parameter cmu_fpll_pll_vreg1_output = "vccdreg_nominal",
parameter enable_mcgb = 0, // \RANGE (0) 1
parameter enable_mcgb_debug_ports_parameters = 0, // \RANGE (0) 1
parameter enable_analog_resets = 0, // (0,1)
// 0 - Disable pll_powerdown and mcgb_rst reset input connections. Still allows soft register override
// 1 - Enable pll_powerdown and mcgb_rst reset input connections
parameter hip_cal_en = "disable", // Indicates whether HIP is enabled or not. Valid values: disable, enable
parameter hssi_pma_cgb_master_silicon_rev = "20nm5es", // \RANGE (20nm5es) "revb" "revc"
parameter hssi_pma_cgb_master_prot_mode = "basic_tx", // \RANGE "unused" (basic_tx) "basic_kr_tx" "pcie_gen1_tx" "pcie_gen2_tx" "pcie_gen3_tx" "pcie_gen4_tx" "cei_tx" "qpi_tx" "cpri_tx" "fc_tx" "srio_tx" "gpon_tx" "sdi_tx" "sata_tx" "xaui_tx" "obsai_tx" "gige_tx" "higig_tx" "sonet_tx" "sfp_tx" "xfp_tx" "sfi_tx"
parameter hssi_pma_cgb_master_cgb_enable_iqtxrxclk = "disable_iqtxrxclk", // \OPEN in atom default is enable in _hw.tcl default is disable // \RANGE disable_iqtxrxclk (enable_iqtxrxclk)
parameter hssi_pma_cgb_master_x1_div_m_sel = "divbypass", // \RANGE (divbypass) divby2 divby4 divby8
parameter hssi_pma_cgb_master_ser_mode = "eight_bit", // \RANGE (eight_bit) ten_bit sixteen_bit twenty_bit thirty_two_bit forty_bit sixty_four_bit
parameter hssi_pma_cgb_master_datarate = "0 Mbps",
parameter hssi_pma_cgb_master_cgb_power_down = "normal_cgb", // \RANGE normal_cgb (power_down_cgb)
parameter hssi_pma_cgb_master_master_cgb_clock_control = "master_cgb_no_dft_control", // \RANGE (master_cgb_no_dft_control) master_cgb_dft_control_high master_cgb_dft_control_low
parameter hssi_pma_cgb_master_observe_cgb_clocks = "observe_nothing", // \RANGE (observe_nothing) observe_x1mux_out
parameter hssi_pma_cgb_master_op_mode = "enabled", // \RANGE (enabled) pwr_down
parameter hssi_pma_cgb_master_tx_ucontrol_reset_pcie = "pcscorehip_controls_mcgb", // \RANGE (pcscorehip_controls_mcgb) cgb_reset tx_pcie_gen1 tx_pcie_gen2 tx_pcie_gen3 tx_pcie_gen4
parameter hssi_pma_cgb_master_vccdreg_output = "vccdreg_nominal", // \RANGE (vccdreg_nominal) vccdreg_pos_setting0 vccdreg_pos_setting1 vccdreg_pos_setting2 vccdreg_pos_setting3 vccdreg_pos_setting4 vccdreg_pos_setting5 vccdreg_pos_setting6 vccdreg_pos_setting7 vccdreg_pos_setting8 vccdreg_pos_setting9 vccdreg_pos_setting10 vccdreg_pos_setting11 vccdreg_pos_setting12 vccdreg_pos_setting13 vccdreg_pos_setting14 vccdreg_pos_setting15 reserved1 reserved2 vccdreg_neg_setting0 vccdreg_neg_setting1 vccdreg_neg_setting2 vccdreg_neg_setting3 reserved3 reserved4 reserved5 reserved6 reserved7 reserved8 reserved9 reserved10 reserved11
parameter hssi_pma_cgb_master_input_select = "lcpll_top", // \RANGE lcpll_bot lcpll_top fpll_bot fpll_top (unused)
parameter hssi_pma_cgb_master_input_select_gen3 = "unused", // \RANGE lcpll_bot lcpll_top fpll_bot fpll_top (unused)
parameter hssi_pma_cgb_master_inclk0_logical_to_physical_mapping = "unused", // \RANGE lcpll_bot lcpll_top fpll_bot fpll_top (unused)
parameter hssi_pma_cgb_master_inclk1_logical_to_physical_mapping = "unused", // \RANGE lcpll_bot lcpll_top fpll_bot fpll_top (unused)
parameter hssi_pma_cgb_master_inclk2_logical_to_physical_mapping = "unused", // \RANGE lcpll_bot lcpll_top fpll_bot fpll_top (unused)
parameter hssi_pma_cgb_master_inclk3_logical_to_physical_mapping = "unused", // \RANGE lcpll_bot lcpll_top fpll_bot fpll_top (unused)
parameter hssi_pma_cgb_master_bonding_reset_enable = "allow_bonding_reset", // \RANGE disallow_bonding_reset (allow_bonding_reset)
parameter hssi_pma_cgb_master_optimal = "true", // \RANGE (true) false
parameter hssi_pma_cgb_master_pcie_gen3_bitwidth = "pciegen3_wide" , // \RANGE (pciegen3_wide) pciegen3_narrow parameter powerdown_mode = "powerup" , //Valid values: powerup , powerdown
parameter hssi_pma_cgb_master_powerdown_mode = "powerup" , // \RANGE (powerup) powerdown
parameter hssi_pma_cgb_master_sup_mode = "user_mode" , // \RANGE (user_mode) engineering_mode
parameter hssi_pma_cgb_master_initial_settings = "true", // \RANGE (false) true
// instantiate paramters for embedded debug
parameter enable_pll_reconfig = 0,
parameter rcfg_jtag_enable = 0,
parameter dbg_embedded_debug_enable = 0,
parameter dbg_capability_reg_enable = 0,
parameter dbg_user_identifier = 0,
parameter dbg_stat_soft_logic_enable = 0,
parameter dbg_ctrl_soft_logic_enable = 0,
parameter cmu_fpll_calibration_en = "disable",
parameter rcfg_separate_avmm_busy = 0, // (0,1)
// 0 - AVMM busy is reflected on the waitrequest
// 1 - AVMM busy must be read from a soft CSR
parameter SIZE_AVMM_RDDATA_BUS = 32,
parameter SIZE_AVMM_WRDATA_BUS = 32
)
(
// general usage for core and HSSI
input pll_refclk0,
input pll_refclk1,
input pll_refclk2,
input pll_refclk3,
input pll_refclk4,
input pll_powerdown,
output tx_serial_clk,
output outclk0,
output outclk1,
output outclk2,
output outclk3,
output pll_pcie_clk,
output pll_locked,
// dynamic phase shift
input phase_reset,
input phase_en,
input updn,
input [3:0] cntsel,
output phase_done,
// clock switchover
input extswitch,
output [1:0] clkbad,
output activeclk,
// reconfig for PLL
input reconfig_clk0,
input reconfig_write0,
input reconfig_read0,
input reconfig_reset0,
input [9:0] reconfig_address0,
input [SIZE_AVMM_WRDATA_BUS-1:0] reconfig_writedata0,
output [SIZE_AVMM_RDDATA_BUS-1:0] reconfig_readdata0,
output reconfig_waitrequest0,
output avmm_busy0,
output pll_cal_busy,
output hip_cal_done,
// reconfig for Master CGB
input reconfig_clk1,
input reconfig_write1,
input reconfig_read1,
input reconfig_reset1,
input [9:0] reconfig_address1,
input [SIZE_AVMM_WRDATA_BUS-1:0] reconfig_writedata1,
output [SIZE_AVMM_RDDATA_BUS-1:0] reconfig_readdata1,
output reconfig_waitrequest1,
output avmm_busy1,
output mcgb_cal_busy,
output mcgb_hip_cal_done,
// Central Clock Divider
input mcgb_aux_clk0,
input mcgb_aux_clk1,
input mcgb_aux_clk2,
input mcgb_rst,
input [1:0] pcie_sw,
output [5:0] tx_bonding_clocks,
output mcgb_serial_clk,
output [1:0] pcie_sw_done,
// cascading
output fpll_to_fpll_cascade_clk,
output hssi_pll_cascade_clk,
input atx_to_fpll_cascade_clk,
// debug ports
output clk_src,
output clklow,
output fref
);
localparam MAX_CONVERSION_SIZE_ALT_XCVR_FPLL_A10 = 128;
localparam MAX_STRING_CHARS_ALT_XCVR_FPLL_A10 = 64;
localparam lcl_enable_analog_resets =
`ifdef ALTERA_RESERVED_QIS
`ifdef ALTERA_XCVR_A10_ENABLE_ANALOG_RESETS
1; // MACRO override for quartus synthesis. Connect resets
`else
enable_analog_resets; // parameter option for synthesis
`endif // ALTERA_XCVR_A10_ENABLE_ANALOG_RESETS
`else
1; // not synthesis. Connect resets
`endif // (NOT ALTERA_RESERVED_QIS)
localparam lcl_disable_reset_connected_to_cal_busy =
`ifdef ALTERA_RESERVED_QIS
`ifdef ALTERA_XCVR_A10_DISABLE_RESET_CONNECTED_TO_CAL_BUSY
1; // MACRO override for quartus synthesis. Disconnect pll_cal_busy connection to reset.
`else
0; // Default. Connect pll_cal_busy to reset.
`endif // ALTERA_XCVR_A10_DISABLE_RESET_CONNECTED_TO_CAL_BUSY
`else
0; // not synthesis. Connect cal_busy and user reset to PLL reset
`endif // (NOT ALTERA_RESERVED_QIS)
function automatic [MAX_CONVERSION_SIZE_ALT_XCVR_FPLL_A10-1:0] str_2_bin_altera_xcvr_fpll_pll_a10;
input [MAX_STRING_CHARS_ALT_XCVR_FPLL_A10*8-1:0] instring;
integer this_char;
integer i;
begin
// Initialize accumulator
str_2_bin_altera_xcvr_fpll_pll_a10 = {MAX_CONVERSION_SIZE_ALT_XCVR_FPLL_A10{1'b0}};
for(i=MAX_STRING_CHARS_ALT_XCVR_FPLL_A10-1;i>=0;i=i-1) begin
this_char = instring[i*8+:8];
// Add value of this digit
if(this_char >= 48 && this_char <= 57)
str_2_bin_altera_xcvr_fpll_pll_a10 = (str_2_bin_altera_xcvr_fpll_pll_a10 * 10) + (this_char - 48);
end
end
endfunction
// String to binary conversions
localparam [127:0] temp_cmu_fpll_pll_dsm_fractional_division = str_2_bin_altera_xcvr_fpll_pll_a10(cmu_fpll_pll_dsm_fractional_division);
localparam [31:0] cmu_fpll_pll_dsm_fractional_division_bin = temp_cmu_fpll_pll_dsm_fractional_division[31:0];
localparam SIZE_CGB_BONDING_CLK = 6;
localparam avmm_interfaces = ((enable_mcgb==1) && (enable_mcgb_debug_ports_parameters==1)) ? 2 : 1;
localparam RCFG_ADDR_BITS = 10;
localparam refiqclk_size = 12;
localparam refclk_cnt = 4;
localparam lcl_adme_assgn_map = {" assignments {device_revision ",cmu_fpll_silicon_rev,"}"};
// upper 24 bits are not used, but should not be left at X
// assign reconfig_readdata0[SIZE_AVMM_RDDATA_BUS-1:8] = 0;
assign reconfig_readdata1[SIZE_AVMM_RDDATA_BUS-1:8] = 0;
//-----------------------------------
// reconfig AVMM to pll internal wires
// interface #0 to PLL, interface #1 to CGB
wire [avmm_interfaces-1 :0] pll_avmm_clk;
wire [avmm_interfaces-1 :0] pll_avmm_rstn;
wire [avmm_interfaces*8-1 :0] pll_avmm_writedata;
wire [avmm_interfaces*9-1 :0] pll_avmm_address;
wire [avmm_interfaces-1 :0] pll_avmm_write;
wire [avmm_interfaces-1 :0] pll_avmm_read;
wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_cmu_fpll;
wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_cmu_fpll_refclk_select;
wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_cgb_master;
wire [avmm_interfaces-1 :0] pll_blockselect_cmu_fpll;
wire [avmm_interfaces-1 :0] pll_blockselect_cmu_fpll_refclk_select;
wire [avmm_interfaces-1 :0] pll_blockselect_cgb_master;
//-----------------------------------
// reconfigAVMM to top wrapper wires
// interface #0 to PLL, interface #1 to CGB
wire [avmm_interfaces-1 :0] reconfig_clk;
wire [avmm_interfaces-1 :0] reconfig_reset;
wire [avmm_interfaces*8-1 :0] reconfig_writedata;
wire [avmm_interfaces*10-1 :0] reconfig_address;
wire [avmm_interfaces-1 :0] reconfig_write;
wire [avmm_interfaces-1 :0] reconfig_read;
wire [avmm_interfaces*8-1 :0] reconfig_readdata;
wire [avmm_interfaces-1 :0] reconfig_waitrequest;
wire [avmm_interfaces-1 :0] avmm_busy;
wire [avmm_interfaces-1 :0] pld_cal_done;
wire [avmm_interfaces-1 :0] hip_cal_done_w;
// AVMM reconfiguration signals for the hardware
wire [avmm_interfaces-1:0] avmm_write;
wire [avmm_interfaces-1:0] avmm_read;
wire [avmm_interfaces-1:0] avmm_waitrequest;
wire [avmm_interfaces*8-1:0] avmm_readdata;
// AVMM reconfiguration signals for embedded debug
wire [avmm_interfaces*8-1:0] debug_writedata;
wire [avmm_interfaces-1:0] debug_clk;
wire [avmm_interfaces-1:0] debug_reset;
wire [avmm_interfaces*10-1:0] debug_address;
wire [avmm_interfaces-1:0] debug_write;
wire [avmm_interfaces-1:0] debug_read;
wire [avmm_interfaces-1:0] debug_busy;
wire [avmm_interfaces-1:0] debug_waitrequest;
wire [avmm_interfaces*8-1:0] debug_readdata;
// Wires for control signals from the embedded debug
wire pll_powerdown_int;
// wire for gating pll_powerdown with pll_cal_busy before connecting to the atom input
wire pll_powerdown_int_gated;
// Wire for FPLL DPS
wire final_phase_en;
wire final_phase_reset;
wire pre_phase_done;
//-----------------------------------
// reconfigAVMM to cgb atom
wire avmm_clk_mcgb;
wire avmm_rstn_mcgb;
wire [7:0] avmm_writedata_mcgb;
wire [8:0] avmm_address_mcgb;
wire avmm_write_mcgb;
wire avmm_read_mcgb;
wire [7:0] avmmreaddata_mcgb;
wire blockselect_mcgb;
// Wires for disconnecting pll_powerdown and mcgb_rst
// When the parameter "lcl_enable_analog_resets" is set to 0, these wires will be driven to 0.
// When the parameter "lcl_enable_analog_resets" is set to 1, these wires will be connected
// to the pll_powerdown and mcgb_rst inputs.
wire pll_powerdown_input;
wire mcgb_rst_input;
// Pulling in the rule for calibration attributes from PCS channel RBC
localparam arbiter_ctrl = (cmu_fpll_calibration_en == "enable") ? "uc" : "pld";
localparam cal_done = (cmu_fpll_calibration_en == "enable") ? "cal_done_deassert" : "cal_done_assert";
localparam hip_cal_en_fnl = (cmu_fpll_calibration_en == "enable") ? hip_cal_en : "disable";
localparam avmm_busy_en = rcfg_separate_avmm_busy ? "enable" : "disable";
// Analog reset masking. We always connect analog resets for simulation.
// For synthesis it is parameter controlled or MACRO overridden
generate
if(lcl_enable_analog_resets == 1) begin
assign pll_powerdown_input = pll_powerdown;
assign mcgb_rst_input = mcgb_rst;
end else begin
assign pll_powerdown_input = 1'b0;
assign mcgb_rst_input = 1'b0;
end
endgenerate
// By default, pll_cal_busy needs to be connected back to pll_powerdown in HSSI and Core mode.
// -> OR pll_cal_busy (active high) from hardware with pll_powerdown_int (active high) from user or embedded CSR.
// If the MACRO is enabled, then do not connect pll_cal_busy to pll_powerdown for a fallback option.
// For synthesis it is MACRO overridden
generate
if((lcl_disable_reset_connected_to_cal_busy == 1) || (hip_cal_en_fnl == "enable")) begin
assign pll_powerdown_int_gated = pll_powerdown_int;
end else begin
assign pll_powerdown_int_gated = pll_powerdown_int | pll_cal_busy;
end
endgenerate
assign pll_avmmreaddata_cgb_master[7:0] = { 8 {1'b0} }; // \NOTE only [15:8] is used, hence [7:0] is tied-off to '0'
assign pll_blockselect_cgb_master[0:0] = {1'b0};
assign reconfig_clk[0] = debug_clk;
assign reconfig_reset[0] = debug_reset;
assign reconfig_writedata[7:0] = debug_writedata[7:0];
assign reconfig_address[9:0] = debug_address;
assign reconfig_write[0] = avmm_write;
assign reconfig_read[0] = avmm_read;
assign avmm_readdata[7:0]=reconfig_readdata[7:0];
assign avmm_waitrequest = reconfig_waitrequest[0];
assign avmm_busy0 = avmm_busy[0];
assign hip_cal_done = hip_cal_done_w[0];
assign mcgb_serial_clk = tx_bonding_clocks[SIZE_CGB_BONDING_CLK-1];
generate
if (avmm_interfaces==2) begin
assign pll_avmmreaddata_cmu_fpll[avmm_interfaces*8-1:8] = { 8 {1'b0} }; // \NOTE only [7:0] is used, hence [15:8] is tied-off to '0'
assign pll_avmmreaddata_cmu_fpll_refclk_select[avmm_interfaces*8-1:8] = { 8 {1'b0} }; // \NOTE only [7:0] is used, hence [15:8] is tied-off to '0'
assign pll_blockselect_cmu_fpll[avmm_interfaces-1:1] = {1'b0}; // \NOTE only [0:0] is used, hence [1:1] is tied-off to '0'
assign pll_blockselect_cmu_fpll_refclk_select[avmm_interfaces-1:1] = {1'b0}; // \NOTE only [0:0] is used, hence [1:1] is tied-off to '0'
assign avmm_clk_mcgb = pll_avmm_clk[1];
assign avmm_rstn_mcgb = pll_avmm_rstn[1];
assign avmm_writedata_mcgb = pll_avmm_writedata[15:8];
assign avmm_address_mcgb = pll_avmm_address[17:9];
assign avmm_write_mcgb = pll_avmm_write[1];
assign avmm_read_mcgb = pll_avmm_read[1];
assign pll_avmmreaddata_cgb_master[15:8] = avmmreaddata_mcgb;
assign pll_blockselect_cgb_master[1] = blockselect_mcgb;
end
endgenerate
//---
assign mcgb_cal_busy = 1'b0;
assign pll_cal_busy = ~pld_cal_done[0];
generate
if (avmm_interfaces==2) begin
assign reconfig_clk[1] = reconfig_clk1;
assign reconfig_reset[1] = reconfig_reset1;
assign reconfig_writedata[15:8] = reconfig_writedata1[7:0];
assign reconfig_address[19:10] = reconfig_address1;
assign reconfig_write[1] = reconfig_write1;
assign reconfig_read[1] = reconfig_read1;
assign reconfig_readdata1[7:0]=reconfig_readdata[15:8];
assign reconfig_waitrequest1 = reconfig_waitrequest[1];
assign avmm_busy1 = avmm_busy[1];
//assign mcgb_cal_busy = ~pld_cal_done[1];
assign mcgb_hip_cal_done = hip_cal_done_w[1];
end
else begin
assign reconfig_readdata1[7:0] = 0;
assign reconfig_waitrequest1 = 0;
assign avmm_busy1 = 1'b0;
assign mcgb_hip_cal_done = 0;
end
endgenerate
// feedback wire
wire refclk_sel_outclk_wire;
wire fbclk_wire;
wire iqtxrxclk_wire;
wire pll_extfb_wire;
wire pll_pa_iqtxrxclk_wire;
// clock switchover wire
wire clk0_bad_wire;
wire clk1_bad_wire;
// cascade out on IQTXRXCLK
assign hssi_pll_cascade_clk = iqtxrxclk_wire;
//-----------------------------------
alt_xcvr_native_avmm_nf #(
.CHANNELS (1),
.ADDR_BITS (RCFG_ADDR_BITS),
.ADME_SLAVE_MAP ("altera_xcvr_fpll_a10"),
.ADME_ASSGN_MAP (lcl_adme_assgn_map),
.RECONFIG_SHARED (0),
.JTAG_ENABLED (enable_pll_reconfig && rcfg_jtag_enable)
) altera_xcvr_pll_avmm_nf_inst (
// Reconfig interface ports
.reconfig_clk (reconfig_clk0 ),
.reconfig_reset (reconfig_reset0 ),
.reconfig_write (reconfig_write0 ),
.reconfig_read (reconfig_read0 ),
.reconfig_address (reconfig_address0 ),
.reconfig_writedata (reconfig_writedata0 ),
.reconfig_readdata (reconfig_readdata0 ),
.reconfig_waitrequest (reconfig_waitrequest0),
// AVMM ports to transceiver
.avmm_clk (debug_clk ),
.avmm_reset (debug_reset ),
.avmm_write (debug_write ),
.avmm_read (debug_read ),
.avmm_address (debug_address ),
.avmm_writedata (debug_writedata ),
.avmm_readdata (debug_readdata ),
.avmm_waitrequest (debug_waitrequest )
);
//-----------------------------------
// Instantiate the embedded debug
generate if(dbg_embedded_debug_enable == 1) begin: en_embedded_debug
// AVMM reconfiguration signals for embedded debug
wire [avmm_interfaces-1:0] csr_write;
wire [avmm_interfaces-1:0] csr_read;
wire [avmm_interfaces-1:0] csr_waitrequest;
wire [avmm_interfaces*8-1:0] csr_readdata;
// avmm arbitration for soft csr and pll
assign csr_read = (debug_address[RCFG_ADDR_BITS-1]) ? debug_read : 1'b0;
assign csr_write = (debug_address[RCFG_ADDR_BITS-1]) ? debug_write : 1'b0;
assign avmm_read = (debug_address[RCFG_ADDR_BITS-1]) ? 1'b0 : debug_read ;
assign avmm_write = (debug_address[RCFG_ADDR_BITS-1]) ? 1'b0 : debug_write ;
assign debug_waitrequest = (debug_address[RCFG_ADDR_BITS-1]) ? csr_waitrequest : avmm_waitrequest ;
assign debug_readdata = (debug_address[RCFG_ADDR_BITS-1]) ? csr_readdata : avmm_readdata ;
alt_xcvr_pll_embedded_debug #(
.dbg_capability_reg_enable ( dbg_capability_reg_enable ),
.dbg_user_identifier ( dbg_user_identifier ),
.dbg_stat_soft_logic_enable ( dbg_stat_soft_logic_enable ),
.dbg_ctrl_soft_logic_enable ( dbg_ctrl_soft_logic_enable ),
.en_master_cgb ( enable_mcgb )
) pll_embedded_debug (
// avmm signals
/*input */ .avmm_clk (debug_clk),
/*input */ .avmm_reset (debug_reset),
/*input [8:0] */ .avmm_address (debug_address[8:0]),
/*input [7:0] */ .avmm_writedata (debug_writedata),
/*input */ .avmm_write (csr_write),
/*input */ .avmm_read (csr_read),
/*output [7:0] */ .avmm_readdata (csr_readdata),
/*output */ .avmm_waitrequest (csr_waitrequest),
// input signals from the core
/*input */ .in_pll_powerdown (pll_powerdown_input),
/*input */ .in_pll_locked (pll_locked),
/*input */ .in_pll_cal_busy (pll_cal_busy),
.in_avmm_busy (avmm_busy0),
// output signals to the ip
/*output */ .out_pll_powerdown (pll_powerdown_int)
);
end else begin: dis_embedded_debug
assign pll_powerdown_int = pll_powerdown_input;
assign avmm_write = debug_write;
assign avmm_read = debug_read;
assign debug_waitrequest = avmm_waitrequest;
assign debug_readdata = avmm_readdata;
end
endgenerate
//----------------------------------
// instantiation of twentynm_xcvr_avmm
twentynm_xcvr_avmm
#(
.rcfg_enable(enable_pll_reconfig),
.avmm_interfaces(avmm_interfaces),
.arbiter_ctrl(arbiter_ctrl),
.calibration_en(cmu_fpll_calibration_en),
.avmm_busy_en(avmm_busy_en),
.cal_done(cal_done),
.hip_cal_en(hip_cal_en_fnl)
) xcvr_avmm_inst (
.avmm_clk( {reconfig_clk } ),
.avmm_reset( {reconfig_reset } ),
.avmm_writedata( {reconfig_writedata } ),
.avmm_address( {reconfig_address[8:0] } ),
.avmm_write( {reconfig_write } ),
.avmm_read( {reconfig_read } ),
.avmm_readdata( {reconfig_readdata } ),
.avmm_waitrequest({reconfig_waitrequest } ),
.avmm_busy( {avmm_busy } ),
.pld_cal_done( {pld_cal_done } ),
.hip_cal_done( {hip_cal_done_w } ),
.chnl_pll_avmm_clk(pll_avmm_clk),
.chnl_pll_avmm_rstn(pll_avmm_rstn),
.chnl_pll_avmm_writedata(pll_avmm_writedata),
.chnl_pll_avmm_address(pll_avmm_address),
.chnl_pll_avmm_write(pll_avmm_write),
.chnl_pll_avmm_read(pll_avmm_read),
.pll_avmmreaddata_cmu_fpll(pll_avmmreaddata_cmu_fpll),
.pll_avmmreaddata_cmu_fpll_refclk_select(pll_avmmreaddata_cmu_fpll_refclk_select),
.pll_avmmreaddata_cgb_master(pll_avmmreaddata_cgb_master),
.pll_blockselect_cmu_fpll(pll_blockselect_cmu_fpll),
.pll_blockselect_cmu_fpll_refclk_select(pll_blockselect_cmu_fpll_refclk_select),
.pll_blockselect_cgb_master(pll_blockselect_cgb_master),
//-----------------------------------
// IRRELEVANT PORTS
.pma_avmmreaddata_tx_ser ( {avmm_interfaces{8'b0}} ),
.pma_avmmreaddata_tx_cgb ( {avmm_interfaces{8'b0}} ),
.pma_avmmreaddata_tx_buf ( {avmm_interfaces{8'b0}} ),
.pma_avmmreaddata_rx_deser ( {avmm_interfaces{8'b0}} ),
.pma_avmmreaddata_rx_buf ( {avmm_interfaces{8'b0}} ),
.pma_avmmreaddata_rx_sd ( {avmm_interfaces{8'b0}} ),
.pma_avmmreaddata_rx_odi ( {avmm_interfaces{8'b0}} ),
.pma_avmmreaddata_rx_dfe ( {avmm_interfaces{8'b0}} ),
.pma_avmmreaddata_cdr_pll ( {avmm_interfaces{8'b0}} ),
.pma_avmmreaddata_cdr_refclk_select ( {avmm_interfaces{8'b0}} ),
.pma_avmmreaddata_pma_adapt ( {avmm_interfaces{8'b0}} ),
.pma_blockselect_tx_ser ( {avmm_interfaces{1'b0}} ),
.pma_blockselect_tx_cgb ( {avmm_interfaces{1'b0}} ),
.pma_blockselect_tx_buf ( {avmm_interfaces{1'b0}} ),
.pma_blockselect_rx_deser ( {avmm_interfaces{1'b0}} ),
.pma_blockselect_rx_buf ( {avmm_interfaces{1'b0}} ),
.pma_blockselect_rx_sd ( {avmm_interfaces{1'b0}} ),
.pma_blockselect_rx_odi ( {avmm_interfaces{1'b0}} ),
.pma_blockselect_rx_dfe ( {avmm_interfaces{1'b0}} ),
.pma_blockselect_cdr_pll ( {avmm_interfaces{1'b0}} ),
.pma_blockselect_cdr_refclk_select ( {avmm_interfaces{1'b0}} ),
.pma_blockselect_pma_adapt ( {avmm_interfaces{1'b0}} ),
.pcs_avmmreaddata_8g_rx_pcs ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_pipe_gen1_2 ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_8g_tx_pcs ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_10g_rx_pcs ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_10g_tx_pcs ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_gen3_rx_pcs ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_pipe_gen3 ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_gen3_tx_pcs ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_krfec_rx_pcs ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_krfec_tx_pcs ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_fifo_rx_pcs ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_fifo_tx_pcs ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_rx_pcs_pld_if ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_com_pcs_pld_if ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_tx_pcs_pld_if ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_rx_pcs_pma_if ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_com_pcs_pma_if ( {avmm_interfaces{8'b0}} ),
.pcs_avmmreaddata_tx_pcs_pma_if ( {avmm_interfaces{8'b0}} ),
.pcs_blockselect_8g_rx_pcs ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_pipe_gen1_2 ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_8g_tx_pcs ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_10g_rx_pcs ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_10g_tx_pcs ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_gen3_rx_pcs ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_pipe_gen3 ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_gen3_tx_pcs ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_krfec_rx_pcs ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_krfec_tx_pcs ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_fifo_rx_pcs ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_fifo_tx_pcs ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_rx_pcs_pld_if ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_com_pcs_pld_if ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_tx_pcs_pld_if ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_rx_pcs_pma_if ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_com_pcs_pma_if ( {avmm_interfaces{1'b0}} ),
.pcs_blockselect_tx_pcs_pma_if ( {avmm_interfaces{1'b0}} ),
.pll_avmmreaddata_lc_pll ( {avmm_interfaces{8'b0}} ),
.pll_avmmreaddata_lc_refclk_select ( {avmm_interfaces{8'b0}} ),
.pll_blockselect_lc_pll ( {avmm_interfaces{1'b0}} ),
.pll_blockselect_lc_refclk_select ( {avmm_interfaces{1'b0}} )
);
//-----------------------------------
// instantiation of twentynm_cmu_fpll_refclk_select
twentynm_cmu_fpll_refclk_select
#(
.pll_clkin_0_src(cmu_fpll_refclk_select_mux_pll_clkin_0_src),
.pll_clkin_1_src(cmu_fpll_refclk_select_mux_pll_clkin_1_src),
.pll_auto_clk_sw_en(cmu_fpll_refclk_select_mux_pll_auto_clk_sw_en),
.pll_clk_loss_edge(cmu_fpll_refclk_select_mux_pll_clk_loss_edge),
.pll_clk_loss_sw_en(cmu_fpll_refclk_select_mux_pll_clk_loss_sw_en),
.pll_clk_sw_dly(cmu_fpll_refclk_select_mux_pll_clk_sw_dly),
.pll_manu_clk_sw_en(cmu_fpll_refclk_select_mux_pll_manu_clk_sw_en),
.pll_sw_refclk_src(cmu_fpll_refclk_select_mux_pll_sw_refclk_src),
.mux0_inclk0_logical_to_physical_mapping(cmu_fpll_refclk_select_mux_mux0_inclk0_logical_to_physical_mapping),
.mux0_inclk1_logical_to_physical_mapping(cmu_fpll_refclk_select_mux_mux0_inclk1_logical_to_physical_mapping),
.mux0_inclk2_logical_to_physical_mapping(cmu_fpll_refclk_select_mux_mux0_inclk2_logical_to_physical_mapping),
.mux0_inclk3_logical_to_physical_mapping(cmu_fpll_refclk_select_mux_mux0_inclk3_logical_to_physical_mapping),
.mux0_inclk4_logical_to_physical_mapping(cmu_fpll_refclk_select_mux_mux0_inclk4_logical_to_physical_mapping),
.mux1_inclk0_logical_to_physical_mapping(cmu_fpll_refclk_select_mux_mux1_inclk0_logical_to_physical_mapping),
.mux1_inclk1_logical_to_physical_mapping(cmu_fpll_refclk_select_mux_mux1_inclk1_logical_to_physical_mapping),
.mux1_inclk2_logical_to_physical_mapping(cmu_fpll_refclk_select_mux_mux1_inclk2_logical_to_physical_mapping),
.mux1_inclk3_logical_to_physical_mapping(cmu_fpll_refclk_select_mux_mux1_inclk3_logical_to_physical_mapping),
.mux1_inclk4_logical_to_physical_mapping(cmu_fpll_refclk_select_mux_mux1_inclk4_logical_to_physical_mapping),
.refclk_select0(cmu_fpll_refclk_select_mux_refclk_select0),
.refclk_select1(cmu_fpll_refclk_select_mux_refclk_select1),
.pll_clk_sel_override(cmu_fpll_refclk_select_mux_pll_clk_sel_override),
.pll_clk_sel_override_value(cmu_fpll_refclk_select_mux_pll_clk_sel_override_value),
.silicon_rev(cmu_fpll_silicon_rev)
) fpll_refclk_select_inst
(
// Input Ports
.avmmaddress(pll_avmm_address[8:0]),
// .avmmclk((cmu_fpll_reconfig_en == "0" && cmu_fpll_dps_en == "false") ? 1'b0 : pll_avmm_clk[0]),
.avmmclk(pll_avmm_clk[0]),
.avmmread(pll_avmm_read[0]),
.avmmrstn(pll_avmm_rstn[0]),
.avmmwrite(pll_avmm_write[0]),
.avmmwritedata(pll_avmm_writedata[7:0]),
.core_refclk(),
.extswitch(extswitch),
.iqtxrxclk(),
.pll_cascade_in(),
.ref_iqclk({{(refiqclk_size-refclk_cnt){1'b0}}, {pll_refclk4, pll_refclk3, pll_refclk2, pll_refclk1}}),
.refclk(pll_refclk0),
.tx_rx_core_refclk(),
// Output Ports
.avmmreaddata(pll_avmmreaddata_cmu_fpll_refclk_select[7:0]),
.blockselect(pll_blockselect_cmu_fpll_refclk_select[0]),
.clk_src(clk_src),
.clk0bad(clk0_bad_wire),
.clk1bad(clk1_bad_wire),
.extswitch_buf(),
.outclk(refclk_sel_outclk_wire),
.pllclksel(activeclk)
);
//-----------------------------------
// Instantiate pulse-width control module
dps_pulse_ctrl phase_en_pulse(
.clk(reconfig_clk), // input clock to the HSSI AVMM
.rst(phase_reset),
.user_phase_en(phase_en),
.phase_en(final_phase_en)
);
//-----------------------------------
// Instantiate dps reset generation
dps_reset_gen dps_reset_gen_1 (
.clk(reconfig_clk), // input clock to the HSSI AVMM
.phase_reset_in(phase_reset), // active high reset input
.phase_en_in(final_phase_en), // phase_en input
.phase_done_in(~pre_phase_done), // phase_done input - this thing is actually active LOW
.phase_reset_out(final_phase_reset), // active high reset output
.phase_done_out(phase_done) // phase_done output
);
wire fbclk_in;
wire iqtxrxclk;
assign fbclk_in = (cmu_fpll_compensation_mode == "normal") ? fbclk_wire : 1'b0;
assign iqtxrxclk = (cmu_fpll_compensation_mode == "iqtxrxclk") ? iqtxrxclk_wire : (cmu_fpll_compensation_mode == "fpll_bonding") ? pll_extfb_wire : (cmu_fpll_is_pa_core == "true") ? pll_pa_iqtxrxclk_wire : 1'b0;
assign pll_pa_iqtxrxclk_wire = (cmu_fpll_is_pa_core == "true") ? outclk1 : 1'b0; // Connect clk1 to this hardwired feedback connection if we are in phase alignment mode
//-----------------------------------
// instantiate of twentynm_cmu_fpll
twentynm_cmu_fpll
#(
.pll_vco_freq_band_0_fix (cmu_fpll_pll_vco_freq_band_0_fix),
.pll_vco_freq_band_0_dyn_low_bits (cmu_fpll_pll_vco_freq_band_0_dyn_low_bits),
.pll_vco_freq_band_0_dyn_high_bits (cmu_fpll_pll_vco_freq_band_0_dyn_high_bits),
.pll_vco_freq_band_0_fix_high (cmu_fpll_pll_vco_freq_band_0_fix_high),
.pll_vco_freq_band_1_fix (cmu_fpll_pll_vco_freq_band_1_fix),
.pll_vco_freq_band_1_dyn_low_bits (cmu_fpll_pll_vco_freq_band_1_dyn_low_bits),
.pll_vco_freq_band_1_dyn_high_bits (cmu_fpll_pll_vco_freq_band_1_dyn_high_bits),
.pll_vco_freq_band_1_fix_high (cmu_fpll_pll_vco_freq_band_1_fix_high),
.xpm_cmu_fpll_core_cal_vco_count_length (cmu_fpll_xpm_cmu_fpll_core_cal_vco_count_length),
.xpm_cmu_fpll_core_pfd_pulse_width (cmu_fpll_xpm_cmu_fpll_core_pfd_pulse_width),
.xpm_cmu_fpll_core_pfd_delay_compensation (cmu_fpll_xpm_cmu_fpll_core_pfd_delay_compensation),
.set_fpll_input_freq_range (cmu_fpll_set_fpll_input_freq_range),
.xpm_cmu_fpll_core_xpm_cpvco_fpll_xpm_chgpmplf_fpll_cp_current_boost (cmu_fpll_xpm_cmu_fpll_core_xpm_cpvco_fpll_xpm_chgpmplf_fpll_cp_current_boost),
// virtual parameters
.is_pa_core(cmu_fpll_is_pa_core),
.bw_sel(cmu_fpll_bw_sel),
.side(cmu_fpll_side),
.top_or_bottom(cmu_fpll_top_or_bottom),
.compensation_mode(cmu_fpll_compensation_mode),
.datarate(cmu_fpll_datarate),
.duty_cycle_0(cmu_fpll_duty_cycle_0),
.duty_cycle_1(cmu_fpll_duty_cycle_1),
.duty_cycle_2(cmu_fpll_duty_cycle_2),
.duty_cycle_3(cmu_fpll_duty_cycle_3),
.feedback(cmu_fpll_feedback),
.hssi_output_clock_frequency(cmu_fpll_hssi_output_clock_frequency),
.initial_settings(cmu_fpll_initial_settings),
.is_cascaded_pll(cmu_fpll_is_cascaded_pll),
.is_otn(cmu_fpll_is_otn),
.is_sdi(cmu_fpll_is_sdi),
.output_clock_frequency_0(cmu_fpll_output_clock_frequency_0),
.output_clock_frequency_1(cmu_fpll_output_clock_frequency_1),
.output_clock_frequency_2(cmu_fpll_output_clock_frequency_2),
.output_clock_frequency_3(cmu_fpll_output_clock_frequency_3),
.phase_shift_0(cmu_fpll_phase_shift_0),
.phase_shift_1(cmu_fpll_phase_shift_1),
.phase_shift_2(cmu_fpll_phase_shift_2),
.phase_shift_3(cmu_fpll_phase_shift_3),
.primary_use(cmu_fpll_primary_use),
.prot_mode(cmu_fpll_prot_mode),
.reference_clock_frequency(cmu_fpll_reference_clock_frequency),
.vco_frequency(cmu_fpll_vco_frequency),
// Bitvec parameters
.reference_clock_frequency_scratch(cmu_fpll_reference_clock_frequency),
.vco_freq(cmu_fpll_vco_freq),
.pfd_freq(cmu_fpll_pfd_freq),
.out_freq(cmu_fpll_out_freq),
.f_out_c0(cmu_fpll_f_out_c0),
.f_out_c1(cmu_fpll_f_out_c1),
.f_out_c2(cmu_fpll_f_out_c2),
.f_out_c3(cmu_fpll_f_out_c3),
.vco_freq_hz(cmu_fpll_vco_freq_hz),
.out_freq_hz(cmu_fpll_out_freq_hz),
.f_out_c0_hz(cmu_fpll_f_out_c0_hz),
.f_out_c1_hz(cmu_fpll_f_out_c1_hz),
.f_out_c2_hz(cmu_fpll_f_out_c2_hz),
.f_out_c3_hz(cmu_fpll_f_out_c3_hz),
// .f_min_vco(cmu_fpll_f_min_vco),
// .f_max_vco(cmu_fpll_f_max_vco),
.l_counter(cmu_fpll_l_counter),
.n_counter(cmu_fpll_n_counter),
.m_counter(cmu_fpll_m_counter),
.m_counter_c0(cmu_fpll_m_counter_c0),
.m_counter_c1(cmu_fpll_m_counter_c1),
.m_counter_c2(cmu_fpll_m_counter_c2),
.m_counter_c3(cmu_fpll_m_counter_c3),
.cgb_div(cmu_fpll_cgb_div),
.pma_width(cmu_fpll_pma_width),
// twentynm_cmu_fpll parameters
.pll_atb(cmu_fpll_pll_atb),
.pll_bw_mode(cmu_fpll_pll_bw_mode),
.pll_c0_pllcout_enable(cmu_fpll_pll_c0_pllcout_enable),
.pll_c1_pllcout_enable(cmu_fpll_pll_c1_pllcout_enable),
.pll_c2_pllcout_enable(cmu_fpll_pll_c2_pllcout_enable),
.pll_c3_pllcout_enable(cmu_fpll_pll_c3_pllcout_enable),
.fpll_cas_out_enable(cmu_fpll_fpll_cas_out_enable),
.fpll_hclk_out_enable(cmu_fpll_fpll_hclk_out_enable),
.fpll_iqtxrxclk_out_enable(cmu_fpll_fpll_iqtxrxclk_out_enable),
.pll_c_counter_0(cmu_fpll_pll_c_counter_0),
.pll_c_counter_0_coarse_dly(cmu_fpll_pll_c_counter_0_coarse_dly),
.pll_c_counter_0_fine_dly(cmu_fpll_pll_c_counter_0_fine_dly),
.pll_c_counter_0_in_src(cmu_fpll_pll_c_counter_0_in_src),
.pll_c_counter_0_min_tco_enable(cmu_fpll_pll_c_counter_0_min_tco_enable),
.pll_c_counter_0_ph_mux_prst(cmu_fpll_pll_c_counter_0_ph_mux_prst),
.pll_c_counter_0_prst(cmu_fpll_pll_c_counter_0_prst),
.pll_c_counter_1(cmu_fpll_pll_c_counter_1),
.pll_c_counter_1_coarse_dly(cmu_fpll_pll_c_counter_1_coarse_dly),
.pll_c_counter_1_fine_dly(cmu_fpll_pll_c_counter_1_fine_dly),
.pll_c_counter_1_in_src(cmu_fpll_pll_c_counter_1_in_src),
.pll_c_counter_1_min_tco_enable(cmu_fpll_pll_c_counter_1_min_tco_enable),
.pll_c_counter_1_ph_mux_prst(cmu_fpll_pll_c_counter_1_ph_mux_prst),
.pll_c_counter_1_prst(cmu_fpll_pll_c_counter_1_prst),
.pll_c_counter_2(cmu_fpll_pll_c_counter_2),
.pll_c_counter_2_coarse_dly(cmu_fpll_pll_c_counter_2_coarse_dly),
.pll_c_counter_2_fine_dly(cmu_fpll_pll_c_counter_2_fine_dly),
.pll_c_counter_2_in_src(cmu_fpll_pll_c_counter_2_in_src),
.pll_c_counter_2_min_tco_enable(cmu_fpll_pll_c_counter_2_min_tco_enable),
.pll_c_counter_2_ph_mux_prst(cmu_fpll_pll_c_counter_2_ph_mux_prst),
.pll_c_counter_2_prst(cmu_fpll_pll_c_counter_2_prst),
.pll_c_counter_3(cmu_fpll_pll_c_counter_3),
.pll_c_counter_3_coarse_dly(cmu_fpll_pll_c_counter_3_coarse_dly),
.pll_c_counter_3_fine_dly(cmu_fpll_pll_c_counter_3_fine_dly),
.pll_c_counter_3_in_src(cmu_fpll_pll_c_counter_3_in_src),
.pll_c_counter_3_min_tco_enable(cmu_fpll_pll_c_counter_3_min_tco_enable),
.pll_c_counter_3_ph_mux_prst(cmu_fpll_pll_c_counter_3_ph_mux_prst),
.pll_c_counter_3_prst(cmu_fpll_pll_c_counter_3_prst),
.pll_cal_status(cmu_fpll_pll_cal_status),
.pll_calibration(cmu_fpll_pll_calibration),
.pll_cmp_buf_dly(cmu_fpll_pll_cmp_buf_dly),
.pll_cp_compensation(cmu_fpll_pll_cp_compensation),
.pll_cp_current_setting(cmu_fpll_pll_cp_current_setting),
.pll_cp_testmode(cmu_fpll_pll_cp_testmode),
.pll_cp_lf_3rd_pole_freq(cmu_fpll_pll_cp_lf_3rd_pole_freq),
.pll_cp_lf_order(cmu_fpll_pll_cp_lf_order),
.pll_ctrl_override_setting(cmu_fpll_pll_ctrl_override_setting),
.pll_ctrl_plniotri_override(cmu_fpll_pll_ctrl_plniotri_override),
.pll_device_variant(cmu_fpll_pll_device_variant),
.pll_dprio_base_addr(cmu_fpll_pll_dprio_base_addr),
.pll_dprio_broadcast_en(cmu_fpll_pll_dprio_broadcast_en),
.pll_dprio_clk_vreg_boost(cmu_fpll_pll_dprio_clk_vreg_boost),
.pll_dprio_cvp_inter_sel(cmu_fpll_pll_dprio_cvp_inter_sel),
.pll_dprio_force_inter_sel(cmu_fpll_pll_dprio_force_inter_sel),
.pll_dprio_fpll_vreg_boost(cmu_fpll_pll_dprio_fpll_vreg_boost),
.pll_dprio_fpll_vreg1_boost(cmu_fpll_pll_dprio_fpll_vreg1_boost),
.pll_dprio_power_iso_en(cmu_fpll_pll_dprio_power_iso_en),
.pll_dprio_status_select(cmu_fpll_pll_dprio_status_select),
.pll_dsm_ecn_bypass(cmu_fpll_pll_dsm_ecn_bypass),
.pll_dsm_ecn_test_en(cmu_fpll_pll_dsm_ecn_test_en),
.pll_dsm_fractional_division(cmu_fpll_pll_dsm_fractional_division_bin),
.pll_dsm_fractional_value_ready(cmu_fpll_pll_dsm_fractional_value_ready),
.pll_dsm_mode(cmu_fpll_pll_dsm_mode),
.pll_dsm_out_sel(cmu_fpll_pll_dsm_out_sel),
.pll_enable(cmu_fpll_pll_enable),
.pll_extra_csr(cmu_fpll_pll_extra_csr),
.pll_fbclk_mux_1(cmu_fpll_pll_fbclk_mux_1),
.pll_fbclk_mux_2(cmu_fpll_pll_fbclk_mux_2),
.pll_iqclk_mux_sel(cmu_fpll_pll_iqclk_mux_sel),
.pll_l_counter(cmu_fpll_pll_l_counter),
.pll_l_counter_bypass(cmu_fpll_pll_l_counter_bypass),
.pll_l_counter_enable(cmu_fpll_pll_l_counter_enable),
.pll_lf_resistance(cmu_fpll_pll_lf_resistance),
.pll_lf_cbig(cmu_fpll_pll_lf_cbig),
.pll_lf_ripplecap(cmu_fpll_pll_lf_ripplecap),
.pll_lock_fltr_cfg(cmu_fpll_pll_lock_fltr_cfg),
.pll_lock_fltr_test(cmu_fpll_pll_lock_fltr_test),
.pll_lpf_rstn_value(cmu_fpll_pll_lpf_rstn_value),
.pll_m_counter(cmu_fpll_pll_m_counter),
.pll_m_counter_coarse_dly(cmu_fpll_pll_m_counter_coarse_dly),
.pll_m_counter_fine_dly(cmu_fpll_pll_m_counter_fine_dly),
.pll_m_counter_in_src(cmu_fpll_pll_m_counter_in_src),
.pll_m_counter_min_tco_enable(cmu_fpll_pll_m_counter_min_tco_enable),
.pll_m_counter_ph_mux_prst(cmu_fpll_pll_m_counter_ph_mux_prst),
.pll_m_counter_prst(cmu_fpll_pll_m_counter_prst),
.pll_n_counter(cmu_fpll_pll_n_counter),
.pll_n_counter_coarse_dly(cmu_fpll_pll_n_counter_coarse_dly),
.pll_n_counter_fine_dly(cmu_fpll_pll_n_counter_fine_dly),
.pll_nreset_invert(cmu_fpll_pll_nreset_invert),
.pll_op_mode(cmu_fpll_pll_op_mode),
.pll_optimal(cmu_fpll_pll_optimal),
.power_mode(cmu_fpll_power_mode),
.pll_powerdown_mode(cmu_fpll_pll_powerdown_mode),
.pll_ppm_clk0_src(cmu_fpll_pll_ppm_clk0_src),
.pll_ppm_clk1_src(cmu_fpll_pll_ppm_clk1_src),
.pll_ref_buf_dly(cmu_fpll_pll_ref_buf_dly),
.pll_rstn_override(cmu_fpll_pll_rstn_override),
.pll_self_reset(cmu_fpll_pll_self_reset),
.pll_cmu_rstn_value(cmu_fpll_pll_cmu_rstn_value),
.silicon_rev(cmu_fpll_silicon_rev),
.pm_speed_grade(cmu_fpll_pm_speed_grade),
.pll_vco_freq_band_0(cmu_fpll_pll_vco_freq_band_0),
.pll_vco_freq_band_1(cmu_fpll_pll_vco_freq_band_1),
.pll_sup_mode(cmu_fpll_pll_sup_mode),
.pll_tclk_mux_en(cmu_fpll_pll_tclk_mux_en),
.pll_tclk_sel(cmu_fpll_pll_tclk_sel),
.pll_test_enable(cmu_fpll_pll_test_enable),
.pll_unlock_fltr_cfg(cmu_fpll_pll_unlock_fltr_cfg),
.pll_vccr_pd_en(cmu_fpll_pll_vccr_pd_en),
.pll_vco_ph0_en(cmu_fpll_pll_vco_ph0_en),
.pll_vco_ph0_value(cmu_fpll_pll_vco_ph0_value),
.pll_vco_ph1_en(cmu_fpll_pll_vco_ph1_en),
.pll_vco_ph1_value(cmu_fpll_pll_vco_ph1_value),
.pll_vco_ph2_en(cmu_fpll_pll_vco_ph2_en),
.pll_vco_ph2_value(cmu_fpll_pll_vco_ph2_value),
.pll_vco_ph3_en(cmu_fpll_pll_vco_ph3_en),
.pll_vco_ph3_value(cmu_fpll_pll_vco_ph3_value),
.xpm_cmu_fpll_core_fpll_refclk_source(cmu_fpll_xpm_cmu_fpll_core_fpll_refclk_source)
) fpll_inst
(
// Input Ports
.avmmaddress(pll_avmm_address[8:0]),
// .avmmclk((cmu_fpll_reconfig_en == "0" && cmu_fpll_dps_en == "false") ? 1'b0 : pll_avmm_clk[0]),
.avmmclk(pll_avmm_clk[0]),
.avmmread(pll_avmm_read[0]),
.avmmrstn(pll_avmm_rstn[0]),
.avmmwrite(pll_avmm_write[0]),
.avmmwritedata(pll_avmm_writedata[7:0]),
.cnt_sel(cntsel),
.csr_bufin(),
.csr_clk(),
.csr_en(),
.csr_in(),
.csr_en_dly(),
.dps_rst_n(~final_phase_reset),
.fbclk_in(fbclk_in),
.iqtxrxclk(iqtxrxclk),
.mdio_dis(),
.num_phase_shifts(3'd1),
.pfden(),
.phase_en(final_phase_en),
.pma_csr_test_dis(),
.refclk(refclk_sel_outclk_wire),
.rst_n(~pll_powerdown_int_gated), //Active low
.scan_mode_n(),
.scan_shift_n(),
.up_dn(updn),
.clk0bad_in(clk0_bad_wire),
.clk1bad_in(clk1_bad_wire),
.lc_to_fpll_refclk(atx_to_fpll_cascade_clk),
// Output Ports
.clk0bad(clkbad[0]),
.clk1bad(clkbad[1]),
.avmmreaddata(pll_avmmreaddata_cmu_fpll[7:0]),
.block_select(pll_blockselect_cmu_fpll[0]),
.clk0(tx_serial_clk),
.clk180(),
.clklow(clklow),
.csr_bufout(),
.csr_out(),
.fbclk_out(fbclk_wire),
.fref(fref),
.hclk_out(pll_pcie_clk),
.iqtxrxclk_out(iqtxrxclk_wire),
.lock(pll_locked),
.outclk({outclk3, outclk2, outclk1, outclk0}),
.phase_done(pre_phase_done),
.pll_cascade_out(fpll_to_fpll_cascade_clk)
);
//-----------------------------------
// instantiate of twentynm_hssi_pma_cgb_master
generate
if (enable_mcgb == 1) begin
twentynm_hssi_pma_cgb_master
#(
.enable_debug_info ( enable_debug_info ),
.silicon_rev ( hssi_pma_cgb_master_silicon_rev ),
.datarate ( hssi_pma_cgb_master_datarate ),
.x1_div_m_sel ( hssi_pma_cgb_master_x1_div_m_sel ),
.prot_mode ( hssi_pma_cgb_master_prot_mode ),
.ser_mode ( hssi_pma_cgb_master_ser_mode ),
.cgb_enable_iqtxrxclk ( hssi_pma_cgb_master_cgb_enable_iqtxrxclk ),
.cgb_power_down ( hssi_pma_cgb_master_cgb_power_down ),
//.master_cgb_clock_control ( hssi_pma_cgb_master_master_cgb_clock_control ),
.observe_cgb_clocks ( hssi_pma_cgb_master_observe_cgb_clocks ),
//.op_mode ( hssi_pma_cgb_master_op_mode ),
//.tx_ucontrol_reset_pcie ( hssi_pma_cgb_master_tx_ucontrol_reset_pcie ),
.vccdreg_output ( hssi_pma_cgb_master_vccdreg_output ),
.input_select ( hssi_pma_cgb_master_input_select ),
.input_select_gen3 ( hssi_pma_cgb_master_input_select_gen3 ),
.bonding_reset_enable ( hssi_pma_cgb_master_bonding_reset_enable ),
.optimal ( hssi_pma_cgb_master_optimal ),
.pcie_gen3_bitwidth ( hssi_pma_cgb_master_pcie_gen3_bitwidth ),
.powerdown_mode ( hssi_pma_cgb_master_powerdown_mode ),
.sup_mode ( hssi_pma_cgb_master_sup_mode ),
.initial_settings ( hssi_pma_cgb_master_initial_settings )
) twentynm_hssi_pma_cgb_master_inst (
.cgb_rstb(~mcgb_rst_input),
//----------------------------------- // \OPEN [FITTER]?
.clk_fpll_b(mcgb_aux_clk2),
// p4:4278541
// Changed default connection from FPLL core to MCGB to port clk_fpll_t
// The aux_clk0 input is now connected to clk_lc_t
// The mcgb tcl package has been modified to default to clk_fpll_t
//.clk_fpll_t(mcgb_aux_clk0),
//.clk_lc_t (tx_serial_clk),
.clk_fpll_t (tx_serial_clk),
.clk_lc_t (mcgb_aux_clk0),
.clk_lc_b (mcgb_aux_clk1),
.clkb_fpll_b( /*unused*/ ),
.clkb_fpll_t( /*unused*/ ),
.clkb_lc_b ( /*unused*/ ),
.clkb_lc_t ( /*unused*/ ),
//-----------------------------------
.cpulse_out_bus(tx_bonding_clocks),
.tx_iqtxrxclk_out(pll_extfb_wire),
.pcie_sw_done(pcie_sw_done),
.pcie_sw(pcie_sw),
//-----------------------------------
.tx_bonding_rstb(1'b1), // \NOTE carried over from slave cgb
//-----------------------------------
.avmmaddress(avmm_address_mcgb),
.avmmclk(avmm_clk_mcgb),
.avmmread(avmm_read_mcgb),
.avmmrstn(avmm_rstn_mcgb),
.avmmwrite(avmm_write_mcgb),
.avmmwritedata(avmm_writedata_mcgb),
.avmmreaddata(avmmreaddata_mcgb),
.blockselect(blockselect_mcgb)
);
end
else begin
assign tx_bonding_clocks = 0;
assign pcie_sw_done = 0;
assign pll_extfb_wire = 0;
end
endgenerate
endmodule
module dps_pulse_ctrl (
input wire clk, // the DPS clock
input wire rst, // active high reset
input wire user_phase_en, // the user's phase_en signal
output reg phase_en // the phase_en signal for the IOPLL atom
);
//-------------------------------------------------------------------------
// States
localparam IDLE = 0, // Idle state: user_phase_en = 0, phase_en = 0
PULSE = 1, // Activate state: phase_en = 1
WAIT = 2; // Wait for user_phase_en to go low
//-------------------------------------------------------------------------
// FSM current and next states
reg [1:0] state, next;
// State update
always @(posedge clk) begin
if (rst) state <= IDLE;
else state <= next;
end
//-------------------------------------------------------------------------
// Next-state and output logic
always @(*) begin
case (state)
IDLE : begin
if (user_phase_en) next = PULSE;
else next = IDLE;
phase_en = 1'b0;
end
PULSE : begin
phase_en = 1'b1;
next = WAIT;
end
WAIT : begin
if (~user_phase_en) next = IDLE;
else next = WAIT;
phase_en = 1'b0;
end
default: begin
next = IDLE;
phase_en = 1'b0;
end
endcase
end
endmodule
/* This module is used to correctly reset the DPS logic.
It snoops the phase_en_in pulse and waits for the phase_done_in
to be asserted by the fpll core. It then generates a phase_reset_out
pulse that resets the DPS logic in the fpll core and finally
generates a phase_done_out to send back to the user. phase_reset_in
generated by the user is OR'ed in with the phase_reset_out generated
by this module.
*/
module dps_reset_gen (
input wire clk, // DPS clock input
input wire phase_reset_in, // active high reset input
input wire phase_en_in, // phase_en input
input wire phase_done_in, // phase_done input
output wire phase_reset_out, // active high reset output
output wire phase_done_out // phase_done output
);
//-------------------------------------------------------------------------
// States
localparam WAIT_PE_PULSE = 4'd0, // Wait for phase_en_in pulse
WAIT_CORE_DONE = 4'd1, // Wait for phase_done_in pulse
GEN_RESET_DELAY = 4'd2, // Wait for N cycle before asserting phase_reset_out
GEN_RESET_1 = 4'd3, // First cycle of phase_reset_out assertion
GEN_RESET_2 = 4'd4, // Second cycle of phase_reset_out assertion
GEN_RESET_DELAY_1 = 4'd5, // Wait for phase_done_in deassertion
GEN_RESET_DELAY_2 = 4'd6, // Wait before deasserting phase_reset_out 1
GEN_RESET_DELAY_3 = 4'd7, // Wait before deasserting phase_reset_out 2
GEN_RESET_DELAY_4 = 4'd8, // Wait before deasserting phase_reset_out 3
GEN_DONE_DELAY = 4'd9, // Wait cycle before asserting phase_done_out 1
GEN_DONE_DELAY_1 = 4'd10, // Wait cycle before asserting phase_done_out 2
GEN_DONE_1 = 4'd11, // First cycle of phase_done_out
GEN_DONE_2 = 4'd12; // Second cycle of phase_done_out
localparam GEN_RESET_DELAY_COUNT = 6'd52; // Number of cycles after DONE assertions to wait before asserting reset
//-------------------------------------------------------------------------
// FSM current and next states
reg [3:0] state, next;
reg [5:0] clock_counter;
wire clock_counter_done;
// Reset Delay Counter
assign clock_counter_done = (clock_counter == GEN_RESET_DELAY_COUNT);
always @(posedge clk) begin
if (phase_reset_in) clock_counter <= 6'd0;
else if (state != GEN_RESET_DELAY) clock_counter <= 6'd0;
else clock_counter <= clock_counter + 6'd1;
end
// State update
always @(posedge clk) begin
if (phase_reset_in) state <= WAIT_PE_PULSE;
else state <= next;
end
//-------------------------------------------------------------------------
// Next-state and output logic
always @(*) begin
case (state)
WAIT_PE_PULSE : begin
if (phase_en_in) next = WAIT_CORE_DONE;
else next = WAIT_PE_PULSE;
end
WAIT_CORE_DONE : begin
if (phase_done_in) next = GEN_RESET_DELAY;
else next = WAIT_CORE_DONE;
end
GEN_RESET_DELAY : begin
if (clock_counter_done) next = GEN_RESET_1;
else next = GEN_RESET_DELAY;
end
GEN_RESET_1 : begin
next = GEN_RESET_2;
end
GEN_RESET_2 : begin
next = GEN_RESET_DELAY_1;
end
GEN_RESET_DELAY_1 : begin
if (!phase_done_in) next = GEN_RESET_DELAY_2;
else next = GEN_RESET_DELAY_1;
end
GEN_RESET_DELAY_2 : begin
next = GEN_RESET_DELAY_3;
end
GEN_RESET_DELAY_3 : begin
next = GEN_RESET_DELAY_4;
end
GEN_RESET_DELAY_4 : begin
next = GEN_DONE_DELAY;
end
GEN_DONE_DELAY : begin
next = GEN_DONE_DELAY_1;
end
GEN_DONE_DELAY_1: begin
next = GEN_DONE_1;
end
GEN_DONE_1 : begin
next = GEN_DONE_2;
end
GEN_DONE_2 : begin
next = WAIT_PE_PULSE;
end
default : begin
next = WAIT_PE_PULSE;
end
endcase
end
assign phase_reset_out = (state == GEN_RESET_1) ||
(state == GEN_RESET_2) ||
(state == GEN_RESET_DELAY_1) ||
(state == GEN_RESET_DELAY_2) ||
(state == GEN_RESET_DELAY_3) ||
(state == GEN_RESET_DELAY_4) ||
phase_reset_in;
assign phase_done_out = (state == GEN_DONE_1) ||
(state == GEN_DONE_2);
endmodule
./twentynm_xcvr_avmm.sv
./alt_xcvr_resync.sv
./altera_xcvr_fpll_a10.sv
./a10_avmm_h.sv
./alt_xcvr_native_avmm_nf.sv
./alt_xcvr_pll_embedded_debug.sv
./alt_xcvr_pll_avmm_csr.sv
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1ps/1ps
module twentynm_xcvr_avmm
#(
//PARAM_LIST_START
parameter avmm_interfaces = 1, //Number of AVMM interfaces required - one for each bonded_lane, PLL, and Master CGB
parameter rcfg_enable = 0, //Enable/disable reconfig interface in the Native PHY or PLL IP
parameter enable_avmm = 1, //Enable/disable AVMM atom instantiation
parameter arbiter_ctrl = "pld", //Calibration request at start-up. Valid values: "uc","pld".
//"uc" =Initial calibration needed at start-up. Internal DPRIO interface is controlled by uC.
//"pld"=Initial calibration is not needed at start-up. Internal DPRIO interface is controlled by PLD.
parameter calibration_en = "disable", //Indicates whether calibration by Hard Nios is enabled or not.Should be set to DISABLE in case if Nios is absent or needs to be bypassed. Valid values: enable, disable
parameter avmm_busy_en = "disable", //Provides a separate interface for determining control of the AVMM bus, and separates its behavior from the avmm_waitreqeust
parameter hip_cal_en = "disable", //Indicates whether HIP is enabled or not. Valid values: disable, enable
parameter cal_done = "cal_done_assert" //Indicates whether calibration is done. This is the start-up value for the corresponding CRAM. THe CRAM is eventually accessed and updated by the Hard uC during calibration. Valid values: cal_done_assert, cal_done_deassert
//PARAM_LIST_END
) (
//PORT_LIST_START
// AVMM slave interface signals (user)
input wire [avmm_interfaces-1 :0] avmm_clk,
input wire [avmm_interfaces-1 :0] avmm_reset,
input wire [avmm_interfaces*8-1 :0] avmm_writedata,
input wire [avmm_interfaces*9-1 :0] avmm_address,
input wire [avmm_interfaces-1 :0] avmm_write,
input wire [avmm_interfaces-1 :0] avmm_read,
output wire [avmm_interfaces*8-1 :0] avmm_readdata,
output wire [avmm_interfaces-1 :0] avmm_waitrequest,
//AVMM interface busy with calibration
output wire [avmm_interfaces-1 :0] avmm_busy,
// Calibration Done
output wire [avmm_interfaces-1 :0] hip_cal_done, //To HIP
output wire [avmm_interfaces-1 :0] pld_cal_done, //To PLD
// Channel/PLL AVMM interface signals (from AVMM atom fanned-out to all the Channel/PLL atoms)
output wire [avmm_interfaces-1 :0] chnl_pll_avmm_clk,
output wire [avmm_interfaces-1 :0] chnl_pll_avmm_rstn,
output wire [avmm_interfaces*8-1 :0] chnl_pll_avmm_writedata, //Internal AVMM interface is 8-bit wide
output wire [avmm_interfaces*9-1 :0] chnl_pll_avmm_address,
output wire [avmm_interfaces-1 :0] chnl_pll_avmm_write,
output wire [avmm_interfaces-1 :0] chnl_pll_avmm_read,
// PMA AVMM signals
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_tx_ser, // TX SER readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_tx_cgb, // TX Slave CGB readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_tx_buf, // TX BUF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_rx_deser, // RX Deser readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_rx_buf, // RX BUF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_rx_sd, // RX SD readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_rx_odi, // RX ODI readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_rx_dfe, // RX DFE readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_cdr_pll, // CDR readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_cdr_refclk_select, // CDR refclk mux readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_pma_adapt, // PMA adaptation readdata (8 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_tx_ser, // TX SER blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_tx_cgb, // TX Slave CGB blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_tx_buf, // TX BUF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_rx_deser, // RX Deser blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_rx_buf, // RX BUF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_rx_sd, // RX SD blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_rx_odi, // RX ODI blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_rx_dfe, // RX DFE blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_cdr_pll, // CDR blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_cdr_refclk_select, // CDR refclk mux blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_pma_adapt, // PMA adaptation blockselect (1 for each lane)
// PCS Channel AVMM signals
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_8g_rx_pcs, // 8G RX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_pipe_gen1_2, // Gen1/2 PIPE readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_8g_tx_pcs, // 8G TX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_10g_rx_pcs, // 10G RX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_10g_tx_pcs, // 10G TX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_gen3_rx_pcs, // GEN3 RX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_pipe_gen3, // GEN3 PIPE readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_gen3_tx_pcs, // GEN3 TX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_krfec_rx_pcs, // KRFEC RX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_krfec_tx_pcs, // KRFEC TX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_fifo_rx_pcs, // FIFO RX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_fifo_tx_pcs, // FIFO TX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_rx_pcs_pld_if, // RX PCS PLD IF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_com_pcs_pld_if, // COM PCS PLD IF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_tx_pcs_pld_if, // TX PCS PLD IF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_rx_pcs_pma_if, // RX PCS PMA IF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_com_pcs_pma_if, // COm PCS PMA IF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_tx_pcs_pma_if, // TX PCS PMA IF readdata (8 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_8g_rx_pcs, // 8G RX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_pipe_gen1_2, // Gen1/2 PIPE blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_8g_tx_pcs, // 8G TX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_10g_rx_pcs, // 10G RX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_10g_tx_pcs, // 10G TX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_gen3_rx_pcs, // GEN3 RX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_pipe_gen3, // GEN3 PIPE blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_gen3_tx_pcs, // GEN3 TX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_krfec_rx_pcs, // KRFEC RX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_krfec_tx_pcs, // KRFEC TX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_fifo_rx_pcs, // FIFO RX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_fifo_tx_pcs, // FIFO TX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_rx_pcs_pld_if, // RX PCS PLD IF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_com_pcs_pld_if, // COM PCS PLD IF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_tx_pcs_pld_if, // TX PCS PLD IF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_rx_pcs_pma_if, // RX PCS PMA IF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_com_pcs_pma_if, // COM PCS PMA IF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_tx_pcs_pma_if, // TX PCS PMA IF blockselect (1 for each lane)
// PLL AVMM signals
input wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_lc_pll, // LC PLL readdata (8 for each PLL)
input wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_lc_refclk_select, // LC Refclk Select Mux readdata (8 for each PLL)
input wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_cgb_master, // Master CGB readdata (8 for each PLL)
input wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_cmu_fpll, // CMU-FPLL readdata (8 for each PLL)
input wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_cmu_fpll_refclk_select, // CMU-FPLL refclk mux readdata (8 for each PLL)
// CDR Tx PLL will connect to pma_avmmreaddata_cdr_pll and pma_avmmreaddata_cdr_refclk_select
input wire [avmm_interfaces-1 :0] pll_blockselect_lc_pll, // LC PLL blockselect (1 for each PLL)
input wire [avmm_interfaces-1 :0] pll_blockselect_lc_refclk_select, // LC Refclk Select Mux blockselect (1 for each PLL)
input wire [avmm_interfaces-1 :0] pll_blockselect_cgb_master, // Master CGB blockselect (1 for each PLL)
input wire [avmm_interfaces-1 :0] pll_blockselect_cmu_fpll, // CMU-FPLL blockselect (1 for each PLL)
input wire [avmm_interfaces-1 :0] pll_blockselect_cmu_fpll_refclk_select // CMU-FPLL refclk mux blockselect (1 for each PLL)
// CDR Tx PLL will connect to pma_blockselect_cdr_pll and pma_blockselect_cdr_refclk_select
//PORT_LIST_END
);
wire [avmm_interfaces-1 :0] avmm_reset_sync;
reg [avmm_interfaces-1 :0] avmm_read_r ={avmm_interfaces{1'b0}};
wire [avmm_interfaces-1 :0] avmm_waitrequest_read;
wire [avmm_interfaces-1 :0] avmm_waitrequest_write;
reg [avmm_interfaces-1 :0] avmm_waitrequest_write_int;
reg [avmm_interfaces*3-1:0] avmm_read_cycles_cnt;
reg [avmm_interfaces-1 :0] avmm_busy_r1 = {avmm_interfaces{1'b0}};
reg [avmm_interfaces-1 :0] avmm_busy_r2 = {avmm_interfaces{1'b0}};
wire [avmm_interfaces-1 :0] avmm_request;
localparam calibration_type = "one_time"; //Not used for now. Virtual attribute with no associated BCM settings. Intended to be set by the IP based on the chosen calibration option and used only by the AVMM sim model to decide whether to release the AVMM interface to the user after start-up or hold on to it until the user request according to the hardware implementation. Valid values: one_time, continuous. Export as parameter if needed.
localparam AVMM_READ_LATENCY = 3'b011; //Read latency in the hardware
localparam AVMM_READ_CYCLES_CNT_RST_VAL = 3'b111; //Reset value of avmm_read_cycles_cnt. Non-zero and >AVMM_READ_LATENCY for avmm_waitrequest to assert during reset
localparam ARBITER_BASE_ADDR = 9'h000; //AVMM<->uC arbiter base address
generate begin
genvar ig;
genvar jg;
for(ig=0;ig<avmm_interfaces;ig=ig+1) begin : avmm_atom_insts
// Size of blockselect bus as defined in the AVMM atom = Number of HSSI atoms + some buffer = 70
wire [70-1:0] chnl_pll_avmm_blockselect;
wire [7:0] chnl_pll_avmm_readdata [0:(70-1)];
wire [70*8-1:0] chnl_pll_avmm_readdatabus;
// Assign the incoming avmmreaddata and blockselect signals from all the atoms to
// the readdata bus and blockselect bus of the AVMM atom respectively
for(jg = 0; jg < 70; jg = jg + 1) begin:avmm_assigns
assign chnl_pll_avmm_readdatabus[jg*8+:8] = chnl_pll_avmm_readdata[jg];
assign {chnl_pll_avmm_readdata[jg],chnl_pll_avmm_blockselect[jg]} =
// TX PMA connections
(jg == 0) ? {pma_avmmreaddata_tx_ser [ig*8+:8],pma_blockselect_tx_ser [ig]} :
(jg == 1) ? {pma_avmmreaddata_tx_cgb [ig*8+:8],pma_blockselect_tx_cgb [ig]} :
(jg == 2) ? {pma_avmmreaddata_tx_buf [ig*8+:8],pma_blockselect_tx_buf [ig]} :
// RX PMA (includes CDR) connections
(jg == 3) ? {pma_avmmreaddata_rx_deser [ig*8+:8],pma_blockselect_rx_deser [ig]} :
(jg == 4) ? {pma_avmmreaddata_rx_buf [ig*8+:8],pma_blockselect_rx_buf [ig]} :
(jg == 5) ? {pma_avmmreaddata_rx_sd [ig*8+:8],pma_blockselect_rx_sd [ig]} :
(jg == 6) ? {pma_avmmreaddata_rx_odi [ig*8+:8],pma_blockselect_rx_odi [ig]} :
(jg == 7) ? {pma_avmmreaddata_rx_dfe [ig*8+:8],pma_blockselect_rx_dfe [ig]} :
(jg == 8) ? {pma_avmmreaddata_cdr_pll [ig*8+:8],pma_blockselect_cdr_pll [ig]} :
(jg == 9) ? {pma_avmmreaddata_cdr_refclk_select [ig*8+:8],pma_blockselect_cdr_refclk_select [ig]} :
(jg == 10) ? {pma_avmmreaddata_pma_adapt [ig*8+:8],pma_blockselect_pma_adapt [ig]} :
// PCS connections
(jg == 20) ? {pcs_avmmreaddata_8g_rx_pcs [ig*8+:8],pcs_blockselect_8g_rx_pcs [ig]} :
(jg == 21) ? {pcs_avmmreaddata_pipe_gen1_2 [ig*8+:8],pcs_blockselect_pipe_gen1_2 [ig]} :
(jg == 22) ? {pcs_avmmreaddata_8g_tx_pcs [ig*8+:8],pcs_blockselect_8g_tx_pcs [ig]} :
(jg == 23) ? {pcs_avmmreaddata_10g_rx_pcs [ig*8+:8],pcs_blockselect_10g_rx_pcs [ig]} :
(jg == 24) ? {pcs_avmmreaddata_10g_tx_pcs [ig*8+:8],pcs_blockselect_10g_tx_pcs [ig]} :
(jg == 25) ? {pcs_avmmreaddata_gen3_rx_pcs [ig*8+:8],pcs_blockselect_gen3_rx_pcs [ig]} :
(jg == 26) ? {pcs_avmmreaddata_pipe_gen3 [ig*8+:8],pcs_blockselect_pipe_gen3 [ig]} :
(jg == 27) ? {pcs_avmmreaddata_gen3_tx_pcs [ig*8+:8],pcs_blockselect_gen3_tx_pcs [ig]} :
(jg == 28) ? {pcs_avmmreaddata_krfec_rx_pcs [ig*8+:8],pcs_blockselect_krfec_rx_pcs [ig]} :
(jg == 29) ? {pcs_avmmreaddata_krfec_tx_pcs [ig*8+:8],pcs_blockselect_krfec_tx_pcs [ig]} :
(jg == 30) ? {pcs_avmmreaddata_fifo_rx_pcs [ig*8+:8],pcs_blockselect_fifo_rx_pcs [ig]} :
(jg == 31) ? {pcs_avmmreaddata_fifo_tx_pcs [ig*8+:8],pcs_blockselect_fifo_tx_pcs [ig]} :
(jg == 32) ? {pcs_avmmreaddata_rx_pcs_pld_if [ig*8+:8],pcs_blockselect_rx_pcs_pld_if [ig]} :
(jg == 33) ? {pcs_avmmreaddata_com_pcs_pld_if [ig*8+:8],pcs_blockselect_com_pcs_pld_if [ig]} :
(jg == 34) ? {pcs_avmmreaddata_tx_pcs_pld_if [ig*8+:8],pcs_blockselect_tx_pcs_pld_if [ig]} :
(jg == 35) ? {pcs_avmmreaddata_rx_pcs_pma_if [ig*8+:8],pcs_blockselect_rx_pcs_pma_if [ig]} :
(jg == 36) ? {pcs_avmmreaddata_com_pcs_pma_if [ig*8+:8],pcs_blockselect_com_pcs_pma_if [ig]} :
(jg == 37) ? {pcs_avmmreaddata_tx_pcs_pma_if [ig*8+:8],pcs_blockselect_tx_pcs_pma_if [ig]} :
// PLL connections
(jg == 50) ? {pll_avmmreaddata_lc_pll [ig*8+:8],pll_blockselect_lc_pll [ig]} :
(jg == 51) ? {pll_avmmreaddata_lc_refclk_select [ig*8+:8],pll_blockselect_lc_refclk_select [ig]} :
(jg == 52) ? {pll_avmmreaddata_cgb_master [ig*8+:8],pll_blockselect_cgb_master [ig]} :
(jg == 53) ? {pll_avmmreaddata_cmu_fpll [ig*8+:8],pll_blockselect_cmu_fpll [ig]} :
(jg == 54) ? {pll_avmmreaddata_cmu_fpll_refclk_select [ig*8+:8],pll_blockselect_cmu_fpll_refclk_select [ig]} :
{8'd0,1'b0}; //unused indices
end //avmm_assigns
if (enable_avmm == 1) begin
// AVMM atom
twentynm_hssi_avmm_if
#(
.arbiter_ctrl (arbiter_ctrl ),
.calibration_en (calibration_en ),
.hip_cal_en (hip_cal_en ),
.cal_done (cal_done ),
.calibration_type (calibration_type )
) twentynm_hssi_avmm_if_inst
(
.avmmrstn (1'b1 ), // Tie-off
.avmmclk (avmm_clk [ig] ),
.avmmwrite (avmm_write [ig] ),
.avmmread (avmm_read [ig] ),
.avmmaddress (avmm_address [ig*9+:9] ),
.avmmwritedata (avmm_writedata [ig*8+:8] ),
.avmmreaddata (avmm_readdata [ig*8+:8] ),
.avmmbusy (avmm_busy [ig] ),
.avmmrequest (avmm_request [ig] ),
.hipcaldone (hip_cal_done [ig] ),
.pldcaldone (pld_cal_done [ig] ),
.clkchnl (chnl_pll_avmm_clk [ig] ),
.rstnchnl (chnl_pll_avmm_rstn [ig] ),
.writechnl (chnl_pll_avmm_write [ig] ),
.readchnl (chnl_pll_avmm_read [ig] ),
.regaddrchnl (chnl_pll_avmm_address [ig*9+:9] ),
.writedatachnl (chnl_pll_avmm_writedata [ig*8+:8] ),
.readdatachnl (chnl_pll_avmm_readdatabus ),
.blockselect (chnl_pll_avmm_blockselect ),
.scanmoden (1'b1 ),
.scanshiftn (1'b1 ),
.avmmreservedin (/*unused*/ ),
.avmmreservedout (/*unused*/ )
);
//***********************************************************************************
//
// Generate avmm_waitrequest
//
//***********************************************************************************
// AVMM slave in hardware:
// avmm_write -> variable latency
// arbiter register = multi-cycle latency with avmm_busy asserted
// other registers = fixed 0-cycle latency
// avmm_read -> fixed 3-cycle latency
// Synchronize the falling edge of incoming reconfig reset
// Waitrequest is asserted during reset
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH(2), // Number of flip-flops for retiming
.WIDTH (1), // Number of bits to resync
.INIT_VALUE (1'b1)
) avmm_reset_sync_inst (
.clk (avmm_clk[ig] ),
.reset (avmm_reset[ig] ),
.d (1'b0 ),
.q (avmm_reset_sync[ig])
);
//***********************************************************************************
//**************** Generate waitrequest for read operation *************************
// Register avmm_read
always @ (posedge avmm_clk[ig] or posedge avmm_reset_sync[ig]) begin
if (avmm_reset_sync[ig]) begin
avmm_read_r[ig] <= 1'b0;
end else begin
avmm_read_r[ig] <= avmm_read[ig];
end
end
// Pipeline registers for avmm_busy
// Do not reset these registers so they can track avmm_busy accurately
always @ (posedge avmm_clk[ig]) begin
avmm_busy_r1[ig] <= avmm_busy[ig];
avmm_busy_r2[ig] <= avmm_busy_r1[ig];
end
// Read counter
// - reset the counter to a value between 0 and AVMM_READ_LATENCY so that waitrequest is asserted during reset
// - after reset de-assertion, flip the counter back to 0 for waitrequest to be de-asserted
// - increment the count:
// - when avmm_read is asserted
// - when avmm_busy_r1 is not asserted => the read operation immediately after recalibration request is served after
// avmm_busy_r1 is deasserted
// - until AVMM_READ_LATENCY count
always @ (posedge avmm_clk[ig] or posedge avmm_reset_sync[ig]) begin
if (avmm_reset_sync[ig])
avmm_read_cycles_cnt[ig*3+:3] <= AVMM_READ_CYCLES_CNT_RST_VAL;
else begin
if (~avmm_busy_r1[ig] & avmm_read[ig] & (avmm_read_cycles_cnt[ig*3+:3] == 3'b000))
avmm_read_cycles_cnt[ig*3+:3] <= avmm_read_cycles_cnt[ig*3+:3] + 1'b1;
else if (~avmm_busy_r1[ig] & (avmm_read_cycles_cnt[ig*3+:3] > 3'b000 && avmm_read_cycles_cnt[ig*3+:3] <= AVMM_READ_LATENCY))
avmm_read_cycles_cnt[ig*3+:3] <= avmm_read_cycles_cnt[ig*3+:3] + 1'b1;
else
avmm_read_cycles_cnt[ig*3+:3] <= 3'b000;
end
end
// waitrequest for read
assign avmm_waitrequest_read[ig] = (avmm_read[ig] & !avmm_read_r[ig]) | //when avmm_read is asserted
(avmm_read_cycles_cnt[ig*3+:3] > 3'b000 && avmm_read_cycles_cnt[ig*3+:3] <= AVMM_READ_LATENCY) | //during current read and possible back-to-back reads wihtout avmm_read being deasserted
(avmm_read_cycles_cnt[ig*3+:3] == AVMM_READ_CYCLES_CNT_RST_VAL) ; //during reset
//***********************************************************************************
//**************** Generate waitrequest for write operation ************************
// Logic enabled only when the calibration feature is enabled
// Assertion - very next clock cycle after receiving the arbiter register write request -> 0x0[0] = 1'b1.
// - this write indicates that the user wants to give-up the AVMM interface so that the Microcontroller can perform calibration (recalibration or adaptive).
// Deassertion - two clock cycles after avmm_busy is deasserted
if(calibration_en == "enable") begin : g_cal_en_wreq
always @ (posedge avmm_clk[ig] or posedge avmm_reset_sync[ig]) begin
if (avmm_reset_sync[ig])
avmm_waitrequest_write_int[ig] <= 1'b0;
else begin
if ((avmm_write[ig] == 1'b1) && (avmm_address[ig*9+:9] == ARBITER_BASE_ADDR) && (avmm_writedata[ig*8] == 1'b1) && (!avmm_waitrequest_write[ig]))
avmm_waitrequest_write_int[ig] <= 1'b1;
else if (avmm_waitrequest_write_int[ig] & ~avmm_busy_r1[ig] & ~avmm_busy_r2[ig])
avmm_waitrequest_write_int[ig] <= 1'b1;
else
avmm_waitrequest_write_int[ig] <= avmm_busy_r1[ig];
end
end
assign avmm_waitrequest_write[ig] = avmm_waitrequest_write_int[ig];
end else begin : g_cal_dis_wreq
assign avmm_waitrequest_write[ig] = 1'b0;
end
//***********************************************************************************
// user waitrequest
// case: 250182
// Allow de-coupling the avmm_busy from the avmm waitrequest to support nios and CPU based
// reconfiguration sequences and masters. This will address issues with returning the
// avmm bus back to the user, which in turn, due to the long waitrequest, causes the system
// to timeout.
if ( avmm_busy_en == "enable" ) begin
assign avmm_waitrequest[ig] = avmm_waitrequest_read[ig];
end else begin
assign avmm_waitrequest[ig] = avmm_waitrequest_write[ig] | avmm_waitrequest_read[ig];
end
//***************************************************************************************************************
//
// Generate avmm_request
//
// When Tx term resistance calibration is enabled in continuous mode, the usemodel
// is that the Nios will hold the AVMM interface until requested by the user.
// The user will request the AVMM interface, perform reconfiguration, and return
// the interface back to the Nios to continue with the adaptive calibration.
// Offset 0x0:
// bit 0 = arbiter control (0=pld, 1=uc)
// bit 1 = cal_done status (0=not done, 1=done) --> updated by Nios. Should not be touched by the user.
//
// If reconfig interface is enabled in the PHY GUI:
// * if calibration is enabled and continuous mode is set
// Steps to access AVMM interface
// 1. User requests the AVMM interface -> offset=0x0, RMW bit 0 = 0
// --> Internally, this module generates avmm_request signal that maps to a status register bit in hardware
// --> Nios reads this bit if the continuous calibration is enabled and gives up the AVMM interface
// 2. When waitrequest is de-asserted, user performs reconfiguration
// 3. User requests recalibration and thereby give up the AVMM interface to Nios
// -> offset=0x0, RMW bit 0 = 1
// * if either calibration is disabled or continuous mode is not set
// tie-off avmm_request to 1'b1 => park the avmm_request bit to always be in the user "request" mode
//
// If reconfig interface is NOT enabled in the PHY GUI:
// tie-off avmm_request to 1'b0 => park the avmm_request bit to always be in the "not request" mode => allow Nios to do adaptive calibration
//***************************************************************************************************************
// Assertion - very next clock cycle after receiving the arbiter register write request -> 0x0[0] = 1'b0
// - this write indicates that the user wants to get the AVMM interface from the Microcontroller so that the user can perform reconfiguration.
// Deassertion - after avmm_busy goes low
// - this indicates that the user has received the AVMM interface
if(rcfg_enable == 1) begin: g_rcfg_en
if ((calibration_en == "enable") && (calibration_type == "continuous")) begin : g_cal_en_req
reg [avmm_interfaces-1 :0] avmm_request_int = 1'b0;
always @ (posedge avmm_clk[ig] or posedge avmm_reset_sync[ig]) begin
if (avmm_reset_sync[ig])
avmm_request_int[ig] <= 1'b0;
else begin
if ((avmm_write[ig] == 1'b1) && (avmm_address[ig*9+:9] == ARBITER_BASE_ADDR) && (avmm_writedata[ig*8] == 1'b0) && (!avmm_request_int[ig]))
avmm_request_int[ig] <= 1'b1;
else if (~avmm_busy_r2[ig])
avmm_request_int[ig] <= 1'b0;
end
end
assign avmm_request[ig] = avmm_request_int[ig];
end else begin: g_cal_dis_req
//Park the interface request favoring the user AVMM
assign avmm_request[ig] = 1'b1;
end
end else begin : g_rcfg_dis
//Park the interface request favoring the Nios if reconfiguration is not enabled by the user
assign avmm_request[ig] = 1'b0;
end
end else begin //if !(enable_avmm), tie-off AVMM atom outputs
assign chnl_pll_avmm_clk [ig] = 1'b0;
assign chnl_pll_avmm_rstn [ig] = 1'b1;
assign chnl_pll_avmm_writedata [ig*8+:8] = 8'd0;
assign chnl_pll_avmm_address [ig*9+:9] = 9'd0;
assign chnl_pll_avmm_write [ig] = 1'b0;
assign chnl_pll_avmm_read [ig] = 1'b0;
end
end
end
endgenerate
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1 ps/1 ps
package a10_avmm_h;
// localparam to define unused bus
localparam RD_UNUSED = 8'h0;
// localparams for common capability registers
localparam A10_XR_ADDR_ID_0 = 9'h0;
localparam A10_XR_ADDR_ID_1 = 9'h1;
localparam A10_XR_ADDR_ID_2 = 9'h2;
localparam A10_XR_ADDR_ID_3 = 9'h3;
localparam A10_XR_ADDR_STATUS_EN = 9'h4;
localparam A10_XR_ADDR_CONTROL_EN = 9'h5;
// Reserve Address 9'h6 to 9'hF for common capablities
// native phy capability
localparam A10_XR_ADDR_NAT_CHNLS = 9'h10;
localparam A10_XR_ADDR_NAT_CHNL_NUM = 9'h11;
localparam A10_XR_ADDR_NAT_DUPLEX = 9'h12;
localparam A10_XR_ADDR_NAT_PRBS_EN = 9'h13;
localparam A10_XR_ADDR_NAT_ODI_EN = 9'h14;
// pll ip capability
localparam A10_XR_ADDR_PLL_MCGB_EN = 9'h10;
// localparams for csr for pll locked and cal busy
localparam A10_XR_ADDR_GP_PLL_LOCK = 9'h80;
localparam A10_XR_OFFSET_GP_LOCK = 0;
localparam A10_XR_OFFSET_GP_CAL_BUSY = 1;
localparam A10_XR_OFFSET_GP_AVMM_BUSY = 2;
localparam A10_XR_OFFSET_LOCK_UNUSED = 3;
localparam A10_XR_LOCK_UNUSED_LEN = 5;
// localparams for pll powerdown
localparam A10_XR_ADDR_GP_PLL_RST = 9'hE0;
localparam A10_XR_OFFSET_PLL_RST = 0;
localparam A10_XR_OFFSET_PLL_RST_OVR = 1;
localparam A10_XR_OFFSET_PLL_RST_UNUSED = 2;
localparam A10_XR_PLL_RST_UNUSED_LEN = 6;
// localparams for csr for lock to ref and lock to data
localparam A10_XR_ADDR_GP_RD_LTR = 9'h80;
localparam A10_XR_OFFSET_RD_LTD = 0;
localparam A10_XR_OFFSET_RD_LTR = 1;
localparam A10_XR_OFFSET_LTR_UNUSED = 2;
localparam A10_XR_LTR_UNUSED_LEN = 6;
// localparams for csr for cal busy
localparam A10_XR_ADDR_GP_CAL_BUSY = 9'h81;
localparam A10_XR_OFFSET_TX_CAL_BUSY = 0;
localparam A10_XR_OFFSET_RX_CAL_BUSY = 1;
localparam A10_XR_OFFSET_AVMM_BUSY = 2;
localparam A10_XR_OFFSET_CAL_DUMMY = 3;
localparam A10_XR_OFFSET_TX_CAL_MASK = 4;
localparam A10_XR_OFFSET_RX_CAL_MASK = 5;
localparam A10_XR_OFFSET_CAL_UNUSED = 6;
localparam A10_XR_CAL_UNUSED_LEN = 2;
// localparams for setting lock to ref and lock to data
localparam A10_XR_ADDR_GP_SET_LTR = 9'hE0;
localparam A10_XR_OFFSET_SET_LTD = 0;
localparam A10_XR_OFFSET_SET_LTR = 1;
localparam A10_XR_OFFSET_SET_LTD_OVR = 2;
localparam A10_XR_OFFSET_SET_LTR_OVR = 3;
localparam A10_XR_OFFSET_SET_LTR_UNUSED = 4;
localparam A10_XR_SET_LTR_UNUSED_LEN = 4;
// localparams for setting loopback
localparam A10_XR_ADDR_GP_LPBK = 9'hE1;
localparam A10_XR_OFFSET_LPBK = 0;
localparam A10_XR_OFFSET_LPBK_UNUSED = 1;
localparam A10_XR_LPBK_UNUSED_LEN = 7;
// localparams for setting channel resets
localparam A10_XR_ADDR_CHNL_RESET = 9'hE2;
localparam A10_XR_OFFSET_RX_ANA = 0;
localparam A10_XR_OFFSET_RX_DIG = 1;
localparam A10_XR_OFFSET_TX_ANA = 2;
localparam A10_XR_OFFSET_TX_DIG = 3;
localparam A10_XR_OFFSET_RX_ANA_OVR = 4;
localparam A10_XR_OFFSET_RX_DIG_OVR = 5;
localparam A10_XR_OFFSET_TX_ANA_OVR = 6;
localparam A10_XR_OFFSET_TX_DIG_OVR = 7;
// localparams for prbs addresses
localparam A10_XR_ADDR_PRBS_CTRL = 9'h100;
localparam A10_XR_ADDR_PRBS_ERR_0 = 9'h101;
localparam A10_XR_ADDR_PRBS_ERR_1 = 9'h102;
localparam A10_XR_ADDR_PRBS_ERR_2 = 9'h103;
localparam A10_XR_ADDR_PRBS_ERR_3 = 9'h104;
localparam A10_XR_ADDR_PRBS_ERR_4 = 9'h105;
localparam A10_XR_ADDR_PRBS_ERR_5 = 9'h106;
localparam A10_XR_ADDR_PRBS_ERR_6 = 9'h107;
localparam A10_XR_ADDR_PRBS_BIT_0 = 9'h10D;
localparam A10_XR_ADDR_PRBS_BIT_1 = 9'h10E;
localparam A10_XR_ADDR_PRBS_BIT_2 = 9'h10F;
localparam A10_XR_ADDR_PRBS_BIT_3 = 9'h110;
localparam A10_XR_ADDR_PRBS_BIT_4 = 9'h111;
localparam A10_XR_ADDR_PRBS_BIT_5 = 9'h112;
localparam A10_XR_ADDR_PRBS_BIT_6 = 9'h113;
// localparams for prbs bit offsets
localparam A10_XR_OFFSET_PRBS_EN = 0;
localparam A10_XR_OFFSET_PRBS_RESET = 1;
localparam A10_XR_OFFSET_PRBS_SNAP = 2;
localparam A10_XR_OFFSET_PRBS_DONE = 3;
localparam A10_XR_OFFSET_PRBS_UNUSED = 4;
localparam A10_XR_PRBS_UNUSED_LEN = 4;
// localparams for odi addresses
localparam A10_XR_ADDR_ODI_CTRL = 9'h120;
localparam A10_XR_ADDR_ODI_ERR_0 = 9'h121;
localparam A10_XR_ADDR_ODI_ERR_1 = 9'h122;
localparam A10_XR_ADDR_ODI_ERR_2 = 9'h123;
localparam A10_XR_ADDR_ODI_ERR_3 = 9'h124;
localparam A10_XR_ADDR_ODI_ERR_4 = 9'h125;
localparam A10_XR_ADDR_ODI_ERR_5 = 9'h126;
localparam A10_XR_ADDR_ODI_ERR_6 = 9'h127;
localparam A10_XR_ADDR_ODI_BIT_0 = 9'h12D;
localparam A10_XR_ADDR_ODI_BIT_1 = 9'h12E;
localparam A10_XR_ADDR_ODI_BIT_2 = 9'h12F;
localparam A10_XR_ADDR_ODI_BIT_3 = 9'h130;
localparam A10_XR_ADDR_ODI_BIT_4 = 9'h131;
localparam A10_XR_ADDR_ODI_BIT_5 = 9'h132;
localparam A10_XR_ADDR_ODI_BIT_6 = 9'h133;
// localparams for odi bit offsets
localparam A10_XR_OFFSET_ODI_EN = 0;
localparam A10_XR_OFFSET_ODI_RESET = 1;
localparam A10_XR_OFFSET_ODI_SNAP = 2;
localparam A10_XR_OFFSET_ODI_DONE = 3;
localparam A10_XR_OFFSET_ODI_UNUSED = 4;
localparam A10_XR_ODI_UNUSED_LEN = 4;
// localparams for embedded reconfig addresses
// Control reg and offsets
localparam A10_XR_ADDR_EMBED_RCFG_CTRL = 9'h140;
localparam A10_XR_OFFSET_EMBED_RCFG_CFG_SEL = 0;
localparam A10_XR_EMBED_RCFG_CFG_SEL_LEN = 6; //bits [5:0] are alloted for cfg_sel even though GUI currently only supports upto 8 profiles.
localparam A10_XR_OFFSET_EMBED_RCFG_BCAST_EN = 6;
localparam A10_XR_OFFSET_EMBED_RCFG_CFG_LOAD = 7;
// Status reg and offsets
localparam A10_XR_ADDR_EMBED_RCFG_STATUS = 9'h141;
localparam A10_XR_OFFSET_EMBED_RCFG_STRM_BUSY = 0;
endpackage
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// Clocked priority encoder with state
//
// On each clock cycle, updates state to show which request is granted.
// Most recent grant holder is always the highest priority.
// If current grant holder is not making a request, while others are,
// then new grant holder is always the requester with lowest bit number.
// If no requests, current grant holder retains grant state
// $Header$
`timescale 1 ns / 1 ns
module alt_xcvr_arbiter #(
parameter width = 2
) (
input wire clock,
input wire [width-1:0] req, // req[n] requests for this cycle
output reg [width-1:0] grant // grant[n] means requester n is grantee in this cycle
);
wire idle; // idle when no requests
wire [width-1:0] keep; // keep[n] means requester n is requesting, and already has the grant
// Note: current grantee is always highest priority for next grant
wire [width-1:0] take; // take[n] means requester n is requesting, and there are no higher-priority requests
assign keep = req & grant; // current grantee is always highest priority for next grant
assign idle = ~| req; // idle when no requests
initial begin
grant = 0;
end
// grant next state depends on current grant and take priority
always @(posedge clock) begin
grant <=
// synthesis translate_off
(grant === {width{1'bx}})? {width{1'b0}} :
// synthesis translate_on
keep // if current grantee is requesting, gets to keep grant
| ({width{idle}} & grant) // if no requests, grant state remains unchanged
| take; // take applies only if current grantee is not requesting
end
// 'take' bus encodes priority. Request with lowest bit number wins when current grantee not requesting
assign take[0] = req[0]
& (~| (keep & ({width{1'b1}} << 1))); // no 'keep' from lower-priority inputs
genvar i;
generate
for (i=1; i < width; i = i + 1) begin : arb
assign take[i] = req[i]
& (~| (keep & ({width{1'b1}} << (i+1)))) // no 'keep' from lower-priority inputs
& (~| (req & {i{1'b1}})); // no 'req' from higher-priority inputs
end
endgenerate
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1 ps/1 ps
module alt_xcvr_native_avmm_csr #(
parameter dbg_capability_reg_enable = 0,
parameter dbg_user_identifier = 0,
parameter dbg_stat_soft_logic_enable = 0,
parameter dbg_ctrl_soft_logic_enable = 0,
parameter channels = 1,
parameter channel_num = 1,
parameter duplex_mode = 3,
parameter dbg_prbs_soft_logic_enable = 0,
parameter dbg_odi_soft_logic_enable = 0,
parameter rcfg_emb_strm_enable = 0,
parameter rcfg_emb_strm_cfg_sel_width = 2
) (
// avmm signals
input avmm_clk,
input avmm_reset,
input [8:0] avmm_address,
input [7:0] avmm_writedata,
input avmm_write,
input avmm_read,
output reg [7:0] avmm_readdata,
output avmm_waitrequest,
// prbs ctrl signal
input [49:0] prbs_err,
input [49:0] prbs_bit,
input prbs_done,
output prbs_count_en,
output prbs_snap,
output prbs_reset,
// odi ctrl signals
input [49:0] odi_bit,
input [49:0] odi_err,
input odi_done,
output odi_count_en,
output odi_reset,
output odi_snap,
// input status signals from the channel
input rx_is_lockedtodata,
input rx_is_lockedtoref,
input tx_cal_busy,
input rx_cal_busy,
input avmm_busy,
// input control signals
input rx_prbs_err_clr,
input set_rx_locktoref,
input set_rx_locktodata,
input serial_loopback,
input rx_analogreset,
input rx_digitalreset,
input tx_analogreset,
input tx_digitalreset,
// embedded reconfigsignals
input rcfg_emb_strm_busy,
input rcfg_emb_strm_chan_sel,
output [rcfg_emb_strm_cfg_sel_width-1:0] rcfg_emb_strm_cfg_sel,
output rcfg_emb_strm_bcast_en,
output rcfg_emb_strm_cfg_load,
// output control signals to the channel
output csr_set_lock_to_data,
output csr_set_lock_to_ref,
output csr_en_loopback,
output csr_rx_analogreset,
output csr_rx_digitalreset,
output csr_tx_analogreset,
output csr_tx_digitalreset,
output csr_tx_cal_busy_mask,
output csr_rx_cal_busy_mask
);
// Import package with parameters for the soft addresses and offsets
import a10_avmm_h::*;
// Reg for generating waitrequest and data valid
reg avmm_valid;
/**********************************************************************/
// wires and bus declaration
/**********************************************************************/
wire [7:0] rd_channel;
wire [7:0] rd_channel_num;
wire [7:0] rd_duplex;
wire [7:0] rd_system_id;
wire [7:0] rd_prbs_en;
wire [7:0] rd_odi_en;
wire [7:0] rd_status_en;
wire [7:0] rd_control_en;
wire [7:0] rd_prbs_ctrl;
wire [7:0] rd_odi_ctrl;
wire [7:0] rd_ltr_status;
wire [7:0] rd_set_ltr;
wire [7:0] rd_loopback;
wire [7:0] rd_cal_busy;
wire [7:0] rd_chnl_reset;
wire [7:0] rd_rcfg_emb_ctrl;
wire [7:0] rd_rcfg_emb_status;
wire [49:0] rd_prbs_err;
wire [49:0] rd_prbs_bit;
wire [49:0] rd_odi_err;
wire [49:0] rd_odi_bit;
/**********************************************************************/
//generate waitrequest
/**********************************************************************/
assign avmm_waitrequest = (~avmm_valid & avmm_read);
/**********************************************************************/
// soft CSRs for embedded debug
/**********************************************************************/
always@(posedge avmm_clk) begin
if(~avmm_read) begin
avmm_valid <= 1'b0;
avmm_readdata <= RD_UNUSED;
end else begin
avmm_valid <= avmm_waitrequest;
case(avmm_address)
// Address for Capabilities
A10_XR_ADDR_ID_0: avmm_readdata <= rd_system_id;
A10_XR_ADDR_STATUS_EN: avmm_readdata <= rd_status_en;
A10_XR_ADDR_CONTROL_EN: avmm_readdata <= rd_control_en;
A10_XR_ADDR_NAT_CHNLS: avmm_readdata <= rd_channel;
A10_XR_ADDR_NAT_CHNL_NUM: avmm_readdata <= rd_channel_num;
A10_XR_ADDR_NAT_DUPLEX: avmm_readdata <= rd_duplex;
A10_XR_ADDR_NAT_PRBS_EN: avmm_readdata <= rd_prbs_en;
A10_XR_ADDR_NAT_ODI_EN: avmm_readdata <= rd_odi_en;
// Addresses for PRBS
A10_XR_ADDR_PRBS_CTRL: avmm_readdata <= rd_prbs_ctrl;
A10_XR_ADDR_PRBS_ERR_0: avmm_readdata <= rd_prbs_err[7:0];
A10_XR_ADDR_PRBS_ERR_1: avmm_readdata <= rd_prbs_err[15:8];
A10_XR_ADDR_PRBS_ERR_2: avmm_readdata <= rd_prbs_err[23:16];
A10_XR_ADDR_PRBS_ERR_3: avmm_readdata <= rd_prbs_err[31:24];
A10_XR_ADDR_PRBS_ERR_4: avmm_readdata <= rd_prbs_err[39:32];
A10_XR_ADDR_PRBS_ERR_5: avmm_readdata <= rd_prbs_err[47:40];
A10_XR_ADDR_PRBS_ERR_6: avmm_readdata <= {6'b0, rd_prbs_err[49:48]};
A10_XR_ADDR_PRBS_BIT_0: avmm_readdata <= rd_prbs_bit[7:0];
A10_XR_ADDR_PRBS_BIT_1: avmm_readdata <= rd_prbs_bit[15:8];
A10_XR_ADDR_PRBS_BIT_2: avmm_readdata <= rd_prbs_bit[23:16];
A10_XR_ADDR_PRBS_BIT_3: avmm_readdata <= rd_prbs_bit[31:24];
A10_XR_ADDR_PRBS_BIT_4: avmm_readdata <= rd_prbs_bit[39:32];
A10_XR_ADDR_PRBS_BIT_5: avmm_readdata <= rd_prbs_bit[47:40];
A10_XR_ADDR_PRBS_BIT_6: avmm_readdata <= {6'b0, rd_prbs_bit[49:48]};
// Address for ODI
A10_XR_ADDR_ODI_CTRL: avmm_readdata <= rd_odi_ctrl;
A10_XR_ADDR_ODI_ERR_0: avmm_readdata <= rd_odi_err[7:0];
A10_XR_ADDR_ODI_ERR_1: avmm_readdata <= rd_odi_err[15:8];
A10_XR_ADDR_ODI_ERR_2: avmm_readdata <= rd_odi_err[23:16];
A10_XR_ADDR_ODI_ERR_3: avmm_readdata <= rd_odi_err[31:24];
A10_XR_ADDR_ODI_ERR_4: avmm_readdata <= rd_odi_err[39:32];
A10_XR_ADDR_ODI_ERR_5: avmm_readdata <= rd_odi_err[47:40];
A10_XR_ADDR_ODI_ERR_6: avmm_readdata <= {6'b0, rd_odi_err[49:48]};
A10_XR_ADDR_ODI_BIT_0: avmm_readdata <= rd_odi_bit[7:0];
A10_XR_ADDR_ODI_BIT_1: avmm_readdata <= rd_odi_bit[15:8];
A10_XR_ADDR_ODI_BIT_2: avmm_readdata <= rd_odi_bit[23:16];
A10_XR_ADDR_ODI_BIT_3: avmm_readdata <= rd_odi_bit[31:24];
A10_XR_ADDR_ODI_BIT_4: avmm_readdata <= rd_odi_bit[39:32];
A10_XR_ADDR_ODI_BIT_5: avmm_readdata <= rd_odi_bit[47:40];
A10_XR_ADDR_ODI_BIT_6: avmm_readdata <= {6'b0, rd_odi_bit[49:48]};
// Address for status registers
A10_XR_ADDR_GP_RD_LTR: avmm_readdata <= rd_ltr_status;
A10_XR_ADDR_GP_CAL_BUSY: avmm_readdata <= rd_cal_busy;
// Addresses for control registers
A10_XR_ADDR_GP_SET_LTR: avmm_readdata <= rd_set_ltr;
A10_XR_ADDR_GP_LPBK: avmm_readdata <= rd_loopback;
A10_XR_ADDR_CHNL_RESET: avmm_readdata <= rd_chnl_reset;
//Embedded reconfig
A10_XR_ADDR_EMBED_RCFG_CTRL: avmm_readdata <= rd_rcfg_emb_ctrl;
A10_XR_ADDR_EMBED_RCFG_STATUS: avmm_readdata <= rd_rcfg_emb_status;
default: avmm_readdata <= RD_UNUSED;
endcase
end
end
/**********************************************************************/
// Generate Capability Registers
/**********************************************************************/
generate if(dbg_capability_reg_enable == 1) begin: g_capability_reg_en
assign rd_channel = channels[7:0];
assign rd_channel_num = channel_num[7:0];
assign rd_duplex = (duplex_mode == "duplex") ? 8'h3 :
(duplex_mode == "tx") ? 8'h2 : 8'h1;
assign rd_system_id = dbg_user_identifier[7:0];
assign rd_prbs_en = dbg_prbs_soft_logic_enable[7:0];
assign rd_odi_en = dbg_odi_soft_logic_enable[7:0];
assign rd_status_en = dbg_stat_soft_logic_enable[7:0];
assign rd_control_en = dbg_ctrl_soft_logic_enable[7:0];
end else begin: g_capability_reg_dis
assign rd_channel = RD_UNUSED;
assign rd_channel_num = RD_UNUSED;
assign rd_duplex = RD_UNUSED;
assign rd_system_id = RD_UNUSED;
assign rd_prbs_en = RD_UNUSED;
assign rd_odi_en = RD_UNUSED;
assign rd_status_en = RD_UNUSED;
assign rd_control_en = RD_UNUSED;
end
endgenerate // End generate for g_capability_reg
/**********************************************************************/
// Generate registers for status signals
/**********************************************************************/
generate if(dbg_stat_soft_logic_enable == 1) begin: g_status_reg_en
/**********************************************************************/
// Wires for status signal synchronizers inside generate to avoid un-used wires
/**********************************************************************/
wire rx_is_ltd_sync;
wire rx_is_ltr_sync;
wire tx_cal_busy_sync;
wire rx_cal_busy_sync;
/**********************************************************************/
// Instantiate Synchronizers and read logic for rx_is_lockedtodata and rx_is_lockedtoref
/**********************************************************************/
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 2 ) // two bits, one for locktodata and one for locktoref
) rx_is_locked_sync (
.clk (avmm_clk),
.reset (avmm_reset),
.d ({rx_is_lockedtodata, rx_is_lockedtoref}),
.q ({rx_is_ltd_sync, rx_is_ltr_sync})
);
assign rd_ltr_status[A10_XR_OFFSET_RD_LTR] = rx_is_ltr_sync;
assign rd_ltr_status[A10_XR_OFFSET_RD_LTD] = rx_is_ltd_sync;
assign rd_ltr_status[A10_XR_OFFSET_LTR_UNUSED+:A10_XR_LTR_UNUSED_LEN] = {A10_XR_LTR_UNUSED_LEN{1'b0}};
/**********************************************************************/
// Instantiate Synchronizers and read logic for avmm busy, cal busy and their masks
/**********************************************************************/
reg r_set_tx_cal_mask;
reg r_set_rx_cal_mask;
reg r_avmm_busy;
// Instantiate Synchronizers and read logic for cal busy and avmm busy
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 2 ) // two bits, one for tx cal busy and one for rx cal busy
) cal_busy (
.clk (avmm_clk),
.reset (avmm_reset),
.d ({rx_cal_busy, tx_cal_busy}),
.q ({rx_cal_busy_sync, tx_cal_busy_sync})
);
assign csr_tx_cal_busy_mask = ~r_set_tx_cal_mask;
assign csr_rx_cal_busy_mask = ~r_set_rx_cal_mask;
assign rd_cal_busy[A10_XR_OFFSET_TX_CAL_BUSY] = tx_cal_busy_sync;
assign rd_cal_busy[A10_XR_OFFSET_RX_CAL_BUSY] = rx_cal_busy_sync;
assign rd_cal_busy[A10_XR_OFFSET_AVMM_BUSY] = r_avmm_busy;
assign rd_cal_busy[A10_XR_OFFSET_CAL_DUMMY] = 1'b0;
assign rd_cal_busy[A10_XR_OFFSET_TX_CAL_MASK] = ~r_set_tx_cal_mask;
assign rd_cal_busy[A10_XR_OFFSET_RX_CAL_MASK] = ~r_set_rx_cal_mask;
assign rd_cal_busy[A10_XR_OFFSET_CAL_UNUSED+:A10_XR_CAL_UNUSED_LEN] = {A10_XR_CAL_UNUSED_LEN{1'b0}};
// Assure that the avmm_busy register always gets updated
always@(posedge avmm_clk) begin
// Register the avmm busy signal
r_avmm_busy <= avmm_busy;
end
// write cal_busy masks
// Due to synthesis option not-gate pushback being optionally enabled, We will hard code its behavior.
// this ensures that with or without a reset, the design will behave the same irrespective of the synth
// option being enabled in the design.
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
r_set_tx_cal_mask <= 1'b0;
r_set_rx_cal_mask <= 1'b0;
end else if(avmm_write && avmm_address == A10_XR_ADDR_GP_CAL_BUSY) begin
r_set_tx_cal_mask <= ~avmm_writedata[A10_XR_OFFSET_TX_CAL_MASK];
r_set_rx_cal_mask <= ~avmm_writedata[A10_XR_OFFSET_RX_CAL_MASK];
end
end
end else begin: g_status_reg_dis
assign rd_ltr_status = RD_UNUSED;
assign rd_cal_busy = RD_UNUSED;
assign csr_tx_cal_busy_mask = 1'b1;
assign csr_rx_cal_busy_mask = 1'b1;
end
endgenerate //End generate g_status_reg
/**********************************************************************/
// Generate registers for control signals
/**********************************************************************/
generate if(dbg_ctrl_soft_logic_enable == 1) begin: g_control_reg
/**********************************************************************/
// Registers for set Lock to ref and set Lock to Data
/**********************************************************************/
reg r_set_ltr;
reg r_set_ltd;
reg r_set_ltr_override;
reg r_set_ltd_override;
// readback control registers for set ltr and ltd
assign rd_set_ltr[A10_XR_OFFSET_SET_LTR] = r_set_ltr;
assign rd_set_ltr[A10_XR_OFFSET_SET_LTD] = r_set_ltd;
assign rd_set_ltr[A10_XR_OFFSET_SET_LTR_OVR] = r_set_ltr_override;
assign rd_set_ltr[A10_XR_OFFSET_SET_LTD_OVR] = r_set_ltd_override;
assign rd_set_ltr[A10_XR_OFFSET_SET_LTR_UNUSED+:A10_XR_SET_LTR_UNUSED_LEN] = {A10_XR_SET_LTR_UNUSED_LEN{1'b0}};
// assign the output signals to the channel. Use the inputs signal with the control registers
assign csr_set_lock_to_ref = (rd_set_ltr[A10_XR_OFFSET_SET_LTR_OVR]) ? rd_set_ltr[A10_XR_OFFSET_SET_LTR] : set_rx_locktoref;
assign csr_set_lock_to_data = (rd_set_ltr[A10_XR_OFFSET_SET_LTD_OVR]) ? rd_set_ltr[A10_XR_OFFSET_SET_LTD] : set_rx_locktodata;
// write control registers for ltr and ltd
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
r_set_ltr <= 1'b0;
r_set_ltd <= 1'b0;
r_set_ltr_override <= 1'b0;
r_set_ltd_override <= 1'b0;
end else if(avmm_write && avmm_address == A10_XR_ADDR_GP_SET_LTR) begin
r_set_ltr <= avmm_writedata[A10_XR_OFFSET_SET_LTR];
r_set_ltd <= avmm_writedata[A10_XR_OFFSET_SET_LTD];
r_set_ltr_override <= avmm_writedata[A10_XR_OFFSET_SET_LTR_OVR];
r_set_ltd_override <= avmm_writedata[A10_XR_OFFSET_SET_LTD_OVR];
end
end
/**********************************************************************/
// Registers for loopback
/**********************************************************************/
reg r_loopback;
// readback control register for enabling loopback
assign rd_loopback[A10_XR_OFFSET_LPBK] = r_loopback;
assign rd_loopback[A10_XR_OFFSET_LPBK_UNUSED+:A10_XR_LPBK_UNUSED_LEN] = {A10_XR_LPBK_UNUSED_LEN{1'b0}};
// assign the output signals to the channel
assign csr_en_loopback = (rd_loopback[A10_XR_OFFSET_LPBK] || serial_loopback);
// write control registers for loopback
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
r_loopback <= 1'b0;
end else if(avmm_write && avmm_address == A10_XR_ADDR_GP_LPBK) begin
r_loopback <= avmm_writedata[A10_XR_OFFSET_LPBK];
end
end
/**********************************************************************/
// Registers for Channel Resets and Overrides
/**********************************************************************/
reg r_rx_analogreset;
reg r_rx_digitalreset;
reg r_tx_analogreset;
reg r_tx_digitalreset;
reg r_rx_analogreset_override;
reg r_rx_digitalreset_override;
reg r_tx_analogreset_override;
reg r_tx_digitalreset_override;
// readback the control registers for the channel resets and overrides
assign rd_chnl_reset[A10_XR_OFFSET_RX_ANA] = r_rx_analogreset;
assign rd_chnl_reset[A10_XR_OFFSET_RX_DIG] = r_rx_digitalreset;
assign rd_chnl_reset[A10_XR_OFFSET_TX_ANA] = r_tx_analogreset;
assign rd_chnl_reset[A10_XR_OFFSET_TX_DIG] = r_tx_digitalreset;
assign rd_chnl_reset[A10_XR_OFFSET_RX_ANA_OVR] = r_rx_analogreset_override;
assign rd_chnl_reset[A10_XR_OFFSET_RX_DIG_OVR] = r_rx_digitalreset_override;
assign rd_chnl_reset[A10_XR_OFFSET_TX_ANA_OVR] = r_tx_analogreset_override;
assign rd_chnl_reset[A10_XR_OFFSET_TX_DIG_OVR] = r_tx_digitalreset_override;
// assign the output signals to the channel
assign csr_rx_analogreset = (rd_chnl_reset[A10_XR_OFFSET_RX_ANA_OVR]) ? rd_chnl_reset[A10_XR_OFFSET_RX_ANA] : rx_analogreset;
assign csr_rx_digitalreset = (rd_chnl_reset[A10_XR_OFFSET_RX_DIG_OVR]) ? rd_chnl_reset[A10_XR_OFFSET_RX_DIG] : rx_digitalreset;
assign csr_tx_analogreset = (rd_chnl_reset[A10_XR_OFFSET_TX_ANA_OVR]) ? rd_chnl_reset[A10_XR_OFFSET_TX_ANA] : tx_analogreset;
assign csr_tx_digitalreset = (rd_chnl_reset[A10_XR_OFFSET_TX_DIG_OVR]) ? rd_chnl_reset[A10_XR_OFFSET_TX_DIG] : tx_digitalreset;
// write reset and reset override registers
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
r_rx_analogreset <= 1'b0;
r_rx_digitalreset <= 1'b0;
r_tx_analogreset <= 1'b0;
r_tx_digitalreset <= 1'b0;
r_rx_analogreset_override <= 1'b0;
r_rx_digitalreset_override <= 1'b0;
r_tx_analogreset_override <= 1'b0;
r_tx_digitalreset_override <= 1'b0;
end else if(avmm_write && avmm_address == A10_XR_ADDR_CHNL_RESET) begin
r_rx_analogreset <= avmm_writedata[A10_XR_OFFSET_RX_ANA];
r_rx_digitalreset <= avmm_writedata[A10_XR_OFFSET_RX_DIG];
r_tx_analogreset <= avmm_writedata[A10_XR_OFFSET_TX_ANA];
r_tx_digitalreset <= avmm_writedata[A10_XR_OFFSET_TX_DIG];
r_rx_analogreset_override <= avmm_writedata[A10_XR_OFFSET_RX_ANA_OVR];
r_rx_digitalreset_override <= avmm_writedata[A10_XR_OFFSET_RX_DIG_OVR];
r_tx_analogreset_override <= avmm_writedata[A10_XR_OFFSET_TX_ANA_OVR];
r_tx_digitalreset_override <= avmm_writedata[A10_XR_OFFSET_TX_DIG_OVR];
end
end
end else begin: g_control_reg_dis
// assign LTR control signals when control registers are disabled
assign rd_set_ltr = RD_UNUSED;
assign rd_loopback = RD_UNUSED;
assign rd_chnl_reset = RD_UNUSED;
// pass through control signals
assign csr_set_lock_to_ref = (set_rx_locktoref);
assign csr_set_lock_to_data = (set_rx_locktodata);
assign csr_en_loopback = (serial_loopback);
assign csr_rx_analogreset = (rx_analogreset);
assign csr_rx_digitalreset = (rx_digitalreset);
assign csr_tx_analogreset = (tx_analogreset);
assign csr_tx_digitalreset = (tx_digitalreset);
end
endgenerate // End generate g_control_reg
/**********************************************************************/
// Embedded reconfig registers
/**********************************************************************/
generate if(rcfg_emb_strm_enable) begin: en_rcfg_reg
/**********************************************************************/
// Generate registers and wires for the reconfig soft logic
/**********************************************************************/
reg [rcfg_emb_strm_cfg_sel_width-1:0] r_rcfg_emb_strm_cfg_sel;
reg r_rcfg_emb_strm_cfg_load;
reg r_rcfg_emb_strm_bcast_en;
reg rcfg_emb_strm_cfg_load_lock = 1'b0;
// readback the embedded reconfig control
assign rd_rcfg_emb_ctrl = {r_rcfg_emb_strm_cfg_load, r_rcfg_emb_strm_bcast_en, {(A10_XR_EMBED_RCFG_CFG_SEL_LEN-rcfg_emb_strm_cfg_sel_width){1'b0}}, r_rcfg_emb_strm_cfg_sel};
assign rd_rcfg_emb_status = {7'b0, rcfg_emb_strm_busy};
// assign the output signals to the channel
assign rcfg_emb_strm_cfg_sel = r_rcfg_emb_strm_cfg_sel;
assign rcfg_emb_strm_cfg_load = r_rcfg_emb_strm_cfg_load;
assign rcfg_emb_strm_bcast_en = r_rcfg_emb_strm_bcast_en;
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
r_rcfg_emb_strm_cfg_sel <= {rcfg_emb_strm_cfg_sel_width{1'b0}};
r_rcfg_emb_strm_cfg_load <= 1'b0;
r_rcfg_emb_strm_bcast_en <= 1'b0;
rcfg_emb_strm_cfg_load_lock <= 1'b0;
end else if(avmm_write && avmm_address == A10_XR_ADDR_EMBED_RCFG_CTRL) begin
// Write to this register
r_rcfg_emb_strm_cfg_sel <= avmm_writedata[A10_XR_OFFSET_EMBED_RCFG_CFG_SEL +: rcfg_emb_strm_cfg_sel_width ];
r_rcfg_emb_strm_cfg_load <= avmm_writedata[A10_XR_OFFSET_EMBED_RCFG_CFG_LOAD];
r_rcfg_emb_strm_bcast_en <= avmm_writedata[A10_XR_OFFSET_EMBED_RCFG_BCAST_EN];
end else if(rcfg_emb_strm_chan_sel & rcfg_emb_strm_busy & ~rcfg_emb_strm_cfg_load_lock) begin
// Reset the cfg_load bit when the streaming has started
r_rcfg_emb_strm_cfg_load <= 1'b0;
rcfg_emb_strm_cfg_load_lock <= 1'b1;
end else if(~rcfg_emb_strm_busy & rcfg_emb_strm_cfg_load_lock)
rcfg_emb_strm_cfg_load_lock <= 1'b0;
end
end else begin: g_rcfg_reg_dis
assign rd_rcfg_emb_ctrl = RD_UNUSED;
assign rd_rcfg_emb_status = RD_UNUSED;
assign rcfg_emb_strm_cfg_sel = 1'b0;
assign rcfg_emb_strm_bcast_en = 1'b0;
assign rcfg_emb_strm_cfg_load = 1'b0;
end
endgenerate //End generate g_rcfg_reg
/**********************************************************************/
// PRBS Registers and logic
/**********************************************************************/
assign rd_prbs_err = prbs_err;
assign rd_prbs_bit = prbs_bit;
generate if(dbg_prbs_soft_logic_enable == 1) begin: g_prbs_reg_en
/**********************************************************************/
// wires for synchronizer and registers for control signals to the PRBS accumulation block
/**********************************************************************/
wire rx_prbs_err_clr_sync;
reg r_prbs_reset;
reg r_prbs_snap;
reg r_prbs_en;
/**********************************************************************/
// Instantiate Synchronizers and read logic for rx_is_lockedtodata and rx_is_lockedtoref
/**********************************************************************/
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 1 ) // two bits, one for locktodata and one for locktoref
) prbs_err_clr_sync (
.clk (avmm_clk),
.reset (avmm_reset),
.d (rx_prbs_err_clr),
.q (rx_prbs_err_clr_sync)
);
// assign control signals for the PRBS accumulation logic
assign prbs_count_en = r_prbs_en;
assign prbs_snap = r_prbs_snap;
assign prbs_reset = r_prbs_reset || rx_prbs_err_clr_sync;
// readback data
assign rd_prbs_ctrl[A10_XR_OFFSET_PRBS_EN] = r_prbs_en;
assign rd_prbs_ctrl[A10_XR_OFFSET_PRBS_RESET] = r_prbs_reset;
assign rd_prbs_ctrl[A10_XR_OFFSET_PRBS_SNAP] = r_prbs_snap;
assign rd_prbs_ctrl[A10_XR_OFFSET_PRBS_DONE] = prbs_done;
assign rd_prbs_ctrl[A10_XR_OFFSET_PRBS_UNUSED+:A10_XR_PRBS_UNUSED_LEN] = {A10_XR_PRBS_UNUSED_LEN{1'b0}};
// write prbs ctrl reg
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
r_prbs_en <= 1'b0;
r_prbs_reset <= 1'b0;
r_prbs_snap <= 1'b0;
end else if(avmm_write && avmm_address == A10_XR_ADDR_PRBS_CTRL) begin
r_prbs_en <= avmm_writedata[A10_XR_OFFSET_PRBS_EN];
r_prbs_reset <= avmm_writedata[A10_XR_OFFSET_PRBS_RESET];
r_prbs_snap <= avmm_writedata[A10_XR_OFFSET_PRBS_SNAP];
end
end
end else begin: g_prbs_reg_dis
assign prbs_reset = (rx_prbs_err_clr);
assign rd_prbs_ctrl = RD_UNUSED;
assign prbs_count_en = 1'b0;
assign prbs_snap = 1'b0;
end
endgenerate //End generate g_prbs_reg
/**********************************************************************/
// ODI Registers and logic
/**********************************************************************/
assign rd_odi_bit = odi_bit;
assign rd_odi_err = odi_err;
generate if(dbg_odi_soft_logic_enable == 1) begin: g_odi_reg_en
/**********************************************************************/
// wires for synchronizer and registers for control signals to the odi accumulation block
/**********************************************************************/
reg r_odi_reset;
reg r_odi_snap;
reg r_odi_en;
// assign control signals for the ODI accumulation logic
assign odi_count_en = r_odi_en;
assign odi_snap = r_odi_snap;
assign odi_reset = r_odi_reset;
// readback data
assign rd_odi_ctrl[A10_XR_OFFSET_ODI_EN] = r_odi_en;
assign rd_odi_ctrl[A10_XR_OFFSET_ODI_RESET] = r_odi_reset;
assign rd_odi_ctrl[A10_XR_OFFSET_ODI_SNAP] = r_odi_snap;
assign rd_odi_ctrl[A10_XR_OFFSET_ODI_DONE] = odi_done;
assign rd_odi_ctrl[A10_XR_OFFSET_ODI_UNUSED+:A10_XR_ODI_UNUSED_LEN] = {A10_XR_ODI_UNUSED_LEN{1'b0}};
// write ODI ctrl reg
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
r_odi_en <= 1'b0;
r_odi_reset <= 1'b0;
r_odi_snap <= 1'b0;
end else if(avmm_write && avmm_address == A10_XR_ADDR_ODI_CTRL) begin
r_odi_en <= avmm_writedata[A10_XR_OFFSET_ODI_EN];
r_odi_reset <= avmm_writedata[A10_XR_OFFSET_ODI_RESET];
r_odi_snap <= avmm_writedata[A10_XR_OFFSET_ODI_SNAP];
end
end
end else begin: g_odi_reg_dis
assign rd_odi_ctrl = RD_UNUSED;
assign odi_reset = 1'b0;
assign odi_count_en = 1'b0;
assign odi_snap = 1'b0;
end
endgenerate //End generate g_odi_reg
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1 ps/1 ps
module alt_xcvr_native_odi_accel #(
parameter DATA_WIDTH = 32
) (
input avmm_clk,
input avmm_reset,
// AVMM signals to the transceiver
output reg odi_read,
output reg odi_write,
output reg [9:0] odi_address,
output reg [DATA_WIDTH-1:0] odi_writedata,
input [7:0] odi_readdata,
input odi_waitrequest,
// Control signals from CSR
input odi_count_en,
input odi_snap,
input odi_reset,
// Status signals from ODI
output odi_done,
output reg [49:0] odi_bit_count,
output reg [49:0] odi_err_count
);
/**********************************************************************/
// States for the Statemachine
// General Sequence: idle > odi_start_0 > odi_rstn_1 > odi_rst_0 > odi_start_1 > odi_start_0 > chck_done > read_bits > read_errs
/**********************************************************************/
localparam SM_ODI_ACCEL_IDLE = 5'd0;
localparam SM_ODI_ACCEL_RD_OFST_169 = 5'd1;
localparam SM_ODI_ACCEL_WR_START_0 = 5'd2;
localparam SM_ODI_ACCEL_WR_RESET_1 = 5'd3;
localparam SM_ODI_ACCEL_WR_RESET_0 = 5'd4;
localparam SM_ODI_ACCEL_WR_START_1 = 5'd5;
localparam SM_ODI_ACCEL_WR_START_DISABLE= 5'd6;
localparam SM_ODI_ACCEL_WAIT = 5'd7;
localparam SM_ODI_ACCEL_RD_ADPT_STAT_BUS= 5'd8;
localparam SM_ODI_ACCEL_RD_ADPT_STATUS = 5'd9;
localparam SM_ODI_ACCEL_RD_ADPT_ERR_1 = 5'd10;
localparam SM_ODI_ACCEL_RD_ADPT_ERR_2 = 5'd11;
localparam SM_ODI_ACCEL_RD_ADPT_BIT_1 = 5'd12;
localparam SM_ODI_ACCEL_RD_ADPT_BIT_2 = 5'd13;
localparam SM_ODI_ACCEL_FINAL_ACCUM = 5'd14;
/**********************************************************************/
// Local wires and registers
/**********************************************************************/
reg [4:0] sm_odi_state;
reg [4:0] sm_odi_next;
reg [5:0] timeout;
reg [7:0] lcl_odi_read;
reg [15:0] adpt_bits;
reg [15:0] adpt_errs;
reg [50:0] odi_bit_accumulator;
reg [50:0] odi_err_accumulator;
/**********************************************************************/
// Statemachine
/**********************************************************************/
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
sm_odi_state <= SM_ODI_ACCEL_IDLE;
odi_read <= 1'b0;
odi_write <= 1'b0;
odi_address <= 10'b0;
odi_writedata <= {DATA_WIDTH{1'b0}};
adpt_bits <= 16'b0;
adpt_errs <= 16'b0;
end else if(odi_reset) begin
sm_odi_state <= SM_ODI_ACCEL_IDLE;
odi_read <= 1'b0;
odi_write <= 1'b0;
odi_address <= 10'b0;
odi_writedata <= {DATA_WIDTH{1'b0}};
adpt_bits <= 16'b0;
adpt_errs <= 16'b0;
end else begin
odi_read <= 1'b0;
odi_write <= 1'b0;
odi_address <= 10'b0;
odi_writedata <= {DATA_WIDTH{1'b0}};
case(sm_odi_state)
SM_ODI_ACCEL_IDLE:
begin
odi_read <= 1'b0;
odi_write <= 1'b0;
adpt_bits <= 16'b0;
adpt_errs <= 16'b0;
if(odi_count_en == 1'b1) begin
sm_odi_state <= SM_ODI_ACCEL_RD_OFST_169;
end
end
SM_ODI_ACCEL_RD_OFST_169:
begin
if(odi_waitrequest == 1'b0 && odi_read == 1'b1) begin
adpt_bits <= 16'b0;
adpt_errs <= 16'b0;
odi_read <= 1'b0;
odi_write <= 1'b1;
odi_address <= 10'h169;
odi_writedata <= {odi_readdata[7:1],1'b0};
lcl_odi_read <= odi_readdata;
sm_odi_state <= SM_ODI_ACCEL_WR_RESET_0;
end else begin
odi_read <= 1'b1;
odi_write <= 1'b0;
odi_address <= 10'h169;
sm_odi_state <= SM_ODI_ACCEL_RD_OFST_169;
end
end
SM_ODI_ACCEL_WR_RESET_0:
begin
odi_read <= 1'b0;
odi_write <= 1'b1;
odi_address <= 10'h169;
odi_writedata <= {lcl_odi_read[7:2],2'b00};
sm_odi_state <= SM_ODI_ACCEL_WR_RESET_1;
end
SM_ODI_ACCEL_WR_RESET_1:
begin
odi_read <= 1'b0;
odi_write <= 1'b1;
odi_address <= 10'h169;
odi_writedata <= {lcl_odi_read[7:2],2'b10};
sm_odi_state <= SM_ODI_ACCEL_WR_START_1;
end
SM_ODI_ACCEL_WR_START_1:
begin
odi_read <= 1'b0;
odi_write <= 1'b1;
odi_address <= 10'h169;
odi_writedata <= {lcl_odi_read[7:2],2'b11};
sm_odi_state <= SM_ODI_ACCEL_WR_START_DISABLE;
end
SM_ODI_ACCEL_WR_START_DISABLE:
begin
odi_read <= 1'b0;
odi_write <= 1'b1;
odi_address <= 10'h169;
odi_writedata <= {lcl_odi_read[7:2],2'b10};
sm_odi_state <= SM_ODI_ACCEL_WAIT;
sm_odi_next <= SM_ODI_ACCEL_RD_ADPT_STAT_BUS;
end
SM_ODI_ACCEL_WAIT:
begin
odi_write <= 1'b0;
odi_read <= 1'b0;
odi_address <= odi_address;
odi_writedata <= odi_writedata;
if(timeout[4] & timeout[3]) begin
sm_odi_state <= sm_odi_next;
end else begin
sm_odi_state <= SM_ODI_ACCEL_WAIT;
end
end
SM_ODI_ACCEL_RD_ADPT_STAT_BUS:
begin
if(odi_waitrequest == 1'b0 && odi_read == 1'b1) begin // TODO
odi_read <= 1'b0;
odi_write <= 1'b1;
odi_address <= 10'h14c;
odi_writedata <= {odi_readdata[7],7'h2D}; // TODO - mask
lcl_odi_read <= odi_readdata;
sm_odi_state <= SM_ODI_ACCEL_WAIT;
sm_odi_next <= SM_ODI_ACCEL_RD_ADPT_STATUS;
end else begin
odi_read <= 1'b1;
odi_write <= 1'b0;
odi_address <= 10'h14c;
odi_writedata <= 8'h00;
sm_odi_state <= SM_ODI_ACCEL_RD_ADPT_STAT_BUS;
end
end
SM_ODI_ACCEL_RD_ADPT_STATUS:
begin
if(odi_waitrequest == 1'b0 && odi_read == 1'b1) begin // TODO
if(odi_readdata[1] == 1'b1) begin
odi_read <= 1'b0;
odi_write <= 1'b1;
odi_address <= 10'h14c;
odi_writedata <= {lcl_odi_read[7],7'h2C};
sm_odi_state <= SM_ODI_ACCEL_WAIT;
sm_odi_next <= SM_ODI_ACCEL_RD_ADPT_ERR_1;
end else begin
sm_odi_state <= SM_ODI_ACCEL_WAIT;
end
end else begin
odi_read <= 1'b1;
odi_write <= 1'b0;
odi_address <= 10'h177;
odi_writedata <= 8'h0;
sm_odi_state <= SM_ODI_ACCEL_RD_ADPT_STATUS;
end
end
SM_ODI_ACCEL_RD_ADPT_ERR_1:
begin
if(odi_waitrequest == 1'b0 && odi_read == 1'b1) begin
odi_read <= 1'b0;
odi_write <= 1'b1;
odi_address <= 10'h14c;
odi_writedata <= {lcl_odi_read[7],7'h2B};
sm_odi_state <= SM_ODI_ACCEL_WAIT;
sm_odi_next <= SM_ODI_ACCEL_RD_ADPT_ERR_2;
adpt_errs[15:8] <= odi_readdata;
end else begin
odi_read <= 1'b1;
odi_write <= 1'b0;
odi_address <= 10'h177;
odi_writedata <= 8'h0;
sm_odi_state <= SM_ODI_ACCEL_RD_ADPT_ERR_1;
end
end
SM_ODI_ACCEL_RD_ADPT_ERR_2:
begin
if(odi_waitrequest == 1'b0 && odi_read == 1'b1) begin
odi_read <= 1'b0;
odi_write <= 1'b1;
odi_address <= 10'h14c;
odi_writedata <= {lcl_odi_read[7],7'h2A};
sm_odi_state <= SM_ODI_ACCEL_WAIT;
sm_odi_next <= SM_ODI_ACCEL_RD_ADPT_BIT_1;
adpt_errs[7:0] <= odi_readdata;
end else begin
odi_read <= 1'b1;
odi_write <= 1'b0;
odi_address <= 10'h177;
odi_writedata <= 8'h0;
sm_odi_state <= SM_ODI_ACCEL_RD_ADPT_ERR_2;
end
end
SM_ODI_ACCEL_RD_ADPT_BIT_1:
begin
if(odi_waitrequest == 1'b0 && odi_read == 1'b1) begin
odi_read <= 1'b0;
odi_write <= 1'b1;
odi_address <= 10'h14c;
odi_writedata <= {lcl_odi_read[7],7'h29};
sm_odi_state <= SM_ODI_ACCEL_WAIT;
sm_odi_next <= SM_ODI_ACCEL_RD_ADPT_BIT_2;
adpt_bits[15:8] <= odi_readdata;
end else begin
odi_read <= 1'b1;
odi_write <= 1'b0;
odi_address <= 10'h177;
odi_writedata <= 8'h0;
sm_odi_state <= SM_ODI_ACCEL_RD_ADPT_BIT_1;
end
end
SM_ODI_ACCEL_RD_ADPT_BIT_2:
begin
odi_write <= 1'b0;
odi_address <= 10'h177;
odi_writedata <= 8'h0;
if(odi_waitrequest == 1'b0 && odi_read == 1'b1) begin
odi_read <= 1'b0;
sm_odi_state <= SM_ODI_ACCEL_FINAL_ACCUM;
adpt_bits[7:0] <= odi_readdata;
end else begin
odi_read <= 1'b1;
sm_odi_state <= SM_ODI_ACCEL_RD_ADPT_BIT_2;
end
end
SM_ODI_ACCEL_FINAL_ACCUM:
begin
if(odi_count_en == 1'b1) begin
sm_odi_state <= SM_ODI_ACCEL_RD_OFST_169;
end else begin
sm_odi_state <= SM_ODI_ACCEL_IDLE;
end
end
default:
begin
odi_read <= 1'b0;
odi_write <= 1'b0;
odi_address <= 10'b0;
odi_writedata <= {DATA_WIDTH{1'b0}};
end
endcase
end
end
// Time between polling the odi_done bit to read out the accumualted read/write
always@(posedge avmm_clk) begin
if(sm_odi_state == SM_ODI_ACCEL_WAIT) begin
timeout <= timeout + 1'b1;
end else begin
timeout <= 5'b0;
end
end
/**********************************************************************/
// Accumulate bit and error count!
/**********************************************************************/
assign odi_done = odi_bit_accumulator[50];
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset == 1'b1) begin
odi_bit_count <= 50'b0;
odi_err_count <= 50'b0;
odi_bit_accumulator <= 51'b0;
odi_err_accumulator <= 51'b0;
end else if(odi_reset == 1'b1) begin
odi_bit_count <= 50'b0;
odi_err_count <= 50'b0;
odi_bit_accumulator <= 51'b0;
odi_err_accumulator <= 51'b0;
end else begin
if(odi_snap) begin
odi_bit_count <= odi_bit_accumulator[49:0];
odi_err_count <= odi_err_accumulator[49:0];
end
if(sm_odi_state == SM_ODI_ACCEL_FINAL_ACCUM) begin
if(odi_done == 1'b1) begin
odi_bit_accumulator <= odi_bit_accumulator;
odi_err_accumulator <= odi_err_accumulator;
end else begin
odi_bit_accumulator <= odi_bit_accumulator + adpt_bits;
odi_err_accumulator <= odi_err_accumulator + adpt_errs;
end
end
end
end
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1ps/1ps
module alt_xcvr_native_pipe_retry (
input pipe_pclk,
input tx_digitalreset,
input [1:0] pld_rate,
input [19:0] pld_testbus,
output reg [1:0] rate_retry
);
/*********************************************************************************/
// Set localparams for configuring index bits as well as synchronizing the reset
/*********************************************************************************/
// if we use a timeout of 127, then the delay for a single attempt is 508ns
// For an attempt + a restore, its 1us, which corresponds to 1.5us to attempt
// both a posedge and a negedge launch attempt. The full retry time before
// a recycle is 2us.
// Timeout value = 2^(lcl_rate_switch_counter_width-2)-1 = 2^7-1 = 127
localparam lcl_rate_switch_counter_width = 9;
localparam lcl_index_switch_clock = lcl_rate_switch_counter_width-1;
localparam lcl_index_restory_pre_rate_sw = lcl_rate_switch_counter_width-2;
localparam lcl_index_max_counter_timeout = lcl_rate_switch_counter_width-3;
// Register for counter
reg [lcl_rate_switch_counter_width-1:0] retry_counter;
// Synchronize tx_digitalreset
wire hv_pipe_clk;
wire tx_digitalreset_pclk_sync;
wire tx_digitalresetn_hv_sync;
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 1 ),
.SLOW_CLOCK ( 0 ),
.INIT_VALUE ( 1 )
) tx_digitalreset_pclk_inst (
.clk (pipe_pclk),
.reset (tx_digitalreset),
.d (1'b0),
.q (tx_digitalreset_pclk_sync)
);
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 1 ),
.SLOW_CLOCK ( 0 ),
.INIT_VALUE ( 0 )
) tx_digitalreset_hv_inst (
.clk (hv_pipe_clk),
.reset (tx_digitalreset),
.d (1'b1),
.q (tx_digitalresetn_hv_sync)
);
/*********************************************************************************/
// Take the asynchronous inputs of Rate from the testbus and the user.
/*********************************************************************************/
// Delcare local wires and registers
//reg [2:0] pld_rate_vec_timeout;
reg [3:0] pma_pld_rate_sync;
reg [3:0] pld_rate_sync;
wire [1:0] pma_pld_rate_r;
wire [1:0] pld_rate_restore;
wire [1:0] pld_rate_r;
// Assign the buses to the second stage of the reset registers;
assign pma_pld_rate_r = pma_pld_rate_sync[3:2];
assign pld_rate_restore = pld_rate_sync[3:2];
assign pld_rate_r = pld_rate_sync[1:0];
// Set a 2-stage synchronizer chain to minimize resolve spy-glass related issues. Since
// the If the pld_rate from the core is asynchronous, then run a counter when the rate
// changes to resolve any issues with bit-skew.
always@(posedge pipe_pclk or posedge tx_digitalreset_pclk_sync) begin
if(tx_digitalreset_pclk_sync) begin
pma_pld_rate_sync <= 4'b0;
pld_rate_sync <= 4'b0;
end else begin
// 2-bit synchronizer for the testbus
pma_pld_rate_sync[1:0] <= pld_testbus[9:8];
pma_pld_rate_sync[3:2] <= pma_pld_rate_sync[1:0];
// 2-bitsynchrnoizer for the user pld_rate
pld_rate_sync[1:0] <= pld_rate;
// when the testbus matches the incoming rate request, update the register.
if( (pma_pld_rate_r == pld_rate_r) && (&retry_counter[lcl_index_max_counter_timeout:2]) ) begin
pld_rate_sync[3:2] <= pld_rate_sync[1:0];
end
end
end
/*********************************************************************************/
// Determine if a retry may be required.
/*********************************************************************************/
// Declare local wires
wire lcl_require_retry;
reg require_retry;
// A retry is required when the transceiver channel's current rate differes from the
// requested rate from the core.
assign lcl_require_retry = (pld_rate_r != pld_rate_restore);
always@(posedge pipe_pclk) begin
require_retry <= lcl_require_retry;
end
/*********************************************************************************/
// Run the timeout counter to track attempts rate and clock edge attempts
/*********************************************************************************/
// Declare local registers and wires
wire switch_clock_edge;
wire restore_pre_rate_sw;
// Assign the wires switch_clock_rate and restor_pre_rate_sw for readability purposes.
assign switch_clock_edge = retry_counter[lcl_index_switch_clock];
assign restore_pre_rate_sw = retry_counter[lcl_index_restory_pre_rate_sw];
// This block essentially runs two counters: a timeout to sample the ASN_TESTBUS for pcie_rate
// and rate attmpt counter to track of the current attempt. For efficiency and readability
// A single physical counter is uses. The upper two bits are the rate attempt counter, and
// the lower 7 bits compose of the timeout counter
//
// Timeout Counter = retry_counter[6:0]
// Rate Attempt Counter = {switch_clock_edge, switch_clock_edge} = retry_counter[8:7]
//
// There are 4 potential combinations for the rate attempt counter (retry_counter[8:7]
// (0)Posedge clock, (0)requested rate switch (encoding: 0 0)
// (0)Posedge clock, (1)restore pre-rate switch rate (encoding: 0 1)
// (1)negedge clock, (0)requested rate switch (encoding: 1 0)
// (1)negedge clock, (1)restory pre-rate switch rate (encoding: 1 1)
always@(posedge pipe_pclk or posedge tx_digitalreset_pclk_sync) begin
if(tx_digitalreset_pclk_sync) begin
retry_counter <= {lcl_rate_switch_counter_width{1'b0}};
end else begin // end if reset condition
if(require_retry) begin
retry_counter <= retry_counter + 1'b1;
end else begin // end if require_retry
retry_counter <= {lcl_rate_switch_counter_width{1'b0}};
end // end else require_retry
end // end else reset condition
end // end always block
/*********************************************************************************/
// Alternate the PCI Rate between transceiver current rate and requested rate
/*********************************************************************************/
// Declare local wires
wire [1:0] retry_attempt;
// Assign the PCIe rate request to the transceiver. Alternates between the transceiver
// rate and the requested rate from the core. Every timeout from the counter, the rate
// will either attempt to downtrain/uptrain or restore the current transceiver rate
assign retry_attempt = (restore_pre_rate_sw == 1'b1) ? pld_rate_restore : pld_rate_r;
/*********************************************************************************/
// Buffer the rate request as well as the clock switch on the PCLK
/*********************************************************************************/
// Declare local wires and registers
wire rate_change_sync;
wire update_pld_rate_output;
reg rate_change;
reg rate_change_edge;
reg restore_pre_rate_sw_buf;
reg require_retry_buf;
reg [1:0] hv_sync_vec_pipe_rate;
// Buffer the rate switch request as well as the clock edge switch on the pclk domain
always@(posedge pipe_pclk or posedge tx_digitalreset_pclk_sync) begin
if(tx_digitalreset_pclk_sync) begin
hv_sync_vec_pipe_rate <= 2'b0;
require_retry_buf <= 1'b0;
restore_pre_rate_sw_buf <= 1'b0;
rate_change <= 1'b0;
end else begin // end if tx_digitalreset_pclk_sync
hv_sync_vec_pipe_rate <= retry_attempt;
restore_pre_rate_sw_buf <= restore_pre_rate_sw;
require_retry_buf <= require_retry;
rate_change <= ((restore_pre_rate_sw ^ restore_pre_rate_sw_buf) || (require_retry & ~require_retry_buf)) ? ~rate_change : rate_change;
end // end else tx_digitalreseet_sync
end
/*********************************************************************************/
// Switch clock edge and rate request update
/*********************************************************************************/
// Based upon the clock edge requirement, swap the unateness
assign hv_pipe_clk = (switch_clock_edge == 1'b1) ? ~pipe_pclk : pipe_pclk;
// Since the rate_sw_req is technically asynchronous due to the different clock networks,
// rate_attempt is on pclk and hv_sync_retry_rate is on HV - after the clock edge switch,
// the signal needs to be synchornized into the HV clock domain
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 1 ),
.SLOW_CLOCK ( 0 ),
.INIT_VALUE ( 0 )
) rate_sw_sync_inst (
.clk (hv_pipe_clk),
.reset (1'b0),
.d (rate_change),
.q (rate_change_sync)
);
// After the rate_sw_req is synchronized (3-clock cycles later) into the hv_pipe_clk domain,
// the hv_sync_retry_rate can be updated. This register will recycle its value until the
// value of rate_sw_req_sync is 1'b1. After hv_sync_retry_rate is updated, the rate_sw_req
// will go to 1'b1, which will take 3-cycles to synchronize, at which point hv_sync_retry_rate
// will recycle its current value.
//
// This offers a 3-cycle window for the value of hv_sync_vec_pipe_rate to stabilize at the input
// to hv_sync_retry_rate.
assign update_pld_rate_output = (rate_change_edge ^ rate_change_sync);
always@(posedge hv_pipe_clk) begin
rate_change_edge <= rate_change_sync;
end
(* altera_attribute = " -name MAX_WIRES_FOR_CORE_PERIPHERY_TRANSFER 2 " *)
dffe hv_sync_retry_rate_r0 (
.d (hv_sync_vec_pipe_rate[0]),
.clk (hv_pipe_clk),
.clrn (tx_digitalresetn_hv_sync),
.prn (1'b1),
.ena (update_pld_rate_output),
.q (rate_retry[0])
);
(* altera_attribute = " -name MAX_WIRES_FOR_CORE_PERIPHERY_TRANSFER 2 " *)
dffe hv_sync_retry_rate_r1 (
.d (hv_sync_vec_pipe_rate[1]),
.clk (hv_pipe_clk),
.clrn (tx_digitalresetn_hv_sync),
.prn (1'b1),
.ena (update_pld_rate_output),
.q (rate_retry[1])
);
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1 ps/1 ps
module alt_xcvr_native_prbs_accum (
input avmm_clk,
input avmm_reset,
// Control signals from CSR
input prbs_reset,
input prbs_snapshot,
input prbs_counter_en,
// Status signals from PRBS
output prbs_done_sync,
output [49:0] prbs_err_count,
output [49:0] prbs_bit_count,
// Signals from the transceiver
input rx_clkout,
input prbs_err_signal,
input prbs_done_signal
);
/**********************************************************************/
// wires for synchronizers
/**********************************************************************/
wire avmm_reset_sync;
wire prbs_reset_sync;
wire prbs_err_rx_sync;
wire prbs_done_rx_sync;
wire avmm_rx_cnt_edge_sync;
/**********************************************************************/
// Synchronizer for avmm_reset to rx_clkout
/**********************************************************************/
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 1 ),
.INIT_VALUE ( 1 )
) rx_clk_reset_sync (
.clk (rx_clkout),
.reset (avmm_reset),
.d (1'b0),
.q (avmm_reset_sync)
);
/**********************************************************************/
// Synchronizer for prbs_reset to rx_clkout
/**********************************************************************/
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 1 ),
.INIT_VALUE ( 1 )
) rx_clk_prbs_reset_sync (
.clk (rx_clkout),
.reset (prbs_reset),
.d (1'b0),
.q (prbs_reset_sync)
);
/**********************************************************************/
// Synchronizer for prbs_err to rx_clkout
/**********************************************************************/
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 2 ),
.WIDTH ( 1 ),
.INIT_VALUE ( 0 )
) rx_clk_prbs_err_sync (
.clk (rx_clkout),
.reset (avmm_reset_sync),
.d (prbs_err_signal),
.q (prbs_err_rx_sync)
);
/**********************************************************************/
// Synchronizer for prbs_done to rx_clkout
/**********************************************************************/
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 2 ),
.WIDTH ( 1 ),
.INIT_VALUE ( 0 )
) rx_clk_prbs_done_sync (
.clk (rx_clkout),
.reset (avmm_reset_sync),
.d (prbs_done_signal),
.q (prbs_done_rx_sync)
);
/**********************************************************************/
// wires and registers
/**********************************************************************/
wire rx_prbs_err_edge;
wire rx_prbs_cnt_edge;
wire avmm_prbs_cnt_edge;
reg rx_prbs_cnt_edge_reg;
reg rx_prbs_err_edge_reg;
reg avmm_prbs_cnt_edge_reg;
reg rx_error_high;
reg [3:0] rx_consecutive_error;
reg [7:0] rx_prbs_bit_count;
reg [7:0] rx_prbs_err_count;
reg [7:0] rx_prbs_err_snapshot;
reg [49:0] avmm_prbs_err_count;
reg [49:0] avmm_prbs_bit_count;
reg [49:0] avmm_prbs_err_snapshot;
reg [49:0] avmm_prbs_bit_snapshot;
/**********************************************************************/
// Logic on rx_clkout for accumulating bits and errors
/**********************************************************************/
assign rx_prbs_err_edge = (~rx_prbs_err_edge_reg && prbs_err_rx_sync);
assign rx_prbs_cnt_edge = (rx_prbs_cnt_edge_reg ^ rx_prbs_bit_count[7]);
always@(posedge rx_clkout or posedge avmm_reset_sync) begin
if(avmm_reset_sync) begin
rx_prbs_err_edge_reg <= 1'b0;
rx_prbs_cnt_edge_reg <= 1'b0;
rx_prbs_bit_count <= 8'b0;
rx_prbs_err_count <= 8'b0;
rx_prbs_err_snapshot <= 8'b0;
rx_consecutive_error <= 4'b0;
rx_error_high <= 1'b0;
end else if (prbs_reset_sync == 1'b1) begin
rx_prbs_err_edge_reg <= 1'b0;
rx_prbs_cnt_edge_reg <= 1'b0;
rx_prbs_bit_count <= 8'b0;
rx_prbs_err_count <= 8'b0;
rx_prbs_err_snapshot <= 8'b0;
rx_consecutive_error <= 4'b0;
rx_error_high <= 1'b0;
end else if (prbs_done_rx_sync == 1'b1) begin
// prbs error edge
rx_prbs_err_edge_reg <= prbs_err_rx_sync;
// prbs count edge
rx_prbs_cnt_edge_reg <= rx_prbs_bit_count[7];
// If the error signal is high for more than 7 cycles, constantly count errors
if(prbs_err_rx_sync == 1'b1) begin
if(&rx_consecutive_error) begin
rx_consecutive_error <= rx_consecutive_error;
end else begin
rx_consecutive_error <= rx_consecutive_error + 1'b1;
end
end else begin
rx_consecutive_error <= 4'b0;
end
rx_error_high <= (&rx_consecutive_error);
// error and bit accumulation
rx_prbs_bit_count <= rx_prbs_bit_count + 1'b1;
rx_prbs_err_count <= (rx_prbs_cnt_edge) ? {7'b0, rx_prbs_err_edge} : (rx_prbs_err_count + (rx_prbs_err_edge || rx_error_high));
rx_prbs_err_snapshot <= (rx_prbs_cnt_edge) ? rx_prbs_err_count : rx_prbs_err_snapshot;
end
end
/**********************************************************************/
// Synchronizer for prbs_done to avmm_clock
/**********************************************************************/
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 1 )
) avmm_clk_prbs_done_sync (
.clk (avmm_clk),
.reset (avmm_reset),
.d (prbs_done_signal),
.q (prbs_done_sync)
);
/**********************************************************************/
// Synchronizer for bit_count edge to avmm_clock
/**********************************************************************/
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 1 )
) avmm_clk_bit_count_edge (
.clk (avmm_clk),
.reset (avmm_reset),
.d (rx_prbs_cnt_edge_reg),
.q (avmm_rx_cnt_edge_sync)
);
/**********************************************************************/
// Logic for overall bit and error count in avmm_clk
/**********************************************************************/
assign prbs_err_count = avmm_prbs_err_snapshot;
assign prbs_bit_count = avmm_prbs_bit_snapshot;
assign avmm_prbs_cnt_edge = (avmm_prbs_cnt_edge_reg ^ avmm_rx_cnt_edge_sync);
always@(posedge avmm_clk or posedge avmm_reset) begin
if(avmm_reset) begin
avmm_prbs_bit_count <= 50'b0;
avmm_prbs_err_count <= 50'b0;
avmm_prbs_bit_snapshot <= 50'b0;
avmm_prbs_err_snapshot <= 50'b0;
avmm_prbs_cnt_edge_reg <= 1'b0;
end else if(prbs_reset) begin
avmm_prbs_bit_count <= 50'b0;
avmm_prbs_err_count <= 50'b0;
avmm_prbs_bit_snapshot <= 50'b0;
avmm_prbs_err_snapshot <= 50'b0;
avmm_prbs_cnt_edge_reg <= 1'b0;
end else if(prbs_counter_en) begin
avmm_prbs_cnt_edge_reg <= avmm_rx_cnt_edge_sync;
// on an edge of prbs count, accumulate the number of errors and bits
if(avmm_prbs_cnt_edge) begin
avmm_prbs_bit_count <= avmm_prbs_bit_count + 8'd128;
avmm_prbs_err_count <= avmm_prbs_err_count + rx_prbs_err_snapshot;
end else begin
avmm_prbs_bit_count <= avmm_prbs_bit_count;
avmm_prbs_err_count <= avmm_prbs_err_count;
end
// on a snapshot signal, capture the bit and error count to keep them in sync with each other
if(prbs_snapshot) begin
avmm_prbs_bit_snapshot <= avmm_prbs_bit_count;
avmm_prbs_err_snapshot <= avmm_prbs_err_count;
end else begin
avmm_prbs_bit_snapshot <= avmm_prbs_bit_snapshot;
avmm_prbs_err_snapshot <= avmm_prbs_err_snapshot;
end
end else begin
avmm_prbs_bit_count <= avmm_prbs_bit_count;
avmm_prbs_err_count <= avmm_prbs_err_count;
avmm_prbs_bit_snapshot <= avmm_prbs_bit_snapshot;
avmm_prbs_err_snapshot <= avmm_prbs_err_snapshot;
avmm_prbs_cnt_edge_reg <= avmm_prbs_cnt_edge_reg;
end
end
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1 ps/1 ps
module alt_xcvr_native_rcfg_arb #(
parameter total_masters = 4,
parameter channels = 1,
parameter address_width = 10,
parameter data_width = 32
) (
// Basic AVMM inputs
input [channels-1:0] reconfig_clk,
input [channels-1:0] reconfig_reset,
// User AVMM input
input [channels-1:0] user_read,
input [channels-1:0] user_write,
input [channels*address_width-1:0] user_address,
input [channels*data_width-1:0] user_writedata,
input [channels-1:0] user_read_write,
output [channels-1:0] user_waitrequest,
// Reconfig Steamer AVMM input
input [channels-1:0] strm_read,
input [channels-1:0] strm_write,
input [channels*address_width-1:0] strm_address,
input [channels*data_width-1:0] strm_writedata,
input [channels-1:0] strm_read_write,
output [channels-1:0] strm_waitrequest,
// ODI AVMM input
input [channels-1:0] odi_read,
input [channels-1:0] odi_write,
input [channels*address_width-1:0] odi_address,
input [channels*data_width-1:0] odi_writedata,
input [channels-1:0] odi_read_write,
output [channels-1:0] odi_waitrequest,
// ADME AVMM input
input [channels-1:0] jtag_read,
input [channels-1:0] jtag_write,
input [channels*address_width-1:0] jtag_address,
input [channels*data_width-1:0] jtag_writedata,
input [channels-1:0] jtag_read_write,
output [channels-1:0] jtag_waitrequest,
// PCIe DFE IP
input [channels-1:0] pcie_dfe_read,
input [channels-1:0] pcie_dfe_write,
input [channels*address_width-1:0] pcie_dfe_address,
input [channels*data_width-1:0] pcie_dfe_writedata,
input [channels-1:0] pcie_dfe_read_write,
output [channels-1:0] pcie_dfe_waitrequest,
// AVMM output the channel and the CSR
input [channels-1:0] avmm_waitrequest,
output [channels-1:0] avmm_read,
output [channels-1:0] avmm_write,
output [channels*address_width-1:0] avmm_address,
output [channels*data_width-1:0] avmm_writedata
);
// General wires
wire [channels*total_masters-1:0] grant;
wire [channels-1:0] strm_grants;
wire [channels-1:0] user_read_write_lcl;
// Variables for the generate loops
genvar ig; // For bus widths
genvar jg; // For Channels
generate for(jg=0;jg<channels;jg=jg+1) begin: g_arb
/*********************************************************************/
// case: 309705
// Simulation fix. When the user inputs drive x at the beginning of simulation,
// then even after a reset, the grant will have been assigned a value of x.
// since there is a loopback in the RTL, the value will continue to be x,
// and gets reflected on avmm_readdata and avmm_waitrequest. once an avmm master
// requests a read or write, the x value for grant will correct itself.
/**********************************************************************/
assign user_read_write_lcl[jg] =
// synthesis translate_off
(user_read_write[jg] === 1'bx) ? 1'b0 :
// synthesis translate_on
user_read_write[jg];
/**********************************************************************/
// Per Instance instantiations and assignments
// Priority in decreasing order is embedded reconfig -> odi -> user AVMM -> JTAG
/**********************************************************************/
alt_xcvr_arbiter #(
.width (total_masters)
) arbiter_inst (
.clock (reconfig_clk[jg]),
.req ({jtag_read_write[jg], user_read_write_lcl[jg], odi_read_write[jg], strm_read_write[jg], pcie_dfe_read_write[jg]}),
.grant (grant[jg*total_masters+:total_masters])
);
// Assign the grant signal
assign strm_grants[jg] = grant[(jg*total_masters)+1];
// Use the grant as a mask for the varoius read and writs signals
// if you or them all together, it will generate the read/write request if any are high
// For streamer write/read condition - if broadcasting, wait for all channels to receive grant before asserting write/read
assign avmm_write[jg] = |(grant[jg*total_masters+:total_masters] & {jtag_write[jg], user_write[jg], odi_write[jg], ((~&strm_write | &strm_grants) & strm_write[jg]), pcie_dfe_write[jg]});
assign avmm_read[jg] = |(grant[jg*total_masters+:total_masters] & {jtag_read[jg], user_read[jg], odi_read[jg], ((~&strm_read | &strm_grants) & strm_read[jg]), pcie_dfe_read[jg]});
// Split the wait request, and if the grant is asserted to any one master, assert wait request to all others
assign {jtag_waitrequest[jg], user_waitrequest[jg], odi_waitrequest[jg], strm_waitrequest[jg], pcie_dfe_waitrequest[jg]} = (~grant[jg*total_masters+:total_masters] | {total_masters{avmm_waitrequest[jg]}});
// Since thse are busses, the logic must be done in a bit-wise fashion; hence the for loop
// Generate the address for the bus width
for(ig=0; ig<address_width;ig=ig+1) begin: g_avmm_address
assign avmm_address[jg*address_width + ig] = |(grant[jg*total_masters+:total_masters] & {jtag_address[jg*address_width + ig], user_address[jg*address_width + ig], odi_address[jg*address_width + ig], strm_address[jg*address_width + ig], pcie_dfe_address[jg*address_width + ig]});
end // End g_avmm_address
// Generate the write data for the bus width
for(ig=0; ig<data_width;ig=ig+1) begin: g_avmm_writdata
assign avmm_writedata[jg*data_width+ ig] = |(grant[jg*total_masters+:total_masters] & {jtag_writedata[jg*data_width + ig], user_writedata[jg*data_width + ig],odi_writedata[jg*data_width + ig], strm_writedata[jg*data_width + ig], pcie_dfe_writedata[jg*data_width + ig]});
end // End g_avmm_writedata
end //End for channel-wise for loop
endgenerate // End generate
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1 ps/1 ps
module alt_xcvr_native_rcfg_opt_logic_7zb32zq #(
// Parameters for the embedded reconfiguration logic
parameter dbg_user_identifier = 0,
parameter duplex_mode = "duplex",
parameter dbg_embedded_debug_enable = 0,
parameter dbg_capability_reg_enable = 0,
parameter dbg_prbs_soft_logic_enable = 0,
parameter dbg_odi_soft_logic_enable = 0,
parameter dbg_stat_soft_logic_enable = 0,
parameter dbg_ctrl_soft_logic_enable = 0,
// Parameter for enabling the PCIe DFE IP
parameter enable_pcie_dfe_ip = 0,
parameter disable_continuous_dfe = 0,
parameter sim_reduced_counters = 0,
parameter enable_hip = 0,
// Parameters for the AVMM masters and split interface
parameter CHANNELS = 1,
parameter RECONFIG_SHARED = 0,
parameter JTAG_ENABLED = 0, // Can only be enabled when using a shared reconfig interface
parameter ADME_SLAVE_MAP = "altera_xcvr_native_a10",
parameter ADME_ASSGN_MAP = " ",
parameter RCFG_EMB_STRM_ENABLED = 0, // Enable the embedded reconfiguration streamer logic
parameter RCFG_PROFILE_CNT = 2, // Number of configuration profiles for embedded streamer
// The following are not intended to be directly set
parameter IFACES = RECONFIG_SHARED ? 1 : CHANNELS,
parameter ADDR_BITS = 10,
parameter SEL_BITS = (RECONFIG_SHARED ? altera_xcvr_native_a10_functions_h::clogb2_alt_xcvr_native_a10(CHANNELS-1) : 0),
parameter DATA_WIDTH = 32
) (
// User reconfig interface ports
input [IFACES-1:0] reconfig_clk,
input [IFACES-1:0] reconfig_reset,
input [IFACES-1:0] reconfig_write,
input [IFACES-1:0] reconfig_read,
input [IFACES*(ADDR_BITS+SEL_BITS)-1:0] reconfig_address,
input [IFACES*DATA_WIDTH-1:0] reconfig_writedata,
output [IFACES*DATA_WIDTH-1:0] reconfig_readdata,
output [IFACES-1:0] reconfig_waitrequest,
// AVMM ports to transceiver Split bychannel
output [CHANNELS-1:0] avmm_clk,
output [CHANNELS-1:0] avmm_reset,
output [CHANNELS-1:0] avmm_write,
output [CHANNELS-1:0] avmm_read,
output [CHANNELS*ADDR_BITS-1:0] avmm_address,
output [CHANNELS*8-1:0] avmm_writedata,
input [CHANNELS*8-1:0] avmm_readdata,
input [CHANNELS-1:0] avmm_waitrequest,
// input signals for PCIe DFE IP
input ltssm_detect_quiet,
input ltssm_detect_active,
input ltssm_rcvr_phase_two,
input [1:0] pcie_rate,
input hip_reduce_counters,
// input signals from the PHY for PRBSerror accumulation
input [CHANNELS-1:0] prbs_err_signal,
input [CHANNELS-1:0] prbs_done_signal,
// input rx_clkout
input [CHANNELS-1:0] in_rx_clkout,
// input status signals
input [CHANNELS-1:0] in_rx_is_lockedtoref,
input [CHANNELS-1:0] in_rx_is_lockedtodata,
input [CHANNELS-1:0] in_tx_cal_busy,
input [CHANNELS-1:0] in_rx_cal_busy,
input [CHANNELS-1:0] in_avmm_busy,
// input control signals
input [CHANNELS-1:0] in_rx_prbs_err_clr,
input [CHANNELS-1:0] in_set_rx_locktoref,
input [CHANNELS-1:0] in_set_rx_locktodata,
input [CHANNELS-1:0] in_en_serial_lpbk,
input [CHANNELS-1:0] in_rx_analogreset,
input [CHANNELS-1:0] in_rx_digitalreset,
input [CHANNELS-1:0] in_tx_analogreset,
input [CHANNELS-1:0] in_tx_digitalreset,
// output control signals to the phy
output [CHANNELS-1:0] out_prbs_err_clr,
output [CHANNELS-1:0] out_set_rx_locktoref,
output [CHANNELS-1:0] out_set_rx_locktodata,
output [CHANNELS-1:0] out_en_serial_lpbk,
output [CHANNELS-1:0] out_rx_analogreset,
output [CHANNELS-1:0] out_rx_digitalreset,
output [CHANNELS-1:0] out_tx_analogreset,
output [CHANNELS-1:0] out_tx_digitalreset,
output [CHANNELS-1:0] out_tx_cal_busy_mask,
output [CHANNELS-1:0] out_rx_cal_busy_mask
);
/**********************************************************************/
// Per Instance instantiations and assignments
/**********************************************************************/
localparam CHANNEL_SEL_WIDTH = altera_xcvr_native_a10_functions_h::clogb2_alt_xcvr_native_a10(CHANNELS-1);
localparam ENABLED_JTAG_MASTERS = 1 + dbg_odi_soft_logic_enable + JTAG_ENABLED + RCFG_EMB_STRM_ENABLED + enable_pcie_dfe_ip;
localparam RCFG_EMB_STRM_CFG_SEL_WIDTH = altera_xcvr_native_a10_functions_h::clogb2_alt_xcvr_native_a10(RCFG_PROFILE_CNT-1);
// Raw rmbedded reconfig signals (always independent)
wire [CHANNELS-1:0] rcfg_emb_strm_write;
wire [CHANNELS-1:0] rcfg_emb_strm_read;
wire [CHANNELS*ADDR_BITS-1:0] rcfg_emb_strm_address;
wire [CHANNELS*DATA_WIDTH-1:0] rcfg_emb_strm_writedata;
wire [CHANNELS-1:0] rcfg_emb_strm_waitrequest;
// User AVMM signals expanded to independent channels
wire [CHANNELS-1:0] split_user_write;
wire [CHANNELS-1:0] split_user_read;
wire [CHANNELS*ADDR_BITS-1:0] split_user_address;
wire [CHANNELS*DATA_WIDTH-1:0] split_user_writedata;
wire [CHANNELS-1:0] split_user_waitrequest;
// ODI AVMM signals
wire [CHANNELS-1:0] odi_write;
wire [CHANNELS-1:0] odi_read;
wire [CHANNELS*ADDR_BITS-1:0] odi_address;
wire [CHANNELS*DATA_WIDTH-1:0] odi_writedata;
wire [CHANNELS-1:0] odi_waitrequest;
// PCIe DFE ip
wire [CHANNELS-1:0] split_pcie_dfe_write;
wire [CHANNELS-1:0] split_pcie_dfe_read;
wire [CHANNELS*ADDR_BITS-1:0] split_pcie_dfe_address;
wire [CHANNELS*DATA_WIDTH-1:0] split_pcie_dfe_writedata;
wire [CHANNELS-1:0] split_pcie_dfe_waitrequest;
wire pcie_dfe_avmm_lock;
// JTAG signals expanded to independent channels
wire [CHANNELS-1:0] split_jtag_write;
wire [CHANNELS-1:0] split_jtag_read;
wire [CHANNELS*ADDR_BITS-1:0] split_jtag_address;
wire [CHANNELS*DATA_WIDTH-1:0] split_jtag_writedata;
wire [CHANNELS-1:0] split_jtag_waitrequest;
// Additional arbitration signals for soft CSR
wire [CHANNELS-1:0] chnl_write;
wire [CHANNELS-1:0] chnl_read;
wire [CHANNELS-1:0] chnl_busy;
wire [CHANNELS-1:0] chnl_waitrequest;
wire [CHANNELS*8-1:0] chnl_readdata;
// embedded reconfig signals
wire [CHANNELS-1:0] rcfg_emb_strm_busy;
wire [CHANNELS-1:0] rcfg_emb_strm_chan_sel;
wire [CHANNELS*RCFG_EMB_STRM_CFG_SEL_WIDTH-1:0] rcfg_emb_strm_cfg_sel;
wire [CHANNELS-1:0] rcfg_emb_strm_bcast_en;
wire [CHANNELS-1:0] rcfg_emb_strm_cfg_load;
// Read_write signals to assist with prioritizing arbitrarion
wire [CHANNELS-1:0] user_read_write;
wire [CHANNELS-1:0] odi_read_write;
wire [CHANNELS-1:0] pcie_dfe_read_write;
wire [CHANNELS-1:0] jtag_read_write;
wire [CHANNELS-1:0] rcfg_emb_strm_read_write;
// Wires for converting between data widths
wire [CHANNELS*DATA_WIDTH-1:0] expanded_avmm_readdata;
wire [CHANNELS*DATA_WIDTH-1:0] expanded_avmm_writedata;
// Wires for control and status signals between the various masters
wire [CHANNELS-1:0] odi_done;
wire [CHANNELS-1:0] prbs_done_sync;
wire [CHANNELS*50-1:0] prbs_err_count;
wire [CHANNELS*50-1:0] prbs_bit_count;
wire [CHANNELS*50-1:0] odi_err_count;
wire [CHANNELS*50-1:0] odi_bit_count;
// Wires for qmap cleanup
wire lcl_g_arbiter_dis;
wire lcl_g_avmm_csr_dis;
wire lcl_ground;
// Warning Removal
assign lcl_g_avmm_csr_dis = &{1'b0,
rcfg_emb_strm_busy,
prbs_done_sync,
odi_done,
prbs_err_count,
prbs_bit_count,
odi_bit_count,
odi_err_count};
assign lcl_g_arbiter_dis = &{1'b0,
rcfg_emb_strm_address,
rcfg_emb_strm_writedata,
odi_address,
odi_writedata,
split_pcie_dfe_address,
split_pcie_dfe_writedata,
split_jtag_address,
split_jtag_writedata,
user_read_write,
odi_read_write,
pcie_dfe_read_write,
jtag_read_write,
rcfg_emb_strm_read_write};
assign lcl_ground = &{1'b0,
lcl_g_avmm_csr_dis,
lcl_g_arbiter_dis};
// Generate variable for channel numbers
genvar ig;
/**********************************************************************/
// Generate Statement for the Shared vs Split user interface
/**********************************************************************/
generate
// Expand the AVMM signals from the channel to the 32-bit interface of the user
for(ig=0;ig<CHANNELS;ig=ig+1) begin: g_expanded_avmm_signals
assign expanded_avmm_readdata [ig*DATA_WIDTH +: DATA_WIDTH] = {24'd0,chnl_readdata [ig*8 +: 8]};
assign avmm_writedata [ig*8 +: 8] = expanded_avmm_writedata [ig*DATA_WIDTH +: 8];
end
/**********************************************************************/
// Split the reconfig interface to the independent channel when using shared reconfig
/**********************************************************************/
if(!RECONFIG_SHARED) begin : g_not_shared
// Signals are already split, so wire straight through
assign avmm_clk = reconfig_clk;
assign avmm_reset = reconfig_reset;
assign split_user_write = reconfig_write;
assign split_user_read = reconfig_read;
assign split_user_address = reconfig_address;
assign split_user_writedata = reconfig_writedata;
assign reconfig_readdata = expanded_avmm_readdata;
assign reconfig_waitrequest = ({CHANNELS{lcl_ground}} | split_user_waitrequest);
// If we are using a shared interface
end else begin : g_shared
wire [CHANNEL_SEL_WIDTH-1:0] rcfg_if_sel;
// Generate interface select based on upper address bits
assign rcfg_if_sel = reconfig_address[ADDR_BITS+:CHANNEL_SEL_WIDTH];
assign reconfig_readdata = expanded_avmm_readdata[rcfg_if_sel*DATA_WIDTH +: DATA_WIDTH];
assign reconfig_waitrequest = split_user_waitrequest[rcfg_if_sel];
for(ig=0;ig<CHANNELS;ig=ig+1) begin : g_shared
// Split shared signals to independent channels
assign avmm_clk [ig] = reconfig_clk;
assign avmm_reset [ig] = reconfig_reset;
assign split_user_write [ig] = reconfig_write & (rcfg_if_sel == ig) | lcl_ground;
assign split_user_read [ig] = reconfig_read & (rcfg_if_sel == ig);
assign split_user_address [ig*ADDR_BITS +: ADDR_BITS] = reconfig_address[0+:ADDR_BITS];
assign split_user_writedata [ig*DATA_WIDTH +: DATA_WIDTH] = reconfig_writedata;
end
end //End g_not_shared
endgenerate
/**********************************************************************/
// Embedded JTAG Debug Master (ADME)
/**********************************************************************/
generate if(JTAG_ENABLED) begin : g_jtag
// Set the slave type for the ADME. Since the span needs to be a string, 2^(total addr_bits) will
// give the max value, however since the adme uses byte alignment, shift the span by two bits.
localparam set_slave_span = altera_xcvr_native_a10_functions_h::int2str_alt_xcvr_native_a10(2**(ADDR_BITS+CHANNEL_SEL_WIDTH+2));
localparam set_slave_map = {"{typeName ",ADME_SLAVE_MAP," address 0x0 span ",set_slave_span," hpath {}",ADME_ASSGN_MAP,"}"};
// Raw JTAG signals
wire jtag_write;
wire jtag_read;
wire [(ADDR_BITS+CHANNEL_SEL_WIDTH)-1:0] jtag_address;
wire [DATA_WIDTH-1:0] jtag_writedata;
wire [DATA_WIDTH-1:0] jtag_readdata;
wire jtag_waitrequest;
wire jtag_readdatavalid;
wire [CHANNEL_SEL_WIDTH-1:0] jtag_if_sel;
// Generate channel select based on upper address bits
assign jtag_if_sel = jtag_address[ADDR_BITS+:CHANNEL_SEL_WIDTH];
assign jtag_readdata = expanded_avmm_readdata[jtag_if_sel*DATA_WIDTH +: DATA_WIDTH];
assign jtag_waitrequest = split_jtag_waitrequest[jtag_if_sel];
// Split shared signals to independent channels
for(ig=0;ig<CHANNELS;ig=ig+1) begin: g_expanded_avmm_signals
assign split_jtag_write [ig] = jtag_write & (jtag_if_sel == ig);
assign split_jtag_read [ig] = jtag_read & (jtag_if_sel == ig);
assign split_jtag_address [ig*ADDR_BITS +: ADDR_BITS] = jtag_address[0+:ADDR_BITS];
assign split_jtag_writedata [ig*DATA_WIDTH +: DATA_WIDTH] = jtag_writedata[DATA_WIDTH-1:0];
end
// When doing RTL sims, remove the altera_debug_master_endpoint, as
// there is no RTL simulation model. Pre and Post Fit sims are ok.
`ifdef ALTERA_RESERVED_QIS
altera_debug_master_endpoint
#(
.ADDR_WIDTH ( (ADDR_BITS+CHANNEL_SEL_WIDTH) ),
.DATA_WIDTH ( DATA_WIDTH ),
.HAS_RDV ( 0 ),
.SLAVE_MAP ( set_slave_map ),
.PREFER_HOST ( " " ),
.CLOCK_RATE_CLK ( 0 )
) adme (
.clk ( reconfig_clk ),
.reset ( reconfig_reset ),
.master_write ( jtag_write ),
.master_read ( jtag_read ),
.master_address ( jtag_address ),
.master_writedata ( jtag_writedata ),
.master_waitrequest ( jtag_waitrequest ),
.master_readdatavalid ( jtag_readdatavalid ),
.master_readdata ( jtag_readdata )
);
`else
assign jtag_write = 1'b0;
assign jtag_read = 1'b0;
assign jtag_address = {(ADDR_BITS+CHANNEL_SEL_WIDTH){1'b0}};
assign jtag_writedata = {DATA_WIDTH{1'b0}};
`endif
// If we have not enabled the ADME
end else begin : g_jtag_disable
assign split_jtag_write = {CHANNELS{1'b0}};
assign split_jtag_read = {CHANNELS{1'b0}};
assign split_jtag_address = {(CHANNELS*ADDR_BITS){1'b0}};
assign split_jtag_writedata = {(CHANNELS*DATA_WIDTH){1'b0}};
end
endgenerate // End g_jtag
/**********************************************************************/
// Enable the PCIe DFE IP
/**********************************************************************/
generate if(enable_pcie_dfe_ip) begin : g_pcie_dfe_ip
// Raw JTAG signals
wire pcie_dfe_write;
wire pcie_dfe_read;
wire [(ADDR_BITS+CHANNEL_SEL_WIDTH)-1:0] pcie_dfe_address;
wire [DATA_WIDTH-1:0] pcie_dfe_writedata;
wire [DATA_WIDTH-1:0] pcie_dfe_readdata;
wire pcie_dfe_waitrequest;
wire [CHANNEL_SEL_WIDTH-1:0] pcie_dfe_if_sel;
// Generate channel select based on upper address bits
assign pcie_dfe_if_sel = pcie_dfe_address[ADDR_BITS+:CHANNEL_SEL_WIDTH];
assign pcie_dfe_readdata = expanded_avmm_readdata[pcie_dfe_if_sel*DATA_WIDTH +: DATA_WIDTH];
assign pcie_dfe_waitrequest = split_pcie_dfe_waitrequest[pcie_dfe_if_sel];
// Split shared signals to independent channels
for(ig=0;ig<CHANNELS;ig=ig+1) begin: g_expanded_avmm_signals
assign split_pcie_dfe_write [ig] = pcie_dfe_write & (pcie_dfe_if_sel == ig);
assign split_pcie_dfe_read [ig] = pcie_dfe_read & (pcie_dfe_if_sel == ig);
assign split_pcie_dfe_address [ig*ADDR_BITS +: ADDR_BITS] = pcie_dfe_address[0+:ADDR_BITS];
assign split_pcie_dfe_writedata [ig*DATA_WIDTH +: DATA_WIDTH] = pcie_dfe_writedata[DATA_WIDTH-1:0];
end
altera_xcvr_native_pcie_dfe_ip #(
.num_channels ( CHANNELS ),
.disable_continuous_dfe ( disable_continuous_dfe ),
.enable_hip ( enable_hip ),
.sim_reduced_counters ( sim_reduced_counters ),
.avmm_sel_bits ( CHANNEL_SEL_WIDTH ),
.avmm_addr_bits ( ADDR_BITS )
) altera_xcvr_native_pcie_dfe_ip_inst (
.clock ( reconfig_clk ),
.reset ( reconfig_reset ),
.ltssm_detect_quiet ( ltssm_detect_quiet ),
.ltssm_detect_active ( ltssm_detect_active ),
.ltssm_rcvr_phase_two ( ltssm_rcvr_phase_two ),
.pcie_rate_sw ( pcie_rate ),
// HIP only port for reduced counters
.hip_reduce_counters ( hip_reduce_counters ),
// Reconfig Interface to the transceiver
.xcvr_rcfg_waitrequest ( pcie_dfe_waitrequest ),
.xcvr_rcfg_readdata ( pcie_dfe_readdata ),
.xcvr_rcfg_lock ( pcie_dfe_avmm_lock ),
.xcvr_rcfg_read ( pcie_dfe_read ),
.xcvr_rcfg_write ( pcie_dfe_write ),
.xcvr_rcfg_address ( pcie_dfe_address ),
.xcvr_rcfg_writedata ( pcie_dfe_writedata )
);
end else begin : g_disable_pcie_dfe_ip
assign pcie_dfe_avmm_lock = 1'b0;
assign split_pcie_dfe_write = {CHANNELS{1'b0}};
assign split_pcie_dfe_read = {CHANNELS{1'b0}};
assign split_pcie_dfe_address = {(CHANNELS*ADDR_BITS){1'b0}};
assign split_pcie_dfe_writedata = {(CHANNELS*DATA_WIDTH){1'b0}};
end
endgenerate
/**********************************************************************/
// Embedded Reconfig Streamer
/**********************************************************************/
generate if(RCFG_EMB_STRM_ENABLED) begin : g_rcfg_strm_enable //TODO check to see if there is parameter redundancy
alt_xcvr_native_rcfg_strm_top_7zb32zq #(
.xcvr_rcfg_interfaces ( CHANNELS ),
.xcvr_rcfg_addr_width ( ADDR_BITS ),
.xcvr_rcfg_data_width ( DATA_WIDTH ),
.rcfg_profile_cnt ( RCFG_PROFILE_CNT )
)rcfg_strm_top_inst(
.clk ( reconfig_clk[0] ), // All clock bits should be driven by the same source if using independent interface
.reset ( |reconfig_reset ), // Any reset bit will reset the reconfig streamer
.cfg_sel ( rcfg_emb_strm_cfg_sel ),
.bcast_en ( rcfg_emb_strm_bcast_en ),
.cfg_load ( rcfg_emb_strm_cfg_load ),
.chan_sel ( rcfg_emb_strm_chan_sel ),
.stream_busy ( rcfg_emb_strm_busy ),
.xcvr_reconfig_write ( rcfg_emb_strm_write ),
.xcvr_reconfig_read ( rcfg_emb_strm_read ),
.xcvr_reconfig_address ( rcfg_emb_strm_address ),
.xcvr_reconfig_writedata ( rcfg_emb_strm_writedata ),
.xcvr_reconfig_readdata ( expanded_avmm_readdata ),
.xcvr_reconfig_waitrequest ( rcfg_emb_strm_waitrequest )
);
// If we disable the reconfig streamer
end else begin: g_rcfg_strm_disable
assign rcfg_emb_strm_write = {CHANNELS{1'b0}};
assign rcfg_emb_strm_read = {CHANNELS{1'b0}};
assign rcfg_emb_strm_address = {(CHANNELS*ADDR_BITS){1'b0}};
assign rcfg_emb_strm_writedata = {CHANNELS{32'b0}};
assign rcfg_emb_strm_busy = {CHANNELS{1'b0}};
end
endgenerate // End g_rcfg_strm_enable
/**********************************************************************/
// AVMM Master read/write signals.
/**********************************************************************/
assign user_read_write = split_user_read | split_user_write; // Bits asserted for corresponding channels from/to which user avmm is currently reading/writing
assign jtag_read_write = split_jtag_read | split_jtag_write; // Bits asserted for corresponding channels from/to which jtag is currently reading/writing
assign rcfg_emb_strm_read_write = rcfg_emb_strm_read | rcfg_emb_strm_write; // Bits asserted for corresponding channels from/to which embedded streamer is currently reading/writing
assign odi_read_write = odi_read | odi_write;
assign pcie_dfe_read_write = split_pcie_dfe_read | split_pcie_dfe_write | {CHANNELS{pcie_dfe_avmm_lock}};
/**********************************************************************/
// AVMM Arbiter. Instantiated once per channel, however to handle streaming
// broadcast, the channel-wise instantiation is handled within the arbiter.
/**********************************************************************/
generate if (ENABLED_JTAG_MASTERS > 1) begin: g_arbiber_enable
alt_xcvr_native_rcfg_arb #(
.total_masters ( 5 ),
.channels ( CHANNELS ),
.address_width ( ADDR_BITS ),
.data_width ( DATA_WIDTH )
) alt_xcvr_rcfg_arb (
// Basic AVMM inputs
.reconfig_clk ( avmm_clk ),
.reconfig_reset ( avmm_reset ),
// User AVMM input
.user_read ( split_user_read ),
.user_write ( split_user_write ),
.user_address ( split_user_address ),
.user_writedata ( split_user_writedata ),
.user_read_write ( user_read_write ),
.user_waitrequest ( split_user_waitrequest ),
// Reconfig Steamer AVMM input
.strm_read ( rcfg_emb_strm_read ),
.strm_write ( rcfg_emb_strm_write ),
.strm_address ( rcfg_emb_strm_address ),
.strm_writedata ( rcfg_emb_strm_writedata ),
.strm_read_write ( rcfg_emb_strm_read_write ),
.strm_waitrequest ( rcfg_emb_strm_waitrequest ),
// ODI AVMM input
.odi_read ( odi_read ),
.odi_write ( odi_write ),
.odi_address ( odi_address ),
.odi_writedata ( odi_writedata ),
.odi_read_write ( odi_read_write ),
.odi_waitrequest ( odi_waitrequest ),
// ADME AVMM input
.jtag_read ( split_jtag_read ),
.jtag_write ( split_jtag_write ),
.jtag_address ( split_jtag_address ),
.jtag_writedata ( split_jtag_writedata ),
.jtag_read_write ( jtag_read_write ),
.jtag_waitrequest ( split_jtag_waitrequest ),
// PCIe DFE
.pcie_dfe_read ( split_pcie_dfe_read ),
.pcie_dfe_write ( split_pcie_dfe_write ),
.pcie_dfe_address ( split_pcie_dfe_address ),
.pcie_dfe_writedata ( split_pcie_dfe_writedata ),
.pcie_dfe_read_write ( pcie_dfe_read_write ),
.pcie_dfe_waitrequest ( split_pcie_dfe_waitrequest ),
// AVMM output the channel and the CSR
.avmm_waitrequest ( chnl_waitrequest ),
.avmm_read ( chnl_read ),
.avmm_write ( chnl_write ),
.avmm_address ( avmm_address ),
.avmm_writedata ( expanded_avmm_writedata )
);
end else begin: g_arbiter_disable
// Pass through signals
assign split_user_waitrequest = chnl_waitrequest;
assign chnl_read = split_user_read;
assign chnl_write = split_user_write;
assign expanded_avmm_writedata = split_user_writedata;
assign avmm_address = split_user_address;
end
endgenerate // End g_arbiter
/**********************************************************************/
// Per Channel instantiations and assignments
/**********************************************************************/
generate for(ig=0;ig<CHANNELS;ig=ig+1) begin: g_optional_chnl_reconfig_logic
wire [CHANNELS-1:0] csr_prbs_snapshot;
wire [CHANNELS-1:0] csr_prbs_count_en;
wire [CHANNELS-1:0] csr_odi_count_en;
wire [CHANNELS-1:0] csr_odi_snap;
wire [CHANNELS-1:0] csr_odi_reset;
/**********************************************************************/
// Instantiate the Soft CSR
/**********************************************************************/
if(dbg_embedded_debug_enable) begin: g_avmm_csr_enabled
// Instantiate wires as part of generate to avoid warnings about unused wires.
// AVMM reconfiguration signals for embedded debug
wire [CHANNELS-1:0] debug_write;
wire [CHANNELS-1:0] debug_read;
wire [CHANNELS-1:0] debug_waitrequest;
wire [CHANNELS*8-1:0] debug_readdata;
// avmm arbitration for soft csr and channel
assign debug_read [ig] = (avmm_address[ig*ADDR_BITS+9]) ? chnl_read [ig] : 1'b0;
assign debug_write [ig] = (avmm_address[ig*ADDR_BITS+9]) ? chnl_write [ig] : 1'b0;
assign avmm_read [ig] = (avmm_address[ig*ADDR_BITS+9]) ? 1'b0 : chnl_read [ig];
assign avmm_write [ig] = (avmm_address[ig*ADDR_BITS+9]) ? 1'b0 : chnl_write [ig];
assign chnl_waitrequest [ig] = (avmm_address[ig*ADDR_BITS+9]) ? debug_waitrequest [ig] : avmm_waitrequest [ig];
assign chnl_readdata [ig*8+:8] = (avmm_address[ig*ADDR_BITS+9]) ? debug_readdata [ig*8+:8] : avmm_readdata [ig*8+:8];
alt_xcvr_native_avmm_csr #(
.channels ( CHANNELS ),
.channel_num ( ig ),
.dbg_user_identifier ( dbg_user_identifier ),
.duplex_mode ( duplex_mode ),
.dbg_capability_reg_enable ( dbg_capability_reg_enable ),
.dbg_prbs_soft_logic_enable ( dbg_prbs_soft_logic_enable ),
.dbg_odi_soft_logic_enable ( dbg_odi_soft_logic_enable ),
.dbg_stat_soft_logic_enable ( dbg_stat_soft_logic_enable ),
.dbg_ctrl_soft_logic_enable ( dbg_ctrl_soft_logic_enable ),
.rcfg_emb_strm_enable ( RCFG_EMB_STRM_ENABLED ),
.rcfg_emb_strm_cfg_sel_width ( RCFG_EMB_STRM_CFG_SEL_WIDTH )
) embedded_debug_soft_csr (
// avmm signals
.avmm_clk ( avmm_clk [ig] ),
.avmm_reset ( avmm_reset [ig] ),
.avmm_address ( avmm_address [ig*ADDR_BITS+:9] ),
.avmm_writedata ( avmm_writedata [ig*8+:8] ),
.avmm_write ( debug_write [ig] ),
.avmm_read ( debug_read [ig] ),
.avmm_readdata ( debug_readdata [ig*8+:8] ),
.avmm_waitrequest ( debug_waitrequest [ig] ),
// prbs control signals
.prbs_err ( prbs_err_count [ig*50+:50]),
.prbs_bit ( prbs_bit_count [ig*50+:50]),
.prbs_done ( prbs_done_sync [ig] ),
.prbs_snap ( csr_prbs_snapshot [ig] ),
.prbs_count_en ( csr_prbs_count_en [ig] ),
.prbs_reset ( out_prbs_err_clr [ig] ),
// odi ctrl signals
.odi_bit ( odi_bit_count [ig*50+:50]),
.odi_err ( odi_err_count [ig*50+:50]),
.odi_done ( odi_done [ig] ),
.odi_count_en ( csr_odi_count_en [ig] ),
.odi_reset ( csr_odi_reset [ig] ),
.odi_snap ( csr_odi_snap [ig] ),
// input status signals from the channel
.rx_is_lockedtodata ( in_rx_is_lockedtodata [ig] ),
.rx_is_lockedtoref ( in_rx_is_lockedtoref [ig] ),
.tx_cal_busy ( in_tx_cal_busy [ig] ),
.rx_cal_busy ( in_rx_cal_busy [ig] ),
.avmm_busy ( in_avmm_busy [ig] ),
// input control signals
.rx_prbs_err_clr ( in_rx_prbs_err_clr [ig] ),
.set_rx_locktoref ( in_set_rx_locktoref [ig] ),
.set_rx_locktodata ( in_set_rx_locktodata [ig] ),
.serial_loopback ( in_en_serial_lpbk [ig] ),
.rx_analogreset ( in_rx_analogreset [ig] ),
.rx_digitalreset ( in_rx_digitalreset [ig] ),
.tx_analogreset ( in_tx_analogreset [ig] ),
.tx_digitalreset ( in_tx_digitalreset [ig] ),
// embedded reconfig signals
.rcfg_emb_strm_busy ( rcfg_emb_strm_busy [ig] ),
.rcfg_emb_strm_chan_sel ( rcfg_emb_strm_chan_sel [ig] ),
.rcfg_emb_strm_cfg_sel ( rcfg_emb_strm_cfg_sel [ig*RCFG_EMB_STRM_CFG_SEL_WIDTH+:RCFG_EMB_STRM_CFG_SEL_WIDTH]),
.rcfg_emb_strm_bcast_en ( rcfg_emb_strm_bcast_en [ig] ),
.rcfg_emb_strm_cfg_load ( rcfg_emb_strm_cfg_load [ig] ),
// output control signals to the channel
.csr_set_lock_to_data ( out_set_rx_locktodata [ig] ),
.csr_set_lock_to_ref ( out_set_rx_locktoref [ig] ),
.csr_en_loopback ( out_en_serial_lpbk [ig] ),
.csr_rx_analogreset ( out_rx_analogreset [ig] ),
.csr_rx_digitalreset ( out_rx_digitalreset [ig] ),
.csr_tx_analogreset ( out_tx_analogreset [ig] ),
.csr_tx_digitalreset ( out_tx_digitalreset [ig] ),
.csr_tx_cal_busy_mask ( out_tx_cal_busy_mask [ig] ),
.csr_rx_cal_busy_mask ( out_rx_cal_busy_mask [ig] )
);
end else begin: g_avmm_csr_disable
// do a pass though for control signals when no embedded debug
assign out_prbs_err_clr [ig] = in_rx_prbs_err_clr [ig];
assign out_set_rx_locktoref [ig] = in_set_rx_locktoref [ig];
assign out_set_rx_locktodata [ig] = in_set_rx_locktodata [ig];
assign out_en_serial_lpbk [ig] = in_en_serial_lpbk [ig];
assign out_rx_analogreset [ig] = in_rx_analogreset [ig];
assign out_rx_digitalreset [ig] = in_rx_digitalreset [ig];
assign out_tx_analogreset [ig] = in_tx_analogreset [ig];
assign out_tx_digitalreset [ig] = in_tx_digitalreset [ig];
assign out_tx_cal_busy_mask [ig] = 1'b1;
assign out_rx_cal_busy_mask [ig] = 1'b1;
// assign these signals to ground when no embedded debug
assign avmm_read [ig] = chnl_read [ig];
assign avmm_write [ig] = chnl_write [ig];
assign chnl_waitrequest [ig] = avmm_waitrequest [ig];
assign chnl_readdata [ig*8+:8] = avmm_readdata [ig*8+:8];
end
/**********************************************************************/
// Instantiate the PRBS accumulators
/**********************************************************************/
if(dbg_prbs_soft_logic_enable == 1) begin: g_prbs_accumulators_enable
alt_xcvr_native_prbs_accum prbs_soft_accumulators (
.avmm_clk ( avmm_clk [ig] ),
.avmm_reset ( avmm_reset [ig] ),
// Control signals from CSR
.prbs_reset ( out_prbs_err_clr [ig] ),
.prbs_snapshot ( csr_prbs_snapshot [ig] ),
.prbs_counter_en ( csr_prbs_count_en [ig] ),
// Status signals from PRBS
.prbs_done_sync ( prbs_done_sync [ig] ),
.prbs_err_count ( prbs_err_count [ig*50+:50] ),
.prbs_bit_count ( prbs_bit_count [ig*50+:50] ),
// Signals from the transceiver
.rx_clkout ( in_rx_clkout [ig] ),
.prbs_err_signal ( prbs_err_signal [ig] ),
.prbs_done_signal ( prbs_done_signal [ig] )
);
// If PRBS is not enabled
end else begin: g_prbs_accumulators_disable
assign prbs_err_count[ig*50+:50] = 50'b0;
assign prbs_bit_count[ig*50+:50] = 50'b0;
assign prbs_done_sync[ig] = 1'b0;
end // End g_prbs_accumulators
/**********************************************************************/
// Instantiate the ODI accumulators
/**********************************************************************/
if(dbg_odi_soft_logic_enable == 1) begin: g_odi_accelerator_enable
alt_xcvr_native_odi_accel #(
.DATA_WIDTH ( DATA_WIDTH )
) odi_soft_accelerator (
.avmm_clk ( avmm_clk [ig] ),
.avmm_reset ( avmm_reset [ig] ),
// AVMM signals to the transceiver
.odi_read ( odi_read [ig] ),
.odi_write ( odi_write [ig] ),
.odi_address ( odi_address [ig*ADDR_BITS+:ADDR_BITS] ),
.odi_writedata ( odi_writedata [ig*DATA_WIDTH+:DATA_WIDTH]),
.odi_readdata ( avmm_readdata [ig*8+:8] ),
.odi_waitrequest ( odi_waitrequest [ig] ),
// Control signals from CSR
.odi_count_en ( csr_odi_count_en [ig] ),
.odi_snap ( csr_odi_snap [ig] ),
.odi_reset ( csr_odi_reset [ig] ),
// Status signals from ODI
.odi_done ( odi_done [ig] ),
.odi_bit_count ( odi_bit_count [ig*50+:50] ),
.odi_err_count ( odi_err_count [ig*50+:50] )
);
end else begin: g_odi_accelerator_disable
assign odi_read[ig] = 1'b0;
assign odi_write[ig] = 1'b0;
assign odi_done[ig] = 1'b0;
assign odi_bit_count[ig*50+:50] = 50'b0;
assign odi_err_count[ig*50+:50] = 50'b0;
assign odi_address[ig*ADDR_BITS+:ADDR_BITS] = {ADDR_BITS{1'b0}};
assign odi_writedata[ig*DATA_WIDTH+:DATA_WIDTH] = {DATA_WIDTH{1'b0}};
end // End g_odi_accelerator
end // End for Loop for channels
endgenerate
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// Module: alt_xcvr_resync
//
// Description:
// A general purpose resynchronization module.
//
// Parameters:
// SYNC_CHAIN_LENGTH
// - Specifies the length of the synchronizer chain for metastability
// retiming.
// WIDTH
// - Specifies the number of bits you want to synchronize. Controls the width of the
// d and q ports.
// SLOW_CLOCK - USE WITH CAUTION.
// - Leaving this setting at its default will create a standard resynch circuit that
// merely passes the input data through a chain of flip-flops. This setting assumes
// that the input data has a pulse width longer than one clock cycle sufficient to
// satisfy setup and hold requirements on at least one clock edge.
// - By setting this to 1 (USE CAUTION) you are creating an asynchronous
// circuit that will capture the input data regardless of the pulse width and
// its relationship to the clock. However it is more difficult to apply static
// timing constraints as it ties the data input to the clock input of the flop.
// This implementation assumes the data rate is slow enough
// INIT_VALUE
// - Specifies the initial values of the synchronization registers.
//
// Apply embedded false path timing constraint
(* altera_attribute = "-name SDC_STATEMENT \"set regs [get_registers -nowarn *alt_xcvr_resync*sync_r[0]]; if {[llength [query_collection -report -all $regs]] > 0} {set_false_path -to $regs}\"" *)
`timescale 1ps/1ps
module alt_xcvr_resync #(
parameter SYNC_CHAIN_LENGTH = 2, // Number of flip-flops for retiming. Must be >1
parameter WIDTH = 1, // Number of bits to resync
parameter SLOW_CLOCK = 0, // See description above
parameter INIT_VALUE = 0
) (
input wire clk,
input wire reset,
input wire [WIDTH-1:0] d,
output wire [WIDTH-1:0] q
);
localparam INT_LEN = (SYNC_CHAIN_LENGTH > 1) ? SYNC_CHAIN_LENGTH : 2;
localparam [INT_LEN-1:0] L_INIT_VALUE = (INIT_VALUE == 1) ? {INT_LEN{1'b1}} : {INT_LEN{1'b0}};
genvar ig;
// Generate a synchronizer chain for each bit
generate begin
for(ig=0;ig<WIDTH;ig=ig+1) begin : resync_chains
wire d_in; // Input to sychronization chain.
(* altera_attribute = "disable_da_rule=D103" *)
reg [INT_LEN-1:0] sync_r = L_INIT_VALUE;
assign q[ig] = sync_r[INT_LEN-1]; // Output signal
always @(posedge clk or posedge reset)
if(reset)
sync_r <= L_INIT_VALUE;
else
sync_r <= {sync_r[INT_LEN-2:0],d_in};
// Generate asynchronous capture circuit if specified.
if(SLOW_CLOCK == 0) begin
assign d_in = d[ig];
end else begin
wire d_clk;
reg d_r = L_INIT_VALUE[0];
wire clr_n;
assign d_clk = d[ig];
assign d_in = d_r;
assign clr_n = ~q[ig] | d_clk; // Clear when output is logic 1 and input is logic 0
// Asynchronously latch the input signal.
always @(posedge d_clk or negedge clr_n)
if(!clr_n) d_r <= 1'b0;
else if(d_clk) d_r <= 1'b1;
end // SLOW_CLOCK
end // for loop
end // generate
endgenerate
endmodule
# (C) 2001-2018 Intel Corporation. All rights reserved.
# Your use of Intel Corporation's design tools, logic functions and other
# software and tools, and its AMPP partner logic functions, and any output
# files from 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 Intel Program License Subscription
# Agreement, Intel FPGA IP License Agreement, or other applicable
# license agreement, including, without limitation, that your use is for the
# sole purpose of programming logic devices manufactured by Intel and sold by
# Intel or its authorized distributors. Please refer to the applicable
# agreement for further details.
# For more information, please refer to the Transceiver User Guide.
# Non-bonded Native PHY configurations
#
# False paths can be set on tx_digitalreset because each channel is
# independent of every other channel in the same instance. Use the false
# path exceptions to remove the tx_digialreset dependency. The following
# three constraints can be enabled and must be modified to include the
# name of the native phy instance to avoid accidentally constraining
# tx_digitalresets for unrelated Native PHY instances.
#
# set_false_path -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_pmaif_tx_pld_rst_n]
# set_false_path -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_8g_g3_tx_pld_rst_n]
# set_false_path -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_10g_krfec_tx_pld_rst_n]
# Bonded Native PHY configurations
#
# A false path cannot be set on tx_digitalreset from the reset controller
# since a skew relationship for tx_digitalreset to the transceiver channels
# must be maintained. The -exlude to_clock ensures the that the data delay
# is matched between channels. The following constraints should be modified for
# hierarchy and skew to match design requirements, where the max_skew should
# satisfy the following: max_skew = tx_clkout_period/2. The 1ns skew covers
# tx_clkout frequency of 500Mhz, and can be relaxed based upon the design.
# set_max_skew -exclude to_clock \
-from [get_registers *altera_xcvr_reset_control*tx_digitalreset*r_reset] \
-to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_*_tx_pld_rst_n] 1ns
# To allow the max_skew constraint to be honored while avoiding recover/removal
# violations, the reset paths are further constrained with a min/max delay. By
# setting a a large min/max delay, the signal is, for all intents and purposes,
# unbounded, and will be treated as if it were a false path. This gives the
# benefits of set_false_path exception while allowing the path to be further
# constrained to meet design requirements. These min/max delay constraints
# are NOT the same as a false path, and in non-bonded configuration, where
# applicable, a flase path should be set.
if { [get_collection_size [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_pmaif_tx_pld_rst_n]] > 0 } {
set_max_delay -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_pmaif_tx_pld_rst_n] 50ns
set_min_delay -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_pmaif_tx_pld_rst_n] -50ns
}
if { [get_collection_size [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_8g_g3_tx_pld_rst_n]] > 0 } {
set_max_delay -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_8g_g3_tx_pld_rst_n] 50ns
set_min_delay -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_8g_g3_tx_pld_rst_n] -50ns
}
if { [get_collection_size [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_10g_krfec_tx_pld_rst_n]] > 0 } {
set_max_delay -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_10g_krfec_tx_pld_rst_n] 50ns
set_min_delay -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_10g_krfec_tx_pld_rst_n] -50ns
}
# PCS liberty files have been modified to add a 0 recovery check
# The two SDCs below bound tx_analogreset and rx_analogreset
if { [get_collection_size [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_pma_txpma_rstb]] > 0 } {
set_max_delay -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_pma_txpma_rstb] 20ns
set_min_delay -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_pma_txpma_rstb] -10ns
}
if { [get_collection_size [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_pma_rxpma_rstb]] > 0 } {
set_max_delay -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_pma_rxpma_rstb] 20ns
set_min_delay -to [get_pins -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_pma_rxpma_rstb] -10ns
}
# Create a set of all asynchronous signals to be looped over for setting false paths
set altera_xcvr_native_a10_async_signals {
pld_10g_krfec_rx_pld_rst_n
pld_10g_krfec_rx_clr_errblk_cnt
pld_10g_rx_clr_ber_count
pld_10g_tx_diag_status
pld_10g_tx_bitslip
pld_8g_g3_rx_pld_rst_n
pld_8g_a1a2_size
pld_8g_bitloc_rev_en
pld_8g_byte_rev_en
pld_8g_encdt
pld_8g_tx_boundary_sel
pld_8g_rxpolarity
pld_pmaif_rx_pld_rst_n
pld_bitslip
pld_rx_prbs_err_clr
pld_polinv_tx
pld_polinv_rx
}
if { [ info exists altera_xcvr_native_a10_async_xcvr_pins ] } {
unset altera_xcvr_native_a10_async_xcvr_pins
}
# Set false paths for each item in the set
foreach altera_xcvr_native_a10_async_signale_name $altera_xcvr_native_a10_async_signals {
set altera_xcvr_native_a10_async_xcvr_pins [get_pins -nowarn -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|${altera_xcvr_native_a10_async_signale_name}*]
if { [get_collection_size $altera_xcvr_native_a10_async_xcvr_pins] > 0 } {
set_false_path -to $altera_xcvr_native_a10_async_xcvr_pins
}
}
# pld_10g_rx_align_clr pin has two timing arcs; one w.r.t rx_coreclkin and the other w.r.t rx_pma_clk (case:294191)
# The arc w.r.t rx_pma_clk is asynchronous, distinguishing the arcs based on destination register name
# To Node: pld_10g_rx_align_clr_reg.reg -> rx_pma_clk
# To Node: pld_10g_rx_align_clr_fifo.reg -> rx_coreclkin
set altera_xcvr_native_a10_async_xcvr_pins [get_pins -nowarn -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_10g_rx_align_clr*]
if {[get_collection_size $altera_xcvr_native_a10_async_xcvr_pins] > 0} {
set_false_path -to *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*inst_twentynm_hssi_10g_rx_pcs~pld_10g_rx_align_clr_reg.reg
}
# For TX burst enable, even though its an asynchronous signal, set a bound, since we need the fitter to place it some-what close to the periphery for interlaken
set altera_xcvr_native_a10_async_xcvr_pins [get_pins -nowarn -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_10g_tx_burst_en*]
if { [get_collection_size $altera_xcvr_native_a10_async_xcvr_pins] > 0 } {
set_max_delay -to $altera_xcvr_native_a10_async_xcvr_pins 20ns
set_min_delay -to $altera_xcvr_native_a10_async_xcvr_pins -20ns
}
# When using the PRBS Error Accumulation logic, set multicycle constraints to reduce routing effor and congestion. Also false path the asynchronous resets
if { [get_collection_size [get_registers -nowarn *xcvr_native*optional_chnl_reconfig_logic*prbs_accumulators_enable*prbs_soft_accumulators\|rx_prbs_err_snapshot*]] > 0 } {
set_max_delay -from [get_registers *xcvr_native*optional_chnl_reconfig_logic*prbs_accumulators_enable*prbs_soft_accumulators\|rx_prbs_err_snapshot*] \
-to [get_registers *xcvr_native*optional_chnl_reconfig_logic*prbs_accumulators_enable*prbs_soft_accumulators\|avmm_prbs_err_count*] \
15
set_min_delay -from [get_registers *xcvr_native*optional_chnl_reconfig_logic*prbs_accumulators_enable*prbs_soft_accumulators\|rx_prbs_err_snapshot*] \
-to [get_registers *xcvr_native*optional_chnl_reconfig_logic*prbs_accumulators_enable*prbs_soft_accumulators\|avmm_prbs_err_count*] \
-8
set_false_path -through [get_pins -compatibility_mode *xcvr_native*optional_chnl_reconfig_logic*prbs_accumulators_enable*prbs_soft_accumulators\|rx_clk_reset_sync*sync_r*clrn] \
-to [get_registers *xcvr_native*optional_chnl_reconfig_logic*prbs_accumulators_enable*prbs_soft_accumulators\|rx_clk_reset_sync*sync_r[?]]
set_false_path -from [get_registers *xcvr_native*optional_chnl_reconfig_logic*avmm_csr_enabled*embedded_debug_soft_csr*prbs_reg*] \
-to [get_registers *xcvr_native*optional_chnl_reconfig_logic*prbs_accumulators_enable*prbs_soft_accumulators\|rx_clk_prbs_reset_sync*sync_r[?]]
}
# When the PIPE Retry circuit is enabled for Gen2, include the following SDC constraint
if { [get_collection_size [get_registers -nowarn *xcvr_native*alt_xcvr_native_pipe_retry*hv_sync_retry_rate*]] > 0 } {
if { [string equal "quartus_sta" $::TimeQuestInfo(nameofexecutable)] } {
set altera_xcvr_native_a10_pld_rate [get_pins -nowarn -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*\|pld_rate*]
if { [get_collection_size $altera_xcvr_native_a10_pld_rate] > 0 } {
set_false_path -to $altera_xcvr_native_a10_pld_rate
}
}
set_false_path -through [get_pins -nowarn -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*pld_test_data*] \
-to [get_registers *xcvr_native*alt_xcvr_native_pipe_retry*pma_pld_rate_sync[0]]
set_false_path -through [get_pins -nowarn -compatibility_mode *twentynm_xcvr_native_inst\|*inst_twentynm_pcs\|*twentynm_hssi_*_pld_pcs_interface*pld_test_data*] \
-to [get_registers *xcvr_native*alt_xcvr_native_pipe_retry*pma_pld_rate_sync[1]]
set_false_path -to [get_registers *xcvr_native*alt_xcvr_native_pipe_retry*tx_digitalreset_pclk_inst*sync_r[*]]
set_false_path -to [get_registers *xcvr_native*alt_xcvr_native_pipe_retry*tx_digitalreset_hv_inst*sync_r[*]]
set_max_delay -from [get_registers *xcvr_native*alt_xcvr_native_pipe_retry*hv_sync_vec_pipe_rate*] \
-to [get_registers *xcvr_native*alt_xcvr_native_pipe_retry*hv_sync_retry_rate*] 8
set_min_delay -from [get_registers *xcvr_native*alt_xcvr_native_pipe_retry*hv_sync_vec_pipe_rate*] \
-to [get_registers *xcvr_native*alt_xcvr_native_pipe_retry*hv_sync_retry_rate*] -4
}
if { [get_collection_size [get_registers -nowarn *xcvr_native*g_pipe_rate_g1_g3*int_pipe_rate_sync[*]]] > 0 } {
set_min_delay -to [get_registers -nowarn *xcvr_native*g_pipe_rate_g1_g3*int_pipe_rate_sync[0]] -4
set_max_delay -to [get_registers -nowarn *xcvr_native*g_pipe_rate_g1_g3*int_pipe_rate_sync[0]] 12
set_min_delay -to [get_registers -nowarn *xcvr_native*g_pipe_rate_g1_g3*int_pipe_rate_sync[1]] -4
set_max_delay -to [get_registers -nowarn *xcvr_native*g_pipe_rate_g1_g3*int_pipe_rate_sync[1]] 12
}
if { [get_collection_size [get_registers -nowarn *xcvr_native*altera_xcvr_native_pcie_dfe_ip*pcie_rate*]] > 0 } {
set_min_delay -to [get_registers -nowarn *xcvr_native*altera_xcvr_native_pcie_dfe_ip*pcie_rate[*]] -4
set_max_delay -to [get_registers -nowarn *xcvr_native*altera_xcvr_native_pcie_dfe_ip*pcie_rate[*]] 30
set_min_delay -to [get_registers -nowarn *xcvr_native*altera_xcvr_native_pcie_dfe_ip*pcie_rate_sync[0]] -4
set_max_delay -to [get_registers -nowarn *xcvr_native*altera_xcvr_native_pcie_dfe_ip*pcie_rate_sync[0]] 30
set_min_delay -to [get_registers -nowarn *xcvr_native*altera_xcvr_native_pcie_dfe_ip*pcie_rate_sync[1]] -4
set_max_delay -to [get_registers -nowarn *xcvr_native*altera_xcvr_native_pcie_dfe_ip*pcie_rate_sync[1]] 30
}
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
//
// Common functions for Arria 10 Native PHY IP
//
`timescale 1 ps/1 ps
package altera_xcvr_native_a10_functions_h;
localparam MAX_CONVERSION_SIZE_ALT_XCVR_NATIVE_A10 = 128;
localparam MAX_STRING_CHARS_ALT_XCVR_NATIVE_A10 = 64;
localparam integer MAX_CHARS_ALT_XCVR_NATIVE_A10 = 86; // To accomodate LONG parameter lists.
////////////////////////////////////////////////////////////////////
// Return the number of bits required to represent an integer
// E.g. 0->1; 1->1; 2->2; 3->2 ... 31->5; 32->6
//
function integer clogb2_alt_xcvr_native_a10;
input integer input_num;
begin
for (clogb2_alt_xcvr_native_a10=0; input_num>0; clogb2_alt_xcvr_native_a10=clogb2_alt_xcvr_native_a10+1)
input_num = input_num >> 1;
if(clogb2_alt_xcvr_native_a10 == 0)
clogb2_alt_xcvr_native_a10 = 1;
end
endfunction
////////////////////////////////////////////////////////////////////
// Used to calculate the value of the "hssi_10g_tx_pcs_comp_cnt"
// parameter for a givin channel in a bonded configuration
//
// @param channels - Number of channels in the interface
// @param pcs_bonding_master - PCS master channel index
// @param channel_index - Index of channel within interface to determine
// parameter value for.
//
// @return An integer value for the parameter "hssi_10g_tx_pcs_comp_cnt".
function [7:0] get_comp_cnt_alt_xcvr_native_a10;
input integer channels;
input integer pcs_bonding_master;
input integer channel_index;
integer max_index;
integer comp_cnt;
begin
// Determine the index of the master
max_index = (pcs_bonding_master > (channels - pcs_bonding_master)) ? pcs_bonding_master
: (channels-pcs_bonding_master);
// Determine the index of this channel
if (channel_index == pcs_bonding_master)
comp_cnt = max_index;
else if (channel_index < pcs_bonding_master)
comp_cnt = max_index - (pcs_bonding_master - channel_index);
else
comp_cnt = max_index - (channel_index - pcs_bonding_master);
// Convert index to count value
comp_cnt = comp_cnt * 2;
get_comp_cnt_alt_xcvr_native_a10 = comp_cnt[7:0];
end
endfunction
////////////////////////////////////////////////////////////////////
// Used to calculate the value of the distance of current channel to mcgb
//
// @param pcs_bonding_master - PCS master channel index
// @param channel_index - Index of channel within interface to determine
// parameter value for.
//
// @return An 4 bits value for the parameter lower 3 showing distance, if MSB 1 then the current channel is above the mcgb
function [3:0] get_mcgb_location_alt_xcvr_native_a10(
input integer pcs_bonding_master,
input integer channel_index
);
integer distance;
begin
if (channel_index < pcs_bonding_master) begin
distance = pcs_bonding_master-channel_index;
get_mcgb_location_alt_xcvr_native_a10 = {1'b1,distance[2:0]};
end else begin
distance = channel_index-pcs_bonding_master;
get_mcgb_location_alt_xcvr_native_a10 = {1'b0,distance[2:0]};
end
end
endfunction
function automatic [MAX_CONVERSION_SIZE_ALT_XCVR_NATIVE_A10-1:0] str_2_bin_alt_xcvr_native_a10;
input [MAX_STRING_CHARS_ALT_XCVR_NATIVE_A10*8-1:0] instring;
integer this_char;
integer i;
begin
// Initialize accumulator
str_2_bin_alt_xcvr_native_a10 = {MAX_CONVERSION_SIZE_ALT_XCVR_NATIVE_A10{1'b0}};
for(i=MAX_STRING_CHARS_ALT_XCVR_NATIVE_A10-1;i>=0;i=i-1) begin
this_char = instring[i*8+:8];
// Add value of this digit
if(this_char >= 48 && this_char <= 57)
str_2_bin_alt_xcvr_native_a10 = (str_2_bin_alt_xcvr_native_a10 * 10) + (this_char - 48);
end
end
endfunction
////////////////////////////////////////////////////////////////////
// Adds an offets to 'scrambler seed' per channel for interlaken as:
// (58'h123456789abcde + user_seed + (24'h826a3*lane_number))
// see FB 138336 for details
//
// @param protocol_hint - only interlaken matters
// @param user_seed - 58 bit base seed to be modified per channel
// @param lane_number - Index of channel within interface to determine
// parameter value for.
//
// @return 58 bits scrambler seed for the channel
function [57:0] set_10g_scrm_seed_user_alt_xcvr_native_a10 (
input [8*MAX_STRING_CHARS_ALT_XCVR_NATIVE_A10:1] protocol_hint,
input [57:0] user_seed,
input integer lane_number
);
set_10g_scrm_seed_user_alt_xcvr_native_a10 = (protocol_hint == "interlaken_mode") ? (58'h123456789abcde + user_seed + (24'h826a3*lane_number)) : user_seed;
endfunction
////////////////////////////////////////////////////////////////////
// Convert an integer to a string
function [MAX_CHARS_ALT_XCVR_NATIVE_A10*8-1:0] int2str_alt_xcvr_native_a10(
input integer in_int
);
integer i;
integer this_char;
i = 0;
int2str_alt_xcvr_native_a10 = "";
do
begin
this_char = (in_int % 10) + 48;
int2str_alt_xcvr_native_a10[i*8+:8] = this_char[7:0];
i=i+1;
in_int = in_int / 10;
end
while(in_int > 0);
endfunction
endpackage
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1ps/1ps
// Revision 2.1
(* altera_attribute = " -name GLOBAL_SIGNAL OFF -to \"alt_xcvr_resync:reset_pulse_inst|resync_chains[0].sync_r[2]\" " *)
module altera_xcvr_native_pcie_dfe_ip #(
parameter num_channels = 8,
parameter disable_continuous_dfe = 0,
parameter enable_hip = 0,
parameter sim_reduced_counters = 0,
parameter avmm_sel_bits = 3,
parameter avmm_addr_bits = 10
) (
input clock,
input reset,
input ltssm_detect_quiet,
input ltssm_detect_active,
input ltssm_rcvr_phase_two,
input [1:0] pcie_rate_sw,
// HIP only signal for supporting reduced sim counters
input hip_reduce_counters,
// Reconfig Interface to the transceiver
input xcvr_rcfg_waitrequest,
input [31:0] xcvr_rcfg_readdata,
output xcvr_rcfg_lock,
output xcvr_rcfg_read,
output xcvr_rcfg_write,
output [avmm_sel_bits+avmm_addr_bits-1:0] xcvr_rcfg_address,
output [31:0] xcvr_rcfg_writedata
);
///////////////////////////////////////////////////////////////////////////////
// Import parameters
///////////////////////////////////////////////////////////////////////////////
import altera_xcvr_native_pcie_dfe_params_h::*;
///////////////////////////////////////////////////////////////////////////////
// Import parameters
///////////////////////////////////////////////////////////////////////////////
wire reduceded_sim_counter;
assign reduceded_sim_counter = (enable_hip) ? hip_reduce_counters : sim_reduced_counters[0];
///////////////////////////////////////////////////////////////////////////////
// Lock out the Reconfig Interface from the user
// wires and registers
///////////////////////////////////////////////////////////////////////////////
wire reset_sync;
wire gen3_speed;
wire gen12_speed;
wire rate_change;
wire detect_skew_timeout;
wire ltssm_detect;
wire indexed_all_channels;
wire ltssm_rcvr_phase_two_sync;
wire ltssm_detect_active_sync;
wire ltssm_detect_quiet_sync;
wire process_running_done;
wire [30:0] mgmt_master_address;
wire [NUM_PIO_IN-1:0] pio_to_mgmt_master;
wire [NUM_PIO_OUT-1:0] pio_from_mgmt_master;
reg modeb_not_restored;
reg process_go;
reg process_running;
reg en_continuous_dfe;
reg phase2_not_request;
reg [1:0] pcie_rate;
reg [1:0] current_rate;
reg [2:0] detect_skew_cnt;
reg [2:0] vec_timeout;
reg [3:0] sm_state;
reg [3:0] pcie_rate_sync;
reg [20:0] timer_counter;
reg [20:0] timer_threshold;
reg [avmm_sel_bits-1:0] channel_count;
///////////////////////////////////////////////////////////////////////////////
// Assign statements for control/status signals
///////////////////////////////////////////////////////////////////////////////
assign gen3_speed = (enable_hip) ? (pcie_rate == 2'b11) : (pcie_rate == 2'b10);
assign gen12_speed = (enable_hip) ? (pcie_rate != 2'b11) : (pcie_rate != 2'b10);
assign rate_change = (current_rate != pcie_rate);
assign ltssm_detect = (ltssm_detect_quiet_sync | ltssm_detect_active_sync);
assign detect_skew_timeout = (detect_skew_cnt == 3'h7);
assign process_running_done = (~pio_from_mgmt_master[PIO_OUT_RUNNING] && process_running);
assign indexed_all_channels = ((channel_count == (num_channels-1)) && process_running_done);
// Lock out the Reconfig Interface from the user
assign xcvr_rcfg_lock = (sm_state != SM_IDLE);
///////////////////////////////////////////////////////////////////////////////
// Create a reset pulse
///////////////////////////////////////////////////////////////////////////////
(*preserve*) reg reg0 = 1'b0;
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 1 ),
.INIT_VALUE ( 1 )
) reset_pulse_inst (
.clk (clock),
.reset (reset),
.d (reg0),
.q (reset_sync)
);
///////////////////////////////////////////////////////////////////////////////
// Synchronize the rate signal as well as the status signals
///////////////////////////////////////////////////////////////////////////////
always@(posedge clock or posedge reset_sync) begin
if(reset_sync) begin
vec_timeout <= 3'b0;
pcie_rate_sync <= 4'b0;
pcie_rate <= 2'b0;
end else begin
pcie_rate_sync <= {pcie_rate_sync[1:0], pcie_rate_sw};
if(pcie_rate != pcie_rate_sync[3:2]) begin
if(vec_timeout != 3'b111) begin
vec_timeout <= vec_timeout + 3'b1;
end else begin
pcie_rate <= pcie_rate_sync[3:2];
end
end else begin
vec_timeout <= 3'b0;
end
end
end
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH ( 3 ),
.WIDTH ( 3 ),
.INIT_VALUE ( 0 )
) ltssm_state_sync_inst (
.clk (clock),
.reset (reset_sync),
.d ({ltssm_rcvr_phase_two, ltssm_detect_active, ltssm_detect_quiet}),
.q ({ltssm_rcvr_phase_two_sync, ltssm_detect_active_sync, ltssm_detect_quiet_sync})
);
///////////////////////////////////////////////////////////////////////////////
// Small counter for skew alignment
// If we are not in detect,
///////////////////////////////////////////////////////////////////////////////
always@(posedge clock or posedge reset_sync)begin
if(reset_sync) begin
detect_skew_cnt <= 3'b0;
end else begin
if(ltssm_detect) begin
detect_skew_cnt <= 3'b0;
end else begin
if(detect_skew_timeout) begin
detect_skew_cnt <= detect_skew_cnt;
end else begin
detect_skew_cnt <= detect_skew_cnt + 3'b1;
end
end
end
end
///////////////////////////////////////////////////////////////////////////////
// register stage for edge detection
///////////////////////////////////////////////////////////////////////////////
always@(posedge clock or posedge reset_sync) begin
if(reset_sync) begin
process_running <= 1'b0;
end else begin
process_running <= pio_from_mgmt_master[PIO_OUT_RUNNING];
end
end
///////////////////////////////////////////////////////////////////////////////
// State machine
///////////////////////////////////////////////////////////////////////////////
always@(posedge clock or posedge reset_sync) begin
if(reset_sync) begin
sm_state <= SM_POWERUP;
process_go <= 1'b0;
current_rate <= 2'b0;
modeb_not_restored <= 1'b1;
en_continuous_dfe <= 1'b1;
phase2_not_request <= 1'b0;
timer_counter <= 21'b0;
timer_threshold <= (reduceded_sim_counter) ? 21'd1200 : 21'd1200000;
end else begin
// default the process_go signal for all states unless otherwise specified
process_go <= 1'b0;
case(sm_state)
// Powerup state to do a one-time readback on the calibration status
SM_POWERUP: begin
sm_state <= SM_CHECK_CAL_STATUS;
end
SM_CHECK_CAL_STATUS: begin
// Intercept the AVMM read from the mgmt_master
if((xcvr_rcfg_address[avmm_addr_bits-1:0] == ADDR_CALIBRATION) && xcvr_rcfg_read == 1'b1 && xcvr_rcfg_waitrequest == 1'b0) begin
en_continuous_dfe <= xcvr_rcfg_readdata[BIT_CALIBRATION];
sm_state <= SM_IDLE;
end
end
SM_IDLE: begin
current_rate <= pcie_rate;
modeb_not_restored <= (detect_skew_timeout) ? 1'b1 : modeb_not_restored;
phase2_not_request <= (ltssm_rcvr_phase_two_sync) ? phase2_not_request : 1'b1;
timer_counter <= 21'b0;
// State Transitions. If we are changin rates, execute the rate change
// current speed is decoded via combinational logic
if (rate_change) begin
sm_state <= SM_EXECUTE_RATE_SW;
end
// Restoring mode B must be done everytime we enter detect quiet. This is
// to ensure that the adaptation block can re-run phase 2. If we enter
// recovery equalization phase 2, then we must restore mode b fo re-running
// phase 2
else if(ltssm_detect_quiet_sync && modeb_not_restored || ltssm_rcvr_phase_two_sync && phase2_not_request) begin
sm_state <= SM_RESTORE_MODEB;
end
end
SM_EXECUTE_RATE_SW: begin
process_go <= 1'b1;
if(indexed_all_channels) begin
sm_state <= SM_IDLE;
end
end
SM_RESTORE_MODEB: begin
// Set the timer threshold for a 12ms timeout
timer_threshold <= (reduceded_sim_counter) ? 21'd1200 : 21'd1200000;
timer_counter <= (reduceded_sim_counter) ? 21'b0 : timer_counter + 21'b1;
// Run process over all channels
process_go <= 1'b1;
// Set modeb_not_restored to 0
modeb_not_restored <= 1'b0;
if(indexed_all_channels) begin
if(ltssm_rcvr_phase_two_sync)
sm_state <= SM_TIMEOUT_CTLE;
else
sm_state <= SM_IDLE;
end
end
SM_TIMEOUT_CTLE: begin
// Set the timer threshold for a 12ms timeout
timer_threshold <= (reduceded_sim_counter) ? 21'd1200 : 21'd1200000;
// Check the timeout, else run the counter
if(timer_counter == timer_threshold) begin
timer_counter <= 21'b0;
sm_state <= SM_EXECUTE_CTLE;
end else begin
timer_counter <= timer_counter + 21'b1;
end
end
SM_EXECUTE_CTLE: begin
// Set the timer threshold for a 10ms timeout
timer_threshold <= (reduceded_sim_counter) ? 21'd1000 : 21'd1000000;
timer_counter <= (reduceded_sim_counter) ? 21'b0 : timer_counter + 21'b1;
// Run process over all channels
process_go <= 1'b1;
if(indexed_all_channels) begin
sm_state <= SM_TIMEOUT_DFE;
end
end
SM_TIMEOUT_DFE: begin
// Set the timer threshold for a 10ms timeout
timer_threshold <= (reduceded_sim_counter) ? 21'd1000 : 21'd1000000;
// Check the timeout, else run the counter
if(timer_counter == timer_threshold) begin
timer_counter <= 21'b0;
sm_state <= SM_EXECUTE_DFE;
end else begin
timer_counter <= timer_counter + 21'b1;
end
end
SM_EXECUTE_DFE: begin
// Indicate that the flow has been run
phase2_not_request <= 1'b0;
// Run the process over all channels
process_go <= 1'b1;
if(indexed_all_channels) begin
sm_state <= SM_IDLE;
end
end
default: begin
process_go <= 1'b0;
sm_state <= SM_IDLE;
end
endcase
end
end
///////////////////////////////////////////////////////////////////////////////
// Assigns for the Control Signals for the mgmt_master
///////////////////////////////////////////////////////////////////////////////
assign pio_to_mgmt_master[PIO_IN_GO] = process_go;
assign pio_to_mgmt_master[PIO_IN_SW_GEN_1_2] = ((sm_state == SM_EXECUTE_RATE_SW) && gen12_speed);
assign pio_to_mgmt_master[PIO_IN_SW_GEN_3] = ((sm_state == SM_EXECUTE_RATE_SW) && gen3_speed);
assign pio_to_mgmt_master[PIO_IN_RESTORE_MODEB] = (sm_state == SM_RESTORE_MODEB);
assign pio_to_mgmt_master[PIO_IN_PHASE2_CTLE] = (sm_state == SM_EXECUTE_CTLE);
assign pio_to_mgmt_master[PIO_IN_PHASE2_DFE] = (sm_state == SM_EXECUTE_DFE);
assign pio_to_mgmt_master[PIO_IN_CONTINUOUS_DFE] = (disable_continuous_dfe) ? 1'b0 : en_continuous_dfe;
///////////////////////////////////////////////////////////////////////////////
// Channel Indexing for the addressing
///////////////////////////////////////////////////////////////////////////////
assign xcvr_rcfg_address = {channel_count, mgmt_master_address[avmm_addr_bits-1:0]};
always@(posedge clock or posedge reset_sync) begin
if(reset_sync) begin
channel_count <= {avmm_sel_bits{1'b0}};
end else begin
if (sm_state == SM_EXECUTE_RATE_SW || sm_state == SM_RESTORE_MODEB || sm_state == SM_EXECUTE_CTLE || sm_state == SM_EXECUTE_DFE) begin
if(channel_count == (num_channels - 1)) begin
channel_count <= channel_count;
end else begin
channel_count <= channel_count + process_running_done;
end
end else begin
channel_count <= {avmm_sel_bits{1'b0}};
end
end
end
///////////////////////////////////////////////////////////////////////////////
// mgmt_master cpu for reconfiguration.
///////////////////////////////////////////////////////////////////////////////
pcie_mgmt_master #(
.CLOCKS_PER_SECOND ( 100000000 ), // Used for time calculations
.PIO_OUT_SIZE ( NUM_PIO_OUT ), // Width of PIO output port
.PIO_IN_SIZE ( NUM_PIO_IN ), // Width of PIO input port
.PIO_OUT_INIT_VALUE ( 0 ), // Initial value for pio_out registers
.MEM_DEPTH ( num_channels * NUM_ADDR_PER_CHNL + 1), // Depth of the memory for DFE and CTLE
.ROM_DEPTH ( 1024 ) // Depth of command ROM
) pcie_mgmt_master_for_dfe (
.clk ( clock ),
.reset ( reset_sync ),
.av_write ( xcvr_rcfg_write ),
.av_read ( xcvr_rcfg_read ),
.av_address ( mgmt_master_address ),
.av_writedata ( xcvr_rcfg_writedata ),
.av_readdata ( xcvr_rcfg_readdata ),
.av_waitrequest ( xcvr_rcfg_waitrequest ),
.pio_out ( pio_from_mgmt_master ),
.pio_in ( pio_to_mgmt_master )
);
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// Revision 2.0
package altera_xcvr_native_pcie_dfe_params_h;
// Program Labels for Jumps
localparam PRGM_BEGIN = 1;
localparam PRGM_SW_GEN3 = 2;
localparam PRGM_PHASE2_CTLE = 3;
localparam PRGM_PHASE2_DFE = 4;
localparam PRGM_SW_GEN1_2 = 5;
localparam PRGM_RESTORE_MODEB = 6;
localparam PRGM_SKIP_MANUAL_DFE = 7;
localparam PRGM_SKIP_CONT_DFE = 8;
localparam PRGM_SKIP_DFE_LOAD = 9;
localparam PRGM_SKIP_DFE_HOLD = 10;
localparam PRGM_SKIP_DFE_MODE_8 = 11;
// Labels for PIO in
localparam NUM_PIO_IN = 7;
localparam PIO_IN_GO = 0;
localparam PIO_IN_SW_GEN_1_2 = 1;
localparam PIO_IN_SW_GEN_3 = 2;
localparam PIO_IN_RESTORE_MODEB = 3;
localparam PIO_IN_PHASE2_CTLE = 4;
localparam PIO_IN_PHASE2_DFE = 5;
localparam PIO_IN_CONTINUOUS_DFE= 6;
// Labels for PIO out
localparam NUM_PIO_OUT = 7;
localparam PIO_OUT_ERROR = 0;
localparam PIO_OUT_RUNNING = 1;
localparam PIO_OUT_SW_GEN_1_2 = 2;
localparam PIO_OUT_SW_GEN_3 = 3;
localparam PIO_OUT_RESTORE_MODEB= 4;
localparam PIO_OUT_PHASE2_CTLE = 5;
localparam PIO_OUT_PHASE2_DFE = 6;
// Static settings
localparam FORCE_JUMP = 1;
localparam GEN1_GEN2_CTLE_VAL = 32'h00;
// Test parameters
localparam TST_MUX_DELAY = 30;
localparam SLEEP_DELAY = 5;
// Parameters for indexing through mem
localparam NUM_ADDR_PER_CHNL = 12;
localparam INDX_ADDR_CTLE = 0;
localparam NUM_ADDR_CTLE = 1;
localparam INDX_ADDR_DFE = 1;
localparam NUM_ADDR_DFE = 11;
// Calibration status
localparam ADDR_CALIBRATION = 10'h103;
localparam BIT_CALIBRATION = 5;
// DFE IP States
localparam SM_POWERUP = 4'h0;
localparam SM_CHECK_CAL_STATUS = 4'h1;
localparam SM_IDLE = 4'h2;
localparam SM_EXECUTE_RATE_SW = 4'h3;
localparam SM_RESTORE_MODEB = 4'h4;
localparam SM_TIMEOUT_CTLE = 4'h5;
localparam SM_EXECUTE_CTLE = 4'h6;
localparam SM_TIMEOUT_DFE = 4'h7;
localparam SM_EXECUTE_DFE = 4'h8;
endpackage
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// Revision 2.0
package pcie_mgmt_commands_h;
localparam CMD_SIZE = 5;
localparam ARG1_SIZE = 32;
localparam ROM_WIDTH = CMD_SIZE + ARG1_SIZE;
// Define bit offsets within ROM word
localparam ARG1_OFST = 0;
localparam CMD_OFST = ARG1_OFST + ARG1_SIZE;
// Bit field abstractions
localparam WAIT_OFST = ARG1_OFST;
localparam WAIT_SIZE = ARG1_SIZE;
localparam REG_OFST = ARG1_OFST;
localparam REG_SIZE = ARG1_SIZE;
localparam REG_VAL_OFST = ARG1_OFST;
localparam REG_VAL_SIZE = ARG1_SIZE;
localparam BIT_INDEX_OFST = ARG1_OFST;
localparam BIT_INDEX_SIZE = 5;
localparam BIT_VAL_OFST = BIT_INDEX_OFST + BIT_INDEX_SIZE;
localparam BIT_VAL_SIZE = 1;
localparam BIT_INDEX2_OFST = BIT_VAL_OFST + BIT_VAL_SIZE;
localparam CMP_VAL_OFST = ARG1_OFST;
localparam CMP_VAL_SIZE = ARG1_SIZE;
// Define all the commands
localparam CMD_HALT = 5'd0,
CMD_WAIT = 5'd1,
// REG ops
CMD_LOAD_ADDR = 5'd2,
CMD_LOAD_RESULT = 5'd3,
CMD_WRITE_REG = 5'd4,
CMD_READ_REG = 5'd5,
CMD_READ_REG_BIT = 5'd6,
CMD_WAIT_REG = 5'd7,
CMD_WAIT_REG_BIT = 5'd8,
// PIO ops
CMD_WRITE_PIO_BIT_RES = 5'd9,
CMD_READ_PIO_BIT = 5'd10,
CMD_WAIT_PIO_BIT = 5'd11,
// Register ops
CMD_CMP_RESULT = 5'd12,
CMD_JNEZ = 5'd13,
//Commands for Read Modified Write
CMD_MOD = 5'd14,
CMD_MASK = 5'd15,
//Memory OPs
CMD_LD_MEM_ADDR = 5'd16,
CMD_ST_MEM_ADDR = 5'd17,
CMD_LD_REG_FROM_MEM = 5'd18,
CMD_LD_MOD_FROM_MEM = 5'd19,
CMD_ST_REG_TO_MEM = 5'd20,
CMD_INC_MEM_ADDR = 5'd21,
//ALU
CMD_ADD = 5'd22,
CMD_SUB = 5'd23,
CMD_CONVERT_CTLE = 5'd24;
`define FUNC_PROTO function [ROM_WIDTH-1:0]
// NOOP
`FUNC_PROTO noop;
input unused;
begin
noop = sleep(0);
end
endfunction
// Halt function
`FUNC_PROTO halt;
input unused;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_HALT;
halt = cmd;
end
endfunction
// Sleep function waits for the specified number of clocks
`FUNC_PROTO sleep;
input [WAIT_SIZE-1:0] clock_cycle_count;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_WAIT;
cmd[WAIT_OFST+:WAIT_SIZE] = clock_cycle_count;
sleep = cmd;
end
endfunction
// Load a value into the address register
`FUNC_PROTO load_address;
input [REG_SIZE-1:0] address;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_LOAD_ADDR;
cmd[REG_OFST+:REG_SIZE] = address;
load_address = cmd;
end
endfunction
// Load a value into the result register
`FUNC_PROTO load_result;
input [REG_SIZE-1:0] result;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_LOAD_RESULT;
cmd[REG_OFST+:REG_SIZE] = result;
load_result = cmd;
end
endfunction
// Write the contents of the result register to the the register specified by
// address.
//
// @writedata - Data to be written.
`FUNC_PROTO write_reg;
input [REG_VAL_SIZE-1:0] unused;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_WRITE_REG;
write_reg = cmd;
end
endfunction
// Reads data from the register specified by address
// and stores the read data into the result register
//
// @address - Address of the register to be read.
`FUNC_PROTO read_reg;
input unused;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_READ_REG;
read_reg = cmd;
end
endfunction
//reads the data from the results register, and writes it to the local
//register, using the mask to modify only the correct bits.
//
// @modify_data- data to be written into the scratch register.
`FUNC_PROTO modify_reg;
input [REG_VAL_SIZE-1:0] modify_data;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_MOD;
cmd[REG_VAL_OFST+:REG_VAL_SIZE] = modify_data;
modify_reg = cmd;
end
endfunction
//Stores the mask value into a local register specifically for performing
//RMW
//
// @mask_data - the mask for performing RMW
`FUNC_PROTO mask_reg;
input [REG_VAL_SIZE-1:0] mask_data;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_MASK;
cmd[REG_VAL_OFST+:REG_VAL_SIZE] = mask_data;
mask_reg = cmd;
end
endfunction
// Reads a data bit from the register at the specified
// address and stores it in the result register
`FUNC_PROTO read_reg_bit;
input [BIT_INDEX_SIZE-1:0] bit_index;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_READ_REG_BIT;
cmd[BIT_INDEX_OFST+:BIT_INDEX_SIZE] = bit_index;
read_reg_bit = cmd;
end
endfunction
// Wait for register to equal value
`FUNC_PROTO wait_for_reg;
input [REG_VAL_SIZE-1:0] expected_data;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_WAIT_REG;
cmd[REG_VAL_OFST+:REG_VAL_SIZE] = expected_data;
wait_for_reg = cmd;
end
endfunction
// Wait for a register bit to be 0 or 1
`FUNC_PROTO wait_for_reg_bit;
input [BIT_INDEX_SIZE-1:0] bit_index;
input [REG_VAL_SIZE-1:0] expected_bit_value;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_WAIT_REG_BIT;
cmd[BIT_INDEX_OFST+:BIT_INDEX_SIZE] = bit_index;
cmd[BIT_VAL_OFST+:BIT_VAL_SIZE] = expected_bit_value;
wait_for_reg_bit = cmd;
end
endfunction
// Write bit from result register to PIO port bit
`FUNC_PROTO write_result_bit_to_pio_bit;
input [BIT_INDEX_SIZE-1:0] result_bit_index;
input [BIT_INDEX_SIZE-1:0] pio_bit_index;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_WRITE_PIO_BIT_RES;
cmd[BIT_INDEX_OFST+:BIT_INDEX_SIZE] = pio_bit_index;
cmd[BIT_INDEX2_OFST+:BIT_INDEX_SIZE] = result_bit_index;
write_result_bit_to_pio_bit = cmd;
end
endfunction
// Read PIO bit and store value (0 or 1) to internal result register
`FUNC_PROTO read_pio_bit;
input [BIT_INDEX_SIZE-1:0] bit_index;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_READ_PIO_BIT;
cmd[BIT_INDEX_OFST+:BIT_INDEX_SIZE] = bit_index;
read_pio_bit = cmd;
end
endfunction
// Wait for a bit on the PIO input to be 0 or 1
`FUNC_PROTO wait_for_pio_bit;
input [BIT_INDEX_SIZE-1:0] bit_index;
input expected_bit_value;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_WAIT_PIO_BIT;
cmd[BIT_INDEX_OFST+:BIT_INDEX_SIZE] = bit_index;
cmd[BIT_VAL_OFST+:BIT_VAL_SIZE] = expected_bit_value;
wait_for_pio_bit = cmd;
end
endfunction
// Compare the value to the result register and staore the compare result
// (0 or 1) in the result register
`FUNC_PROTO compare_result;
input [CMP_VAL_SIZE-1:0] compare_value;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_CMP_RESULT;
cmd[CMP_VAL_OFST+:CMP_VAL_SIZE] = compare_value;
compare_result = cmd;
end
endfunction
// Compare the value in the result register to 0
// If they are equal, continue execution, otherwise, jump to the
// command previously stored by the set_jump_address command.
`FUNC_PROTO jump_not_equal_zero;
input [CMP_VAL_SIZE-1:0] address;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_JNEZ;
cmd[REG_OFST+:REG_SIZE] = address;
jump_not_equal_zero = cmd;
end
endfunction
`FUNC_PROTO add_to_reg;
input [REG_SIZE-1:0] value;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_ADD;
cmd[REG_OFST+:REG_SIZE] = value;
add_to_reg = cmd;
end
endfunction
`FUNC_PROTO convert_ctle;
input [REG_SIZE-1:0] value;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_CONVERT_CTLE;
cmd[REG_OFST+:REG_SIZE] = value;
convert_ctle = cmd;
end
endfunction
`FUNC_PROTO sub_from_reg;
input [REG_SIZE-1:0] value;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_SUB;
cmd[REG_OFST+:REG_SIZE] = value;
sub_from_reg = cmd;
end
endfunction
`FUNC_PROTO inc_mem_address;
input unused;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_INC_MEM_ADDR;
inc_mem_address = cmd;
end
endfunction
`FUNC_PROTO load_mem_addr_to_reg;
input unused;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_LD_MEM_ADDR;
load_mem_addr_to_reg = cmd;
end
endfunction
`FUNC_PROTO store_reg_to_mem_addr;
input [REG_SIZE-1:0] address;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_ST_MEM_ADDR;
cmd[REG_OFST+:REG_SIZE] = address;
store_reg_to_mem_addr = cmd;
end
endfunction
`FUNC_PROTO wr_to_mem_address;
input unused;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_ST_REG_TO_MEM;
wr_to_mem_address = cmd;
end
endfunction
`FUNC_PROTO rd_from_mem_address;
input unused;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[CMD_OFST+:CMD_SIZE] = CMD_LD_REG_FROM_MEM;
rd_from_mem_address = cmd;
end
endfunction
`FUNC_PROTO modify_reg_from_mem_address;
input [REG_SIZE-1:0] mask;
reg [ROM_WIDTH-1:0] cmd;
begin
cmd = {ROM_WIDTH{1'b0}};
cmd[REG_OFST+:REG_SIZE] = mask;
cmd[CMD_OFST+:CMD_SIZE] = CMD_LD_MOD_FROM_MEM;
modify_reg_from_mem_address = cmd;
end
endfunction
// Log base 2 function for calculating bus widths
function integer clogb2;
input [31:0] value;
for (clogb2=0; value>0; clogb2=clogb2+1)
value = value>>1;
endfunction
endpackage
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1ps/1ps
// Revision 2.1
module pcie_mgmt_cpu #(
parameter PIO_OUT_SIZE = 8, // Width of PIO output port
parameter PIO_IN_SIZE = 8, // Width of PIO input port
parameter [PIO_OUT_SIZE-1:0] PIO_OUT_INIT_VALUE = 0, // Initial value for pio_out registers
parameter ROM_DEPTH = 512, // Depth of command ROM
parameter MEM_DEPTH = 8,
parameter ROM_WIDTH = pcie_mgmt_commands_h::ROM_WIDTH,
parameter ADDR_WIDTH = pcie_mgmt_commands_h::clogb2(ROM_DEPTH)
) (
input clk,
input reset,
output reg av_write,
output reg av_read,
output reg [30:0] av_address,
output reg [31:0] av_writedata,
input [31:0] av_readdata,
input av_waitrequest,
// Instruction master (ROM interface)
output reg [ADDR_WIDTH-1:0] rom_address,
output rom_read,
input [ ROM_WIDTH-1:0] rom_data,
output reg [PIO_OUT_SIZE-1:0] pio_out,
input [ PIO_IN_SIZE-1:0] pio_in
);
import pcie_mgmt_commands_h::*; // Contains low-level instructions
integer i;
localparam ST_FETCH = 0, // Fetching and decoding command
ST_WAIT = 1, // Waiting for a number of clock cycles
ST_WRITE_REG = 2, // Writing to an avalon register
ST_READ_REG = 3, // Reading from an avalon register
ST_WAIT_PIO = 4, // Reading from the PIO input
ST_HALT = 5; // HALT, no more commands
// State machine signals
reg [ 2:0] state;
reg [ 2:0] next_state;
reg [31:0] wait_count;
wire wait_done;
wire read_reg_done;
// ROM operands
wire [CMD_SIZE-1:0] rom_cmd;
wire [REG_VAL_SIZE-1:0] reg_val;
wire [REG_VAL_SIZE-1:0] mask_val;
wire [REG_SIZE-1:0] reg_addr;
wire [BIT_INDEX_SIZE-1:0] bit_index;
wire [BIT_INDEX_SIZE-1:0] bit_index2;
wire bit_val;
wire [WAIT_SIZE-1:0] wait_val;
wire [CMP_VAL_SIZE-1:0] cmp_val;
// Internal signals
reg cmd_done;
wire reg_match;
wire reg_bit_match;
wire pio_bit_match;
wire [REG_VAL_SIZE-1:0] mem_data;
reg [REG_VAL_SIZE-1:0] r0;
reg [REG_VAL_SIZE-1:0] mem_addr;
reg [REG_VAL_SIZE-1:0] mask = {REG_VAL_SIZE{1'b0}};
reg [REG_VAL_SIZE-1:0] cpu_memory [0:MEM_DEPTH-1];
//*********************************************************************
//************************ Command ROM ********************************
assign rom_read = cmd_done | reset;
//********************** End Command ROM ******************************
//*********************************************************************
//*********************************************************************
//**************** Extract Operands From ROM Data *********************
assign rom_cmd = rom_data[CMD_OFST+:CMD_SIZE];
assign reg_addr = rom_data[REG_OFST+:REG_SIZE];
assign wait_val = rom_data[WAIT_OFST+:WAIT_SIZE];
assign reg_val = rom_data[REG_VAL_OFST+:REG_VAL_SIZE];
assign mask_val = rom_data[REG_VAL_OFST+:REG_VAL_SIZE];
assign bit_index = rom_data[BIT_INDEX_OFST+:BIT_INDEX_SIZE];
assign bit_index2= rom_data[BIT_INDEX2_OFST+:BIT_INDEX_SIZE];
assign bit_val = rom_data[BIT_VAL_OFST+:BIT_VAL_SIZE];
assign cmp_val = rom_data[CMP_VAL_OFST+:CMP_VAL_SIZE];
//************** End Extract Operands From ROM Data *******************
//*********************************************************************
//*********************************************************************
//************************ Internal Signals ***************************
// Matches
assign reg_match = (av_readdata == reg_val);
assign reg_bit_match = (av_readdata[bit_index] == bit_val);
assign pio_bit_match = (pio_in [bit_index] == bit_val);
// Done flags
assign wait_done = !wait_count;
assign read_reg_done = (rom_cmd == CMD_WAIT_REG) ? reg_match :
(rom_cmd == CMD_WAIT_REG_BIT) ? reg_bit_match :
1'b1;
always @* begin
case(state)
ST_FETCH:
case(rom_cmd)
CMD_LOAD_ADDR,
CMD_LOAD_RESULT,
CMD_WRITE_PIO_BIT_RES,
CMD_READ_PIO_BIT,
//--self
CMD_MOD,
CMD_MASK,
CMD_LD_MEM_ADDR,
CMD_ST_MEM_ADDR,
CMD_ST_REG_TO_MEM,
CMD_LD_REG_FROM_MEM,
CMD_LD_MOD_FROM_MEM,
CMD_INC_MEM_ADDR,
CMD_ADD,
CMD_CONVERT_CTLE,
CMD_SUB,
CMD_CMP_RESULT:
cmd_done = 1'b1;
default: cmd_done = 1'b0;
endcase
ST_WAIT: cmd_done = wait_done;
ST_WRITE_REG: cmd_done = !av_waitrequest;
ST_READ_REG: cmd_done = !av_waitrequest & read_reg_done;
ST_WAIT_PIO: cmd_done = pio_bit_match;
default: cmd_done = 1'b0;
endcase
end
//************************ Internal Signals ***************************
//*********************************************************************
//*********************************************************************
//************************ State Machine ******************************
// State decoder
always @(posedge clk or posedge reset)
if(reset) state <= ST_FETCH;
else if(state == ST_FETCH) state <= next_state;
else if(cmd_done) state <= next_state;
always @*
begin
case(state)
// Get next command
ST_FETCH:
case(rom_cmd)
CMD_HALT: next_state = ST_HALT;
CMD_WRITE_REG: next_state = ST_WRITE_REG;
CMD_READ_REG,
CMD_READ_REG_BIT,
CMD_WAIT_REG,
CMD_WAIT_REG_BIT: next_state = ST_READ_REG;
CMD_WAIT_PIO_BIT: next_state = ST_WAIT_PIO;
CMD_JNEZ,
CMD_WAIT: next_state = ST_WAIT;
default: next_state = state;
endcase
// Wait
ST_WAIT: next_state = ST_FETCH;
// Write
ST_WRITE_REG: next_state = ST_FETCH;
// Read register
ST_READ_REG: next_state = ST_FETCH;
// Read the PIO port
ST_WAIT_PIO: next_state = ST_FETCH;
// HALT!(remain here)
ST_HALT: next_state = ST_HALT;
default: next_state = state;
endcase
end
//********************** End State Machine ****************************
//*********************************************************************
//*********************************************************************
//*********************** Output Encoders *****************************
// Registers changing only on fetch
always @(posedge clk or posedge reset)
if(reset)
rom_address <= {ADDR_WIDTH{1'b0}};
else if((state == ST_FETCH) & (rom_cmd == CMD_JNEZ) & |r0)
rom_address <= reg_addr[0+:ADDR_WIDTH];
else if(cmd_done)
rom_address <= rom_address + { {(ADDR_WIDTH-1){1'b0}}, 1'b1};
// Avalon interface decoder
always @(posedge clk or posedge reset)
if(reset) begin
av_write <= 1'b0;
av_read <= 1'b0;
av_address <= 31'd0;
av_writedata<= 32'd0;
end else begin
case(state)
// Get next command
ST_FETCH: begin
case(rom_cmd)
CMD_LOAD_ADDR:
av_address <= reg_addr[30:0];
CMD_WRITE_REG: begin
av_write <= 1'b1;
av_writedata<= r0;
end
CMD_READ_REG,
CMD_READ_REG_BIT,
CMD_WAIT_REG,
CMD_WAIT_REG_BIT:
av_read <= 1'b1;
endcase
end
// Write
ST_WRITE_REG: av_write <= ~cmd_done;
// Read register
ST_READ_REG: av_read <= ~cmd_done;
endcase
end
// Wait counter
always @(posedge clk or posedge reset)
if(reset) wait_count <= 32'd0;
else if((state == ST_FETCH) && (rom_cmd == CMD_WAIT))
wait_count <= wait_val;
else if((state == ST_WAIT) && !cmd_done)
wait_count <= wait_count + 32'hffffffff;
// pio_out decoder
always @(posedge clk or posedge reset)
if(reset) pio_out <= PIO_OUT_INIT_VALUE[0+:PIO_OUT_SIZE];
else if(state == ST_FETCH) begin
if(rom_cmd == CMD_WRITE_PIO_BIT_RES)
pio_out[bit_index] <= r0[bit_index2];
end
// Error decoder
assign mem_data = cpu_memory[mem_addr];
always @(posedge clk or posedge reset)
if(reset) begin
r0 <= {REG_VAL_SIZE{1'b0}};
mask <= {REG_VAL_SIZE{1'b0}};
mem_addr <= {REG_VAL_SIZE{1'b0}};
for( i = 0; i < MEM_DEPTH; i = i + 1 ) begin
cpu_memory[i] <= 'd0;
end
end else begin
for( i = 0; i < MEM_DEPTH; i = i + 1 ) begin
cpu_memory[i] <= cpu_memory[i];
end
case(state)
ST_FETCH:
if(rom_cmd == CMD_CMP_RESULT) begin
r0 <= {CMP_VAL_SIZE{1'b0}};
r0[0] <= (r0 == cmp_val) ? 1'b0 : 1'b1;
end else if(rom_cmd == CMD_LOAD_RESULT) begin
r0 <= reg_val;
end else if(rom_cmd == CMD_READ_PIO_BIT) begin
r0 <= {{REG_VAL_SIZE-1{1'b0}},pio_in[bit_index]};
end else if(rom_cmd == CMD_MASK) begin
//Stores the mask in a local register.
mask <= mask_val;
end else if(rom_cmd == CMD_MOD) begin
r0 <= ((mask & reg_val) | (~mask & r0));
end else if(rom_cmd == CMD_ADD) begin
r0 <= r0+reg_val;
end else if(rom_cmd == CMD_CONVERT_CTLE) begin
r0 <= (mem_data[3:1] == 3'b111) ? {r0[REG_VAL_SIZE-1:6],5'b11100,r0[0]} : {r0[REG_VAL_SIZE-1:6],mem_data[3:0],1'b0,r0[0]};
end else if(rom_cmd == CMD_SUB) begin
r0 <= r0-reg_val;
end else if(rom_cmd == CMD_LD_MEM_ADDR) begin
r0 <= mem_addr;
end else if(rom_cmd == CMD_ST_MEM_ADDR) begin
mem_addr <= r0;
end else if(rom_cmd == CMD_INC_MEM_ADDR) begin
mem_addr <= mem_addr + 32'b1;
end else if(rom_cmd == CMD_LD_REG_FROM_MEM) begin
r0 <= mem_data;
end else if(rom_cmd == CMD_LD_MOD_FROM_MEM) begin
r0 <= ((mask_val & mem_data) | (~mask_val & r0));
end else if(rom_cmd == CMD_ST_REG_TO_MEM) begin
cpu_memory[mem_addr] <= r0;
end
ST_READ_REG:
if(cmd_done)
if(rom_cmd == CMD_READ_REG_BIT)
r0 <= {{REG_VAL_SIZE-1{1'b0}},av_readdata[bit_index]};
else
r0 <= av_readdata;
ST_WAIT_PIO:
r0 <= {{REG_VAL_SIZE-1{1'b0}},pio_in[bit_index]};
endcase
end
//********************* End Output Encoders ***************************
//*********************************************************************
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// Revision 2.0
package pcie_mgmt_functions_h;
`define f_set_rom prog_rom[rom_i]=
`define f_inc_rom rom_i=rom_i+1
import pcie_mgmt_commands_h::*;
localparam MAX_LABEL = 512;
localparam MAX_DEPTH = 4096;
// These should be synthesized away
integer rom_labels[0:(MAX_LABEL-1)];
reg [ROM_WIDTH-1:0] prog_rom [0:(MAX_DEPTH-1)]; // Command storage ROM
integer rom_i;
integer clocks_per_second; // Must be set from outside
task set_clocks_per_second;
input integer new_clocks_per_second;
begin
clocks_per_second = new_clocks_per_second;
end
endtask
task f_noop;
begin
`f_set_rom sleep(0);
`f_inc_rom;
end
endtask
// Halt function
// Required as last instruction in ROM. Instructs the command
// processor to halt execution indefinitely.
//
// @param unused - An unused but required value.
task f_halt;
begin
`f_set_rom halt(0);
`f_inc_rom;
end
endtask
// Sleep function
// Pauses execution for the number of clock cycles specified
// by the parameter "ticks"
//
// @param ticks - The number of clock cycles to sleep
task f_sleep;
input [WAIT_SIZE-1:0] ticks;
begin
`f_set_rom sleep(ticks);
`f_inc_rom;
end
endtask
task f_convert_ctle;
begin
`f_set_rom convert_ctle(0);
`f_inc_rom;
end
endtask
task f_add_to_reg;
input [REG_SIZE-1:0] value;
begin
`f_set_rom add_to_reg(value);
`f_inc_rom;
end
endtask
task f_mod_mem_value;
input [REG_SIZE-1:0] mask;
begin
`f_set_rom modify_reg_from_mem_address(mask);
`f_inc_rom;
end
endtask
task f_sub_from_reg;
input [REG_SIZE-1:0] value;
begin
`f_set_rom sub_from_reg(value);
`f_inc_rom;
end
endtask
task f_inc_mem_address;
begin
`f_set_rom inc_mem_address(0);
`f_inc_rom;
end
endtask
task f_load_mem_address;
begin
`f_set_rom load_mem_addr_to_reg(0);
`f_inc_rom;
end
endtask
task f_store_mem_address;
begin
`f_set_rom store_reg_to_mem_addr(0);
`f_inc_rom;
end
endtask
task f_st_reg_to_address;
begin
`f_set_rom wr_to_mem_address(0);
`f_inc_rom;
end
endtask
task f_ld_address_to_reg;
begin
`f_set_rom rd_from_mem_address(0);
`f_inc_rom;
end
endtask
// Micro-sleep function
// Pauses execution for the number of microseconds specified
// by the parameter "usecs"
//
// @param usecs - The number of microseconds to sleep.
task f_usleep;
input integer usecs;
reg [WAIT_SIZE-1:0] ticks;
begin
ticks = (clocks_per_second / 1000000) * usecs;
f_sleep(ticks);
end
endtask
// Load the internal result register with the value
// specified.
//
// @param datain - The value to be loaded to the internal result
// register
task f_load_result;
input [REG_SIZE-1:0] datain;
begin
`f_set_rom load_result(datain);
`f_inc_rom;
end
endtask
// Write result to register function
// Writes the data stored in the internal result register to the
// register specified by the parameter "address".
//
// @param address - Address of the register to write
task f_write_result_to_reg;
input [REG_SIZE-1:0] address;
begin
`f_set_rom load_address(address);
`f_inc_rom;
`f_set_rom write_reg(0);
`f_inc_rom;
end
endtask
// Write register function
// Writes the data specified by the parameter "writedata" to the
// register specified by the parameter "address". First stores
// the writedata in the internal result register then writes it
// to the the specified address.
//
// @param address - Address of the register to write
// @param writedata - Data to be written to register
task f_write_reg;
input [REG_SIZE-1:0] address;
input [REG_VAL_SIZE-1:0] writedata;
begin
f_load_result(writedata);
f_write_result_to_reg(address);
end
endtask
//Modifies the value of the results register with the value of the
//you with to write to the address. Specify two values. The first
//is used to mask the data register, and the second is the data value
//itself. A 1 in the mask specifies that bit to be written from the data
//value. A 0 in the mask specifies that bit to be igrored. ie recycled.
//
//@param mask_data - 32-bit mask for RMW
//@param modify_data - 32-bt data value for the register
//
//Use: f_modify_reg(mask_data, modify_data);
task f_modify_reg;
input [REG_VAL_SIZE-1:0] mask_data;
input [REG_VAL_SIZE-1:0] modify_data;
begin
`f_set_rom mask_reg(mask_data);
`f_inc_rom;
`f_set_rom modify_reg(modify_data);
`f_inc_rom;
end
endtask
// Read register function
// Reads data from the register specified by the parameter "address"
// and stores the value in the internal result register.
//
// @param address - Address of the register to read
task f_read_reg;
input [REG_SIZE-1:0] address;
begin
`f_set_rom load_address(address);
`f_inc_rom;
`f_set_rom read_reg(0);
`f_inc_rom;
end
endtask
// Read register bit function
// Reads data from the register specified by the parameter "address"
// and stores the value of the bit within the register specified by
// the parameter "bit_index" in the internal result register.
//
// @param address - Address of the register to read
// @param bit_index - Index of the bit within the register to read
task f_read_reg_bit;
input [REG_SIZE-1:0] address;
input [BIT_INDEX_SIZE-1:0] bit_index;
begin
`f_set_rom load_address(address);
`f_inc_rom;
`f_set_rom read_reg_bit(bit_index);
`f_inc_rom;
end
endtask
// Wait for register function
// Continuously reads data from the register specified by the parameter
// "address" and waits until the register's value equals the value
// specified by parameter "expected_data" before continuing execution.
// The value of the register is stored in the internal result register.
//
// @param address - Address of the register to read (and wait for)
// @param expected_data - Value to wait for the register to equal.
task f_wait_for_reg;
input [REG_SIZE-1:0] address;
input [REG_VAL_SIZE-1:0] expected_data;
begin
`f_set_rom load_address(address);
`f_inc_rom;
`f_set_rom wait_for_reg(expected_data);
`f_inc_rom;
end
endtask
// Wait for register bit function
// Continuously reads data from the register specified by the parameter
// "address" and waits until the value of the bit specified by "bit_index"
// equals the value specified by the parameter "expected_data" (0 or 1).
//
// @param address - Address of the register to read (and wait for).
// @param bit_index - Index of the bit within the register to read.
task f_wait_for_reg_bit;
input [REG_SIZE-1:0] address;
input [BIT_INDEX_SIZE-1:0] bit_index;
input [REG_VAL_SIZE-1:0] expected_data;
begin
`f_set_rom load_address(address);
`f_inc_rom;
`f_set_rom wait_for_reg_bit(bit_index, expected_data);
`f_inc_rom;
end
endtask
// Write bit from result register to PIO output bit
// Reads a bit specified by the parameter "result_bit_index" within the
// internal result register and writes the value to the PIO output port bit
// specified by the parameter "pio_bit_index".
//
// @param result_bit_index - Index of the bit within the internal result
// register.
// @param pio_bit_index - Index of the bit within the PIO output port to write
// to.
task f_write_result_bit_to_pio_bit;
input [BIT_INDEX_SIZE-1:0] result_bit_index;
input [BIT_INDEX_SIZE-1:0] pio_bit_index;
begin
`f_set_rom write_result_bit_to_pio_bit(result_bit_index, pio_bit_index);
`f_inc_rom;
end
endtask
// Write PIO bit function
// Writes the value specified by the parameter "bit_value" (0 or 1) to
// the PIO output bit specified by the parameter "bit_index". First
// writes the value to the internal result register then writes it to the
// PIO.
//
// @param bit_index - The bit within the PIO output port to write to.
// @param bit_value - The value to write to the PIO output bit.
task f_write_pio_bit;
input [BIT_INDEX_SIZE-1:0] bit_index;
input [BIT_VAL_SIZE-1:0] bit_value;
begin
f_load_result(bit_value);
f_write_result_bit_to_pio_bit(0, bit_index);
end
endtask
// Read PIO bit function
// Reads a bit from the PIO input port and stores the value (0 or 1) into the
// internal result register.
//
// @param bit_index - Index of bit within the PIO input port to read.
task f_read_pio_bit;
input [BIT_INDEX_SIZE-1:0] bit_index;
begin
`f_set_rom read_pio_bit(bit_index);
`f_inc_rom;
end
endtask
// Wait for PIO bit function
// Continuously reads the value of the bit specified by the parameter
// "bit_index" within the PIO input port and waits for the value of the
// bit to be equal to the value specified by the parameter
// "expected_bit_value" before continuing execution.
//
// @param bit_index - Index of bit within the PIO input port to read.
// @param expected_bit_value - Expected value of the bit on the PIO
// input port
task f_wait_for_pio_bit;
input [BIT_INDEX_SIZE-1:0] bit_index;
input [BIT_VAL_SIZE-1:0] expected_bit_value;
begin
`f_set_rom wait_for_pio_bit(bit_index, expected_bit_value);
`f_inc_rom;
end
endtask
// Compare result function
// Compares the contents of the internal result register to the value
// specified by the parameter "compare_value". Stores the result (1 for
// no-match, 0 for match) in the internal result register.
//
// @param compare_value. The value to compare with the internal result
// register.
task f_compare_result;
input [CMP_VAL_SIZE-1:0] compare_value;
begin
`f_set_rom compare_result(compare_value);
`f_inc_rom;
end
endtask
// Set a label which can be subsequently jumped to.
//
// @param label - The integer label to assign as an identifier.
task f_label;
input integer label;
begin
if(rom_labels[label] != -1)
$display("[f_label] ERROR - Duplicate label %0d! at address %0d", label, rom_i);
else if(label < MAX_LABEL && label >= 0)
rom_labels[label] = rom_i;
else
$display("[f_label] ERROR - Invalid label: %0d!, must be between 0<=MAX_LABEL", label);
end
endtask
// jump-not-equal-zero instruction
// Compares the contents of the internal result register to 0. If the
// contents are 0, program execution continues, otherwise the program
// jumps to the indicated label which was set by a previous set_label command
task f_jump_not_equal_zero;
input integer label;
begin
if(label > MAX_LABEL || label < 0)
$display("[mgmt_master] ERROR - Invalid jump label %0d!, must be between 0<=MAX_LABEL", label);
begin
`f_set_rom jump_not_equal_zero(label);
`f_inc_rom;
end
end
endtask
task pre_process;
begin
// Initialize ROM with HALT instructions
for(rom_i=0;rom_i<MAX_DEPTH;rom_i=rom_i+1) begin
prog_rom[rom_i] = halt(0);
end
// Initialize ROM labels (0 is an invalid address)
for(rom_i=0;rom_i<MAX_LABEL;rom_i=rom_i+1) begin
rom_labels[rom_i] = -1;
end
rom_i = 0;
f_noop(); // First instruction is a NOOP
end
endtask
// The post process task resolves code labels and jump instructions
task post_process;
integer label;
begin
for(rom_i=0;rom_i<MAX_DEPTH;rom_i=rom_i+1) begin
label = prog_rom[rom_i][REG_VAL_OFST+:REG_VAL_SIZE];
if(prog_rom[rom_i][CMD_OFST+:CMD_SIZE] == CMD_JNEZ) begin
if(rom_labels[label] == -1) begin
$display("[post_process] ERROR - Invalid jump label %0d at address %0d. Label not initialized!", label, rom_i);
end else begin
`f_set_rom jump_not_equal_zero(rom_labels[label]);
end
end
end
end
endtask
`undef f_set_rom
`undef f_inc_rom
endpackage
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1ps/1ps
// Revision 2.0
module pcie_mgmt_master #(
parameter CLOCKS_PER_SECOND = 125000000, // Used for time calculations
parameter PIO_OUT_SIZE = 8, // Width of PIO output port
parameter PIO_IN_SIZE = 8, // Width of PIO input port
parameter [PIO_OUT_SIZE-1:0] PIO_OUT_INIT_VALUE = 0, // Initial value for pio_out registers
parameter MEM_DEPTH = 8,
parameter ROM_DEPTH = 512 // Depth of command ROM
// parameter INIT_FILE_NAME = "" // If specified, ROM will be initialized from file using $readmemh
) (
input clk,
input reset,
output reg av_write,
output reg av_read,
output reg [30:0] av_address,
output reg [31:0] av_writedata,
input [31:0] av_readdata,
input av_waitrequest,
output reg [PIO_OUT_SIZE-1:0] pio_out,
input [ PIO_IN_SIZE-1:0] pio_in
);
import pcie_mgmt_functions_h::*;
import pcie_mgmt_commands_h::*;
import pcie_mgmt_program::*;
//localparam LOAD_FROM_FILE = (INIT_FILE_NAME == "") ? 0 : 1;
//localparam FILETYPE="hex";
localparam ADDR_WIDTH = clogb2(ROM_DEPTH);
reg [ROM_WIDTH-1:0] rom [0:(ROM_DEPTH-1)]; // Command storage ROM
wire [ADDR_WIDTH-1:0] rom_address;
wire rom_read;
reg [ ROM_WIDTH-1:0] rom_data;
//*********************************************************************
//************************ Command ROM ********************************
// Output addressed ROM contents
always @ (posedge clk)
if(rom_read)
rom_data <= rom[rom_address];
//********************** End Command ROM ******************************
//*********************************************************************
pcie_mgmt_cpu #(
.PIO_OUT_SIZE (PIO_OUT_SIZE),
.PIO_IN_SIZE (PIO_IN_SIZE ),
.PIO_OUT_INIT_VALUE (PIO_OUT_INIT_VALUE),
.ROM_DEPTH (ROM_DEPTH ),
.MEM_DEPTH (MEM_DEPTH)
) mgmt_cpu_inst (
.clk (clk ),
.reset (reset ),
.av_write (av_write ),
.av_read (av_read ),
.av_address (av_address ),
.av_writedata (av_writedata ),
.av_readdata (av_readdata ),
.av_waitrequest (av_waitrequest ),
.rom_address (rom_address ),
.rom_read (rom_read ),
.rom_data (rom_data ),
.pio_out (pio_out ), .pio_in (pio_in )
);
//generate if(LOAD_FROM_FILE == 0) begin : load_ram
integer i;
initial begin
clocks_per_second = CLOCKS_PER_SECOND;
pre_process(); // Pre process
pcie_mgmt_program();
post_process(); // Post process program
// Copy program from temporary prog_rom to rom
for(i=0;i<ROM_DEPTH;i=i+1) begin
rom[i] = prog_rom[i];
end
end
//end
//
//else begin
// if(FILETYPE == "hex") begin
// initial begin
// $readmemh(INIT_FILE_NAME, rom);
// end
// end else begin
// initial begin
// $readmemb(INIT_FILE_NAME, rom);
// end
// end
//end
//endgenerate
// Undefine previously defined macros
`ifdef MGMT_UNDEF
`undef MGMT_PROGRAM_TASK
`undef MGMT_UNDEF
`endif
endmodule
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
// Revision 2.0
package pcie_mgmt_program;
import pcie_mgmt_functions_h::*;
import altera_xcvr_native_pcie_dfe_params_h::*;
task pcie_mgmt_program;
begin
// Read the calibration status
f_sleep (SLEEP_DELAY);
f_read_reg (ADDR_CALIBRATION);
//////////////////////////////////////////////////////////
// All for-loops are done via handshake from the CPU to the SM
// This way, the loops can be parameterized via channel, and
// the looping won't require adding a new reg to the memory
//
// ** IMPORTANT **
// Don't know what I'm going to put here yet, but there has
// to be something important, right?
//////////////////////////////////////////////////////////
f_label (PRGM_BEGIN);
// Clear all pio_out
f_write_pio_bit (PIO_OUT_ERROR,0);
f_write_pio_bit (PIO_OUT_RUNNING,0);
f_write_pio_bit (PIO_OUT_SW_GEN_1_2,0);
f_write_pio_bit (PIO_OUT_SW_GEN_3,0);
f_write_pio_bit (PIO_OUT_PHASE2_CTLE,0);
f_write_pio_bit (PIO_OUT_PHASE2_DFE,0);
f_write_pio_bit (PIO_OUT_RESTORE_MODEB,0);
// Set Tag for beginning of program
f_load_result (32'b0); // Since the address store works off of r0... set r0 first
f_store_mem_address (); // Store r0 into the mem address
// Begin!
// First check for the "Go!"
// We hit the Go! - Set a bit to indicate SM is running
f_wait_for_pio_bit (PIO_IN_GO, 1);
//////////////////////////////////////////////////////////
// Decode the incoming PIO to determine which steps to run
// then jump to the correct section of the code. If none
// of the bits are asserted, then assert the error bit
// and go to the beginning of the program
//////////////////////////////////////////////////////////
// Read PIO[1] - Are We rate switching to Gen3
f_read_pio_bit (PIO_IN_SW_GEN_3);
// Jump!
f_jump_not_equal_zero (PRGM_SW_GEN3);
//////////////////////////////////////////////////////////
// Read PIO[2] - Are we entering Phase 2 Equalization; check ctle
f_read_pio_bit (PIO_IN_PHASE2_CTLE);
// Jump!
f_jump_not_equal_zero (PRGM_PHASE2_CTLE);
//////////////////////////////////////////////////////////
// Read PIO[2] - Are we entering Phase 2 Equalization; run DFE
f_read_pio_bit (PIO_IN_PHASE2_DFE);
// Jump!
f_jump_not_equal_zero (PRGM_PHASE2_DFE);
//////////////////////////////////////////////////////////
// Read PIO[3] - Are we returning to Gen1/2
f_read_pio_bit (PIO_IN_SW_GEN_1_2);
// Jump!
f_jump_not_equal_zero (PRGM_SW_GEN1_2);
//////////////////////////////////////////////////////////
// Read PIO[3] - Are we returning to Gen1/2
f_read_pio_bit (PIO_IN_RESTORE_MODEB);
// Jump!
f_jump_not_equal_zero (PRGM_RESTORE_MODEB);
//////////////////////////////////////////////////////////
// None of the PIO were asserted... we have an error
f_write_pio_bit (PIO_OUT_ERROR,1);
f_sleep (SLEEP_DELAY);
f_write_pio_bit (PIO_OUT_ERROR,0);
// Return to the beginning
f_load_result (FORCE_JUMP);
f_jump_not_equal_zero (PRGM_BEGIN);
//////////////////////////////////////////////////////////
// Code for returning to Gen1/2. The CTLE values are hard
// coded. We want to first assert the signal to indicate
// we are switching back. We can use this to verify the
// jump and the code. At the end of the
//////////////////////////////////////////////////////////
// We made it this far... we must be returning to Gen1/2
// Code for entering Gen1/2
f_label (PRGM_SW_GEN1_2);
// Assert the signal to indicate we are running Gen1/2 switch
f_write_pio_bit (PIO_OUT_SW_GEN_1_2,1);
f_write_pio_bit (PIO_OUT_RUNNING,1);
//<-- Put Code Here -->//
f_read_reg (31'h167);
f_modify_reg (32'h3E, GEN1_GEN2_CTLE_VAL);
f_write_result_to_reg (31'h167);
// Clear all DFE Taps
// Read second address for a channel... DFE Tap 1
f_read_reg (32'h14F);
f_modify_reg (32'hFF, 32'h00);
f_write_result_to_reg (32'h14F);
// Read second address for a channel... DFE Tap 2
f_read_reg (32'h150);
f_modify_reg (32'hFF, 32'h00);
f_write_result_to_reg (32'h150);
// Read second address for a channel... DFE Tap 3
f_read_reg (32'h151);
f_modify_reg (32'hFF, 32'h00);
f_write_result_to_reg (32'h151);
// Read second address for a channel... DFE Tap 4
f_read_reg (32'h152);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h152);
// Read second address for a channel... DFE Tap 5
f_read_reg (32'h153);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h153);
// Read second address for a channel... DFE Tap 6
f_read_reg (32'h154);
f_modify_reg (32'h3F, 32'h00);
f_write_result_to_reg (32'h154);
// Read second address for a channel... DFE Tap 7
f_read_reg (32'h155);
f_modify_reg (32'h3F, 32'h00);
f_write_result_to_reg (32'h155);
// Read second address for a channel... DFE Tap 8
f_read_reg (32'h157);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h157);
// Read second address for a channel... DFE Tap 9
f_read_reg (32'h158);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h158);
// Read second address for a channel... DFE Tap 10
f_read_reg (32'h159);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h159);
// Read second address for a channel... DFE Tap 11
f_read_reg (32'h15A);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h15A);
//<-- End Code Here -->//
// Indicate channel is done
f_write_pio_bit (PIO_OUT_RUNNING,0);
// If PIO_IN_GO isn't low, then we havn't completed all channels. Repeat
f_sleep (SLEEP_DELAY);
f_read_pio_bit (PIO_IN_GO);
f_jump_not_equal_zero (PRGM_SW_GEN1_2);
// Return to Beginning
f_load_result (FORCE_JUMP);
f_jump_not_equal_zero (PRGM_BEGIN);
//////////////////////////////////////////////////////////
// Code for entering Gen3
// When entering Gen3, restore the DFE settings from the mem
//////////////////////////////////////////////////////////
// We made it this far... we must be returning to Gen1/2
f_label (PRGM_SW_GEN3);
// Assert the signal to indicate we are switching to Gen3
f_write_pio_bit (PIO_OUT_SW_GEN_3,1);
f_write_pio_bit (PIO_OUT_RUNNING,1);
//<-- Put Code Here -->//
// Reading from the first address for a channel... CTLE value
f_read_reg (32'h167);
f_convert_ctle ();
f_write_result_to_reg (32'h167);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 1
f_read_reg (32'h14F);
f_modify_reg (32'hFF, 32'h00);
//f_mod_mem_value (32'hFF);
f_write_result_to_reg (32'h14F);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 2
f_read_reg (32'h150);
f_mod_mem_value (32'hFF);
f_write_result_to_reg (32'h150);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 3
f_read_reg (32'h151);
f_mod_mem_value (32'hFF);
f_write_result_to_reg (32'h151);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 4
f_read_reg (32'h152);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h152);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 5
f_read_reg (32'h153);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h153);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 6
f_read_reg (32'h154);
f_mod_mem_value (32'h3F);
f_write_result_to_reg (32'h154);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 7
f_read_reg (32'h155);
f_mod_mem_value (32'h3F);
f_write_result_to_reg (32'h155);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 8
f_read_reg (32'h157);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h157);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 9
f_read_reg (32'h158);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h158);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 10
f_read_reg (32'h159);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h159);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 11
f_read_reg (32'h15A);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h15A);
f_inc_mem_address ();
//////////////////////////////////////////////////////////
// Read the PIO bit
// Use the compare result function as an inverter... when the input
// is 0 and we compare it with 0, it will stay 0, else it will
// 1. To load taps, create a multi-cycle pulse
f_read_pio_bit (PIO_IN_CONTINUOUS_DFE);
f_compare_result (32'b1);
// Jump to skip loading the DFE taps to adaptation
f_jump_not_equal_zero (PRGM_SKIP_DFE_LOAD);
// Load the DFE Taps into the adaptation block
// adp_dfe_fxtap_load = RADP_DFE_FXTAP_LOAD_1
f_read_reg (32'h15B);
f_modify_reg (32'h2,32'h2);
f_write_result_to_reg (32'h15B);
// create an extended pulse
f_sleep (SLEEP_DELAY);
// Clear the load signal for the DFE taps
// adp_dfe_fxtap_load = RADP_DFE_FXTAP_LOAD_0
f_read_reg (32'h15B);
f_modify_reg (32'h2,32'h0);
f_write_result_to_reg (32'h15B);
// Skips loading the DFE taps
f_label (PRGM_SKIP_DFE_LOAD);
//<-- End Code Here -->//
// Indicate channel is done
f_write_pio_bit (PIO_OUT_RUNNING,0);
// If PIO_IN_GO isn't low, then we havn't completed all channels. Repeat
f_sleep (SLEEP_DELAY);
f_read_pio_bit (PIO_IN_GO);
f_jump_not_equal_zero (PRGM_SW_GEN3);
// Return to Beginning
f_load_result (FORCE_JUMP);
f_jump_not_equal_zero (PRGM_BEGIN);
//////////////////////////////////////////////////////////
// Code for entering Phase 2
// When running phase 2, wait for the GO signal, which should
// be after a 12ms timeout. At which point, save the CTLE
// setting, and read out the value before enabling DFE manual
// mode. once in manual mode, jump and let the Master SM
// change the channels before starting again. In the meantime
// the Master SM will run a 10ms timeout. After the 10ms,
// save the DFE settings into the memory
//////////////////////////////////////////////////////////
// CTLE Time - read out the CTLE value
// TODO: Do I need to save the originals?
f_label (PRGM_PHASE2_CTLE);
// Assert the signal to indicate we are switching to Gen3
f_write_pio_bit (PIO_OUT_PHASE2_CTLE,1);
f_write_pio_bit (PIO_OUT_RUNNING,1);
//<-- Put Code Here -->//
//////////////////////////////////////////////////////////
// Set the testbus
// Set the test mux value to point to CTLE
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h1B);
f_write_result_to_reg (32'h14C);
// Wait 5 cycles, then read the value out and compare it to verify we
// wrote the correct testbus
f_sleep (TST_MUX_DELAY);
// Read out the value
f_read_reg (32'h177); // Backup... in case 171 is a different setting
f_st_reg_to_address ();
//////////////////////////////////////////////////////////
// Disable the Adaptation Mode B and configure to Adaptation Mode E
// pdb_fxtap4t7 = FXTAP4T7_ENABLE
f_read_reg (32'h123);
f_modify_reg (32'h8,32'h8);
f_write_result_to_reg (32'h123);
// adp_dfe_fxtap_en = RADP_DFE_FXTAP_ENABLE
// adp_dfe_fltap_en = RADP_DFE_FLTAP_ENABLE
f_read_reg (32'h148);
f_modify_reg (32'h3,32'h3);
f_write_result_to_reg (32'h148);
// adp_dfe_fxtap_bypass = RADP_DFE_FXTAP_BYPASS_0
// adp_dfe_fltap_bypass = RADP_DFE_FLTAP_BYPASS_0
// adp_dfe_fxtap_hold_en = RADP_DFE_FXTAP_NOT_HELD
f_read_reg (32'h15B);
f_modify_reg (32'h15,32'h0);
f_write_result_to_reg (32'h15B);
// adp_vga_bypass = RADP_VGA_BYPASS_1
f_read_reg (32'h160);
f_modify_reg (32'h1,32'h1);
f_write_result_to_reg (32'h160);
// adp_dfe_mode = RADP_DFE_MODE_0
f_read_reg (32'h14D);
f_modify_reg (32'h7,32'h0);
f_write_result_to_reg (32'h14D);
// adp_ctle_adapt_cycle_window = RADP_CTLE_ADAPT_CYCLE_WINDOW_0
f_read_reg (32'h163);
f_modify_reg (32'hE0,32'h0);
f_write_result_to_reg (32'h163);
// adp_1s_ctle_bypass = RADP_1S_CTLE_BYPASS_1
f_read_reg (32'h166);
f_modify_reg (32'h1,32'h1);
f_write_result_to_reg (32'h166);
// adp_4s_ctle_bypass = RADP_4S_CTLE_BYPASS_1
f_read_reg (32'h167);
f_modify_reg (32'h1,32'h1);
f_write_result_to_reg (32'h167);
//////////////////////////////////////////////////////////
// Write back the CTLE Manual setting
f_convert_ctle ();
f_write_result_to_reg (32'h167);
// Index to the start of the next channel's CTLE memory address
f_load_mem_address ();
f_add_to_reg (NUM_ADDR_PER_CHNL);
f_store_mem_address ();
//////////////////////////////////////////////////////////
// Start the DFE
// adp_adapt_control_sel = RADP_ADAPT_CONTROL_SEL_1
f_read_reg (32'h149);
f_modify_reg (32'h10,32'h10);
f_write_result_to_reg (32'h149);
// assert adp_start = radp_adapt_start_0
f_read_reg (32'h149);
f_modify_reg (32'h20,32'h0);
f_write_result_to_reg (32'h149);
// rstn by adp_adp_rstn = radp_adapt_rstn_0
f_read_reg (32'h149);
f_modify_reg (32'h40,32'h0);
f_write_result_to_reg (32'h149);
// rstn by adp_adp_rstn = radp_adapt_rstn_1
f_read_reg (32'h149);
f_modify_reg (32'h40,32'h40);
f_write_result_to_reg (32'h149);
// assert adp_start = radp_adapt_start_1
f_read_reg (32'h149);
f_modify_reg (32'h20,32'h20);
f_write_result_to_reg (32'h149);
//<-- End Code Here -->//
// Indicate channel is done
f_write_pio_bit (PIO_OUT_RUNNING,0);
// If PIO_IN_GO isn't low, then we havn't completed all channels. Repeat
f_sleep (SLEEP_DELAY);
f_read_pio_bit (PIO_IN_GO);
f_jump_not_equal_zero (PRGM_PHASE2_CTLE);
// Return to beginning
f_load_result (FORCE_JUMP);
f_jump_not_equal_zero (PRGM_BEGIN);
//////////////////////////////////////////////////////////
// DFE time - read out the DFE converged values
// We are still in Phase 2, however the 10ms are up,
// and we can now store the values for the DFE
//////////////////////////////////////////////////////////
f_label (PRGM_PHASE2_DFE);
// Assert the signal to indicate we are reading out DFE
f_write_pio_bit (PIO_OUT_PHASE2_DFE,1);
f_write_pio_bit (PIO_OUT_RUNNING,1);
//<-- Put Code Here -->//
// Set the starting address for DFE
f_load_mem_address ();
f_add_to_reg (NUM_ADDR_CTLE);
f_store_mem_address ();
// Check the PIO in for continuous dfe... we need to skip the TAP hold
f_read_pio_bit (PIO_IN_CONTINUOUS_DFE);
f_jump_not_equal_zero (PRGM_SKIP_DFE_HOLD);
// Assert the Hold for DFE -- Might need to be moved
// adp_dfe_fxtap_hold_en = RADP_DFE_FXTAP_HELD
f_read_reg (32'h15B);
f_modify_reg (32'h10,32'h10);
f_write_result_to_reg (32'h15B);
// Used to skip the DFE HOLD on the Taps
f_label (PRGM_SKIP_DFE_HOLD);
// Setup the test mux for DFE
f_read_reg (32'h171);
f_modify_reg (32'h1E,32'h16);
f_write_result_to_reg (32'h171);
// Read back TAP 1
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h1E);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
// Read back TAP 2
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h1F);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
// Read back TAP 3
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h20);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
// Read back TAP 4
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h21);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
// Read back TAP 5
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h22);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
// Read back TAP 6
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h23);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
// Read back TAP 7
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h24);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
// Read back TAP 8
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h25);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
// Read back TAP 9
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h26);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
// Read back TAP 10
f_read_reg (32'h14C);
f_modify_reg (32'h3F,32'h27);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
// Read back TAP 11
f_read_reg (32'h14C);;
f_modify_reg (32'h3F,32'h28);
f_write_result_to_reg (32'h14C);
f_sleep (TST_MUX_DELAY);
f_read_reg (32'h176);
f_st_reg_to_address ();
f_inc_mem_address ();
//////////////////////////////////////////////////////////
// Check the status of continuous DFE. If the status is set, skip manual DFE
// and jump to the end of writing back the tap values. At that point write the
// bits to enable Mode 4. If we do run manual DFE, force a jump at the end to
// skip the continuous DFE Mode 4 write
f_read_pio_bit (PIO_IN_CONTINUOUS_DFE);
// Skip manual DFE
f_jump_not_equal_zero (PRGM_SKIP_MANUAL_DFE);
//////////////////////////////////////////////////////////
// Disable DFE One time, and switch to manual manual
// adp_dfe_fxtap_en = RADP_DFE_FXTAP_DISABLE
// adp_dfe_fltap_en = RADP_DFE_FLTAP_DISABLE
// adp_vref_en = RADP_VREF_DISABLE
// adp_vga_en = RADP_VGA_DISABLE
// adp_ctle_en = RADP_CTLE_DISABLE
f_read_reg (32'h148);
f_modify_reg (32'h1F,32'h0);
f_write_result_to_reg (32'h148);
// adp_dfe_fxtap_bypass = RADP_DFE_FXTAP_BYPASS_1
// adp_dfe_fltap_bypass = RADP_DFE_FLTAP_BYPASS_1
f_read_reg (32'h15B);
f_modify_reg (32'h5,32'h5);
f_write_result_to_reg (32'h15B);
// adp_vref_bypass = RADP_VREF_BYPASS_1
f_read_reg (32'h15E);
f_modify_reg (32'h1,32'h1);
f_write_result_to_reg (32'h15E);
// adp_ctle_adapt_cycle_window = RADP_CTLE_ADAPT_CYCLE_WINDOW_7
f_read_reg (32'h163);
f_modify_reg (32'hE0,32'hE0);
f_write_result_to_reg (32'h163);
// Might have to disable DFE Hold
// adp_dfe_fxtap_hold_en = RADP_DFE_FXTAP_NOT_HELD
//////////////////////////////////////////////////////////
// Load the DFE Manual
// Potential enhancement: Call Gen3_SW to set all the DFE Taps
// For now, finish, and then make an immediate call to run Gen3 SW
// Restore the address for the start of the Memory
f_load_mem_address ();
f_sub_from_reg (NUM_ADDR_DFE);
f_store_mem_address ();
// Read second address for a channel... DFE Tap 1
f_read_reg (32'h14F);
f_modify_reg (32'hFF, 32'h00);
//f_mod_mem_value (32'hFF);
f_write_result_to_reg (32'h14F);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 2
f_read_reg (32'h150);
f_mod_mem_value (32'hFF);
f_write_result_to_reg (32'h150);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 3
f_read_reg (32'h151);
f_mod_mem_value (32'hFF);
f_write_result_to_reg (32'h151);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 4
f_read_reg (32'h152);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h152);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 5
f_read_reg (32'h153);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h153);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 6
f_read_reg (32'h154);
f_mod_mem_value (32'h3F);
f_write_result_to_reg (32'h154);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 7
f_read_reg (32'h155);
f_mod_mem_value (32'h3F);
f_write_result_to_reg (32'h155);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 8
f_read_reg (32'h157);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h157);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 9
f_read_reg (32'h158);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h158);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 10
f_read_reg (32'h159);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h159);
f_inc_mem_address ();
// Read second address for a channel... DFE Tap 11
f_read_reg (32'h15A);
f_mod_mem_value (32'h7F);
f_write_result_to_reg (32'h15A);
f_inc_mem_address ();
//////////////////////////////////////////////////////////
// Force a jump to skip continuous DFE
// This jump is only executed when we run manual DFE; in continuous we
// use a jump to skip the manual process (including this jump) If we
// use this jump, go ahead and skip manual
f_load_result (FORCE_JUMP);
f_jump_not_equal_zero (PRGM_SKIP_CONT_DFE);
// label for the end of manual mode
f_label (PRGM_SKIP_MANUAL_DFE);
// Switch adaptation from Mode 8 to Mode 4 to support loading
// adp_mode = RADP_MODE_4
f_read_reg (32'h149);
f_modify_reg (32'h0F,32'h04);
f_write_result_to_reg (32'h149);
// label for the end of continuous DFE
f_label (PRGM_SKIP_CONT_DFE);
//<-- End Code Here -->//
// Indicate channel is done
f_write_pio_bit (PIO_OUT_RUNNING,0);
// If PIO_IN_GO isn't low, then we havn't completed all channels. Repeat
f_sleep (SLEEP_DELAY);
f_read_pio_bit (PIO_IN_GO);
f_jump_not_equal_zero (PRGM_PHASE2_DFE);
// Return to beginning
f_load_result (FORCE_JUMP);
f_jump_not_equal_zero (PRGM_BEGIN);
//////////////////////////////////////////////////////////
// If we hit a global reset or enter detect
//////////////////////////////////////////////////////////
f_label (PRGM_RESTORE_MODEB);
// Assert the signal to indicate we need to restore the original
// Adapation Mode settings
// TODO: should these be hard coded or do we need to save them?
f_write_pio_bit (PIO_OUT_RESTORE_MODEB,1);
f_write_pio_bit (PIO_OUT_RUNNING,1);
//<-- Put Code Here -->//
//////////////////////////////////////////////////////////
// We are reseting... Restore Mode B
// adp_dfe_fxtap_en = RADP_DFE_FXTAP_DISABLE
// adp_dfe_fltap_en = RADP_DFE_FLTAP_DISABLE
// adp_vref_en = RADP_VREF_ENABLE
// adp_vga_en = RADP_VGA_ENABLE
// adp_ctle_en = RADP_CTLE_ENABLE
f_read_reg (32'h148);
f_modify_reg (32'h1F,32'h1C);
f_write_result_to_reg (32'h148);
// Switch adaptation from Mode 4 to Mode 8 to support running
// continuous CTLE. If we are not in continuous DFE, skip
f_read_pio_bit (PIO_IN_CONTINUOUS_DFE);
f_compare_result (32'b1);
f_jump_not_equal_zero (PRGM_SKIP_DFE_MODE_8);
// adp_mode = RADP_MODE_8
f_read_reg (32'h149);
f_modify_reg (32'h0F,32'h08);
f_write_result_to_reg (32'h149);
// SKIP Mode8
f_label (PRGM_SKIP_DFE_MODE_8);
// adp_vref_bypass = RADP_VREF_BYPASS_0
f_read_reg (32'h15E);
f_modify_reg (32'h1,32'h0);
f_write_result_to_reg (32'h15E);
// adp_vga_bypass = RADP_VGA_BYPASS_1
f_read_reg (32'h160);
f_modify_reg (32'h1,32'h1);
f_write_result_to_reg (32'h160);
// adp_1s_ctle_bypass = RADP_1S_CTLE_BYPASS_0
f_read_reg (32'h166);
f_modify_reg (32'h1,32'h0);
f_write_result_to_reg (32'h166);
// adp_4s_ctle_bypass = RADP_4S_CTLE_BYPASS_0
f_read_reg (32'h167);
f_modify_reg (32'h1,32'h0);
f_write_result_to_reg (32'h167);
// Restore Gen1/2 rates
f_read_reg (31'h167);
f_modify_reg (32'h3E, GEN1_GEN2_CTLE_VAL);
f_write_result_to_reg (31'h167);
// Clear all DFE Taps
// Read second address for a channel... DFE Tap 1
f_read_reg (32'h14F);
f_modify_reg (32'hFF, 32'h00);
f_write_result_to_reg (32'h14F);
// Read second address for a channel... DFE Tap 2
f_read_reg (32'h150);
f_modify_reg (32'hFF, 32'h00);
f_write_result_to_reg (32'h150);
// Read second address for a channel... DFE Tap 3
f_read_reg (32'h151);
f_modify_reg (32'hFF, 32'h00);
f_write_result_to_reg (32'h151);
// Read second address for a channel... DFE Tap 4
f_read_reg (32'h152);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h152);
// Read second address for a channel... DFE Tap 5
f_read_reg (32'h153);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h153);
// Read second address for a channel... DFE Tap 6
f_read_reg (32'h154);
f_modify_reg (32'h3F, 32'h00);
f_write_result_to_reg (32'h154);
// Read second address for a channel... DFE Tap 7
f_read_reg (32'h155);
f_modify_reg (32'h3F, 32'h00);
f_write_result_to_reg (32'h155);
// Read second address for a channel... DFE Tap 8
f_read_reg (32'h157);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h157);
// Read second address for a channel... DFE Tap 9
f_read_reg (32'h158);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h158);
// Read second address for a channel... DFE Tap 10
f_read_reg (32'h159);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h159);
// Read second address for a channel... DFE Tap 11
f_read_reg (32'h15A);
f_modify_reg (32'h7F, 32'h00);
f_write_result_to_reg (32'h15A);
//<-- End Code Here -->//
// Indicate channel is done
f_write_pio_bit (PIO_OUT_RUNNING,0);
// If PIO_IN_GO isn't low, then we havn't completed all channels. Repeat
f_sleep (SLEEP_DELAY);
f_read_pio_bit (PIO_IN_GO);
f_jump_not_equal_zero (PRGM_RESTORE_MODEB);
// Return to beginning
f_load_result (FORCE_JUMP);
f_jump_not_equal_zero (PRGM_BEGIN);
end
endtask
endpackage
./alt_xcvr_resync.sv
./alt_xcvr_arbiter.sv
./twentynm_pcs.sv
./twentynm_pma.sv
./twentynm_xcvr_avmm.sv
./twentynm_xcvr_native.sv
./altera_xcvr_native_a10_functions_h.sv
./a10_avmm_h.sv
./alt_xcvr_native_pipe_retry.sv
./alt_xcvr_native_avmm_csr.sv
./alt_xcvr_native_prbs_accum.sv
./alt_xcvr_native_odi_accel.sv
./alt_xcvr_native_rcfg_arb.sv
./altera_xcvr_native_pcie_dfe_params_h.sv
./pcie_mgmt_commands_h.sv
./pcie_mgmt_functions_h.sv
./pcie_mgmt_program.sv
./pcie_mgmt_cpu.sv
./pcie_mgmt_master.sv
./altera_xcvr_native_pcie_dfe_ip.sv
// (C) 2001-2018 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files from 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 Intel Program License Subscription
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors. Please refer to the applicable
// agreement for further details.
`timescale 1ps/1ps
module twentynm_xcvr_avmm
#(
//PARAM_LIST_START
parameter avmm_interfaces = 1, //Number of AVMM interfaces required - one for each bonded_lane, PLL, and Master CGB
parameter rcfg_enable = 0, //Enable/disable reconfig interface in the Native PHY or PLL IP
parameter enable_avmm = 1, //Enable/disable AVMM atom instantiation
parameter arbiter_ctrl = "pld", //Calibration request at start-up. Valid values: "uc","pld".
//"uc" =Initial calibration needed at start-up. Internal DPRIO interface is controlled by uC.
//"pld"=Initial calibration is not needed at start-up. Internal DPRIO interface is controlled by PLD.
parameter calibration_en = "disable", //Indicates whether calibration by Hard Nios is enabled or not.Should be set to DISABLE in case if Nios is absent or needs to be bypassed. Valid values: enable, disable
parameter avmm_busy_en = "disable", //Provides a separate interface for determining control of the AVMM bus, and separates its behavior from the avmm_waitreqeust
parameter hip_cal_en = "disable", //Indicates whether HIP is enabled or not. Valid values: disable, enable
parameter cal_done = "cal_done_assert" //Indicates whether calibration is done. This is the start-up value for the corresponding CRAM. THe CRAM is eventually accessed and updated by the Hard uC during calibration. Valid values: cal_done_assert, cal_done_deassert
//PARAM_LIST_END
) (
//PORT_LIST_START
// AVMM slave interface signals (user)
input wire [avmm_interfaces-1 :0] avmm_clk,
input wire [avmm_interfaces-1 :0] avmm_reset,
input wire [avmm_interfaces*8-1 :0] avmm_writedata,
input wire [avmm_interfaces*9-1 :0] avmm_address,
input wire [avmm_interfaces-1 :0] avmm_write,
input wire [avmm_interfaces-1 :0] avmm_read,
output wire [avmm_interfaces*8-1 :0] avmm_readdata,
output wire [avmm_interfaces-1 :0] avmm_waitrequest,
//AVMM interface busy with calibration
output wire [avmm_interfaces-1 :0] avmm_busy,
// Calibration Done
output wire [avmm_interfaces-1 :0] hip_cal_done, //To HIP
output wire [avmm_interfaces-1 :0] pld_cal_done, //To PLD
// Channel/PLL AVMM interface signals (from AVMM atom fanned-out to all the Channel/PLL atoms)
output wire [avmm_interfaces-1 :0] chnl_pll_avmm_clk,
output wire [avmm_interfaces-1 :0] chnl_pll_avmm_rstn,
output wire [avmm_interfaces*8-1 :0] chnl_pll_avmm_writedata, //Internal AVMM interface is 8-bit wide
output wire [avmm_interfaces*9-1 :0] chnl_pll_avmm_address,
output wire [avmm_interfaces-1 :0] chnl_pll_avmm_write,
output wire [avmm_interfaces-1 :0] chnl_pll_avmm_read,
// PMA AVMM signals
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_tx_ser, // TX SER readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_tx_cgb, // TX Slave CGB readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_tx_buf, // TX BUF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_rx_deser, // RX Deser readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_rx_buf, // RX BUF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_rx_sd, // RX SD readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_rx_odi, // RX ODI readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_rx_dfe, // RX DFE readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_cdr_pll, // CDR readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_cdr_refclk_select, // CDR refclk mux readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pma_avmmreaddata_pma_adapt, // PMA adaptation readdata (8 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_tx_ser, // TX SER blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_tx_cgb, // TX Slave CGB blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_tx_buf, // TX BUF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_rx_deser, // RX Deser blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_rx_buf, // RX BUF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_rx_sd, // RX SD blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_rx_odi, // RX ODI blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_rx_dfe, // RX DFE blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_cdr_pll, // CDR blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_cdr_refclk_select, // CDR refclk mux blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pma_blockselect_pma_adapt, // PMA adaptation blockselect (1 for each lane)
// PCS Channel AVMM signals
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_8g_rx_pcs, // 8G RX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_pipe_gen1_2, // Gen1/2 PIPE readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_8g_tx_pcs, // 8G TX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_10g_rx_pcs, // 10G RX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_10g_tx_pcs, // 10G TX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_gen3_rx_pcs, // GEN3 RX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_pipe_gen3, // GEN3 PIPE readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_gen3_tx_pcs, // GEN3 TX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_krfec_rx_pcs, // KRFEC RX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_krfec_tx_pcs, // KRFEC TX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_fifo_rx_pcs, // FIFO RX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_fifo_tx_pcs, // FIFO TX PCS readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_rx_pcs_pld_if, // RX PCS PLD IF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_com_pcs_pld_if, // COM PCS PLD IF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_tx_pcs_pld_if, // TX PCS PLD IF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_rx_pcs_pma_if, // RX PCS PMA IF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_com_pcs_pma_if, // COm PCS PMA IF readdata (8 for each lane)
input wire [avmm_interfaces*8-1 :0] pcs_avmmreaddata_tx_pcs_pma_if, // TX PCS PMA IF readdata (8 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_8g_rx_pcs, // 8G RX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_pipe_gen1_2, // Gen1/2 PIPE blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_8g_tx_pcs, // 8G TX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_10g_rx_pcs, // 10G RX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_10g_tx_pcs, // 10G TX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_gen3_rx_pcs, // GEN3 RX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_pipe_gen3, // GEN3 PIPE blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_gen3_tx_pcs, // GEN3 TX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_krfec_rx_pcs, // KRFEC RX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_krfec_tx_pcs, // KRFEC TX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_fifo_rx_pcs, // FIFO RX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_fifo_tx_pcs, // FIFO TX PCS blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_rx_pcs_pld_if, // RX PCS PLD IF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_com_pcs_pld_if, // COM PCS PLD IF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_tx_pcs_pld_if, // TX PCS PLD IF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_rx_pcs_pma_if, // RX PCS PMA IF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_com_pcs_pma_if, // COM PCS PMA IF blockselect (1 for each lane)
input wire [avmm_interfaces-1 :0] pcs_blockselect_tx_pcs_pma_if, // TX PCS PMA IF blockselect (1 for each lane)
// PLL AVMM signals
input wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_lc_pll, // LC PLL readdata (8 for each PLL)
input wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_lc_refclk_select, // LC Refclk Select Mux readdata (8 for each PLL)
input wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_cgb_master, // Master CGB readdata (8 for each PLL)
input wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_cmu_fpll, // CMU-FPLL readdata (8 for each PLL)
input wire [avmm_interfaces*8-1 :0] pll_avmmreaddata_cmu_fpll_refclk_select, // CMU-FPLL refclk mux readdata (8 for each PLL)
// CDR Tx PLL will connect to pma_avmmreaddata_cdr_pll and pma_avmmreaddata_cdr_refclk_select
input wire [avmm_interfaces-1 :0] pll_blockselect_lc_pll, // LC PLL blockselect (1 for each PLL)
input wire [avmm_interfaces-1 :0] pll_blockselect_lc_refclk_select, // LC Refclk Select Mux blockselect (1 for each PLL)
input wire [avmm_interfaces-1 :0] pll_blockselect_cgb_master, // Master CGB blockselect (1 for each PLL)
input wire [avmm_interfaces-1 :0] pll_blockselect_cmu_fpll, // CMU-FPLL blockselect (1 for each PLL)
input wire [avmm_interfaces-1 :0] pll_blockselect_cmu_fpll_refclk_select // CMU-FPLL refclk mux blockselect (1 for each PLL)
// CDR Tx PLL will connect to pma_blockselect_cdr_pll and pma_blockselect_cdr_refclk_select
//PORT_LIST_END
);
wire [avmm_interfaces-1 :0] avmm_reset_sync;
reg [avmm_interfaces-1 :0] avmm_read_r ={avmm_interfaces{1'b0}};
wire [avmm_interfaces-1 :0] avmm_waitrequest_read;
wire [avmm_interfaces-1 :0] avmm_waitrequest_write;
reg [avmm_interfaces-1 :0] avmm_waitrequest_write_int;
reg [avmm_interfaces*3-1:0] avmm_read_cycles_cnt;
reg [avmm_interfaces-1 :0] avmm_busy_r1 = {avmm_interfaces{1'b0}};
reg [avmm_interfaces-1 :0] avmm_busy_r2 = {avmm_interfaces{1'b0}};
wire [avmm_interfaces-1 :0] avmm_request;
localparam calibration_type = "one_time"; //Not used for now. Virtual attribute with no associated BCM settings. Intended to be set by the IP based on the chosen calibration option and used only by the AVMM sim model to decide whether to release the AVMM interface to the user after start-up or hold on to it until the user request according to the hardware implementation. Valid values: one_time, continuous. Export as parameter if needed.
localparam AVMM_READ_LATENCY = 3'b011; //Read latency in the hardware
localparam AVMM_READ_CYCLES_CNT_RST_VAL = 3'b111; //Reset value of avmm_read_cycles_cnt. Non-zero and >AVMM_READ_LATENCY for avmm_waitrequest to assert during reset
localparam ARBITER_BASE_ADDR = 9'h000; //AVMM<->uC arbiter base address
generate begin
genvar ig;
genvar jg;
for(ig=0;ig<avmm_interfaces;ig=ig+1) begin : avmm_atom_insts
// Size of blockselect bus as defined in the AVMM atom = Number of HSSI atoms + some buffer = 70
wire [70-1:0] chnl_pll_avmm_blockselect;
wire [7:0] chnl_pll_avmm_readdata [0:(70-1)];
wire [70*8-1:0] chnl_pll_avmm_readdatabus;
// Assign the incoming avmmreaddata and blockselect signals from all the atoms to
// the readdata bus and blockselect bus of the AVMM atom respectively
for(jg = 0; jg < 70; jg = jg + 1) begin:avmm_assigns
assign chnl_pll_avmm_readdatabus[jg*8+:8] = chnl_pll_avmm_readdata[jg];
assign {chnl_pll_avmm_readdata[jg],chnl_pll_avmm_blockselect[jg]} =
// TX PMA connections
(jg == 0) ? {pma_avmmreaddata_tx_ser [ig*8+:8],pma_blockselect_tx_ser [ig]} :
(jg == 1) ? {pma_avmmreaddata_tx_cgb [ig*8+:8],pma_blockselect_tx_cgb [ig]} :
(jg == 2) ? {pma_avmmreaddata_tx_buf [ig*8+:8],pma_blockselect_tx_buf [ig]} :
// RX PMA (includes CDR) connections
(jg == 3) ? {pma_avmmreaddata_rx_deser [ig*8+:8],pma_blockselect_rx_deser [ig]} :
(jg == 4) ? {pma_avmmreaddata_rx_buf [ig*8+:8],pma_blockselect_rx_buf [ig]} :
(jg == 5) ? {pma_avmmreaddata_rx_sd [ig*8+:8],pma_blockselect_rx_sd [ig]} :
(jg == 6) ? {pma_avmmreaddata_rx_odi [ig*8+:8],pma_blockselect_rx_odi [ig]} :
(jg == 7) ? {pma_avmmreaddata_rx_dfe [ig*8+:8],pma_blockselect_rx_dfe [ig]} :
(jg == 8) ? {pma_avmmreaddata_cdr_pll [ig*8+:8],pma_blockselect_cdr_pll [ig]} :
(jg == 9) ? {pma_avmmreaddata_cdr_refclk_select [ig*8+:8],pma_blockselect_cdr_refclk_select [ig]} :
(jg == 10) ? {pma_avmmreaddata_pma_adapt [ig*8+:8],pma_blockselect_pma_adapt [ig]} :
// PCS connections
(jg == 20) ? {pcs_avmmreaddata_8g_rx_pcs [ig*8+:8],pcs_blockselect_8g_rx_pcs [ig]} :
(jg == 21) ? {pcs_avmmreaddata_pipe_gen1_2 [ig*8+:8],pcs_blockselect_pipe_gen1_2 [ig]} :
(jg == 22) ? {pcs_avmmreaddata_8g_tx_pcs [ig*8+:8],pcs_blockselect_8g_tx_pcs [ig]} :
(jg == 23) ? {pcs_avmmreaddata_10g_rx_pcs [ig*8+:8],pcs_blockselect_10g_rx_pcs [ig]} :
(jg == 24) ? {pcs_avmmreaddata_10g_tx_pcs [ig*8+:8],pcs_blockselect_10g_tx_pcs [ig]} :
(jg == 25) ? {pcs_avmmreaddata_gen3_rx_pcs [ig*8+:8],pcs_blockselect_gen3_rx_pcs [ig]} :
(jg == 26) ? {pcs_avmmreaddata_pipe_gen3 [ig*8+:8],pcs_blockselect_pipe_gen3 [ig]} :
(jg == 27) ? {pcs_avmmreaddata_gen3_tx_pcs [ig*8+:8],pcs_blockselect_gen3_tx_pcs [ig]} :
(jg == 28) ? {pcs_avmmreaddata_krfec_rx_pcs [ig*8+:8],pcs_blockselect_krfec_rx_pcs [ig]} :
(jg == 29) ? {pcs_avmmreaddata_krfec_tx_pcs [ig*8+:8],pcs_blockselect_krfec_tx_pcs [ig]} :
(jg == 30) ? {pcs_avmmreaddata_fifo_rx_pcs [ig*8+:8],pcs_blockselect_fifo_rx_pcs [ig]} :
(jg == 31) ? {pcs_avmmreaddata_fifo_tx_pcs [ig*8+:8],pcs_blockselect_fifo_tx_pcs [ig]} :
(jg == 32) ? {pcs_avmmreaddata_rx_pcs_pld_if [ig*8+:8],pcs_blockselect_rx_pcs_pld_if [ig]} :
(jg == 33) ? {pcs_avmmreaddata_com_pcs_pld_if [ig*8+:8],pcs_blockselect_com_pcs_pld_if [ig]} :
(jg == 34) ? {pcs_avmmreaddata_tx_pcs_pld_if [ig*8+:8],pcs_blockselect_tx_pcs_pld_if [ig]} :
(jg == 35) ? {pcs_avmmreaddata_rx_pcs_pma_if [ig*8+:8],pcs_blockselect_rx_pcs_pma_if [ig]} :
(jg == 36) ? {pcs_avmmreaddata_com_pcs_pma_if [ig*8+:8],pcs_blockselect_com_pcs_pma_if [ig]} :
(jg == 37) ? {pcs_avmmreaddata_tx_pcs_pma_if [ig*8+:8],pcs_blockselect_tx_pcs_pma_if [ig]} :
// PLL connections
(jg == 50) ? {pll_avmmreaddata_lc_pll [ig*8+:8],pll_blockselect_lc_pll [ig]} :
(jg == 51) ? {pll_avmmreaddata_lc_refclk_select [ig*8+:8],pll_blockselect_lc_refclk_select [ig]} :
(jg == 52) ? {pll_avmmreaddata_cgb_master [ig*8+:8],pll_blockselect_cgb_master [ig]} :
(jg == 53) ? {pll_avmmreaddata_cmu_fpll [ig*8+:8],pll_blockselect_cmu_fpll [ig]} :
(jg == 54) ? {pll_avmmreaddata_cmu_fpll_refclk_select [ig*8+:8],pll_blockselect_cmu_fpll_refclk_select [ig]} :
{8'd0,1'b0}; //unused indices
end //avmm_assigns
if (enable_avmm == 1) begin
// AVMM atom
twentynm_hssi_avmm_if
#(
.arbiter_ctrl (arbiter_ctrl ),
.calibration_en (calibration_en ),
.hip_cal_en (hip_cal_en ),
.cal_done (cal_done ),
.calibration_type (calibration_type )
) twentynm_hssi_avmm_if_inst
(
.avmmrstn (1'b1 ), // Tie-off
.avmmclk (avmm_clk [ig] ),
.avmmwrite (avmm_write [ig] ),
.avmmread (avmm_read [ig] ),
.avmmaddress (avmm_address [ig*9+:9] ),
.avmmwritedata (avmm_writedata [ig*8+:8] ),
.avmmreaddata (avmm_readdata [ig*8+:8] ),
.avmmbusy (avmm_busy [ig] ),
.avmmrequest (avmm_request [ig] ),
.hipcaldone (hip_cal_done [ig] ),
.pldcaldone (pld_cal_done [ig] ),
.clkchnl (chnl_pll_avmm_clk [ig] ),
.rstnchnl (chnl_pll_avmm_rstn [ig] ),
.writechnl (chnl_pll_avmm_write [ig] ),
.readchnl (chnl_pll_avmm_read [ig] ),
.regaddrchnl (chnl_pll_avmm_address [ig*9+:9] ),
.writedatachnl (chnl_pll_avmm_writedata [ig*8+:8] ),
.readdatachnl (chnl_pll_avmm_readdatabus ),
.blockselect (chnl_pll_avmm_blockselect ),
.scanmoden (1'b1 ),
.scanshiftn (1'b1 ),
.avmmreservedin (/*unused*/ ),
.avmmreservedout (/*unused*/ )
);
//***********************************************************************************
//
// Generate avmm_waitrequest
//
//***********************************************************************************
// AVMM slave in hardware:
// avmm_write -> variable latency
// arbiter register = multi-cycle latency with avmm_busy asserted
// other registers = fixed 0-cycle latency
// avmm_read -> fixed 3-cycle latency
// Synchronize the falling edge of incoming reconfig reset
// Waitrequest is asserted during reset
alt_xcvr_resync #(
.SYNC_CHAIN_LENGTH(2), // Number of flip-flops for retiming
.WIDTH (1), // Number of bits to resync
.INIT_VALUE (1'b1)
) avmm_reset_sync_inst (
.clk (avmm_clk[ig] ),
.reset (avmm_reset[ig] ),
.d (1'b0 ),
.q (avmm_reset_sync[ig])
);
//***********************************************************************************
//**************** Generate waitrequest for read operation *************************
// Register avmm_read
always @ (posedge avmm_clk[ig] or posedge avmm_reset_sync[ig]) begin
if (avmm_reset_sync[ig]) begin
avmm_read_r[ig] <= 1'b0;
end else begin
avmm_read_r[ig] <= avmm_read[ig];
end
end
// Pipeline registers for avmm_busy
// Do not reset these registers so they can track avmm_busy accurately
always @ (posedge avmm_clk[ig]) begin
avmm_busy_r1[ig] <= avmm_busy[ig];
avmm_busy_r2[ig] <= avmm_busy_r1[ig];
end
// Read counter
// - reset the counter to a value between 0 and AVMM_READ_LATENCY so that waitrequest is asserted during reset
// - after reset de-assertion, flip the counter back to 0 for waitrequest to be de-asserted
// - increment the count:
// - when avmm_read is asserted
// - when avmm_busy_r1 is not asserted => the read operation immediately after recalibration request is served after
// avmm_busy_r1 is deasserted
// - until AVMM_READ_LATENCY count
always @ (posedge avmm_clk[ig] or posedge avmm_reset_sync[ig]) begin
if (avmm_reset_sync[ig])
avmm_read_cycles_cnt[ig*3+:3] <= AVMM_READ_CYCLES_CNT_RST_VAL;
else begin
if (~avmm_busy_r1[ig] & avmm_read[ig] & (avmm_read_cycles_cnt[ig*3+:3] == 3'b000))
avmm_read_cycles_cnt[ig*3+:3] <= avmm_read_cycles_cnt[ig*3+:3] + 1'b1;
else if (~avmm_busy_r1[ig] & (avmm_read_cycles_cnt[ig*3+:3] > 3'b000 && avmm_read_cycles_cnt[ig*3+:3] <= AVMM_READ_LATENCY))
avmm_read_cycles_cnt[ig*3+:3] <= avmm_read_cycles_cnt[ig*3+:3] + 1'b1;
else
avmm_read_cycles_cnt[ig*3+:3] <= 3'b000;
end
end
// waitrequest for read
assign avmm_waitrequest_read[ig] = (avmm_read[ig] & !avmm_read_r[ig]) | //when avmm_read is asserted
(avmm_read_cycles_cnt[ig*3+:3] > 3'b000 && avmm_read_cycles_cnt[ig*3+:3] <= AVMM_READ_LATENCY) | //during current read and possible back-to-back reads wihtout avmm_read being deasserted
(avmm_read_cycles_cnt[ig*3+:3] == AVMM_READ_CYCLES_CNT_RST_VAL) ; //during reset
//***********************************************************************************
//**************** Generate waitrequest for write operation ************************
// Logic enabled only when the calibration feature is enabled
// Assertion - very next clock cycle after receiving the arbiter register write request -> 0x0[0] = 1'b1.
// - this write indicates that the user wants to give-up the AVMM interface so that the Microcontroller can perform calibration (recalibration or adaptive).
// Deassertion - two clock cycles after avmm_busy is deasserted
if(calibration_en == "enable") begin : g_cal_en_wreq
always @ (posedge avmm_clk[ig] or posedge avmm_reset_sync[ig]) begin
if (avmm_reset_sync[ig])
avmm_waitrequest_write_int[ig] <= 1'b0;
else begin
if ((avmm_write[ig] == 1'b1) && (avmm_address[ig*9+:9] == ARBITER_BASE_ADDR) && (avmm_writedata[ig*8] == 1'b1) && (!avmm_waitrequest_write[ig]))
avmm_waitrequest_write_int[ig] <= 1'b1;
else if (avmm_waitrequest_write_int[ig] & ~avmm_busy_r1[ig] & ~avmm_busy_r2[ig])
avmm_waitrequest_write_int[ig] <= 1'b1;
else
avmm_waitrequest_write_int[ig] <= avmm_busy_r1[ig];
end
end
assign avmm_waitrequest_write[ig] = avmm_waitrequest_write_int[ig];
end else begin : g_cal_dis_wreq
assign avmm_waitrequest_write[ig] = 1'b0;
end
//***********************************************************************************
// user waitrequest
// case: 250182
// Allow de-coupling the avmm_busy from the avmm waitrequest to support nios and CPU based
// reconfiguration sequences and masters. This will address issues with returning the
// avmm bus back to the user, which in turn, due to the long waitrequest, causes the system
// to timeout.
if ( avmm_busy_en == "enable" ) begin
assign avmm_waitrequest[ig] = avmm_waitrequest_read[ig];
end else begin
assign avmm_waitrequest[ig] = avmm_waitrequest_write[ig] | avmm_waitrequest_read[ig];
end
//***************************************************************************************************************
//
// Generate avmm_request
//
// When Tx term resistance calibration is enabled in continuous mode, the usemodel
// is that the Nios will hold the AVMM interface until requested by the user.
// The user will request the AVMM interface, perform reconfiguration, and return
// the interface back to the Nios to continue with the adaptive calibration.
// Offset 0x0:
// bit 0 = arbiter control (0=pld, 1=uc)
// bit 1 = cal_done status (0=not done, 1=done) --> updated by Nios. Should not be touched by the user.
//
// If reconfig interface is enabled in the PHY GUI:
// * if calibration is enabled and continuous mode is set
// Steps to access AVMM interface
// 1. User requests the AVMM interface -> offset=0x0, RMW bit 0 = 0
// --> Internally, this module generates avmm_request signal that maps to a status register bit in hardware
// --> Nios reads this bit if the continuous calibration is enabled and gives up the AVMM interface
// 2. When waitrequest is de-asserted, user performs reconfiguration
// 3. User requests recalibration and thereby give up the AVMM interface to Nios
// -> offset=0x0, RMW bit 0 = 1
// * if either calibration is disabled or continuous mode is not set
// tie-off avmm_request to 1'b1 => park the avmm_request bit to always be in the user "request" mode
//
// If reconfig interface is NOT enabled in the PHY GUI:
// tie-off avmm_request to 1'b0 => park the avmm_request bit to always be in the "not request" mode => allow Nios to do adaptive calibration
//***************************************************************************************************************
// Assertion - very next clock cycle after receiving the arbiter register write request -> 0x0[0] = 1'b0
// - this write indicates that the user wants to get the AVMM interface from the Microcontroller so that the user can perform reconfiguration.
// Deassertion - after avmm_busy goes low
// - this indicates that the user has received the AVMM interface
if(rcfg_enable == 1) begin: g_rcfg_en
if ((calibration_en == "enable") && (calibration_type == "continuous")) begin : g_cal_en_req
reg [avmm_interfaces-1 :0] avmm_request_int = 1'b0;
always @ (posedge avmm_clk[ig] or posedge avmm_reset_sync[ig]) begin
if (avmm_reset_sync[ig])
avmm_request_int[ig] <= 1'b0;
else begin
if ((avmm_write[ig] == 1'b1) && (avmm_address[ig*9+:9] == ARBITER_BASE_ADDR) && (avmm_writedata[ig*8] == 1'b0) && (!avmm_request_int[ig]))
avmm_request_int[ig] <= 1'b1;
else if (~avmm_busy_r2[ig])
avmm_request_int[ig] <= 1'b0;
end
end
assign avmm_request[ig] = avmm_request_int[ig];
end else begin: g_cal_dis_req
//Park the interface request favoring the user AVMM
assign avmm_request[ig] = 1'b1;
end
end else begin : g_rcfg_dis
//Park the interface request favoring the Nios if reconfiguration is not enabled by the user
assign avmm_request[ig] = 1'b0;
end
end else begin //if !(enable_avmm), tie-off AVMM atom outputs
assign chnl_pll_avmm_clk [ig] = 1'b0;
assign chnl_pll_avmm_rstn [ig] = 1'b1;
assign chnl_pll_avmm_writedata [ig*8+:8] = 8'd0;
assign chnl_pll_avmm_address [ig*9+:9] = 9'd0;
assign chnl_pll_avmm_write [ig] = 1'b0;
assign chnl_pll_avmm_read [ig] = 1'b0;
end
end
end
endgenerate
endmodule
component arria10gx_ftm4_pcie_hip is
port (
clr_st : out std_logic; -- reset
hpg_ctrler : in std_logic_vector(4 downto 0) := (others => 'X'); -- hpg_ctrler
tl_cfg_add : out std_logic_vector(3 downto 0); -- tl_cfg_add
tl_cfg_ctl : out std_logic_vector(31 downto 0); -- tl_cfg_ctl
tl_cfg_sts : out std_logic_vector(52 downto 0); -- tl_cfg_sts
cpl_err : in std_logic_vector(6 downto 0) := (others => 'X'); -- cpl_err
cpl_pending : in std_logic := 'X'; -- cpl_pending
coreclkout_hip : out std_logic; -- clk
currentspeed : out std_logic_vector(1 downto 0); -- currentspeed
test_in : in std_logic_vector(31 downto 0) := (others => 'X'); -- test_in
simu_mode_pipe : in std_logic := 'X'; -- simu_mode_pipe
sim_pipe_pclk_in : in std_logic := 'X'; -- sim_pipe_pclk_in
sim_pipe_rate : out std_logic_vector(1 downto 0); -- sim_pipe_rate
sim_ltssmstate : out std_logic_vector(4 downto 0); -- sim_ltssmstate
eidleinfersel0 : out std_logic_vector(2 downto 0); -- eidleinfersel0
eidleinfersel1 : out std_logic_vector(2 downto 0); -- eidleinfersel1
eidleinfersel2 : out std_logic_vector(2 downto 0); -- eidleinfersel2
eidleinfersel3 : out std_logic_vector(2 downto 0); -- eidleinfersel3
powerdown0 : out std_logic_vector(1 downto 0); -- powerdown0
powerdown1 : out std_logic_vector(1 downto 0); -- powerdown1
powerdown2 : out std_logic_vector(1 downto 0); -- powerdown2
powerdown3 : out std_logic_vector(1 downto 0); -- powerdown3
rxpolarity0 : out std_logic; -- rxpolarity0
rxpolarity1 : out std_logic; -- rxpolarity1
rxpolarity2 : out std_logic; -- rxpolarity2
rxpolarity3 : out std_logic; -- rxpolarity3
txcompl0 : out std_logic; -- txcompl0
txcompl1 : out std_logic; -- txcompl1
txcompl2 : out std_logic; -- txcompl2
txcompl3 : out std_logic; -- txcompl3
txdata0 : out std_logic_vector(31 downto 0); -- txdata0
txdata1 : out std_logic_vector(31 downto 0); -- txdata1
txdata2 : out std_logic_vector(31 downto 0); -- txdata2
txdata3 : out std_logic_vector(31 downto 0); -- txdata3
txdatak0 : out std_logic_vector(3 downto 0); -- txdatak0
txdatak1 : out std_logic_vector(3 downto 0); -- txdatak1
txdatak2 : out std_logic_vector(3 downto 0); -- txdatak2
txdatak3 : out std_logic_vector(3 downto 0); -- txdatak3
txdetectrx0 : out std_logic; -- txdetectrx0
txdetectrx1 : out std_logic; -- txdetectrx1
txdetectrx2 : out std_logic; -- txdetectrx2
txdetectrx3 : out std_logic; -- txdetectrx3
txelecidle0 : out std_logic; -- txelecidle0
txelecidle1 : out std_logic; -- txelecidle1
txelecidle2 : out std_logic; -- txelecidle2
txelecidle3 : out std_logic; -- txelecidle3
txdeemph0 : out std_logic; -- txdeemph0
txdeemph1 : out std_logic; -- txdeemph1
txdeemph2 : out std_logic; -- txdeemph2
txdeemph3 : out std_logic; -- txdeemph3
txmargin0 : out std_logic_vector(2 downto 0); -- txmargin0
txmargin1 : out std_logic_vector(2 downto 0); -- txmargin1
txmargin2 : out std_logic_vector(2 downto 0); -- txmargin2
txmargin3 : out std_logic_vector(2 downto 0); -- txmargin3
txswing0 : out std_logic; -- txswing0
txswing1 : out std_logic; -- txswing1
txswing2 : out std_logic; -- txswing2
txswing3 : out std_logic; -- txswing3
phystatus0 : in std_logic := 'X'; -- phystatus0
phystatus1 : in std_logic := 'X'; -- phystatus1
phystatus2 : in std_logic := 'X'; -- phystatus2
phystatus3 : in std_logic := 'X'; -- phystatus3
rxdata0 : in std_logic_vector(31 downto 0) := (others => 'X'); -- rxdata0
rxdata1 : in std_logic_vector(31 downto 0) := (others => 'X'); -- rxdata1
rxdata2 : in std_logic_vector(31 downto 0) := (others => 'X'); -- rxdata2
rxdata3 : in std_logic_vector(31 downto 0) := (others => 'X'); -- rxdata3
rxdatak0 : in std_logic_vector(3 downto 0) := (others => 'X'); -- rxdatak0
rxdatak1 : in std_logic_vector(3 downto 0) := (others => 'X'); -- rxdatak1
rxdatak2 : in std_logic_vector(3 downto 0) := (others => 'X'); -- rxdatak2
rxdatak3 : in std_logic_vector(3 downto 0) := (others => 'X'); -- rxdatak3
rxelecidle0 : in std_logic := 'X'; -- rxelecidle0
rxelecidle1 : in std_logic := 'X'; -- rxelecidle1
rxelecidle2 : in std_logic := 'X'; -- rxelecidle2
rxelecidle3 : in std_logic := 'X'; -- rxelecidle3
rxstatus0 : in std_logic_vector(2 downto 0) := (others => 'X'); -- rxstatus0
rxstatus1 : in std_logic_vector(2 downto 0) := (others => 'X'); -- rxstatus1
rxstatus2 : in std_logic_vector(2 downto 0) := (others => 'X'); -- rxstatus2
rxstatus3 : in std_logic_vector(2 downto 0) := (others => 'X'); -- rxstatus3
rxvalid0 : in std_logic := 'X'; -- rxvalid0
rxvalid1 : in std_logic := 'X'; -- rxvalid1
rxvalid2 : in std_logic := 'X'; -- rxvalid2
rxvalid3 : in std_logic := 'X'; -- rxvalid3
rxdataskip0 : in std_logic := 'X'; -- rxdataskip0
rxdataskip1 : in std_logic := 'X'; -- rxdataskip1
rxdataskip2 : in std_logic := 'X'; -- rxdataskip2
rxdataskip3 : in std_logic := 'X'; -- rxdataskip3
rxblkst0 : in std_logic := 'X'; -- rxblkst0
rxblkst1 : in std_logic := 'X'; -- rxblkst1
rxblkst2 : in std_logic := 'X'; -- rxblkst2
rxblkst3 : in std_logic := 'X'; -- rxblkst3
rxsynchd0 : in std_logic_vector(1 downto 0) := (others => 'X'); -- rxsynchd0
rxsynchd1 : in std_logic_vector(1 downto 0) := (others => 'X'); -- rxsynchd1
rxsynchd2 : in std_logic_vector(1 downto 0) := (others => 'X'); -- rxsynchd2
rxsynchd3 : in std_logic_vector(1 downto 0) := (others => 'X'); -- rxsynchd3
currentcoeff0 : out std_logic_vector(17 downto 0); -- currentcoeff0
currentcoeff1 : out std_logic_vector(17 downto 0); -- currentcoeff1
currentcoeff2 : out std_logic_vector(17 downto 0); -- currentcoeff2
currentcoeff3 : out std_logic_vector(17 downto 0); -- currentcoeff3
currentrxpreset0 : out std_logic_vector(2 downto 0); -- currentrxpreset0
currentrxpreset1 : out std_logic_vector(2 downto 0); -- currentrxpreset1
currentrxpreset2 : out std_logic_vector(2 downto 0); -- currentrxpreset2
currentrxpreset3 : out std_logic_vector(2 downto 0); -- currentrxpreset3
txsynchd0 : out std_logic_vector(1 downto 0); -- txsynchd0
txsynchd1 : out std_logic_vector(1 downto 0); -- txsynchd1
txsynchd2 : out std_logic_vector(1 downto 0); -- txsynchd2
txsynchd3 : out std_logic_vector(1 downto 0); -- txsynchd3
txblkst0 : out std_logic; -- txblkst0
txblkst1 : out std_logic; -- txblkst1
txblkst2 : out std_logic; -- txblkst2
txblkst3 : out std_logic; -- txblkst3
txdataskip0 : out std_logic; -- txdataskip0
txdataskip1 : out std_logic; -- txdataskip1
txdataskip2 : out std_logic; -- txdataskip2
txdataskip3 : out std_logic; -- txdataskip3
rate0 : out std_logic_vector(1 downto 0); -- rate0
rate1 : out std_logic_vector(1 downto 0); -- rate1
rate2 : out std_logic_vector(1 downto 0); -- rate2
rate3 : out std_logic_vector(1 downto 0); -- rate3
pld_core_ready : in std_logic := 'X'; -- pld_core_ready
pld_clk_inuse : out std_logic; -- pld_clk_inuse
serdes_pll_locked : out std_logic; -- serdes_pll_locked
reset_status : out std_logic; -- reset_status
testin_zero : out std_logic; -- testin_zero
rx_in0 : in std_logic := 'X'; -- rx_in0
rx_in1 : in std_logic := 'X'; -- rx_in1
rx_in2 : in std_logic := 'X'; -- rx_in2
rx_in3 : in std_logic := 'X'; -- rx_in3
tx_out0 : out std_logic; -- tx_out0
tx_out1 : out std_logic; -- tx_out1
tx_out2 : out std_logic; -- tx_out2
tx_out3 : out std_logic; -- tx_out3
derr_cor_ext_rcv : out std_logic; -- derr_cor_ext_rcv
derr_cor_ext_rpl : out std_logic; -- derr_cor_ext_rpl
derr_rpl : out std_logic; -- derr_rpl
dlup : out std_logic; -- dlup
dlup_exit : out std_logic; -- dlup_exit
ev128ns : out std_logic; -- ev128ns
ev1us : out std_logic; -- ev1us
hotrst_exit : out std_logic; -- hotrst_exit
int_status : out std_logic_vector(3 downto 0); -- int_status
l2_exit : out std_logic; -- l2_exit
lane_act : out std_logic_vector(3 downto 0); -- lane_act
ltssmstate : out std_logic_vector(4 downto 0); -- ltssmstate
rx_par_err : out std_logic; -- rx_par_err
tx_par_err : out std_logic_vector(1 downto 0); -- tx_par_err
cfg_par_err : out std_logic; -- cfg_par_err
ko_cpl_spc_header : out std_logic_vector(7 downto 0); -- ko_cpl_spc_header
ko_cpl_spc_data : out std_logic_vector(11 downto 0); -- ko_cpl_spc_data
app_int_sts : in std_logic := 'X'; -- app_int_sts
app_int_ack : out std_logic; -- app_int_ack
app_msi_num : in std_logic_vector(4 downto 0) := (others => 'X'); -- app_msi_num
app_msi_req : in std_logic := 'X'; -- app_msi_req
app_msi_tc : in std_logic_vector(2 downto 0) := (others => 'X'); -- app_msi_tc
app_msi_ack : out std_logic; -- app_msi_ack
npor : in std_logic := 'X'; -- npor
pin_perst : in std_logic := 'X'; -- pin_perst
pld_clk : in std_logic := 'X'; -- clk
pm_auxpwr : in std_logic := 'X'; -- pm_auxpwr
pm_data : in std_logic_vector(9 downto 0) := (others => 'X'); -- pm_data
pme_to_cr : in std_logic := 'X'; -- pme_to_cr
pm_event : in std_logic := 'X'; -- pm_event
pme_to_sr : out std_logic; -- pme_to_sr
refclk : in std_logic := 'X'; -- clk
rx_st_bar : out std_logic_vector(7 downto 0); -- rx_st_bar
rx_st_mask : in std_logic := 'X'; -- rx_st_mask
rx_st_sop : out std_logic_vector(0 downto 0); -- startofpacket
rx_st_eop : out std_logic_vector(0 downto 0); -- endofpacket
rx_st_err : out std_logic_vector(0 downto 0); -- error
rx_st_valid : out std_logic_vector(0 downto 0); -- valid
rx_st_ready : in std_logic := 'X'; -- ready
rx_st_data : out std_logic_vector(63 downto 0); -- data
tx_cred_data_fc : out std_logic_vector(11 downto 0); -- tx_cred_data_fc
tx_cred_fc_hip_cons : out std_logic_vector(5 downto 0); -- tx_cred_fc_hip_cons
tx_cred_fc_infinite : out std_logic_vector(5 downto 0); -- tx_cred_fc_infinite
tx_cred_hdr_fc : out std_logic_vector(7 downto 0); -- tx_cred_hdr_fc
tx_cred_fc_sel : in std_logic_vector(1 downto 0) := (others => 'X'); -- tx_cred_fc_sel
tx_st_sop : in std_logic_vector(0 downto 0) := (others => 'X'); -- startofpacket
tx_st_eop : in std_logic_vector(0 downto 0) := (others => 'X'); -- endofpacket
tx_st_err : in std_logic_vector(0 downto 0) := (others => 'X'); -- error
tx_st_valid : in std_logic_vector(0 downto 0) := (others => 'X'); -- valid
tx_st_ready : out std_logic; -- ready
tx_st_data : in std_logic_vector(63 downto 0) := (others => 'X') -- data
);
end component arria10gx_ftm4_pcie_hip;
config arria10gx_ftm4_pcie_hip_cfg;
design arria10gx_ftm4_pcie_hip;
instance arria10gx_ftm4_pcie_hip.pcie_a10_hip_0 use arria10gx_ftm4_pcie_hip_altera_pcie_a10_hip_181.arria10gx_ftm4_pcie_hip_altera_pcie_a10_hip_181_hyz2b2a;
endconfig
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment