ตัวอย่าง Quartus® II Tcl: การรายงานเวลาของพาธโดยพลการ

author-image

โดย

คําสั่ง list_path และ report_timing Tcl นั้นทรงพลังมาก แต่มีข้อจํากัดบางประการ ปลายทางพาธต้องเป็นนาฬิกา พิน หรือการลงทะเบียน นอกจากนี้ คําสั่งเหล่านี้ไม่ได้รายงานทุกพาธรวมกันระหว่างปลายทาง ตัวอย่างสคริปต์ขั้นสูงนี้รองรับการรายงานเวลาบนเส้นทางโดยพลการในการออกแบบของคุณ (รวมถึงจุดสิ้นสุดแบบรวม) และรายงานพาธรวมทั้งหมดระหว่างปลายทาง สคริปต์ใช้อัลกอริธึมการค้นหาซ้ําเพื่อค้นหาเส้นทาง อัลกอริทึมจะหยุดที่พินและรีจิสเตอร์เพื่อป้องกันเวลาทํางานที่มากเกินไป

คุณสามารถระบุชื่อโหนด สัญลักษณ์ตัวแทน หรือชื่อกลุ่มเวลาสําหรับแหล่งข้อมูลและปลายทาง การยกเว้นกลุ่มเวลาไม่รองรับโดยสคริปต์นี้ คําเตือนจะปรากฏขึ้นหากคุณระบุกลุ่มเวลาที่มีการยกเว้นสําหรับปลายทาง และละเว้นการยกเว้น

คุณสามารถส่งเอาต์พุตของสคริปต์ไปยังไฟล์ Comma Separated Value (.csv) ชื่อไฟล์เริ่มต้นคือp2p_timing.csv นอกจากนี้ คุณสามารถส่งเอาต์พุตสคริปต์ไปยังแผงในรายงานเวลาของโครงการของคุณ ชื่อแผงเริ่มต้นคือการกําหนดเวลาแบบจุดต่อจุด

quartus_tan -t p2p_timing.tcl -project <project name> -จากชื่อ <node|wildcard|timegroup> -to <node name| >ชื่อwildcard|timegroup> [-write_file] [-file <output file name>] [-write_panel] [-panel <report panel name>]

หากคุณต้องการส่งเอาต์พุตไปยังไฟล์ที่แตกต่างจากชื่อไฟล์เริ่มต้น คุณต้องระบุตัวเลือก -write_file และ -file <output file> หากคุณต้องการส่งเอาต์พุตไปยังแผงรายงานที่แตกต่างจากชื่อแผงรายงานเริ่มต้น คุณต้องระบุตัวเลือก -write_panel และ -panel <report panel>

คัดลอกคําสั่ง Tcl ต่อไปนี้ไปยังไฟล์และตั้งชื่อไฟล์p2p_timing.tcl

แพคเกจต้องมี cmdline 
load_package advanced_timing 
รายงานload_package 

Quartus ระดับโลก 
ผันแปร ::argv0 $::quartus(args) 

ตั้งค่าตัวเลือก { \ 
   { "from.arg" "" "ชื่อโหนดต้นทาง" } \ 
   { "to.arg" "" "ชื่อโหนดปลายทาง" } \ 
   { "project.arg" "" "ชื่อโครงการ" } \ 
   { "file.arg" "p2p_timing.csv" "Output csv file name" } \ 
   { "write_file" "" "เขียนผลลัพธ์ไปยังไฟล์" } \ 
   { "panel.arg" "การกําหนดเวลาแบบจุดต่อจุด" "ชื่อแผงรายงาน" } \ 
   { "write_panel" "" "เขียนผลลัพธ์ไปยังแผงรายงาน" } \ 
} 

