Cum se configurează smartphone-uri și PC-uri. Portal informativ

Circuite integrate programabile. Plis - primii mei pași

Recent, am făcut primul pas către FPGA și v-am sunat să mă urmați. Pasiunea mea fanatică pentru FPGA și ideea că FPGA sunt cea mai bună platformă pentru crearea oricărui dispozitiv a devenit una religioasă. Secta mea FPGA predică o respingere completă a microcontrolerelor, iar o ramură deosebit de extremistă propovăduiește o respingere nu numai a procesoarelor soft, ci și a computerelor seriale în general!

Ca întotdeauna, înțelegerea adevărurilor a fost ajutată de rezolvarea problemelor reale. În predica de astăzi, aș dori să vorbesc despre încercările care cad asupra unui tânăr FPGA. Depășind încercările, înțelegem adevărul. Dar sunt întrebări la care nu am găsit răspunsuri. Prin urmare, mi-ar plăcea foarte mult ca frații Khabrov - lideri FPGA cu experiență să participe la discuție, să dea o mână de ajutor fraților lor mai mici.

Acest articol este pentru începători. În ea, voi descrie probleme tipice, întrebări, concepții greșite, greșeli care pot apărea chiar la începutul antrenamentului (pentru că le-am avut). Cu toate acestea, contextul articolului este limitat de faptul că dezvoltarea se realizează pe FPGA de la Altera în mediul Quartus în limbajul Verilog.

Este greu să trăiești fără a face nimic, dar nu ne este frică de greutăți!

Unul dintre motivele pentru care mulți oameni nu încep să învețe Verilog chiar acum este lipsa unui FPGA real. Cineva nu poate comanda pentru că este scump, iar cineva pentru că nu știe ce să ia (problema alegerii a fost discutată în articolul precedent). Cineva FPGA mai merge prin poștă.

Dar în dezvoltarea mea, am ajuns la concluzia că am nevoie de un FPGA adevărat deja în stadiul final de dezvoltare, când trebuie să testez proiectul „în hardware”. Ideea este că de cele mai multe ori îmi petrec depanarea codului folosind simulatoare.

Prin urmare, sfatul meu este: absența FPGA-urilor nu este un motiv pentru a fi inactiv. Scrieți și depanați module FPGA în simulatoare!

Simulator pentru Verilog

Deci, cum să te distrezi cu zile de lucru lungi plictisitoare (dacă sunt)? Desigur, vom stăpâni FPGA! Dar cum puteți face ca un întreg mediu de dezvoltare de la Altera să funcționeze dacă cântărește limitele de internet de lucru lunare de 3? Îl poți aduce pe o unitate flash! Dar dacă subiectul de studiu este Verilog, atunci vă puteți limita la un bloc de note, compilatorul IcarusVerilog și vă puteți uita la rezultatul în GTK Wave.

Încearcă acum

Pentru a începe să lucrați într-un mediu Windows, trebuie doar să descărcați fișierul de instalare iverilog-20130827_setup.exe (instantaneu de dezvoltare) de la linkul http://bleyer.org/icarus/

Instalarea nu provoacă dificultăți. Acum să trecem puțin înainte: să creăm un folder pentru proiect și în el câteva fișiere cu conținut care nu este încă clar:

Fișier modul cu cod pentru testarea unitară - bench.v

