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

برای آموزش و یادگیری این زبان نیاز به یک سری اطلاعات از مدار منطقی است.

دو شرکت بزرگ در دنیا به نام های ALTRA و Xilinx تولید کننده ی FPGA هستند.

نرم افزار های شبیه سازی برای این دو شرکت به ترتیب Quartus و Xilinx ISE است.

System Edition کامل ترین نسخه ی نرم افزار ISE است.

یک زبان سخت افزاری دیگر هم به نام Verilog وجود دارد.

منابع زیادی برای یادگیری این زبان سخت افزاری وجود دارد.

FPGA ها معمولا برای پردازش های سریع و بلادرنگ استفاده میشوند.

همزمان بهتر است که دانشی از زبان C و ++C داشته باشید چرا که برای برنامه نویسی MicroBlaze استفاده خواهد شد.

MicroBlaze میکروکنترلری است که درون FPGA به صورت Soft Core قابل پیاده سازی است.

 

نرم افزار های دیگر

Xilinx Embedded Development Kit (EDK)

Xilinx Software Development Kit (SDK)

Xilinx Platform Studio (XPS)

 

امکاناتی در نرم افزار متلب وجود دارد که میتوان با استفاده از ISE از آن ها استفاده کرد

برای شبیه سازی باید در کد Test Bench کلاک حذف شود چون کلاکی وجود ندارد

برای وارد کردن ورودی ها در TB به قسمت insert stimulus باید وارد شد

برای تغییر میتوان از دستور wait for  استفاده کرد.

توضیح انکدر وزن دار (مهم)

نرم افزار ISim برای شبیه سازی 

 vivado نرم افزار جدیدی است که سری های جدیدتر FPGA های Xilinx را پشتیبانی میکند.

AXI4 روش انتقالی است که توسط ARM و Xilinx استفاده می شود

در بسیاری از کاربرد های FPGA ها پردازش سیگنال انجام میشود بنابراین بهتر است که با مفاهیم سیگنال و سیستم آشنایی داشته باشید.

 در شبیه سازی ها دقت داشته باشید در واقعیت هر یک از المان های استفاده شده در برنامه نویسی داری تاخیر هستند و هر یک با توجه با آن المان متغییر است (Propagation delay)

 

-------------------------------------------------------------

 شروع به به کد زنی vhdl 

hello world

 


entity T01_HelloWorldTb is

end entity;

architecture sim of T01_HelloWorldTb is

begin

    process is

    begin

        report "Hello World!";

        wait;

    end process;

end architecture;

 

 

این کد به شکل  sequentially اجرا می شود و هر خط به ترتیب از بالا به  پایین اجرا میشود.

با زدن کلیک راست و وارد شدن به قسمت project setting  و فعال کردن display compile output  اطلاعات بیشتر نمایش داده خواهد شد

برای اجرای دوباره باید تنظیمات شبیه ساز ریست شود

-------------------------------------------------------------------

دستور wait برای وایستادن برای همیشه استفاده میشود

دستور wait for برای منتظر نگه ماندن برای یک زمان مشخص استفاده میشود.

 

entity T02_WaitForTb is
end entity;
 
architecture sim of T02_WaitForTb is
begin
 
    process is
    begin
        -- This is the start of the process "thread"
  
        report "Peekaboo!";
         
        wait for 10 ns;
         
        -- The process will loop back to the start from here
    end process;
 
end architecture;

 

کامنت گزاری با -- شروع میشود

 ----------------------------

آمورش استفاده از دستور wait for

 

The syntax of the wait for statement is:
wait for <time_value> <time_unit>;
where <time_value> is number and <time_unit> is one of the following time units:

fs    femtoseconds
ps    picoseconds
ns    nanoseconds
us    microseconds
ms    milliseconds
sec    seconds
min    minutes
hr    hours

 

When working with digital logic that runs at MHz clock frequencies, you will usually be working with nanosecond increments.

When we ran the code in the simulator, it printed “Peekaboo!” to the console every 10 ns. Because this is a simulation, the report statement takes zero time, and so does the looping.

 

-------------------------------------------------------------

 آموزش استفاده از Loop و خارج شدن از آن در زبان VHDL

entity T03_LoopTb is
end entity;
 
architecture sim of T03_LoopTb is
begin
 
    process is
    begin
  
        report "Hello!";
         
        loop
            report "Peekaboo!";
            exit;
        end loop;
         
        report "Goodbye!";
        wait;
         
    end process;
 
end architecture;

 

The loop statement implements an infinite loop
The exit statement will break out of any loop

The process thread will pause at wait for for the exact specified time
All statements other than wait statements take zero simulation time

 

-----------------------------------------------------------

آموزش استفاده از for loop 

 

The syntax of the For-Loop is:

