Programmerbar logik (CPLD/FPGA)

Här skriver vi inga frågor. Här finns svaren.
cyr
Inlägg: 2712
Blev medlem: 27 maj 2003, 16:02:39
Ort: linköping
Kontakt:

Programmerbar logik (CPLD/FPGA)

Inlägg av cyr »

Som utlovat så skriver jag lite om programmerbar logik. Har tänkt skriva flera delar, och den här första blir bara en liten introduktion. Sen tänkte jag fylla på med en liten "tutorial", och sen får vi väl se... Kommentarer, rättningar och önskemål tas gärna emot.

Jag tänker mig att den som läser den här guiden har lite grundläggande kunskaper i digitalteknik, och i "vanlig" programmering av t.ex. mikrokontrollers.

Hårdvaran

Det finns flera olika typer av programmerbara logikchip, de som används idag kan grovt delas in i två kategorier:

CPLD (Complex Programmable Logic Device):
  • Liten (c:a 30 - 1000 logikceller, 40 - 256 pinnar).
    Billig (c:a $1 - $50 styckvis)
    Behåller sitt "program" när strömmen stängs av.
FPGA (Field Programmable Gate Array)
  • Stor (c:a 500 - 200000+ logikceller, 100 - 1500+ pinnar)
    Dyr (c:a $10 - $1000+ styckvis)
    Måste laddas med sitt "program" utifrån varje gång man slår på strömmen.
Gränsen mellan CPLD och FPGA (och andra namn som en del tillverkare använder) är lite diffus idag. Det finns t.ex. FPGA:er som har ett internt flashminne och därmed inte behöver programmeras utifrån varje gång den slås på.

Vad är en logikcell?

Logikcellen är det grundläggande byggblocket i alla programmerbara logikchip och ser ut på ungefär samma sätt (om man inte tittar för noga :) )

Den har ett antal ingångar (i en FPGA oftast 4, i en CPLD ofta fler) som går in till ett kombinatoriskt nät, vars utgång går vidare till en vippa. Det kombinatoriska nätet är en del av det som gör kretsen programmerbar, det kan nämligen programmeras till att skapa vilken logisk funktion som helst av ingångarna.

Dessutom finns ett programmerbart nätverk av ledningar som kan koppla ihop logikcellerna med varandra och med IO-pinnar och andra byggblock som kan finnas i kretsen.

I FPGA:er kan man ofta förutom de vanliga logikcellerna hitta en del andra saker, bland annat minnen, multiplikatorer och t.o.m. hela PowerPC-processorer!

Tillverkare

De två största tillverkarna av programmerbar logik är Altera och Xilinx, men det finns även en hög andra märken (Atmel, Actel, Cypress, Lattice, Quicklogic...). Själv har jag bara erfarenhet av de två första, så jag tänker inte uttala mig om resten.

Både "märke A" och "märke X" har gratis mjukvara man kan ladda ner, och en online-shop där man kan köpa chip styckvis.

När det gäller billiga FPGA:er har Xilinx Spartan3 och Altera har Cyclone/Cyclone2. Den allra största skillnaden mellan dessa är att Spartan3 och Cyclone2 båda har inbyggda multiplikatorer medan Cyclone (1) saknar dessa. Något som talar för Xilinx är kanske att det finns ett ganska användbart Spartan3 "starterkit" för bara $99.

Språken

Man använder vanligtvis ett av språken VHDL eller Verilog för att skriva "programmet" till sin FPGA/CPLD. VHDL är mest populärt i Europa medan Verilog används mest i USA. VHDL har ett syntax som påminner en del om ADA eller Pascal, medan Verilog är mer likt C. Personligen gillar jag Verilog, så det kommer jag att använda till exempelkod.

Både VHDL och Verilog var från början bara avsedda för att beskriva och simulera hårdvara, inte för att syntetisera (skapa) hårdvara automatiskt. Det finns en del saker som är giltiga i språket, men som inte går att syntetisera till något vettigt.

Mer om Verilog kommer i nästa del, inom ett par dagar!
Användarvisningsbild
jack
EF Sponsor
Inlägg: 2059
Blev medlem: 5 oktober 2004, 17:32:27

Inlägg av jack »

Skitbra initativ.
En liten fundering bara.. Hur ser en FPGA med 1500 pinnar ut?
cyr
Inlägg: 2712
Blev medlem: 27 maj 2003, 16:02:39
Ort: linköping
Kontakt:

Inlägg av cyr »

Ungefär såhär (underifrån):

Bild

"Pinnar" är kanske inte riktigt rätt ord, det är alltså BGA-paket det handlar om.
cyr
Inlägg: 2712
Blev medlem: 27 maj 2003, 16:02:39
Ort: linköping
Kontakt:

Del 2: Verilog

Inlägg av cyr »

OK, dags för andra delen - några små Verilog-exempel.

Vi börjar med ett riktigt trivialt exempel, en OCH-grind:

Kod: Markera allt

module and_gate(a,b,y);

   input a,b;
   output y;

   assign y = a & b;

