1 - سطح گیت
جلسه اول (ماژول ها) جلسه دوم (گیت ها) جلسه سوم (نوع سیگنال) جلسه چهارم (پایان فصل)2 - مقداردهی مداوم
جلسه پنجم (اُپراتور ها) جلسه ششم (آرایه ها) جلسه هفتم (شرط ها) جلسه هشتم (فراخوانی ماژول) جلسه نهم (تست بنچ) جلسه دهم (نگاشت حافظه)3 - سطح رفتاری (ترکیبی)
جلسه یازدهم (بلاک Always) جلسه دوازدهم (ابزار ها) جلسه سیزدهم (نوع پردازش) جلسه چهاردهم (نکات تکمیلی) جلسه پانزدهم (پایان فصل)4 - سطح رفتاری (ترتیبی)
جلسه شانزدهم (لبه ها) جلسه هفدهم (تست بنچ 2) جلسه هجدهم (شمارنده ها) جلسه نوزدهم (ضرب و شیفت) جلسه بیستم (استیت ماشین) جلسه بیست و یکم (کشف رشته) جلسه بیست و دوم (فرکانس) جلسه بیست و سوم (نان بلاک) جلسه بیست و چهارم (پایان)5 - جلسات تمرینی
جلسه تمرین اول (تاخیر ها) جلسه تمرین دوم (الحاق-منطق) جلسه تمرین سوم (شیفت ها) جلسه تمرین چهارم (استیت)6 - مثال های پروژه محور
پروژه طراحی پردازنده RTL پروژه پردازنده Maano پروژه پردازنده MIPS7 - ارتباط و گفتگو
ارتباط با نویسنده گروه تلگرام تبلیغات و آگهیآموزش وریلاگ آموزش Verilog
حالا که پیاده سازی مدارات با کلاک و بدون کلاک رو یاد گرفتیم دیگه میتونیم کد وریلاگ هرچیزی رو بنویسیم . از مدارات ساده بگیرید تا شبیه سازی انواع پردازنده های پیچیده . الان میخوایم یه ضرب کننده ترتیبی رو توصیف کنیم . قبلا ضرب کننده ترکیبی رو باهم کار کرده بودیم اما ضرب کننده ترتیبی فرق داره ، به این ضرب کننده کلاک پالس داده میشه و توی هر کلاک یک بیت ضرب انجام میشه و برای ضرب دو عدد 8 بیتی باید 8 کلاک زمان صرف بشه .
به شکل بالا نگاه کنید ، ساختار یک ضرب کننده ترتیبی هست ، برای ضرب دو عدد A و B هشت بیتی یک شیفت رجیستر 16 بیتی نیاز داریم که هشت بیت بالای اون صفر و هشت پایین اش برابر A باشه ، یه شیفت رجیستر 8 بیتی هم نیاز داریم که عدد B رو بهش بدیم و در نهایت یک ALU که عمل جمع رو برای ما انجام میده و حاصل جمع رو توی رجیستر معمولی F که 16 بیتی هست میریزه . یه واحد کنترل هم داریم که 4 تا سیگنال رو مقداردهی میکنه . سیگنال هایی که باعث میشن رجیستر A به سمت چپ و رجیستر B به سمت راست شیفت پیدا کنه .و همچنین سیگنالی که به ALU دستور میده عمل جمع رو انجام بده و سیگنالی که اجازه میده حاصل این جمع توی رجیستر F ریخته بشه . اگه بخایم توصیف این ضرب کننده رو به روش ساختاری بنویسیم خیلی طولانی میشه ، باید دوتا شیفت رجیستر بسازیم و یدونه ALU و یک واحد کنترل و چون گسترده میشه من از این روش استفاده نمیکنم . بنابراین بهتره از روش سطح رفتاری استفاده کنیم و رفتار این ضرب کننده ترتیبی رو توصیف کنیم :
فلوچارت بالا رفتار این ضرب کننده رو نشون میده ، ابتدای کار عدد A و B رو توی متغییر های Copy_A و Copy_B میریزیم تا اگه وسط کار مقادیر A و B یهو عوض شد ، ما مقادیر قبلی شون رو داشته باشیم . یه شمارنده به اسم N هم میذاریم که از 0 تا 8 قراره بشماره . حالا توی هر مرحله از این 8 مرحله ، باید کوچترین بیت Copy_B رو بررسی کنیم و اگه یک بود ، مقدار Copy_A رو به F اضافه کنیم در غیراینصورت به مقدار F دست نمیزنیم . سپس Copy_B رو یک بیت به سمت راست و Copy_A رو یک بیت به چپ شیفت میدیم . هر بار که این کارهارو میکنیم یدونه به N اضافه میکنیم تا N به عدد 8 برسه و عمل ضرب تموم بشه . حالا بیاین کد وریلاگ رفتار این فلوچارت رو بنویسیم :
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16- 17- 18- 19- 20- 21- 22- 23- 24- 25- 26- 27- 28- 29- 30- 31- 32- 33- 34- 35- 36- 37- 38- 39- 40-
module Zarb( input Clk, input Rst, input [7:0] A, input [7:0] B, output reg DONE, output reg [15:0] F ); reg [15:0] Copy_A; reg [7:0] Copy_B; reg [7:0] N; always @(posedge Clk or negedge Rst) begin if (~Rst) begin N=0; F=0; Copy_A={8'b0,A}; Copy_B=B; DONE=0; end else if (DONE==0) begin if (Copy_B[0]==1) F=F+Copy_A; Copy_B=Copy_B>>1; Copy_A=Copy_A<<1; N=N+1; if (N==8) DONE=1; end end endmodule
دو عدد 8 بیتی A و B تعریف کردیم و یه خروجی 16 بیتی که حاصلضرب ماست ، یه سیگنال DONE هم تعریف کردیم که وقتی جواب ضرب حاضر بشه ، مقدار این سیگنال یک میشه . دوتا متغییر تعریف کردیم که قراره توی ریست مدار مقداردهی شون کنیم . طبق فلوچارت وقتی مدار ریست هست و تازه قراره شروع به کار کنه مقادیر خط 18 تا 22 رو بهش میدیم . حالا یه شرط میذاریم ، تا وقتی که DONE فعال نشده یا به عبارتی جواب ضرب حاضر نشده ، مدام چند کار تکرار بشه که اون کارها چیه ؟ بررسی کوچکترین بیت B و بروزرسانی مقدار F و همچنین شیفت راست و شیفت چپ برای دو عدد مون و در آخر اضافه کردن یک عدد به متغییر N . هر بار هم چک میکنیم که N به هشت رسیده یا خیر ، اگه رسیده باشه DONE رو فعال میکنیم تا دیگه کارهای بالا انجام نشه. البته میشد به جای مانور دادن روی DONE ، این سیگنال رو کلا حذف کنیم و شرط بذاریم هر وقت N از هشت کوچیکتر بود کارهای بالا انجام بشه ولی خب کاملا سلیقه ای اومدیم یه سیگنال DONE اضافه کردیم تا برنامه خوشگلتر بشه ، همین . حالا ضرب کننده رو بی خیال شید یه مثال جدید حل کنیم :
شکل بالا یه شیفت رجیستر 8 بیتی هست که با توجه به مقدار ورودی LR در هر کلاک یک اتفاقی می افته . اگه LR صفر باشه خروجی شیفت رجیستر بدون تغییر و ثابت خواهد بود ، اگه مقدار LR یک باشه خروجی همون مقدار قبلیش خواهد بود اما یک بیت به سمت راست شیفت میخوره و از سمت چپ یک بیت به اسم Left_input وارد میشه . اگه مقدار LR دو باشه خروجی همون مقدار قبلی خواهد بود اما یک بیت به سمت چپ شیفت میخوره و از اسمت راست یک بیت به اسم Right_input وارد میشه . در نهایت اگه مقدار LR سه بود خروجی F ما برابر خواهد شد با ورودی Data که اصطلاحا بارگزاری رجیستر هم بهش میگن . اینو اگه بخایم سطح گیت یا سطح ساختاری بنویسیم باید کلی فلیپ فلاپ و مالتی پلکسر تعریف کنیم و با نظم خاصی بهم وصل کنیم که وقت گیر خواهد بود . من قصد دارم در سطح رفتاری کد شو بنویسم :
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16- 17- 18- 19- 20- 21- 22- 23- 24- 25- 26- 27- 28-
module Shift( input Clk, input Rst, input [7:0] Data, input [1:0] LR, input Left_Input, input Right_Input, output reg [7:0] F ); always @(posedge Clk or negedge Rst) begin if (~Rst) begin F=0; end else begin case (LR) 0 : F=F; 1 : begin F=F>>1; F[7]=Left_Input; end 2 : begin F=F<<1; F[0]=Right_Input; end 3 : F=Data; endcase end end endmodule
توضیح زیادی نیاز نداره ، یه کیس میزنیم روی مقدار LR و به ازای مقادیر مختلفی که LR میتونه داشته باشه ، مقدار خروجی مون که F هست رو مشخص میکنیم . برای قسمت شیفت ها ، عملگرد >> و یا << شیفت لاجیکال هستند ، یعنی یک صفر از سمت چپ یا سمت راست وارد میکنن و یک بیت از سیگنال خارج میکنند ، اما توی شیفت رجیستری که ما تصویر شو دیدیم قرار نبود از سمت چپ و یا راست ، یک صفر وارد باشه ، بلکه قرار بود مقادیر سیگنال های Left_input و Right_input وارد F بشه ، بنابراین بعد از عمل شیفت لاجیکال ، اومدیم و بجای بیت صفری که وارد شیفت شده بود ، مقدار سیگنال نامبرده شده رو گذاشتیم . درکل اگه این مبحث شیفت رو مشکل دارید و مسلط نیستید بهتره به جلسه "تمرین (3)" مراجعه کنید . توی این جلسه تمرینی به بررسی و پیاده سازی انواع شیفت لاجیکال ، چرخشی و ارثمتیک پرداختیم . سعی کنید حتما مطالعه کنید چون من کلا 4 جلسه تمرینی توی سایت گذاشتم که هر چهار تاش از نون شب واجب تره براتون . دانلود فیلم جلسه
رفتن به جلسه بعد ...