1 - سطح گیت
جلسه اول (ماژول ها) جلسه دوم (گیت ها) جلسه سوم (نوع سیگنال) جلسه چهارم (پایان فصل)2 - مقداردهی مداوم
جلسه پنجم (اُپراتور ها) جلسه ششم (آرایه ها) جلسه هفتم (شرط ها) جلسه هشتم (فراخوانی ماژول) جلسه نهم (تست بنچ) جلسه دهم (نگاشت حافظه)3 - سطح رفتاری (ترکیبی)
جلسه یازدهم (بلاک Always) جلسه دوازدهم (ابزار ها) جلسه سیزدهم (نوع پردازش) جلسه چهاردهم (نکات تکمیلی) جلسه پانزدهم (پایان فصل)4 - سطح رفتاری (ترتیبی)
جلسه شانزدهم (لبه ها) جلسه هفدهم (تست بنچ 2) جلسه هجدهم (شمارنده ها) جلسه نوزدهم (ضرب و شیفت) جلسه بیستم (استیت ماشین) جلسه بیست و یکم (کشف رشته) جلسه بیست و دوم (فرکانس) جلسه بیست و سوم (نان بلاک) جلسه بیست و چهارم (پایان)5 - جلسات تمرینی
جلسه تمرین اول (تاخیر ها) جلسه تمرین دوم (الحاق-منطق) جلسه تمرین سوم (شیفت ها) جلسه تمرین چهارم (استیت)6 - مثال های پروژه محور
پروژه طراحی پردازنده RTL پروژه پردازنده Maano پروژه پردازنده MIPS7 - ارتباط و گفتگو
ارتباط با نویسنده گروه تلگرام تبلیغات و آگهیآموزش وریلاگ آموزش Verilog
اگه یادتون باشه جلسه اول گفتم ، یکی از اهدافی که ما بخاطرش کُد هامونو توی ماژول مینویسیم اینه که شاید خواستیم یجایی دوباره همون کُد رو بنویسیم و ازش استفاده کنیم . با فراخوانی کردن اون قطعه کُد ، از شَر نوشتن دوباره اش خلاص میشیم . فرض کنید ما در گذشته یک ماژول جمع کننده چهار بیتی نوشتیم :
1- 2- 3- 4- 5- 6- 7- 8- 9-
module MyAdder( input [3:0] X, input [3:0] Y, output [4:0] F ); assign F=X+Y; endmodule
و حالا قراره یه ماژول جدید بنویسیم که توی این ماژول جدید سه عمل جمع انجام بشه ، البته نمیخوایم سه تا جمع کننده رو بنویسیم ، قراره سه بار ماژول جمع کننده ای که از قبل نوشتیم رو فراخوانی کنیم ، یعنی مقدار ورودی هارو بهش بدیم ، اون به ما مقدار خروجی رو بده :
برای فراخوانی کردن ، ابتدا باید اسم ماژولی که قراره فراخوانی کنید رو بنویسید ، که در این مثال قراره MyAdder رو فراخوانی کنیم ، حالا باید برای این ماژولِ کپی شده یا فراخوانی شده یه اسم مستعار انتخاب کنیم که من برای ماژولِ فراخوانی شده اول ، اسم U1 رو انتخاب کردم ، می تونید هر اسمی که عشقتونه انتخاب کنید. پس تا اینجا شد MyAdder U1 ، حالا داخل پرانتز ورودی و خروجی های ماژول فراخوانی شده رو بنویسید (قبل از هرکدوم یه نقطه هم بذارید) و جلوی هرکدوم یه پرانتز باز و بسته کنید : )MyAdder U1 ,( )X. ,( )Y. ( )F. ); حالا تعیین کنید ، کدوم سیگنال های ماژول جدید رو قصد دارید به این ماژولِ فراخوانی شده بدید :
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-
module NewAdder3( input [3:0] A, input [3:0] B, input [3:0] M, input [3:0] N, input [3:0] X, input [3:0] Y, output [4:0] C, output [4:0] P, output [4:0] F ); MyAdder U1 ( .X(A), .Y(B), .F(C) ); //C=A+B MyAdder U2 ( .X(M), .Y(N), .F(P) ); //P=M+N MyAdder U3 ( .X(X), .Y(Y), .F(F) ); //F=X+Y endmodule
در فراخوانی اول (خط13) ما A و B و C رو به MyAdder دادیم تا بره برای خودش محاسبات رو انجام بده و حاصل جمع A+B رو در C بریزه . در فراخوانی دوم (خط19) ما M و N و Pرو به MyAdder دادیم تا بره برای خودش محاسبات رو انجام بده و حاصل جمع M+N رو در P بریزه . در فراخوانی سوم (خط25) ما X و Y و F رو به MyAdder دادیم تا بره برای خودش محاسبات رو انجام بده و حاصل جمع X+Y رو در F بریزه . ببینید از قصد اسم سیگنال های فراخوانی سوم رو ، با اسم سیگنال های مربوط به ماژول MyAdder یکسان گذاشتم که بفهمید ماژول فعلی ما با ماژول فراخوانی شده ، دوتا چیزِ مُجزا هستن و هیچ نقطه اشتراکی نسبت بهم ندارند، پس عیبی نداره یک متغییر با اسم یکسان توی هر دوتا ماژول دیده بشه ، ماژولِ فراخوانی شده ، اصلا با اسم سیگنالهای تو کاری نداره ، فقط مقدار شونو میگیره ، محاسبه رو انجام میده ، حاصل رو میریزه توی متغییری که بهش دادی (F) . خب تموم شد ، الان اگه شکل موج خروجی رو با نرم افزار نگاه کنید ، C و P و F برابر با حاصل جمع های مذکور هستند.
به شکل بالا نگاه کنید ، این یکی از ماژول های جلسه ششم هست ، فرض کنید از قبل یه تفریق کننده 4 بیتی داریم به اسم Sub که دو ورودی 4 بیتی میگیره (w و h) و حاصل تفریق 5 بیتی رو (g) به عنوان خروجی میده . قصد داریم کُد رو به روش فراخوانی بنویسیم :
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16- 17- 18-
module Test( input [3:0] X, input [3:0] Y, output H ); wire [4:0] T; Sub U ( .w(X), .h(Y), .g(T) ); //T=X-Y assign H = T[2] | Y[0]; endmodule
فقط یه یک نکته توجه کنید ، وقتی قراره یه ماژول رو فراخوانی کنین حق ندارید یه reg رو به پایه های خروجی اون ماژول وصل کنین ، یعنی در اینجا که ما T رو وصل کردیم به پایه خروجی Sub ، سیگنال T حتما باید wire باشه .
تصویر بالا ، یه جمع کننده تک بیتی هست ، ابتدا کُد این جمع کننده رو می نویسیم :
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13-
module Adder( input X, input Y, input K, output N, output G ); assign N = (X^Y) ^ (K); assign G = ((X^Y)&(K)) | (X&Y); endmodule
حالا میخوایم با روش فراخوانی کردن یه جمع کننده 4 بیتی بسازیم :
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 Add4B( input [3:0] A, input [3:0] B, output [4:0] F ); wire [3:0] C; assign C[0]=1'b0; //C[0]=0(GND) Adder Sum1 ( .X(A[0]), .Y(B[0]), .K(C[0]), .N(F[0]), .G(C[1]) ); Adder Sum2 ( .X(A[1]), .Y(B[1]), .K(C[1]), .N(F[1]), .G(C[2]) ); Adder Sum3 ( .X(A[2]), .Y(B[2]), .K(C[2]), .N(F[2]), .G(C[3]) ); Adder Sum4 ( .X(A[3]), .Y(B[3]), .K(C[3]), .N(F[3]), .G(F[4]) ); endmodule
به چهار سیگنال واسطه ای نیاز دارم که با اسم C تعریف شون کردم و C0 رو برابر با صفر یا همون زمین قرار دادم . حالا چهار بار عمل نمونه گیری یا فراخوانی رو انجام میدم و چهار اسم مستعار واسشون انتخاب میکنم که از Sum1 تا Sum4 اسم های مستعار هستند . حالا سمت چپ اسم سیگنال هایی رو مینویسم که توی ماژول فراخوانی شده قرار دارند ، یعنی سیگنال های X,Y,K,N,G که توی فول ادر تعریف شدن . در نهایت اسم سیگنال های ماژول فعلی رو هم سمت راست مینویسم تا عمل جمع تک بیتی روی این سیگنالها انجام بشه .
به شکل بالا نگاه کنید ، بعضی ها جمع کننده چهاربیتی رو اینطور تعریف میکنند ، در ورودی علاوه بر دو عدد چهاربیتی یه Cin هم ورودی میگیرند و توی خروجی هم یه عدد چهاربیتی رو خروجی قرار میدن به همراه یک بیت Carry. کد وریلاگ شکل بالا به صورت زیر خواهد شد :
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 Add4B( input [3:0] A, input [3:0] B, input Cin, output [3:0] F, output Carry ); wire [3:0] C; Adder Sum1 ( .X(A[0]), .Y(B[0]), .K(Cin), .N(F[0]), .G(C[1]) ); Adder Sum2 ( .X(A[1]), .Y(B[1]), .K(C[1]), .N(F[1]), .G(C[2]) ); Adder Sum3 ( .X(A[2]), .Y(B[2]), .K(C[2]), .N(F[2]), .G(C[3]) ); Adder Sum4 ( .X(A[3]), .Y(B[3]), .K(C[3]), .N(F[3]), .G(Carry) ); endmodule
فراخوانی ها یه کاربرد دیگه هم دارند که توی تست بنچ نویسی هست که در جلسه بعدی با این مسئله آشنا خواهیم شد . این جلسه هم تموم شد خسته نباشید دوستای خوبم . دانلود فیلم جلسه
رفتن به جلسه بعد ...علی
سلام توی دومین کد زده شده همچین چیزی نوشته: MyAdder U1 ( .X(A), .Y(B), .F(C) ); وریلاگ از کچا میفهمه که باید این دستور جمع رو انجام بده؟ میره توی فایل های کامپیوترم تا دنبال فایلی به نام myadder بگرده؟
سید محسن
سلام میره بین کد های وریلاگی که توی پروژه جاری ساختید میگرده و اگه یه همچین ماژولی با همچین اسمی پیدا کنه ، میاره کد شو میذاره جای این خطوط کدی که الان شما نوشتی . فقط دیگه این جایگزین شدن کد رو ما نمیبینیم .