array set opts [::cmdline::getoptions ::argv0 $options "ตัวเลือกไม่ถูกต้อง"] 
############################################################## 
# 
# ส่งกลับรายชื่อของชื่อโหนดและรหัสโหนดที่เกี่ยวข้อง 
# สําหรับชื่อการออกแบบที่ตรงกับรูปแบบที่มีลวดลายอยู่ 
# รูปแบบใดๆ ที่ไม่ตรงกับชื่อในการออกแบบมี 
จํานวนรายการว่างเปล่าที่ส่งคืน 
# ตัวอย่าง: ส่งผ่านใน "รีเซ็ต" และรับ { รีเซ็ต 3 } กลับคืน 
# 
############################################################## 
proc get_node_ids { pattern } { 
   ชุดอาร์เรย์name_to_node [list] 

ถ้า { [string เท่ากับ "" $pattern] } { 
      ส่งคืน [รายการ] 
   }

# จริงๆ แล้วรูปแบบคือชื่อของกลุ่มเวลาหรือไม่ 
   # หากเป็นเช่นนั้น สคริปต์จะได้รับสมาชิกของ 
   # กลุ่มเวลา 
   ตั้งค่าสมาชิก [get_all_global_assignments -name TIMEGROUP_MEMBER -section_id $pattern] 

# หากมีสมาชิกในคอลเลกชันนี้ 
   # รูปแบบคือ Timegroup 
   หาก { 0 < [get_collection_size $members]} { 
      # เตือนหากมีข้อยกเว้น เนื่องจากสคริปต์ 
      # ข้ามข้อยกเว้น 
      หาก {0 < [get_collection_size [get_all_global_assignments -name TIMEGROUP_EXCLUSION -section_id $pattern]] } 
         คําเตือน post_message -type "ข้ามการยกเว้นใน$patternกลุ่มเวลา" 
      } 

# ดูแต่ละรายการในกลุ่มเวลา 
      $membersการมอบหมายforeach_in_collection { 
         # แต่ละรายการในคอลเลกชันเป็นรายการดังนี้: 
         จํานวน {$pattern} {TIMEGROUP_MEMBER} {node/real pattern} 
         ชุดอาร์เรย์sub_collection_names [get_node_ids [lindex $assignment 2]] 

foreach node_name [array names sub_collection_names] { 
            ตั้งค่า name_to_node($node_name) $sub_collection_name($node_name) 
         } 
      } 
   } อื่นๆ { 
      # ไม่ใช่กลุ่มเวลา 
      # คํานวณใหม่ผ่านโหนดเวลาทั้งหมดในการออกแบบ 
      # ตรวจสอบว่าชื่อตรงกับรูปแบบที่ระบุหรือไม่ 
      foreach_in_collection node_id [get_timing_nodes -พิมพ์ทั้งหมด] { 
         ตั้งค่าnode_name [get_timing_node_info -ชื่อข้อมูล $node_id] 
         หาก { [string match [escape_brackets $pattern] $node_name] } { 
            ตั้งค่า name_to_node($node_name) $node_id 
         } 
      } 
   } 
   ส่งคืน [array get name_to_node]
} 

