سلام

برای این کاری که دارم انجام میدم لازم شد که 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 بود.

 


مشخصات

آخرین ارسال ها

آخرین جستجو ها