آموزش وریلاگ | پروژه وریلاگ
 گروه تلگرام 
VerilogCode.ir
آموزش وریلاگ | پروژه وریلاگ


آموزش وریلاگ - جلسه 16 :

آموزش وریلاگ آموزش Verilog

دانلود فیلم مربوط به (جلسه شانزدهم)

رسیدیم به آخرین و البته جذاب ترین فصل آموزش وریلاگ ، مدار های دیجیتالی معمولا یا ترکیبی هستن یا ترتیبی ، ترکیبی یعنی سیگنال های ما بصورت مداوم و همیشه باید مقداردهی بشن ، اما ترتیبی یعنی مداراتی که سیگنال های اون فقط در لبه های کلاک مقدار دهی میشن و تا وقتی کلاک بعدی نیومده ، مقدار سیگنال ها تغییری نمی کنه . این فصل میریم سراغ پیاده سازی یا توصیف مدارات ترتیبی .

آموزش وریلاگ

به شکل بالا نگاه کنید ، یه سیگنال کلاک داریم که لبه های بالای کلاک با رنگ آبی مشخص شده ، ما توی وریلاگ می تونیم مشخص کنیم که سیگنال های ما ، هروقت لبه ی بالا کلاک اومد ، مقداردهی بشن .

آموزش وریلاگ

همینطور توی این شکل لبه های پایین کلاک با رنگ آبی مشخص شده و می تونیم بگیم هرگاه لبه پایین کلاک رُخ داد ، سیگنال های ما مقادیر جدید رو بگیرند.
البته این نکته هم بگم اینطور نیست که ما فقط با لبه های کلاک کار داشته باشیم گاهی وقتا یه سیگنال معمولی (مثلا Carry در یک جمع کننده ) هم میشه از لبه اش استفاده کرد. مثلا بگیم هر وقت لبه بالارونده Carry رخ داد (یعنی هر وقت سیگنال Carry از صفر یهو یک شد) ، یه سری کارها انجام بشه.

آموزش وریلاگ

بی خیال ، اگه فهمیدین چیشد چه بهتر ، اگه نفهمیدین بریم توی مثال تا داستان روشن شه . شکل بالا یه شمارنده 16 بیتی هست که قراره از 0 تا 65535 بشماره . در واقع هم X و هم Y جفت شون قراره این شمارش رو انجام بدن ، ورودی مدار هم چیزی جز کلاک نیست .

ISE Project - VerilogCode.ir : \ Box16-1.v
 1-
 2-
 3-
 4-
 5-
 6-
 7- 
 8-
 9-
10-
11-
12-
13-
14-
15-
16-
17-
18-
19-
20-
21-
22-
23- 
module Counter(
    input Clk,
    output reg [15:0] X,
    output reg [15:0] Y
    );  
	
    initial
    begin 
	X=0;
	Y=0;
    end 
	
    always 
    begin 
	X=X+1;
    end 

    always @(posedge Clk)
    begin 
	Y=Y+1;
    end 
	
endmodule

ورودی مدار رو مشخص میکنیم که Clk هست ، قراره وقتی مقدار کلاک 0 یا 1 باشه هیچ اتفاقی نیفته اما وقتی مقدار کلاک یهو از 0 به 1 میره ، توی اون لبه بالارونده یه واحد به شمارنده اضافه بشه . توی خط 7 مقدار اولیه X و Y رو صفر میکنیم تا شمارش ما از 0 آغاز بشه .
حالا اینجا من از دوتا بلاک استفاده کردم ، یکی always که بصورت همیشگی میاد یدونه به X اضافه میکنه و اصلا با کلاک کاری نداره ، یه بلاک always دیگه هم داریم که گفتیم فقط در لبه بالارونده کلاک یدونه به Y اضافه کنه .
چیزی که توی خروجی میبینیم اینه که ، سیگنال X مقدار نامشخصی خواهد داشت ، چرا ؟ چون با سرعت نور داره بهش یدونه یدونه اضافه میشه و ما اصلا نمیفهمیم هر لحظه چه مقداری داره ، با تمام قوا و توان در هر کلاک شاید میلیون ها بار به عدد X اضافه بشه . اما سیگنال Y فقط وقتی لبه کلاک بیاد ، یدونه بهش اضافه میشه ، مثلا اگه دوره تناوب کلاک ما 1 ثانیه باشه ، هر ثانیه یدونه به Y اضافه میشه .

