1 - سطح گیت
جلسه اول (ماژول ها) جلسه دوم (گیت ها) جلسه سوم (نوع سیگنال) جلسه چهارم (پایان فصل)2 - مقداردهی مداوم
جلسه پنجم (اُپراتور ها) جلسه ششم (آرایه ها) جلسه هفتم (شرط ها) جلسه هشتم (فراخوانی ماژول) جلسه نهم (تست بنچ) جلسه دهم (نگاشت حافظه)3 - سطح رفتاری (ترکیبی)
جلسه یازدهم (بلاک Always) جلسه دوازدهم (ابزار ها) جلسه سیزدهم (نوع پردازش) جلسه چهاردهم (نکات تکمیلی) جلسه پانزدهم (پایان فصل)4 - سطح رفتاری (ترتیبی)
جلسه شانزدهم (لبه ها) جلسه هفدهم (تست بنچ 2) جلسه هجدهم (شمارنده ها) جلسه نوزدهم (ضرب و شیفت) جلسه بیستم (استیت ماشین) جلسه بیست و یکم (کشف رشته) جلسه بیست و دوم (فرکانس) جلسه بیست و سوم (نان بلاک) جلسه بیست و چهارم (پایان)5 - جلسات تمرینی
جلسه تمرین اول (تاخیر ها) جلسه تمرین دوم (الحاق-منطق) جلسه تمرین سوم (شیفت ها) جلسه تمرین چهارم (استیت)6 - مثال های پروژه محور
پروژه طراحی پردازنده RTL پروژه پردازنده Maano پروژه پردازنده MIPS7 - ارتباط و گفتگو
ارتباط با نویسنده گروه تلگرام تبلیغات و آگهیآموزش وریلاگ آموزش Verilog
این جلسه تمرینی میخوام پیاده سازی چهار مدل شیفت رو بهتون بگم . شیفت منطقی یا لاجیکال ، شیفت چرخشی ، شیفت از طریق ورودی گرفتن و شیفت ارثمتیک .
توی تصویر بالا دو مرتبه از شیفت لاجیکال به راست استفاده کردیم ، در شیفت لاجیکال به سمت راست یک بیت صفر از سمت چپ وارد میشه و یک بیت (کوچکترین بیت عدد) از سمت راست خارج میشه . بنابراین اگه مقدار اولیه 111111 رو داشته باشیم بعد از یک بیت شیفت به راست میشه 011111 و مجددا بعد از یک بیت شیفت به راست میشه 001111 و این کار میتونه ادامه دار باشه .
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15-
module Shift_Logical( input Clk, input Rst, output reg [5:0] F ); always @(posedge Clk or negedge Rst) begin if(~Rst) F=6'b111111; else F=F>>1; end endmodule
برای پیاده سازی کد وریلاگ این نوع شیفت کار سختی در پیش نداریم فقط کافیه از >> برای شیفت به چپ و از << برای شیفت به راست استفاده کنیم . کد بالا میگه هر زمان که لبه کلاک اومد خروجی ما یک بیت به سمت راست شیفت پیدا کنه . عدد 111111 بعد از دو کلاک تبدیل میشه به 001111 .
شیفت چرخشی به راست به اینصورته که همه بیت ها به سمت راست شیفت پیدا میکنن و کوچکترین بیت از عدد خارج میشه و به بزرگترین بیت منتقل میشه . شیفت چرخشی به چپ هم به همین صورت همه بیت ها به سمت چپ شیفت پیدا میکنن و بزرگترین بیت از عدد خارج شده به کوچکترین بیت منتقل میشه . شکل بالا دو بار شیفت چرخشی به راست هستش که عدد 111010 بعد از یک شیفت چرخشی به 011101 و بعد از یک شیفت چرخشی دیگر به 101110 تبدیل می شود.
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16- 17-
module Shift_Cir( input Clk, input Rst, output reg [5:0] F ); always @(posedge Clk or negedge Rst) begin if(~Rst) F=6'b111010; else begin F={F[0],F[5:1]}; end end endmodule
برای پیاده سازی این نوع شیفت از دو روش استفاده میکنم . روش اول الحاق هست که توی جلسه تمرین دوم ، الحاق رو یاد گرفتید . به کمک الحاق کوچکترین بیت عدد رو در جایگاه بزرگترین بیت قرار میدیم و مابقی بیت هارو دست نخورده کنار همون بیت میذاریم باشن . با هر بار اومدن لبه کلاک یک شیفت چرخشی به راست رخ خواهد داد . برای شیفت چرخشی به چپ نیز کافی بود بنویسیم F={F[4:0],F[5]} .
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16- 17- 18- 19- 20- 21-
module Shift_Cir( input Clk, input Rst, output reg [5:0] F ); reg G; always @(posedge Clk or negedge Rst) begin if(~Rst) F=6'b111010; else begin G=F[0]; F=F>>1; F[5]=G; end end endmodule
در روش دوم برای شیفت چرخشی از شیفت لاجیکال کمک میگیریم ، ابتدا کوچکترین بیت رو توی G ذخیره میکنیم (کپی میگیریم ازش) سپس عدد رو یک بیت به سمت راست شیفت لاجیکال میدیم ، چه اتفاقی رخ میده ؟ یدونه صفر وارد میشه و توی بزرگترین بیت میشینه و مابقی بیت ها به سمت راست شیفت پیدا میکنن و کوچکترین بیت هم شوت میشه بیرون . حالا کافیه بگیم بجای اون صفر که وارد بزرگترین بیت شد ، مقدار G وارد بشه که مقدار G همون مقدار کوچکترین بیت است . در این روش برای شیفت به چپ کافیه بنویسیم G=F[5] و F=F<<1 و در نهایت F[0]=F[5] .
شکل بالا دو مرحله شیفت به راست از طریق یه ورودی هست ، تقریبا شبیه شیفت چرخشی هست اما بجای اینکه کوچکترین بیت از سمت چپ وارد بشه ، یک بیت از ورودی میاد وارد بزرگترین بیت عدد میشه . بنابراین نحوه پیاده سازی هم شبیه به شیفت چرخشی خواهد بود .
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16- 17- 18-
module Shift_inp( input Clk, input Rst, input X, output reg [5:0] F ); always @(posedge Clk or negedge Rst) begin if(~Rst) F=6'b001100; else begin F={X,F[5:1]}; end end endmodule
دقیقا مثل کد وریلاگِ شیفت چرخشی هست فقط نیازی نیست به اینکه از بیت کوچیک کپی بگیریم . ورودی رو در جایگاه بزرگترین بیت قرار میدیم و پنج بیت دیگه رو کنارش میذاریم و اثری هم از کوچکترین بیت نیست ، شوت میشه بیرون . برای شیفت به چپ هم کافیه بنویسیم F={F[4:0],X} .
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16- 17- 18- 19-
module Shift_inp( input Clk, input Rst, input X, output reg [5:0] F ); always @(posedge Clk or negedge Rst) begin if(~Rst) F=6'b001100; else begin F=F>>1; F[5]=X; end end endmodule
در روش دوم هم مثل شیفت چرخشی ، کافیه ابتدا از شیفت لاجیکال استفاده کنیم و عدد رو به سمت راست شیفت لاجیکال بدیم تا یک صفر از سمت چپ وارد بزرگترین بیت بشه ، حالا بعدش میگیم این عدد صفر از بزرگترین بیت پاک بشه و بجاش ورودی X نوشته بشه . برای شیفت به چپ هم کافیه بنویسیم F=F<<1 و F[0]=X .
تا اینجا هر بار که شیفت به راست رو توضیح میدادیم ، خیلی ریز به شیفت به چپ هم اشاره میکردیم که چطور نوشته میشه . اما برای شیفت ارثمتیک ، شیفت به چپ رو نمیگیم ، چرا ؟ چون شیفت به چپ ارثمتیک همون شیفت به چپ لاجیکال هست و موو نمیزنه بدون کوچکترین تفاوتی . اما شیفت به راست ارثمتیک متفاوته و باید توضیح بدم . ببینین در شیفت به راست ارثمتیک همه بیت ها به سمت راست شیفت میخورن و کوچکترین بیت شوت میشه بیرون ، از سمت چپ هم بجای اینکه یک عدد صفر وارد شه ، یک کپی از بزرگترین بیت وارد میشه . مثلا عدد 100010 بخواد شیفت به راست ارثمتیک اجرا بشه ، همه بیت ها میرن به سمت راست و بزرگترین بیت که 1 هست مجددا از سمت چپ وارد میشه و میشه 110001 و اگه یه بار دیگه اینکار رو کنیم میشه 111000 و اگه یکبار دیگه انجامش بدیم میشه 111100 و همینطور میشه ادامه داد .
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16- 17- 18-
module Shift_Arth( input Clk, input Rst, output reg [5:0] F ); always @(posedge Clk or negedge Rst) begin if(~Rst) F=6'b100010; else begin F=F>>1; F[5]=F[4]; end end endmodule
در روش اول کافیه ابتدا عدد رو به سمت راست شیفت لاجیکال بدیم و یک صفر از سمت چپ وارد بزرگترین بیت بشه . بعدش میگیم اون صفر رو برداره و بجاش بیت سمت راستش رو قرار داده .
1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16- 17-
module Shift_Arth( input Clk, input Rst, output reg [5:0] F ); always @(posedge Clk or negedge Rst) begin if(~Rst) F=6'b100010; else begin F={F[5],F[5:1]}; end end endmodule
به یه روش دیگه هم میشه این شیفت رو پیاده سازی کرد ، کافیه به کمک الحاق بزرگترین بیت رو در سمت چپ قرار بدیم و پنج بیت دیگه رو کنارش قرار بدیم و بیت صفرم رو هم شوت کنیم بیرون .
رفتن به جلسه بعد ...