for <c> in <r> loop
end loop;
The <c> is an arbitrary name for a constant that will available inside of the loop. The <r> is a range of integers or enumerated values which the loop will iterate over. An integer range can be either incrementing or decrementing.

The VHDL code for an incrementing range including all 10 numbers from 0 to 9:

0 to 9
The VHDL code for a decrementing range including all 10 numbers from 9 to 0:

9 downto 0
The VHDL code for a range including only the number 0:

0 to 0
The VHDL code for an empty range that doesn’t have any numbers at all:

0 to -1

 

entity T04_ForLoopTb is
end entity;
 
architecture sim of T04_ForLoopTb is
begin
 
    process is
    begin
 
        for i in 1 to 10 loop
            report "i=" & integer'image(i);
        end loop;
        wait;
         
    end process;
 
end architecture;

 

Not totally unexpectedly our For-Loop iterated ten times before terminating. The value of i is printed to the simulator console ten times at simulation time 0. There’s no wait statement inside of the loop, and therefore the loop takes zero time to complete. Finally, the program goes into an infinite pause on the wait;.

We learned how to convert an integer to a string by using integer'image(), and we used the & character to join the two strings together.

 

The For-Loop can iterate over an incrementing or decrementing integer range
An incrementing range is denoted by to, and a decrementing range by downto
An integer can be converted to a string by using integer'image()
Two strings can be joined by using the string concatenation character &

 

----------------------------------------------

آموزش while

گزاشتن شرط برای اجرای یک دستور

برای این که یک متغییر مقدار دهیم از =: استفاده میکنیم

برای تعریف متغییر بین process is و  begin آن را تعریف میکنیم به اسم variable و سپس نوع آن و سپس مقدار اولیه برای آن در نظر میگیریم

entity T05_WhileLoopTb is
end entity;

architecture sim of T05_WhileLoopTb is
begin

process is
variable i : integer := 0;
begin

while i < 10 loop
report "i=" & integer'image(i);
i := i + 2;
end loop;
wait;

end process;

end architecture;

توضیحات

ساختار loop

The syntax of the While-Loop is:

while <condition> loop
end loop;


The <condition> is a boolean true or false. It can also be an expression which evaluates to true or false. The condition is evaluated before every iteration of the loop, and the loop will continue only if the condition is true.

مثال

Example expression which is true if i is less than 10:

i < 10
Example expression which is true if i is not 10:

i /= 10
Example expression which is true if i is greater than or equal to 0, and less than 28=256:

i >= 0 and i < 2**8;


Relational operators:

عملگرها

= equal
/= not equal
< less than
<= less than or equal
> greater than
>= greater than or equal


Logical operators:

عملگرهای منطقی

not a         true if a is false
a and b      true if a and b are true
a or b        true if a or b are true
a nand b      true if a or b is false
a nor b       true if a and b are false
a xor b       true if exactly one of a or b are true
a xnor b     true if a and b are equal

We created an integer variable i and gave it an initial value of 0. We used an expression in the While-Loop that is true as long as i is less than 10. Because we were incrementing i by 2 in each iteration, the last number that was printed out was 8.

On the next iteration, the i < 10 evaluated to false, because 10 is not less than 10. After the loop terminated, the program hit the wait; where it paused infinitely.

The While-loop will continue as long as the condition is true

دستور loop  تا زمانی که شرط آن درست باشه اجرا میشه


The condition is evaluated before every iteration of the While-Loop


Variables may be declared and used within a process

-------------

entity و architecture در هر کد باید متناسب با آن باشد

تفاوت سیگنال ها و متغییر ها

متغییر ها (variables) برای طراحی الگوریتم داخل پروسه استفاده میشوند ولی قابلیت دسترسی به دنیای بیرونی را ندارند.

In the previous tutorial we learned how to declare a variable in a process. Variables are good for creating algorithms within a process, but they are not accessible to the outside world. If a scope of a variable is only within a single process, how can it interact with any other logic? The solution for this is a signal.

Signals are declared between the architecture <architecture_name> of <entity_name> is line and the begin statements in the VHDL file. This is called the declarative part of the architecture.

طراحی سیگنال

The syntax for declaring a signal is:
signal <name> : <type>;

A signal may optionally be declared with an initial value:
signal <name> : <type> := <initial_value>;

We created a signal and a variable with the same initial value of 0. In our process we treated them in the exact same way, yet the printouts reveal that they behaved differently. First we saw that the assignment to a variable and a signal has a different notation in VHDL. Variable assignment uses the := operator while signal assignment uses the <= operator.

MyVariable behaves as one would expect a variable to behave. In the first iteration of the loop it is incremented to 1, and then to 2. The last printout from the first iteration shows that its value is still 2, as we would expect.

