وحدة البناء: D flip-flop
كل شيء في التصميم المتزامن يعود إلى قطعة عتاد صغيرة واحدة: D flip-flop. لها دخل clock ودخل بيانات وخرج بيانات. عند كل حافة clock صاعدة، تلتقط قيمة D وتحتفظ بها حتى الحافة التالية. هذا كل شيء.
في Verilog:
always @(posedge clk) begin
q <= d;
end
ثلاثة أسطر، flip-flop واحد. <= هو non-blocking، وهو بالضبط سلوك flip-flops الحقيقية (مغطى في Blocking مقابل Non-blocking). حساسية posedge clk هي ما يجعلها تسلسلية.
كدّس كثير منها مع منطق توافقي بينها وستحصل على أي دارة متزامنة قد تريد بناءها.
Register بـ Reset
التصاميم الحقيقية تحتاج دائمًا reset - طريقة لوضع النظام في حالة معروفة عند بدء التشغيل أو عند الطلب:
هذا reset متزامن - حالة reset تُقيَّم عند حافة clock مثل أي دخل آخر. تُنتج أداة التركيب flip-flop بـ mux 2-إلى-1 على دخل بياناتها: عندما يكون reset مرتفعًا، يُغذّي mux صفرًا؛ غير ذلك يُغذّي d.
لمعظم التصاميم، reset متزامن هو الخيار الصحيح. توقيت أبسط، يلعب بلطف مع FPGAs، وإشارة reset يمكن أن تأتي من أي مكان - لا تحتاج مصدرها الخاص المُحاذى مع clock.
Register بـ Enable
غالبًا تريد register يُحدَّث فقط عندما يخبره شيء. استخدم if داخل الكتلة المتزامنة مع clock، واعتمد على سلوك "احتفظ بالقيمة السابقة" الضمني لـ else المفقود:
هذا هو "load-enabled register" المعتاد. يظهر في كل مكان - registers الإعداد، مراحل pipeline التي تتقدم فقط عندما يكون ما يليها جاهزًا، عدّادات تتوقف وتُستأنف. حذف else الأخير متعمَّد وآمن داخل كتلة متزامنة مع clock: flip-flop يتذكر بالفعل قيمته السابقة، فـ "لا تفعل شيئًا" يعني "احتفظ".
في كتلة توافقية، نفس الشيفرة ستستنتج latch. قواعد مختلفة، صياغة نفسها.
عدّاد
العدّاد هو register قيمته التالية هي قيمته الحالية زائد واحد:
العدّاد يزيد كل دورة clock عندما يكون enable مرتفعًا. بعد 16 دورة يلتفّ إلى 0 (لأننا أعلنا 4 بت و15 + 1 يفيض إلى 0). الالتفاف ذاك أصيل في حساب N-بت وهو بالضبط كيف يتصرف عدّاد عتادي حقيقي.
Shift Register
تكديس flip-flops يعطيك shift register. الخدعة هي إجراء كل الإزاحات في جملة non-blocking واحدة:
الجسم out <= {out[WIDTH-2:0], in} - اربط البتات السفلى لـ out الحالي مع in الجديد، وأسند الكل. بما أنه non-blocking، يقرأ RHS out القديم قبل أن يُحدَّث LHS. التأثير إزاحة N-بت نظيفة في دورة clock واحدة.
هذا نمط shift register في أصغر شكله. يُعمَّم إلى LFSRs، مرسلات تسلسلية، deserializers - أي تصميم تتحرك فيه البيانات عبر سلسلة من flip-flops في كل clock.
Pipelines
Pipeline هو سلسلة من registers مفصولة بمنطق توافقي. كل مرحلة تعالج بيانات من المرحلة السابقة وتُغذّي التالية:
ثلاث مراحل، ثلاث دورات تأخير، لكن نتيجة جديدة كل دورة بمجرد امتلاء pipeline. التأخير 3 ساعات لأن البيانات تمر عبر ثلاث flip-flops؛ الإنتاجية 1 عملية لكل clock لأن المراحل الثلاث تعمل في وقت واحد على مدخلات مختلفة.
هكذا تصل التصاميم عالية الأداء إلى أهداف إنتاجيتها: أبقِ المراحل قصيرة، اعمل pipeline أعمق، ودع التوازي يقوم بالعمل.
Reset غير متزامن (عندما تحتاجه)
أحيانًا لا تستطيع انتظار حافة clock لتأكيد reset - الشريحة تُغلَق، الساعة مُغلَقة، watchdog خارجي يسحب الخط. في تلك الحالات:
always @(posedge clk or negedge reset_n) begin
if (~reset_n) q <= 0;
else q <= d;
end
قائمة الحساسية الآن لها حافة clock وحافة reset. يستجيب flip-flop فورًا لأي منهما. reset_n بالعرف active-low (مؤكَّد عندما منخفض)، لهذا الاختبار ~reset_n.
Reset غير متزامن له مقايضات: أصعب في تحليل الزمن، يمكن أن يُسبّب metastability إن لم يُعالَج بعناية عند رفع التأكيد، غير محمول عبر كل بنى FPGA. استخدم reset متزامن افتراضيًا، غير متزامن فقط عندما يتطلب التصميم.
ماذا بعد
تستطيع الآن بناء أي datapath متزامن. المستند التالي - آلات الحالة المنتهية - يضع register متزامن مع clock مع جملة case لإنتاج اصطلاح FSM القياسي: حصان العمل لكل متحكم ومحرّك بروتوكول وكتلة اتخاذ قرار في التصميم الرقمي.
الأسئلة الشائعة
ما هو المنطق المتزامن مع clock في Verilog؟
منطق تُحكَم تحديثاته بإشارة clock. الاصطلاح القياسي هو always @(posedge clk) target <= next_value; - عند كل حافة صاعدة لـ clk، يلتقط target قيمة next_value. هذا السطر الواحد يصف flip-flop في العتاد. تكديس كثير منها مع منطق توافقي بينها يبني عدّادات وshift registers وpipelines - كل شيء متزامن.
ما الفرق بين reset متزامن وreset غير متزامن في Verilog؟
Reset متزامن يستخدم always @(posedge clk) if (reset) ... - يُؤخذ reset عينة عند حافة clock مثل أي دخل آخر. Reset غير متزامن يستخدم always @(posedge clk or negedge reset_n) if (~reset_n) ... - تُفعَّل الكتلة عند حافة clock أو تأكيد reset، فيأخذ reset مفعوله فورًا. المتزامن هو الخيار الافتراضي؛ غير المتزامن يُستخدم عندما يجب ضمان أخذ reset مفعوله حتى لو كانت الساعة ميتة.
كيف تبني pipeline في Verilog؟
كدّس عدة مراحل من always @(posedge clk) stageN_reg <= stageN_combinational; - منطق كل مرحلة التوافقي يُغذّي register المرحلة التالية، وكل register يلتقط في نفس حافة clock. النتيجة pipeline حيث تدخل بيانات جديدة كل دورة وتخرج بعد N دورة، بإنتاجية نتيجة واحدة لكل clock.
ما هو shift register في Verilog؟
سلسلة من flip-flops حيث خرج كل واحد يُغذّي دخل التالي. كل حافة clock تُزيح كل بت موضعًا واحدًا. نسخة Verilog المعتادة تستخدم non-blocking assignments: out <= {out[N-2:0], in}; - هذا السطر الواحد يُنشئ shift register بـ N بت يأخذ بتًا واحدة لكل دورة من in.