altmemddr_phy_report_timing.tcl

来自「nios里面用自定义指令集来实现三角函数」· TCL 代码 · 共 407 行 · 第 1/2 页

TCL
407
字号
      set verify_assumptions_result {0}
      set verify_assumptions_exception [catch {verify_assumptions -memory_type ddr -read_pins_list $read_pins_list -write_pins_list $write_pins_list -ck_ckn_pairs $ck_ckn_pairs -clk_to_write_d $clk_to_write_d -clk_to_write_clock $clk_to_write_clock -clk_to_ck_ckn $clk_to_ck_ckn -mimic_pin [lindex $ck_pins 0]  } verify_assumptions_result]
      if {$verify_assumptions_exception == 0} {
        incr num_errors [lindex $verify_assumptions_result 0]
        set failed_assumptions [concat $failed_assumptions [lrange $verify_assumptions_result 1 end]]
      }
    }
    if {$verify_assumptions_exception != 0} {
      lappend failed_assumptions "Error: Macro timing assumptions could not be verified"
      incr num_errors
    }
  }
  if {$num_errors != 0} {
    for {set i 0} {$i != [llength $failed_assumptions]} {incr i} {
      set raw_msg [lindex $failed_assumptions $i]
      if {[regexp {^\W*(Info|Extra Info|Warning|Critical Warning|Error): (.*)$} $raw_msg -- msg_type msg]} {
        regsub " " $msg_type _ msg_type
        if {$msg_type == "Error"} {
          set msg_type "critical_warning"
        }
        post_message -type $msg_type $msg
      } else {
        post_message -type info $raw_msg
      }
    }
    post_message -type critical_warning "Read Capture and Write timing analyses may not be valid due to violated timing model assumptions"
  }
  return [expr $num_errors == 0]
}
proc ddr_pin {n pin pin_array_name} {
	upvar 1 $pin_array_name pins
	lappend pins($n) $pin
}

