ทําให้การออกแบบซ้ําง่ายขึ้นด้วยข้อจํากัด SDC แบบไดนามิก

author-image

โดย

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

ตัวอย่างการออกแบบนี้ครอบคลุมเทคนิคการสร้างข้อจํากัด SDC แบบไดนามิกที่จัดการกับปัญหาสองประการต่อไปนี้:

  • การกําหนดชื่อของ I/O ระดับสูงสุดที่เชื่อมต่อโดยตรงกับโมดูลระดับต่ํา
  • การสร้างนาฬิกาที่สร้างขึ้นบนตรรกะในโมดูลระดับต่ํา

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

รูปภาพที่ 1 ตัวอย่างวงจรสําหรับตัวอย่างการออกแบบ

รูปภาพที่ 2 ของreusable_block

การระบุชื่อ I/O ระดับสูงสุด

ข้อจํากัดสําหรับreusable_blockต้องรองรับการเปลี่ยนแปลงชื่อ I/O ระดับสูงสุด ดังนั้น ต้องกําหนดชื่อ I/O ระดับสูงสุดในระหว่างการคอมไพล์หรือการวิเคราะห์เวลา คําสั่ง get_fanouts Tcl จะส่งคืนชุดข้อมูลของ ID ที่แสดงถึงพอร์ตหรือการลงทะเบียนที่เป็นส่วนหนึ่งในชื่อที่ระบุ คําสั่ง get_fanouts Tcl ใช้ Netlist กําหนดเวลาที่มีอยู่ในระหว่างการคอมไพล์หรือการวิเคราะห์เวลา จึงกําหนดการเชื่อมต่อแบบไดนามิกโดยไม่คํานึงชื่อของโหนดพัดลม รหัส Tcl ต่อไปนี้แสดงวิธีใช้get_fanoutsเพื่อรับผลลัพธ์ระดับสูงสุดซึ่งเป็นความคับคั่งโดยตรงของการลงทะเบียนระดับต่ํา

foreach_in_collection fanout_id [get_fanouts $low_level_register_name] { break }
set top_level_io_name [get_node_info -name $fanout_id]

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

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

# รับแฟนๆ ของชุดลงทะเบียนระดับต่ํา
fanout_collection [get_fanouts $low_level_register_name]

# ตรวจสอบให้แน่ใจว่ามีnum_fanoutsชุดพัดลมเพียงชุดเดียว
[get_collection_size $fanout_collection]
หาก { 1 != $num_fanouts } {
    ข้อผิดพลาดในการส่งคืนรหัส "$low_level_register_name fans ออกไปยัง$num_fanouts \
        โหนด แต่ต้องออกเป็นหนึ่งโหนด"
}

# รับชื่อของโหนด fanout
foreach_in_collection fanout_id $fanout_collection { break }
set fanout_name [get_node_info -name $fanout_id] #

ตรวจสอบว่าโหนด fanout เป็นพอร์ตเอาต์พุตหาก
{ get_port_info -is_output_port $fanout_id } is_output] } {
    # มีข้อผิดพลาด - ไม่ได้ทําให้พอร์ต
    ส่งคืน -code error "$low_level_register_name fans out to $fanout_name \
        ซึ่งไม่ใช่พอร์ต"
} อื่นๆ { ! $is_ เอาต์พุต } {
    # ไม่มีข้อผิดพลาด แต่พอร์ตไม่ใช่ข้อผิดพลาดในการส่งคืนพอร์ตเอาต์พุต
    -code "$fanout_name ไม่ใช่พอร์ตเอาต์พุต"
} อีกอย่าง { set
    top_level_io_name $fanout_name
} #

top_level_io_nameเป็นพอร์ตเอาต์พุตเพียงพอร์ตเดียวของ low_level_register_name และเป็น
# พอร์ตเอาต์พุต

การสร้างนาฬิกาที่สร้างขึ้น

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

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

