إنشاء ساعة في FPGA على البدائيين

عند قراءة أوراق البيانات على FPGA ، يمكنك العثور على إشارات حول ترددات التشغيل الخاصة بهم ... ولكن



لا ، تبدأ القصة في عام 2015 ، عندما تعرفت على FPGAs. في أول أعمالي البسيطة ، قمت بتشكيل الساعة التي احتاجها من العداد وأطعمت كل المنطق منه (بطبيعة الحال ، شريطة أن أحتاج إلى الساعة بشكل أبطأ مما تم تغذيته إلى FPGA ، على سبيل المثال UART و SPI). بطبيعة الحال ، طاردوني من أجل ذلك ، لكن كان لدي عذر بسيط "لكنه يعمل!" ، وعمل كل شيء حقًا. ومنذ ذلك الحين تسللت الفكرة إلى رأسي: "من أين يمكنني الحصول على إشارة التوقيت؟"



لا يوجد العديد من الخيارات للمصادر لأخذ أجاد. خذ إما من ClockWizard معينة قائمة على PLL أو MMCM ، أو قم بتشكيلها من عداد ، أو على الفور من الساق ، إذا جاز التعبير ، انتهت بمفردها. ماذا لو أخذنا إشارة الساعة التي تم إنشاؤها بواسطة بدائية FPGA؟



كجزء من هذه المقالة ، قررت النظر في ثلاثة خيارات: معدد الإرسال (MUXF7) ، وجدول الحقيقة (LUT1) وقصر دائرة الساقين FPGA لأنفسهم.



في حالة معدد إرسال ، يتم تغذية الإخراج إلى إشارة التحكم ، ويتم سحب إشارات الإدخال إلى 0 و 1.



صورة


في حالة LUT ، نقوم بتقصير الإخراج إلى الإدخال وتعيين جدول الحقيقة العكسية. عند توريد "1" ، إخراج صفر ، وعند توريد "0" ، إخراج واحد.



صورة


في حالة GPIO ، كل شيء بسيط هناك ، يتم تعيين إشارة الإخراج معكوس إشارة الإدخال:

تعيين s2 = ~ s1 ؛


غرض التجربة: توليد تردد بثلاث طرق وقياسه.

سنقيس التردد على حساب العدادات. سيكون هناك 4 عدادات: ثلاثة لكل خيار وعداد أساسي واحد ، حيث سيتم حساب كل شيء. وسنراقب هذه العدادات من خلال ChipScope.



وإليك رمز الوحدة النمطية بالكامل:
module gen_clk(
    input clk_base,
    input s1, //gpio
    output s2 //gpio
    );

//  - 
assign s2 = ~s1;
wire clk_gpio = s1;
reg [31:0] cnt_gpio = 0;
 (* MARK_DEBUG="true" *) reg [31:0] cnt_gpio_buf = 0;