آموزش وریلاگ

به شکل بالا نگاه کنید ، تقریبا همون شمارنده قبلی هست ، با این تفاوت که یدونه حباب روی ورودی کلاک اضافه شده (دایره آبی رنگ) ، توی دیجیتال اگه دیدین روی سیگنالی حباب گذاشتن یعنی اون سیگنال وقتی صفر بود وظیفه شو انجام بده ، مثلا اگه سیگنال ریست بود یعنی وظیفه ریست شدن مدار باید وقتی انجام بشه که سیگنال ریست مقدارش 0 هست ، اگه حباب نبود وظیفه ریست شدن مدار وقتی رخ میداد که سیگنال ریست مقدارش 1 باشه .
اما داستان این حباب برای ورودی های کلاک اینه که وقتی حباب دیدین یعنی مدار تون با لبه پایین رونده کلاک کار کنه ، اگه هم مثل مثال قبلی حباب نبود ، با لبه بالارونده کلاک کار کنه .

ISE Project - VerilogCode.ir : \ Box16-2.v
 1-
 2-
 3-
 4-
 5-
 6-
 7- 
 8-
 9-
10-
11-
12-
13-
14-
15-
16- 
module Counter(
    input Clk,
    output reg [15:0] Y
    );  
	
    initial
    begin 
	Y=0;
    end 
	
    always @(negedge Clk)
    begin 
	Y=Y+1;
    end 
	
endmodule

خب این هم کد وریلاگ این شمارنده ، فقط بجای posedge از negedge که بیانگر لبه پایین هست ، استفاده کردیم . یه نکته دیگه اینکه من بارها بهتون گفتم ، اصلا زیبا نیست توی کد مون از بلاک initial استفاده کنیم چون قابلیت پیاده سازی واقعی نداره و تو دنیای واقعی نمیشه همچین کاری کرد ، هرچند توی نرم افزار و شبیه سازی این کد شما ایراد نداره و بهتون خروجی میده اما بیاین واقعی تر کار کنیم . معمولا توی مدارات ترتیبی برای مشخص کردن مقادیر اولیه سیگنال های خروجی ، بجای اینکه از initial استفاده کنند ، میان یه سیگنال ورودی جدید تعریف میکنن به اسم ریست و میگن هر وقت ریست فعال بود مقادیر اولیه به سیگنال های خروجی داده بشه . پس ازین به بعد من توی مثال های بعدی همیشه یک سیگنال ریست توی مدار میذارم که تکلیف مقادیر اولیه رو روشن کنه .

آموزش وریلاگ

به شکل بالا نگاه کنین یه دی فلیپ فلاپ هست ، کارش چیه ؟ هر بار که لبه کلاک میاد اگه ریست فعال باشه ، خروجی شو صفر میکنه ولی اگه ریست فعال نبود ، به ورودی D نگاه میکنه ، اگه D صفر بود ، خروجی Q رو صفر میکنه و اگه D یک بود خروجی Q رو یک میکنه . به عبارتی میشه گفت هر وقت لبه کلاک که میاد Q برابر با D میشه .البته یه خروجی دیگه هم داره به اسم Q پریم ، که مقدارش همیشه معکوسه Q هست.

ISE Project - VerilogCode.ir : \ Box16-3.v
 1-
 2-
 3-
 4-
 5-
 6-
 7- 
 8-
 9-
10-
11-
12-
13-
14-
15-
16- 
17-
18-
19-
module DFF(
    input Clk,
    input Rst,
    input D,
    output reg Q,
    output Qp
    );  
	
    assign Qp=~Q;
 
    always @(posedge Clk)
    begin 
	if (Rst==0)
	    Q=0;
	else 
	    Q=D;
    end 
	
endmodule

طبق کد بالا ، هرگاه لبه بالارونده کلاک بیاد ، یک شرط بررسی میشه ، اگه ریست فعال باشه (یعنی صفر باشه ، چرا صفر ؟ چون حباب داره) خروجی ما 0 و اگه ریست غیر فعال ( مقدار 1 ) باشه خروجی ما برابر با ورودی D خواهد بود . توی خط 9 هم مشخص کردیم که خروجی Qپریم ، همیشه معکوسه Q باشه .