############################################################## 
# 
# กระบวนการนี้ค้นหาพาธผสมระหว่างแหล่งข้อมูล 
# โหนดและรายการโหนดปลายทาง โดยจะส่งคืนรายชื่อ 
# พาธระหว่างโหนด แต่ละพาธประกอบด้วยทริปเล็ต 
จํานวน ID โหนด และการเชื่อมต่อระหว่างกันและความล่าช้าของเซลล์จาก 
# โหนดก่อนหน้า 
# ขั้นตอนหยุดข้าม Netlist ที่การลงทะเบียน 
# หรือพิน จึงไม่พบพาธที่ลงทะเบียน 
#
############################################################## 
proc find_combinational_paths_between {queue dest_nodes} { 
   ตั้งค่า num_iterations 0 
   ตั้งค่าพาธ [list] 
   
ในขณะที่ {0 < [llength $queue]} { 
      # รายงานความคืบหน้าของลูปทุกพันครั้ง 
      # การnum_iterationsแบบบูรณาการ 
      ถ้า { 1000 == $num_iterations } { 
         ตั้งค่า num_iterations 0 
         post_message "กําลังเลือกพาธ [llength $queue] 
      } 
      
# ป็อปพาธแรกจากคิว 
      # เป็นครั้งแรกที่เรียกว่าขั้นตอน คิว 
      # เป็นเพียงตัวเลขเดียว โหนดต้นทาง 
      ตั้งค่าพาธ [lindex $queue 0] 
      ตั้งคิว [lrange $queue 1 end] 
      
# รับโหนดสุดท้ายในเส้นทาง แล้วในลูป foreach 
      # รับ fanout จากโหนดนั้น 
      ตั้งค่าlast_triplet_in_path [lindex $path End] 
      ตั้งค่าlast_node_in_path [lindex $last_triplet_in_path 0] 
 
# ดึงข้อมูลเฉพาะ ID โหนดในพาธปัจจุบัน 
      # ซึ่งจะถูกใช้ในภายหลังเพื่อให้แน่ใจว่าจะไม่มีการเคลื่อนที่ของลูป 
      ตั้งค่าnodes_in_path [collapse_triplets_to_node_list $path] 

# รับแฟนๆ ทั้งหมดของโหนดสุดท้ายในเส้นทางนี้และทําให้ 
      # เส้นทางใหม่กับพวกเขาเพื่อกดดันคิว 
      foreach n [get_timing_node_fanout $last_node_in_path] { 
         foreach { node_id ic_delay cell_delay } $n { 
            แบ่ง 
         }
 
ถ้า { -1 != [lsearch $dest_nodes $node_id] } { 
            # ถ้าโหนดนี้ในพาธอยู่ในรายการ 
            # โหนดปลายทาง มีพาธ 
            # เพิ่มลงในรายการพาธระหว่างโหนด 
            ตั้งค่าnew_path $pathยืม 
            new_path $n 
            พาธ lappend $new_path 
         } 

ถ้า { -1 == [lsearch $nodes_in_path $node_id] } 
            # หากโหนดนี้ในเส้นทางไม่อยู่ในเส้นทาง 
            # แล้ว นี่ไม่ใช่ลูป ดันไปที่ 
            # Queue ถ้าเป็นโหนดผสมหรือโหนดนาฬิกา 
            # เส้นทางจะไม่ถูกผลักดันถ้าโหนดนี้เป็น 
            # ลงทะเบียนหรือพิน 
            # ผลักดันเส้นทางใหม่บนคิวเช่นนี้ 
            # แม้ว่าโหนดนี้ในเส้นทางอาจตรงกัน 
            # โหนดปลายทาง ช่วยให้มั่นใจได้ว่าจะนานที่สุด 
            พบพาธต่างๆ 
            ตั้งค่าnode_type [get_timing_node_info -ชนิดข้อมูล $node_id] 
            สวิตช์ -- $node_type { 
               หวี - 
               clk { 
                  ตั้งค่าnext_path $path 
                  next_path $nยืม 
                  lappend queue $next_path 
               } 
               { เริ่มต้น 
               } 
            } 
         } 
      }
   }
   $pathsส่งคืน 
} 

############################################################## 
# 
# บวกตัวเลขหน่วงเวลาสองตัวและคืนค่าผลลัพธ์ 
# หมายเลขหน่วงเวลาอยู่ในฟอร์ม "หน่วยมูลค่า" ที่หน่วยต่างๆ 
# อาจเป็นนาโนวินาที (ns) หรือ picoseconds (ps) และอาจมีค่า 
# เป็น x{1,3} หากหน่วยเป็น picoseconds หรือ x+.y{1,3} หาก 
# หน่วยคือนาโนวินาที ขั้นตอนนี้จะทําให้ความล่าช้าเป็นปกติ 
# นาโนวินาทีและเพิ่มค่า 
# ตัวอย่าง: add_delays "1.234 ns" "56 ps" # 
############################################################## 
add_delays proc { a b } { 
   หาก { ![ regexp {^([\d\] +)\s+([np]s)$} $a match a_value a_unit] } { 
      ข้อผิดพลาด post_message -type "ความซับซ้อนไม่ได้ระบุส่วนของเวลา: $a" 
   } 

หาก { ![ regexp {^([\d\] +)\s+([np]s)$} การจับคู่$b b_value b_unit] } { 
      ข้อผิดพลาด post_message -type "ที่ยอมรับได้ไม่กําหนดส่วนของเวลา: $b" 
   } 
  
# แปลงทุกอย่างเป็นระดับนาโนวินาทีหากจําเป็น 
   หาก { [string equal -nocase ps $a_unit] } { 
      ตั้งค่า a_value_ps [format "%.3f" $a_value] 
      ตั้งค่าa_value [format "%.3f" [expr { $a_value_ps / 1000 }]] 
   } 

หาก { [string equal -nocase ps $b_unit] } { 
      ตั้งค่า b_value_ps [format "%.3f" $b_value] 
      ตั้งค่าb_value [format "%.3f" [expr { $b_value_ps / 1000 }]] 
   } 

# ตอนนี้หน่วยมีค่าเท่ากันและระดับนาโนวินาที 
   # เพียงเพิ่มตัวเลขเข้าด้วยกัน 
   ตั้งค่า sum_value [format "%.3f" [expr { $a_value + $b_value }]] 
  
ส่งคืน "$sum_value ns" 
} 