MySignal behaves slightly different. The first +1 increment doesn’t seem to have any effect. The printout reveals that its value is still 0, the initial value. The same is true after the second +1 increment. Now the value of MyVariable is 2, but the value of MySignal is still 0. After wait for 10 ns; the third printout shows that the value of MySignal is now 1. The subsequent printouts follow this pattern as well.

What is this sorcery? I will give you a clue, the wait for 10 ns; has something to do with it. Signals are only updated when a process is paused. Our process pauses only one place, at wait for 10 ns;. Therefore, the signal value changes only every time this line is hit. The 10 nanoseconds is an arbitrary value, it could be anything, even 0 nanoseconds. Try it!

Another important observation is that event though the signal was incremented twice before the wait, its value only incremented once. This is because when assigning to a signal in a process, the last assignment “wins”. The <= operator only schedules a new value onto the signal, it doesn’t change until the wait. Therefore, at the second increment of MySignal, 1 is added to its old value. When it is incremented again, the first increment is completely lost.
A variable can be used within one process while signals have a broader scope
Variable assignment is effective immediately while signals are updated only when a process pauses
If a signal is assigned to several times without a wait, the last assignment “wins”

entity T06_SignalTb is
end entity;

architecture sim of T06_SignalTb is

signal MySignal : integer := 0;

begin

process is
variable MyVariable : integer := 0;
begin

report "*** Process begin ***";

MyVariable := MyVariable + 1;
MySignal <= MySignal + 1;

report "MyVariable=" & integer'image(MyVariable) &
", MySignal=" & integer'image(MySignal);

MyVariable := MyVariable + 1;
MySignal <= MySignal + 1;

report "MyVariable=" & integer'image(MyVariable) &
", MySignal=" & integer'image(MySignal);

wait for 10 ns;

report "MyVariable=" & integer'image(MyVariable) &
", MySignal=" & integer'image(MySignal);

end process;

end architecture;

 

 تغییر variable ها در همان لحظه اتفاق می افتد ولی singnal ها مقادیرشون وقتی به روز میشه که پروسس pause بشه 

 برای تعیین آدرس ها حتما دقت داشته باشید که ماژول به چه تعداد آدرس نیاز دارند و از آدرس و تعداد کم به زیاد آدرس دهی کنید

برای دسترسی به اطلاعات حجیم میتوان از DMA و AXI استفاده کرد

Petalinux is a tool you use to customise, build and deploy Embedded Linux solutions on Xilinx processing systems. It is an Embedded Linux Systems Development Kit that targets Xilinx SoC designs

-------------------------

How to use Wait On and Wait Until in VHDL

برای دسترسی و آپدیت مقادیر سیگنال ها باید از دستور wait on و wait until استفاده میکنیم

entity T07_WaitOnUntilTb is
end entity;

architecture sim of T07_WaitOnUntilTb is

signal CountUp : integer := 0;
signal CountDown : integer := 10;

begin

process is
begin

CountUp <= CountUp + 1;
CountDown <= CountDown - 1;
wait for 10 ns;

end process;

process is
begin

wait on CountUp, CountDown;
report "CountUp=" & integer'image(CountUp) &
" CountDown=" & integer'image(CountDown);

end process;

process is
begin

wait until CountUp = CountDown;
report "Jackpot!";

end process;


end architecture;


The Wait On statement will pause the process until one of the specified signals change:
wait on <signal_name1>, <signal_name2> ...;

The Wait Until statement will pause until an event causes the condition to become true:
wait until <condition>;

In fact, Wait On, Wait Until and Wait For can be combined:
wait on <signal_name1> until <condition> for <time_value>;

This example will pause for 10 nanoseconds, or until signal1 changes and signal2 is equal to signal3:
wait on signal1 until signal2 = signal3 for 10 ns;

ANALYSIS
The first process increments the CountUp counter and decrements the CountDown counter. They are updated simultaneously. Although the signal assignments of the two signals are on different lines in the process, assigned signal values only become effective then the program hits a Wait statement. The process perform this operation at the start of the simulation, and then every 10 nanoseconds.

The second process’ first line is wait on CountUp, CountDown;. The program will wait at this line until one or both of the signals change. As we can see from the printout, this happens at 0 ns simulation time when the counters are changed for the first time, and every time they change after that.

The third process’ first line is wait until CountUp = CountDown;. The program will wake up every time one of the two signals change, just like the first process did. But it will only continue if the expression evaluates to true, otherwise it will go back to sleep. As we can see from the printout, “Jackpot!” is only printet once, at 40 ns when both counters have the same value.

Wait On will wait until one of the signals change
Wait Until will wake up if one of the signals change, but will only continue if the expression is true
Wait On, Wait Until and Wait For can be combined
---------------

