مدارات ترتیبی;
در قسمت هفتم از آموزش FPGA ساختار ارجاع انتخابی را تشریح، و با استفاده از آن یک مالتیپلکسر 4 به 1 را توصیف کردیم. در همان قسمت بحث مربوط به مدارات ترکیبی را به پایان رساندیم و همچنین هرآنچه در مورد کلیات و مفهوم مدارات ترکیبی نیاز بود، را به شما آموزش دادیم.
در این قسمت با پایهایترین عناصر سازنده مدارات ترتیبی و اینکه چگونه میتوانیم منطق یک مدار ترتیبی را با استفاده از زبان VHDL توصیف کنیم آشنا خواهیم شد. در نهایت، در این قسمت برای درک منطق و فلسفه مدارات ترتیبی، یک کد خیلی ساده خواهیم نوشت و مقادیر ارجاعات در لحظات مختلف را بررسی خواهیم کرد.
قابل توجه است که در ابتدای کار ما قواعدی را به کار خواهیم برد که در نهایت خودمان این قواعد را بنا به دلایلی نقد و حتی نقض خواهیم کرد. گرچه در بسیاری از دورههای آموزشی، که غالبا پول هنگفتی از این بابت از شما دریافت میشود و همچنین بسیاری از کتابها، اعم از داخلی و خارجی این قواعد رعایت نمیشود. بعضا رعایت نکردن این قواعد مداری را خلق میکند که خلاف منطق و فلسفه مدارات ترتیبی است، یا حداقل مدار خلق شده غیر بهینه خواهد بود.
مدارات ترتیبی
در قسمت چهارم توضیحات مختصری را در رابطه با این مدارات بیان کردیم، و همانطور که شما میدانید در اینگونه مدارات ما برای داشتن خروجی، علاوه بر داشتن ورودیهای مدار در همان لحظه، به ورودیهای لحظات قبلتر مدار نیز نیاز داریم. اما چگونه؟
در مدارات ترتیبی عناصر پایهای به اسم حافظه وجود دارند که در مواقع لزوم، ما برای داشتن دادهای از لحظات قبلتر، از مقادیر این عناصر حافظه استفاده خواهیم کرد.
فلیپفلاپها انواع مختلفی دارند که شما میتوانید برای آشنایی بیشتر با انواع فلیپفلاپها به کتابهای مرجع همانند کتاب مدار منطقی موریس مانو مراجعه کنید.
آشنایی با فلیپفلاپهای به کار رفته در FPGA های شرکت Xilinx میتواند به ما دیدی بدهد که کد VHDL را طوری بنویسیم که مدار بهینهتری پیادهسازی شود. ولی همانطور که قبلا ذکر کردیم در ابتدای کار این اصول را رعایت نمیکنیم تا بعدا که به صورت اصولی کدنویسی کردیم بتوانیم مقایسهای بین این دو انجام بدهیم تا ارزش کدنویسی اصولی مشخص شود و همچنین شما پس از اینکه این موارد بیان گردید، حتی اگر بخواهید غیر اصولی کد بنویسید، دیگر نتوانید.
مدارات ترتیبی در محیط Sequential
محیطی به اسم محیط Sequential در دل محیط Concurrent نهفته است که ما برای توصیف مدارات ترتیبی از این محیط استفاده میکنیم. اگر برگردید به قسمت چهارم در تصویر الگو و ساختار کد در زبان VHDL، الگوی کلی این محیط ترتیبی را مشاهده میکنید. محیط Sequential، با کلمه کلیدی process شروع میشود و با کلمه کلیدی end process به پایان میرسد.
همانطور که مشاهده میکنید در جلوی عبارت process، لیستی وجود دارد به اسم لیست حساسیت. اما این لیست حساسیت چیست؟
اما ارجاعات درون process چگونه رخ میدهند؟ وقتی تغییری روی یکی از سیگنالهای لیست حساسیت رخ بدهد، همانطور که گفتیم process فعال میشود و تازه قرار است که ارجاعات انجام شوند، و تا به این لحظه هیچ کدام از ارجاعها به صورت تکی رخ نداده است. با توجه به اینکه سمت راست ارجاع چه عبارتی نوشته شده باشد، این ارجاع میتواند سریعتر یا دیرتر از سایر ارجاعات به پایان برسد. یعنی درون FPGA، یک ارجاع با توجه به عبارت سمت راستش سریعتر یا دیرتر از سایر ارجاعات شروع و به پایان میرسد؟ خیر، اینگونه نیست. در زبان VHDL و درون FPGA همه ارجاعات باهم شروع میشوند، اما اجازه بدهید در رابطه با زمان پایان یافتنشان با همدیگر بحث کنیم. ما بیان کردیم که ارجاعات با توجه به عبارت سمت راستشان میتوانند سریعتر یا دیرتر به پایان برسند نه اینکه هر ارجاع برای خودش در زمان خاصی شروع شود و به پایان برسد.
در بالا در رابطه با ارجاعات مختلف دو مورد را بیان کردیم. مورد اول گفتیم که زمان پایان یافتن هر ارجاع با توجه به عبارت سمت راستش میتواند متفاوت باشد. و مورد دوم اینکه در زبان VHDL و درون FPGA تمامی ارجاعات باهم و همزمان شروع میشوند. ظاهرا این دو اصل با هم ناسازگاری دارند و برقرار شدن این دو اصل باهم غیر ممکن است! خیر اینگونه نیست، بلکه به نحوی این دو اصل سازگاری کامل باهم دارند و در نهایت مدار توصیف شده نیز عملکرد صحیحی خواهد داشت. برای روشن شدن هرچه بیشتر موضوع با سیسوگ همراه باشید.
در ادامه برای شما دو راهحل ارائه خواهیم داد که راهحل اول بی مورد و حتی با فرضیات مسئله که گفتیم زمان پایان یافتن ارجاعات متفاوت است هم سازگاری ندارد (چون در راهحل پیشرو فرض میکنیم که زمان پایان یافتن ارجاعات مانند زمان شروعشان، همزمان با یکدیگر است) و اصولا اسم راهحل گذاشتن روی این مورد خود اشتباه است. اما برای درک هرچه بیشتر موضوع، شما حتما این راهحل اشتباه را بخوانید و از ما خرده نگیرید.
اما این دو راه حل چیست؟ راهحل اول این است که ارجاعی که عبارت سمت راستش نیاز به محاسبات بیشتری دارد همزمان با ارجاعی که عبارت سمت راستش نیاز به محاسبات کمتری دارد به اتمام برسد، و در لحظه بعد دوباره ارجاعات شروع شوند. اما این راه حل اشتباه است، چرا؟ چون که هنوز یکی از ارجاعات محاسباتش تمام نشده است ولی ارجاعات همزمان به پایان رسیدهاند و تازه قرار است که دوباره ارجاعات شروع شوند، پس در خروجی ارجاعی که عبارت سمت راستش نیاز به محاسبات بیشتری دارد، مقدار یا دیتای غیر صحیحی خواهیم داشت. پس این راهحل، راهحلی اشتباه است.
اما راهحل دوم، ارجاعی که عبارت سمت راستش نیاز به محاسبات کمتری دارد، وقتی محاسباتش تمام شد حق ندارد دوباره استارت بخورد، بلکه صبر میکند تا ارجاع دیگر نیز محاسباتش تکمیل و به پایان برسد و در این لحظه هر دو باهم دوباره استارت میخورند و ارجاعات همزمان با یکدیگر شروع میشوند. که این عملکرد، عملکرد صحیحی میباشد و تنها راهحل صحیح نیز همین میباشد.
اولین سوالی که شاید ذهنتان را درگیر خود کند، این است که راهحل دوم که راهحلی صحیح میباشد، به چه نحوی در زبان VHDL نوشته میشود و چگونه در FPGA پیادهسازی میشود، و یکی از ارجاعات چگونه میتواند منتظر ارجاع دیگر بماند؟
فرض کنید در لیست حساسیت، فقط کلاک قرار دارد و همهی ارجاعات با تغییر کلاک موردنظر رخ میدهند. همچنین ما این انعطاف را داریم که سرعت کلاک را متناسب با عملیات انخاب کنیم. راهحل این است که سرعت کلاک را دقیقا متناسب با ارجاعی که سمت راستش پیچیدهترین عبارت قرار دارد انتخاب کنیم. با رعایت کردن همین نکته خود به خود بحث منتظر ماندن ارجاعات، برای سایر ارجاعاتی که ممکن است محاسباتشان نیاز به زمان بیشتری داشته باشد حل میشود و تضمین میشود که سایر ارجاعات نیز به طور کاملا صحیحی انجام میشوند. حالا فکر نکنید که ما باید بشینیم تک به تک این ارجاعات را چک کنیم و تازه بعد از کلی محاسبات متوجه بشیم که فرکانس کلاک اعمالی باید فلان مقدار باشد. خبر خوب اینکه تمامی این کارها و محاسبات را خود نرمافزار انجام میدهد و در نهایت گزارشهایی را در اختیار ما قرار میدهد که حداکثر سرعت کلاک اعمالی نیز در این گزارشها قرار دارد. در قسمتهای آتی این گزارشها را بیشتر بررسی خواهیم کرد.
اگر برای اولین بار است که با توضیحات بالا آشنا میشوید به احتمال زیاد این توضیحات کمی برایتان گنگ خواهد بود. برای درک هرچه بیشتر موضوع میتوانید به مقاله “با مفهوم Pipeline بهتر آشنا شوید” مراجعه کنید. گرچه کلیت این مقاله در مورد موضوع دیگری است، ولی تمامی مواردی که در بالا ذکر کردیم را نیز پوشش میدهد و به تعدادی از سوالاتی که برایتان پیش آمده است پاسخ میدهد. در نهایت اگر سوالی داشتید میتوانید با ما به اشتراک بگذارید تا به آنها پاسخ دهیم.
اگر خاطرتان باشد در قسمت اول خدمتتان عرض کردیم که FPGA موازی کار میکند و در قسمتهای بعدتر از آن نیز درباره عملکرد موازی این تراشهها توضیحاتی دادیم و به شما قول دادیم که در روند این آموزش هرچه بیشتر با این عملکرد آشنا خواهید شد. در این قسمت هم مشاهده کردیم که تمامی ارجاعات باهم و همزمان با یکدیگر انجام میشوند که این موضوع خود مفهوم موازی بودن را میرساند.
با تمامی این تفاسیر و توصیحات مفصلی که هم وجود دارد و هم ما خدممتان عرض کردیم، به گوشمان رسیده است که بعضی از افراد عادی که نه، بلکه بعضی از افراد به اصطلاح استاد در آموزشگاهها یا موسسات مختلف به شاگردان خود آموزش میدهند که در محیط ترتیبی ارجاعات یکی پس از دیگری به ترتیب اجرا میشوند! خودتان را ناراحت نکنید، در جواب این اساتید عزیز فقط بگویید پس فرق زبان VHDL با زبانهای برنامهنویسی در چیست؟ یا در مقابل میکروکنترلرها چرا FPGA ها هم وجود دارند؟
منحصرا این قسمت را اختصاص دادیم به توضیحاتی در مورد محیط Sequential، و قصد نداریم در این قسمت مثال خاصی ارائه بدهیم چون اگر شما متوجه شوید که پشت پرده کد VHDL و در درون FPGA چه اتفاقاتی میافتد، خودتان قادر خواهید بود هر کد و مثالی را بنویسید.
در بخش پایانی یک کد ساده که از سه ارجاع تشکیل شده است، در زیر برای شما آورده شده است.
1 2 3 4 5 6 7 8 | process(x,y) begin B <= A; C <= B; A <= B; end process; |
مقادیر هر سه ارجاع در لحظات مختلف، در جدول بالا نمایش داده شده است که شما به راحتی میتوانید تحلیل کنید که چرا این مقادیر به دست آمدند. فقط یادتان باشد که همهی این ارجاعات همزمان با یکدیگر رخ میدهند و با زبان برنامهنویسی فرق دارد.
در قسمت نهم عناصر حافظه را توصیف خواهیم کرد و با استفاده از چندین مثال در مورد ساختارهای شرطی در محیط Sequential صحبت خواهیم کرد.