if { ! [timing_netlist_exist] } {
  post_message -type error "Timing Netlist has not been created. Run the 'Update Timing Netlist' task first."
  return
} 
source "${corename}_ddr_pins.tcl"
set corename [file tail $corename]
set instance_names [get_core_full_instance_list $corename]
for {set inst_index 0} {$inst_index != [llength $instance_names]} {incr inst_index} {
set full_instance_name [lindex $instance_names $inst_index]
set instance_name [get_timequest_name $full_instance_name]
set instname "${instance_name}|${corename}"
set pins(ck_p) [list]
set pins(ck_n) [list]
set pins(addrcmd) [list]
set pins(addrcmd_2t) [list]
set pins(dqsgroup) [list]
set pins(dgroup) [list]
get_ddr_pins $instname pins
# Find all the DQ pins
set alldqpins [list]
set alldqdmpins [list]
set alldqspins [list]
  foreach dqsgroup $pins(dqsgroup) {
    set alldqpins [concat $alldqpins [lindex $dqsgroup 2]]
    set alldqdmpins [concat $alldqdmpins [lindex $dqsgroup 2] [lindex $dqsgroup 1]]
    lappend alldqspins [lindex $dqsgroup 0]
  }
set summary [list]
foreach opc $opcs {
  if {$opc != "" } {
    set_operating_conditions $opc 
    update_timing_netlist
  }
  set opcname [get_operating_conditions_info [get_operating_conditions] -display_name]
  set opcname [string trim $opcname]
  
  if {$altmemddr_phy_use_high_performance_timing} {
    set assumptions_valid [verify_high_performance_timing_assumptions $instname pins]
  }
  # endif !altmemddr_phy_use_high_performance_timing
if {!$altmemddr_phy_use_high_performance_timing} {
# Write
set res_0 [report_timing -detail full_path -to [get_ports $alldqdmpins] -npaths 100 -panel_name "$instname Write \u0028setup\u0029" -setup]
set res_1 [report_timing -detail full_path -to [get_ports $alldqdmpins] -npaths 100 -panel_name "$instname Write \u0028hold\u0029" -hold]
lappend summary [list $opcname 0 "Write ($opcname)" [lindex $res_0 1] [lindex $res_1 1]]

}
# endif !altmemddr_phy_use_high_performance_timing
# Address Command
set res_0 [report_timing -detail full_path -to $pins(addrcmd) -npaths 100 -panel_name "$instname Address Command \u0028setup\u0029" -setup]
set res_1 [report_timing -detail full_path -to $pins(addrcmd) -npaths 100 -panel_name "$instname Address Command \u0028hold\u0029" -hold]
lappend summary [list $opcname 0 "Address Command ($opcname)" [lindex $res_0 1] [lindex $res_1 1]]

# DQS vs CK
set res_0 [report_timing -detail full_path -to [get_ports $alldqspins] -npaths 100 -panel_name "$instname DQS vs CK \u0028setup\u0029" -setup]
set res_1 [report_timing -detail full_path -to [get_ports $alldqspins] -npaths 100 -panel_name "$instname DQS vs CK \u0028hold\u0029" -hold]
lappend summary [list $opcname 0 "DQS vs CK ($opcname)" [lindex $res_0 1] [lindex $res_1 1]]

load_package report
load_report
if {!$altmemddr_phy_use_high_performance_timing} {
# Read Capture
set res_0 [report_timing -detail full_path -from [get_ports $alldqpins] -to [all_registers] -npaths 100 -panel_name "$instname Read Capture \u0028setup\u0029" -setup]
set res_1 [report_timing -detail full_path -from [get_ports $alldqpins] -to [all_registers] -npaths 100 -panel_name "$instname Read Capture \u0028hold\u0029" -hold]
lappend summary [list $opcname 0 "Read Capture ($opcname)" [lindex $res_0 1] [lindex $res_1 1]]

}
# endif !altmemddr_phy_use_high_performance_timing
# Core
set res_0 [report_timing -detail full_path -npaths 100 -panel_name "$instname Core \u0028setup\u0029" -setup]
set res_1 [report_timing -detail full_path -npaths 100 -panel_name "$instname Core \u0028hold\u0029" -hold]
lappend summary [list $opcname 0 "Core ($opcname)" [lindex $res_0 1] [lindex $res_1 1]]

# Core Reset/Removal
set res_0 [report_timing -detail full_path -npaths 100 -panel_name "$instname Core Reset/Removal \u0028recovery\u0029" -recovery]
set res_1 [report_timing -detail full_path -npaths 100 -panel_name "$instname Core Reset/Removal \u0028removal\u0029" -removal]
lappend summary [list $opcname 0 "Core Reset/Removal ($opcname)" [lindex $res_0 1] [lindex $res_1 1]]

# Mimic
set res_1 [list xxx ""]
set res_0 [report_timing -detail full_path -from $pins(ck_p) -to * -npaths 100 -panel_name "$instname Mimic \u0028setup\u0029" -setup]
lappend summary [list $opcname 0 "Mimic ($opcname)" [lindex $res_0 1] [lindex $res_1 1]]

}
set opcname "All Conditions"
if {$altmemddr_phy_use_high_performance_timing} {
set period 9.090
set tDCD [round_3dp [expr $period * 0.05]]
set board_skew 0.020
set tDS 0.400
set tDH 0.400
set tDQSQ 0.400
set tQHS 0.500
set tAC 0.700
set all_read_dqs_list [get_all_dqs_pins $pins(dqsgroup)]
set all_write_dqs_list $all_read_dqs_list
set mem_if_memtype "DDR SDRAM"
set dqs_phase 60.000
# Write capture
set tccs [get_tccs $mem_if_memtype $all_write_dqs_list $period] 
set su   [expr {$period*0.25 - $tDCD*0.5 - $board_skew - [lindex $tccs 0]/1000.0 - $tDS}]
set hold [expr {$period*0.25 - $tDCD*0.5 - $board_skew - [lindex $tccs 1]/1000.0 - $tDH}]
lappend summary [list $opcname 0 "Write ($opcname)" $su $hold]

# Read capture
set tsw [get_tsw $mem_if_memtype $all_read_dqs_list $period]
set margin  [expr {$period*0.5 - $tDCD - 2*$board_skew - 2*$tAC - [lindex $tsw 0]/1000.0 - [lindex $tsw 1]/1000.0}]
set marginby2 [expr {$margin*0.5}]
lappend summary [list $opcname 0 "Read Capture ($opcname)" $marginby2 $marginby2]
post_message -type warning "Read and write timing characteristics of memory interface $instname are preliminary"

}
# endif altmemddr_phy_use_high_performance_timing
proc sort_proc {a b} {
  set idxs [list 1 2 0]
  foreach i $idxs {
    set ai [lindex $a $i]
    set bi [lindex $b $i]
    if {$ai > $bi} {
      return 1
    } elseif { $ai < $bi } {
      return -1
    }
  }
  return 0
}
set summary [lsort -command sort_proc $summary]
if {[llength $instance_names] <= 1} {
  set f [open "${corename}_summary.csv" w]
} else {
  set f [open "${corename}${inst_index}_summary.csv" w]
}
post_message -type info "                                       setup  hold"
set panel_name "[get_report_folder]||$instname"
set root_folder_name "TimeQuest Timing Analyzer"
if { ! [string match "${root_folder_name}*" $panel_name] } {
  set panel_name "${root_folder_name}||$panel_name"
}
if {[get_report_panel_id $root_folder_name] == -1} {
  set panel_id [create_report_panel -folder $root_folder_name]
}
set panel_id [get_report_panel_id $panel_name]
if {$panel_id != -1} {
  delete_report_panel -id $panel_id
}

set panel_id [create_report_panel -table $panel_name]
add_row_to_table -id $panel_id [list "Path" "Operating Condition" "Setup Slack" "Hold Slack"] 
foreach summary_line $summary {
  foreach {corner order path su hold} $summary_line { }
  if { $su < 0 || ($hold!="" && $hold < 0) } {
    set type warning
    set offset 32
  } else {
    set type info
    set offset 35
  }
  set su [format %.3f $su]
  if {$hold != ""} {
    set hold [format %.3f $hold]
  }
  post_message -type $type [format "%-${offset}s | %6s %6s" $path $su $hold]
  puts $f [format "\"%s\",%s,%s" $path $su $hold]
  add_row_to_table -id $panel_id [list $path $corner $su $hold] 
}
close $f
}
write_timing_report

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?