
Recent am avut ocazia sa citesc lucarea de diploma a dlui inginer Glont Aurelian Ionut abolvent 2009 al facultatii de Inginerie “Hermann Oberth” din Sibiu specializarea Calculatoare si Tehnica Informatiei. Am fost placut impresionat de calitatea lucarii. Consider ca si Dv veti aprecia la fel de bine acesta lucare. Am convingerea ca Dl inginer Glont Aurelian Ionut are un potential tehnic foarte bun si va face o cariera stralucita in automatizari industriale
Pentru cei interesati de o colaborare cu Dl inginer Glont Aurelian Ionut il puteti contacta prin intermediul ferestrei de comentarii asociate acestui articol
Structura unităţii de procesare
Unitatea de procesare este cea mai importantă parte a circuitului de ansamblu. Ea reprezintă porţiunea din circuit în care au loc transformările valorilor de intrare cu scopul de a realiza orientarea turbinei eoliene.
Ca şi intrări în circuit avem:
– a – valoare preluată de la Registrul A în care a fost stocată în prealabil valoarea emisă de traductorul de poziţie unghiulară al turbinei – a este o valoare pe 9 biţi pentru a putea acoperi întreg intervalul [0,360].
– b – valoare preluată de la Registrul B în care a fost stocată în prealabil valoarea emisă de traductorul de poziţie unghiulară al giruetei – b este o valoare pe 9 biţi pentru a putea acoperi întreg intervalul [0,360].
La ieşire vom avea:
– f – valoarea cu care va trebui sa se miste turbina pentru a se orienta pe directia vantului – deasemenea valoare pe 9 biti pentru a putea acoperi intreg intrvalul [0,360].
– sens – va fi o valoare pe 2 biti ce va reprezenta logica de sens a circuitului şi anume directia în care se va deplasa turbina: stanga, dreapta sau stop.

Figura 7 – Structura Unitatii de Procesare(se afla in directorul cu figuri)
Exemplificăm în continuare transformările valorilor de intrare pe parcursul întregii unităţi de procesare pentru o înţelegere cât mai bună a funcţionării acesteia.
După cum am precizat anterior valorile a – reprezentând poziţia unghiulară a turbinei şi b – reprezentând poziţia unghiulară a giruetei reprezintă valorile de intrare ale acestui circuit. Ne dorim să aflăm valoarea cu care se va misca turbina spre direcţia vântului cu intensitate maximă şi sensul în care aceasta se va roti.
Paşii ce trebuie urmaţi pentru realizarea obiectivului:
1. Sunt comparate valorile a şi b cu ajutorul unui comparator ce va avea la ieşire o valoare pe 2 biţi c1. În urma comparării c1 va lua valorile:
– 10 , când a>b
– 11 , când a=b
– 01 , când a<b
2. Se calculează valoarea diferenţei dintre a şi b în modul. Pentru aceasta este nevoie de un dispozitiv de scădere şi de două multiplexoare care vor stabili care dintre valorile a şi b vor fi puse pe intrarea cu plus a scăzătorului şi care valoare dintre valorile a şi b vor fi puse pe intrarea cu minus a scăzătorului. Valoarea diferenţei va fi preluată de variabila m – care este ieşirea scăzătorului deasemenea pe 9 biţi pentru a acoperi întreg intervalul .
Multiplexoarele vor fi comandate de valoarea c1(1) calculată la pasul anterior. Astfel c1(1) va putea lua valorile 1 sau 0. Rezulta deci două cazuri:
– când c1(1)=1 observăm că a>b deci Multiplexorul 1 va selecta valoarea a ca fiind pe intrarea cu plus a scăzătorului şi Multiplexorul 2 va selecta valoarea b ca fiind valoarea pe intrarea cu minus a scăzătorului.
– când c1(1)=0 observăm că a<b deci Multiplexorul 1 va selecta valoarea b ca fiind pe intrarea cu plus a scăzătorului şi Multiplexorul 2 va selecta valoarea a ca fiind valoarea pe intrarea cu minus a scăzătorului.
3. Este comparată valoarea m calculată la pasul anterior cu 180 cu ajutorul unui comparator. La ieşire vom avea o valoare pe un singur bit c2 astfel că:
– c2=0 , când m ≤ 180
– c2=1 , când m > 180
4. Se calculează diferenţa dintre 360 şi valoarea m calculată la pasul 2 cu ajutorul unui scăzător. Ieşirea acestuia va fi km şi va fi tot o valoare pe 9 biţi pentru a acoperi întreg intervalul [0,360].
5. Conform principiului de elaborare a comenzilor dacă:
– m ≤ 180 , atunci valoarea de ieşire f a unităţii de procesare ia valoarea lui m.
– m > 180 , atunci valoarea de ieşire f a unităţii de procesare ia valoarea lui km calculat la pasul 4.
Selecţia lui f se face cu ajutorul Multiplexorului 3 comandat de c2 obţinut la pasul 3. Astfel că:
– dacă c2=0 atunci f = m – unde m reprezintă în acest caz cel mai scurt drum pe care trebuie să-l parcurgă turbina până pe direcţia vântului cu cea mai mare intensitate.
– dacă c2=1 atunci f = km – unde km reprezintă în acest caz cel mai scurt drum pe care trebuie să-l parcurgă turbina până pe direcţia vântului cu cea mai mare intensitate.
6. Este generată logica de sens cu ajutorul semnalelor c1 calculat la pasul 1 şi c2 calculat la pasul 3. Astfel că:
c1 |
c2 |
sens |
10 |
0 |
10 Stânga |
11 |
0 |
00 Stop |
01 |
0 |
01 Dreapta |
10 |
1 |
01 Dreapta |
01 |
1 |
10 Stânga |
Deci putem concluziona că dacă:
– sens = 10 turbina se va mişca la stanga
– sens = 01 turbina se va mişca la dreapta
– sens = 11 turbina nu se va mişca
Descrierea blocurilor funcţionale
Un bloc funcţional reprezintă o anumită componentă dintr-un circuit care îndeplineşte o anumită funcţie. În cazul circuitului nostru au fost folosite următoarele blocuri funcţionale:
- Registru
- Comparator
- Multiplexor
- Scăzător
- Numărător
- Poarta Logică ŞI
- Logica de sens
1. Registru – rolul acestuia este de a memora informaţie. În circuitul nostru avem regiştrii de intrare ce memorează datele iniţiale (Reg_a şi Reg_b), regiştrii intermediari ce memorează date intermediare (Reg_sens, Reg_f) şi regiştrii de ieşire ce memorează datele finale (Reg_m). Fiecare astfel de registru are o intrare de Load şi una de Reset. Când comanda Load este activată are loc încărcarea în registru a informaţiei dorite iar când comanda Reset este activată are loc punerea pe 0 a ieşirii registrului. Cele două comenzi sunt date de ieşirile automatului.

