Wat leren we vandaag ? Logica maken in CPLD/FPGA met SystemVerilog

Op zondag 9 november 2025 16:41:36 schreef free_electron:
Een ander voorbeeld : maak een programme wat een 8 bit getal inleest en de bits omdraait (lsb en msb swap)
Dat is flink wat werk in een computerprogramma.

In programmeerbare logica ?


uitgang[7:0] = ingang[0:7]

Benodigde logica ? NIKS. Alleen wat draden !

in werkelijkheid zal de synthesizer een foutmelding geven omdat het bit order in de vector (een waarde langer dan 1 bit is een vector. er zijn geen bytes, integers , signed of andere dingen. het is 1 bit of een array van bits met een gegeven lengte en orde: een vector) anders is.

je omzeilt dit door het op te breken in stukjes voor de synthesizer:


uitgang[7] = ingang[0]
uitgang[6] = ingang[1]
...
uitgang[0] = ingang[7]

Je kan dit ook in een lus doen.


for (i=0,i<8,i++) begin
    uitgang[i] = ingang[7-i]
end

Die lus wordt dan uitgevoerd tijdens de synthese en het resultaat is nog steeds draden !

Lussen in een synthesetaal worden gebruikt om logische functies te herhalen.

Dit geeft aan hoe krachtig een synthesetaal + programmerbare logica is in vergelijking met een programmeertaal en een processor.

Dat probleem kwam ik tegen bij het inlezen van de bitjes van een E-paper module via SPI met AVR.
Die bitjes in het byte moesten achterstevoren ingelezen worden.
Oplossingen: https://omarfrancisco.com/reversing-bits-in-a-byte/
Vooral die hocus pocus in C intrigeerde me (listing 2)
Zie ook Stackoverflow: https://stackoverflow.com/questions/2602823/in-c-c-whats-the-simplest-…

Uiteindelijk lijkt me de beste (snelst werkende) oplossing een tabelletje van 256 bytes. Tegenwoordig hebben AVR's veel grotere flash geheugens. Genoeg ruimte voor tabelletjes dus.

In assembly de instructies "rol" en "ror" gebruiken in een loop is simpel en zeer snel om bits in een byte om te draaiien en kost slechts enkele bytes en geen storage (maar daar is heden ten dage plenty van).

Op donderdag 4 december 2025 09:54:30 schreef Spog2:
Oplossingen: https://omarfrancisco.com/reversing-bits-in-a-byte/
Vooral die hocus pocus in C intrigeerde me (listing 2)

ERG slecht leesbaar daar omdat er ergens << niet goed voor HTML ge-escaped is. (CO doet dat wel goed: ik kan gewoon << typen).

In een AVR (en de meeste andere processors) kan je meestal bij het instellen van de SPI module aangeven welke kant ie op moet shiften en dus welk bitje eerst gaat.

Die ATTINY 2313 heeft geen SPI module, maar USI: Universal Serial Interface. Ik dacht dat die ook zo'n linksaf of rechtsaf bitje had, maar kennelijk niet. Of in ieder geval in de 2313 niet.

@Bobosje, dat kan inderdaad. Dan gebruik je het carry bitje als extra storage tussen de twee shifts. Heb je wel twee registers nodig.


int reverse (int a)
{
  int b=0;
  for (int i=0;i<8;i++) {
    b <<= 1;
    b |= a & 1;
    a >>= 1;
  }
  return b;
}

wordt door gcc voor AMD64 gecompileerd naar:

        movl    $8, %edx
        xorl    %eax, %eax
        .p2align 4,,10
        .p2align 3
.L2:
        movl    %edi, %ecx
        addl    %eax, %eax
        sarl    %edi
        andl    $1, %ecx
        orl     %ecx, %eax
        subl    $1, %edx
        jne     .L2
        ret

6 instructies binnen de loop.

ARM en AVR zijn vergelijkbaar. (op AVR moest ik daarvoor de declaratie naar 8bits char veranderen).

Het kan dus met ongeveer 3 instructies binnen de loop. (rol, ror, dec).