############################################################## 
# 
# รูปแบบและพิมพ์ชื่อโหนดในเส้นทางที่มี  
# ความล่าช้าระหว่างโหนด 
# 
############################################################## 
proc print_path_delays { พาธ {iteration ก่อน}} { 
   ตั้งค่าsource_triplet [lindex $path 0] 
   ตั้งค่าsource_node [lindex $source_triplet 0] 
   ตั้งค่าsource_node_name [get_timing_node_info -ชื่อข้อมูล $source_node] 
   ตั้งค่าsource_node_loc [get_timing_node_info -ตําแหน่งข้อมูล $source_node] 
   
# พิมพ์ความล่าช้าก่อน 
   ถ้า { [string เท่ากับ "แรก" $iteration] } { 
      accumulate_data [รายการ "IC(0.000 ns)" "CELL(0.000 ns)"] 
   } อื่นๆ { 
      ตั้งค่าic_delay [lindex $source_triplet 1] 
      ตั้งค่าcell_delay [lindex $source_triplet 2] 
      accumulate_data [list "IC($ic_delay)" "CELL($cell_delay)"] 
   } 
   accumulate_data [list $source_node_loc $source_node_name] 
   print_accumulated_data 

# เกิดขึ้นอีกครั้งบนเส้นทางที่เหลือ 
   ถ้า { 1 < [llength $path] } { 
      print_path_delays [lrange $path 1 End] อื่นๆ 
   } 
} 

############################################################## 
# 
# รวมความล่าช้าของ IC และเซลล์บนพาธที่ระบุ และ 
# ส่งกลับรายการที่มีความล่าช้าในการเชื่อมต่อระหว่างกันทั้งหมดและเซลล์ทั้งหมด 
# หน่วงเวลา 
# 
############################################################## 
proc end_to_end_delay { พาธ } { 
   ตั้งค่า ic_total "0.000 ns" 
   ตั้งค่า cell_total "0.000 ns" 
   
# การดําเนินการนี้จะผ่านโหนด 1 เพื่อสิ้นสุดในเส้นทางเนื่องจาก 
   # โหนดแรกในพาธคือแหล่งที่มาและแต่ละโหนดใน 
   # พาธมีความล่าช้าจากโหนดก่อนหน้า # Source ไม่มีโหนดก่อนหน้า จึงไม่มีความล่าช้า 
   foreach n [lrange $path 1 end] { 
      foreach { node_id ic_delay cell_delay } $n { 
         แบ่ง 
      } 
      ตั้งค่าic_total [add_delays $ic_total $ic_delay] 
      ตั้งค่าcell_total [add_delays $cell_total $cell_delay] 
   } 

การส่งคืน [list $ic_total $cell_total] 
} 

##############################################################
# 
# ตรวจสอบให้แน่ใจว่าต้นทางและปลายทางที่ระบุมีอยู่ใน 
# การออกแบบ ค้นหาเส้นทางผสมระหว่างพวกเขาและ 
# พิมพ์เส้นทาง 
# 
############################################################## 
proc find_paths_and_display { Source Dest } { 
   แหล่งข้อมูลชุดอาร์เรย์ [get_node_ids $source] 
   dests ชุดอาร์เรย์ [get_node_ids $dest] 

ตั้งค่า nodes_exist 1 

# ตรวจสอบว่ามีโหนดที่มีชื่ออยู่ 
   ถ้า { 0 == [llength [array get sources]] } { 
      ตั้งค่า nodes_exist 0 
      post_message -type error "ไม่พบโหนดที่ตรงกับ$sourceในการออกแบบของคุณ" 
   } 
   ถ้า { 0 == [llength [array get dests]] } { 
      ตั้งค่า nodes_exist 0 
      post_message -type error "ไม่พบโหนดที่ตรงกับ$destในการออกแบบของคุณ" 
   } 

# หากเป็นเช่นนั้น ให้หาเส้นทาง   หาก { $nodes_exist } { 
      # รับรายการ ID โหนดปลายทาง 
      ตั้งค่าdest_node_ids [list] 
      foreach D [array names dests] { 
         dest_node_ids $destsให้ยืม ($d) 
      } 

# ดูทั้งหมดจากโหนด 
      foreach s [แหล่งข้อมูลชื่ออาร์เรย์] { 
         ตั้งค่าพาธ [find_combinational_paths_between $sources($s) $dest_node_ids] 
         ถ้า { 0 == [llength $paths] } {  
            post_message "ไม่มีพาธแบบผสมจาก$sไปยัง$dest" 
         } อื่นๆ { 
            เส้นทางการก้าว$paths { 
               # พิมพ์เส้นทาง 
               print_path_delays $path 

# Sum ความล่าช้าของเซลล์และการเชื่อมต่อระหว่างกัน และ 
               # พิมพ์ออกทางใต้เส้นทาง 
               foreach {total_ic_delay total_cell_delay } [end_to_end_delay $path] { 
                  แบ่ง 
               } 
               accumulate_data [list $total_ic_delay $total_cell_delay] 
               accumulate_data [รายการ [add_delays $total_ic_delay $total_cell_delay]] 

# มีสองสายให้print_accumulated_data 
               # ตรงนี้ หนึ่งภาพเพื่อพิมพ์ยอดรวมของการเชื่อมต่อระหว่างกัน 
               # และเซลล์เกิดความล่าช้า และอีกเซลล์หนึ่งเพื่อสร้างเซลล์ว่าง 
               # บรรทัดในเอาต์พุต 
               print_accumulated_data print_accumulated_data 
            } 
         } 
      }
   } 
} 

