مهاجرت به VHDL

ساخت وبلاگ

سلام

برای این کاری که دارم انجام میدم لازم شد که VHDL یاد بگیرم.

شنیده بودم که VHDL خیلی زبون نچسب و بدیه ولی فکر نمیکردم تا این حد بد باشه.

البته در حال بسیار نچسب بودن بسیار قوی و پر از امکاناته.

تو این پست یه نکته هایی که شاید بتونه مهاجرت از Verilog به VHDL رو آسون تر کنه رو مینویسم که خودم زیاد بهش برخورد کردم.

این پست هم خیلی سادس و چیزایی که خودم بلد بودم از درس مدار منطقی رو دارم میگم. خیلی امکانات دیباگ زیادی داره که اصلا نمیدونم که چیا رو نمیدونم. ولی بنظرم یه jump start خیلی خوبه برای کسی که میخواد از وریلاگ کوچ کنه VHDL.

1- ساختار یه ماژول: 

توی وریلاگ همه چیز رو توی یه ماژول مینوشتیم. مثلا از ساییت asic-world:

 1 //----------------------------------------------------- 2 // Design Name : up_counter 3 // File Name : up_counter.v 4 // Function : Up counter 5 // Coder : Deepak 6 //----------------------------------------------------- 7 module up_counter ( 8 out , // Output of the counter 9 enable , // enable for counter 10 clk , // clock Input 11 reset // reset Input 12 ); 13 //----------Output Ports-------------- 14 output [7:0] out; 15 //------------Input Ports-------------- 16 input enable, clk, reset; 17 //------------Internal Variables-------- 18 reg [7:0] out; 19 //-------------Code Starts Here------- 20 always @(posedge clk) 21 if (reset) begin 22 out <= 8'b0 ; 23 end else if (enable) begin 24 out <= out + 1; 25 end 26  27  28 endmodule 

ورودی خروجی ها توی خط اول تعریف شدن و بعدش اومده گفته که چی هستن و چند بیتی هستن و بعدش reg تعریف کرده و بعدشم یه مدار sequential درست کرده که حساس به لبه ی بالا رونده کلاک هست و enable داره.

 

حالا همین مدار تو VHDL 

1 ------------------------------------------------------- 2 -- Design Name : up_counter 3 -- File Name : up_counter.vhd 4 -- Function : Up counter 5 -- Coder : Deepak Kumar Tala (Verilog) 6 -- Translator : Alexander H Pham (VHDL) 7 ------------------------------------------------------- 8 library ieee; 9 use ieee.std_logic_1164.all; 10 use ieee.std_logic_unsigned.all; 11  12 entity up_counter is 13 port ( 14 cout :out std_logic_vector (7 downto 0); -- Output of the counter 15 enable :in std_logic; -- Enable counting 16 clk :in std_logic; -- Input clock 17 reset :in std_logic -- Input reset 18 ); 19 end entity; 20  21 architecture rtl of up_counter is 22 signal count :std_logic_vector (7 downto 0); 23 begin 24 process (clk, reset) begin 25 if (reset = '1') then 26 count <= (others=>'0'); 27 elsif (rising_edge(clk)) then 28 if (enable = '1') then 29 count <= count + 1; 30 end if; 31 end if; 32 end process; 33 cout <= count; 34 end architecture;

همون طور که دیده میشه تو نگاه اول 2-3 برابر بیشتر کد تایپ کردیم. گویا دکتر نوابی که خودش از اونایی بوده که استانداردای VHDL رو در اوردن، به این زبون میگن Verbose یعنی وراج. چون خیلی باید کد زده بشه.

اول کد یه سری لایبرری Add شده. 

این یکی از ویژگی های جالب VHDL هست که باید برای چیزایی که میخواید استفاده کنید حتما لایبرری هاشون رو اضافه کنید. تو یه پست بعدی مثلا یه لایبرری میگم که محاسبات fixed و floating پوینت رو انجام میده. بدون درد سر!

مثلا اینجا چون لازم بوده یه add انجام بشه، لایبرری unsigned logic اضافه شده.

 

تو نگاه دوم! میبینیم که ماژول در واقع یه تیکه نیست، دو تیکه هست. تو بخش اول entity تعریف میشه و تو بخش دوم architecture. 

entity از دو بخش(تا جایی که میدونم) تشکیل میشه. اولیش Generic ها هست و دومیش Port ها هست. Generic ها پارامتر هایی هستن که دیزاینتون با اونا تعریف میشه. مثلا میتونید تعداد بیت های یک رجیستر رو تو اون بگید. موقعی که دارید instance میگیرید از این ماژولتون، میتونید Generic ها رو ست کنید یا اگه کاری نداشته باشید میتونه default value داشته باشه.