Figura 8 – Reprezentare registru
Descrierea în VHDL a unui Registru:
entity registru is
port
(t:in std_logic_vector(8 downto 0); //valoarea ce trebuie memorată în registru
load,reset:in std_logic; //semnale ce vin de la automat load sau reset
a:out std_logic_vector(8 downto 0)); //valoarea de ieşire din registru
end registru;
architecture arch_registru of registru is
begin
proc_registru : process(reset,load) //procesul este senzitiv la reset şi la load
begin
if reset=’1′ then a <=”000000000″; //dacă reset=1 atunci val de ieşire este pusă pe 0
elsif load=’1′ then a <= t; //dacă load=1 punem val. de la intrare la ieşire
end if;
end process proc_registru;
end arch_registru;

Figura 9. Simularea unui registru
După cum observăm în Figura 9 valoarea t de intrare ce trebuie memorată este reprezentată în hexazecimal. Semnalul Reset este activat dupa cum se vede încă de la startul simulării. Am declarat mai multe valori ale lui t pentru a se observa cum funcţioneaza acest registru. Semnalul Load este semnal de tip clock şi după cum se poate vedea pe fiecare impuls al semnalului clock are loc memorarea datei de intrare la ieşire.
2. Comparator – rolul unui comparator aşa cum îi şi spune numele este de a compara două valori. La ieşire un comparator poate avea o valoare pe un bit sau mai multi biţi în funcţie de cerinţele problemei.
Să presupunem că avem de comparat două numere a şi b care sunt datele de intrare în comparator. Ieşirea o notăm cu c.
Dacă ieşirea c este pe un bit putem avem cazurile:
– dacă a ≠ b atunci c=1
– dacă a = b atunci c=0
Dacă ieşirea c este pe doi biţi putem avem cazurile:
– dacă a > b atunci c=00
– dacă a > b atunci c=01
– dacă a = b atunci c=10
Figura 10. Reprezentarea unui comparator cu două intrări şi o ieşire
Descrierea în VHDL a unui Comparator:
entity comparator is
port
(a,b:in std_logic_vector(8 downto 0);
c: out std_logic);
end comparator;
architecture arch_comparator of comparator is
begin
c<=’0′ when (a=b) else
‘1’;
end arch_comparator;
Analog se scrie codul şi pentru comparatorul ce are ieşirea pe doi biţi.
Dacă valorile de intrare sunt diferite observăm în Figura 11 că iesirea c are valoarea 1.