############################################################## 
# 
# พาธประกอบด้วยข้อมูลเป็นสามเท่า - รหัสโหนด 
# ความล่าช้าการเชื่อมต่อระหว่างกัน และความล่าช้าของเซลล์ ขั้นตอนนี้จะแยกออก 
# ID โหนดจากแต่ละ Triplet ในการสั่งซื้อและส่งคืนรายการ 
# ID โหนด 
# 
############################################################## 
collapse_triplets_to_node_list proc { l } { 
   ตั้งค่าto_return [list] 
   foreach triplet $l { 
      to_returnยืม [lindex $triplet 0] 
   } 
   return $to_return 
} 

############################################################## 
# 
# รวมข้อมูลเข้ากับตัวแปรระดับโลกในการเตรียมการ 
# สําหรับงานที่กําลังพิมพ์ออกมา 
# 
############################################################## 
proc accumulate_data { ข้อมูล } { 
   คํากล่าวหาระดับโลก [concat $accum $data] 
}
 
############################################################## 
# 
# พิมพ์ข้อมูลที่สะสมออกมา 
# ไฟล์จะถูกพิมพ์ออกเป็นมาตรฐาน และอาจเลือกเป็นไฟล์ใน 
# รูปแบบ CSV หากไฟล์จัดการอยู่ และอาจเลือกเป็น 
แผงรายงาน # หากมีแผงรายงานอยู่ (ไม่ใช่ค่า -1) 
# 
############################################################## 
print_accumulated_data proc {} { 
   panel_id accum fh ระดับโลก 
   ใส่ [เข้าร่วม$accum ","] 

# เขียนลงในไฟล์? 
   หาก { [info มี fh] } } 
      ใส่$fh [เข้าร่วม$accum "," ] 
   } 

# เพิ่มลงในแผงรายงานหรือไม่ 
   ถ้า { -1 != $panel_id } { 
      # หากแถวแผงรายงานไม่มี 4 รายการ 
      # ในเครื่อง ให้กดเป็น 4 
      ในขณะที่ { 4 > [llength $accum] } { 
         lappend accum [list] 
      } 
      add_row_to_table -id $panel_id $accum 
   } 
   # ล้างข้อมูลในตัวแปรส่วนกลาง 
   ตั้ง accum [list] 
}

############################################################## 
############################################################## 
# 
# สิ้นสุดขั้นตอน การเริ่มต้นสคริปต์ 
# 
############################################################## 
##############################################################
# 
# ตัวแปร Global เพื่อเก็บข้อมูลเพื่อจัดแสดง และแผง 
# ID สําหรับแผงรายงานเพิ่มเติม 

ตั้ง accum [list] 
ตั้งค่าpanel_id -1 