بخش دوم Port ها هست که همون ورودی خروجی ها هست. این جا حتما باید سایزشون و تایپشون رو مشخص کنید. چندین روش برای تعریف کردن سایز وجود داره مثلا میتونید تعداد بیت ها رو بگید مثلا 

7 downto 0

یا میتونید range تعریف کنید که از فلان عدد تا فلان عدد باشه. بسته به نوع تایپ چیزی که تعریف میکنید داره. مثلا تو کتابخونه fixed point که میگم بعدا میتونید بگید

7 downto -24

یعنی 7 بیت برای بخش integer و 24 بیت برای بخش fractional.

آها راستی دقت کنید تو لیست ورودی ها، خط آخر ; نداره ! که بسیار آزار دهندس.

 

بریم پایین تر Architecture شروع میشه. آرکیتکچر در واقع نحوه ی کار کرد entity رو میگه. فکر میکنم میتونید چند تا Architecture مختلف تعریف کنید برای شرایط مختلف مثل اون چیزه تو C++

بعد از خط تعریف، باید signal ها رو تعریف کنید.

مفهوم سیگنال برای من خیلی ناراحت کننده بود در قدم اول. بخاطر این که وریلاگ، reg و wire داشت که کاملا کارکردشون مشخص بود ولی VHDL فقط همین signal رو داره که بسته به شرایطی که استفاده میشه، اگه مدار combinational باشه بدون رجیستر و اگه مدار sequential باشه با رجیستر میشه.

 

بعد ازون process رو میبینیم، این یه چیزی تو مایه های always هست تو وریلاگ ولی فکر میکنم مستقیم نمیتونید به posedege مثلا حساسش کنید. به یه سری سیگنال حساسش میکنید و بعد تو شرط ها posedge بودن یه چیزای دیگه رو چک میکنید.

 

بقیش خیلی شبیه وریلاگ هست. فقط باید حواستون باشه مثلا if ها then دارن و elsif درسته نه elseif یا else if(کار دیگه میکنه). و endif; هم داریم. که دقت کنید ; داره.

 

2- تایپ ها

یکی از چیزای بسیار آزار دهنده ولی در عین حال کمکی VHDL اینه که وقتی یه چیزی یه تایپی داره مثلا std_logic_vector که وکتوری از چند بیته، همینجوری نمیتونید توش یه عدد بریزید. باید Cast کنید.

 مثلا 

signal x : std_logic_vector(7 downto 0);

..

x <= 4;

کار نمیکنه چون 4 دسیمال هست.

باید بنویسید

x <= "00000100";

یا مثلا همچین چیزی هم با معنی هست.

x <= (2 => '1', 7 downto 4 => '1', others => '0');

که در نگاه اول بسیار اذیت میکنه. ولی خب در نهایت کمک میکنه سیگنالا اشتباه نشن.

این که keyword های زیادی داره خیلی گیج کنندس ولی کم کم عادت میکنید.

دقت کنید چون بیت بودن اونا توی ' ' قرار گرفتن. اون یکی چون وکتور بود توی " "  بود. اولیه چون عدد بود توی هیچی نبود. 

اگرم میخواید عدد بریزید باید کست کنید دیگه

x <= to_slv(4);

x <= std_logic_vector(4);

فکر کنم جفتشون کار میکنن.

 

3- وصل کردن چیزا.

چیزای مختلف وصل کردنشون به راحتی وریلاگ نیست که چیزای غیر همسایز رو بشه راحت وصل کرد. اگه تعداد بیت ها یکی نباشه باید یه کاریش بکنید مثلا ریسایز کنید

 

4- مدارای combinational و sequential

باید توجه کنید که سینتکس هایی که برای این دوتا استفاده میشه فرق میکنه مثلا 

http://insights.sigasi.com/tech/signal-assignments-vhdl-withselect-whenelse-and-case.html

with a select b <= "1000" when "00", "0100" when "01", "0010" when "10", "0001" when "11";
b <= "1000" when a = "00" else "0100" when a = "01" else "0010" when a = "10" else "0001" when a = "11";

 

 

این دوتا برای مدارای combinational هستن و دستور if رو هم که دیدیم تو اولین مثال.

تقریبا شبیه وریلاگه اونجا هم switch داشتیم و استیتمنت های a?b:c که بیشتر شبیه C بود.

 

لیسانس 4 ساله...
ما را در سایت لیسانس 4 ساله دنبال می کنید

برچسب : نویسنده : cmostfet1 بازدید : 196 تاريخ : دوشنبه 20 اسفند 1397 ساعت: 19:02