endmodule
Här har vi definierat en modul vid namn "and_gate", med tre portar (a,b och y). Den har två ingångar (a,b) och en utgång (y). Utgången tilldelas (assign) värdet "a & b", vilket betyder logisk (bitvis) AND precis som vanligt.

Exempel 2, en 8-bitars 2:1 MUX:

Kod: Markera allt

module mux2_8(a,b,y,sel);

   input [7:0] a,b;
   input sel;
   output [7:0] y; 

   assign y = (sel == 1'b0) ? a : b;

endmodule
Här är portarna a,b och y vardera 8 bitar, numrerade från 7 ner till 0. Assign-raden ser nog bekant ut för de som kan C, men totalt obegriplig annars. Om det som står före frågetecknet är sant används det första värdet, annars det andra. Alltså, om sel är 0 sätt y = a, annars sätts y = b. Precis som i C används "==" för jämförelse och "=" för tilldelning, och precis som i C kan man få konstiga resultat om man råkar skriva fel!

Konstanter i Verilog skrivs på formen " n'rv ", där n är storleken (antalet bitar), r är radix (binärt, hexadecimalt eller decimalt) och v är själva värdet.

Exempel:

1'b1 , 4'h9, 16'd4500

Man kan utelämna stolek och radix, och bara skriva t.ex. 12345. Det tolkas då som ett decimalt tal med storleken 32 bitar. I de flesta situationer så spelar dock storleken på konstanter inte någon roll, de konverteras automatiskt för att passa det man tilldelar eller jämför med.

Exempel 3, en 4-bits binär räknare med synkron reset:

Kod: Markera allt

module cnt4(clk,rst,out);

   input clk,rst;
   output reg [3:0] out;

   always@(posedge clk)
      if(rst) out <= 0;
      else out <= out+1;

endmodule
Här har vi några nyheter, för det första ordet "reg". Det betyder inte nödvändigtvis att den här signalen är en vippa, men ofta är det så. Själva ordet "reg" tillför egentligen inte mycket till språket, men om en signal ska tilldelas inuti en always-sats måste den definieras som "reg".

Den andra nyheten är "always@(posedge clk)". Det kan verka något kryptiskt, men betyder ungefär "varje gång clk går hög ska detta hända". Always-satser används dels för att skapa klockad logik (vippor) som i det här fallet, men kan också användas för att skapa ren kombinatorik (grindar), som i nästa exempel:

Exempel 4, en 1-av-4 avkodare:

Kod: Markera allt

module decoder(in,out);

   input [1:0] in;
   output reg [3:0] out;

   always@(in)
      case(in)
         2'b00: out <= 4'b0001;
         2'b01: out <= 4'b0010;
         2'b10: out <= 4'b0100;
         2'b11: out <= 4'b1000;
      endcase

endmodule
Observera att utgången även här är "reg", men det skapas inga vippor. Istället för "posedge clk" i always-satsen har vi "in". Om man listar alla signaler som används inuti always så "körs" den varje gång någon av dessa signaler ändras, vilket gör att inga värden behöver lagras och därmed inga vippor! För att slippa lista alla signaler kan man instället skriva "always@(*)".

Ni har nog lagt märke till att jag använder "<=" istället för "=" för tilldelning här, det beror på att Verilog har två olika sorters tilldelning, "blocking" och "non-blocking". Det finns rätt och fel tillfällen för båda varianterna, och många lägen där det kvittar, men om man följer regeln att alltid använda "<=" inuti always-satser och "=" utanför så uppnår man troligen det resultat man vill ha.

Nu har jag bara visat en liten del av Verilog-språket, men förhoppningsvis räcker det för att få en liten uppfattning om hur det kan se ut när man "kodar hårdvara".

En snabbreferens till Verilog finns här:
http://www.sutherland.com/on-line_ref_g ... f_top.html

I nästan del tänkte jag visa hur man kan sätta ihop några enkla moduler skrivna i Verilog, syntetisera det hela och testa i en FPGA.
cyr
Inlägg: 2712
Blev medlem: 27 maj 2003, 16:02:39
Ort: linköping
Kontakt:

Inlägg av cyr »

OK, det är väl hög tid att jag skrev vidare här...

Dags att göra något på riktigt! Det blir något så fantastiskt som en sekund-räknare som räknar från 0 till 99.

Hårdvaran består av det här utvecklingskortet, som bland annat innehåller en nästan antik FPGA samt en oscillator, knappar och LED-displayer.

Bild.

FPGA:n är en Altera FLEX10K, inte precis det bästa man kan hitta men det klarar nog av den här uppgiften :)

Mjukvaran som behövs är gratisversionen av Altera Quartus, och kan hämtas här: http://www.altera.com/support/software/ ... enter.html

Koden till sekundräknaren består av fyra verilog-filer:

bcd_counter.v - En dekad-räknare (räknar 0-9).
bcd_to_7seg.v - Översätter BCD-kod till motsvarande bitmönster för att driva en LED-display.
tick_generator.v - Skapar 1Hz-tick från klockan på kortet.
sec_cnt.v - Topp-blocket, som kopplar ihop de övriga blocken.