آموزش وریلاگ

شکل بالا یه فلیپ فلاپ نوع JK هست که هنگام لبه کلاک با توجه به مقدار ورودی های J و K مشخص میشه که خروجی ما چه مقداری داشته باشه . اگه J و K هر دو صفر باشند خروجی ما برابر با خودش میشه (حفظ مقدار قبلی) ، اگه هر دو یک باشند ، خروجی ما معکوس (نات) میشه و اگه فقط J یک باشه خروجی ما یک میشه و اگه فقط K یک باشه خروجی ما صفر میشه .

ISE Project - VerilogCode.ir : \ Box16-4.v
 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-
module JKFF(
    input Clk,
    input Rst,
    input J,
    input K,
    output reg Q,
    output Qp
    );  
	
    assign Qp=~Q;
 
    always @(posedge Clk)
    begin 
	if (Rst==0)
	    Q=0;
	else 
	begin 
	    if (J==0 && K==0)
		Q=Q;
	    else if (J==0 && K==1)
		Q=0;
	    else if (J==1 && K==0)
		Q=1;
	    else if (J==1 && K==1)
		Q=~Q;		
        end 
    end 
	
endmodule

کد وریلاگش توضیح خاصی نداره ، مثل کد فلیپ فلاپ D هست فقط چند تا شرط بهش اضافه شده که با کمک شرط ها مقدار خروجی تعیین میشه .

بیاین یه مبحث جدید رو بهتون بگم ، به قسمت ریست ها دقت کردین ؟ ما گفتیم هر بار که لبه کلاک میاد بررسی کن و ببین ریست فعال هست یا نه ، اگه فعال بود خروجی رو صفر کن . به این شیوه بررسی ریست ، میگن ریستِ سنکرون یا ریستِ همزمان ، یعنی اگه ریست فعال بشه باید صبر کنیم لبه کلاک بیاد تا خروجی رو صفر کنه . اما یه شیوه ریست دیگه داریم به اسم ریستِ آسنکرون یا غیرهمزمان ، به این صورت که هروقت سیگنال ریست فعال شد بلافاصله خروجی مدار صفر بشه و اصلا منتظر اومدنِ لبه کلاک نباشه . در واقع باید کاری کنیم که محتوای درون always فقط در لبه کلاک اجرا نشه ، بلکه هم در لبه کلاک و هم در لبه ریست اجرا بشه . برای اینکار فقط کافیه خط 12 کد مون رو مطابق زیر تغییر بدیم :

ISE Project - VerilogCode.ir : \ Box16-5.v
 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-
module JKFF2(
    input Clk,
    input Rst,
    input J,
    input K,
    output reg Q,
    output Qp
    );  
	
    assign Qp=~Q;
 
    always @(posedge Clk , negedge Rst)
    begin 
	if (Rst==0)
	    Q=0;
	else 
	begin 
	    if (J==0 && K==0)
		Q=Q;
	    else if (J==0 && K==1)
		Q=0;
	    else if (J==1 && K==0)
		Q=1;
	    else if (J==1 && K==1)
		Q=~Q;		
        end 
    end 
	
endmodule

توی خط 12 گفتیم اجرای کد های درون always در دو هنگام رخ بده ، وقتی لبه بالای کلاک میاد و همچنین وقتی که لبه پایین ریست میاد ، چرا لبه پایین ؟ چون پایه ریست ما حباب داشت و این یعنی هروقت مقدارش صفر شد (لبه پایین) مدار ریست بشه . بنابراین هرگاه ورودی ریست صفر شد بلافاصله و بدون توجه به کلاک ، خروجی ما سریعا صفر میشه .
نکته اینکه اگه احیانا پایه ریست تون حباب نداشت یعنی هروقت ریست تون یک شد خروجی ریست بشه پس باید بنویسید : always @( posedge Clk or posedge Rst) به همین راحتی . دانلود فیلم جلسه

رفتن به جلسه بعد ...

مشاهده نظرات کاربران




پیام شما با موفقیت ارسال شد و به زودی در این قسمت به نمایش در خواهد آمد .
لطفا تمام فیلد های الزامی را پُر کنید .


رضا

عالی