Figura 11. Simularea unui comparator cu valori de intrare diferite
Dacă valorile de intrare sunt egale observăm în Figura 12 că iesirea c are valoarea 0.

Figura 12. Simularea unui comparator cu valori de intrare egale
3. Multiplexor – rolul unui multiplexor este acela de a selecta o ieşire din n intrări. Selecţia liniei de ieşire se face cu ajutorul unor semnale de control. Semnalul de ieşire este reprezentat pe atâţia biţi câţi sunt necesari pentru a acoperi numărul de intrări ale multiplexorului. De exemplu dacă n = 2 selectorul este pe 1 bit, dacă n = 5 selectorul este pe 3 biţi etc.

Figura 13. Reprezentarea unui multiplexor
În acest caz avem două intrări deci selectorul va fi pe un singur bit. Dacă selectorul este 1 la ieşire va fi adusă valoarea a iar dacă selectorul este 0 la ieşire va fi adusă valoarea b.
Descrierea în VHDL a unui Multiplexor:
entity multiplexor is
port
(a,b : in std_logic_vector(8 downto 0); //intrările dintre care se va alege ieşirea
rez : out std_logic_vector(8 downto 0); //ieşirea
sel : în std_logic); //selectorul
end multiplexor;
architecture arch_multiplexor of multiplexor is
begin
rez <= a when sel = ‘1’ else //dacă selectorul este 1 atunci ieşirea este a
b; //în caz contrar ieşirea este b
end arch_multiplexor;

Figura 14. Simularea unui multiplexor
În Figura 14 avem confirmarea celor spuse anterior. Observăm că atunci când selectorul sel se află pe 0 atunci la ieşire avem valoarea lui b. Când selectorul se află pe 1 atunci la ieşire avem valoarea lui a.
4. Scăzător – după cum îi spune şi numele acest bloc funcţional realizează diferenţa dintre două numere. Un astfel de dispozitiv are două intrări: o intrare “+” pe care se aplică cea mai mare dintre cele două valori care se doresc a fi scăzute şi o intrare “-“ pe care se aplică cea mai mică dintre cele două valori câte se doresc a fi scăzute. În majoritatea cazurilor potrivirea celor două valori la intrarea potrivită se face cu ajutorul multiplexoarelor.

Figura 15. Reprezentarea unui Scăzător
Descrierea în VHDL a unui Multiplexor:
entity scazator is
port
(a,b : in std_logic_vector(8 downto 0); //valorile care se doresc a fi scăzute
rez : out std_logic_vector(8 downto 0)); //rezultatul scăderii
end scazator;
architecture arch_scazator of scazator is
begin
rez <= a – b ; //operaţia de scădere
end arch_scazator;

Figura 16. Simularea unui Scăzător
După cum se vede în Figura 16 scăderea dintre a şi b s-a efectuat cu success. Numerele sunt reprezentate în hexazecimal.
5. Numărător – după cum îi spune şi numele acest dispozitiv are rolul de a număra impulsuri. În cazul nostru are rolul de a număra impulsuri clk. Această numărare se poate face atât pe frontul crescător al semnalului cât şi pe frontul descrescător al semnalului. În majoritatea cazurilor numărătoarele trebuie resetate înainte de a putea începe o numărătoare. Intrarea într-un astfel de numărator este de tip clock. Ieşirea trebuie declarată de tip buffer pentru a realiza reacţia internă.

Figura 17. Reprezentarea unui Numărător
Descrierea în VHDL a unui Numărător:
entity numarator is
port
(a: in std_logic; //semnalul de intrare
reset: in std_logic; //semnalul de reset
rez: buffer std_logic_vector(8 downto 0)); //semnalul de ieşire–rezultatul numărării
end numarator;
architecture arch_numarator of numarator is
begin
proc_numarator: process(a) //procesul este senzitiv la semnalul de intrare
begin
if rising_edge(a) then //testăm dacă suntem pe frontul crescător
if reset=’1′ then rez<=”000000000″; //testăm semnalul de reset
else rez<=rez+1; //efectuăm incrementarea
end if;
end if;
end process proc_numarator;
end arch_numarator;

Figura 18. Simularea unui Numărător
Semnalul a fost ales semnal de tip clock de frecvenţa 20 Mhz. Semnalul de reset se aplică chiar la începutul simulării pentru a aduce valoarea de ieşire pe 0. Observăm că pe fiecare front crescător al semnalului de intrare avem o incrementare a valorii de ieşire în cazul nostru 4 fronturi crescătoare.
6. Poarta Logica ŞI – după cum îi spune şi numele realizează ŞI logic între două semnale de intrare.
Tabel de adevăr ŞI Logic
a |
b |
a AND b |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |

