ฉันต้องการออกแบบบล็อกของตรรกะเชิงผสมโดยใช้ VHDL แต่บางครั้งผลการสังเคราะห์ที่มีการสลักโดยไม่ได้ตั้งใจ
ฉันต้องปฏิบัติตามแนวทางการเขียนโค้ดใดเพื่อหลีกเลี่ยงการสังเคราะห์ซิงก์จากการสลักสลัก
ตัวอย่าง: ในส่วนเล็ก ๆ ของรหัสฉันควรใช้คำสั่ง if-else?
ฉันต้องการออกแบบบล็อกของตรรกะเชิงผสมโดยใช้ VHDL แต่บางครั้งผลการสังเคราะห์ที่มีการสลักโดยไม่ได้ตั้งใจ
ฉันต้องปฏิบัติตามแนวทางการเขียนโค้ดใดเพื่อหลีกเลี่ยงการสังเคราะห์ซิงก์จากการสลักสลัก
ตัวอย่าง: ในส่วนเล็ก ๆ ของรหัสฉันควรใช้คำสั่ง if-else?
คำตอบ:
เพื่อหลีกเลี่ยงการสลักคุณต้องตรวจสอบให้แน่ใจว่าเอาต์พุตทั้งหมดของคุณได้รับการกำหนดที่สาขาที่เป็นไปได้ทั้งหมดของรหัส
ตัวอย่างเช่น,
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
จะหลีกเลี่ยงการสลักเพราะมันยังต้องรักษาสถานะของสัญญาณ
หากคุณกำลังใช้กระบวนการสำหรับตรรกะเชิงผสม (และฉันขอแนะนำให้ใช้ด้วยเหตุผลนี้) ให้ตรวจสอบให้แน่ใจว่าทุกเส้นทางผ่านกระบวนการกำหนดบางสิ่งให้กับสัญญาณทุกสัญญาณที่กระบวนการขับเคลื่อน ไม่มีเอาต์พุตใดสามารถขึ้นอยู่กับเอาต์พุตใด ๆ จาก "ครั้งล่าสุด" ที่กระบวนการทำงาน
มิฉะนั้นคุณจะอนุมานกลอนเพราะในครั้งต่อไปที่กระบวนการถูกกำหนดเวลาไว้มันจะต้องรักษาค่าของสัญญาณที่ไม่ได้รับค่าใหม่ในครั้งสุดท้าย
ฉันชอบที่จะรักษาตรรกะการผสมแบบหมดจดไว้เป็นการมอบหมายอย่างต่อเนื่องและใช้กระบวนการสำหรับตรรกะแบบโอเวอร์คล็อกจากนั้นฉันจะไม่ได้รับกลอน
กฎสี่ข้อเพื่อหลีกเลี่ยงการสลัก:
นอกจากนี้หากคุณมีกระบวนการผสมหลายกระบวนการตรวจสอบให้แน่ใจว่าคุณไม่ได้สร้างลูป
สไตล์การเขียนโค้ดหลายแบบสามารถช่วยคุณยึดกฎเหล่านี้ได้ตัวอย่างเช่นสไตล์ในคำตอบของ @ TomiJ @Martin Thompson ชี้ให้เห็นว่าอาจเป็นการดีกว่าที่จะหลีกเลี่ยงการใช้ตรรกะร่วมกัน ใส่ทุกอย่างในกระบวนการโอเวอร์คล็อกแทน
ดังที่ได้รับการชี้ให้เห็นโดย @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;