`Timescale 1ns / 100ps modul testbench(); reg clk; initial begin $display("start"); $dumpfile("test.vcd"); $dumpvars(0,testbench); clk<= 0; repeat (100) begin #10; clk <= 1; #10; clk <= 0; end $display("finish"); end


Fișierul bench.v descrie modulul de testare testbench, conține o sursă de semnal de test clk (meadru). Alte module vor fi create în fișiere separate, sau logica poate fi testată mai întâi în acest modul și apoi mutată într-un modul separat. Apoi, instanțe ale acestor module vor fi adăugate la modulul testbench, unde vom aplica semnale de testare la intrările lor și vom obține rezultate de la ele. Din module putem construi o ierarhie, cred că acest lucru este clar pentru toată lumea.

Fișier BAT care va compila și simula modulul principal prin adăugarea altor module din folderul curent - makev.bat

iverilog -o test -I./ -y./ bench.v vvp test pauză


După rularea acestui fișier, vom vedea pe ecran textul specificat în afișajul $ (aceasta este ieșirea de depanare), în timp ce valoarea semnalelor și a registrelor circuitului va fi în fișierul test.vcd. Facem clic pe fișier și selectăm programul pentru vizualizare - GTKWave (în cazul meu D:\iverilog\gtkwave\bin\gtkwave.exe). Încă câteva clicuri și vom vedea clk-ul nostru.



Aproape fiecare modul nou pe care îl creez în notepad și depanez IcarusVerilog. Următorul pas după o astfel de depanare este verificarea modulelor din Quartus. Deși Quartus are și propriul simulator, îl folosesc mai rar. Motivul este ușurința de a actualiza codul și de a vizualiza rezultatul în IcarusVerilog: a salvat modificările în fișier, a lansat BAT, a apăsat butonul „actualizare” în GTKWave - asta e tot! În ModelSim, acest lucru necesită puțin mai multă mișcare, dar nici nu este rău, mai ales pe aceste structuri complexe.

După simulare, este timpul să rulați Quartus. Dar este încă prea devreme pentru a încărca firmware pe FPGA. Trebuie să ne asigurăm că computerul divin a înțeles corect ce circuit dorim să obținem, expunând gândurile noastre sub forma Verilog „a.

Diferența dintre simulare și hardware real

La început eu, ca un pisoi orb, mi-am bătut capul de stâlpi. S-ar părea că codul corect nu funcționează deloc sau nu funcționează conform așteptărilor. Sau pur și simplu a funcționat, iar acum s-a oprit brusc!

Un pisoi curios începe să caute relația dintre acțiunile sale și rezultat („superstiția porumbeilor”).

Cea mai mare dramă
Mai jos este o listă de ciudatenii, dar mai întâi cea mai mare dramă pe care am întâlnit-o: nu toate constructele Verilog pot fi sintetizate în hardware. Acest lucru se datorează faptului că Verilog descrie nu numai logica hardware, care este combinată în module și funcționează în hardware. Pe același Verilog sunt descrise module de testare care combină modulele testate, aplică semnale de testare intrărilor lor și, în general, există doar pentru testare pe un computer. Modificarea valorilor semnalului în timp este specificată de construcții care conțin semnul „#” în textul Verilog. Un astfel de semn înseamnă o întârziere în timp. În exemplul de mai sus, așa este generat semnalul CLK. Și am crezut păcătos că la fel, în interiorul unui FPGA adevărat, poți genera, de exemplu, o secvență de biți pentru trimiterea unui mesaj prin RS232. La urma urmei, un semnal de la un generator de 50 MHz este aplicat la intrarea FPGA! Poate că ea se cam înclină spre el. După cum s-a dovedit, nu sunt singurul care a sperat într-o minune: , , , . Realitatea, ca întotdeauna, se dovedește a fi mai severă: un FPGA este un set de logică și o întârziere a acestuia poate apărea atunci când se utilizează un contor, a cărui valoare este crescută cu cicluri de la generator la o valoare dată sau într-un alt fel (dar întotdeauna în hardware).
Lista cu ciudateniile gasite
Lucruri uimitoare, totuși, citirea cărților aruncă lumină asupra acestei diavolități. Mai mult, se obține harul.
Dacă desemnați reg, atunci nu este un fapt că va fi creat
Cum am ajuns la problema? Să presupunem că există un singur modul, la intrarea căruia trebuie să furnizez o valoare (după tipul de parametru). În viitor, acest parametru va trebui să se modifice în timp în funcție de unele evenimente externe. Prin urmare, valoarea trebuie stocată într-un registru (reg). Dar implementarea recepționării evenimentelor externe nu a fost încă implementată, așa că nu schimb registrul, ci pur și simplu îl setez la valoarea inițială, care nu se schimbă în viitor.

//setează registrul de 8 biți reg val; //o inițiază cu val inițial<= 8"d0240; //wire к которому подключим выход из модуля wire out_data; //неведомый модуль, называется bbox //экземпляр этого модуля называется bb_01 //будем считать, что в модуле есть входной порт in_data и выходной out_data //во входной порт подаем значение с регистра val, а выход подключаем к wire - out_data bbox bb_01(.in_data(val), .out_data(out_data));
Care ar părea a fi captura? În limbajele de programare imperative, deseori setăm variabilele ca constante și apoi nu le schimbăm niciodată și totul funcționează. Ce vedem în fier?


În primul rând, nu vedem registrul. În al doilea rând, 8 "hFF este furnizat la intrarea modulului în loc de 8" d0240! Și acest lucru este deja suficient pentru ca schema să funcționeze altfel decât am planificat. Faptul că nu există registru este normal. În Verilog, puteți descrie logica în multe feluri, în același timp, sintetizatorul optimizează întotdeauna implementarea hardware. Chiar dacă scrieți un bloc mereu și lucrați cu registre în el, dar valoarea de ieșire va fi întotdeauna determinată de cele de intrare, atunci utilizarea registrului de aici se va dovedi a fi de prisos și sintetizatorul nu o va seta. Și invers, dacă pentru unele valori ale datelor de intrare valoarea de ieșire nu se modifică, atunci nu există nicio modalitate de a face fără un registru de blocare și sintetizatorul îl va crea. (Cartea 1 p. 88-89). Ce rezultă din asta? Dacă începem să schimbăm valoarea registrului, de exemplu, în funcție de apăsarea butoanelor, atunci registrul va fi deja creat și totul va funcționa așa cum trebuie. Dacă se dovedește că butoanele nu schimbă nimic, atunci sintetizatorul îl va arunca din nou și totul se va strica din nou. Ce să faci cu o constantă? Trebuie să îl aplicați direct la intrarea modulului:

Bbox bb_01(.in_data(8"d0240), .out_data(out_data));
Acum, la intrarea modulului avem valoarea corectă:

Rămâne un mister de ce, la reducerea registrului, valoarea lui în inițială nu este înlocuită cu intrarea modulului.

Este mai bine să setați singur dimensiunea firului.
Atunci când se dezvoltă în mediul Quartus, este permisă nu setarea în avans a liniilor de sârmă. În acest caz, acestea vor fi create automat, dar va fi emis un avertisment în acest sens. Problema este că lățimea firului va fi de 1 bit, iar dacă porturile sunt mai mari de 1 bit, atunci valoarea nu va fi transmisă.

Bbox bb_01(.in_data(8"d0240), .out_data(int_data)); other_bbox bb_02(.in_data(int_data), .out_data(out_data));
Avertizare
Avertisment (10236): Avertisment Verilog HDL Implicit Net la test.v(15): a creat o rețea implicită pentru „int_data”
Rezultat:

După cum puteți vedea, un bit este conectat, iar restul de 7 biți nu sunt conectați (NC). Pentru a evita o astfel de problemă, trebuie să creați singur un fir. Nu degeaba compilatorul IcarusVerilog nu emite un avertisment, ci o eroare dacă firul nu este specificat în prealabil.

Wire int_data; bbox bb_01(.in_data(8"d0240), .out_data(int_data)); other_bbox bb_02(.in_data(int_data), .out_data(out_data));

Computerul nu va urca module, vezi care este adâncimea de biți a porturilor. În plus, adâncimea de biți se poate dovedi a fi diferită și nu toți biții sunt luați la intrarea modulului sau de la ieșire, ci unii specifici.

Nu puteți utiliza ieșirea unei funcții logice ca semnal de ceas
Uneori, într-un proiect, este necesară reducerea frecvenței ceasului sau introducerea unei întârzieri de N cicluri. Un începător poate aplica un contor și o schemă suplimentară pentru a determina când contorul atinge o anumită valoare (schemă de comparație). Cu toate acestea, dacă utilizați direct ieșirea din circuitul de comparație ca ceas, atunci pot apărea probleme. Acest lucru se datorează faptului că circuitul logic durează ceva timp pentru a se stabili la o valoare de ieșire stabilă. Această întârziere deplasează marginea semnalului care trece prin diferite părți ale circuitului logic în raport cu ceasul, rezultând curse, metastabilitate, asincronie. Chiar și o dată am auzit o remarcă despre asta ca o critică la adresa FPGA: „există probleme constante cu FPGA - curse de semnal”.

Dacă citești cel puțin câteva articole:
Metastabilitatea flip-flop și sincronizarea ciclu-la-ceas
Câteva cuvinte despre conducte în FPGA

Devine clar cum sunt dezvoltate dispozitivele FPGA: întreaga sarcină este împărțită în blocuri hardware, iar datele dintre ele se deplasează de-a lungul conductelor, încadrându-se sincron în registre în funcție de un semnal de ceas. Astfel, cunoscând frecvența totală de ceas, sintetizatorul calculează frecvența maximă de funcționare a tuturor circuitelor combinatorii, determină dacă viteza acestora se încadrează în perioada ciclului și concluzionează dacă circuitul din FPGA va funcționa sau nu. Toate acestea se întâmplă în stadiul de sinteză. Dacă circuitele se încadrează în parametri, atunci puteți flash FPGA.

Astfel, toate metodologiile necesare au fost create pentru dezvoltatorii de dispozitive bazate pe FPGA, iar dacă sunt urmate, atunci nu vor fi probleme.

Dacă vreau să merg împotriva sistemului?
Ordinea de dezvoltare și comportamentul sintetizatorului de circuit ne aduce la concluzia a ceea ce este un FPGA la nivel hardware. Acestea sunt circuite sincrone. Prin urmare, printre scopurile sintetizatorului se numără respectarea intervalelor de timp. Pentru a face acest lucru, de exemplu, simplifică expresiile logice, aruncă din sinteză părți ale circuitelor care nu sunt utilizate de alte circuite și nu sunt legate de ieșirile fizice ale FPGA. Soluțiile asincrone și trucurile analogice nu sunt binevenite, deoarece munca lor poate fi imprevizibilă și depinde de orice (tensiune, temperatură, proces de fabricație, lot, generare FPGA) și, prin urmare, nu oferă un rezultat garantat, repetabil, portabil. Dar toată lumea are nevoie de un rezultat stabil și de abordări comune ale designului!

Dar ce să faceți dacă nu sunteți de acord cu opinia sintetizatorului că trebuie să aruncați registrele imuabile, să reduceți circuitele logice? Ce se întâmplă dacă doriți să faceți circuite cu logică asincronă? Aveți nevoie de reglaj fin? Sau poate doriți să asamblați un circuit pe componente FPGA de nivel scăzut? Uşor! Mulțumim dezvoltatorilor Altera pentru această oportunitate și pentru documentația detaliată!

Cum să o facă? Puteți încerca editorul de schemă grafică. Poate ați auzit că Quartus vă permite să desenați diagrame? Puteți alege singur blocurile de construcție și le puteți conecta. Dar aceasta nu este o soluție! Chiar și circuitul desenat va fi optimizat de sintetizator, dacă este posibil.

Ca urmare, ajungem la vechiul adevăr: dacă toate celelalte nu reușesc, citiți instrucțiunile. Și anume "Manual Altera" partea numită „Opțiuni de sinteză Quartus II”.

Să începem cu faptul că descriind arhitectura pe Verilog într-un anumit mod, puteți obține un anumit rezultat. Iată exemple de cod pentru obținerea declanșatorului RS sincron și asincron:

//modul modul de declanșare RS sincron rs(clk, r, s, q); fir de intrare clk, r, s; regq de ieșire; întotdeauna @(posedge clk) începe dacă (r) începe q<= 0; end else if (s) begin q <= 1; end end endmodule
În acest caz, obțineți un declanșator sincron.

Dacă ignorăm semnalul de ceas și comutăm în funcție de orice modificări în r și s, atunci rezultatul va fi un element cu o valoare setată asincronă - latch (latch).

//exemplu modul de declanșare RS asincron ModuleTester(clk, r, s, q); fir de intrare clk, r, s; regq de ieșire; întotdeauna @(r sau s) începe dacă (r) începe q<= 0; end else if (s) begin q <= 1; end end endmodule

Module ModuleTester(clk, r, s, q); fir de intrare clk, r, s; regq de ieșire; DLATCH lt(.q(q), .clrn(~r), .prn(~s)); modul final

Ca urmare, întregul „kit de corp” de la intrarea latch, pe care sintetizatorul l-a considerat necesar, va dispărea și vom obține exact ceea ce ne-am dorit:

O listă a primitivelor existente poate fi găsită pe site-ul web Altera.

Și acum un mic exemplu despre asincronie și reducere. M-am gândit, de exemplu, să fac un generator după același principiu pe care se obișnuia să se facă înainte, dar numai pe un FPGA:

Dar pentru a mări perioada, voi lua 4 elemente, dar doar unul dintre ele va fi inversat:

Modul ModuleTester(q); fir de ieșire q; fir a, b, c, d; atribui a = b; atribuie b = c; atribuie c = d; atribui d = ~a; assignq = a; modul final

Dar se dovedește o reducere (1 element, în loc de patru). Ceea ce este logic. Dar apoi am conceput o linie de întârziere.

Dar dacă punem condiția sintetizatorului ca liniile a, b, c, d să nu fie scurtate, atunci obținem ceea ce ne-am propus. Directivele sunt folosite pentru a indica sintetizatorul. O modalitate de a specifica este textul într-un comentariu:

Modul ModuleTester(q); fir de ieșire q; sârmă a,b,c,d /* păstrarea sintezei */; // ^^^--- aceasta este o directivă de sintetizare atribui a = b; atribuie b = c; atribuie c = d; atribui d = ~a; atribuie q = a; modul final
Și iată rezultatul - un lanț de patru elemente:

Și asta nu este tot! O să-l las pe bucuria auto-studiului: lucrul cu carcasa și o directivă de implementare ca RAM/ROM sau un circuit logic; lucrați cu blocuri de memorie încorporate (RAM / ROM); alegerea implementării înmulțirii - un multiplicator hardware sau un circuit logic.

Odată cu dezvoltarea microcircuitelor digitale, a apărut o contradicție între gradul posibil de integrare și gama de microcircuite produse. S-a justificat din punct de vedere economic să se producă microcircuite de integrare medie, cum ar fi,. Din aceste noduri trebuiau create circuite mai complexe. Nu au fost probleme de a plasa un circuit mai complex pe un cip semiconductor, dar acest lucru a fost justificat fie de un număr de serie foarte mare de echipamente, fie de prețul echipamentelor (militare, aviatice sau spațiale). Microcircuite personalizate nu au putut satisface nevoia emergentă de miniaturizare a echipamentelor. Ar putea exista o singură soluție - să ofere dezvoltatorilor de hardware capacitatea de a schimba structura internă a microcircuitului (programului).

Istoria dezvoltării circuitelor integrate logice programabile (FPGA) începe odată cu apariția dispozitivelor de memorie programabile doar pentru citire. La început, ROM-urile programabile au fost folosite exclusiv pentru stocarea datelor, dar în curând au început să fie folosite pentru a implementa dispozitive digitale combinate cu un tabel de adevăr arbitrar. Ca dezavantaj al unei astfel de soluții, trebuie remarcată o creștere exponențială a complexității dispozitivului în funcție de numărul de intrări. Adăugarea unei intrări suplimentare pentru dispozitiv digital dublează numărul necesar de celule ROM. Acest lucru nu permite implementarea intrărilor multiple.

Pentru a implementa dispozitive combinaționale digitale cu un număr mare de intrări, au fost dezvoltate matrice logice programabile (PLM). În literatura străină, ele sunt numite - Programmable Logic Arrays (PLA). Este vorba despre matrice logice programabile care pot fi considerate primele circuite integrate logice programabile (Dispozitive logice programabile - PLD-uri). PLA-urile au fost utilizate pe scară largă ca primele cipuri de integrare mare de uz general.

Clasificarea FPGA

În prezent, circuitele integrate logice programabile se dezvoltă în mai multe direcții, așa că a devenit necesar să se facă oarecum distincție între aceste microcircuite. Clasificarea circuitelor integrate logice programabile (FPGA) este prezentată în Figura 1.


Figura 1. Clasificarea circuitelor integrate logice programabile (FPGA)

Aștepți un semn? Aici era!

De mulți ani am ezitat să încep să programez FPGA-uri, pentru că este dificil, costisitor și dureros (cum mi s-a părut). Dar e bine să ai prieteni care te ajută să faci primul pas. Și acum nu înțeleg un lucru - DE CE AM AȘTEPTAT ATÂT?

Acum te voi ajuta să faci primul pas!

Și de ce este pentru mine?

Te-ai săturat să citești în mod constant docurile de pe MK-ul tău sau să ții în cap o grămadă de informații. Ai rescris totul în asm, dar viteza încă nu este suficientă. Ai conectat două dispozitive externe la MK-ul tău, îl conectezi pe al treilea, dar ai rămas fără întreruperi, acele module care deja funcționau nu mai funcționează. Mai iei un MK, mai puternic din aceeași linie, dar din nou manuale, registre de steag, biți... la naiba. Schimbați platforma: treceți la un alt MK și aruncați cunoștințele pe platforma anterioară la coșul de gunoi. Orice ai face, e greu. Găsești o platformă populară în care poți asambla cu ușurință un proiect din componente, dar totuși nu poți sări peste limitările hardware ale acestui MK... Undeva la marginea conștiinței, uneori alunecă gândul că pe un FPGA ar fi cu siguranță funcționează rapid și în paralel, care este „exact sarcina care ar trebui rezolvată pe plis”, dar sunt bătrân / prost / ocupat / etc pentru a putea / începe să fac asta.

Vrei să respiri în sfârșit liber? Daţi-i drumul!

Bucuria dezvoltării FPGA

Am avut o zi grea la serviciu. De la un loc de muncă am ajuns la un al doilea loc de muncă, apoi la dacha, seara, treburile casnice, lecțiile, apoi familia vizionarea unui film, și abia la ora 23 eram complet liber! A spune că am obosit înseamnă a nu spune nimic. Dar în această stare, m-am așezat la laptop cu un scop ferm: să fac un generator de unde pătrate la 440 Hz. Au trecut 20 de minute și deja am auzit-o în căști. Nu-mi venea să cred urechilor! Mi-a luat încă 15 minute să fac PWM și să schimb volumul. Până atunci, aveam doar o placă cu FPGA timp de o săptămână și înainte de asta răsfoisem doar câteva cărți despre Verilog.

În seara aceea mi-am dat seama IATĂ-L! Aceasta este platforma în care îmi pot transforma rapid și ușor gândurile în hardware de lucru real!

De ce este asta?

Voi descrie avantajele care sunt în studiul și aplicarea FPGA-urilor, deși toată lumea le cunoaște deja:
  • Universalitatea cunoașterii- la schimbarea modelului MK, trebuie să citiți docurile. Când schimbați producătorul MK, trebuie să citiți docurile. Trebuie să citiți constant docuri, să păstrați în mod constant o grămadă de informații în cap. Când dezvoltați pe un FPGA, dacă cunoașteți Verilog sau VHDL, atunci puteți nu numai să programați orice FPGA din linia unui producător, ci și, dacă doriți, să treceți la altul (Altera, Xilinx). Deși vor exista momente cu dezvoltarea unui mediu de dezvoltare diferit, momente hardware subtile, însăși esența abordării de proiectare a dispozitivelor HDL nu se va schimba de la aceasta.
  • De la idee la hardware- la dezvoltarea unui proiect, daca iti lipseste un micro, atunci trebuie sa alegi altul. În principiu, se pot face ipoteze dacă acest MK va face față sau nu proiectului. Sau există un anumit MK și încercați să vă potriviți proiectul acolo. Cel mai adesea este. Îmi amintește cumva de apropierea bunicului meu, care face o scară din ce este în șopron. Deși puteți proiecta o scară, cumpărați scânduri care se potrivesc... De la idee la fier, și nu invers.
  • Ușurința de utilizare a evoluțiilor altor persoane- poți lua modulul altcuiva și îl poți aplica în proiectul tău. Prin cod puteți înțelege cum funcționează. Chiar dacă este pentru xilinx, și o faci sub altera. Uneori, acest lucru nu funcționează bine, dar este mai ușor decât, de exemplu, adăugarea de biblioteci binare la un proiect c++/Qt
  • blochează independența. Blocurile din HDL sunt ca funcțiile pure din PL. Ele depind doar de semnalele de intrare. Modulul dezvoltat și depanat va continua să funcționeze corect, indiferent de cum crește proiectul. Nimic din exterior nu va afecta funcționarea corectă a acestuia din interior. Și, în general, puteți uita cum funcționează - este o cutie neagră. De asemenea, blocurile funcționează. paralel.

Problema alegerii

Opriți cu putere întrebările despre ce să alegeți: Altera / Xilinx, Verilog / VHDL, care placa de depanare să ia. Dar mai întâi lucrurile.

Producător

Am ales Altera. De ce? Ei bine, eu și prietenul meu am decis așa, deși numele Xilinx este mai frumos pentru mine. DAR. Dacă nu poți alege chiar acum, o voi face pentru tine. Ai nevoie de Altera! De ce? Nu știu. Acum este mai important să faci un pas: să faci o alegere. Am ales Altera și nu am regretat până acum.



Limba

Luăm Verilog - deoarece… Ei bine, înțelegi.

Placă de depanare

Alegerea plăcii de depanare a durat cel mai mult. Este clar că plăcile diferă în ceea ce privește cipul FPGA instalat. Și cipurile FPGA diferă unele de altele prin numărul de elemente. Dar nu este deloc clar câte dintre ele vor fi necesare pentru proiectele dumneavoastră de testare. Prin urmare, de cele mai multe ori am petrecut căutând tot felul de proiecte FPGA pentru a afla cât de mult consumă resurse FPGA.

În familia Altera, pentru bani rezonabili, putem cumpăra plăci cu CPLD MAX II pentru 240, 570 și 1270 de elemente, sau cipuri FPGA mai vechi, care sunt Cyclone 1, 2, 3, 4 cu până la 10.000 sau mai multe celule. Cum să alegi?

Chiar și pe baza a 240 de celule, proiectul roverului Marte realizează doar un număr mare de proiecte. Vă recomand cu tărie să îl citiți pentru a vă face o idee aproximativă asupra complexității proiectelor care se pot încadra în 240 de celule. Pe de altă parte, există proiecte care sunt complet programate pentru o copie hardware a unui anumit PC, inclusiv procesorul și toată logica din jurul acestuia (NES, Speccy, Orion, UT-88 etc.). Acest lucru necesită deja cinci, zece sau mai multe mii de celule. În plus, aceste plăci conțin dispozitive externe suplimentare.

Prin urmare, aș sfătui să luați ceva între 240 și 10.000 de celule, cu preferință spre creștere în funcție de fondurile disponibile. Pe placa de depanare, celulele suplimentare nu sunt înfricoșătoare, iar dacă nu sunt suficiente, nu este nimic de făcut. Apoi, când dispozitivul este depanat, va deveni clar de câte celule aveți nevoie, cumpărați-l pentru suma potrivită, fără „kit de corp” inutil, mai ieftin și lăsați-l în dispozitivul finit.

Ceea ce diferă cu adevărat MAX de Cyclones, pe lângă numărul de celule, este:
1) Seria MAX nu are PLL în interior. Fiecare placă de dezvoltare are un oscilator, de obicei la 50 MHz. Acest lucru va fi suficient pentru cea mai mare parte a proiectelor. Toată sincronizarea va avea loc prin împărțirea a 50 MHz la o anumită valoare. Sau, puteți lua un generator extern și îl aplicați la o intrare FPGA separată. Dar dacă aveți nevoie de o frecvență de peste 50 MHz? Nu am reușit să găsesc generatoare de peste 50 MHz din mers. Dar aici PLL vine în ajutor, care este încorporat în Cicloni. Pe el, puteți înmulți frecvența, de exemplu, până la 100 MHz.
2) Seria Cyclone are unități de multiplicare hardware încorporate. Numărul lor depinde de modelul specific - aici puteți doar „vă uitați în instrucțiuni” pentru a afla câte. Dacă intenționați să faceți un fel de DSP, atunci vă vor fi la îndemână: vor salva celulele, vor crește viteza. Pe de altă parte, dacă nu există multiplicatori, aceștia pot fi sintetizați, dar un FPGA mic poate să nu aibă suficiente resurse pentru asta.

În toate celelalte privințe, am criteriul „potrivit / nu se potrivește”. Depanare pe o placă care este evident mai mare decât este necesar, urmată de completarea minimului necesar pentru aceasta.

Câți bani sunt necesari?


programator
Constat că nu am timp să lipim programatori liberi.

300 de ruble. L-am luat pe al meu de pe ebay si arata cam asa:

Placă de depanare
Alegerea este largă, în funcție de suma de bani.

Primul nivel 350 - 550 de ruble. Acestea sunt plăci pentru MAX II (sau celule). Ele pot fi potrivite pentru cunoașterea inițială și adaptarea ulterioară la dispozitivele finale. Placa are un generator, o pereche de butoane, o pereche de LED-uri, restul de 80 de pini sunt la discreția ta.

unitate de putere
Trebuie să fie, dar nu întotdeauna inclus. Veți avea nevoie de o sursă de alimentare de 5 volți și un curent de 2A.

Nivel mediu de la 900 la 1500 de ruble. Acestea sunt Cyclone 1, 2, 3, 4 plăci care diferă în principal prin numărul de celule.
Marcat astfel:
EP 2 C 5 T144 - Ciclonul 2 aproximativ 5k celule
EP 4 CE 6 E22C8N - Ciclon 4 aproximativ 6k celule
EP 2 C 8 Q208C8N - Ciclon 2 aproximativ 8k celule

Este posibil să observați că Ciclonul 3 poate avea mai multe celule decât Ciclonul 4.

Iată câteva opțiuni:

835 de ruble.
ALTERA FPGA CycloneII EP2C5T144 Placă de sistem minimă pentru a învăța bine

880 de ruble
Altera CycloneII EP2C5T144 FPGA Mini Development Learn Core Board E081

1265 de ruble
EP2C8 EP2C8Q208C8N ALTERA Cyclone II FPGA Evaluare Dezvoltare Placă de bază

Placi avansate . Acestea sunt plăci pe care sunt instalate module suplimentare (UTP, USB, AUDIO), conectori (SD, VGA), butoane, comutatoare, LED-uri, indicatoare cu șapte segmente etc. Sau poate exista o placă de bază și plăcile de expansiune pot fi atașate separat.

Am un astfel de kit - placa + placa de extensie:
Altrea EP4CE10E22 FPGA CORE Board+ Device Board USB/Sound/Ethernet/SD Card/VGA
2760 de ruble

Aici este placa principală. Are 2 LED-uri, 2 butoane, 4 comutatoare, un indicator cu șapte segmente și un cip RAM.

Placa de expansiune. Are SD, VGA, precum și controlere USB (High Speed ​​​​USB2.0 Chip: CY7C68013A), AUDIO (Placă de sunet de până la 96kHz/32bit ADC/DAC: WM8731S), UTP(100M interfață Ethernet: DM9000A):

Aceste plăci sunt pur și simplu introduse una în alta, dar încă le am în cutie. Pentru meseria mea, am o placă de breadboard, cu care mă conectez cu un cablu care vine cu trusa. De asemenea, vine cu o sursă de alimentare de 5 volți.

Am fost obligat să scriu acest articol de tovarăși care înțeleg controlorii foarte bine (mult mai bine decât mine) și le folosesc peste tot. Cu toate acestea, există un număr mare de aplicații în care utilizarea FPGA-urilor nu este doar justificată, ci duce și la o simplificare semnificativă a sistemului și la îmbunătățirea parametrilor acestuia. O să fac imediat o rezervare: în acest articol și, eventual, în articolele ulterioare, consider doar FPGA-uri Xilinx, nu pentru că m-au plătit și nici măcar pentru că sunt cei mai buni, tocmai s-a întâmplat istoric să lucrez aproape exclusiv cu ei. .

Deci, să începem cu puțină teorie. FPGA sunt împărțite în două grupe principale: CPLD (Complex Programmed Logic Device) și FPGA (Field Programmed Gate Array). CPLD- acesta este de obicei un FPGA din clasa „economie”, adică au un preț scăzut și o cantitate destul de redusă de resurse, acest lucru se observă în special pe declanșatoare. FPGA de obicei mai scumpe, conțin mai multe resurse (logică simplă - declanșatoare...) și, cel mai important, blocuri „complexe” de curând suplimentare, precum multiplicatori, memorie bloc, obiecte personale de interfață (Ethernet, PCI-express...) și chiar Miezuri de procesor PowerPC. Separat, putem aminti seria Zinq de la Xilinx - în general au umplut nuclee ARM acolo. Principala diferență dintre FPGA și CPLD este necesitatea de a încărca configurația la pornire și, în consecință, un ROM extern cu configurația. Chiar și familia SPARTAN-3AN are un ROM încorporat la bord, de pe care se încarcă.

Acum, cel mai important lucru: cum diferă un FPGA de un controler și când să le folosești. Totul este destul de simplu aici: FPGA (le luăm pe cele fără clopoței și fluiere) este, de fapt, un sac de logică pe un singur cip, care poate fi conectat în mod arbitrar: aceleași declanșatoare, AND, OR și primitive similare, cum ar fi, pt. de exemplu, în seria K155 sau 74HC. Controlerul, pe de altă parte, este un procesor gata făcut (deși cu un număr mic de comenzi), memorie încorporată, magistrale de date și comandă, periferice etc. În general, puteți face un controler mic dintr-un FPGA mare, dar această idee este cel puțin stupidă. Deci, controlerul este ascuțit pentru executarea lanțurilor lungi de comenzi, repetarea lor ciclică, trecerea de la un lanț la altul etc., iar FPGA este ascuțit pentru a efectua operații logice simple și, important, un număr mare deodată (și chiar și la frecvențe de ceas diferite) .

Să trecem de la teorie la practică. Pentru început, avem nevoie de un fel de cip CPLD. Sunt puține resurse, dar pentru dezvoltare este cea mai mare. Voi lua XC95288XL în carcasa TQ144 (din nou, tocmai s-a întâmplat să fie disponibil), în general recomand să luați ceva mai proaspăt, de exemplu, din seria CoolRunner 2. Pentru a obține produsul finit (chiar dacă clipește puțin cu un LED), trebuie să: lipim hardware-ul (sper că nu vor fi probleme aici, dar voi menționa nuanțele), „scriem” firmware-ul (în caz, mai degrabă, desenați-l) și introduceți firmware-ul în microcip. În general, avem nevoie de software care generează firmware și un programator. Software-ul (Xilinx ISE Webpack) este descărcat de pe site-ul oficial (cu toate acestea, vă vor cere să vă înregistrați), licența Webpack este gratuită. Programatorul poate fi realizat conform schemei din Fig. 1 (pentru un port LPT) sau puteți achiziționa un USB-shny din fabrică (în magazinele online chinezești am întâlnit la un preț de aproximativ 50 de dolari, dar nu l-am cumpărat eu însumi ). Mai mult.

Orez. 1

După ce am lipit FPGA-ul pe placa, am lipit sau am cumpărat un programator, am descărcat și instalat pachetul ISE Webpack (am versiunea 13.2), lansăm Project Navigator și creăm un nou proiect. Pentru a crea un proiect, selectați Fișier -> Proiect nou, specificați numele proiectului și unde să îl salvați, specificați și tipul sursei TOP-LEVEL (Fig. 2). Faptul este că pentru un FPGA nu este necesar să desenați o diagramă a declanșatorilor și a conexiunilor acestora, puteți, de exemplu, să scrieți în limbaje de nivel înalt (VHDL, Verilog) și nu este deloc necesar să folosiți un singur lucru în cadrul aceluiași proiect. Pentru moment, folosim doar Schematic la toate nivelurile.


Orez. 2
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

În fereastra următoare (Fig. 3) ne selectăm microcircuitul (nu atingem restul la început); în fereastra care apare după ce faceți clic pe butonul „Next”, admirați parametrii proiectului creat, faceți clic pe „Finish” - și gata: proiectul a fost creat.


Orez. 3

Acum trebuie să desenăm de fapt o diagramă: faceți clic dreapta pe fereastra cu proiectul și noua sursă (Fig. 4.), Dați un nume acestei surse (acesta este numele circuitului nostru, pot fi multe dintre ele în proiect), selectați din nou Schematic, faceți clic pe „Next”, admirați parametrii fișierului nou creat, faceți clic pe „Finish” și obțineți o schemă curată.


Orez. 4
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

Începe distracția: pe panoul din stânga (nu chiar de la margine), apăsați butonul „adăugați simbol” (Fig. 5).


Orez. 5
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

Și ajungem și mai mult la stânga o listă de simboluri ale bibliotecii curente. Cum să adăugați, să creați, să editați biblioteci, vom afla mai târziu (după caz). Acum este important pentru noi să alegem simbolul necesar. Așadar, în fereastra de sus vedem un anumit clasificator - un filtru care nu este necesar să îl folosim (ei bine, de ce să parcurgeți tot felul de declanșatoare și elemente logice atunci când avem nevoie de un contor).

De exemplu, luați în considerare următoarea sarcină: trebuie să determinați cu precizie timpul de întârziere dintre marginile de început ale 2 impulsuri care apar pe fire diferite și să îmbinați această valoare în controler prin interfața SPI. Orice similitudine a sarcinii cu subiectul „Creșterea frecvenței de operare a MK” de pe unul dintre forumurile robotizate este intenționată. Deci, la intrarea dispozitivului sunt 2 fire pentru impulsuri și 3 fire pentru controlerul SPI. Adăugăm și o intrare de ceas (deși nu știm la ce frecvență, putem doar presupune că este de cel puțin 70 MHz). Începem să desenăm firmware-ul: avem nevoie de declanșatoare latch care vor „prinde” impulsuri, un contor de timp, un registru de deplasare (nu trebuie să le creați, sunt de bibliotecă). Nu voi descrie ce sunt declanșatorii și contoarele, sper că cititorii sunt „în cunoștință” și nu vor fi probleme, altfel va trebui să mai scriu câteva articole. Avem o astfel de schemă (Fig. 6), după cum puteți vedea, nu este necesar să trageți firul de la ieșirea simbolului la intrare, este suficient doar să apelați circuitul. Pentru a desemna intrările și ieșirile externe, utilizați butonul „Add I/O Marker”.


Orez. 6
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

Când schema este gata, accesați fila Design și faceți dublu clic pe Implement Design - încep tot felul de procese (pentru început, nu contează care dintre ele - principalul lucru este că totul împreună este procesul de distilare codul sursă în firmware). Când totul merge bine, ne uităm la erori cu avertismente: reparăm tot ce este important, lăsăm restul. De exemplu, nu avem nevoie de ieșirile SEO și TS ale contorului, iar restul de 15 biți ai ieșirii paralele a registrului de deplasare nu sunt, de asemenea, necesari, dar jură pe avertismente. Dacă jură pe erori că vrem așa, atunci vrem ceva greșit. Dacă totul ni se potrivește (și sintetizatorului) - continuăm să admirăm rapoartele: câte resurse au fost cheltuite, ce frecvențe de ceas sunt disponibile... Dacă totul este din nou în regulă, atunci este timpul să simulăm circuitul și să ne asigurăm că acesta de fapt funcționează conform sarcinii. După verificarea timpurilor, vă sugerez să faceți simularea pentru că uneori trebuie să agitați întregul circuit pentru a obține frecvența de ceas dorită, ceea ce, desigur, poate afecta rezultatul...

Deci, simulare: în fila Design (în panoul din stânga), selectați simulare (Fig. 7).


Orez. 7
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

Mai jos, în procese, în locul proceselor de sinteză și cablare, a apărut procesul Simulare model comportamental, dublu clic pe el - pornește simulatorul, în care ne vedem semnalele (nu doar intrare-ieșire, ci și intermediare) ( Fig. 8).


Orez. 8
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

Mutați cursorul mouse-ului peste butoane, citiți comentariile la butoane. Setăm timpul de pas de simulare (Fig. 9) și valorile inițiale ale semnalelor de intrare, setăm imediat semnalele de ceas (nu vom simula și comuta ceasul la fiecare 5 ns).


Orez. 9
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

Pasând în timp prin manipularea intrărilor și (dacă este necesar) cu pasul de simulare, obținem o diagramă de timp (Fig. 10).


Orez. 10
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

Ne asigurăm că totul funcționează conform intenției (sau depanăm în continuare circuitul) și trecem la pasul următor - distribuția ieșirilor și intrărilor de-a lungul picioarelor microcircuitului. Pentru a face acest lucru, adăugați un alt fișier sursă (Fig. 11), și anume Fișierul Implementation Constraints.


Orez. unsprezece
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

Noi prescriem „pinout-ul microcircuitului” (Fig. 12), aici prescriem cerințele pentru frecvențele de ceas. Și aici ajungem la nuanța asociată cu semnalele de ceas. Cert este că semnalele de ceas trebuie să vină la așa-numitele linii globale - linii care trec prin întregul microcircuit, restul liniilor sunt de natură locală și trec prin logica de comutare de la bloc la bloc. Cipul XC95288XL din pachetul TQ144 are 3 astfel de linii și sunt conectate la picioarele 30, 32, 38. Semnalele rămase pot fi conectate la orice pini I/O.


Orez. 12
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

Din nou, faceți dublu clic pe Implement Design, așteptați, citiți comentariile pe tema avertismentelor cu erori și accesați rapoartele despre pinouts (Fig. 13) și timings (Fig. 14); ne asigurăm că totul ni se potrivește și avem fericire sub forma unui fișier %project_name%.jed.


Orez. 13
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)


Orez. 14
(imagine se poate face clic pentru mărire, se va deschide într-o fereastră nouă)

Fișierul firmware este gata. Să spunem și dispozitivul. Conectam cablul JTAG la computer și facem dublu clic pe Configure Target Device. Utilitarul de firmware (Impact.exe) va porni, de fapt, la fabricarea mai multor dispozitive pentru flash-ul unei serii, vă puteți limita la lansarea doar a unuia dintre ele. Creăm un nou proiect (acesta este un proiect pentru un program de firmware), lăsăm să găsească automat programatorul și microcircuitul conectat, arătăm fișierul firmware și facem clic pe Program. Așteptăm câteva zeci de secunde, vedem o inscripție că totul este în regulă - dispozitivul este gata.


Câmp semănat cu matrice de porți programabile

Începem un curs de prelegeri despre ce este logica programabilă și cum să începem să o folosim în beneficiul nostru și al vecinului nostru...

FPGA- deci se numește în rusă. P programabil L logic ȘI integrală CU hema.
În burgheză sună puțin diferit - FPGA - F câmp de P programabil G a mancat A razele. Literal, se traduce prin „Un câmp semănat cu matrice de porți programabile”.
Pentru a fi puțin mai serios, o puteți numi „Matricea porții programabile”

Ce este o supapă?
Așa e, la subsol există așa ceva pe o conductă de apă, care dacă o dai peste cap, toată casa va rămâne fără apă. Pe scurt, este ceva care se poate închide și deschide.

Deci, să fie o revelație pentru tine, dar fiecare microcircuit este format din porți. Adevărat, nu seamănă prea mult cu ceea ce avem tu și cu mine la subsol. Dar ei fac același lucru - se deschid și se închid.

Supapă- aceasta este o componentă elementară a oricărui microcircuit digital.

Chiar și cel mai sofisticat supermegaprocesor constă din supape. Sunt multe, multe, doar o mare întreagă dintre ele. Desigur, în fiecare microcircuit, porțile sunt conectate într-un anumit fel. De fapt, funcționalitatea microcircuitului depinde de modul în care sunt conectate.

În microcircuitele convenționale, schema de conectare a porții este setată în timpul producției și, ulterior, nu mai poate fi schimbată.
FPGA ne permite să setăm singuri acest circuit și să îl schimbăm după bunul plac în timpul „vieții” microcircuitului. Este suficient doar să desenați un circuit pe un computer și, folosind un programator, să îl introduceți într-un cip FPGA.

Aceasta este în general.

De fapt, totul este mult mai complicat :) Uită-te la poză


Aceasta este o macrocelulă - Macrocell în limba lor.
Fiecare cip FPGA este format din astfel de macroce... macrocelule. După cum se poate vedea din diagrama de macrocelule, acesta constă dintr-un bloc Tabel de căutare ( LUT) - „Tabel de căutare”, de asemenea, declanșatorul cu intrări sincrone și asincrone și ceva logică pe intrările de declanșare. De fapt, doar LUT este programat. După cum puteți vedea, are 4 intrări și o ieșire. Această ieșire poate fi conectată fie direct la ieșirea macrocelulă (Q0), fie la intrarea de date de declanșare sincronă (D).

LUT nu este altceva decât un ROM pentru celule de 16 biți. Când o anumită combinație de semnale digitale este aplicată intrărilor LUT (D0 ... D3), le percepe ca o adresă și scoate la ieșire conținutul celulei la această adresă.

În general, orice circuit de poartă care are 4 intrări (sau mai puține) și o ieșire poate fi descris printr-un tabel de adevăr pe 16 rânduri. De exemplu, să luăm un astfel de circuit simplu și să scriem un tabel de adevăr pentru el:

Tabelul de adevăr descrie nivelul logic al ieșirii circuitului (Q) pentru toate combinațiile posibile de semnale la intrări (D0…D3). În același mod, în LUT, fiecare combinație de semnale de intrare (citește - fiecare adresă ROM) are propriul semnal de ieșire. Adică, tabelul de adevăr al circuitului pe care vrem să-l vedem în locul lui este cusut în LUT. Este atat de simplu!

Dacă circuitul conține mai mult de 4 intrări sau mai mult de 1 ieșire, sunt utilizate LUT-urile mai multor macrocelule.

clear="toate">

Dar cel mai important lucru este declanșatorul. La urma urmei, după cum știți (sau poate nu știți încă), toate registrele, contoarele și multe alte elemente ale tehnologiei digitale constau în flip-flops. Deci, numărul de macrocelule din cipul FPGA determină numărul de declanșatoare. Și invers :) Deci, atunci când alegeți un microcircuit pentru orice proiect, trebuie mai întâi să estimați câți declanșatori vor fi în circuit și să îl luați cu o marjă ...

Figura de mai jos prezintă o diagramă bloc a cipurilor Altera din seria EPM7000. Această imagine este extrasă din fișa de date https://www.altera.com/literature/ds/m7000.pdf Se referă la cipurile EPM7032, EPM7064, EPM7096. Deci, ultimele două cifre din nume indică exact numărul de macrocelule din microcircuit.


După cum se poate vedea din diagramă, macrocelulele sunt combinate în „blocuri de matrice logice” (LAB - Logic Array Block).
Aceste blocuri sunt interconectate printr-o „matrice de interconectare programabilă” (PIA).
În plus, LAB-urile sunt conectate la pinii microcircuitului prin blocuri de control I/O.

Când clipește, fiecare dintre blocuri este „cusut” cu propriile sale informații:
- LUT-urile sunt programate în Macrocell,
- PIA stochează informații despre interconexiunile interne,
- informațiile despre conexiunile la picioarele microcircuitului sunt cusute în blocurile de control I/O.

Serios, FPGA „firmware” se numește „configurație de încărcare”.

Și ce părere aveți, cu ce vom încărca configurația?
Ei bine, bineînțeles, vechiul Byte Blaster! :) Byte Blaster este un lucru universal :) Despre cum să-l faci, am povestit în detaliu aici

Top articole similare