Figura 19. Reprezentarea unei Porţi Logice ŞI
Descrierea în VHDL a unei Porţi ŞI:
entity si is
port
(a,b : in std_logic; //semnalele de intrare
rez: out std_logic); //semnalul de ieşire
end si;
architecture arch_si of si is
begin
rez<= a and b; //realizarea operatiei ŞI între cele două semnale de intrare
end arch_si;

Figura 20. Simularea unei Porţi Logice ŞI
Semnalele de intrare au fost alese de tip clock unul cu frecvenţa de 15 Mhz şi unul de frecvenţa 5 Mhz pentru a putea observa cât mai bine rezultatul. Observăm că semnalul de ieşire este 1 numai când cele două semnale de intrare sunt 1.
7. Logica de Sens – este un bloc funcţional care generează o ieşire pe 2 biţi în funcţie de două intrări: o intrare a pe doi biţi şi o intrare b pe un singur bit. Ieşirea reprezintă codificat direcţia unde se va deplasa turbina – stânga, dreapta sau stop.
a |
b |
sens |
10 |
0 |
10 Stânga |
11 |
0 |
00 Stop |
01 |
0 |
01 Dreapta |
10 |
1 |
01 Dreapta |
01 |
1 |
10 Stânga |

Figura 21. Reprezentarea Logicii de Sens
Descrierea în VHDL a blocului funcţional Logica de Sens:
entity logica is
port
( a : in std_logic_vector (1 downto 0); //intarea pe 2 biţi
b : in std_logic; //intrarea pe un bit
sens : out std_logic_vector (1 downto 0)); //iesirea pe 2 biţi
end logica;
architecture arch_logica of logica is
begin
sens<=”10″ when (a=”10″ AND b=’0′) else //descrierea logicii de sens cu
„00” when (a=”11″ AND b=’0′) else // structura when – else
„01” when (a=”01″ AND b=’0′) else
„01” when (a=”10″ AND b=’1′) else
„10”;
end arch_logica;