create_generated_clock -name reusable_generated -source [get_pins \
    *|reusable_block_clock_out|altddio_out_component|auto_generated|ddio_outa[0]|muxsel] \
    $top_level_io_name

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

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

รหัส Tcl ต่อไปนี้แสดงวิธีสร้างข้อจํากัดนาฬิกาที่สร้างขึ้นบนเอาต์พุตระดับสูงสุดที่ขับเคลื่อนด้วยการลงทะเบียนระดับต่ําในการออกแบบที่แสดงในรูปภาพที่ 1 สัญญาณนาฬิกาที่สร้างขึ้นจะใช้เอาต์พุตระดับสูงสุดเป็นเป้าหมาย และพิน muxsel ของaltddio_outputรีจิสเตอร์เป็นแหล่งข้อมูล รหัสนี้ใช้ลูปเพื่อทําซ้ําการสร้างอินสแตนซ์ทั้งหมดของreusable_blockในการออกแบบ และลูปที่ซ้อนกันเพื่อจัดการกับสถานการณ์การล็อกหลายตัวด้วยขั้นตอนแบบกําหนดเองของget_clocks_driving_pin จะถือว่ามีการกําหนดขั้นตอนget_clocks_driving_pinไว้แล้ว

# get_pins ส่งกลับหนึ่งพิน muxsel สําหรับการสร้างอินสแตนซ์แต่ละreusable_block #
foreach_in_collectionซ้ําforeach_in_collection pin_idพิน muxsel แต่ละตัว
[get_pins -compatibility_mode \
    *|reusable_block_clock_out|altddio_out_component|auto_generated|ddio_outa[0]|muxsel] {

    # pin_name มีลําดับชั้นการออกแบบเต็มรูปแบบของพิน muxsel สําหรับ
    การสร้างอินสแตนซ์ชุดreusable_blockหนึ่งpin_name
    [get_node_info -name $pin_id]
    
    # ใช้รหัสที่แสดงด้านบนโดยไม่มีการตรวจสอบข้อผิดพลาด เพื่อรับ
    ชื่อของforeach_in_collection port_idเอาต์พุตระดับสูงสุด
    [get_fanouts $pin_name] { break }
    ตั้งค่าport_name [get_node_info -name $port_id]
    
    # อาจมีนาฬิกาหลายตัวที่ป้อนaltddio_outputลงทะเบียน
    # นาฬิกาที่สร้างขึ้นหนึ่งตัวสําหรับแต่ละนาฬิกาที่ป้อน
    # พิน muxsel แต่ละนาฬิกาที่ป้อนพิน muxsel เป็นนาฬิกา
    หลัก foreach master_clock [get_clocks_feeding_pin $pin_name] { post_message

        "การสร้างนาฬิกาที่สร้างขึ้นบน $port_name ที่ป้อนโดย $pin_name"
        # สร้างนาฬิกาที่สร้างขึ้นด้วยนาฬิกา
        หลักที่เหมาะสม # แหล่งที่มาคือพิน muxsel ของเซลล์ altddio_output ใน
        # การสร้างอินสแตนซ์ปัจจุบันของreusable_block
        # ชื่อคือการรวมกันของนาฬิกาหลักและ
        ชื่อลําดับชั้นแบบเต็ม # ของพิน
        muxsel # เป้าหมายคือพอร์ตระดับบนสุดที่เป็นส่วนสําคัญของพิน
        muxsel create_generated_clock -add -master_clock $master_clock \
            -source [get_pins $pin_name] -name ${master_clock}-${pin_name} \
            [get_ports $port_name]
}

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

  • reusable_blockจะสร้างอินสแตนซ์หรือย้ายไปยังจุดอื่นๆ ในลําดับชั้นของการออกแบบ
  • I/O ระดับสูงสุดจะถูกเปลี่ยนชื่อ
  • ตัวออกแบบใช้คําจํากัดความนาฬิกาหลายคําในการออกแบบ

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