ถ้า { [string equal "" $opts(project)] } } 
   # ตัวเลือกการใช้การพิมพ์หากมีการเรียกสคริปต์โดยไม่มี 
   จํานวนข้อโต้แยะ 
   puts [::cmdline::การใช้งาน$options] 
} elseif { [string equal "" $opts(project)] } { 
   post_message -type error "ระบุโครงการที่มีตัวเลือก -project" 
} อื่นๆ { ! [project_exists $opts(Project)] } { 
   ข้อผิดพลาด post_message -type "ไม่มี project $opts(project) อยู่ในไดเรกทอรีนี้" 
} elseif { [string equal "" $opts(จาก)] } { 
   post_message -type error "ระบุชื่อหรือรูปแบบสัญลักษณ์ตัวแทนด้วยตัวเลือก -from" 
} elseif { [string equal "" $opts(to)] } { 
   post_message -type error "ระบุชื่อหรือรูปแบบสัญลักษณ์ตัวแทนด้วยตัวเลือก -to" 
} อื่นๆ { 
   ตั้งค่าcur_revision [get_current_revision $opts(โครงการ)] 
   project_open $opts (โครงการ) -การปรับปรุงแก้ไข $cur_การปรับปรุงแก้ไข 

# พยายามสร้าง Netlist กําหนดเวลา คําสั่งนี้จะล้มเหลว 
   # หากยังไม่ได้รันquartus_fit 
   ถ้า { [จริงใจ { create_timing_netlist } msg ] } { 
      $msgข้อผิดพลาด post_message -type 
   } อื่นๆ { 

# เตรียมเขียนเอาต์พุตไปยังไฟล์หากจําเป็น 
      ถ้า { 1 == $opts(write_file) } { 
         ถ้า { [ดูข้อมูล {open $opts(ไฟล์) w} fh] } { 
            ข้อผิดพลาด post_message -type "การไม่เปิด$opts(write_file): $fh" ไม่ตั้งค่า fh 
         } อื่นๆ { 
            post_message "การเขียนเอาต์พุตไปยัง$opts (ไฟล์)" 
            # เพิ่มข้อมูลระดับเริ่มต้นให้กับไฟล์เอาต์พุต 
            ใส่$fh "รายงานพาธจาก $opts(จาก) ไปยัง $opts(to)" 
            ใส่$fh "สร้างขึ้นบน [รูปแบบนาฬิกา [วินาทีนาฬิกา]" 
            ใส่ $fh "" ทําให้$fh "IC ล่าช้า,ความล่าช้าของเซลล์,ตําแหน่งโหนด,ชื่อโหนด" 
         } 
      } 

# เตรียมเขียนเอาต์พุตไปยังแผงรายงานหากจําเป็น 
      ถ้า { 1 == $opts(write_panel) } { 
         # โหลดรายงาน ลบแผงหากมีอยู่แล้ว 
         # สร้างแผงใหม่และเพิ่มแถวหัวเรื่อง 
         load_report 
         ตั้งค่าpanel_id [get_report_panel_id "ตัววิเคราะห์เวลา|| $opts (แผง)"] 
         ถ้า { -1 != $panel_id } { 
            delete_report_panel -id $panel_id 
         } 
        ตั้งค่าpanel_id [create_report_panel -table "ตัววิเคราะห์เวลา|| $opts (แผง)"] 
        add_row_to_table -id $panel_id [list "IC delay" "ความล่าช้าของเซลล์" "ตําแหน่งโหนด" "ชื่อโหนด"] 
      } 
      find_paths_and_display $opts(จาก) $opts(ไปยัง) 

# ปิดไฟล์เอาต์พุตหากจําเป็น 
      หาก { [info มี fh] } { close $fh } 

# บันทึกแผงรายงานหากจําเป็น 
      ถ้า { -1 != $panel_id } { 
         save_report_database 
         unload_report 
      } 
   } 
   project_close 
}    

เนื้อหาในหน้านี้เป็นการผสมผสานระหว่างการแปลเนื้อหาต้นฉบับภาษาอังกฤษโดยมนุษย์และคอมพิวเตอร์ เนื้อหานี้จัดทำขึ้นเพื่อความสะดวกของคุณและเพื่อเป็นข้อมูลทั่วไปเท่านั้นและไม่ควรอ้างอิงว่าสมบูรณ์หรือถูกต้อง หากมีความขัดแย้งใด ๆ ระหว่างเวอร์ชันภาษาอังกฤษของหน้านี้กับคำแปล เวอร์ชันภาษาอังกฤษจะมีผลเหนือกว่าและควบคุม ดูเวอร์ชันภาษาอังกฤษของหน้านี้