Op donderdag 4 december 2025 14:39:27 schreef rew:
[...]
In een AVR (en de meeste andere processors) kan je meestal bij het instellen van de SPI module aangeven welke kant ie op moet shiften en dus welk bitje eerst gaat.

Ik liep er tegenaan bij deze 200x200 E-paper van Waveshare: https://www.waveshare.com/product/displays/e-paper/epaper-3/1.54inch-e…

Ik wou de "9 bit SPI" (zie page 7 Datasheet )gebruiken omdat die met slechts 3 draden toe kan.
Dat is geen echte SPI, maar moest (meen ik te herinneren) via serial USART. De Commandrichting en Leesrichting gebruiken een tegengesteld formaat LSB-MSB / MSB-LSB. Dat was niet snel om te schakelen naar mijn idee, de snelste routine met de minste draden leidde tot het byte om te keren via tabelletje.
Ik gebruik Atmega 1284P

Vandaag mijn nieuw Cyclone10LP boardje aangesloten. Het programmeren verliep eerst niet zo vlot. Dus eerst nog even de laatste releases bijgenomen. Ze hebben in de laatste versie een grotere flash configuratie chip gebruikt. Als je de userguide bijneemt om te zien hoe je de programmer moet instellen dan staat daar natuurlijk nog de oude kleine flash device nog vermeld. T'ja dan maar opnieuw de procedure doorlopen om te zien hoe je indirect zo een flash moet configureren. En ja dat zijn toch nog wat verschillende stappen. Maar goed na wat foutieve instellingen ben ik toch geslaagd om het voor elkaar te krijgen. Probleem is dat je alles in een maal moet goed doen, nieuwe display aansluiten, de juiste I/O pinnen selecteren enz. Maar hier staan de beide versies, eentje met de MAX1000 en eentje met de Cyclone10LP:

Beide boardjes hebben dezelfde pinout volgorde. De aansluiting is net hetzelfde voor beiden. Je kunt zo de displays omwisselen, alle verbindingen nu zijn dezelfde. Bij de Cyclone10LP zijn er 464 LE's gebruikt van de 24624.


Device	       10CL025YU256C8G
Total logic elements	  464 / 24,624 ( 2 % )
Total registers	          209
Total pins	          32 / 151 ( 21 % )
Total virtual pins	  0
Total memory bits	  0 / 608,256 ( 0 % )
Multiplier 9-bit elements 0 / 132 ( 0 % )
Total PLLs	          1 / 4 ( 25 % )

In de code zit ook mijn afstandsbediening. Ik ga die IR diode ook nog aansluiten en een draadje leggen naar beide modules. Dan zou de remote code op beide display's gelijktijdig moeten verschijnen. De counters lopen voor beide boardjes mooi gelijk (na een gezamelijke reset).

Hoe maakt u de 3D print aan de fischer techniek vast?

Ik heb verschillende 3D stukjes geprint. Die passen allemaal op de Fischertechniek onderdelen. Hier is dus een standaard Fischer basisplaat onderaan gebruikt. Frame van het display 4x20char is ook 3D print. Mijn oude 3D printer heeft al ruim 1600 uren werk gedaan. Nooit iets moeten vervangen aan de printer.

Bij een FPGA heeft men meestal een of meerdere PLL's beschikbaar. Dat is een belangrijke hulp bij het leren werken met FPGA's. Vanaf 1 input clock kun je meteen meerdere andere gewenste nieuwe clocks aanmaken.

Ik heb hier 4 uitgangen aangemaakt C0, C1, C2 en C3. De clock ingang is hier 12 MHz.

Bij de Cyclone10 LP moet je na het compileren via de menu file->Convert Programming Files nog een convertie maken om een JTAG Indirect Configuration File (.jic) aan te maken. Die .jic file heb je nodig in de programmer om de Configuratie flash doorheen de FPGA te kunnen programmeren.

De configuratie flash van de Trenz cyclone10 LP module is nu een EPCQ64A ( in de Userguide staat nog de oudere type EPCQ16). Hierbij een afbeelding van de nieuwe instellingen. Onderaan (oef nu uitbeeld) kun je dan de Generate klikken om de .jic file aan te maken die daarna in de programmer zal gebruikt worden.
De programmer ziet er dan zo uit:

