รับนาฬิกาที่ป้อนพิน

author-image

โดย

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

โค้ดแบบเต็มสําหรับขั้นตอนอยู่ด้านล่างของหน้า ตามด้วยคําอธิบายโดยสมบูรณ์เกี่ยวกับวิธีการทํางานของขั้นตอน ในการใช้ขั้นตอนget_clocks_driving_pinsกําหนดเองในไฟล์ SDC ตรวจสอบให้แน่ใจว่าได้กําหนดขั้นตอนไว้แล้ว จากนั้นให้เรียกใช้งานเหมือนกับคําสั่ง SDC อื่นๆ มีสองวิธีง่ายๆ เพื่อให้แน่ใจว่ามีการกําหนดขั้นตอนไว้ก่อนใช้งาน:

  • บันทึกรหัสขั้นตอนในไฟล์ SDC แยกต่างหากและรวมไฟล์ SDC ในโครงการ
  • คัดลอกและวางรหัสขั้นตอนที่ด้านบนของไฟล์ SDC ใดๆ ก่อนที่จะใช้ขั้นตอนที่กําหนดเองget_clocks_driving_pins

แยกไฟล์ SDC

การบันทึกรหัสขั้นตอนในไฟล์ SDC แยกต่างหากจะแยกรหัสออกจากข้อจํากัดที่เหลือของคุณและทําให้ง่ายต่อการนําไปใช้ในโครงการอื่น ๆ หากคุณใช้ไฟล์ SDC แยกต่างหาก คุณต้องเพิ่มไฟล์ SDC พร้อมขั้นตอนไปยังรายการไฟล์ในโครงการและไฟล์ต้องปรากฏเหนือไฟล์ SDC ใดๆ ที่ใช้ขั้นตอน รายการไว้เหนือไฟล์ SDC อื่น ๆ ช่วยให้มั่นใจได้ว่าซอฟต์แวร์ Quartus® II จะกําหนดขั้นตอนก่อนที่จะใช้งานเมื่อใดก็ตามที่มีการอ่านไฟล์ SDC

คัดลอกและวาง

การคัดลอกและวางรหัสขั้นตอนในไฟล์ SDC เดียวกันกับที่ใช้ส่งผลให้ไฟล์ SDC ในโครงการมีไฟล์ SDC น้อยลง หากคุณกําลังสร้างไฟล์ SDC สําหรับโมดูลที่จะนํามาใช้ใหม่โดยนักออกแบบรายอื่น อาจเป็นเรื่องง่ายที่สุดที่จะรวมข้อจํากัดทั้งหมดและรหัสสนับสนุนไว้ในไฟล์ SDC เดียว คุณต้องรวมรหัสขั้นตอนไว้ในไฟล์ SDC ก่อนการใช้ขั้นตอนแรกเพื่อให้มีการกําหนดก่อนที่จะใช้ โดยทั่วไปคุณจะวางไฟล์ไว้ด้านบนสุดของไฟล์เพื่อตอบสนองความต้องการนี้

การทํางานของสคริปต์

การรับรายการนาฬิกาทั้งหมดในการออกแบบที่ป้อนพินใช้เวลาสามขั้นตอนหลัก:

  1. รับนาฬิกาทั้งหมดและสร้างการแมปจากโหนดเป้าหมายของพวกเขาไปยังนาฬิกาบนโหนดเป้าหมาย
  2. ดูรายชื่อโหนดที่มีนาฬิกาอยู่บนพาธพัดลมไปยังพินที่ระบุ
  3. จากรายการโหนดดังกล่าว ให้ค้นหาโหนดที่อยู่ใกล้กับพินที่ระบุมากที่สุด และส่งคืนนาฬิกาบนโหนดนั้น

ขั้นตอนที่ 1 รับนาฬิกาทั้งหมดและสร้างการแมป

รหัส Tcl ต่อไปนี้ได้รับนาฬิกาทั้งหมดในการออกแบบและสร้างการแมป (ด้วยอาร์เรย์ Tcl) จากโหนดไปยังนาฬิกาบนโหนด

... { array unset nodes_with_clocks }
array set nodes_with_clocks [list]

