วิธีการหลีกเลี่ยงการสลักในระหว่างการสังเคราะห์


9

ฉันต้องการออกแบบบล็อกของตรรกะเชิงผสมโดยใช้ VHDL แต่บางครั้งผลการสังเคราะห์ที่มีการสลักโดยไม่ได้ตั้งใจ

ฉันต้องปฏิบัติตามแนวทางการเขียนโค้ดใดเพื่อหลีกเลี่ยงการสังเคราะห์ซิงก์จากการสลักสลัก

ตัวอย่าง: ในส่วนเล็ก ๆ ของรหัสฉันควรใช้คำสั่ง if-else?


หากใครได้สิ่งที่ฉันลองถามได้โปรดแจ้งฉัน

ฉันไม่แน่ใจว่าคุณหมายถึงอะไรจากตัวอย่างของคุณ โปรดตรวจสอบเพื่อให้แน่ใจว่าการประกาศใหม่นั้นตรงกับความตั้งใจดั้งเดิมของคุณ
W5VO

@fatai ฉันได้แสดงความคิดเห็นแล้วมีวิธีเฉพาะในการลบบัญชีของคุณที่มีอยู่ใน meta.stackexchange.com ฉันเชื่อมโยงคำถามสุดท้ายที่ฉันตั้งค่าสถานะไว้ ผู้ดูแลในเว็บไซต์ไม่มีอำนาจนี้เคย สิ่งนี้ต้องติดต่อกับทีมงาน dev
Kortuk

คำตอบ:


13

เพื่อหลีกเลี่ยงการสลักคุณต้องตรวจสอบให้แน่ใจว่าเอาต์พุตทั้งหมดของคุณได้รับการกำหนดที่สาขาที่เป็นไปได้ทั้งหมดของรหัส

ตัวอย่างเช่น,

if a = '1' then
   b(0) <= '1';
else
   b(1 downto 0) <= "00";
end if;

จะสร้าง latch เพราะในเงื่อนไขแรกไม่ได้ระบุค่าของ b (1) ดังนั้นคอมไพเลอร์ตัดสินใจว่าคุณต้องการเก็บค่าก่อนหน้าของ b (1) ไว้ที่นั่น วิธีหนึ่งในการเขียนสิ่งนี้ซึ่งจะไม่สร้างสลักคือ:

if a = '1' then
   b <= prev_b;
   b(0) <= '1';
else
   b(1 downto 0) <= "00";
end if;

...

if rising_edge (clk)
    prev_b <= b;
end if;

ที่นี่คุณระบุอย่างชัดเจนว่า b ควรเก็บไว้เป็นค่าเก่าแล้วเขียนทับ b (0) ด้วยค่าใหม่

อีกวิธีหนึ่งคือการให้ค่าเริ่มต้น ba เช่นเดียวกับในคำตอบของ @ TomiJ

หากคุณโพสต์รหัสที่คุณได้รับกลอนเราสามารถช่วยคุณหาเหตุผลที่เฉพาะเจาะจง


ฉันไม่คิดว่าวิธีการของคุณb <= bจะหลีกเลี่ยงการสลักเพราะมันยังต้องรักษาสถานะของสัญญาณ
Tomi Junnila

คุณอาจจะถูก; ฉันคุ้นเคยกับตรรกะนาฬิกา ฉันจะแก้ไข
fbo

6

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

มิฉะนั้นคุณจะอนุมานกลอนเพราะในครั้งต่อไปที่กระบวนการถูกกำหนดเวลาไว้มันจะต้องรักษาค่าของสัญญาณที่ไม่ได้รับค่าใหม่ในครั้งสุดท้าย

ฉันชอบที่จะรักษาตรรกะการผสมแบบหมดจดไว้เป็นการมอบหมายอย่างต่อเนื่องและใช้กระบวนการสำหรับตรรกะแบบโอเวอร์คล็อกจากนั้นฉันจะไม่ได้รับกลอน


5

กฎสี่ข้อเพื่อหลีกเลี่ยงการสลัก:

  • อย่าอ่านสัญญาณที่คุณเขียน
  • มีรายการความไวที่ถูกต้อง (สัญญาณทั้งหมดที่คุณอ่านควรอยู่ในรายการความไว)
  • ตรวจสอบให้แน่ใจว่าสัญญาณทั้งหมดที่การเขียนของคุณได้รับมอบหมายในทุกเส้นทาง (ตัวอย่างเช่น: ในแต่ละสาขาของคำสั่ง if-else-statement)
  • สำหรับกระบวนการที่ใช้ตัวแปรตรวจสอบให้แน่ใจว่าตัวแปรทุกตัวมีค่าเริ่มต้นเป็นค่าเริ่มต้นก่อนที่จะอ่าน (ในตัวแปรหรือสัญญาณอื่น)