Je ziet hier in de voorstelling hoe de flash geprogrammeerd word.
Na het programmeren moet je de reset drukken om de module opnieuw te starten.
In mijn voorbeeld heb ik 4 nieuwe clocks aangemaakt vertrekkende van de input 12MHz clock. Die clocks zijn:
CLK20 -> 20 MHz
CLK4 -> 4 MHz
CLK1 -> 1 MHz
CLK27 -> 27 MHz
Dit om even de extra stap aan te duiden voor de programming van de Configuratie Flasch.
Ik gebruik Quartus Prime Version 23.1 std build 933 SC Lite Edition.

Een PLL gebruik je doorgaans alleen om van een basis externe lage clockfrequentie naar een hogere interne clockfrequentie te gaan.
Lagere interne clockfrequenties dan de basis externe lage clockfrequentie kun je gewoon met logica maken daarvoor hoef je geen PLL te gebruiken.

Op zaterdag 6 december 2025 14:46:30 schreef Bobosje:
Een PLL gebruik je doorgaans alleen om van een basis externe lage clockfrequentie naar een hogere interne clockfrequentie te gaan.
Lagere interne clockfrequenties dan de basis externe lage clockfrequentie kun je gewoon met logica maken daarvoor hoef je geen PLL te gebruiken.

Het ging mij erom dat je in een CPLD zoals free_electron aangaf om te beginnen direct een hoop LE's nodig hebt om een gepaste clock te maken. Anderzijds gebruiken al mijn FPGA's altijd meerdere clock uitgangen en die zijn zowel lager als hoger. We hebben het hier toch over CPLD en FPGA toepassingen. Heb je een toepassing waarbij je echter voldoende hebt met een kleine CPLD dan hoef daar geen FPGA in.

@free-electron
Dank voor de uitgebreide uitleg.
Ik zag op wat oudere boards dat die 'tegels' vaak werden geflankeerd door een seriëel EEPROMmetje. Zat daar de definitie van het logisch netwerk (de draadjes zoals jij ze noemde) in?

Ik heb ooit een chinees bordje met leds en drukknopjes op E-bay gevonden en was al snel in staat om met de bijgeleverde (illegale kopie destijds?) software het meegeleverde programmaatje te verbouwen... Bij gebrek aan een serieuze toepassing is e.e.a. weer in de vergetelheid geraakt, maar fascinerend was het wel.

Op maandag 8 december 2025 18:49:26 schreef soldeersmurf:
@free-electron
Dank voor de uitgebreide uitleg.
Ik zag op wat oudere boards dat die 'tegels' vaak werden geflankeerd door een seriëel EEPROMmetje. Zat daar de definitie van het logisch netwerk (de draadjes zoals jij ze noemde) in?

De max serie is "met ingebouwde flashchip", dan worden ze "CPLD" genoemd.

Met externe opslag voor het "programma-voor-de-hardware", heet het een FPGA. Cyclone is van Altera een familie van FPGAs.

Dus, ja in zo'n externe flashchip, daar kan je de configuratie in zetten.

Mijn testbordje hier heeft die optie. Fotoopa heeft pas nog gepost hoe je in de quartus software de configuratie in die flashchip krijgt.

De FPGA heeft de mogelijkheid om bij het opstarten die flash chip uit te lezen en zichzelf dan te starten. D'r zijn een aantal verschillende mogelijkheden, maar dit is er 1 van.

Ik heb hier m'n flashchip nog niet gebruikt. Voor tests is het net zo makkelijk om hem met de "programmer" te programmeren en dan te kijken of ie doet wat je wilt.

Fotoopa had (heeft?) FPGAs waarmee ie na het programmeren op insectenjacht ging. Dan zit het ding dus "ergens in" en moet ie doen wat hem opgedragen is. Dan is het "onhandig" om je laptop met programmer mee te moeten zeulen.

