سیمولیشن
در دو قسمت قبلی تا اینجا پیش رفتیم که یک ماژول سادهی اینورتر ساختیم و ابزارهای لازم برای تست را نیز دانلود کردیم، در این جلسه میخواهیم ماژول مذکور را سیموله کنیم و ببینیم آیا همانطور که میخواستیم کار میکند یا خیر.
برای سیموله کردن ماژول، باید تعدادی ورودی مشخص به آن بدهیم. اما چطور این کار را انجام دهیم؟
پاسخ این است که باید یک تست بنچ (test bench) تولید کنیم. کار تست بنچ این است که ورودیهای لازم را برای ارزیابی عملکرد ماژولی که میخواهیم آن را مورد ارزیابی قرار دهیم، تولید کند. اگر به این فکر میکنید که خب خود test bench اصلا چیست؟ باید بگوییم که یک ماژول وریلاگی دیگر. کاری که برای این ماژول تعریف شده است این است که سیگنالهای لازم برای ماژول دیگری که به آن وصل میشود تا عملکرد آن مورد بررسی قرار گیرد را تامین کند.
در طی فرآیند سیموله کردن، ماژول test bench باید به عنوان top module قرار گیرد و هیچ پورت ورودی/خروجیای نیز ندارد.
همینجا در پرانتز اعلام کنیم که اگر بخواهیم فرآیند سیمولیشن را بر روی FPGA واقعی پیاده کنیم، در آنجا top module میتواند پورتهای ورودی و خروجی هم داشته باشد و از طرفی در آنجا دیگر test bench به عنوان top module نخواهد بود. (در مورد جزئیات این موضوع در ادامه صحبت خواهیم کرد)
بسیار خب، کد تست بنچ را با هم میبینیم.
module myModule_tb(); wire out; reg clock; always begin #1 clock =!clock; end initial begin //Initialize clock clock = 0; //End simulation #10 $finish; end myModule notGate(clock, out); endmodule
اجازه بدهید که کد را خط به خط با هم بررسی کنیم.
همانطور که گفتیم خود تست بنچ هم یک ماژول وریلاگ است. پس ابتدا باید آن را معرفی کنیم که در خط اول همین اتفاق افتاده است و همانطور که گفتیم در سیمولیشن غیرسختافزاری، تست بنچ پورتهای I/O ندارد و میبینیم که در پرانتز مقابل آن نیز چیزی قید نشده است.
بعد از آن میبینیم که دو متغیر با نامهای out و clock تعریف شدهاند. اولی با نوع wire و دومی با نوع reg. کاربرد این متغیرها چیست؟
ما میخواهیم از طریق متغیر clock واقعا یک کلاک برای مدار بسازیم و آن را به عنوان ورودی ماژول اینورتر به آن بدهیم (به پورت A از myModule). اما چگونه این کلاک را میسازیم؟ متغیر clock را به طور متناوب معکوس میکنیم و به این ترتیب یک پالس ساعت خواهیم داشت.
متغیر out را هم به پورت خروجی myModule (یعنی پورت B) وصل میکنیم. نتایج سیمولیشن را از طریق این پورت رصد میکنیم.
میرسیم به قطعه کد مربوط به بخش always، به این قسمت توجه ویژهای داشته باشید. همانطور که از نام آن پیداست، این بلوک از کد، تا زمانی که سیمولیشن در حال اجرا باشد، مرتب و پشتسرهم اجرا میشود و البته always blockهایی که در دنیای واقعی وجود دارند، قدری پیچیدهتر از چیزی هستند که در اینجا میبینیم. از جمله اینکه مثلا دارای لیست حساسیت (sensitivity lists) هستند و … به هر حال، برای یک سیمولیشن آموزشی فعلا همین فرم ساده کفایت میکند. و اینکه نگران نباشید، در قسمتهای بعدی در مورد این پیچیدگیها بیشتر صحبت خواهیم کرد.
اما در درون این بلوک always چه اتفاقی میافتد؟ طبق کد، و همانگونه که گفتیم، متغییر clock را میبینیم که به صورت متناوب و با تاخیرهای 1 واحد ثانیهای معکوس میشود و خروجی میدهد. در زبان وریلاگ یکی از روشهای نشان دادن تاخیر استفاده از نماد # است.
بنابراین بلوک always اولا که همواره در حال اجرا شدن است و ثانیا که در درون آن، متغییر clock به صورت پیوسته در حال معکوس شدن است؛ البته با فواصل زمانی 1 واحدی. (شکل موج آن به صورت یک پالس مربعی خواهد بود)
این را هم گفتیم که علامت # نماد تاخیر است. این نماد از دستورات قابل سنتز شدن (synthesizable) محسوب نمیشود و فقط در پروسهی سیمولیشن قابل فهم است. بنابراین اگر بخواهیم کدی را سنتز کنیم و درون آن تاخیر وجود داشته باشد، باید آن را به طریق دیگری بیان کنیم.
بلوک بعدی که درون کد test bench میبینیم، initial block است. همانطور که از نام آن پیداست (مقداردهی اولیه) این بلوک فقط یکبار و در زمان شروع (t=0) اجرا میشود. پس هر متغیری که در کل ماژول نیاز به مقداردهی اولیه داشته باشد را در این قسمت قید میکنیم. این بلوک معمولا فقط در ماژولهای تست بنچ کاربرد دارد و در کدهای قابل سنتز نیز به ندرت استفاده میشود. در عوض در آنجا اگر نیاز به مقداردهی اولیه باشد، از روش reset کردن استفاده میکنند.
خب، از کد خودمان فاصله نگیریم. ما در این بخش متغیر clock را با مقدار اولیه 0، مقداردهی اولیه میکنیم. شاید فکر کنید که این کار چه اهمیتی میتواند داشته باشد؟ اگر این کار را نکنیم، مقدار اولیهی متغیری که از نوع reg است، به صورت نامعلوم (unknown) در نظر گرفته میشود و چیزی که نامعلوم است، حالا هر چند باری هم که ما بگوییم معکوس شود، باز هم نامعلوم است! یعنی پاسخ همیشه در وضعیت unknown قفل خواهد شد. به عبارت دیگر، اگر متغیر clock را مقداردهی اولیه نکنیم، هیچ پالس ساعتی تولید نخواهد شد. پس این امر بسیار مهم است.
در انتهای این بلوک دستور دیگری داریم به شکل، $finish. که میبینیم بعد از یک تاخیر 10 واحدی قرار گرفته است. معنای این خط این است که پس از آنکه مدار تحت سیمولیشن را به اندازهی 10 واحد زمانی سیموله کردی، عملیات سیمولیشن را متوقف کن.
تمام توابع و دستوراتی که با علامت $ شروع میشوند را task مینامیم. Taskها دستوراتی هستند که تنها به سیمولاتور فرمان میدهند و با مدار طراحی شده کاری ندارند و تغییری در آن ایجاد نمیکنند.
و در انتهای کد –که البته قرار گرفتن آن در بخش انتهایی اصلا به معنای کم اهمیتی آن نیست– بخش معرفی ماژولی است که میخواهیم عملکرد آن را مورد ارزیابی قرار دهیم.
عبارت «myModule notGate(clock, out)»، به این معناست که یک نمونه از ماژولی که به نام myModule ساختهایم را کپی کن و اسم آن را مثلا notGate بگذار و عملکرد آن را بررسی کن.
نکتهای که در اینجا باید توجه کنید این است که شما هر تعداد نمونه که از یک ماژول طراحی شده بخواهید داشته باشید، میتوانید و محدودیتی وجود ندارد.
و البته یک نکتهی بسیار مهم که حتما باید در این بخش رعایت کنید اتصال صحیح ورودی و خروجیهای ماژول تحت بررسی است.
اگر به کد دقت کنید، میبینید که در قسمت پرانتز مربوط به معرفی پورتهای I/O، ابتدا متغیر clock و سپس متغیر out را نوشتهایم. این رعایت ترتیب به طور ضمنی به این معناست که متغیر clock را به پورت A ماژول و متغیر out را به پورت B ماژول میخواهیم وصل کنیم.
بسیار خب. بررسی کد تمام شد. حالا نوبت شروع سیمولیشن است. برای آنکه بتوانید سیمولیشن را بر روی Xilinx ISE Webpack اجرا کنید، قدم به قدم مراحل زیر را اجرا کنید. (عکس ها براساس نسخهی 14.7 نرمافزار گرفته شدهاند)
- از منوی برنامههای ویندوز، ISE Project navigator را اجرا کنید. براساس سیستمعامل خودتان نسخهی 32 بیت یا 64 بیتِ ISE را انتخاب کنید.
- از طریق منوی file در زبانهی بالا، New Projectرا انتخاب کنید.
- برای پروژهتان یک نام انتخاب کنید و مسیره ذخیره شدن فایل را هم مشخص کنید و گزینهی next را بزنید. (مطابق تصویر زیر)
- در مرحلهی بعدی، تنظیمات پروژهی ساخته شده را مطابق نیاز آن پروژه انجام دهید. مثلا نوع FPGA و Device را براساس بوردی که استفاده میکنید انتخاب کنید. اگر از بورد Mimas V2 Spartan 6 FPGA Development Board استفاده میکنید تنظیمات را مطابق تصویر زیر قرار دهید و اگر بورد شما Elbert V2 Spartan 3A FPGA Development Board باشد؛ گزینهی family را روی Spartan 3A and Spartan 3AN قرار دهید و گزینهی device را روی XC3S50A. به همین ترتیب package را بر روی TQ144 و سرعت را بر روی 4-. زمانیکه تمام تنظیمات را وارد کردید، گزینه next و سپس finish را بزنید.
- حالا ما یک پروژهی خالی در Xilinx ISE Webpack ایجاد کردهایم. بر روی صفحهی پروژه راست کلیک کنید و از روی منویی که ظاهر میشود گزینهی New source را انتخاب کنید.
- در قسمت انتخاب source type (سمت چپ پنجره)، Verilog Modul را انتخاب کنید و سپس نام فایل را مانند تصویر زیر وارد کنید.
- کدی که به صورت خودکار ساخته شده است را با کد زیر جایگزین کنید.
module myModule_tb(); wire out; reg clock; always begin #1 clock =!clock; end initial begin //Initialize clock clock = 0; //End simulation #10 $finish; end myModule notGate(clock, out); endmodule module myModule(A, B); input wire A; output wire B; assign B = !A; endmodule
- در قسمت design view بروید و مطمئن شوید که در مود simulation هستیم.
- سیمولیشن را به این ترتیب آغاز کنید: در بخش process view، بر روی sim راست کلیک کنید و در منوی باز شده گزینهی Run را اجرا کنید. (اگر گزینهی Run برای شما نمایش داده نشده است، باید به قسمت Design View بروید و فایل v را انتخاب کنید)
- حالا دیگر سیمولاتور ISim کارش را شروع کرده و درنهایت نتایج را به صورت شکل موجهای شبیه تصویر زیر به شما ارائه خواهد داد. (توجه داشته باشید که گاهی اوقات برای آنکه شکل موج را کامل و درست ببینید، نیاز است قدری با موس بزرگنمایی یا کوچکنمایی کنید. (Zoom in/out)
خب، حالا این شکل موج را ببینید و مطمئن شوید که ماژول اینورتری که در جلسه قبل طراحی کرده بودیم به درستی کار میکند چون شکل موج خروجی در هر لحظه معکوس شکل موج ورودی است و این دقیقا همان چیزی است که از یک Not gate انتظار داریم. در جلسهی چهارم این آموزش، این ماژول را بر روی سختافزار واقعی پیادهسازی خواهیم کرد. پس با ما همراه باشید.
پروژهی کامل این سیمولیشن برای mimas V2 را از اینجا دانلود کنید.
پروژهی کامل این سیمولیشن برای Elbert V2 را از اینجا دانلود کنید.
- منبع: ترجمه از سایت numato.com
- منبع: عکس شاخص از سایت alamy.com
خب در جلسه بعدی آموزش Verilog با ما همراه باشید. و اگر این آموزش براتون مفید واقع شده ما را نیز دعا کنید و اگر خواستین میتوانید از محتوای رایگان آموزشی حمایت مالی کنید.
اگر این نوشته برایتان مفید بود لطفا کامنت بنویسید.