Figura 22. Simularea Logicii de Sens
Observăm în Figura 22 că având intrarea a = “01” şi b = “0” obţinem ieşirea sens = “01” adică turbina se va deplasa spre dreapta conform tabelului.
Descrierea în VHDL a ansamblului
Punând la un loc tot ce am precizat pâna acum, obţinem întregul circuit ce va comanda orientarea turbinei pe direcţia vântului cu intensitatea cea mai mare. Descrierea întregului circuit este facută în limbajul VHDL (Very High Integrated Circuits Hardware Description Language).
Prezentăm în continuare codul sursă al dispozitivului de orientare a turbinelor eoliene în limbajul VHDL.
library ieee; //apelarea bibliotecilor necesare compilării
use ieee.std_logic_1164.all; //circuitului descris
use work.std_arith.all; //apelarea bibliotecii aritmetice
entity turbina is //declararea entităţii turbinei
port //definirea portului
(t,g,k1,k2: in std_logic_vector (8 downto 0); //semnale de intrare
p : in std_logic; //semnale de intrare
clk,start,init: in std_logic; //semnale de intrare
m0,m1: out std_logic);
end turbina;
architecture arch_turbina of turbina is //definirea arhitecturii turbinei
signal a,b,aa,bb,f,ff,pp,m,km: std_logic_vector (8 downto 0); //semnale interne pe 9 biţi
signal sens,c1,ss: std_logic_vector(1 downto 0); //semnale interne pe 2 biţi
signal r0,r1,c2,c3,reset,resetn,load,loads,loadm: std_logic; //semnale interne pe 1 bit
signal y: std_logic_vector(1 to 5); //semale interne pe 5 biţi
type STARE is (s0,s1,s2,s3,s4,s5,s6,s7); //definirea stărilor automatului
signal s: STARE; //definirea tipului stărilor
begin
–Descriere Registru a
registru_a : process(reset,load) //procesul este senzitiv la reset şi load
begin
if reset=’1′ then a <=”000000000″; //se resetează ieşirea (se pune pe 0)
elsif load=’1′ then a <= t; //se încarcă valoarea la ieşire
end if;
end process registru_a;
–Descriere Registru b
registru_b : process(reset,load) //process senzitiv la reset şi load
begin
if reset=’1′ then b <=”000000000″; //se resetează ieşirea (se pune pe 0)
elsif load=’1′ then b <= g; //se încarcă valoarea la ieşire
end if;
end process registru_b;
–Descriere Comparator ab
c1<=”10″ when (a>b) else //condiţia pentru a > b
„11” when (a=b) else //condiţia pentru a = b
„01”; //condiţia pentru alte cazuri
–Descriere Multiplexor 1
aa <= a when c1(1) = ‘1’ else //daca selectorul este 1 incarcam pe a
b; //in caz contrar incarcam pe b
–Descriere Multiplexor 2
bb <= b when c1(1) = ‘1’ else //dacă selectorul este 1 încărcăm pe b
a; //în caz contrar încărcăm pe a
–Descriere Scăzător aa_bb
m <= aa – bb; //realizarea operaţiei de scădere între cei doi operanzi
–Descriere Comparator 180
c2<=’1′ when (m>k1) else //ieşirea este 1 când valoarea este > 180
‘0’; //ieşirea este 0 când valoarea este < 180
–Descriere Scăzător k2_m
km <= k2 – m; //realizarea operaţiei de scădere între cei doi operanzi
–Descriere Multiplexor 3
f <= km when c2 = ‘1’ else //dacă selectorul este 1 încărcăm pe km
m; //dacă selectorul este 0 încărcăm pe m
–Descriere Logica de sens
sens<=”10″ when (c1=”10″ AND c2=’0′) else //elaborarea comenzilor
„00” when (c1=”11″ AND c2=’0′) else
„01” when (c1=”01″ AND c2=’0′) else
„01” when (c1=”10″ AND c2=’1′) else
„10”;
–Descriere Registru sens
registru_sens : process(reset,loads) //process senzitiv la reset şi load
begin
if reset=’1′ then ss <=”00″; //se resetează ieşirea (se pune pe 0)
elsif loads=’1′ then ss <= sens; //se încarcă valoarea dorită la ieşire
end if;
end process registru_sens;
–Descriere Registru f
registru_f : process(reset,loads) //process senzitiv la reset şi load
begin
if reset=’1′ then ff <=”000000000″; //se resetează ieşirea (se pune pe 0)
elsif loads=’1′ then ff <= f; //se încarcă valoarea dorită la ieşire
end if;
end process registru_f;
–Descriere Numarator
numarare:process(resetn,p) //process senzitiv la resetn şi p
begin
if resetn=’1′ then pp<=”000000000″; //se resetează ieşirea (se pune pe 0)
elsif rising_edge(p) then pp<=pp+1; //pe frontul crescător al clock-ului are
end if; //loc incrementarea ieşirii
end process numarare;
–Descriere Comparator 180
c3<=’0′ when (pp=ff) else //ieşirea este 0 când valorile sunt egale
‘1’; //ieşirea este 1 când valorile sunt diferite
–Descriere Poarta ŞI 1
r0<= ss(0) and c3; //ŞI_Logic
–Descriere Poarta ŞI 2
r1<= ss(1) and c3; //ŞI_Logic
–Descriere Registru m
registru_m : process(reset,loadm) //process senzitiv la reset şi loadm
begin
if reset=’1′ then m0<=’0′; //resetarea ieşirilor (punerea pe 0 a acestora)
m1<=’0′;
elsif loadm=’1′ then m0<=r0; //încărcarea valorilor la cele două ieşiri
m1<=r1;
end if;
end process registru_m;
–Descriere AUTOMAT
automat: process(start,init,clk) //process senzitiv la start,init şi clk
begin
if init = ‘1’ then s<= s0 ; //iniţializarea automatului
elsif clk’event and clk = ‘1’ then //testarea frontului crescător al clk
case s is //stabilirea legăturilor între stări
when s0=> if start=’1’then s<=s1;
end if;
when s1=> s<=s2;
when s2=> s<=s3;
when s3=> s<=s4;
when s4=> if ss=”00″ then s<=s1;
else s<=s5;
end if;
when s5=> s<=s6;
when s6=> if c3=’1′ then s<=s6;
else s<=s7;
end if;
when s7=>s<=s0;
end case;
end if;
end process automat;
with s select //atribuirea de valori variabilelor de stare
y<=”10100″ when s0,
„00000” when s1|s6,
„01000” when s2,
„00100” when s3,
„00010” when s4,
„00001” when others;
–Conexiuni interne
reset<=y(1); //atribuirea fiecărui bit al variabilei de stare unei anumite comenzi
load<=y(2); //dacă bitul este 1 comanda este activă
resetn<=y(3); //dacă bitul este 0 comanda este inactivă
loads<=y(4);
loadm<=y(5);
end arch_turbina;