در این جلسه آشنایی با نرم افزار ISE و نحوه شبیهسازی کدهای VHDL با استفاده
از نرم افزار ISE توضیح داده میشود و همچنین مقدمه از زبان برنامه نویسی VHDL توضیح داده
خواهد شد نحوه پیادهسازی یک نیم جمع کننده شرح داده میشود و نهایتا نیم جمع
کننده تولید شده شبیهسازی میگردد.
زبان توصیف سخت افزار VHDL برای توصیف و شبیهسازی مدارهای دیجیتال از ساده ترین نوع آن یعنی
گیتها، تا سیستمهای پیجیدهتری مانند پروسسورها و ... به کار برده میشود.VHDL یک
زبان استاندارد بین المللی برای توصیف مدارهای دیجیتال است. در طراحی مدارهای
دیجیتال، معمولا مدار را به تعدادی بلوک دیاگرام تقسیم میکنند و سپس مدار داخلی
هر بلوک را، رسم میکنند. در سادهترین حالت ، یک طرح دیجیتال شامل یک بلوک است.
همانطور که در برگه مشخصات یک IC،ورودی، خروجیهای IC شرح داده میشود، در VHDL نیز در entity ورودی، خروجیهای مدار یا ارتباط طرح با خارج مدار از طریق port آن مشخص میشود.
همچنین در برگه مشخصات IC، مدار داخل IC یا معماری مدار رسم میشود. در VHDL نیزتوسط architecture،
مدار داخلی یا معماری مدار، یعنی طرز اتصال قطعات به ورودی، خروجیها توصیف میگردد،
به عبارت دیگر طرز کار مدار توضیح داده میشود.
هر فایل VHDL از سه بخش تشکیل شده است: معرفی کتابخانهها، تعریف اینترفیس قطعه
با دنیای بیرون خود، توصیف عملکرد قطعه.
برای معرفی کتابخانه از دستورات Library و use استفاده میشود.
به عنوان نمونه، سه خط زیر در اغلب فایلهای VHDL آورده میشود.
library
IEEE;
use
IEEE.STD_LOGIC_1164.ALL;
use
IEEE.std_logic_UNSIGNED.ALL;
برای تعریف اینترفیس قطعه با دنیای بیرون خود از کلمه کلیدی entity
استفاده میشود. به عنوان مثال برای یک نیم جمع کننده میتوان این اینترفیس را به
صورت زیر تعریف کرد. ( معمولا نامیکه برای فایل انتخاب میشود با نامی که برای entity
انتخاب میشود یکسان است)
entity HalfAdder is
Port (
a
:in std_logic;
b
:in std_logic;
Sum
:out std_logic;
Cout
:out std_logic
);
end
HalfAdder;
در تعریف یک architecture باید مشخص شود که این توصیف برای کدام entity نوشته میشود.
به عنوان مثال توصیف عملکرد داخلی یک نیم جمع کننده به صورت زیر خواهد
بود:
architecture
Behavioral of HalfAdder is
begin
Sum
<= a xor b;
Cout<=
a and b;
end
Behavioral;
نرم افزار ISE از محصولات شرکت زایلینکس است که یک محیط مجتمع
برای کار با FPGA میباشد. این نرم افزار قابلیت شبیهسازی، سنتز و
ایمپلیمنت و پراگرام کردن تمام تراشههای این شرکت را دارد. در این آزمایش مراحل
کامل نوشتن یک برنامه VHDL و شبیهسازی آن برای یک نیم جمع کننده توسط این نرم
افزار آموزش داده میشود.
از منوی File گزینه New Project را انتخاب کنید. پنجره شکل 1-1 نمایش داده میشود. در این پنجره در
قسمت Name نام پروژه را وارد کنید (مثلا HalfAdder )
شکل 1-1: ایجاد یک پروژه
جدید
در مرحله بعد باید نام و مشخصات FPGA را معین کرد. در شکل 1-2، مشخصات یکی
از FPGAهایی که در آزمایشگاه استفاده میشود
انتخاب شده است.
شکل 1-2: انتخاب FPGA
بعد از اتمام ایجاد پروژه، باید فایلهای VHDL خود را به
پروژه اضافه کنید. برای ایجاد یک برنامه VHDL جدید، مطابق شکل 1-3 روی نام تراشه FPGA، کلیک راست
نموده و گزینه New Source را انتخاب کنید.
شکل 1-3: ایجاد یک فایل
جدید و اضافه کردن آن به پروژه
سپس در پنجره ظاهر شده، نوع فایل جدید را VHDL انتخاب کنید
و نام فایل را وارد کنید. در مرحله بعد نام پورتها و نوع آن را مشخص کنید (با
توجه به توضیحات داده شده در بخش 1-1-1) تا نرم افزار ISE فایل VHDL را ایجاد
کند.
شکل 1-4: انتخاب نوع فایل
جدید و نامگذاری آن
بعد از اتمام مراحل فوق، فایل VHDL تولید شده نمایش داده میشود. در این
فایل کتابخانههای مورد نیاز به فایل اضافه شده و همچنین Entity نیز به صورت
اتوماتیک تولید شده است. تنها کاری که باید انجام شود این است که قسمت architecture نیز
تکمیل گردد. طبق برنامه داده شده در بخش 1-1-1، این قسمت را نیز تکمیل کنید.
حال پس از طراحی مدار و قبل از پیادهسازی آن بر روی برد FPGA نیاز به
محیطی است که مدار خود را در آن شبیهسازی کنید و صحت عملکرد آن را مشاهده کنید.
برای وارد شدن به محیط شبیهسازی، باید سه گام انجام دهید. در شکل 1-5، این سه گام
نمایش داده شده است. در گام اول گزینه Simulation را انتخاب کنید.
1-5: انتخاب گزینه Simulation
در گام دوم، روی نام فایل مورد نظر کلیک کنید (ممکن است در پروژه چندین
فایل VHDL وجود
داشته باشد که در این صورت با کلیک کردن روی نام فایل مورد نظر تعیین میکنید که
قصد شبیهسازی کدام فایل را دارید)
در گام سوم، روی گزینه Simulate
Behavioral Model، دابل کلیک کنید تا پنجره ISIM باز شود. در
این گام به پنجره کنسول و پیغامهای نمایش داده شده نیز دقت کنید ممکن است در برنامه
شما اشکالاتی وجود داشته باشد که پیغامهای آن در پنجره کنسول نمایش داده میشود. (نکته مهم: قبل از انجام مرحله 3، با استفاده از گزینه Behavioral Check Syntax از صحت گرامری برنامه اطمینان حاصل
کنید)
در برنامه ISIM شما میتوانید
با کلیک راست روی نام سیگنالها و پورتها و انتخاب گزینه Force Constant… به سیگنالهای
خود مقدار صفر یا یک را اختصاص دهید و شبیهسازی کنید. بعد از اینکه به سیگنالهای
خود مقدار دهی کردید با فشردن دکمه عملیات شبیهسازی شروع میشود و به مدت زمان
نمایش داده شده در تکست باکس کنار علامت مثلث، شبیهسازی انجام خواهد شد.
در شکل 1-6، نتیجه شبیهسازی یک HalfAdder نمایش داده شده است:
1-6: نتیجه شبیهسازی یک HalfAdder
برخی از گزینههای پرکاربرد در نوار ابزار نرم افزار ISIM به شرح زیر
است:
|
حذف شکل موجها و شروع مجدد شبیهسازی، بهتر است هنگام ورود به نرم
افزار ISIM در
لحظه اول این دکمه را بزنید
|
|
اگر هنگام شبیهسازی، تغییراتی در برنامه VHDL اعمال شد و
خواستید نتیجه تغییرات را در شبیهسازی هم ببینید این دکمه را بزنید تا مجدد فایلها
را لود کند
|
|
ابزار زوم کردن روی شکل موجها، برای اینکه تمام شکل موجها را در صفحه
ببینید (مثل شکل 6-1) لازم است با استفاده از این ابزار زمینه را فراهم کنید
|
1- برنامه
VHDL برای
یک تمام
جمع کننده( FullAdder) بنویسید.
2- برنامه
نوشته شده را شبیهسازی کنید و از نتیجه شبیهسازی عکس بگیرید
یک فولدر به نام YourName-H1ایجاد کنید (به جای YourName ،
نام خودتان را قرار دهید) و در داخل آن به ازای هر سوال یک زیرفولدر ایجاد کنید
به
نامهای ًQ1، Q2،Q3 و.... و در داخل هر زیر فولدر کل پروژه "آی اس ای"
مربوط به آن سوال را قرار دهید سپس آن را زیپ کنید و ارسال کنید.
کل پروژه مورد نیاز است(فقط فایل ارسال نکنید)
نکته 1: برای اینکه حجم فایلهای پروژه کاهش یابد، قبل از ارسال، گزینه CleanUp project files را از منوی project
انتخاب کنید
تا فایلهای موقتی را حذف کند
در این جلسه چگونگی استفاده از برنامههای VHDL ساده برای
نوشتن برنامههای پیچیده تر ارائه خواهد شد در این آزمایش، نحوه ترکیب دو FullAdder برای
ایجاد یک جمع کننده دو بیتی شرح داده شده است. همچنین شبیهسازی کدهای VHDL با استفاده
از TestBench
توضیح داده میشود نهایتا جمع کننده تولید شده شبیهسازی میگردد.
توصیف سیستمهای سخت افزاری پیچیده توسط VHDL، عموما به
صورت سلسله مراتبی انجام میشود. روش سلسله مراتبی به این صورت است که طرح بزرگ به
طرحهای کوچکتر شکسته میشود و کد VHDL طرحهای کوچکتر نوشته میشود سپس با ترکیب آنها
طرح بزرگتر ایجاد میگردد. به عنوان مثال برای برای پیادهسازی یک جمع کننده 2
بیتی می توان ابتدا کد جمع کننده یک بیتی (تمام جمع کننده یا Full adder) را
نوشت سپس با کنار هم قرار دادن 2 تا از آنها میتوان جمع کننده 2بیتی را ایجاد
کرد. در شکل 2-1 اتصالات مورد نیاز برای ایجاد یک جمع کننده دو بیتی نمایش داده
شده است.
شکل 2-1: ایجاد یک جمع
کننده دو بیتی با استفاده از FullAdder
در ادامه برنامه مورد نیاز برای ساخت یک جمع کننده 2 بیتی با استفاده از
2عدد FullAdder آورده شده است.
library
IEEE;
use
IEEE.STD_LOGIC_1164.ALL;
entity
Adder2Bits is
Port (
a
:in std_logic_vector(1 downto 0);
b
:in std_logic_vector(1 downto 0);
Cin
:in std_logic;
Sum
:out std_logic_vector(1 downto 0);
Cout
:out std_logic
);
end
Adder2Bits;
architecture
Behavioral of Adder2Bits is
component
FullAdder is
Port (
a
:in std_logic;
b
:in std_logic;
Cin
:in std_logic;
Sum
:out std_logic;
Cout
:out std_logic
);
end
component;
signal
c1:std_logic:='0';
begin
U0:
FullAdder
Port map (
a
=> a(0),
b
=> b(0),
Cin
=> Cin,
Sum
=> Sum(0),
Cout
=> c1
);
U1:
FullAdder
Port map (
a
=> a(1),
b
=> b(1),
Cin
=> c1,
Sum
=> Sum(1),
Cout
=> Cout
);
end
Behavioral;
برای شبیهسازی و تست یک برنامه VHDL، باید ورودیهای مورد نیاز برای آن را
تولید کرد. برنامه ISIM، در محیط شبیهسازی خود یکسری سیگنالهای از قبل تعریف شدهای دارد
که میتوان از آنها برای شبیهسازی استفاده کرد(در آزمایش اول از این روش استفاده
گردید) ولی اگر بخواهیم شبیهسازی مدار را با انعطاف پذیری بیشتری انجام دهیم،
باید یک برنامه VHDL نوشت که ورودیهای مورد نیاز برای تست قطعه مد نظرمان را تولید
کند. به این برنامه VHDL که مخصوص شبیهسازی نوشته میشود، TestBench گفته میشود.
TestBench
هیچگونه پورت ورودی یا خروجی ندارد و در واقع Entity آن خالی است
و در قسمت Architecture باید کامپوننت مربوط به برنامهای که میخواهیم تست کنیم را معرفی
کنیم. سپس سیگنالهای ورودی مورد نیاز را تعریف کنیم و بعد از کلمه کلیدی Begin،
برنامه خود برای تولید سیگنالها را بنویسیم.
به عنوان مثال در ادامه یک برنامه testBench برای FullAdder
آورده شده است.
library ieee;
use ieee.STD_LOGIC_UNSIGNED.all;
use ieee.std_logic_1164.all;
entity fulladder_tb is
end fulladder_tb;
architecture TB_ARCHITECTURE of fulladder_tb is
component fulladder
port(
a : in STD_LOGIC;
b : in STD_LOGIC;
Cin : in STD_LOGIC;
Sum : out STD_LOGIC;
Cout : out STD_LOGIC );
end component;
signal a : STD_LOGIC:=’0’;
signal b : STD_LOGIC:=’0’;
signal Cin : STD_LOGIC;
signal Sum : STD_LOGIC;
signal Cout : STD_LOGIC;
begin
UUT : FullAdder
port map (
a => a,
b => b,
Cin => Cin,
Sum => Sum,
Cout => Cout
);
a <= not a after 10ns;
b <= not b after 20ns;
Cin <= '1' after 50 ns, '0' after 100 ns,
'1' after 200ns;
end TB_ARCHITECTURE;
سیگنالهای a و b در برنامه TestBench، مقدار دهی اولیه شده اند(در هنگام تعریف این دو سیگنال)
دستور a<= not a after
10ns; باعث میشود که سیگنال a هر به 10
نانو ثانیه مکمل شود، بنابراین سیگنال a معادل یک کلاک 50مگاهرتز خواهد بود
(چرا؟!!!)
سیگنال Cin به این صورت مقداردهی شده است که بعد از 50 نانو ثانیه(از لحظه
شروع شبیهسازی)، مقدار آن برابر با 1 شود بعد از 100 نانوثانیه (از لحظه شروع شبیهسازی)
مقدار آن صفر شود و نهایتا بعد از 200نانوثانیه(از لحظه شروع شبیهسازی)، مقدار
آن 1 شود و تا بینهایت 1 بماند. در شکل 8-4، شکل موج تولید شده برای سیگنال Cin نمایش داده
شده است.
شکل 2-2: نتیجه دستور Cin <= '1' after 50 ns,'0' after 100 ns,
'1' after 200ns
اگر وارد محیط شبیهسازی شوید و فایل testBench را برای شبیهسازی
انتخاب کنید دیگر نیازی به استفاده از گزینه Simulators برای
مقداردهی سیگنالها نیست و مستقیما میتوانید دکمه شروع شبیهسازی را بزنید.
نکته پیادهسازی: دستور after قابل سنتز شدن روی FPGA نیست و فقط برای شبیهسازی استفاده میشوند. نرم افزارهای سنتز
کننده از دستورهای ایجاد تاخیر صرف نظر میکنند. در صورت نیاز به تولید تاخیر در
سخت افزار باید آن را با استفاده از شمارنده ایجاد کرد (در واقع تاخیر میتواند به
صورت مضاربی از پریود کلاک باشد)
نرم افزار ISE این امکان را به کاربران میدهد تا چارچوب برنامه TestBench را
به صورت اتوماتیک تولید کند. برای ایجاد TestBench کافی است در پنچره پروژه، کلیک
راست نموده و گزینه New Source… را انتخاب کنید سپس در پنجره ظاهر شده گزینه VHDL TestBench را انتخاب
کنید و نامی برای این فایل انتخاب کنید(معمولا دو حرف TB به ابتدا یا
انتهای نام فایل اصلی اضافه میشود). در شکل 2-3، نحوه ایجاد یک TestBench
نمایش داده شده است.
شکل 2-3: نحوه ایجاد یک TestBench
1- برنامه
VHDL برای
یک جمع کننده 4 بیتی بنویسید به نحوی که از 4 عدد fulladder استفاده شده
باشد.
2- برنامه
VHDL برای
یک جمع کننده 8 بیتی بنویسید به نحوی که از 4 عدد جمع کننده Adder2Bits استفاده شده باشد.
3- با
نوشتن TestBench برای سوال 2، آن را شبیهسازی کنید و از نتیجه شبیهسازی عکس تهیه
کنید و ارسال کنید.
برای هر سوال کل پروژه مورد نیاز است(فقط فایل ارسال نکنید)
یک فولدر به نام YourName-H2ایجاد کنید (به جای YourName ،
نام خودتان را قرار دهید) و در داخل آن به ازای هر سوال یک زیرفولدر ایجاد کنید
به
نامهای ًQ1، Q2،Q3 و.... و در داخل هر زیر فولدر کل پروژه "آی اس ای"
مربوط به آن سوال را قرار دهید سپس آن را زیپ کنید و ارسال کنید.
نکته 1: برای اینکه حجم فایلهای پروژه کاهش یابد، قبل از ارسال، گزینه CleanUp project files را از منوی project
انتخاب کنید
تا فایلهای موقتی را حذف کند
در آزمایشهای قبلی با نرم افزار ISE و شبیهساز ISIM آشنا شدید.
همچنین با اجزاء یک برنامه VHDL آشنا شدید. از این آزمایش به بعد، یک کامپیوتر کامل به صورت مرحله
به مرحله طراحی و پیادهسازی میشود. در این آزمایش ابتدا قالب دستورات و مجموعه
دستورات این کامپیوتر معرفی میگردد سپس با معرفی بخش حافظه این کامپیوتر به
برنامه نویسی آن و شبیهسازی اجرای برنامه پرداخته میشود.
در آزمایشهای بعدی برنامههای VHDL تک تک بخشهای آن نوشته میشود
تا نهایتا کامپیوتر تکمیل گردد و روی بورد پیادهسازی
و تست شود.
کامپیوتر پایه دارای یک پردازنده 8 بیتی است که طول دستورات آن ثابت و به
صورت 8 بیتی میباشد. قالب دستورات این پردازنده در شکل 3-1 نمایش داده شده است.
شکل 3-1: قالب دستوالعمل
همانطور که ملاحظه میشود با توجه به 5 بیتی بودن فیلد آدرس، بنابراین
حداکثر حافظهای که به این کامپیوتر متصل میشود یک حافظه 32 بایتی است. لیست دستورالعملهای
این کامپیوتر در شکل 3-2 ارائه شده است:
شکل 3-2: لیست دستورالعملهای
کامپیوتر پایه به همراه Op-Code آنها
همانطور که در لیست دستورات ملاحظه میگردد، پردازنده دارای دستورات خاص
برای I/O نمیباشد.
و I/O آن
به صورت نقشه حافظه (Memory Map) میباشد. آدرسهای 1D و 1E به ترتیب به پورت خروجی و پورت ورودی مپ شده اند(یعنی اینکه اگر
در آدرس 1D عملیات نوشتن انجام شود، به
جای اینکه در حافظه نوشته شود در پورت خروجی نوشته میشود و اگر پردازنده از آدرس 1E بخواند، به جای اینکه محتویات حافظه خوانده شود، پورت ورودی
خوانده میشود)
در شکل 3-3 کامپیوتر پایه، از دیدگاه ورودی/ خروجی نمایش داده شده است.
همانطور که ملاحظه میشود این کامپیوتر دارای یک پورت ورودی و یک پورت خروجی است و
سیگنال کلاک و سیگنال ریست نیز از ورودیهای این کامپیوتر هستند. برای شروع به کار
این کامپیوتر باید پایه ریست حداقل به مدت یک پالس ساعت فعال(Active High) شود
به محض غیر فعال شدن پایه ریست، برنامه از آدرس صفر حافظه شروع به اجرا میشود.
برنامه در صورت نیاز به گرفتن ورودی، از پورت InPort داده را
دریافت میکند و خروجی برنامه روی پورت OutPort ظاهر میگردد. بخش حافظه این کامپیوتر
نیز در داخل خود ماجول CPU_Top میباشد که در قسمت بعدی توضیح داده خواهد شد.
شکل 3-3: ورودی/خروجیهای
کامپیوتر پایه
ورودیهای و خروجیهای حافظه استفاده شده در کامپیوتر پایه در شکل 3-4
نمایش داده شده است.
شکل 3-4: ورودیها و خروجیهای
حافظه کامپیوتر پایه
همانگونه که ملاحظه میکنید، خطوط دیتای ورودی و خروجی در این حافظه
مستقل از همدیگر و به صورت یک طرفه هستند(بر خلاف حافظههای معمول که خطوط دیتا به
صورت دو طرفه ورودی/خروجی هستند).
برنامه VHDL برای توصیف یک حافظهRAM
32 کلمهای که هر کلمه آن 8 بیتی است:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE
ieee.std_logic_unsigned.all;
entity RAM32x8Bits is
Port (
Addr :
in STD_LOGIC_VECTOR(4 downto 0);
Clk :
in STD_LOGIC;
Rd :
in STD_LOGIC;
Wr : in
STD_LOGIC;
Din :
in STD_LOGIC_VECTOR (7 downto 0);
DOut :
out STD_LOGIC_VECTOR (7 downto 0)
);
end RAM8x8Bits;
architecture Behavioral of
RAM8x8Bits is
Subtype RAM_WORD is
std_logic_vector(8 downto 0) ;
Type RAM_TABLE is array ( 0
to 31) of RAM_WORD;
signal RAM: RAM_TABLE :=
(
x"1e",
x"C0", x"3D", x"40", x"00",
x"00", x"00", x"77",
x"88",
x"99", x"aa", x"bb", x"cc",
x"dd", x"ee", x"ff",
x"AA",
x"11", x"22", x"33", x"44",
x"55", x"66", x"77",
x"88",
x"99", x"aa", x"bb", x"cc",
x"dd", x"ee", x"ff" );
Begin
DOut <= RAM(conv_integer
( Addr ));
process(Clk)
begin
if(Clk='1' and
Clk'event)then
if(Wr='1')then
RAM(conv_integer
( Addr ))<= Din;
end if;
end if;
end process;
end Behavioral;
1-
همانطور که در برنامه مربوط به حافظه ملاحظه میگردد، حافظه
دارای مقدار اولیه به صورت زیر میباشد
signal RAM: RAM_TABLE :=
(
x"1e", x"C0",
x"3D", x"40", x"00", x"00",
x"00", x"77",
x"88", x"99",
x"aa", x"bb", x"cc", x"dd",
x"ee", x"ff",
x"AA", x"11",
x"22", x"33", x"44", x"55",
x"66", x"77",
x"88", x"99",
x"aa", x"bb", x"cc", x"dd",
x"ee", x"ff" );
اگر محتویات حافظه حاوی برنامهای
از کامپیوتر پایه باشد آنگاه با استفاده از شکل 3-2، مشخص کنید این برنامه چه کاری
انجام میدهد(استخراج چهار دستور اول کفایت میکند).
2-
یک پروژه در ISE ایجاد کنید سپس برنامه حافظه را وارد کنید و با نوشتن یک تست بنچ،
عملکرد حافظه را شبیهسازی کنید. در تست بنچ عملهای زیر انجام شود: الف) خواندن
آدرسهای 0، 1 ،2 و 3 حافظه. ب) نوشتن در آدرس 0 حافظه. ج) خواندن از آدرس 0 و 1
حافظه. (با بررسی شکل موجها از صحت عملکرد حافظه اطمینان حاصل کنید)
3-
با استفاده از شکل 3-1 و 3-2، کد زبان ماشین برنامهای را
استخراج کنید که در یک حلقه بینهایت پورت ورودی را بخواند، سپس پنج واحد به آن
اضافه کند و نهایتا در پورت خروجی بنویسد.
4-
برنامه کامپیوتر پایه را از استاد آزمایشگاه تحویل بگیرید
سپس یک تست بنچ برای برنامه CPU_Top ایجاد کنید و با وارد کردن کدهای زبان ماشین قسمت 1، در بلوک
حافظه آن، کامپیوتر را شبیهسازی کنید و از صحت برنامه خود اطمینان حاصل کنید.
5-
برنامهای بنویسید که عددی را از پورت ورودی دریافت کند و
مکمل دو آن را محاسبه و نتیجه را روی پورت OutPort بریزد.
در آزمایش قبلی، کامپیوتر پایه را با استفاده از شبیهساز ISIM شبیهسازی کردید. هدف آزمایش چهارم این است که کامپیوتر را روی یک بورد FPGA پیادهسازی کنید و به صورت عملی نتیجه اجرای برنامه نوشته شده را روی پورت
خروجی مشاهده نمایید.
4-1-1 معرفی بورد FPGA موجود در
آزمایشگاه
نمای کلی از بورد PosEdge موجود در آزمایشگاه در شکل 4-1 نمایش داده شده است. برای پیادهسازی
کامپیوتر پایه، از کلیدهای فشاری، دیپ سوئیچها و LEDهایی که روی بورد است برای ورودیها و خروجیهای کامپیوتر
استفاده شده است. از کلیدهای فشاری برای ریست کردن کامپیوتر و دادن کلاک، از دیپ
سوئیچ به عنوان پورت ورودی(اعمال یک عدد هشت بیتی مبنای 2) و از LEDها به عنوان پورت خروجی استفاده شده است. تراشه FPGA استفاده شده
در این بورد از خانواده Spartan6 است.
شکل 4-1: نمای کلی از بورد پازج
در جلسه قبل کامپیوتر پایه شبیهسازی شد و از صحت عملکرد آن اطمینان حاصل
شد. برای اینکه کامپیوتر پایه را روی بورد تست کنید لازم است مراحل سنتز و پیادهسازی
انجام شود.
برای سنتز و پیادهسازی برنامه VHDL، نرم افزارهای مختلفی وجود دارد. با
توجه به اینکه در طراحی بوردهای آزمایشگاه، از FPGAهای شرکت Xilinx استفاده شده است بنابراین از نرم افزار تولید شده شرکت زایلینکس
برای سنتز و پیادهسازی کدهای VHDL نوشته شده استفاده میکنیم. در شکل 4-2، شکل ظاهر این نرم افزار
نمایش داده شده است. در این شکل، قسمتهای مختلف این نرم افزار مشخص شدهاند.
هنگام ایجاد یک پروژه جدید در این نرم افزار، باید نام خانواده FPGA، نام قطعه،
نوع بسته بندی انتخاب گردد. مثلا FPGAهای استفاده شده در بوردهای
آزمایشگاه از خانواده Spartan6 هستند و نام قطعه 6SLX9 ونوع
بسته بندی تراشه TQG144 میباشد(تراشه از نوع چهارطرفه و دارای 144 پایه). بعد از اینکه
در این نرم افزار پروژه خود را ایجاد کردید نام تراشه به صورت اختصار در قسمت
فوقانی پنجره مینویسد. تراشهای که در شکل 4-2 استفاده شده است xc6slx9-3tqg144 میباشد
که حاوی تمام اطلاعات تراشه مورد نظر میباشد.
شکل 4-2: قسمتهای مختلف
نرم افزار ISE
بعد از اطمینان از صحت عملکرد مدار(با استفاده از شبیهسازی)، با دابل
کلیک کردن روی گزینه Synthesize، عملیات سنتز شروع میگردد. گزارش مربوط به سنتز کردن را در پنجره
console
(قسمت پایینی پنجره) نمایش میدهد. در صورت موفقیت آمیز بودن عملیات سنتز، میتوان
گام بعدی که پیادهسازی طرح باشد را شروع کرد. برای شروع عملیات پیادهسازی باید
روی گزینه Implement Design دابل کلیک کنید. همانطور که در شکل 4-2 مشاهده میشود عملیات
پیادهسازی از سه گام به نامهای Translate، Map و Place &
Route تشکیل شده است. برای ایجاد فایل نهایی
باید روی گزینه Generate
Programming… دابل کلیک کنید. نتیجه این مرحله،
ایجاد یک فایل با پسوند bit است که باید FPGA روی بورد را با این فایل پراگرام نمود.
برای پراگرام کردن FPGA بورد پازج، دو روش وجود دارد. روش اول استفاده از نرم افزار خاص
منظورهای که برای اینکار نوشته شده است. در صورتی که نسخه ISE استفاده شده
کمتر از 14.7 باشد اجبارا باید از این نرم افزار استفاده شود. روش دوم استفاده از
نرم افزار Impact که جزئی از نرم افزار ISE میباشد. در ادامه نحوه
پراگرام کردن به هر دو روش توضیح داده خواهد شد.
توجه: قبل از پراگرام کردن، باید درایور USB Digilent نصب شده
باشد.
نرم افزار miniSProg را اجرا کنید.
پنجره نمایش داده شده در شکل 4-3 ظاهر خواهد شد. در گام اول، باید مسیر فایل bit را تعیین
کنید(این فایل در فولدر مربوط به پروژه ISE قرار دارد) و در گام دوم، دکمه Write to FPGA را
بزنید، در قسمت مشکی رنگ، پیغام مبنی بر موفقیت آمیز بودن پراگرام کردن نمایش داده
خواهد شد.
شکل 4-3: مراحل پراگرام
کردن با استفاده از نرم افزار miniSProg
برای پراگرام کردن FPGA میتوان مستقیما روی گزینه Configure Target Device دابل
کلیک کرد یا اینکه از نرم افزار Impact استفاده کرد. این نرم افزار جزء مجموعه ISE است و به
صورت اتوماتیک هنگام نصب نرم افزار ISE، نصب میگردد. بعد از اجرای نرم افزار Impact، پنجره نمایش
داده شده در شکل 4-4 ظاهر میشود، در این پنجره روی گزینه Boundary scan دابل
کلیک کنید
شکل 4-4: انتخاب گزینه Boundary Scan
در پنجره ظاهر شده، کلیک راست نموده و گزینه Initialize Chain را
بزنید تا دو تراشه روی بورد که قابل
برنامه ریزی هستند شناسایی شود و شکل 4-6 نمایش داده شود. اگر شکل 4-6 نمایش داده
نشد به این معنا است که اتصالات کابل Jtag بین کامپیوتر و بورد اشکالاتی دارد که باید برطرف کنید. سپس
همانطور که در شکل 4-6 ملاحظه میگردد، روی تراشه xc6slx9 کلیک راست
نموده و گزینه Assign New.. را انتخاب کنید و مسیر فایل bit را که در
پروژه جاری میباشد را انتخاب کنید.
سپس روی تراشه xc6slx9 مجددا کلیک نموده و گزینه Program را انتخاب کنید. اگر برنامه ریزی با
موفقیت انجام شود گزینه Programing
Successful با رنگ آبی نمایش داده میشود.
شکل 4-5: تشخیص اتوماتیک
زنجیره تراشههای قابل برنامه ریزی روی بورد
شکل 4-6: اختصاص فایل Bit برای پراگرام
نمودن
شکل 4-7: پراگرام کردن FPGA روی بورد با
انتخاب گزینه Program
شکل 4-8: موفقیت آمیزبودن
پراگرام
در شکل 4-9، بلوک دیاگرام کامپیوتر پایه نمایش داده شده است. که در ادامه
توضیحات مختصری در مورد هر قسمت داده میشود.
شکل 4-9: بلوک دیاگرام
کامپیوتر پایه
بلوک MemIO: این بخش در برگیرنده حافظه 32 بایتی (حافظه مربوط به برنامه و داده) و بلوک
دیکد کننده آدرس برای پورتهای ورودی و خروجی میباشد.
بلوک DataPath: این بخش در برگیرنده رجیسترها، باس مشترک و ALU کامپیوتر
پایه میباشد.
بلوک ControlUnit: این بخش در برگیرنده واحد کنترل میباشد
بلوک CPU_TOP: این بخش برای اتصال سه بلوک قبلی میباشد.
بلوک IO_Interface: در سخت افزار مربوط به بورد آزمایشگاه، کلیدها و LEDها مستقیما به FPGA متصل نشده اند و به صورت سریال(شیفت رجیستر) به FPGA متصل شده
اند، بلوک IO_Interface وظیفه خواندن وضعیت کلیدها به صورت سریال و تبدیل آنها به موازی
و تحویل آنها به بلوک CPU_Top را دارد. همچنین داده هشت بیتی مربوط به پورت خروجی را از بلوک CPU_Top
دریافت میکند و به صورت سریال برای LEDهای روی بورد ارسال میکند.
بلوک Board_Top: این بلوک برای اتصال بلوکهای IO_Interface و CPU_Top استفاده شده
است.
ساختار فایلهای مربوط به بلوکهای فوق، در پروژه ایجاد شده برای آزمایش
چهارم، در شکل 4-10 نمایش داده شده است. در این پروژه شما فقط به سورس برنامههای
مربوط به MemIO دسترسی خواهید داشت. در آزمایشهای بعدی واحدهای DataPath و ControlUnit را
طراحی خواهید کرد.
شکل 4-10: ساختار فایلهای
مربوط به پروژه آزمایش چهارم
برای تست کامپیوتر پایه روی بورد از کلیدها و LEDهای نمایش داده شده در شکل 4-11 استفاده میشود. همانطور که
در شکل ملاحظه میگردد از کلید فشاری S4 برای کلاک دادن دستی به کامپیوتر استفاده میشود. کلید S4 فشرده و به
مدت سه ثانیه نگه داشته شود به صورت اتوماتیک کلاک به پردازنده اعمال خواهد
شد(کلاک با فرکانس 1هرتز). در صورتی که فشردن کلید
به درستی انجام پذیرفته باشد، دو عدد نمایشگر هفت قسمتی سمت چپ خاموش میشوند و دو
عدد نمایشگر هفت قسمتی سمت راست، تعداد لبههای بالارونده را نمایش میدهند. یک
دیپ سوئیچ هشتتایی به عنوان پورت ورودی استفاده شده است که صفر یا یک بودن آن روی
شکل نمایش داده شده است. کلید فشاری S1 برای ریست کردن کامپیوتر استفاده شده است که جایگاه آن در شکل 4-11
مشخص شده است. از LEDهای شماره 0 تا 7 نیز به
عنوان پورت خروجی استفاده شده است.
شکل 4-11: کلیدها و LEDهای استفاده شده برای تست کامپیوتر پایه
1-
پروژه مربوط به این آزمایش را از مربی آزمایشگاه تحویل
بگیرید سپس بررسی کنید که برنامه موجود در حافظه این کامپیوتر چه کاری انجام میدهد.
(با توجه به راهنمایی انجام شده در شکل 4-10، فایل مربوط به حافظه کامپیوتر پایه
را باز کنید).
2-
پروژه فوق را سنتز و ایمپلیمنت کنید و فایل Bit را تولید
کنید.
3-
بورد آزمایشگاه را تحویل بگیرید سپس با راهنمایی مربی
آزمایشگاه، آن را با استفاده از فایل Bit بدست آمده از مرحله قبل پراگرام کنید.
4-
با استفاده از دیپ سوئیچ روی بورد، عدد 11001111 را به پورت ورودی اعمال کنید. سپس با استفاده از کلید ریست و کلید
کلاک روی بورد، ابتدا کامپیوتر پایه را ریست کنید سپس با فشردن کلید کلاک، دستورات
را اجرا کنید. آیا نتیجه صحیح روی LEDها ظاهر شد؟ با تغییر عدد
ورودی و اجرای مجدد برنامه، از صحت اجرای برنامه اطمینان حاصل کنید.
5-
برنامهای برای کامپیوتر پایه بنویسید که عددی را از ورودی
دریافت کند و با 1 جمع بزند و نتیجه را روی پورت خروجی بفرستد. کدهای ماشین مربوط
به این برنامه را در حافظه کامپیوتر پایه وارد کنید سپس پروژه را مجدد سنتز و
ایمپلیمنت کنید و برنامه را روی بورد تست کنید.
6-
برنامهای برای کامپیوتر پایه بنویسید که عددی را از ورودی
دریافت کند یک واحد از آن کم کند و نتیجه را روی پورت خروجی بفرستد. کدهای ماشین
مربوط به این برنامه را در حافظه کامپیوتر پایه وارد کنید سپس پروژه را مجدد سنتز
و ایمپلیمنت کنید و برنامه را روی بورد تست کنید.
در جلسه قبل، کامپیوتر پایه را روی بورد پیادهسازی و به صورت عملی نتیجه
اجرای برنامه را مشاهده کردید. البته به سورس برنامهها دسترسی نداشتید و فقط به
سورس بخش MemIO دسترسی داشتید تا بتوانید برای کامپیوتر پایه برنامه نویسی کنید.
از این جلسه به بعد به نوشتن برنامه VHDL قسمتهای مختلف کامپیوتر پایه پرداخته میشود. در
هر جلسه یک بخشی از کامپیوتر پایه کد نویسی و شبیهسازی میگردد و برای تست عملی
آن قسمت روی بورد، توسط مربی آزمایشگاه پروژهای در اختیار شما قرار داده میشود
که کلیه قسمتهای کامپیوتر پایه را دارد بجز بخشی که مربوط به آن جلسه است. سپ
برنامه نوشته شده در آن جلسه را کنار آن میگذارید و عملیات سنتز و ایمپلیمنت را
انجام خواهید داد.
در این جلسه ساختار DataPath کامپیوتر پایه (رجیسترها و ساختار باس) ارائه خواهد شد. سپس نحوه پیادهسازی
رجیستر و باس مشترک در زبان VHDL بررسی خواهند شد.
ساختار DataPath کامپیوتر پایه در شکل 5-1 نمایش داده شده است. همانطور که ملاحظه میشود
این کامپیوتر دارای 4 رجیستر هشت بیتی است که با حافظه و ALU با استفاده
از یک باس مشترک به یکدیگر متصل شده اند. رجیسترهای AR و PC با وجود
اینکه هشت بیتی هستند ولی فقط از 5 بیت کم ارزش آنها استفاده میشود.
شکل 5-1: ساختار DataPath
کامپیوتر پایه
5-1-2 جایگاه بلوک DataPath در کامپیوتر
پایه و ورودی/خروجیهای آن
در شکل 5-2، جایگاه بلوک DataPath در کامپیوتر پایه نمایش داده شده است. این بلوک با بلوکهای MemIO و ControlUnit در
ارتباط است. همچنین در شکل 5-3 ورودیها و خروجیهای این بلوک نمایش داده شده است.
شکل 5-2: بلوک دیاگرام
کامپیوتر پایه و جایگاه بلوک DataPath
|
|
|
شکل 5-3: ورودیها و خروجیهای
بلوک DataPath
|
بلوک DataPath از زیربلوکهای ALU، BUS8 و چهارعدد رجیستر 8 بیتی تشکیل شده است. در این آزمایش زیربلوکهای
BUS8 و
رجیستر هشت بیتی را پیادهسازی خواهیم کرد. در شکل 5-4 اجزاء داخلی بلوک DataPath و
ارتباطات آنها با یکدیگر نمایش داده شده است.
شکل 5-4: اجزاء داخلی بلوک DataPath
در شکل 5-5، باس مشترک استفاده شده در کامپیوتر پایه نمایش داده شده است.
یکی از روشهای ایجاد باس مشترک، استفاده از مالتی پلکسر میباشد. در زبان VHDL برای پیادهسازی
مالتی پلکسر میتوان از دستور انتساب شرطی استفاده کرد. در قطعه برنامه زیر نحوه پیادهسازی
یک مالتی پلکسر 4x1 با زبان VHDL نمایش داده
شده است:
Outp <= I0 when Sel=”00”else
I1 when Sel=”01”else
I2 when Sel=”10”else
I3 ;
ساختار باس مشترکی که در کامپیوتر پایه استفاده میشود در شکل 5-5 نمایش
داده شده است. در آزمایشگاه ماجولی به نام Bus8 ایجاد کنید و برنامه آن را بنویسید.
شکل 5-5: ورودی و خروجیهای
یک باس مشترک
مدارهای ترتیبی در زبان VHDL را با مفهومی به نام process پیادهسازی میکنند. ساختار کلی Process به
صورت زیر است:
Process(Clk)
Begin
If(Clk=’1’ and Clk’event)then
End if;
End process;
دستور if که در process فوق به کار برده شده است، بیانگر این است که دستورات داخل بدنه if زمانی اجرا
شود که لبه بالارونده کلاک رخ دهد. اگر مدار به لبه پایین رونده کلاک حساس باشد آنگاه
دستور Clk=’1’ باید به دستور Clk=’0’ تبدیل شود.
دستورات داخل Process به صورت ترتیبی اجرا میشوند. در ادامه نحوه پیادهسازی دو مدار
ترتیبی که برای پیادهسازی کامپیوتر پایه مورد نیاز است آورده میشود
رجیسترهایی که در کامپیوتر پایه استفاده میشوند دارای مشخصات زیر هستند:
حساس به لبه بالارونده، دارای قابلیت loadشدن، دارای قابلیت Increament، و
دارای قابلیت Clear شدن.
Entity مربوط به رجیستر هشت بیت را میتوان به صورت شکل 5-6 در نظر گرفت:
شکل 5-6: ورودی و خروجیهای
یک رجیستر 8 بیتی
کد مربوط به رجیستر هشت
بیتی
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_UNSIGNED.ALL;
entity reg8bits is
Port (
Clk : in STD_LOGIC;
Rst : in STD_LOGIC;
LD : in STD_LOGIC;
Inc : in STD_LOGIC;
Din : in
STD_LOGIC_VECTOR(7 downto 0);
Dout : out
STD_LOGIC_VECTOR(7 downto 0)
);
end reg8bits;
architecture Behavioral of reg8bitsis
signal Dout_sig: STD_LOGIC_VECTOR(7
downto 0);
begin
Dout <= Dout_sig;
process(Clk)
begin
if(Clk='1' and
Clk'event)then
if(Rst='1')then
Dout_sig<=(others=>'0');
elsif(LD='1')then
Dout_sig<=
Din;
elsif(Inc='1')then
Dout_sig<=
Dout_sig+1;
end if;
end if;
end process;
end Behavioral;
نکته
1: در برنامه فوق، اولویت با Rst سپس با LD ونهایتا با Inc در نظر گرفته شده است. یعنی اگر همزمان این سه پایه با همدیگر
فعال شدند اولویت به Rst داده میشود.
نکته
2: با توجه به اینکه سیگنال Dout خروجی است نمیتوان برای افزایش آن از دستور Dout <= Dout +1; استفاده
کرد، به همین دلیل یک سیگنال 8 بیتی به نام Dout_sig تعریف شده
است که عملیات روی آن انجام میشود و نهایتا با استفاده از دستور Dout <= Dout_sig مقدار
آن به خروجی انتساب داده میشود.
1-
ماژول نمایش داده شده در شکل 5-5 را طراحی کنید. نام پورتها
را دقیقا مشابه شکل 5-5 قرار دهید. سپس با نوشتن یک تست بنچ، عملکرد این ماژول را شبیهسازی
کنید.
2-
ماژول نمایش داده شده در شکل 5-6 را طراحی کنید. نام پورتها
را دقیقا مشابه شکل 5-6 قرار دهید. سپس با نوشتن یک تست بنچ، عملکرد این ماژول را شبیهسازی
کنید.
3-
پروژه مربوط به آزمایش 5 را از مربی آزمایشگاه تحویل بگیرید
و فایلهای Bus8 و reg8bits (فایلهای مربوط به سوال 1 و سوال 2) را به آن اضافه کنید. سپس
پروژه را ایمپلیمنت کنید.
4-
برنامه Impact را اجرا کنید و بورد را با فایل Bit تولید شده در
قسمت قبل پراگرام کنید سپس با اعمال کلاک به صورت دستی از صحت عملکرد کامپیوتر پایه
اطمینان حاصل کنید.
5-
برنامهای بنویسید که عددی را از پورت ورودی دریافت کند و
مکمل دو آن را محاسبه و نتیجه را روی LEDهای بورد نمایش دهد.
در جلسه قبل بخش DataPath کامپیوتر پایه معرفی گردید، همانطور که در شکل 5-1 مشاهده گردید، ALU به عنوان یکی
از بخشهایی از پردازنده است که به باس مشترک متصل شده است. نقش ALU در پردازنده
انجام عملیاتهای محاسباتی و منطقی میباشد. در شکل 6-1 لیست دستورات کامپیوتر پایه
آورده شده است. عملیات AND، ADD، NOT و SHR توسط ALU انجام خواهد شد.
شکل 6-1: لیست دستورات
کامپیوتر پایه
در شکل 6-2 جایگاه ALU در کامپیوتر پایه مشخص شده است. همانطور که ملاحظه میگردد این
بلوک در داخل DataPath قرار دارد و پورتهای ورودی/خروجی آن در شکل 6-3 نمایش داده شده
است.
شکل 6-2: بلوک دیاگرام
کامپیوتر پایه و جایگاه بلوک DataPath
|
شکل 6-3: ورودیها و خروجیهای
ALU
|
در شکل 6-4 ساختار داخلی بلوک ALU نمایش داده شده است. همانطور که
ملاحظه میگردد در ورودی ALU دو رجیستر 8 بیتی وجود دارد که عملوندها باید در آنها
ذخیره شوند. سیگنال load این دو رجیستر از بیرون قابل دسترس است و واحد کنترل در زمان
مناسب آنها را فعال خواهد کرد. سیگنال دو بیتی Control_Cmd برای تعیین
عملیات استفاده شده است که نحوه کد کردن 4 حالت آن در جدول نمایش داده شده است.
نتیجه محاسبات انجام شده توسط ALU روی سیگنال AluOut ظاهر میشود. علاوه بر این خروجی، سه فلگ نیز توسط بلوک ALU مقدار دهی میشوند.
بیتهای رقم نقلی، بیت علامت و بیتی برای مشخص کردن اینکه آیا نتیجه محاسبات ALU صفر شده است
یا خیر؟
شکل 6-4: ساختار داخلی بلوک
ALU
عملگر &، در VHDL برای اتصال
دو سیگنال استفاده میشود. مثلا اگر فرض کنید سیگنالهای a و b هر دو
چهاربیتی باشند و بخواهید آنها را به همدیگر متصل و یک سیگنال هشت بیتی تولید
کنید دستور زیر را میتوان به کار برد
C <= a & b;
از این عملگر میتوان برای پیادهسازی شیفت نیز استفاده کرد. به عنوان
مثال اگر سیگنال a هشت بیتی باشد و بخواهید یک بیت به سمت راست شیفت دهید، دستور زیر
این عملیات را انجام خواهد داد:
S <= ‘0’ & a(7 downto 0);
از عملگر NOT برای بدست آوردن مکمل یک میتوان استفاده کرد. به عنوان مثال در
دستور زیر مکمل سیگنال هشت بیتی a محاسبه و به سیگنال b انتساب داده میشود.
C <= not a(7 downto 0);
برای پیادهسازی قسمت ALU، با توجه به شکل 6-4، نیاز به تعریف شش عدد Entity دارید که
عبارتند از:
الف) یک Entity برای جمع دو عدد 8 بیتی (در آزمایش 2، مشابه این کار انجام شده
است)
ب) یک Entity برای and دو عدد 8 بیتی
ج) یک Entity برای NOT کردن یک عدد 8 بیتی
د) یک Entity برای شیفت به راست یک عدد 8 بیتی
ه) یک Entity برای مالتی
پلکسر 4x1 (در آزمایش 5، مشابه این کار
انجام شده است)
و)یک Entity برای رجیستر هشت بیتی(در آزمایش 5، مشابه این کار انجام شده است)
ز)یک Entity برای خود ALU (مطابق با پورتهای نمایش داده شده در شکل 6-3)
1- برنامه
VHDL
مربوط به موارد الف تا و را بنویسید و شبیهسازی کنید.
2- یک Entity به
نام ALU
بنویسید و پورتهای آن را هم نام با پورتهای شکل 6-3 قرار دهید، سپس طبق شکل 6-4،
از ماجولهای نوشته شده در سوال 1، پورت مپ کنید تا ALU ایجاد شود
3- برای
مقدار دهی سیگنال سه بیتی Alu_Fgags دستورات زیر را به برنامه قسمت قبل اضافه کنید:
ALU_Flags(0)<= Carry_Out;
--این
سیگنال از خروجی جمع کننده میآید
ALU_Flags(1)<=
MUX_OUT(7);-- بیت آخر خروجی مالتی پلکسر
ALU_Flags(2)<= '1' when MUX_OUT(7
downto 0)="00000000" else '0';
4-
پروژه مربوط به آزمایش 6 را از مربی آزمایشگاه تحویل بگیرید
و هفت برنامه نوشته شده در قسمتهای قبل را به آن اضافه کنید. سپس پروژه را ایمپلیمنت
کنید.(برنامه Bus8 را که در آزمایش 5 نوشته اید را هم اضافه کنید)
5-
برنامه Impact را اجرا کنید و بورد را با فایل Bit تولید شده در
قسمت قبل پراگرام کنید سپس با اعمال کلاک به صورت دستی از صحت عملکرد کامپیوتر پایه
اطمینان حاصل کنید(برنامه موجود در حافظه، عدد ورودی را مکمل میکند و روی پورت
خروجی میریزد).(تست انجام عملیات مکمل سازی توسط ALU)
برای تست عملی ALU، کد ماشین
برنامههای زیر را استخراج کنید و در سه مراحله مجزا دستورات AND، ADD و SHR را روی بورد
تست کنید.
6-
برنامهای بنویسید که چهار بیت کم ارزش عدد ورودی را صفر
کند(با استفاده از AND کردن عدد با F0) و روی پورت خروجی بریزد(تست انجام عملیات AND توسط ALU)
7-
برنامهای بنویسید که عدد ورودی را با 5 جمع کند و روی پورت
خروجی بریزد(تست انجام عملیات جمع توسط ALU)
8-
برنامهای بنویسد که عدد ورودی را دو بیت به سمت راست شیفت
دهد(تست انجام عملیات شیفت توسط ALU).
در آزمایش قبل، با پیادهسازی ALU، بخش DataPath از کامپیوتر
پایه تکمیل گردید. تنها قسمتی از کامپیوتر پایه که باقی مانده است واحد کنترل آن میباشد.
در این آزمایش و آزمایش بعدی به طراحی واحد کنترل به صورت سخت افزاری پرداخته میشود.
در شکل 7-1 جایگاه واحد کنترل در کامپیوتر پایه مشخص شده است. همانطور که
ملاحظه میگردد این بلوک در کنار بلوکهای DataPath و MemIO قرار دارد. پورتهای
ورودی/خروجی آن در شکل 7-2 نمایش داده شده است.
شکل 7-1: بلوک دیاگرام
کامپیوتر پایه و جایگاه واحد کنترل
|
شکل 7-2: ورودیها و خروجیهای
واحد کنترل
|
همانطور که در شکل 7-2 مشاهده میشود. همه ورودیهای واحدکنترل بجز Clk و Rst از بلوک DataPath میآیند و خروجیهای آن به واحدهای DataPath و MemIO میروند. خروجیهای این واحد عبارتند از: خطوط انتخاب باس مشترک، فرامین ALU، پایه لود
رجیسترهای ALU، پایههای لود، ریست رجیسترهای کامپیوتر پایه، خطوط خواندن و
نوشتن در حافظه و سیگنال ریست Sequence
Counter میباشد.
وظیفه واحد کنترل، دریافت سیگنالهای وضعیت از واحد Data_path و
تولید سیگنالهای کنترلی برای آن واحد و واحد MemIO میباشد. سیگنالهایی که واحد کنترل دریافت میکند عبارتند از: ALU_flags(سه
بیت مربوط به رقم نقلی، بیت علامت و صفربودن نتیجه ALU) و رجیستر IR . بلاک
دیاگرام داخلی واحد کنترل در شکل 7-3 نمایش داده شده است. اجزای تشکیل دهنده واحد
کنترل عبارتند از:
دیکدر 3x8(DEC3x8): وظیفه این دیکدر، دریافت
سه بیت پرارزش رجیستر IR، (کد دستورالعمل) و تولید 8 خروجی برای تفکیک نوع دستورالعمل
شمارنده 4 بیتی(Counter4Bits): وظیفه این شمارنده، شمارش اعداد 0 تا 15 است. خروجی این بلوک به یک
دیکدر 4x16 داده میشود تا سیگنالهای
زمانبندی(T0, T1,T2,… T15) را تولید کند.
دیکدر 4x16(DEC4x16): وظیفه این دیکدر، تولید سیگنالهای
زمانبندی است و سیگنالهای زمانبندی(T0, T1,T2,… T15) را
تولید کند.
بلوک CreateControlSig: این بلوک خروجی دیکدر دستورالعمل و سیگنالهای زمانبندی را دریافت میکند
و یک واحد کنترل سخت افزاری را پیادهسازی میکند.
در این آزمایش، سه بلوک اول پیادهسازی میشوند و در آزمایش بعدی بلوک CreateControlSig پیادهسازی خواهد شد.
شکل 7-3: دیاگرام داخلی
واحد کنترل
با توجه به اینکه شمارنده یک مدار ترتیبی است بنابراین برای نوشتن کد آن،
نیاز به یک Process میباشد. بلاک دیاگرام یک شمارنده 4 بیتی در شکل
7-4 نمایش داده شده است.
شکل 7-4: ورودی و خروجیهای
یک شمارنده 4 بیتی
کد مربوط به یک شمارنده 4 بیتی
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_UNSIGNED.ALL;
entity Counter4Bits is
Port (
Clk : in STD_LOGIC;
Rst : in STD_LOGIC;
Inc : in STD_LOGIC;
Dout : out
STD_LOGIC_VECTOR(3 downto 0)
);
end Counter4Bits;
architecture Behavioral of
Counter4Bits is
signal Dout_sig: STD_LOGIC_VECTOR(3
downto 0);
begin
Dout <= Dout_sig;
process(Clk)
begin
if(Clk='1' and
Clk'event)then
if(Rst='1')then
Dout_sig<=(others=>'0');
elsif(Inc='1')then
Dout_sig<=
Dout_sig+1;
end if;
end if;
end process;
end Behavioral;
با توجه به ایتکه دیکدر،
جزء مدارهای ترکیبی میباشد بنابراین برای پیادهسازی آن میتوان از دستور when استفاده کرد.
در ادامه کد یک دیکد 3x8 نمایش داده
شده است. این دیکدر بدون پایه فعال ساز میباشد:
Outp<= "00000001" when
Inp="000" else
"00000010" when
Inp="001" else
"00000100" when
Inp="010" else
"00001000" when
Inp="011" else
"00010000" when
Inp="100" else
"00100000" when
Inp="101" else
"01000000" when
Inp="110" else
"10000000" ;
1-
ماژول دیکدر 3x8 را
بر اساس پورتهای نشان داده شده در شکل 7-3 طراحی کنید و برای آن تست بنچ بنویسید
و شبیهسازی کنید. نام پورتها را دقیقا مشابه شکل 7-3 قرار دهید.
2-
ماژول دیکدر 4x16 را
بر اساس پورتهای نشان داده شده در شکل 7-3 طراحی کنید و برای آن تست بنچ بنویسید
و شبیهسازی کنید. نام پورتها را دقیقا مشابه شکل 7-3 قرار دهید.
3- ماژول
دیکدر Counter4Bits را بر اساس پورتهای نشان داده شده در شکل 7-3 طراحی کنید و برای آن تست
بنچ بنویسید و شبیهسازی کنید. نام پورتها را دقیقا مشابه شکل 7-3 قرار دهید.
4-
پروژه مربوط به آزمایش 7 را از مربی آزمایشگاه تحویل بگیرید،
در این پروژه سه فایل که درشکل زیر نمایش داده شده است وجود ندارد.
فایلهای DEC3x8، DEC4x16 و Counter4Bits را به آن اضافه کنید(فایلهایی را که برای سوال 1، 2 و 3 نوشته
اید) را به آن اضافه کنید. سپس پروژه را ایمپلیمنت کنید.
برنامه Impact را اجرا کنید
و بورد را با فایل Bit تولید شده در قسمت قبل پراگرام کنید سپس با اعمال کلاک به صورت دستی از
صحت عملکرد کامپیوتر پایه اطمینان حاصل کنید.
در آزمایش قبل، بیان گردید که واحد کنترل از چهار بخش تشکیل شده است. در
آزمایش هفتم، سه بخش از واحد کنترل پیادهسازی گردید. برای اینکه واحد کنترل تکمیل
شود باید بخش CreateControlSig نیز تکمیل شود. در شکل 8-1 بخشهای واحد کنترل و قسمتهایی که تکمیل
شدهاند مشخص گردیدهاند. در این آزمایش، قسمتهایی از بخش CreateControlSig
تکمیل میشود.
شکل 8-1: دیاگرام داخلی
واحد کنترل
سیکل اجرای دستورات در کامپیوتر پایه به صورت زیر است:
1-
برداشت دستور از حافظه
2-
دیکد دستور
3-
اجرای دستور
برای ایجاد این توالی از پالسهای ساعت T0، T1 و
... استفاده میشود.
در اولین مرحله، در سیکل T0، باید رجیستر AR با رجیستر PC مقدار دهی و سیگنال Mem_Rd فعال شود. برای اینکار باید، مقدار PC روی باس
مشترک گذاشته شود(یعنی Bus_sel=”010” شود) و سیگنال LD_AR فعال شود.
T0: ARçPC, Mem_Rdç 1
اگر بخواهیم دقیقتر بنویسیم، در T0 باید عملیات
زیر انجام شود:
T0: LD_ARç1, Bus_selç”010” , Mem_Rdç 1
در سیکل T1،
حافظه محتویات مربوط به آدرس داده شده را آماده کرده است بنابراین محتویات حافظه
باید روی باس مشترک قرار گیرد و LD_IR فعال شود تا دستور خوانده شده در رجیستر IR ذخیره شود.
همچنین مقدار PC یک واحد افزایش یابد(برای دستور بعدی آماده شود).
T1: IRçMem[AR], Inc_PCç 1
اگر بخواهیم دقیقتر بنویسیم، در T1 باید عملیات
زیر انجام شود:
T1: LD_IR ç1, Bus_selç”000” , Inc_PCç 1
با توجه به مطالب فوق میتوان نتیجه گرفت که بعد از T0 و T1،
مرحله واکشی دستورالعمل به پایان رسیده است و دستورالعمل در رجیستر IR قرار گرفته
است.
در سیکل T2 عملیات دیکد کردن دستور انجام میگیرد و واحد کنترل هیچ سیگنالی
را فعال نمیکند. از سیکل T3 به بعد اجرای دستور دیکد شده شروع خواهد شد.
در این آزمایش فرض میکنیم کامپیوتر پایه فقط دو دستور LD و ST را دارد و
واحد کنترل را برای طراحی میکنیم.
ریزعملهای مورد نیاز برای اجرای دستور LDبه صورت زیر خواهد بود:
LD
A,[Addr]
T3D0 :
ARçIR[4 … 0], Mem_Rdç1
T4D0 :
AC çMem[AR] , Clr_SCç1
ریزعملهای مورد نیاز برای اجرای دستور ST به صورت زیر
خواهد بود:
ST A,[Addr]
T3D1 :
AR çIR[4 … 0]
T4D1 :
Mem[AR]çAC, Clr_SCç1, Mem_Wrç1
در صورتیکه کامپیوتر فقط دستورات فوق را داشته باشد میتوان نتیجه گرفت
که سیگنالهای کنترلی زیر باید توسط واحد کنترل تولید شود و بقیه سیگنالهای
کنترلی باید غیر فعال باشند: Mem_Wr، Mem_Rd، Bus_sel، Inc_PC، LD_AR و Clr_SC.
اگر کلیه ریزعملهای مورد نیاز را به صورت منسجم در نظر بگیریم میتوانیم
رابطه بین خروجیهای واحد کنترل(سیگنالهای ذکر شده در فوق) با ورودیهای واحد
کنترل(سیگنالهای زمانبندی، نتیجه دیکد دستور) را بدست آوریم. اگر کامپیوتر پایه
را فقط با دستورات LD و ST در نظر بگیریم آنگاه کلیه ریزعملهای ممکن را میتوان به صورت شکل
8-2 نوشت.
T0:
ARçPC, Mem_Rdç 1
T1:
IRçMem[AR], Inc_PCç 1
T3D0
: ARçIR[4 … 0], Mem_Rdç1
T4D0
: AC çMem[AR] , Clr_SCç1
T3D1
: AR çIR[4 … 0]
T4D1
: Mem[AR]çAC, Clr_SCç1, Mem_Wrç1
شکل 8-2: لیست ریزعملهای
کامپیوتر پایه اگر فقط دستورات LD و ST داشته باشد
بنابراین میتوان سیگنالهای کنترلی
را به صورت نمایش داده شده در شکل 8-3 نوشت.
Mem_Wr ç T4D1 ;
Mem_Rd ç T0 or T3D0;
Inc_PC ç T1;
LD_AR ç T0 or T3D0 or T3D1;
LD_AC
ç T4D0;
LD_IR ç T1;
Clr_SC ç T4D0 or T4D1;
Bus_sel ç “010” when (T0='1') else --PC
“000”
when (T1='1' or (T4='1' and D0='1') else --Memory
“011”
when (T4='1' and D1='1') else --AC
“100”
when ((T3='1' and D0='1') or (T3='1' and D1='1')
else -- IR
“111”;
-- No thing
شکل 8-3: واحد کنترل سخت
افزاری کامپیوتر پایه اگر فقط دستورات LD و ST داشته باشد
مقادیری که برای انتساب به Bus_Sel
نوشته شده است از آزمایش 5، شکل 5-1 استخراج شدهاند. بقیه سیگنالهای کنترلی را
باید با صفر مقدار دهی کرد.
7-
پروژه مربوط به آزمایش 8 را از مربی آزمایشگاه تحویل
بگیرید(بخش شبیهسازی CPU_PosEdge_Az8_Sim)،
فایل CreateControlSig را باز کنید و مطابق شکل 8-3 سیگنالهای کنترلی را مقدار دهی
کنید.(در شکل 8-4، جایگاه این فایل مشخص شده است)
شکل 8-4: جایگاه فایل CreateControlSig در
پروژه
8-
برنامه موجود در حافظه را بررسی کنید(فایل RAM32x8Bits) این
برنامه چه کاری انجام میدهد؟ با توجه به اینکه در حال حاضر واحد کنترل از تمام
دستورات کامپیوتر پایه پشتیبانی نمیکند اگر برنامه را اجرا کنیم چه اتفاقی میافتد؟
آیا کامپیوتر قفل میکند؟ اگر دستور پرش به ابتدای برنامه وجود نداشته باشد چه
اتفاقی میافتد؟
9-
مراحل نمایش داده شده در شکل 8-5 را انجام دهید تا وارد محیط
شبیهسازی شوید. تست بنچی که برای کامپیوتر پایه نوشته شده است به این صورت است که
سیگنال ریست را به مدت 150 نانو ثانیه فعال میکند و پورت ورودی را با x"AA"
مقدار دهی میکند و کلاک 100مگاهرتز به پردازنده اعمال میکند. مراحل زیر را انجام
دهید:
الف) بعد از اجرا شدن ISIM، سیگنالهای
موجود را حذف کنید
ب) با باز کردن سلسله مراتب فایلهای
سمت چپ، رجیسترهای AC، IR، PC، Mem_Rd، Mem_Wr ، T، D، Bus_sel، Clr_SC، LD_AR، Inc_PC را
به صفحه شبیهسازی اضافهکنید. سپس شبیهسازی کنید و مراحل اجرای برنامه را بررسی
کنید و صحت جوابهایی را که به سوال 2 دادهاید را بررسی کنید.
شکل 8-5: مراحل اجرای ISIM برای شبیهسازی
کامپیوتر پایه
پروژه مربوط به آزمایش 8 را از مربی
آزمایشگاه تحویل بگیرید(بخش پیادهسازی CPU_PosEdge_Az8_Imp)،
فایل CreateControlSig را باز کنید و مطابق سوال 1، این برنامه را تکمیل کنید سپس پروژه
را ایمپلیمنت کنید و بورد را پراگرام کنید آیا نتیجه اجرای برنامه قابل انتظار
است؟
در دو آزمایش قبل، بخشهایی از واحد کنترل طراحی گردید به صورتی که فقط از
دو دستور LD و ST پشتیبانی میکرد.
در این آزمایش بخش CreateControlSig به صورت کامل تکمیل شود. در شکل 9-1 بخشهای واحد کنترل و قسمتهایی
که تکمیل شدهاند مشخص گردیدهاند.
شکل 9-1: دیاگرام داخلی
واحد کنترل
شکل 9-2: لیست دستورالعملهای
کامپیوتر پایه به همراه Op-Code آنها
در شکل 9-3 کلیه ریزعملهای مورد نیاز برای واکشی دستورالعمل و اجرای هشت
دستور کامپیوتر پایه لیست شده است.
Fetch
T0: ARçPC, Mem_Rdç 1
T1: IRçMem[AR], Inc_PCç 1
LD
A,[Addr]
T3D0 :
ARçIR[4 … 0], Mem_Rdç1
T4D0 :
AC çMem[AR] , Clr_SCç1
ST A,[Addr]
T3D1 :
AR çIR[4 … 0]
T4D1 :
Mem[AR]çAC, Clr_SCç1, Mem_Wrç1
JP Addr
T3D2 :
PCçIR[4 … 0], Clr_SCç1
JPC Addr
T3D3 CFlag:
PCçIR[4 … 0]
T3D3 :
Clr_SCç1
AND A,[Addr]
T3D4 :
ARçIR[4 … 0] , Mem_Rdç1
T4D4 :
ALU_Reg1ç Mem[AR]
T5D4 :
ALU_Reg2ç AC
T6D4 :
ACç ALU_Reg1 & ALU_Reg2, Clr_SCç1
ADD A,[Addr]
T3D5 :
ARçIR[4 … 0] , Mem_Rdç1
T4D5 :
ALU_Reg1ç Mem[AR]
T5D5 :
ALU_Reg2ç AC
T6D5 :
ACç ALU_Reg1 + ALU_Reg2, Clr_SCç1
NOT A
T3D6 :
ALU_Reg1ç AC
T4D6 :
AC ç NOT ALU_Reg1, Clr_SCç1
SHR A
T3D7 :
ALU_Reg1ç AC
T4D7 :
AC ç ALU_Reg1 >> 1, Clr_SCç1
شکل 9-3: لیست کلیه
ریزعملهای کامپیوتر پایه
1- با
توجه به لیست ریزعملهای نمایش داده شده در شکل 9-3، عبارات منطقی برای تولید سیگنالهای
Bus_sel، Control_Cmd، ALU_LD_Reg1، ALU_LD_Reg2، Clr_SC، Inc_AC، Inc_AR، Inc_PC، LD_AC، LD_AR، LD_IR، LD_PC، Mem_Rd، Mem_Wr، Rst_AC، Rst_AR و Rst_PC را
بدست آورید.
10-پروژه مربوط به آزمایش 9 را از مربی
آزمایشگاه تحویل بگیرید(بخش شبیهسازی CPU_PosEdge_Az9_Sim)،
فایل CreateControlSig را باز کنید و با اطلاعاتی که برای پیش گزارش تهیه کرده اید، آن
را تکمیل کنید.
شکل 9-4: جایگاه فایل CreateControlSig در
پروژه
11-برنامه موجود در حافظه را به گونهای
تغییر دهید (فایل RAM32x9Bits) که هشت دستور کامپیوتر پایه به ترتیب در آدرس صفر تا هفت قرار
گیرند. سپس وارد محیط شبیهسازی شوید و با اضافه کردن سیگنالهای ALU_Out، ALU_Flags، Mem_Dout، Mem_Wr، AC ، IR ، D و T دستورات را
یکی یکی اجرا کنید و شکل سیگنالهای فوق را مشاهده کنید و از صحت اجرا مطمئن شوید.
از شکل موج سیگنالها شبیهسازی برای هر دستور عکس بگیرید و در یک فایل Word ذخیره کنید و
به عنوان گزارش تحویل دهید.
12-پروژه مربوط به آزمایش 9 را از مربی
آزمایشگاه تحویل بگیرید(بخش پیادهسازی CPU_PosEdge_Az9_Imp)،
فایل CreateControlSig را باز کنید و مطابق سوال 1، این برنامه را تکمیل کنید سپس برنامهای
در حافظه بنویسید که دو عدد AA و B1 را جمع بزند و روی پورت خروجی نمایش دهد. پروژه را ایمپلیمنت کنید
و بورد را پراگرام کنید و نتیجه را به مربی آزمایشگاه نشان دهید.
در آزمایش قبل کامپیوتر پایه به صورت کامل پیادهسازی و تست گردید. در
این آزمایش قصد داریم تعدادی دستور جدید به کامپیوتر پایه اضافه و تست کنیم.
شکل 10-1: لیست دستورالعملهای
کامپیوتر پایه به همراه Op-Code آنها
2- به
جای دستورهای NOT A و دستور SHR A، دستورهای INC A و JP [Addr] را به کامپیوتر پایه اضافه کنید
3- به
جای دستور JP Addr دستور JPAZ را اضافه کنید(پرش کن در صورتی که مقدار AC=0 باشد).
4- راهکاری
ارائه دهید که کامپیوتر پایه، همه هشت دستور قبلی خود را داشته باشد و از سه دستور
INC A، JP [Addr] و JPAZ هم پشتیبانی
کند(ساختار حافظه و تعداد بیتهای Op-Code تغییری نکند)
13-پروژه مربوط به آزمایش 10 را از مربی
آزمایشگاه تحویل بگیرید، برای سوال 1 پیش گزارش، تغییرات مورد نیاز را در واحد
کنترل اعمال کنید سپس برنامهای در حافظه وارد کنید که اولین دستور برنامه به صورت
غیر مستقیم به آدرس 5 پرش کند و در آنجا پورت ورودی را بخواند و یک واحد افزایش
دهد و روی پورت خروجی بریزد. پروژه را ایمپلیمنت کنید و روی بورد تست کنید.
14-تغییرات مورد نیاز در واحد کنترل را
اعمال کنید تا از دستور JPAZ پشتیبانی کند. سپس برنامهای بنویسید که عددی را از ورودی دریافت
کند و اگر مقدارش صفر بود روی پورت خروجی عدد FF بریزد و در
غیر اینصورت یک واحد افزایش دهد و روی پورت خروجی بریزد.
15-تغییرات مورد نیاز در واحد کنترل را
اعمال کنید تا سوال سوم پیش گزارش را تست کنید. برای تست آن یک برنامه بنویسید و
نتیجه را روی بورد به مربی آزمایشگاه نشان دهید.