# ทําซ้ํานาฬิกาแต่ละนาฬิกาในforeach_in_collection clock_idการออกแบบ
[all_clocks] {

    ตั้งค่าclock_name [get_clock_info -name $clock_id]

    # นาฬิกาแต่ละนาฬิกาจะถูกนําไปใช้กับโหนด รับชุดข้อมูลโหนดเป้าหมาย
    foreach_in_collection target_id [get_clock_info -targets $clock_id] {

        # เชื่อมโยงชื่อนาฬิกาด้วยชุดโหนดเป้าหมาย
        target_name [get_node_info -name $target_id]
        lappend nodes_with_clocks($target_name) $clock_name
}

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

ขั้นตอนที่ 2 รับโหนดที่มีนาฬิกาในเส้นทาง Fanin

ขั้นตอนที่สองคือการค้นหาชุดย่อยของโหนดที่มีนาฬิกาที่อยู่บนพาธพัดลมไปยังพินที่ระบุ สําหรับแต่ละโหนดที่มีนาฬิกา (พบในขั้นตอนที่ 1) ให้หาพินที่ระบุผ่านโหนด หากมีพัดลม โหนดจะอยู่ในพาธพัดลมไปยังพิน หากไม่มีพัดลม โหนดจะไม่อยู่บนพาธพัดลมไปยังพิน

รหัส Tcl ต่อไปนี้จะวนรอบโหนดทั้งหมดด้วยนาฬิกาจากขั้นตอนที่ 1 และใช้คําสั่ง get_fanins เพื่อตรวจสอบว่าแต่ละโหนดอยู่บนพาธพัดลมของพินที่ระบุหรือไม่ หากโหนดอยู่บนพาธพัดลมของพินที่ระบุ โหนดนั้นจะถูกบันทึกไว้ในรายการ pin_drivers

ตั้งค่า pin_drivers [list]

# ทําซ้ําโหนดทั้งหมดในการแมปที่สร้างขึ้นในขั้นตอนที่ 1
foreach node_with_clocks [array name nodes_with_clocks] {

    # รับพัดลมไปยังพินที่ระบุผ่านโหนดปัจจุบัน
    ตั้งค่าfanin_col [get_fanins -clock -through $node_with_clock $pin_name]

    # หากมีโหนด Fanin อย่างน้อยหนึ่งโหนด โหนดปัจจุบันอยู่บน
    พาธ fanin ไปยังพินที่ระบุ  ดังนั้นโปรดบันทึกไว้
    หาก { 0 < [get_collection_size $fanin_col] } {
        lappend pin_drivers $node_with_clocks
} }

รหัสกระบวนการแบบเต็มที่แสดงด้านล่างใช้ข้อมูลเพิ่มเติมเกี่ยวกับประเภทโหนดเพื่อระบุชุดข้อมูลเฉพาะชนิดสําหรับค่า -through ในคําสั่ง get_fanins

ขั้นตอนที่ 3 ค้นหาโหนดที่อยู่ใกล้พินที่ระบุที่สุด

ตัวแปร pin_drivers มีรายชื่อโหนดทั้งหมดพร้อมนาฬิกาที่อยู่บนพาธพัดลมไปยังพินที่ระบุ ขั้นตอนนี้จะค้นหาโหนดที่อยู่ใกล้กับพินที่ระบุมากที่สุด ในขณะที่มีมากกว่าหนึ่งโหนดในรายการpin_drivers รหัสจะใช้สองโหนดแรกในรายการและตรวจสอบว่ามีโหนดหนึ่งอยู่บนพาธพัดลมไปยังอีกโหนดหนึ่งหรือไม่ หากอยู่บนพาธพัดลม โหนดแรกต้องอยู่ไกลจากพินที่มากกว่าโหนดที่สอง จึงจะสามารถลบโหนดออกจากรายการได้

ในขณะที่ { 1 < [llength $pin_drivers] } {

    # รับสองโหนดแรกในชุดรายการpin_drivers
    node_a [lindex $pin_driver 0]
    ตั้งค่าnode_b [lindex $pin_drivers 1] #

    ตรวจสอบว่าnode_bอยู่บนพาธพัดลมของnode_a
    ตั้งค่าfanin_col [get_fanins -clock -through $node_b $node_a]

    # หากมีโหนด fanin อย่างน้อยหนึ่งโหนด  node_bต้อง
    อยู่ห่างจากพินที่ระบุมากกว่าพิน node_a
    # หากไม่มีโหนด Fanin node_bต้องอยู่ใกล้กับ
    พิน # ที่ระบุมากกว่า node_a
    หาก { 0 < [get_collection_size] } {

        # node_a อยู่ใกล้กับพินมากขึ้น
        # ลบnode_bออกจากชุดรายการpin_drivers
        pin_drivers [lreplace $pin_driver 1 1] } อื่นๆ {

    #

        node_bอยู่ใกล้กับพินมากกว่า
        # Remove node_a จากชุดรายการpin_drivers
        pin_drivers [lreplace $pin_drivers 0]
    } }

จํานวนโหนดหนึ่งที่เหลือใน pin_drivers คือโหนดที่ขับเคลื่อน node_driving_pinชุดพินที่ระบุ
[lindex $pin_driver 0]

# ค้นหานาฬิกาบนโหนดในการแมปจากขั้นตอนที่ 1 และ
ส่งคืน$nodes_with_clocks($node_driving_pin

รหัสกระบวนการแบบเต็มที่แสดงด้านล่างใช้ข้อมูลเพิ่มเติมเกี่ยวกับประเภทโหนดเพื่อระบุชุดข้อมูลเฉพาะชนิดสําหรับค่า -through ในคําสั่ง get_fanins

รหัสกระบวนการแบบเต็ม

รหัสสมบูรณ์สําหรับขั้นตอนget_clocks_driving_pinกําหนดเองมีการระบุไว้ด้านล่าง ซึ่งรวมถึงคุณสมบัติการตรวจสอบข้อผิดพลาดและการสนับสนุนเพิ่มเติมที่ไม่ได้อธิบายโดยละเอียดข้างต้น

proc get_clocks_feeding_pin { pin_name } {

    # ก่อนขั้นตอนที่ 1 ให้ทําการตรวจสอบข้อผิดพลาดเพื่อให้แน่ใจว่าpin_name
    # ถูกส่งผ่านไปยังกระบวนการที่ตรงกันเพียงหนึ่งพิน
    เท่านั้น # ส่งคืนข้อผิดพลาดหากไม่ตรงกับพินเดียวและมีเพียงพิน
    เดียว ตั้งค่า pin_col [get_pins -compatibility_mode $pin_name] หาก {
    0 == [get_collection_size $pin_col] } {
        ข้อผิดพลาดในการส่งคืน -code "No pins match $pin_name"
    } } อื่นๆ { 1 < [get_collection_size $pin_col] } {
        ข้อผิดพลาดการส่งคืน -code "$pin_name matches [get_collection_size $pin_col]\
            พินแต่ต้องตรงกันเพียงหนึ่งตัว"
    } #
    
    เริ่มต้นตัวแปรที่ใช้ในขั้นตอน
    { array unset nodes_with_clocks } การจํา { array
    unset node_types }
    ชุดอาร์เรย์nodes_with_clocks [list]
    ชุดอาร์เรย์ node_types [list]
    ตั้งค่าpin_drivers [list]
    
    # ขั้นตอนที่ 1 รับนาฬิกาทั้งหมดในการออกแบบและสร้างการแมปจาก
    # โหนดเป้าหมายไปยังนาฬิกาบนโหนดเป้าหมาย #

    ซ้ําต่อนาฬิกาในแต่ละนาฬิกาใน
    foreach_in_collection clock_idการออกแบบ [all_clocks] {

        ตั้งค่าclock_name [get_clock_info -name $clock_id]
        ตั้งค่าclock_target_col [get_clock_info -targets $clock_id]
        
        # แต่ละนาฬิกาจะถูกนําไปใช้กับโหนด รับชุดข้อมูลโหนดเป้าหมาย
        foreach_in_collection target_id [get_clock_info -targets $clock_id] {

            # เชื่อมโยงชื่อนาฬิกาด้วยชุดโหนดเป้าหมาย
            target_name [get_node_info -name $target_id]
            lappend nodes_with_clocks(($target_name) $clock_name

            # บันทึกประเภทของโหนดเป้าหมายสําหรับการตั้งค่า
            target_type [get_node_info -type $target_id]
            ตั้งค่าnode_types($target_name) $target_type
        }
    }

    ขั้นตอนที่ 2 ดูรายชื่อโหนดที่มีนาฬิกาอยู่บน
    พาธ # fanin ไปยังพินที่ระบุ

    # ทําซ้ําโหนดทั้งหมดในการแมปที่สร้างขึ้นในขั้นตอนที่ 1
    foreach node_with_clocks [array name nodes_with_clocks] {

        # ใช้ประเภทของโหนดเป้าหมายเพื่อสร้างชุดข้อมูล # เฉพาะประเภท
        สําหรับค่า -through ในคําสั่ง
        get_fanins switch -exact -- $node_type($node_with_clocks) {
            "pin" {  ตั้งค่าthrough_col [get_pins $node_with_clocks] }
            "พอร์ต" { ตั้งค่าthrough_col [get_ports $node_with_clocks] } "เซลล์" { ตั้งค่าthrough_col [get_ports $node_with_clocks] }
            "เซลล์" { ตั้งค่าthrough_col [get_cells $node get_ports $node_with_clocks] }
            "reg" {  set through_col [get_registers $node_with_clocks] } ค่าเริ่มต้น { return
            -code error "$node_type($node_with_clocks) ไม่ได้รับการจัดการ\
                เป็นประเภท fanin โดยสคริปต์"
        } }

        # รับแฟนๆ ไปยังพินที่ระบุผ่านชุดโหนดปัจจุบัน
        fanin_col [get_fanins -clock -through $through_col $pin_name] # หากมีอย่างน้อยหนึ่งโหนด

        fanin โหนดปัจจุบันอยู่บน
        พาธ # fanin ไปยังพินที่ระบุ ดังนั้นบันทึกไว้
        หาก { 0 < [get_collection_size $fanin_col] } {
            lappend pin_drivers $node_with_clocks
    } } #

    ก่อนขั้นตอนที่ 3 ให้ทําการตรวจสอบข้อผิดพลาดเพื่อให้แน่ใจว่าอย่างน้อยหนึ่ง
    # โหนดที่มีนาฬิกาในการออกแบบอยู่บนพาธพัดลมไปยัง
    # พินที่ระบุ
    หาก { 0 == [llength $pin_drivers] } {
        ข้อผิดพลาด return-code "ไม่พบโหนดใดๆ ที่มีนาฬิกาที่ขับเคลื่อน $pin_name"
    } # ขั้นตอนที่
    
    3 จากรายการโหนดที่สร้างขึ้นในขั้นตอนที่ 2 ให้ค้นหาโหนด
    # ที่ใกล้เคียงที่สุดกับพินที่ระบุและส่งคืนนาฬิกาบนโหนด

    นั้น ในขณะที่ { 1 < [llength $pin_drivers] } {

        # รับสองโหนดแรกในชุดรายการpin_drivers
        node_aตั้งค่า [lindex $pin_drivers 0]
        node_b [lindex $pin_driver 1]
        
        # ใช้ประเภทของโหนดเป้าหมายเพื่อสร้างชุดข้อมูล # เฉพาะประเภท
        สําหรับค่า -through ในคําสั่ง
        get_fanins switch -exact -- $node_type($node_b) {
            "pin" {  ตั้งค่าthrough_col [get_pins $node_b] }
            "พอร์ต" { ตั้งค่าthrough_col [get_ports $node_b] }
            "เซลล์" { ตั้งค่าthrough_col [get_cells $node_b] }
            "reg" {  set through_col [get_registers $node_b] ค่าเริ่มต้น {
            ข้อผิดพลาดการส่งคืน -code "$node_types($node_b) ไม่ได้รับการจัดการ\
                เป็นประเภท fanin โดยสคริปต์" } }
        #

        ตรวจสอบว่าnode_bอยู่บนเส้นทางพัดลมของnode_aหรือไม่        
        ตั้งค่าfanin_col [get_fanins -clock -through $through_col $node_a]

        # หากมีโหนดพัดลมอย่างน้อยหนึ่งโหนด node_bต้อง
        อยู่ไกลจากพินที่ระบุมากกว่า node_a
        # หากไม่มีโหนด Fanin node_bต้องอยู่ใกล้กับ
        พิน # ที่ระบุมากกว่า node_a
        หาก { 0 < [get_collection_size $fanin_col] } {

            # node_aอยู่ใกล้กับพินมากขึ้น
            # ลบnode_bออกจากชุดรายการpin_drivers
            pin_drivers [lreplace $pin_drivers 1 1]

        } อื่น { #

            node_b อยู่ใกล้กับพิน # Remove
            node_aจากชุดรายการpin_drivers
            pin_drivers [lrange" มากกว่า $pin_drivers 1 end]
        } #
    
    หนึ่งโหนดที่เหลือใน pin_drivers คือโหนดที่ขับเคลื่อนชุดพินที่ระบุ
    node_driving_pin [lindex $pin_drivers 0]

    # ค้นหานาฬิกาบนโหนดในการแมปจากขั้นตอนที่ 1 และส่งคืน
    $nodes_with_clocks($node_driving_pin)
}

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