always@(posedge clk_gpio)
begin 
    if(cnt_gpio[2:0]==3'd0) cnt_gpio_buf<=cnt_gpio; 
    cnt_gpio <= cnt_gpio + 1'b1;
end

//  
wire clk_mux;
MUXF7 MUXF7_inst
(
    .O(clk_mux),
    .I0(1'b1),
    .I1(1'b0),
    .S(clk_mux)
);
reg [31:0] cnt_mux = 0;
 (* MARK_DEBUG="true" *) reg [31:0] cnt_mux_buf = 0;
always@(posedge clk_mux)
begin 
    if(cnt_mux[2:0]==3'd0) cnt_mux_buf<=cnt_mux; 
    cnt_mux <= cnt_mux + 1'b1;
end
//   
wire clk_lut;
LUT1#(
    .INIT(2'b01)
)
LUT1_inst(
    .O(clk_lut),
    .I0(clk_lut)
);
reg [31:0] cnt_lut = 0;
 (* MARK_DEBUG="true" *) reg [31:0] cnt_lut_buf = 0;
always@(posedge clk_lut)
begin 
    if(cnt_lut[2:0]==3'd0) cnt_lut_buf<=cnt_lut; 
    cnt_lut <= cnt_lut + 1'b1;
end
//         
 (* MARK_DEBUG="true" *) reg [31:0] cnt_base = 'd0;        
always@(posedge clk_base)
begin
    cnt_base <= cnt_base + 1'b1;
end    
   
endmodule




هنا رسم تخطيطي للمشروع. البدائيون محاطون بدائرة ، وتشير الأسهم إلى الإشارة التي سيتم إدخالها في ChipScope لتحليل التردد:



صورة




الجزء العملي لدي



ثلاث لوحات تحت تصرفي:



  1. طقم تقييم KC705



    صورة


  2. ML507 أدوات التقييم



    صورة


  3. الصينية Spartan-6 XC6SLX16 board



    صورة


    أتطلع قدما
    واستشرافا للمستقبل ، سأقول أن اللوحة الأخيرة لم تكن لها نتيجة طبيعية.





وحتى الآن النتائج الفعلية



Kintex-7:



منذ بدء تنفيذ المشروع من أجله ، لم تتم كتابة المشروع بالكامل في الحال ، ولكن على مراحل. أولاً ، قمت بتوصيل LUT واحد ، وإضافة إشارات إلى التصحيح وبدأت في المشاهدة.



يتم تسجيل عداد الأساس بسرعة 200 ميجاهرتز ، لذلك ليس من الصعب حساب تردد الساعات التي تم إنشاؤها على المسروقات ، وكم مرة يكون عداد دلتا عداد المسروقات هو دلتا العداد الأساسي في نفس الوقت ، ومرات عديدة تردده. في هذه الحالة: التردد الناتج عن الغنيمة هو 381.55 ميجاهرتز.



صورة


الآن سنضيف معددًا للمشروع ، ومن خلال القياس مع نهب واحد ، سنحسب التردد له ، وللنهب (بعد كل شيء ، يجب تغيير شيء ما).



صورة


أول شيء يلقى نظرة خاطفة هو كم يهز العداد. يؤثر هذا على التردد الهائل للمُعدِّد ، ولكن بشكل عام من الواضح أن العداد آخذ في الازدياد ، مما يعني أنه يمكن أيضًا أخذه وعده. في النهاية:



  • تردد معدد: 5953.89 ميجاهرتز
  • تردد المسروقات (تم التغيير): 379.98 ميجاهرتز


حسنًا ، في النهاية ، دعنا نضيف حلقة مغلقة من زوج GPIO إلى المشروع. تحتوي لوحة KC705 على موصلات SMA J13 و J14. هنا أغلقتها بموصل بطول حوالي 10 سم ، ونتيجة لذلك:



  • تردد GPIO: 90.59 ميجاهرتز
  • تردد معدد: 12994.13 ميجاهرتز
  • تردد المسروقات: 380.18 ميجاهرتز


دعونا نستبدل ، من أجل التجربة ، الموصل بواحد أطول ، لدي سلك ضعف طوله. ونتيجة لذلك ، انخفض التردد إلى 85.29 ميجاهرتز.



في هذه المرحلة من التجربة ، يمكن ملاحظة أن تواتر تشغيل البدائيين في FPGAs ليس هو نفسه. في حالة وجود نهب واحد فقط ، اختار المزج أسرع المسروقات وقام ببناء دائرة حوله ، ثم عندما تمت إضافة معدد الإرسال ، حاول المزج العثور على هذا الموضع الفائق حيث يعمل كل من المسروقات والمعدد بأسرع ما يمكن ، وهذه عناصر وترددات أبطأ بالفعل. عندما تمت إضافة دبابيس خارجية ، تم نقل المشروع بالكامل على بلورة بشكل أساسي إلى هذه الأرجل وبدأ المشروع في التوليف على العناصر المجاورة ، لسبب ما ، في ذلك المكان ، زادت ترددات المسروقات والمضاعف بشكل ملحوظ ، ولكن لا تنس أنه على خلفية كل هذا إلى المشروع متصل ChipScope بعمق 1024 وحافلة بيانات من 64 إلى 128 (يتغير من مشروع إلى مشروع). الآن دعنا ننتقل إلى اللوحة التالية.



Virtex-5:



لم أذهب طوال الطريق الذي ذهبت إليه مع اللوحة السابقة ، أضفت على الفور جميع الخيارات الثلاثة لتوليد عباءة ونظرت في ChipScope ما حدث.



صورة


يوضح الشكل تسميتين X و O. بالإضافة إلى قيمها في الأعمدة ، فإن تنسيق الأرقام غير عشري. من الجدير بالذكر أن العداد الأساسي يحسب الآن عند 100 ميجاهرتز. وهكذا كانت النتيجة:



  • تردد GPIO: 96.34 ميجاهرتز
  • تردد معدد: 614.41 ميجاهرتز
  • تردد المسروقات: 5761.1 ميجا هرتز


يمكن ملاحظة أن المسروقات في هذا اللوح تحولت إلى أن تكون أسرع من معدد الإرسال ، واتضح أن تواتر المسامير أعلى من اللوح الأول ، ربما لأنني قمت بتوصيل الدبابيسين ليس بموصل 10 سم ، ولكن مع الطائر ، ونتيجة لذلك ، أصبح خط الاتصال أقصر ، وكان التردد أعلى.



والآن الخيار الأخير مع مجلس صيني.



Spartan-6:



هناك عدادات أساسية في ChipScope ، في الواقع إنه نفس العداد الذي لم يرغب في إعادة تكوين ChipScope. في هذا المشروع ، يتم تسجيل العداد الأساسي بسرعة 50 ميجا هرتز.



صورة


في حالة هذا المنتدى ، تبين أن كل شيء أكثر تعقيدًا. أولاً ، لم يكن المشروع يريد أن يتم توليفه بأي شكل من الأشكال بالشكل الذي تم توليفه في الإصدارات السابقة. ثانيًا ، في النهاية ، كان علي التخلص من LUT ، حاولت استبدالها بواحدة من خمسة اتجاهات ، لكنها لم تنجح أيضًا. بشكل عام ، فيما يلي النتائج:



  • تردد GPIO: 51.77 ميجاهرتز
  • تردد معدد الإرسال: 3 490 504 ميجاهرتز
  • تردد الغنيمة: فشل في التجميع


تبين أن النتائج التي أجرتها هذه اللوحة لم تكن سعيدة على الإطلاق ، وليس فقط لأن المسروقات لا يمكن استخدامها كقطعة ، ولكن أيضًا بسبب التردد الهائل بشكل لا يصدق للمضاعف. أما بالنسبة للقطعة المتولدة على الساقين ، فقد تم استخدام موصل بطول حوالي 25-30 سم ، مغلقًا بسلك في النهاية ، من المحتمل أن تكون هناك مكثفات طفيلية ومحاثات هناك ، مما كان له تأثيرها على توليد القطع.



خاتمة



بشكل عام ، تمكنا من توليد إشارات ساعة على بدائيات مختلفة ، وتمكنا أيضًا من رؤية (باستخدام Kintex-7 كمثال) أن البدائية لها زمن انتقال مختلف اعتمادًا على موقعها. نيابة عني ، أود أن أضيف أنني لا أعتبر أن التجربة التي تم إجراؤها صحيحة تمامًا ، على سبيل المثال ، لم يتم حساب عرض البتات للعدادات ، ولم يؤخذ نقل الإشارة من نطاقات تسجيل الوقت المختلفة في الاعتبار (على الرغم من أنني جعلت الإشارة في المخزن المؤقت لعدة ساعات) ، يجب إزالة ChipScope نفسه بشكل مثالي ويجب إيجاد طريقة أخرى بشكل مثالي تحليل التردد المتولد.



المشاكل المصادفة:
Vivado ISE , . :



  • set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets -of_objects [get_cells gen_clk_inst/LUT1_inst]]
  • NET «s1» CLOCK_DEDICATED_ROUTE = FALSE;





All Articles