1 - سطح گیت
جلسه اول (ماژول ها) جلسه دوم (گیت ها) جلسه سوم (نوع سیگنال) جلسه چهارم (پایان فصل)2 - مقداردهی مداوم
جلسه پنجم (اُپراتور ها) جلسه ششم (آرایه ها) جلسه هفتم (شرط ها) جلسه هشتم (فراخوانی ماژول) جلسه نهم (تست بنچ) جلسه دهم (نگاشت حافظه)3 - سطح رفتاری (ترکیبی)
جلسه یازدهم (بلاک Always) جلسه دوازدهم (ابزار ها) جلسه سیزدهم (نوع پردازش) جلسه چهاردهم (نکات تکمیلی) جلسه پانزدهم (پایان فصل)4 - سطح رفتاری (ترتیبی)
جلسه شانزدهم (لبه ها) جلسه هفدهم (تست بنچ 2) جلسه هجدهم (شمارنده ها) جلسه نوزدهم (ضرب و شیفت) جلسه بیستم (استیت ماشین) جلسه بیست و یکم (کشف رشته) جلسه بیست و دوم (فرکانس) جلسه بیست و سوم (نان بلاک) جلسه بیست و چهارم (پایان)5 - جلسات تمرینی
جلسه تمرین اول (تاخیر ها) جلسه تمرین دوم (الحاق-منطق) جلسه تمرین سوم (شیفت ها) جلسه تمرین چهارم (استیت)6 - مثال های پروژه محور
پروژه طراحی پردازنده RTL پروژه پردازنده Maano پروژه پردازنده MIPS7 - ارتباط و گفتگو
ارتباط با نویسنده گروه تلگرام تبلیغات و آگهیآموزش وریلاگ آموزش Verilog
فرض کنید قراره مدار زیر که از بخش های مختلفی (دیکُدر-مالتی پلکسر- اَند) تشکیل رو توصیف کنیم :
یک روش اینه که هر قسمت رو در یک ماژول جُدا توصیف کنیم و بعد همه ی قسمت ها رو در یک ماژول اصلی فراخوانی کنیم . این روش بسیار هم عالیه اما روش های دیگه ای هم هست ، مثلا کل قسمت هارو بصورت یکجا در یک ماژول توصیف کنیم و کار رو تموم کنیم :
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- 41- 42- 43- 44- 45- 46- 47- 48-
module Test( input Start, input [1:0] X, output reg FADD, output reg [3:0] F ); reg [3:0] Y; always @(*) begin if (X==0) begin Y=4'b0001; end else if (X==1) begin Y=4'b0010; end else if (X==2) begin Y=4'b0100; end else if (X==3) begin Y=4'b1000; end else begin Y=4'bzzzz; end if (Start) begin F=Y; else if (~Start) begin F=0; end FADD = F[0] & F[1] & F[2] & F[3]; end endmodule
همه سیگنال هارو قراره توی یک بلاک
always
مقدار دهی کنیم ، بنابراین سیگنال های F,FADD,Y همگی بصورت
reg
تعریف می شود . سیگنال واسطه ای Y نیز باید
reg
تعریف شود چرا که مقداردهی آن را در بلاک
always
انجام داده ایم .
در خط 43 برنامه ، تکلیف FADD را مشخص کرده ایم که حاصل اَند بیت های مختلف F می باشد . در خط 15 تا 34 به کمک ابزار
if
یک دیکُدر 2 به 4 را توصیف کردیم و در خط 37 تا 43 یک مالتی پلکسر را توصیف کردیم که در صورت یک بودن مقدار Start ، خروجی آن Y می شود و در غیر اینصورت خروجی آن زمین یا همان صفر می شود.
دقت کنید که تمامی خطوط و ابزار ها و بخش های مختلف ، درون یک
always
قرار دارد که این
always
از خط 11 شروع و در خط 54 خاتمه می یابد .
حال به کد زیر نگاه کنید :
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- 41- 42- 43- 44- 45- 46- 47- 48- 49- 50- 51- 52- 53- 54- 55- 56-
module Test( input Start, input [1:0] X, output reg FADD, output reg [3:0] F ); reg [3:0] Y; always @(*) begin FADD = F[0] & F[1] & F[2] & F[3]; end always @(*) begin if (X==0) begin Y=4'b0001; end else if (X==1) begin Y=4'b0010; end else if (X==2) begin Y=4'b0100; end else if (X==3) begin Y=4'b1000; end else begin Y=4'bzzzz; end end always @(*) begin if (Start) begin F=Y; else if (~Start) begin F=0; end end endmodule
این بار اومدیم هر بخش از مدار رو در یک
always
جداگونه توصیف کردیم و از سه بلاک
always
استفاده کردیم . بنابراین ما توی ماژول مون هیچ محدودیتی نداریم که از چند بلاک استفاده میکنیم و برای این موضوع دست مون کاملا بازه . حالا نکته مهم این وسط چیه ؟
الان کدوم بلاک اول اجرا میشه ؟ کدوم بلاک آخر اجرا میشه ؟ ببینید ما توی وریلاگ فقط داریم مدار رو توصیف میکنیم کسی که قراره مدار رو اجرا کنه ، وریلاگ نیست ، بلکه شبیه ساز ها هستند ، بنابراین توی توصیف کردن یک مدار ، ترتیب اصلا بی معنیه ، یعنی چی اول کدوم قسمت توصیف بشه ؟ چه فرقی داره اول کجای مدار رو توصیف کنیم ؟ شما در نهایت همه جای مدار رو توصیف میکنی تموم میشه میره و بعد شبیه ساز ها از توصیف شما استفاده میکنند . بنابراین در اینجا همه ی بخش ها و بلاک ها بصورت یکجا اجرا می شوند و هیچ بلاکی نسبت به دیگری ارجعیت و برتری نداره .
حالا به کد زیر نگاه کنید :
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- 41- 42- 43-
module Test( input Start, input [1:0] X, output FADD, output [3:0] F ); reg [3:0] Y; and(FADD,F[0],F[1],F[2],F[3]); always @(*) begin if (X==0) begin Y=4'b0001; end else if (X==1) begin Y=4'b0010; end else if (X==2) begin Y=4'b0100; end else if (X==3) begin Y=4'b1000; end else begin Y=4'bzzzz; end end assign F = (Start)? Y : 0; endmodule
در گذشته بهتون گفته بودم یک مدار رو میشه به روش های مختلفی کد نویسی کرد ، سطح گیت ، مقداردهی مداوم و بلاک
always
، حالا بهتون میگم شما اجازه دارید در صورت تمایل ، هر جزء از مدار رو به یک روش توصیف کنید ، اصلا محدودیتی در این زمینه ندارید . بخش اَند مدار رو به روش سطح گیت توصیف کردیم و بخش دیکُدر با استفاده از بلاک
always
توصیف شد و در نهایت بخش مالتی پلکسر رو با
assign
توصیف کردیم .
ترتیب شون اصلا مهم نیست ، اگه دوست داشتید میتونید اول مالتی پلکسر رو توصیف کنید و در آخر اَند رو توصیف کنید . نکته مهم اینکه چون ما ایندفعه F و FADD رو توی بلاک
always
مقداردهی نکردیم ، پس نباید نوع شون
reg
باشه ، بنابراین توی خط 4 و 5 کلمه
reg
رو برداشتیم . اما Y همچنان باید از نوع
reg
باشه چون توی بلاک
always
مقداردهی شده .
به شکل بالا نگاه کنید ، این یه دیکُدر 3 به 8 هست که می تونیم خیلی راحت با استفاده از ابزار های if و case توصیف اش کنیم .
اما فرض کنید به ما گفتن حق چنین کاری ندارید بلکه باید با استفاده از ساخت دو عدد دیکُدر 2 به 4 و متصل کردن شون بهمدیگه (مشابه شکل بالا) یک دیکُدر 3 به 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-
module DEC2_4( input [1:0] X, input en, output reg [3:0] Y ); always @(*) begin if (en) begin case (X) 0 : begin Y=4'b0001; end 1 : begin Y=4'b0010; end 2 : begin Y=4'b0100; end 3 : begin Y=4'b1000; end default : begin Y=4'bz; end endcase end else if (~en) begin Y=0; end end endmodule
احتمالا دیگه خودتون میتونید کُد بالا رو درک کنید ، صرفا یه دیکُدر 2 به 4 رو توصیف کردیم . حالا باید یه ماژول جدید بسازیم و با استفاده از فراخوانی کردن ماژول بالا ، مدار اصلی رو بسازیم :
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16- 17- 18-
module DEC3_8( input [2:0] X, output [7:0] Y ); DEC2_4 DEC1 ( .X({X[1],X[0]}), .en(~X[2]), .Y({Y[3],Y[2],Y[1],Y[0]}) ); DEC2_4 DEC2 ( .X({X[1],X[0]}), .en(X[2]), .Y({Y[7],Y[6],Y[5],Y[4]}) ); endmodule
طبق تصویر زیر ، باید دو بیت X[0] و X[1] رو به بخش X ماژول قبلی وصل کنیم ، یعنی خطوط 7 و 13 که این کار را به کمک الحاق انجام دادیم ، البته میشد بجای الحاق نوشت X[1:0] ، که در این صورت باز هم این دو بیت به بخش X ماژول قبلی وصل خواهد شد .
برای پایه en ، طبق تصویر زیر باید ~X[2] را به ماژول اول و خود X[2] را به ماژول دوم بدیم و در نهایت خروجی هارو مشخص کردیم که برای ماژول اول پایه های Y[3:0] و ماژول دوم پایه های Y[7:4] خروجی های ما خواهند بود .
اگه سوالی هست توی کامنت ها بپرسید ولی سعی کنید این جلسه رو حتما ویدئو شو ببینید چون بسیاری از توضیحات تکمیلی توی ویدئو گفته میشه ، موفق باشید .
دانلود فیلم جلسه