هر دو زبان VHDL و verilog برای برنامه نویسی سخت افزار استفاده میشود

زبان verilog بیشتر نزدیک به زیان های برنامه نویسی C و ++C است

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

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

زبان VHDL به نسبت قید و بند بیشتری در برنامه نویسی را دارند.

به نظر میرسد که زبان VHDL در ایران بیشتر مورد توجه قرار گرفته است.

--------------------------------------------------

استفاده از شرط ها

The basic syntax is:

if <condition> then
elsif <condition> then
else
end if;

The elsif and else are optional, and elsif may be used multiple times. The <condition> can be a boolean true or false, or it can be an expression which evaluates to true or false.

Example expression which is true if MyCounter is less than 10:

MyCounter < 10

entity T08_IfTb is

end entity;

---------------

architecture sim of T08_IfTb is

signal CountUp : integer := 0;

signal CountDown : integer := 10;

begin

process is

begin

CountUp <= CountUp + 1;

CountDown <= CountDown - 1;

wait for 10 ns;

end process;

process is

begin

if CountUp > CountDown then

report "CountUp is larger";

elsif CountUp < CountDown then

report "CountDown is larger";

else

report "They are equal";

end if;

wait on CountUp, CountDown;

end process;

end architecture;

We gave CountDown an initial value of 10, and CountUp a value of 0. The first process changes both counter values at the exact same time, every 10 ns. When this happens, the second process is triggered because the program will always be waiting at the wait on CountUp, CountDown; line. The program will always be waiting there because the If-Then-Elsif-Else and the report statements consume zero simulation time.

The If-Then-Elsif-Else statement will cause the program to take one of the three branches we created. The two first branches cover the cases where the two counters have different values. We could have dropped the single else, and used elsif CountUp = CountDown then which would have had the same result. But it is good design practice to cover all branches, and the else clause covers all intentional and unforeseen cases.

As we can see from the printout, the second process takes one of the three branches every time the counters change.

If-Then may be used alone or in combination with Elsif and Else.

Expressions may contain relational and logical comparisons and mathematical calculations
-------------

---------------

چطوری SENSITIVITY LIST درست کنیم ؟

You should always use a sensitivity list to trigger processes in production modules. Sensitivity lists are parameters to a process which lists all the signals that the process is sensitive to. If any of the signals change, the process will wake up, and the code within it is executed.

We’ve already learned to use the wait on and wait until statements for waking up a process when a signal changes. However, to be honest, this isn’t how I write most of my processes.

When writing VHDL code, the style of writing depends on whether or not the code is intended to be run only in a simulator. If I’m writing simulation code, like we have been doing in this tutorial series, I always use wait statements to control the processes. If I’m writing code that I intend to create a physical implementation of, I never use wait statements.

The syntax for a process with a sensitivity list is:
process(<signal1>, <signal2>, ..) is
begin
    <main logic here>
end process;

An important quirk with the sensitivity list is that all signals that are read within the process must be on the sensitivity list. However, the simulator won’t inform you if you fail to add a signal to the sensitivity list, because it’s legal in the VHDL language. The problem is that if you fail to do this, the code will behave differently when synthesized and used in a physical implementation.

In VHDL-2008, the keyword all is allowed to use instead of listing every signal. Unfortunately most synthesizing software don’t support this newer revision of the VHDL language.

entity T09_SensitivityListTb is
end entity;
 
architecture sim of T09_SensitivityListTb is
 
    signal CountUp   : integer := 0;
    signal CountDown : integer := 10;
 
begin
 
    process is
    begin
 
        CountUp   <= CountUp + 1;
        CountDown <= CountDown - 1;
        wait for 10 ns;
 
    end process;
 
    -- Process triggered using Wait On
    process is
    begin
 
        if CountUp = CountDown then
            report "Process A: Jackpot!";
        end if;
 
        wait on CountUp, CountDown;
 
    end process;
 
    -- Equivalent process using a sensitivity list
    process(CountUp, CountDown) is
    begin
 
        if CountUp = CountDown then
            report "Process B: Jackpot!";
        end if;
 
    end process;
 
end architecture;

 

We can see from the printouts that the two processes behave alike. That is because a process with a sensitivity list is by definition equivalent to a process with wait on at the end of the process.

Processes with sensitivity lists are normally used in code that is intended to be synthesized. Such code is commonly referred to as register-transfer level (RTL) code. This is a convention, but there are good reasons for it. Although some wait on and wait until statements can be synthesized, it’s hard to know what kind of hardware it will create.

  • A process with a sensitivity list is equivalent to a process with wait on at the end
  • All signals that are being read within a process must be on the sensitivity list
  • Use wait statements in simulation code, and sensitivity lists in RTL code

----------------------