Ik vrees dat dat niet helemaal klopt rew. Er zijn FPGAs die flash based zijn, bv Lattice. Maar de meeste zijn ram based en die hebben een externe opslag nodig. Flash, of een micro die de config laadt. Een CPLD heeft een andere interne structuur dan een FPGA, maar of dat nou flash of ram based is maakt daarvoor niets uit.
Maar gelijk erbij zeggen: die definitie van FPGA vs CPLD is zeer vaag.

@smurf, dus ja, daar zit de config in. Een EE lijkt me nogal klein daarvoor, meestal is het Flash. Maar misschien met de kleine FPGAs dat het wel EE kan zijn.

Ehh... Het zou evt kunnen dat er een 96C46 eeprom is. Die is dan om de FTDI chip te vertellen dat ie "Altera USB BLASTER" heet.

Tja. PLD is begonnen als een specifieke and/or array met evt een registertje op het eind. CPLD... complexe PLD, tja, dan maakt men ineens de stap naar een complete lookup tabel. En die lookup tabel maakt voor mij dat ik het niet meer PLD vind, maar eigenlijk een FPGA.

De max2 serie heeft dus een lookup tabel. Maar goed. Met "het verschil is vaag" ben ik het met je eens. Dan zullen er allicht fabrikanten zijn die een iets andere definitie hanteren en dus de algemene scheidslijn niet respecteren.

Maar mijnsinziens noem je een max II dus een CPLD omdat die z'n config nog (net als de oudere PLDs) in z'n eigen flash-bare geheugen heeft.

En een Cyclone dat is een FPGA omdat die z'n config uit een bijbehorend flashchipje moet halen, of kan wachten tot ie geconfigureerd wordt door een CPU of zoiets.

Kitt in actie in GAL/PAL formaat.

A is het updown bitje, B-F de leds?
Dan krijg je inderdaad: C= UP & B of DOWN & B

(en UP is A, DOWN is ~A).

En A is dan C & DOWN | B & UP | C & UP | D & UP | E & UP

Netjes!

Een CPLD/FPGA is zoals een grote doos met duizenden IC's zoals we vroeger gebruikten. Je kunt het vergelijken met de vele 74LS reeks waar we onze schakelingen mee bouwden. Vandaar dat we toen een grote reeks IC's in voorraad hadden. Schema's werden toen nog veel uit de hand op een stukje papier getekend om vervolgens te bouwen. Toen bouwde ik de meeste ontwerpen op enkelzijdige printplaat. Ze ontwikkelen was niet moeilijk, raster 2.54 en een belichtingstafel met 3 UV lampen (6 indien dual layer maar die waren dan niet doorgemetaliseerd).
Met de Quartus tool kun je nu nog steeds op deze manier de schema's tekenen. Voordeel is dat je een onbeperkte voorraad hebt om je schakeling op te bouwen. Je moet zelfs geen verilog code kennen, alles was gewoon schema entry. Zo heb ik zeer grote projecten gemaakt met vele blz tekeningen.
Ik wou nu even terug een test maken met zo een schema entry. Hier het totale schema:

Het is een 8 bit counter met 2x4 bit type 74163. De uitgangen worden naar 8 leds gestuurd. Deze uitgangen zijn ook op de connector aangesloten. Daar kan ik mijn Picoscope aansluiten. Tussen de leds staat een invertor omdat mijn CPLD kaart actief laag nodig heeft. Het clock signaal wordt gemaakt via een 24bit prescaler(LPM_COUNTER) en een comperator. Ik zou hiervoor evengoed 6 x de 74163 kunnen nemen maar de Quartus tool laat toe direct een blockje aan te maken met de gewenste deelfactor. Dat maakt de tekening eenvoudiger. De comparator (LPM_COMPARE) staat nu op 12000000. Mijn boardje bezit een 50MHz oscilator die ik gebruik. Op deze manier gaan de ledjes niet te snel gaan tellen. De 8 leds geven de teller aan.

Of je dat nu gebruikt voor een CPLD boardje of een MAX10 FPGA dat maakt helemaal geen verschil. Ik heb de schakeling voor verschillende type boardjes gemaakt. De gebruikte cellen zijn nagenoeg gelijk:

Family                 MAX II
Device                 EPM2210F324C5
Total logic elements   42 / 2,210 ( 2 % )
Total pins             18 / 272 ( 7 % )