De tre första filerna används som komponenter i den fjärde, ungefär på samma sätt som man anropar funktioner i vanliga programmeringsspråk. Så här ser det ut:

Kod: Markera allt


	tick_generator tickgen(
		.clk(clk),
		.rst(rst),
		.out(tick)
		);

tick_generator är namnet på modulen man vill använda (definierat med "module tick_generator" i en annan fil). tickgen är instans-namnet (samma modul kan användas flera gånger i samma fil, därför behövs unika namn).

De resterande raderna talar om hur modulens in- och utgångar ska kopplas ihop med signalerna i den här filen. Ingångarna "clk" och "rst" kopplas till signaler med samma namn, medan utgången "out" kopplas till en signal som heter "tick". Signalerna man kopplar till kan vara definierade som in- eller utgångar eller som interna signaler (wire).

För att kunna syntetisera och testa koden måste man skapa ett projekt i Quartus, lägga in filerna ovan och ange vilken fil som är "top-level". Det går till på följande sätt (om någon vill testa).

Starta Quartus.
Välj File -> New Project Wizard
Sökväg och namn spelar inte någon större roll, men "top-level" ska vara "sec_cnt" i det här fallet. Det går dock att ändra senare om man vill (eller skriver fel).
På nästa sida kan man lägga till verilog-filerna i projektet, men det kan även göras senare (oftast så har man ju inte filerna färdiga när man startar ett nytt projekt...)
På sidan tre väljer man vilket chip som ska användas. I det här fallet är det FLEX10K EPF10K70RC240-4
Det är alla inställningar som behövs, klicka på "finish".

Om man lagt in verilog-filerna i projektet ska de finnas med i fil-listan under "Project navigator" på följande sätt:

Bild

Om man nu syntetiserar projektet kommer alla in- och utgångar i top-level modulen att bli fysiska in- och utgångar på FPGA:n, men vi måste tala om vilka pinnar som ska användas. Om man klickar på "Assignments -> Pins" kan man åstadkomma detta, bara att peka och klicka:

Bild

Vilka pinnar som ska användas får man förstås lista ut med hjälp av manualen när man har ett färdigt kort som detta, men när man bygger sitt eget kan man välja (nästan) fritt, vilket kan underlätta väldigt mycket när man ska göra PCB-layout!

I det här exemplet har vi två ingångar, "clk" som kopplas till oscillatorn på kortet (25.175MHz) och "rst" som är en aktivt låg reset-ingång och kopplas till en av knapparna på kortet. Utgångarna är 2x8 bitar till LED-displayerna på kortet.

Nu kan vi syntetisera ("kompilera") koden, genom att klicka här:

Bild

Efter några sekunder får man veta att allting var OK, och lite information:

Bild

Vi ser bland annat att vi använt 2% av logikcellerna i FPGA:n...

Nästa steg är att ladda FPGA:n och se om det hela fungerar, för att programmera chip klickar man här:

Bild

Om det är första gången måste man först göra lite inställningar, t.ex. vilken sorts nerladdningskabel man har och vilken port den är kopplad till. Sen är det bara att klicka på "start", och:

http://area26.no-ip.org/linked/pltut/pltut_counting.avi

Det var väl spännande? :)
Användarvisningsbild
Mignon
EF Sponsor
Inlägg: 174
Blev medlem: 6 mars 2006, 18:37:46
Ort: Göteborg
Kontakt:

Inlägg av Mignon »

För den som vill se ett exempel på VHDL-kod så kommer här OCH-grinden i VHDL:

Kod: Markera allt

library IEEE;
use IEEE.std_logic_1164.all;

entity portar is
    port (a : in std_logic;
          b : in std_logic;
          y : out std_logic; );
end entity portar

architecture andGate of portar is
 begin
    y <= a and b;
end andGate


VHDL skriver och simulerar man förslagsvis i ModelSim som finns att ladda hem här: http://www.model.com
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43150
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

Skitbra !
Men ska det inte över till wiki'n ?

EDIT : Heja danei !! :-)
Senast redigerad av sodjan 7 mars 2006, 14:59:30, redigerad totalt 1 gång.
danei
EF Sponsor
Inlägg: 26335
Blev medlem: 2 juni 2003, 14:21:34
Ort: Östergötland
Kontakt:

Inlägg av danei »

GeekJoan skrev:I denna kategorin Guider / FAQ skriver vi inga frågor alls. Här finner ni guider och frågor som brukar komma upp. Alla "nybörjarfrågor" hänvisas till Allmänt!
Användarvisningsbild
manw
Inlägg: 207
Blev medlem: 16 november 2005, 11:16:17
Ort: Södermalm

Inlägg av manw »

Det här var en höjdartråd. Hittade den först nu fast den är gammal. Tråkigt att den aldrig kom över till "Wikin" och bilderna försvann :(
Skriv svar