นอกจากนี้หากคุณมีกระบวนการผสมหลายกระบวนการตรวจสอบให้แน่ใจว่าคุณไม่ได้สร้างลูป

สไตล์การเขียนโค้ดหลายแบบสามารถช่วยคุณยึดกฎเหล่านี้ได้ตัวอย่างเช่นสไตล์ในคำตอบของ @ TomiJ @Martin Thompson ชี้ให้เห็นว่าอาจเป็นการดีกว่าที่จะหลีกเลี่ยงการใช้ตรรกะร่วมกัน ใส่ทุกอย่างในกระบวนการโอเวอร์คล็อกแทน


+1 กฎที่ดี คุณจะเห็นด้วยหรือไม่ว่ากฎ # 2 ของคุณ (เกี่ยวกับรายการความไว) มีความสำคัญจริง ๆ เพื่อให้แน่ใจว่าผลลัพธ์ที่สอดคล้องกันระหว่างการสังเคราะห์และการจำลอง แต่ไม่ได้สร้างความแตกต่างเกี่ยวกับการอนุมานของสลัก?
Rick

@rick AFAIK ไม่มีการรับประกันว่าเครื่องมือสังเคราะห์จะทำอย่างไรกับรายการความไวที่ไม่สมบูรณ์ มาตรฐาน IEEE สำหรับการสังเคราะห์ VHDL (1076.6-1999) ระบุว่า: "รายการความไวของกระบวนการต้องมีสัญญาณทั้งหมดที่อ่านได้ในคำชี้แจงกระบวนการกระบวนการไม่สนับสนุนกระบวนการที่มีรายการความไวที่ไม่สมบูรณ์" ที่กล่าวว่าฉันรู้ว่าเครื่องมือสังเคราะห์บางอย่าง (อาจจะทั้งหมด?) ยอมรับรายการความไวที่ไม่สมบูรณ์ แต่เพียงแค่ละเว้นรายการความไวทั้งหมดเข้าด้วยกัน หากคุณต้องการใช้พฤติกรรมนั้นแทนมาตรฐาน IEEE ที่เข้มงวดกว่าฉันเดาว่าคำสั่งของคุณจะถูกต้อง
Philippe

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

3

ดังที่ได้รับการชี้ให้เห็นโดย @fbo และ @Martin Thompson คุณจำเป็นต้องตรวจสอบให้แน่ใจว่าสัญญาณที่ถูกขับเคลื่อนโดยกระบวนการได้รับการกำหนดค่าบางอย่างในทุกสาขาของกระบวนการและค่านั้นจะต้องไม่ขึ้นอยู่กับสถานะก่อนหน้าของผลลัพธ์ใด ๆ ของกระบวนการ

วิธีที่ง่ายที่สุดเพื่อให้แน่ใจว่านี่คือการกำหนดค่าเริ่มต้นให้กับแต่ละเอาต์พุตที่จุดเริ่มต้นของกระบวนการตัวอย่างเช่น (ตัวอย่างของการเลือก fbo ร่วม):

COMBO: process(a)
begin
    b <= (others => '0'); -- Assign default value to b
    if a = '1' then
        b(0) <= '1';
    else
        b(1 downto 0) <= "00";
    end if;
end process COMBO;

1
นี่เป็นวิธีที่ดีที่ฉันมักใช้ บางครั้งคำเตือนแลตช์อาจบอกคุณว่าคุณลืมกำหนดบิตบางส่วนในขณะที่วิธีนี้อาจทำให้บั๊กหายากขึ้น ตัวอย่างเช่นหากคุณกำหนดบิตทั้งหมดของสัญญาณแบบกว้างแยกจากกันและผิดพลาดโดยไม่ตั้งใจ
fbo

2
เฉพาะในกระบวนการ combinatorial ในกระบวนการโอเวอร์คล็อกคุณอนุมาน flipflop ซึ่งอาจเป็นสิ่งที่คุณต้องการ
Martin Thompson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.