Hier zijn er 42 van de 2210 LE's gebruikt. Op mijn Trenz MAX10 boardje was dit: 43 / 15.840 ( < 1 % ).

Wat ik vooral wilde aangeven is dat een klassieke manier van werken even goed gaat, maar dan zonder dat je al die IC's moet bezitten en opbouwen. Nu 1 type kaartje kopen, zelfs eentje van "Ali" en je kunt enorm veel schakelingen live testen.

En wat je in Quartus in schematic entry tekent kun je ook precies zo intypen als text entry in een AHLD tekstbestand.
Kwestie van smaak en voorkeur of je voor schematic entry of voor AHDL text entry kiest, beiden leveren dezelfde logica op en geen kennis van Verilog of VHDL nodig.

Maar verilog (of VHDL) is een stuk krachtiger. Dan kan je opschrijven wat je WIL en hoef je niet over de vertaling naar 74xx chips te denken.

En met die 74LS chips, kan je zomaar een ding kiezen die beroerd op de FPGA of CPLD mapt en dan "groot" wordt. Anderzijds, met verilog kan je dat ook.

Op zondag 14 december 2025 19:35:14 schreef Bobosje:
En wat je in Quartus in schematic entry tekent kun je ook precies zo intypen als text entry in een AHLD tekstbestand.
Kwestie van smaak en voorkeur of je voor schematic entry of voor AHDL text entry kiest, beiden leveren dezelfde logica op en geen kennis van Verilog of VHDL nodig.

Dat is juist! Ik wilde vooral aangeven dat je kunt vertrekken van schema entry voor de oudere hardware mensen die toch willen overgaan om eens een CPLD/FPGA te gebruiken zonder dat ze AHDL, verilog of VHDL hoeven te leren. Voor die mensen zou de overgang nog eenvoudiger zijn.

Op zondag 14 december 2025 19:47:55 schreef rew:
Maar verilog (of VHDL) is een stuk krachtiger. Dan kan je opschrijven wat je WIL en hoef je niet over de vertaling naar 74xx chips te denken.

En met die 74LS chips, kan je zomaar een ding kiezen die beroerd op de FPGA of CPLD mapt en dan "groot" wordt. Anderzijds, met verilog kan je dat ook.

Toch probeer ik al vandaag een tijdje om hetzelfde in verilog te schrijven maar telkens kom ik tot minimaal 59 LE's ipv 42. Dus ja schema entry is zo slecht niet. Het kan ook zijn dat mijn verilog code niet optimaal was of mijn vertaling net ietsjes anders.

Ik denk dat "free_electron" ondertussen druk bezig is met zijn nieuw printje ofwel het opgegeven heeft om nog verder te gaan met dit topic.

Ik heb vandaag een Cyclone II bordje wat ik ooit ontworpen heb teruggevonden en in de doos FPGA gedaan zodat ik hem kan vinden.

En een "bluebird". Geloof ik ook door iemand gemaakt die meer van de MAX serie houdt dan Cyclone, net als free elektron. Hmm. Niets meer te vinden van dat ding. Ik geloof dat het een "samenkopen" project was.

Ik heb het toen ook aangekocht, idd samenkopen. Ik heb daar nog wel gegevens van.

Het boardje heb ik niet meer. In de eerste versie zaten enkele zware fouten en die werden toen met een nieuwe update verbeterd. De goede versie's werden toen nagestuurd. Ik heb toen nog een aantal zaken helpen oplossen. De manual is van 2007.

Ook het schema van het blue bird bordje heb ik hier nog. Ik heb zelf nog Quartus programma's die hiermee gemaakt zijn ze zijn in Quartus versie 9.1 Build 222 Web edition 2009 gecompileerd. Net opnieuw even opgestart en zonder fouten gecompileerd.
Het display was een kleur TFT-LCD 43T3DX02 type. Ik heb daar nog een macro opname van:

[Bericht gewijzigd door fotoopa op (17%)]

Thanks. Opgeslagen. Mijne heeft (nog) niet alle onderdelen. Dingen als die VGA output... daar was ik toen niet zo mee bezig, dus er af gelaten.