
في هذه المقالة ، سنشارك خبرتنا في تطوير بطاقات الواجهة لوحدة الواجهة استنادًا إلى SoC ARM + FPGA Xilinx Zynq 7000. تم تصميم اللوحات لتسجيل إشارات الكلام بتنسيق PRI / BRI التناظري والرقمي (ISDN ، E1 / T1). سيتم استخدام الجهاز النهائي نفسه لتسجيل المفاوضات في مجال الطيران المدني.
الحديد: اختيار منصة الأجهزة
تم تحديد اختيار النظام الأساسي للأجهزة من خلال دعم بروتوكولات PRI / BRI ، والتي يمكن تنفيذها فقط على الجانب FPGA. وحدات التحكم الدقيقة (MCUs) والمعالجات الدقيقة (MPUs) لم تكن مناسبة.
يمكن للمرء أن يختار حلين لهذه المشكلة:
- التوليف الأساسي لـ Microblaze IP
- SoC Zynq-7000.
استقرنا على نظام على شريحة Zynq 7000 (SoC) ، لأن من الأسهل كتابة تطبيقات البرامج وتوفر المزيد من الوظائف للمهام الحالية والمستقبلية.
في المجموع ، تم جمع القائمة التالية من الحديد في إطار المشروع:
1.Xilinx Zynq 7020 (
Mars-ZX3 و
Mars EB1 )
Enclustra Mars ZX3 SOM
Enclustra Mars EB1 Baseboard2. TI TLV320AIC34 (
tlv320aic34evm-k واللوحة الأم USB).
لوحة التصحيح لـ tlv320aic34 (tlv320aic34evm-k)
لوحة توسيع USB-MODEVM لـ tlv320aic34evm-k3. IDT82P2288 - PRI ، XHFC-4SU - BRI microcircuits ، لم تكن هناك مجموعات تصحيح ، لذلك وضعنا الأساس فقط كنواة للملكية الفكرية للاختبار ، وحدثت معمودية الحريق مباشرة في هذه العملية ، بعد عمل لوحات النموذج الأولي.
العمل مع النظام على رقاقة Xilinx Zynq 7000
الهيكل الداخلي لـ SoC Xilinx Zynq 7000
خطوات إنشاء ملفات التمهيد لـ Xilinx Zynqيختلف وميض / تنزيل الملفات التنفيذية لـ Zynq عن التنزيل المعتاد لـ MPU. العمل المعتاد مع معالجات Cortex-A هو تحميل u-boot و kernel linux و rootfs. وعلى Zynq ، يظهر bitstream ، ملف البرامج الثابتة لـ FPGA. يحتوي تدفق البت على وصف لمكونات الأجهزة في FPGA والاتصالات الداخلية مع المعالج. يتم تحميل هذا الملف عند بدء تشغيل النظام. أيضا على الجانب لينكس هناك آلية تسمح لك وميض جزء PL على الفور أثناء التشغيل ، ويسمى هذا الجهاز xdevcfg (
مدير ZYNQ FPGA منذ 2018.1 ).
واجهات PRI / BRI
ملامح الشبكات الرقمية PRI / BRIواجهة المعدل الأساسي (PRI) هي واجهة شبكة ISDN قياسية تحدد انضباط توصيل محطات ISDN بخطوط الاتصال ذات النطاق العريض التي تربط التبادلات المحلية والمركزية أو محولات الشبكة.
نوع الإطار المرسل لـ PRI
عرض الإطار المرسل لـ BRI
البنية الداخلية لفيزياء PRI - IDT82P2288
البنية الداخلية لفيزياء BRI - XHFC-4SUبرنامج ترميز الصوت TLV320AIC34
يعد
برنامج ترميز الصوت TLV320AIC34 منخفض الطاقة
رباعي القنوات للصوت المحمول والمهاتفة حلاً جيدًا للاستخدام في الاتصالات الهاتفية التناظرية.
Tlv320aic34 A-part ، يحتوي برنامج الترميز الصوتي على كتلتين من الوظائفيمكن إرسال البيانات من خلال واجهة I2S ، وكذلك من خلال DSP و PCM و TDM.
I2S هو معيار واجهة ناقل تسلسلي ، يتم استخدامه لتوصيل أجهزة الصوت الرقمية ويمثل كهربائيًا 3 موصلات تنتقل من جهاز نشط إلى آخر سلبي ، بالإضافة إلى 4 إشارات تتوافق معها على النحو التالي:
- ساعة بت (BCLK).
- تزامن إطار إشارة الساعة (حسب الكلمات) (WCLK).
- إشارة بيانات يمكنها إرسال أو استقبال قناتين مقسمتين زمنياً (DIN / DOUT).
تنقسم قنوات استقبال البيانات وإرسالها ، أي أن هناك قناة منفصلة لاستقبال البيانات وقناة للإرسال. تستقبل وحدة التحكم البيانات المرسلة بواسطة برنامج الترميز الصوتي ، ولكن العكس ممكن أيضًا.
إطار I2S ، ميزات واجهة I2Sبعد اختيار جميع مكونات الأجهزة ، قمنا بحل مشكلة توصيل برنامج ترميز الصوت و Xilinx Zynq 7020.
ابحث عن نوى I2S
ربما كانت أصعب لحظة عند العمل مع دفق الصوت في Xilinx Zynq 7020 هي أنه في جزء المعالج من هذا النظام لا يوجد في الأساس ناقل I2S على الشريحة ، لذلك كان علي العثور على نواة I2S. كانت هذه المهمة معقدة بسبب شرط أن يكون ip core مجانيًا.
استقرنا على العديد من نوى الملكية الفكرية. العثور على الأساسية المعدنية العارية I2S
Digilent . لقد وجدنا العديد من نوى ip على
opencores ، وربما يكون أفضل خيار بالنسبة لنا هو
الأجهزة التناظرية ip core. أنها تنتج النوى الملكية الفكرية لمعداتهم ، لتفاعل FPGA / FPGA.
نحن مهتمون بـ ip-core يسمى
AXI-I2S-ADI. تقوم الأجهزة التناظرية نفسها بالترويج لأنوية IP هذه لمنصات الأجهزة الخاصة بها.
قائمة حالات الاستخدام:
- Bare metal - IP core for I2S (Digilent ZYBO audio)
- opencores.org
- وحدة تحكم AXI-I2S-ADI (أجهزة تناظرية)
AXI-I2S-ADI IP Core
يبدو جوهر IP نفسه كما يلي: يحتوي على الخطوط bclk و wclk و din و dout. يتصل DMA Xilinx Zynq 7000 ، في مثالنا ، يتم استخدام جزء DMA PS. يحدث كل تبادل البيانات من خلال DMA. يمكن أن تكون DMA وحدة قائمة بذاتها أو جزءًا لا يتجزأ من PS SoC.
عند تكوين ip-kernel ، من المهم عدم نسيان إرسال تردد mclk الرئيسي إلى tlv320aic34 نفسه ، كخيار عند استخدام مجموعة تصحيح الأخطاء لـ tlv320aic34 - إرسال تردد رئيسي خارجي.
كتلة وظيفية مع axi-i2s-adi متصلبعد إجراء التكوين ، كانت المهمة هي إطلاق الوظائف في نظام التشغيل Linux.
تكوين i2c (تم تكوين tlv320aic34 على هذه الواجهة):
i2c0: i2c@e0004000 { ... tlv320aic3x: tlv320aic3x@18 { #sound-dai-cells = <0>; compatible = "ti,tlv320aic3x"; reg = <0x18>; gpio-reset = <&axi_gpio_0 0 0>; ai3x-gpio-func = <&axi_gpio_0 1 0>, /* AIC3X_GPIO1_FUNC_DISABLED */ <&axi_gpio_0 2 0>; /* AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT */ AVDD-supply = <&vmmc2>; DRVDD-supply = <&vmmc2>; IOVDD-supply = <&vmmc2>; DVDD-supply = <&vmmc2>; ai3x-micbias-vg = <1>; }; ... };
تكوين i2s (يتم نقل البيانات الصوتية عبر هذه الواجهة):
i2s_clk: i2s_clk { #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <11289600>; clock-output-names = "i2s_clk"; }; axi_i2s_adi_0: axi_i2s_adi@43C00000 { compatible = "adi,axi-i2s-1.00.a"; reg = <0x43C00000 0x1000>; xlnx,bclk-pol = <0x0>; xlnx,dma-type = <0x1>; xlnx,has-rx = <0x1>; xlnx,has-tx = <0x1>; xlnx,lrclk-pol = <0x0>; xlnx,num-ch = <0x1>; xlnx,s-axi-min-size = <0x000001FF>; xlnx,slot-width = <0x18>; }; &axi_i2s_adi_0 { #sound-dai-cells = <0>; compatible = "adi,axi-i2s-1.00.a"; clocks = <&clkc 15>, <&i2s_clk>; clock-names = "axi", "ref"; dmas = <&dmac_s 0 &dmac_s 1>; dma-names = "tx", "rx"; };
ضبط بطاقة الصوت في شجرة الجهاز (بطاقات الصوت):
sound { compatible = "simple-audio-card"; simple-audio-card,name = "TLV320AIC34"; simple-audio-card,format = "i2s"; simple-audio-card,bitclock-master = <&dailink0_master>; simple-audio-card,frame-master = <&dailink0_master>; simple-audio-card,widgets = ... simple-audio-card,routing = ... dailink0_master: simple-audio-card,cpu { clocks = <&i2s_clk>; sound-dai = <&axi_i2s_adi_0>; }; simple-audio-card,codec { clocks = <&i2s_clk>; sound-dai = <&tlv320aic3x>; }; }; };
بعد كل التلاعبات لتكوين وتكوين برنامج الترميز في شجرة الجهاز في Linux ، ظهرت بطاقة الصوت المرغوبة وتمكننا من سماع الموسيقى (كان أول مسار موسيقي لدينا هو الطريق السريع إلى الجحيم ، AC / DC).
إليك ما كان علينا فعله لهذا:
- توليد التردد اللازم باستخدام clk_wiz (معالج تسجيل الوقت)
- تكوين DTS بشكل صحيح لـ tlv320aic34
- إضافة دعم للسائق tlv320aic3x
- تمت إضافة حزم الصوت إلى buildroot لتشغيل دفق الصوت (aplay و madplay وما إلى ذلك)
في عملية تطوير الجهاز النهائي ، واجهنا مهمة توصيل 4 شرائح tlv320aic34. تحتوي شريحة tlv320aic34 الموضحة أعلاه على كتلتين للعمل مع الدفق الصوتي ، ولكل كتلة خط i2c الخاص بها لتكوين وإعداد معلمات الصوت. يمكن أن يكون للكتلة أربعة عناوين فقط ، على التوالي ، من المستحيل توصيل أربعة دوائر صغيرة جدًا tlv320aic34 بواجهة i2c واحدة ، تحتاج إلى استخدام واجهتين i2c (8 كتل صوتية مستقلة). لكل كتلة ، إذا بدأت mclk ، blck ، wclk ، din / dout بشكل فردي ، فأنت بحاجة إلى إضافة 40 خط إشارة إجمالاً ، وهو أمر مستحيل وغير منطقي من وجهة نظر الدائرة لوحدة سوم التي اخترناها ، لأنه بالإضافة إلى هذه الإشارات ، كان عليك توصيل العديد من الخطوط الأخرى و واجهات.
ونتيجة لذلك ، قررنا نقل بطاقة الصوت إلى
وضع TDM ، حيث يتم دمج جميع خطوط mclk ، bclk ، din ، dout ، مما يسمح لنا بتقليل العدد الإجمالي لخطوط الاتصال. أثر هذا القرار على تشغيل axi-i2s-adi ، بسبب حقيقة أن لب ip نفسه يعمل في الوضع الرئيسي. أيضًا ، لم يسمح لنا هذا التغيير باستخدام IP-core الخاص بنا في وضع TDM ، وقرار قوي الإرادة كان علينا التخلي عن استخدام IP-core المحدد. اضطررت إلى كتابة نواة IP للاستماع إلى حركة مرور i2s وإرسالها إلى dma ، سمح لنا هذا الحل بإنشاء واجهة مشتركة لتلقي البيانات التي لا تعتمد على نوع البطاقة لتسجيل المكالمات (بطاقات تناظرية ورقمية).
البنية الأولية لاستقبال الدفق الصوتي ومعالجته عبر واجهة i2s:

البنية النهائية لاستقبال الدفق الصوتي ومعالجته عبر واجهة i2s:

معمارية استقبال تيار PRI ومعالجته:

معمارية استقبال تيار BRI ومعالجته:

Axi dma
هذا عنصر مهم من نظام مزامنة dma.
نافذة تكوين AXI DMA في Xilinx Vivadoعلى الشاشة المطبوعة ، يتم تقديم كتلة AXI DMA نفسها. لديها العديد من المعلمات. يمكنك تكوين الحافلة كم من البيانات لنقلها. يمكن محاذاة البيانات أو بأي تنسيق. وصف مفصل للعمل والتفاعل مع axi dma موصوف
في الوثائق الفنية (من إصدار إلى إصدار هناك إضافة وتصحيح عدم الدقة في الوصف ، بالإضافة إلى تنقيح ip-kernels).
تحقق من نقل البيانات من خلال خيارات اختبار AXI DMA و AXI DMA
عند تطوير السائق ، قررنا إيجاد مصدر مفتوح وتكييفه مع مهمتنا. نتيجة لذلك ، اخترنا مصادر
ezdma مشروع github (التورية ، قراءة سهلة dma).
الخطوة التالية هي تطوير محرك اختبار ، وكانت مرحلة تحضيرية تحسبًا للحظة عندما وصل إلينا جوهر IP مع وظائف جاهزة من قسم تطوير FPGA (تم تشكيل عملية التطوير الموصوفة من قبل المبرمجين المضمنين). قبل هذه اللحظة ، قررنا أخذ AXI DMA و AXI DATA FIFO وإجراء استرجاع للتأكد من الأخطاء المستقبلية المحتملة. لقد قمنا بتكرار إرسال البيانات واستلامها ، لذلك تحققنا من نتيجة عملنا وأداء سائقنا. قمنا بتكييف الوظيفة قليلاً ، وأدخلناها في رغباتنا على واجهة التفاعل وفحصنا مرة أخرى قابلية تشغيل السائق ومبدأ التفاعل المحدد.
نظرة كتلة تصميم إلى الوراء ، الطريقة الأولى لاختبار AXI DMAمثال على وصف DMA و ezdma في شجرة الجهاز:
/ { amba_pl: amba_pl { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; ranges ; axi_dma_1: axi_dma { #dma-cells = <1>; compatible = "xlnx,axi-dma-1.00.a"; reg = <0x40400000 0x10000>; clock-names = "s_axi_lite_aclk", "m_axi_sg_aclk", "m_axi_mm2s_aclk", "m_axi_s2mm_aclk"; clocks = <&clkc 15>, <&clkc 15>, <&clkc 15>, <&clkc 15>; interrupt-parent = <&intc>; interrupts = <0 29 4 0 30 4>; xlnx,addrwidth = <0x20>; xlnx,include-sg; dma-channel@40400000 { compatible = "xlnx,axi-dma-mm2s-channel"; dma-channels = <0x1>; interrupts = <0 29 4>; xlnx,datawidth = <0x20>; xlnx,device-id = <0x0>; xlnx,include-dre ; }; dma-channel@40400030 { compatible = "xlnx,axi-dma-s2mm-channel"; dma-channels = <0x1>; interrupts = <0 30 4>; xlnx,datawidth = <0x20>; xlnx,device-id = <0x0>; xlnx,include-dre ; }; }; ezdma0 { compatible = "ezdma"; dmas = <&axi_dma_1 0 &axi_dma_1 1>; dma-names = "loop_tx", "loop_rx"; // used when obtaining reference to above DMA core using dma_request_slave_channel() ezdma,dirs = <2 1>; // direction of DMA channel: 1 = RX (dev->cpu), 2 = TX (cpu->dev) }; ... }; };
يمكنك بسهولة إنشاء ملفات dts / dtsi باستخدام
أداة Device Tree Generator .
الخطوة الثانية في عملية التطوير لدينا هي إنشاء اختبار IP-kernel للتحقق من أداء السائق ، هذه المرة ستكون البيانات ذات مغزى ، مع النقل عبر AXIS إلى AXI_DMA (كما سيكون في الإصدار النهائي من ip-kernel).
سير عمل واجهة AXISننفذ نوعين مختلفين من نواة ip لتوليد البيانات ، يتم تنفيذ الإصدار المختبر الأول من خلال verilog ، والثاني - على HLS (في هذا السياق ، ظهر HLS تحت شعار "fashion-fashion-youth").
يعد مولد بيانات verilog (وبشكل عام بلغات عائلة hdl - verilog ، vhdl ، إلخ) حلاً قياسيًا عند تطوير نوى IP من هذا النوع. فيما يلي بعض مقتطفات التعليمات البرمجية لـ ip kernel المتوسطة:
module GenCnt ( …. assign HandsHake = m_axis_din_tready & m_axis_dout_tvalid; always @(posedge Clk) begin if (Rst) begin smCnt <= sIDLE; end else begin case (smCnt) sIDLE: begin smCnt <= sDATA; end sDATA: begin if (Cnt == cTopCnt - 1) begin smCnt <= sLAST; end end ... endmodule
ليست هناك حاجة لوصف أكثر تفصيلاً ، لأن هذه مهمة نموذجية لمصمم FPGA.
"الوحش" الأكثر إثارة للاهتمام هنا هو HLS.
Vivado HLS (High Level Synthesis) هو برنامج Xilinx CAD الجديد لإنشاء أجهزة رقمية باستخدام لغات عالية المستوى مثل OpenCL أو C أو C ++.
C / C ++ هي اللغات الرئيسية لمهندس برامج مضمن ، لذا فإن حل مشكلة باستخدام هذه اللغات أكثر إثارة للاهتمام من حيث التنفيذ والتحليل المقارن للمشاريع المستقبلية.
فيما يلي مثالان صغيران للعمل مع HLS. المثال الأول هو مولد بيانات لـ AXI_DMA ، والمثال الثاني هو تبادل البيانات بين جزء المعالج والمنطق القابل للبرمجة عبر واجهة s_axilite.
تم تنفيذ تبادل البيانات عبر واجهة s_axilite (المثال الثاني) بحيث كان من الممكن في أي وقت في procfs طرح أي تدفق بت تم تحميله ، وبالتالي كان من الممكن تتبع صحة العمل عن طريق الإصدار لجزء PL من SoC. هنا تظهر نقطة مثيرة للاهتمام للغاية مع s_axilite: Vivado HLS يولد برنامج تشغيل لنظام Linux (السائق ، بدوره ، تكيفنا للعمل من خلال procfs للحفاظ على وراثة الكتابة). يوجد أدناه مثال للرمز الذي تم إنشاؤه لنظام التشغيل Linux (المسار إلى الحل المصدر 1 / impl / ip / drivers / name_xxx / src /).
مراحل توليف HLS وتوليد كود rtlمولد بيانات HLS لفحص العملية باستخدام AXI_DMA:
#include <ap_axi_sdata.h> #include <hls_stream.h> #define SIZE_STREAM 1024 struct axis { int tdata; bool tlast; }; void data_generation(axis outStream[SIZE_STREAM]) { #pragma HLS INTERFACE axis port=outStream int i = 0; do{ outStream[i].tdata = i; outStream[i].tlast = (i == (SIZE_STREAM - 1)) ? 1 : 0; i++; }while( i < SIZE_STREAM); }
مثال على الحصول على الإصدار ونوع لوحة الواجهة:
#include <stdio.h> void info( int &aVersion, int &bSubVersion, int &cTypeBoard, int version, int subVersion, int typeBoard ){ #pragma HLS INTERFACE s_axilite port=aVersion #pragma HLS INTERFACE s_axilite port=bSubVersion #pragma HLS INTERFACE s_axilite port=cTypeBoard #pragma HLS INTERFACE ap_ctrl_none port=return aVersion = version; bSubVersion = subVersion; cTypeBoard = typeBoard; }
كما لاحظت ، من أجل التطوير على hls ، من المهم جدًا فهم عمل وتطبيق البراغمات المختلفة (HLS pragma) ، حيث أن عملية التوليف مرتبطة مباشرة بالبراغمات.
برنامج تشغيل تم إنشاؤه لـ s_axilite:
الملف المهم الذي يخبرك بموقع المتغيرات (التسجيلات) في مساحة العنوان هو الملف x # your_name # _hw.h. يمكنك دائمًا التحقق من صحة IP-kernel المكتوب باستخدام أداة devmem.
محتويات هذا الملف:
يصف هذا الملف عناوين السجلات ، وتتوافق السجلات مع موقع الوسيطات في الوظيفة. بعد تجميع المشروع ، يمكنك أن ترى كيف سيتم تنفيذ المشروع الذي تم إنشاؤه في دورات.
مثال على فوز المشروعأظهر العمل مع hls أن هذه الأداة مناسبة لحل المهام بسرعة ، خاصة أنها أثبتت نفسها لحل المشكلات الرياضية في رؤية الكمبيوتر ، والتي يمكن وصفها بسهولة في C ++ أو C ، وكذلك لإنشاء نواة IP صغيرة للتفاعل والتبادل المعلومات مع واجهات FPGA القياسية.
في الوقت نفسه ، HLS غير مناسب لتنفيذ واجهات أجهزة معينة ، على سبيل المثال ، في حالتنا كان I2S ، ويأخذ كود rtl الذي تم إنشاؤه مساحة أكبر على FPGA مما هو مكتوب بلغات HDL القياسية.
الخطوة الأخيرة في اختبار السائق هي تطوير مولد حركة المرور I2S. يكرر هذا ip-core وظائف نواة ip السابقة ، باستثناء أنه يولد بيانات إضافية (حركة المرور) تتوافق مع بيانات I2S الحقيقية في وضع TDM.
تصميم كتلة للاختبار الأساسي I2S المخصص في المستقبل ومولد حركة المرور I2Sونتيجة لذلك ، حصلنا على نتائج hls و axi dma و s_axilite ، وراجعنا أداء برامجنا وبرامج التشغيل.
الاستنتاجات
تمكنا من تطوير الأنواع الضرورية من بطاقات الواجهة ، بالإضافة إلى نواة IP لـ tdm و pri و bri. لقد قمنا بتحسين النهج الحالي لتطوير هذه الأجهزة بشكل كبير وخلقنا حلًا شاملاً يمكن أن يتنافس مع لوحات واجهة مماثلة من
Asterick و
patton وغيرها. ميزة حلنا هو أن المطور لا يحتاج إلى رابط وسيط بين الكمبيوتر الشخصي و PCI لنقل البيانات ، سيكون قادرًا على نقل المعلومات المستلمة مباشرة عبر إيثرنت.