ตรรกะหรือรีเซ็ตและล้าง?

Sep 16 2020

ฉันกำลังพยายามหาแนวทางปฏิบัติที่ดีที่สุดในการใช้การรีเซ็ต (ใช้ async, ซิงค์ล้าง) และอินพุตที่ชัดเจน ฉันมีกระบวนการที่ต้องรันนาฬิกาที่ได้รับตรรกะ (NCO) ที่เรียกว่า code_clk ช้ากว่า แต่ซิงโครนัสกับ clk จริง กระบวนการนี้เกี่ยวข้องกับการลงทะเบียน Linear Feedback Shift ที่ต้องรีเซ็ตเป็น 1 ทั้งหมดเพื่อเริ่มลำดับการสร้างรหัสหลังจากที่การรีเซ็ตถูกยกขึ้น อย่างไรก็ตามตลอดการดำเนินการกระบวนการควรรีเซ็ตเป็น 1 ทั้งหมดเมื่อมีการเลือกชุดก๊อกใหม่ (T1 และ T2) สำหรับเอาต์พุตแน่นอนเพื่อรีเซ็ตลำดับการสร้างรหัสและตรวจสอบให้แน่ใจว่ารหัสใหม่ถูกต้องกับใหม่ ก๊อก สิ่งนี้ทำได้ด้วยอินพุต clr แบบซิงโครนัสแยกต่างหากซึ่งจะค้างไว้สูงสำหรับรอบนาฬิการะบบเดียวในขณะที่เลื่อนก๊อกไปรอบ ๆ

นี่คือรหัสของฉัน:

  process(code_clk, reset, clr)
  begin
    if(reset='0' or clr='1') then
      -- EARLY LFSR
      EG1(1 to 10) <= (others => '1');
      EG2(1 to 10) <= (others => '1');
      early_code   <= '0';
      delay_os     <= '0';
    elsif(falling_edge(code_clk)) then
      if(delay_os='0') then
        -- LFSR feedbacks for early code
        EG1(2 to 10) <= EG1(1 to 9);
        EG2(2 to 10) <= EG2(1 to 9);
        EG1(1) <= EG1(3) xor EG1(10);
        EG2(1) <= EG2(2) xor EG2(3) xor EG2(6) xor EG2(8) xor EG2(9) xor EG2(10);
        early_code <= EG1(10) xor EG2(T1) xor EG2(T2); -- C/A output of early LFSR
      else
        -- delay of code chips commanded - do not shift this time
        delay_os <= '0';
      end if;
      late_code   <= early_code; -- one half chip delay from prompt code
    elsif(rising_edge(code_clk)) then 
      prompt_code <= early code; -- one half chip delay from early code
    end if;
  end process;

เงื่อนไข if (reset = '0' หรือ clr = '1') จะกระโดดใส่ฉันว่าเป็นสไตล์ที่ไม่ดี ดูเหมือนว่าสถานการณ์หนึ่งที่การสังเคราะห์จะสร้างตรรกะที่ไม่จำเป็นหรือการหน่วงเวลาเนื่องจากเส้นทางการรีเซ็ตไม่ตรงไปตรงมา ฉันสามารถทำได้หรือควรลองอย่างอื่น ความชัดเจนจะต้องเกิดขึ้นทันทีดังนั้นฉันต้องทำให้กระบวนการหมดไปจากนาฬิการะบบหรืออย่างอื่น นี่ถือเป็นการปฏิบัติที่ดีหรือไม่?

คำตอบ

2 Vance Sep 16 2020 at 18:50

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

process(clk, reset)
begin
  if reset = '1' then  -- async reset
    -- your code here
  elsif Rising_edge(clk) then
    if sync_clr = '1' then  -- sync clear
      -- your code here
    end if;
  end if;
end process;

ฉันทราบว่าการรีเซ็ตของคุณทำงานอยู่ในระดับต่ำซึ่งมีแนวโน้มที่จะขมวดคิ้วภายใน FPGA (เกี่ยวข้องกับการอ่านโค้ดมากกว่าปัญหาทางสถาปัตยกรรมจริง)

แต่เดี๋ยวก่อน! ทำไมเรื่องนี้ถึงมีความสำคัญ?

ซึ่งรวมถึงสถาปัตยกรรมส่วนบุคคลของ FPGA ที่คุณใช้อยู่ ด้านล่างนี้คือส่วนย่อยของแผนภาพบล็อกสำหรับ Cyclone V Adaptive Logic Module

เมื่อดูที่รีจิสเตอร์คุณจะเห็นว่ามีเพียงตัวควบคุมเดียว - CLR ที่ด้านบนของแผนภาพคุณจะเห็นสัญญาณaclr [1: 0]เข้ามาใน ALM เมื่อคุณสรุปการรีเซ็ตแบบ async นี่คือสิ่งที่ตั้งค่าไว้ โปรดทราบว่า ALM นี้มีการลงทะเบียน 4 รายการ แต่มีสัญญาณรีเซ็ตเพียง 2 รายการเท่านั้นที่ใช้ร่วมกันโดยคู่ สิ่งนี้มีความหมายสำหรับจำนวน ALM ที่ใช้

คุณยังสามารถเห็นสัญญาณซิงโครนัสที่ชัดเจน ( sclr ) และสัญญาณโหลดซิงโครนัส ( syncload ) ที่เข้ามาใน ALM สิ่งเหล่านี้แชร์โดยทั้ง 4 รีจิสเตอร์ จะใช้วงจรเหล่านี้หากอนุมานในรหัส แผนภาพมีรายละเอียดเพียงพอที่จะเข้าใจวิธีการทำงานของสัญญาณ

sclrตั้งใจให้แอคทีฟสูง มีการกลับด้านและ AND ด้วยข้อมูลที่ฟีดอินพุต D ของรีจิสเตอร์ นั่นหมายความว่าเมื่อสูง 0 จะถูกป้อนไปยังอินพุต D และ Q จะอัปเดตเป็น 0 ในรอบนาฬิกาถัดไป

syncloadไดรฟ์มัลติเพล็กเซอร์ซึ่งเลือกเอาต์พุตจาก LUTs หรือ datae0 ซึ่งมาจากภายนอก ALM

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

Xilinx มีเอกสารไวท์เปเปอร์ที่อธิบายรายละเอียดเพิ่มเติม: https://www.xilinx.com/support/documentation/white_papers/wp275.pdf