Názory k článku Navrhujeme a vyrábíme vlastní CPU: první pokusy s FPGA

  • Článek je starý, nové názory již nelze přidávat.
  • 4. 3. 2025 9:42

    Marvin

    FPGA má v sobě nějakou flashku s konfigurací?
    Nebo se po každým resetu načítá konfigurace z SPI flashky, co je na desce?

  • 4. 3. 2025 10:10

    zz_indigo

    Záleží od typu. Štandard je externá SPI flash. Ale niektoré ju majú integrovanú (Altera MAX10) pripadne sa to dá konfigurovať cez JTAG. (Niektoré FPGA cez to zvládajú aj iste spôsoby debugingu)

  • 4. 3. 2025 10:43

    acx99

    "Debuging" ne logický analyzátor. Tzn. zvládají to všechny, protože to je jen další logika, která se tam syntetizuje. Tzn. jediné omezení je, aby se tam vešla.

    4. 3. 2025, 10:43 editováno autorem komentáře

  • 4. 3. 2025 12:49

    zz_indigo

    Altera vie do vnútra vopchať logicky analyzátor. Ten ma podporu priamo v quartuse (Signal Tap Logic Analyzer). Ale môžeš si tam naďatlovat aj svoj vlastný.

    JTAG ako taký ma podporu len na zistenie stavu jednotlivých pinov. (Boundary scan) Ale ta nieje povinna a nevie ho kazda vec z JTAG portom.

  • 4. 3. 2025 15:02

    RDa

    Debugging ale v nekterych FPGA existuje - tusim PolarFire a obecne Microsemi obvody maji dva dedikovane piny - na ktere se daji z beziciho signalu namapovat jakekoliv interni signaly. Tj. je to skutecne jako kdyz si nekdo prilozi "analogovou" sondu k slozitemu obvodu.

    Klasicky digitalni LA ktery se syntetizuje se tam nemusi vejit, nebo muze vyzadovat rekompilaci designu, a pak se DUT chova jinak a snaha chytit bug je marnejsi.

  • 5. 3. 2025 20:38

    zz_indigo

    To vieš spraviť na každom FPGA. akýkoľvek univerzálny IO pin vieš namapovat na akýkoľvek signál. Musíš ho mat len vyvedení do top-level entity

  • 6. 3. 2025 2:11

    RDa

    No prave ze nemuzes - tohle je specialni hw debug featura, ktera jde prenastavit runtime v bezicim FPGA. hodne stesti s necim takovym tam, kde chcete menit netlist.. to bude vyzadovat kompletni reload a ztratu aktualniho stavu.

  • 4. 3. 2025 10:15

    Martin Beran

    Moje FPGA má konfigurační flash na desce. Kromě toho se dá konfigurovat přímo přes JTAG z vývojového prostředí, což je při vývoji pohodlnější.

  • 4. 3. 2025 10:28

    zz_indigo

    Pozrel som si zdrojak toho blikania ledkou. A ak by ste ste prestali rozmýšľať ako programátor tak by syntetizovaný obvod bol podstatne menší.

    1.) Použiť internú PLL na vygenerovanie čo najnižšej frekvencie.
    2.) RS obvod na generovanie signálu či má alebo nemá počítať
    3.) Xbitový čítač z resetom.

    PLL nieje nutné za podmienky že čítač bude viac-bytový.

    Porovnajte si tu váš kód napríklad z týmto tu: https://www.fypsolutions.com/fpga/fpga-led-blinking-example/

    A RTL vystúp tiež bude vyzerať príčetnejšie.

  • 4. 3. 2025 10:58

    Martin Beran

    A ak by ste ste prestali rozmýšľať ako programátor

    Co tím myslíte?

    1.) Použiť internú PLL na vygenerovanie čo najnižšej frekvencie.

    PLL jsou v FPGA právě 2. U složitějších obvodů by mi docela rychle došly.

    2.) RS obvod na generovanie signálu či má alebo nemá počítať

    Co myslíte tím "RS obvodem"? Zapojení pomocí LEs, což je v FPGA špatně? Nebo použití registru, což tam je, protože signál running12, resp. proměnná running34 se syntetizují jako registry?

    3.) Xbitový čítač z resetom.

    Je tam cyklický čítač bez resetu.

    Porovnajte si tu váš kód napríklad z týmto tu

    V mém kódu jsou dva procesy, protože jsem si chtěl vyzkoušet dva možné zápisy: if rising_edge(clk) nebo wait on clk until clk = '1'. Každý z nich ovládá dvě LED. Jestliže nechám jen jeden proces, jednu LED a vyhodím ovládací tlačítko, dostanu prakticky stejný kód, jako je ve Vámi odkazovaném příkladu.

  • 4. 3. 2025 14:27

    zz_indigo

    1. PLL ma viac výstupov každé vie vygenerovať 2 dve vcelku nezávislé freq. A ak nechcete riešiť problémy z rôznymi "clock domains". Tak väčšinu ostatných freq budete generovať z freq ktorú získate z PLL cez deličku.

    2. No a to je to že ste preskočil základy a znova vymýšľate koleso. RS flip-flop. Je základný prvok nepouživaný keď mate vystúp ktorý jedným vstupom zapínate druhým vypínate. Ďalšie sú D latch, JK flip-flop.

    3. Sú dva a reset tam mate. Reset po dosiahnutí hodnoty. Na kurze by vás pravdepodobne tlačili do vygenerovania si signálu 1hz ako process a na základe neho už len blikaly z led.

    Áno ten druhy process je lepši. Ono je dobre sa naučiť tie už prešlapané cestičky. Sú efektívnejšie čo sa týka LUT, sú známe rizikové stavy, Optimalizator ich pozná. A vďaka tomu dosiahnete lepších freq ktoré návrh zvládne. Ono pri zložitejších návrhoch sa bude stávať že niektoré signály sa budú musieť generovať na viacerých miestach naraz. (prepoje medzi lutmy nebudú volné) Takže si ušetríte čas a nervy ak si pozriete optimálne riešenia. Je fakt frustrujúce keď mate 50% vyťaženie LUT a aj tak sa to do FPGA nedá dostať.

  • 4. 3. 2025 14:59

    Martin Beran

    K PLL: Já si tady vystačím se základními 50 MHz hodinami. PLL si nechávám na generování VGA pixel clock a případně na budoucí pokusy s taktováním CPU na vyšší frekvenci než 50 MHz.

    Tak väčšinu ostatných freq budete generovať z freq ktorú získate z PLL cez deličku.

    Jak podle Vás implementuju tu děličku kmitočtu? Nějakým zásadně lepším způsobem, než je ten můj čítač?

    RS flip-flop. Je základný prvok

    Ptám se potřetí: Jak podle Vás implementuju RS flip-flop v FPGA a jak se to bude lišit od mého použití registru nebo proměnné?

    Sú dva a reset tam mate.

    Čítače jsou dva, protože v tom jednom VHDL souboru jsou záměrně dvě samostatné různé implementace (skoro) identické logiky. Pod pojmem "reset" si představuju spíš (asynchronní) externí signál reset, nikoliv wrap-around hodnoty čítače.

  • 4. 3. 2025 15:08

    RDa

    2.) RS obvod na generovanie signálu či má alebo nemá počítať

    Vzdy ho tam ma - konkretne tedy ve variante "asynchronni RS s prioritou resetu", coz reprezentuje nasledovny kod:

    running12 <=
            '0' when stop = '0' else
            '1' when start = '0' else
            unaffected;

    Ale ano, mam radeji synchronni struktury, takze by to mohlo byt pouzito za podminky kdy se hodiny meni - coz ale vyzaduje "always-running" hodiny. Touto asynch veci by totiz klidne nejake to PLL a clock buffery mohl uspat a fugnovalo by start-stop.. takze by dosahl nejake uspory pri stop stavu.

  • 5. 3. 2025 19:56

    zz_indigo

    Zápis je na zlý. aj Quartus to píše. (Quartus || 13.0.1 aj Quartus 22.1)

    Info (10041): Inferred latch for "running12" at blink.vhd(22)

    Keby ludi čítali čo im syntetizátory a kompilátory píšu. SW by bol lepši.

  • 5. 3. 2025 20:34

    Martin Beran

    Keby ludi čítali čo im syntetizátory a kompilátory píšu.

    Já to čtu. Asi jsem to měl víc zdůraznit, ale je to jeden z prvních kousků kódu, co jsem ve VHDL napsal. Do článku jsem ho nezařadil kvůli tomu, že by byl dokonalý, ale protože jsem chtěl ukázat jednoduchý kód a k tomu ty dva obrázky.

  • 6. 3. 2025 2:15

    RDa

    Info neni ani warning ani error. Takovych Info veci pise normalni prekladac spousty.

    Kdyz to tedy vymysli ze pouzije latch.. budiz. Ma to latch? Ma. Tak nevim kde hledate ted jako problem.

    Latch NENI problem, kdyz o nem nastroj vi.

    Az vam to neprojde timingem, tak pak si muzete zacit resit, ze proc asi.. ale o tom tato cast problemu neni.

  • 17. 3. 2025 14:52

    Biktop

    Info neni ani warning ani error.

    Je to asi tak na úrovni "warning: null pointer assignment" v C. Tedy na 99,99 % je to hrubá chyba!

    Ma to latch? Ma. Tak nevim kde hledate ted jako problem.

    Tohle jsou ale neznalosti naprostých základů návrhu na FPGA. "Inferred latch" znamená, že došlo k propojení výstupu a vstupu kombinačního obvodu, tedy že vznikl jakýsi nechtěný latch. A ne, že byl využit DFF, který je k dispozici v každé logické jednotce. Proč je to špatně se dočtete snad v každém textu o návrhu obvodů na FPGA.

    Latch NENI problem, kdyz o nem nastroj vi.

    JE to právě dost zákeřný problém, i když o něm nástroj ví. Je to bonus pro vás, že to nástroj odhalil.

  • 4. 3. 2025 13:31

    zz_indigo

    "A ak by ste ste prestali rozmýšľať ako programátor"
    Co tím myslíte?

    Logiku popisu. Píšete to ako program nie ako HDL popis.

    Pekným príkladom je process led12 ten je napísaný logikou sekvenčného programu. "wait on clk until clk = '1';" vyslovene kolie oči.

    proces led34 je už lepši

    tam je "if rising_edge(clk) then..."

    Alebo running12 to je úloha pre klasicky RS obvod a je dobrým zvykom vstupy dostať do "clockdomain" (ako je running34). LUTov nieje nekonečno prečo znova generujete signál ktorý ste si už vygenerovali?

    A ak by nešlo o test a kedže čitače nezastavujete tak by sa zozdielali. Ten druhy je o polovicu pomalší takže stačí predchádzajúci vydeliť dvomi.

    Ak by ste obe časti urobili rovnako pravdepodobne by to optimizer spojil.

    p.s. Quartus vám nenadával že v procese používate signály ktoré nie sú vymenované? (start, stop)

  • 4. 3. 2025 14:09

    Martin Beran

    Pekným príkladom je process led12 ten je napísaný logikou sekvenčného programu. "wait on clk until clk = '1';" vyslovene kolie oči.
    proces led34 je už lepši
    tam je "if rising_edge(clk) then..."

    Podle VHDL Handbooku jsou oba zápisy ekvivalentní...

    Alebo running12 to je úloha pre klasicky RS obvod

    Opakuji otázku: Co je klasický RS obvod v kontextu FPGA?

    a je dobrým zvykom vstupy dostať do "clockdomain"

    Uznávám, že synchronní registr pro running34 je lepší než latch pro running12, ale nepovažuji to za příklad "psaní programovou logikou".

    Quartus vám nenadával že v procese používate signály ktoré nie sú vymenované? (start, stop)

    Proč by měl nadávat? Já chci ty signály testovat v procesu, ale nechci proces asynchronně spouštět, když se kterýkoliv z nich změní. Chci proces spouštět pouze synchronně na vzestupné hraně hodin.

    K tomu zbytku: v článku jsem to dostatečně nezdůraznil, ale je to opravdu jeden z prvních kousků VHDL kódu, který jsem napsal, když jsem začínal. A cílem bylo vyzkoušet si různé varianty zápisu, nikoliv vyrobit perfektní super optimalizovaný obvod.

  • 4. 3. 2025 15:53

    zz_indigo

    Pekným príkladom je process led12 ten je napísaný logikou sekvenčného programu. "wait on clk until clk = '1';" vyslovene kolie oči.
    proces led34 je už lepši
    tam je "if rising_edge(clk) then..."

    Podle VHDL Handbooku jsou oba zápisy ekvivalentní...

    To ťažko. Jeden detekuje hranu druhy úroveň. A ak by boli ekvivalentne tak by ich quartus zobrazil v RTL rovnako.

    ==========
    "Opakuji otázku: Co je klasický RS obvod v kontextu FPGA?" Neviem ako odpovedať na zle položenu otázku. Čo je to kontext FPGA?

    =========
    Quartus vám nenadával že v procese používate signály ktoré nie sú vymenované? (start, stop)

    Proč by měl nadávat? Já chci ty signály testovat v procesu, ale nechci proces asynchronně spouštět, když se kterýkoliv z nich změní. Chci proces spouštět pouze synchronně na vzestupné hraně hodin.

    Dalsia ukazka ze nechapete rozdiel medzi popisom a programovanim.

    - Signali v definicii procesu, je zoznam signálov ktoré na nejak testujú v rámci definícii.

    - To že sa to vola proces neznamená že je to nejaký proces ktorý sa niekde spusta. je to len obálka definície. nemá nič spoločne z procesom ktorý poznáte z programovania. Je to tam a spracováva vstupy stále či sa vám paci alebo nie. Ono to dosť nestatne popisujú tie časti na sensitivity list, declarative part a sequential statement.

    sequential statement sa totiž nevykonáva sekvenčne ale paralelne.
    sekvenčnost sa "simuluje" väzbov na hranu nejakého signálu (clk). Ale aj tam sa všetko čo je v danom IF-e stane naraz.

    Ak dám do procesu dve IF podmienky na rovnaký signál tak keď sa podmienka splní tak sa obe časti stanu naraz. A vymenenie poradia na tom nič nezmení. Ak si takéto "maličkosti" neuvedomíte tak keď budete robiť ten CPU tak vás môžu prekvapiť. hlavne ak v jednom IF budete používať výsedok druhého.

    p.s. Skúste namiesto VHDL handbooku skúsiť nejaký tutoriál od začiatku. Ono je to VHDL dosť mätúce pre programátora. A fakt že v tom istom jazyku sa opisuje HW ale aj testbooky moc nepomáha. (Sú totiž veci ktoré sa používajú v testbookoch ale nie sú syntetizovatelné)

  • 4. 3. 2025 17:10

    Martin Beran

    To ťažko. Jeden detekuje hranu druhy úroveň.

    if rising_edge(clk) then detekuje vzestupnou hranu. wait on clk until clk = '1' čeká, až se změní hodnota signálu (to je část on clk) a nová hodnota bude 1 ( until clk='1'), tedy efektivně také detekuje vzestupnou hranu.

    "Opakuji otázku: Co je klasický RS obvod v kontextu FPGA?" Neviem ako odpovedať na zle položenu otázku. Čo je to kontext FPGA?

    Já tuším, jak vypadá zapojení RS pomocí hradel nebo tranzistorů. Ale nevím, jak si představujete, že tohle vyrobím v FPGA, resp. nechápu, co se Vám nelíbí na na použití signálů/proměnných v mém VHDL kódu, které mají stejnou funkci.

    Dalsia ukazka ze nechapete rozdiel medzi popisom a programovanim.

    Já si myslím, že ten rozdíl chápu docela dobře.

    Signali v definicii procesu, je zoznam signálov ktoré na nejak testujú v rámci definícii.

    To je dost nepřesné.

    To že sa to vola proces neznamená že je to nejaký proces ktorý sa niekde spusta.

    Dovolím si tvrdit, že docela chápu principy, jak se kombinační a sekvenční procesy překládají do zapojení obvodu. Já si fakt nemyslím, že by tam někde běželo něco, co připomíná proces v operačním systému.

    sequential statement sa totiž nevykonáva sekvenčne ale paralelne.

    Není to ani čistě sekvenční, ani čistě paralelní, struktura je odvozená z data flow. A "mezi iteracemi procesu" se data (hodnoty signálů) ukládají do registrů.

    Ak si takéto "maličkosti" neuvedomíte tak keď budete robiť ten CPU tak vás môžu prekvapiť.

    To je sice pravda, ale vzhledem k tomu, že ten CPU existuje, tak asi něco tuším o tom, jak to funguje, že?

  • 4. 3. 2025 18:44

    Bel Shamharoth

    Opravdu, nechaj si poradit...

    Zkuste si vzít tu blikoledku, resp. vemte si papír a ten obvod si nakreslete, hradla, registry, multiplexory, jako kdybyste to chtěl vysázet na plošňák. A pak to 1:1 přepište do VHDL.

    Vy to fakt píšete, jako program (resp. behaviorálně), takhle se to nedělá.

    To je sice pravda, ale vzhledem k tomu, že ten CPU existuje, tak asi něco tuším o tom, jak to funguje, že?
    Vůbec. Ten syntetizátor dokáže schroustat lecos a ono to nějak funguje. Ale zabírá to mnohem víc, nezvládne to takové frekvence a občas to může dělat i blbiny.

  • 4. 3. 2025 19:16

    Michal Kubeček

    Když vidím tu diskusi, nemůžu si nevzpomenout na stavebnici Logitronik 01, kde na blikání stačila dvě hradla (invertory), dva kondenzátory a dva odpory. :-) (Čtyři odpory, když budu počítat i ty dva na omezení proudu procházejícího LEDkami.)

    (A kutilové ze staré školy jistě namítnou, že místo dvou hradel stačí dva tranzistory.)

    Samozřejmě, tady jde o demonstraci fungování a možností technologie, ne o nejefektivnější řešení.

  • 4. 3. 2025 19:25

    Bel Shamharoth

    Samozřejmě, tady jde o demonstraci fungování a možností technologie, ne o nejefektivnější řešení.
    Nikoli, tohle je prostě blbě. Logika zápisu je blbě. Bez jakékoli urážky, já napsal větší čuňárny, ale dřív, nebo později, člověk musí pochopit, že takhle ne. A lépe dřív, než později.

  • 4. 3. 2025 19:54

    Martin Beran

    Vy to fakt píšete, jako program (resp. behaviorálně), takhle se to nedělá.

    A jak se to dělá? Podle Vás se behaviorální zápis vůbec nepoužívá?

    Nikoli, tohle je prostě blbě. Logika zápisu je blbě.

    Můžete napsat konkrétně, v čem je to "prostě blbě", a ukázat správné řešení?

  • 4. 3. 2025 20:09

    Bel Shamharoth

    RTL.
    Vy nepopisujete algoritmus, ale střeva toho čipu. Ne to tam behaviorálně napsat a ono z toho "něco" vyleze. Jako některý syntetizátory z toho opravdu něco vymyslí, některé trvají na RTL (ono je to možná lepší). Viděl jsem i přístup, že někdo vyloženě modeloval LUTky, což teda nemusím, už jen proto, že různé FPGA mají různě vělké LUTky.
    V behaviorálním popisu snadno napíšete něco, co pak uděla latche, má dlouhou kritickou cestu atp. Pak Vám to dá 10Mhz s větrem v zádech a ani nemusí být jasné proč.

  • 4. 3. 2025 20:20

    Martin Beran

    RTL

    Nechcete sem napsat ukázku, třeba to LED blikátko s tlačítky start/stop?

    Vy nepopisujete algoritmus, ale střeva toho čipu.

    Bude ten Váš přístup škálovatelný na složité obvody typu CPU?

    Ne to tam behaviorálně napsat a ono z toho "něco" vyleze.

    Opakuju otázku: Podle Vás se behaviorální zápis vůbec nepoužívá? (Nebo nemá používat?)

  • 4. 3. 2025 20:55

    Bel Shamharoth

    Bude ten Váš přístup škálovatelný na složité obvody typu CPU?
    Samozřemě, ale tak to nebudete házet do jednoho souboru, ne? Je to stavebnice.

    Podle Vás se behaviorální zápis vůbec nepoužívá? (Nebo nemá používat?)
    Behaviorální popis se na jakoukoli rozumnou věc nepoužívá.

    Mrkněme třeba sem:

    cnt := cnt + 1;
    if cnt = 2 * crystal_khz * period_ms then
    cnt := 0;
    state := not state;
    end if;

    Máte představu, co to udělá? To by mělo hodit sčítačku, za ní komparátor a do registru to dá hodnotu dle výsledku komparátoru (protože ten if na náběžnou hranu). No jo, ale ten komparátor přeci může být vedle sčítačky a kritická cesta bude kratší...

  • 4. 3. 2025 22:39

    Martin Beran

    Behaviorální popis se na jakoukoli rozumnou věc nepoužívá.

    Zajímavé, když jsem se tak rozhlížel např. po nějakých implementacích RISC-V, tak je to samý process a state machine... Trochu se bojím, že s tou reálnou škálovatelností definice obvodu striktně bez behaviorálního zápisu to bude něco jako assembler místo C - ve speciálních případech to bude potřeba, ale bude to mnohem pracnější, většinou to bude jedno, a často syntetizér/kom­pilátor vyprodukuje lepší výsledek než člověk.

    Mrkněme třeba sem

    Docela by pomohlo, kdybyste ukázal svou verzi tohoto kódu místo slovního popisu.

    Máte představu, co to udělá?

    Mám. Od "totálně špatně" jsme se dostali k chybějící mikrooptimalizaci, kdy jedno přiřazení do proměnné, které je před příkazem if způsobí, že se jedna cesta v obvodu protáhne o pár hradel v situaci, kdy na tom nejspíš prakticky vůbec nezáleží. Celé se to dá opravit přesunem toho přiřazení do větve else. Vůbec mi není jasné, proč by to v jiné formě zápisu mělo být celé přehlednější a automaticky vyloučit vytvoření obdobné neefektivity.

  • 5. 3. 2025 8:29

    Bel Shamharoth

    je to samý process a state machine...
    Tak to pozor. To, že je tam process neznamená, že je to (špatný) behaviorální popis. Na FSM taky není nic špatně (a ano taky se píše processem). Špatně je to, že dáte do procesu například to:

    cnt := cnt + 1;
    if cnt = ...

    A čekáte, že to ten syntetizátor nějak vymyslí, ale on to nemá jak vymyslet.
    I na cyklech nemusí být nic špatně (ty tam nemáte, ale píšu příkald), pokud chcete udělat něco např. pro všechny piny. Ale je to špatně, pokud v tom cyklu budete upravovat stejnou proměnnou (nevím proč mě napadá bubble sort).
    Tohle je pointa toho "Myslet jako programátor". Jak jsem psal, vy popisujete fyzickou věc, popisujete, jak to tam má být uspořádané a ne, co to má dělat.

    Docela by pomohlo, kdybyste ukázal svou verzi tohoto kódu místo slovního popisu.
    No asi jo, ale zaprvé si mi s tím nechce psát (už takhle jsem chtěl napsat jen jeden comment) a za druhé je toho plný Internet.

    Od "totálně špatně" jsme se dostali k chybějící mikrooptimalizaci,
    Tohle není mikrooptimalizace, to je zcela špatný přístup. Něco jako goto, nebo neuvolňování paměti (ono to nepojede dlouho, že?). A s tím přesunem máte pravdu, jenom je to důležitější, než si myslíte.

    Jako takhle. Já jsem Vám to nechtěl sepsout. Sám jsem si tímhle obdobím prošel taky. Jenže Vy si to vehementně bráníte. Psal jsem, ať si necháte poradit, ušetříte si čas, protože, pokud u toho HW zůstanete, tak dřív, nebo později se k tomu propracujete (A to třeba i nedobrovolně).

    Jinak ještě pozor na testbenche, tam tyhle věci nevadí, tak si je neberte za vzor pro HW.

  • 5. 3. 2025 18:04

    Ravise
    Stříbrný podporovatel

    > Tohle není mikrooptimalizace, to je zcela špatný přístup. Něco jako goto (...)

    Čéče, o křemíku vím kulový, ale jestli tě mám soudit podle toho, co si myslíš o goto, tak z toho srovnání nevyjdeš dobře...

    Goto je legitimní programátorský nástroj, který - klasicky v Céčku - umožňuje při chybě přeskočit nerelevantní operace a skočit do místa, kde program může začít uvolňovat alokované zdroje. V assembleru nebo strojáku pak už vůbec na výběr nemáš... Autoři Luy (např.) to taky zvorali?

  • 5. 3. 2025 20:24

    echo_zulu

    Existuje niečo, čo sa volá štrukturované programovanie a bolo to vymyslené preto, aby boli programy prehľadnejšie, pretože držať kontext pri ich čítaní a mať prehľad o tom, čo sa v nich deje, sa bez toho ukázalo pri väčších programoch komplikované ak nie priam nemožné. A bolo to práve kvôli tomu, že tok inštrukcií bol riadený príkazom goto.

    Áno, goto je stále možné použiť, otázka je, čo to prináša a čím sa za to platí.

    Vzhľadom na to, že sa goto všeobecne neodporúča, sa dá predpokladať, že je to kvôli tomu, že cena za použitie je vyššia ako prinosy. Už celé desaťročia.

    A ja osobne som si skoro istý, že ak píšete programy v C, tak štrukturované programovanie používate v drvivej väčšine prípadov a ak tam máte nejaké goto, tak je to v porovnaní so štrukturovaným programovaním v mizivom počte prípadov.

    Takže goto používate ako mikrooptimalizáciu. Vášho vývojového procesu.

  • 5. 3. 2025 20:05

    zz_indigo

    Obávam sa že sa zbytočne snažíme. Autor ma zafixované čo je to process a statemachine z programovania a cez to tanky nejdu.

  • 5. 3. 2025 21:34

    Martin Beran

    Autor ma zafixované čo je to process a statemachine z programovania a cez to tanky nejdu.

    Zkuste nám popsat, co podle Vás má autor zafixované jako proces a statemachine a jak to je správně. Rád se poučím.

  • 6. 3. 2025 21:06

    zz_indigo

    Vase slova:

    Proč by měl nadávat? Já chci ty signály testovat v procesu, ale nechci proces asynchronně spouštět, když se kterýkoliv z nich změní. Chci proces spouštět pouze synchronně na vzestupné hraně hodin.

    ========
    Ono by bolo lepšie skúsiť pochopiť čo vám ľudia pysu nie sa snažiť za každú cenu obhájiť svoj názor.

    modelovanie hardware a programovanie maju uplne rovnaku logiku a do toho pouzivaju podobny format. To neksutocne metie. Ak to nemienite akceptovat OK. odrazi sa to na kvalite clankou a aj vysledneho HW

  • 6. 3. 2025 21:27

    Martin Beran

    Ono by bolo lepšie skúsiť pochopiť

    Zkouším to, ale pomohlo by, kdybyste konečně seozumitelně napsal, jak to s těmi procesy podle Vás je. A nepodsouvejte mi prosím něco, co jsem netvrdil.

  • 5. 3. 2025 20:52

    Martin Beran

    A čekáte, že to ten syntetizátor nějak vymyslí, ale on to nemá jak vymyslet.

    Čekám, že syntetizuje to, co je tam napsané, ať už je to dobře/špatně nebo optimální/neop­timální.

    zaprvé si mi s tím nechce psát

    Možná by těch 5 až 10 řádků kódu s komentáři řeklo víc, než to dlouhé nekonkrétní povídání.

    Tohle není mikrooptimalizace, to je zcela špatný přístup. Něco jako goto, nebo neuvolňování paměti

    Je to malá změna, která nijak neovlivní očekávané chování obvodu navenek. Ušetří zdroje, co v tomto případě stejně nijak nevyužijí. To je pro mě zbytečná mikrooptimalizace. Až to bude ve velkém obvodu v mnoha kopiích nebo na opravdu kritické cestě, bude to něco jiného.

    Příkaz goto je standardní způsob, jak v C nebo C++ vyskočit z několika úrovní zanořených cyklů, nebo jak v C po chybě přeskočit na "úklidový" kód pro uvolnění zdrojů před návratem z funkce.

  • 5. 3. 2025 20:53

    zz_indigo

    vo VHDL sa škáluje takto: (cwidth a owidth "premenne")

    ===============
    -- Numeric controled oscilator

    library ieee;
    use ieee.std_logic_1164­.all;
    use IEEE.STD_LOGIC_A­RITH.all;
    use IEEE.STD_LOGIC_UN­SIGNED.all;

    entity NCO is
    generic (
    cwidth : integer := 31;
    owidth : integer :=11
    );
    port
    (
    clk : in std_logic;
    freq : in std_logic_vector (cwidth downto 0);
    phase : in std_logic_vector (owidth downto 0);
    output : out std_logic_vector (owidth downto 0)
    );

    end entity;

    architecture rtl of NCO is

    signal sr: std_logic_vector (cwidth downto 0) := (others => '0');

    begin

    process (clk)
    begin
    if (rising_edge(clk)) then

    sr <= sr + freq;

    end if;
    end process;

    output <= sr (cwidth downto cwidth - owidth) + phase;

    end rtl;
    ===============
    Ked budem potrebovať v návrhu dva rôzne NCO tak pri definícii komponent použijem "generic map" a cwidth a owidth si predefinujem ako budem potrebovať.

  • 4. 3. 2025 22:42

    Martin Beran

    Když vidím tu diskusi, nemůžu si nevzpomenout na stavebnici Logitronik 01

    Na stavebnice Logitronik 01 a 02 jsem si taky vzpomněl, když jsem začal přemýšlet o nápadu, že bych si pomocí FPGA mohl vyplnit mentální mezeru mezi hradly a strojovým kódem.

  • 4. 3. 2025 19:28

    RDa

    Vy to fakt píšete, jako program (resp. behaviorálně), takhle se to nedělá.

    Takhle se HDL rozhodne nedela. To radite jako ze si vemte C++/C#, include <asm.h> a piste si vse v intrinsics.

    Od toho mame VHDL a jine vysokourovnove jazyky, aby slo napsat myslenku obvodu na papir - ono je uplne jedno jak to popisete, pokud po synteze dostanete obvod ktery bude delat to, co chcete.

    HDL jsem napsal hodne - a vesinou kdyz neco nejelo tak to byl muj problem - protoze jsem to nevysvetlil / nezapsat tu esenci dostatecne jednoznacne, aby si to kompilator nevylozil jinak.

    A opravu na hradla se tady nehraje ve smyslu "TTL" obvodu.

  • 4. 3. 2025 19:38

    Bel Shamharoth

    VHDL právě není ani C++, ani C#, ani java ani žádný vysokoúrovňový jazyk. Já toho VHDL taky napsal docela dost plus něco ve verilogu. U toho HDL prostě musíte mít dobrou představu, co z toho vyleze. Ale OK, raďte blbě, já se o tom přít nemusím.

  • 5. 3. 2025 0:42

    RDa

    Ja bych ten luxus z VHDL a moznosti generik, hlavne i pro packages v pozdejsich verzich, prirovnal k C++ (a jeho templatum).

    Mel jsem historicky cest s necim co se jmenovalo ABEL, a to bylo spis jako asm v te jazykove analogii, protoze zrejme cileno na prvni PLD /PLA,PAL,GAL/ obvody s fixni strukturou:

    https://en.wikipedia.org/wiki/Advanced_Boolean_Expression_Language

  • 4. 3. 2025 20:04

    Biktop

    ono je uplne jedno jak to popisete, pokud po synteze dostanete obvod ktery bude delat to, co chcete.

    Ono to není jedno ani v případě klasického počítačového programu. V případě popisu obvodu bývá ten rozdíl mezi dobrým a špatným (třebaže funkčním) popisem ještě propastnější.

    HDL jsem napsal hodně

    Nechci se vás dotknout, ale pokud jste k tomu přistupoval tak, jak naznačujete, tak to ovšem neznamená, že jste odváděl kvalitní práci.

  • 5. 3. 2025 0:38

    RDa

    Me prekvapuje jak si nejaky anonymko z internetu dovoli kritizovat nejen autora clanku, ale i velice nespecificke a nekonkretni prispevky v diskuzi.

    Vsechno ma svoji "learning curve" a pokud clovek neni uplne nemehlo, tak i slozity projekt dokaze zdarne realizovat - a metrika na vysledek je boolean - jede to / nejede to (v ramci predem danych constraints). Zda je neco ve svete digitalni logiky kvalitni, nema zadnou jinou metriku.

    Apropo, jak k vecem pristupuji je moje vec - a to taky nemuzete kritizovat, protoze muj pristup zde odhalen neni. Ale typicky ma clovek sw modely, ktere tu mega slozitou vec dokazou pred-implementovat a mit moznost odsimulovat i jinak nez psanim hdl a testbenche. Ty uz jsou pak s modelem mnohem snazsi.

  • 5. 3. 2025 20:15

    zz_indigo

    A dôvod prečo nemôžeme kritizovať autora?

    Tu mam VHDL čo som v rámci učenia robil už dávno: SVN tvrdi 11.8.2011:

    --- efekt za pomoci Linear feedback shift register

    library IEEE;
    use IEEE.STD_LOGIC_1164­.ALL;
    use IEEE.STD_LOGIC_A­RITH.ALL;
    use IEEE.STD_LOGIC_UN­SIGNED.ALL;

    entity efekt is
    PORT ( clk : in STD_LOGIC;
    num : out STD_LOGIC_VECTOR (8 downto 0);
    led : out STD_LOGIC_VECTOR (7 downto 0));
    end efekt;

    architecture behavioral of efekt is
    signal count : STD_LOGIC_VECTOR (24 downto 0) := (others => '0');
    signal tik : STD_LOGIC := '0';
    signal tak : STD_LOGIC := '0';
    signal count1 : STD_LOGIC_VECTOR (24 downto 0) := (others => '0');
    signal registr : STD_LOGIC_VECTOR (5 downto 0) := "000001";
    signal reg : STD_LOGIC_VECTOR (8 downto 0) := "111111110";

    begin

    div:process (clk) -- delicka na ziskanie nizsej freq
    begin
    if clk='1' and clk'event then
    count <= count + 1;
    if count = "101111101011­110000011111" then
    count <= (others => '0');
    tik <= '1';
    else
    tik <= '0';
    end if;
    end if;
    end process;

    div2:process (clk) -- delicka na ziskanie nizsej freq
    begin
    if clk='1' and clk'event then
    count1 <= count1 + 1;
    if count1 = "000000000101­111000001111" then
    count1 <= (others => '0');
    tak <= '1';
    else
    tak <= '0';
    end if;
    end if;
    end process;

    shift:process (clk) -- posuvny register na generovanie pseudonahodnich kombinacii
    begin
    if clk='1' and clk'event then
    if tik = '1' then
    registr <= registr (4 downto 0) & ( registr(5) xor registr(4) );
    end if;
    if tak = '1' then
    reg <= reg(7 downto 0) & reg(8);
    end if;
    end if;
    end process;

    led <= registr & registr(1 downto 0);
    num <= reg;

    end behavioral;


    Porovnajte si čo vypadne ako RTL z môjho zápisu a porovnajte z tou hrôzou čo vygeneruje quartus z kódu čo sem tal autor.

  • 5. 3. 2025 21:05

    Martin Beran

    Porovnajte si čo vypadne ako RTL z môjho zápisu a porovnajte z tou hrôzou čo vygeneruje quartus z kódu čo sem tal autor.

    Nádhera. Ještě kdyby to bylo odsazené, aby se to dalo číst. Nějaká normální čísla místo těch binárních řetězců by taky pomohla. Já nechápu, proč pořád předpokládáte, že netuším, co dělám, a že jsem třeba neměl dobrý důvod, proč jsem kód napsal zrovna takto. Třeba abych si ty "hrůzy" prakticky zkusil.

  • 6. 3. 2025 23:49

    Pavel Píša

    Dobrý den, nepovažuji se za nějakého experta na VHDL, někdy s ním celkem bojuji a vycházím z toho, co jsem již napsal nebo napsali druzí, případně když jsme se o pravidlech bavili. Ale pár mých studentů vyrostlo v odborníky celkem značné a i se s nimi bavím a zase se zpět něco dozvídám.

    blink.vhd

    pro mě byl otevřením očí, protože jsem si vůbec neuměl představit, že se kód, ve kterém jsou vnitřní proměnné v procesu, které jsou použité jako stav přes wait, může syntentizovat do logiky. Sám jsem žil v přesvědčení, že tyto možnosti jsou použitelné jen pro účely behaviorálně popsaného testbedu a syntéza s nimi selže, protože jako paměť určenou pro syntézu lze používat pouze signály.

    U signálů je pak ale přiřazení "<=" v procesu neblokující, jen přidává event do seznamu toho co se stane. Takže je potřeba počítat s tím, že po celou jednu dobu běhu procesu signál nese tu původní hodnotu a až při dalším z běhů se nastaví na tu hodnou, která do něj byla poslední přidaná. Někdy se takto hodí, ale bez toho uvažování že to bude zpožděné se nadělá mnoho chyb. Ve verilogu jsou obě možnosti přiřazení blokující "=" a neblokující "<=" a není činěn rozdíl mezi signálem/proměnnou. Ve VHDL jsem chápal proměnnou buď jako normální proměnnou v procedure, function a třeba i procesu ale u procesu jen takového který je určený pro testbed. Ale v syntetizované logice chápu v procesu proměnné maximálně jako zjednodušení zápisu nějakého složitějšího kombinačního výrazu. Stejně tak přiřazení výsledku funkce a je jasné, že jak ta funkce tak ty výrazy přes proměnné se musí vysyntetizovat tak, aby to byla jen kombinační logika, tedy jeden převod stavu vstupů na výstupy. Ano, mohu napsat klidně bubblesort s proměnnými a for cyklem bez čekání, ale očekávám pak, že systéza navrhne takovou logickou síť, která v převede všechny možné kombinace vstupů (to je třeba 10 signálů, kde každý je po 8 bitech) na výstupních 80 vodičů tak že tam budou setříděné. Je asi jasné, že pro 2^80 vstupů se to syntéze nemůže povést. Udivuje mě, že by to možná s vložením nějakého delaye mezi jednotlivé iterace možná i takto psát šlo.

    Ale to co vzniká je opravdu něpěkné a nenapadlo mě ani na začátku, při prvním návrhu s VHDL, že by něco takového šlo. Ono jsem byl předtím vycvičený návrhem pro GAL, kde když jsme měli problémy s převody mezi různými variantami, tak jsem přímo and, or a configy psal v JED, pak jsem něco psal v ABELu. Pak pro XC3000 se kreslilo ze specializované řady TTL7400, takže tam opravdu člověka nenapadlo, že by to mohl psát jako kód.

    Pak když jsem se bavil na začátku o VHDL s Markem Pecou, který mi s ním pomáhal, tak ten mě odkázal na publikace Jiřího Gaislera (autor procesorů Leon a dalších pro Evropskou vesmírnou agenturu). Protože u jeho návrhů, které pak končily i na křemíku bylo požadavkem, aby šly převést na redundantní, majoritní logiku, která zvládá v daném kroku minimálně jednu dočasnou chybu a dlouhodobě i jednu trvalou, tak pro návrh a jeho možnost i automatizovaného převodu mezi jednoduchou a vícenásobnou logickou zavádí striktnější požadavky než limit toho, co zvládne syntéza v stále se vyvíjejících a zlepšujících nástrojích.

    Nehledal jsem zatím dostatečně dlouho, ale toto jsem od něj našel veřejné

    https://download.gaisler.com/research_papers/vhdl2proc.pdf

    Jinak u sebe na disku mám k VHDL asi 30 PDF souborů/knih. Ale nemám nyní čas najít, kde by tyto základy byly nějak dobře.

    Pro naše studenty pro svůj předmět, kde učí s VHDL, připravil mnoho knih a materiálů kolega doktor Richard Šusta. Zde je česká verze https://dcenet.fel.cvut.cz/edu/fpga/navody.aspx.

    Pro redundanci, asi starší verze jeho návodů zde https://susta.cz/FelUcebnice.aspx

    Odkazoval jsem na ně i pod minulým článkem.

    Ale jako spisovatel (i scifi), počítá s tím, že lidé umí číst delší texty, což je dnes i u mě problém, ale na rozdíl od jiných to nenechávám běšinou na výdobytcích strojového učení...

    Kolega se k prvnímu sekvenčnímu obvodu ve VHDL dostává po knihách BinarniPrerekvizita (29 str.), Logické obvody na FPGA (159 str.), Úvod do návrhu obvodů v jazyce VHDL I. (96 str.) až v uprostřed druhé knihy Úvod do návrhu obvodů v jazyce VHDL II. (70 str.) v kapitole 3 Obvody řízené hodinovým signálem. Je pravda, že on i ty postupy s použitím variable v procesech ale používá.

    Pokud si pamatuji správně Gaislera, tak ten byl tvrdě pro rozdělené logiky na kombinační proces, kde všechny uvnitř použité signály na pravých stranách jdou povinně v sensitivity listu. Naopak levé strany jsou zcela oddělěné signály třeba _next nebo _s a pak existuje druhý zcela nezávislý sekvenční proces, který pouze signály s _s nebo _next registruje při rising edge na _r, které jsou zase do toho kombinačního procesu a na výstupy. Takto má jasnou kontrolu, co je co...

  • 7. 3. 2025 0:48

    Martin Beran

    pro mě byl otevřením očí, protože jsem si vůbec neuměl představit, že se kód, ve kterém jsou vnitřní proměnné v procesu

    Já si to představuji tak, že proměnná představuje cestu v syntetizovaném obvodu. Každé použití proměnné ve výrazu odpovídá přivedení proměnné na vstupy nějaké skupiny LUT. Každé přiřazení do proměnné je realizováno nějakou skupinou LUT, která má proměnnou jako výstup. Pokud je proces sekvenční, na konci se poslední hodnota proměnné uloží do registru a tím se zachová pro další iteraci procesu (tj. je na výstupu registru při dalším hodinovém pulzu). Signál funguje podobně, ale ve výrazu se vždy použije hodnota přímo z registru, nikoliv z předchozího přiřazení. Výsledek přiřazení se přivádí pouze na vstup registru.

    Tělo procesu je kombinační obvod bez vnitřních stavů a interní proměnné jsou reprezentovány vodiči spojujícími části obvodu. Pokud je proces sekvenční, stav se na konci procesu uloží do registrů, kde je k dispozici na začátku další iterace.

    Nehledal jsem zatím dostatečně dlouho, ale toto jsem od něj našel veřejné https://download.gaisler.com/research_papers/vhdl2proc.pdf

    Tohle mi připadá dost podobné tomu, jak se standardně v literatuře popisuje implementace konečných automatů (state machine) pomocí dvou procesů, kde kombinační proces počítá další stav a výstupy a sekvenční proces si jen v každé iteraci zapamatuje nový stav. Alternativa je spojit oba procesy do jednoho. Já ve svém kódu používám obě varianty. Quartus oba způsoby zápisu rozpozná a nakreslí pro ně schéma automatu jako graf obsahující stavy jako uzly a přechody mezi nimi jako orientované hrany.

    Poněkud zvláštní je, že v textu jsou příklady kódu uvnitř procesů, které mi připadají celkem přirozené, ale mám pocit, že to je přesně ten styl, o němž tu někteří diskutující tvrdí, že je úplně špatně...

    Jestli jsem některé námitky zde v diskuzi správně pochopil, tak směřovaly právě proti použití behaviorálního popisu a upřednostňovaly data-flow návrh. Odkazovaný text naopak tvrdí, že data-flow popis je pro složitější obvody nesrozumitelný a behaviorální popis pomocí procesu, definující funkci obvodu v podstatě jako algoritmus, je vhodnější.

    Pro naše studenty pro svůj předmět, kde učí s VHDL, připravil mnoho knih a materiálů kolega doktor Richard Šusta.

    Děkuji za zopakování odkazů na studijní materiály. Díval jsem se na ně už když jste je napsal do diskuze u prvního článku a podle mého názoru jsou velmi užitečné a pěkně zpracované.

  • 7. 3. 2025 1:07

    RDa

    Je treba rozlisovat mezi process-variable a function-variable ...

    To prvni jsou opravdu jako "lokalni signaly" jen pro dany proces a maji "perzistenci" (proto se tvari jako signaly).

    Do nich se prirazuje ihned skrze := (kdy se zmeni hodnota ihned) - a hodnota muze byt na kazdem radku kodu tedy jina (a syntetizuji se pak jako aliasy), zatimco prirazeni do klasickyho signalu skrze <= je takove prepisujici - plati hodnota na kterou se signal ustali na konci procesu (a syntetizuje se kombinacni logika + registr, pokud je to pod hodinama).

    To druhe, kdyz je to ve funkci, tak je to spis makro/pomucka, skrze kterou popisete decision tree rychleji, nebo udelate ruzne opakovani. Samotna funkce se syntetizuje vzdy na kombinacni logiku (lut/rom). Tamni promenne nemaji pak syntetizovany ekvivalent.

    A stejne se chovaji i promenne pouzite ve for/generate, ze jsou takove.. nad veci.

    Promenne ve funkci a generate cyklech perzistenci nemaji.

  • 8. 3. 2025 14:37

    Biktop

    Pro naše studenty pro svůj předmět, kde učí s VHDL, připravil mnoho knih a materiálů kolega doktor Richard Šusta.

    Koukám do skript "Logické obvody na FPGA" a tedy musím říci, že z těchto skript bych to rozhodně nepochopil. Připadá mi, že s triviálními věcmi se tam autor zbytečně patlá, zatímco náročnější vysvětluje pro mě velmi těžko stravitelným způsobem – např. kapitola o Karnaughových mapách.
    Výklad mi připadá zmatený, stylově neukotvený ("přesuneme bublinku zprava doleva" na jednom místě vs. standardní styl "definice: Nechť je dána funkce..." o kousek dál).
    Naprosto nepochopitelná pro mě je volba fontů textu, zcela v rozporu s ustálenými zvyklostmi sazby matematických textů, nevhodný zůsob zvýrazňování atp. Autor se nejspíš snažil o jakýsi inovativní způsob sazby za účelem zvýšení přehlednosti, podle mě se mu podařil pravý opak zamýšleného – má na mysli funkci? Nebo má na mysli logický prvek? Nebo snad jen anglický termín? Je to proměnná, nebo jen spojka či předložka ve větě? O obrázcích uvádí, že je jejich autorem – pak ovšem nechápu, proč používá anglická spojení i v místech, kde nejde o žádný ustálený termín. Je to matoucí. Snad se na přednáškách dokáže vyjadřovat lépe, jinak studenty lituji.
    V úvodu také zmiňuje, že k sazbě byl místo profesionálního systému použit MS Word vzhledem k velkému počtu obrázků. Toto vysvětlení jde zcela mimo mé chápání. S obrázky jsem v TeXu nikdy nezažíval takový boj, jako v MS Wordu. Zároveň to dokazuje, že k vytváření solidně vypadajících bohatších textů se MS Word opravdu nehodí.

    Delší dobu sháním nějakou literaturu na toto téma pro mladší kolegy, zatím marně. Česky, anglicky, zadarmo či za peníze... Doufal jsem, že toto by mohlo být to pravé, ale bohužel.

  • 9. 3. 2025 1:49

    Pavel Píša

    Tak nabízím to, o čem vím. Myslím si, že konstrukce VHDL jsou v textu popsané a lze se je z něj naučit. Ano, zrovna sám bych ten styl s proměnnými v procesech použitými přes wait nebo rising edge nepoužíval. Nějak jsem naučený, že paměť má být na signálu. Ale možná je to moje chyba.

    Jinak sám bych také preferoval jiný formát než Word, slidy k našim přednáškám k procesorovým předmětů byly v LibreOffice, nyní ty základní máme v LaTeX beameru, a zdroj jak u nás, tak na GitHubu, pokud by chtěl někdo mimo ČVUT poslat korekci. Tato iterace je teď primárně česky, ale sám si myslím, že splnění rozkazu vedoucího programu přepsat slidy do češtiny nebyl dobrý nápad a teď je zase potřebuji dokončit přepsání z té upravené podoby zpět do angličtiny pro cizince. Jinak z té tabulky přednášek jsou pod jednotlivými čísly také odkazy na zdroje, naše starší přednášky a i různé rozšiřující materiály. Na logiku třeba i v polypad amplify, kde si lze logiku proklikat.

    Během překládání se dost z původních přednášek vypustilo, některé obrázky rozbily a teď nacházíme chyby a to i vhledem k časové tísni na přehlad tak to vypouštění je i proto, že ty původní slidy byly opravdu obsáhlé. Zase se ale něco zajímavého přidalo a kolega bude část přesovat do nového úvodního předmětu, který bude na takovou spíše všeobecnou znalost a z třetiny i na tu Booleovu algebru a ukládání informace do bitů.

    Jinak pěkný úvod v češtině i angličtině do Verilogu má i kolega z FITu, se kterým jsme původně náš kurz dávali dohromady. Jedná se o předmět
    Architektura počítačových systémů (BI-APS), Přednáška: Úvod do jazyka Verilog, ale FIT obecně materiály volně přístuné nemá. Dvě jejich přednášky v rámci naší spolupráce placené z veřejných zdrojů byly přidané na společně využívaný comparch. Kolega má v plánu napsat i skripta, knihu, spíš ale na procesory. Sám spíš doporučuji ty zahraniční učebnice od prof. Pattersona (Computer organization and design RISC-V edition: the hardware/software interface) a nebo Sarah Harris a David Harris (Digital Design and Computer Architecture, RISC-V Edition), v té druhé se vysloveně konstrukce Verilogu a VHDL ukazují na stavbě procesoru.

  • 4. 3. 2025 15:47

    calvera

    zz_indigo: soudim, ze tomu rozumite, budu rad, kdyz nam pripadne napisete na root.cz nejaky (klidne maly) tutorial k VHDL (verilogu)

  • 5. 3. 2025 20:34

    zz_indigo

    Nerozumiem tomu toľko aby som vypisoval články. A tiež chápem svoje limity. Moje SVN je plne hrobov ;-)

    To najzložitejšie, čo som vo VHDL spravil sam od začiatku, je FastRAM pre A600. Z autokonfigom a za použitia DRAM.

    Všetko zložitejšie využíva prácu radovo šikovnejších. (opencores.org) napr PMI-80 (https://youtu.be/LNxGf5JVSt0?feature=shared)

  • 5. 3. 2025 1:53

    radioing

    Ahoj, predne musim rict, ze se tu rozjizdi pekny serial (moc dik za nej), a jelikoz se v branzi pohybuji uz nejaky ten patek a nemohl jsem si nevsimnout komentaru vyse, tak jsem nevydrzel, a podival se na github a i na ten procesor 5016.
    Vytky kolegu bych shrnul asi tak, ze se jim nelibi nektere spatne navyky a nebezpecne konstrukty, ktere se mohou v budoucnnosti pekne vymstit (ve smyslu, ze se u komplikovanejsich obvodu bude pripadna chyba pekne spatne hledat), nekdy zbytecne prodluzuji signalpath (tj. cas mezi Q->D DFFs, coz se projevi snizenym max. hodinovym kmitoctem vysledneho designu) a design pozira zbytecne mnoho resources.
    Nicmene pokud jste se sam v uvedenem case dopracoval az sem, tak klobouk dolu, pokud mohu srovnavat se studenty a juniory. Budete-li s FPGA pokracovat (vrele doporucuji, je nas malo), pak by stalo za to poohlednout se po najake ucebnici VHDL + VHDL standard, a vstrebat nektere lety proverene "best practices" (Risc-V nekde na githubu nemusi byt dobry vzor.)
    Ono napriklad ten prvni proces led12 je v podstate OK (wait on clk...) a je syntetizovatelny (jinak by to nechodilo, ze), ale jen diky tomu, jak je to napsane (tj. forma zapisu wait, jeden wait v procesu), protoze jinak obecne wait syntetizovatelny byt nemusi. Takto zapsane je to skutecne ekvivalentni "if rising_edge(clk)", coz je patrne z toho, ze cnt, state, led1 a led2 jsou vystupy DFF. Nicmene rozhodne to neni "best practice" a pri komplikovanejsim designu jsou vidle uz hodne blizko.
    Par hintu:
    1. Pokud to jde, strkejte vse dovnitr procesu uvozenych rising_edge (running12, running34). Vidite, co napachalo to running34 (zbytecna LUT na vystupu), nebo running12 (latch). Logika se vam pak zdrcne do LUT pred DFF (tj. signaly na leve strane = vystup DFF) a design se stane plne synchronni, coz je z mnoha duvodu zadana vlastnost.
    2. Zkuste zapremyslet, jaka je presne perioda blikani (dabel je ukryt v detailu).
    3. Pro casovani pomoci citacu pouzivejte citani smerem dolu s preloadem. On ten konstrukt citac nahoru-komparace-reset je obecne rozsireny nesvar i v lepsich ucebnicich, ale vidite, co to udela - krome uz tak pomaleho citace (carry pres moc moc bitu) je za nim jeste dalsi logika (komparator), a pak teprve feedback. To vede k tomu, ze jednak ma citac nizsi fmax, druhak to zere zbytecne moc zdroju. Pritom by na to deleni 50 MHz stacilo 27 DFF + pridruzene LUT v ramci makrocely. Jeden proces by pak vystacil s 29 DFF a cely design pri jeste stale citelnem zapisu (idealne FSM se stavy = led vystupy) s 32 DFF. Chapu, ze to zde vubec neni o optimalizaci, na druhou stranu VHDL je o praxi, tak proc si to neprocvicovat hned od zacatku.

  • 5. 3. 2025 11:18

    RDa

    Ja si treba nestezuji, ale nedelam to jako full-time job, spise se povede raz za cas licencovat vetsi a ucelenejsi IP celek, takze klient tam plati za to, ze neco dostane "hned", a to muze byt pak zajimava vysokohorska prirazka. Zatimco v kodu nebo sw utilitach vam konkuruje mnoho i free alternativ, tak v pripade embedded, a HDL IP ten prostor neni tak na krev konkurencni a porad existuji nepokryta mista, kde se lze realizovat. Plus temer vse komercniho neni ve forme zdrojaku, na coz nekteri zakaznici slysi (to jenom stat je neschopnej si specifikovat pristup a licenci ke zdrojakum).

    Pokud se budeme bavit o nabidce vyvoje za hodinovku, resp zamestnani, tak tam rozdil nebude.. zidle jako zidle, ruce jak ruce, jste jen kapkou v korporatnim mori.

  • 21. 3. 2025 10:02

    Biktop

    Docela mě děsí, že někdo, kdo tvrdí, že inferred latch není problém, navrhuje FPGA za peníze. Pro koho jste dělal návrhy? Abych se těmto produktům mohl co největším obloukem vyhnout.
    Elektrikáře, který by mi tvrdil, že nezapojený PE vodič není problém, že bez něho to taky bude fungovat, bych vyhnal okamžitě. Vaše tvrzení o latchích je na podobné úrovni.

  • 21. 3. 2025 13:35

    RDa

    Tak jeste jednou - jestli projde simulace, jestli vyhovuji constrainty, jestli produkt funguje - a nastroje s tim nemaji vubec problem, tak proc je inferred latch problem, na rozdil treba od inferred block ram? Evidentne tool sam vi, co si muze dovolit.

    Jina vec by byla, kdyby design nebyl spravne naconstrainovan, coz je vas pripad PE vodice, ale nemit constrainty by v pripade FPGA vedlo na neco co ani fungovat nebude.

  • 5. 3. 2025 21:30

    Martin Beran

    Ahoj, predne musim rict, ze se tu rozjizdi pekny serial

    Dík za pochvalu.

    Vytky kolegu bych shrnul asi tak, ze se jim nelibi nektere spatne navyky a nebezpecne konstrukty, ktere se mohou v budoucnnosti pekne vymstit

    Bez obav, už se vymstily, když se mi někde při dalším vývoji nějaké podobné konstrukce podařilo udělat. Všichni se tu pořád točí na asi třetím .vhd souboru, co jsem kdy napsal, navíc jsem si na něm zkoušel, jak a proč se různé konstrukce chovají, ať už jsou dobře nebo špatně.

    protoze jinak obecne wait syntetizovatelny byt nemusi

    To vím, ostatně je to i napsané v dokumentaci Quartusu.

    Pokud to jde, strkejte vse dovnitr procesu uvozenych rising_edge

    To dělám, ten wait je nikde jinde v celém repozitáři nevyskytuje (kromě jednoho testbenche), navíc často používám ještě asynchronní reset, což se s if píše lépe.

    Zkuste zapremyslet, jaka je presne perioda blikani (dabel je ukryt v detailu).

    Hledání chyb v časování událostí +/- jeden takt hodin už jsem si užil dost.

    Pro casovani pomoci citacu pouzivejte citani smerem dolu s preloadem.

    Můžete sem hodit ukázku kódu, jak přesně to myslíte? Zkusil jsem toto a Quartus hlásí 49 LEs a 27 registrů. Tak nevím co a jak ušetřím čítáním dolů.

    process (Clk) is
        variable cnt: unsigned(25 downto 0) := (others=>'0');
    begin
        if rising_edge(Clk) then
            if cnt = 50_000_000 then
                cnt := (others=>'0');
                state <= not state;
            else
                cnt := cnt + 1;
            end if;
        end if;
    end process;
    LED(0) <= state;
  • 5. 3. 2025 22:54

    radioing

    Trik s citanim dolu spociva v tom, ze registr citace ma jeden DFF na nejvyssi pozici navic (tj. chcete delit napr. 200, potrebujete 8 DFF, pridate devaty). Pri citani dolu dojde k podteceni hodnoty v citaci (2 -> 1-> 0 -> 511 (1FFh)), a prave tento signal z pridaneho DFF je zaveden zpet do vsech LUT pridruzenych k DFF a zpusobi nastaveni nove hodnoty citace (preload). V pripade deleni 200 by to byla hodnota 198. Nastaveni nove hodnoty preklapi nejvyssi DFF zpet do nuly, takze ten generuje pouze 1T 'reload' puls.
    Co ztracim:
    1. Pozere mne to jeden DFF navic.
    2. Citani dolu s podtecenim znamena, ze hodnoty v citaci nejsou "slusne vychovane", ale v drtive vetsine pripadu (delicky kmitoctu, casove zakladny generujici 1T pulsy dane repetice, zpozdovaci obvody,... odhaduji tak 90 % aplikaci), to neni na zavadu.
    Co ziskam: fmax a resources (LUT)
    Reseni s komparatorem znamena, ze povetsinou vsechny bity citace (vystupy DFF) musi byt zavedeny do kaskady LUTs (mame typ. 4- nebo 6vstupe), a teprve vysledek komb. obvodu je zaveden zpet do LUT pridruzenych k DFF nebo sync resetu vsech DFF, pokud jiz neni obsazen 'POR' resetem. Vysledkem potom je signalova smycka LUT-DFF-LUT, kde LUT za DFF malokdy byva soucasti makrocely (tu obsadi citac, nebot v ramci makrocely je vertikalne natazena cesta fast carry).
    Reseni s downcounterem usetri LUT za DFF a muze byt vyrazne rychlejsi (reload signal se nevytahuje do right/left makrocel, ale do top/bottom makrocel, ktere maji rychle interni propojeni, protoze vyrobce s n-bitovymi operacemi pocita - podobne, jako je zde natazena fast carry logika).
    Treba na Versalu to za priznivych okolnosti muze zvysit max fclk az o desitky procent.
    Samozrejme existuje i symetricke reseni s upcounterem, kde preteceni je indikovano pulsem do log. 0 na vystupu pridaneho DFF.

  • 5. 3. 2025 23:46

    Martin Beran

    Trik s citanim dolu spociva v tom, ze registr citace ma jeden DFF na nejvyssi pozici navic

    Díky za vysvětlení, tenhle trik jsem neznal. Zkusil jsem si Váš popis přepsat do VHDL a dává mi to smysl.

  • 6. 3. 2025 12:46

    calvera

    takze takhle?


    entity test is
    port (
    reset : in std_logic;
    clk_i : in std_logic;
    clk_o : out std_logic
    );
    end entity;
    architecture arch of test is
    signal count : STD_LOGIC_VECTOR (25 downto 0) := (25 => '1', others => '0');
    begin
    process (clk_i) -- delicka na ziskanie nizsej freq
    begin
    if reset = '0' then
    count <= (25 => '1', others => '0');
    elsif (rising_edge(clk_i)) then
    count <= count - 1;
    if count(25) = '1' then
    clk_o <= NOT clk_o;
    count <= "010111110101­11100001000000";
    end if;
    end if;
    end process;
    end architecture;

    6. 3. 2025, 12:49 editováno autorem komentáře

  • 7. 3. 2025 1:16

    radioing

    Jj, treba tak.
    Takhle by to bylo napr. s temi 4 x LED, kdy vystupy na LED jsou primo vystupy DFF a zmena urovne nastava ve stejnem okamziku na vsech LED.
    Prvni proces je optimalizovan pro 4 x LUT4 + 4 x DFF (citac nepocitaje). Ma ale sve neduhy -> prechody mezi LED nesviti/LED blikaji nejsou uplne "slusne vychovane".
    Druhy proces to resi ponekud lepe, ale uz potrebuje LUT6 (stop by mel byt zaveden do CLR DFFs), nicmene co se tyce resources, stale by se mel vejit do 4 x LUT6 + 4 x DFF.
    Omlouvam se za blbe formatovani, ale nic lepsiho jsem v povolenych tags nenasel.

    ----------------------------------------------------------------------------------
    -- LED1234
    ----------------------------------------------------------------------------------
    
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    use IEEE.MATH_REAL.ALL;
    
    entity led is
        generic (
            crystal_khz : integer := 50_000;
            period_ms :   integer :=  1_000
        );
        port (
            start : in std_logic;
            stop :  in std_logic;
            rst :   in std_logic;
            clk :   in std_logic;
            led1 :  out std_logic;
            led2 :  out std_logic;
            led3 :  out std_logic;
            led4 :  out std_logic
        );
    end led;
    
    architecture rtl of led is
    
    -- Select variant
    constant GEN_TYPE : natural := 1;
    
    -- Counter
    constant cnt_width : integer := integer(ceil(log2(real(2 * crystal_khz * period_ms)))) - 1;
    signal cnt : std_logic_vector(cnt_width downto 0);
    
    -- FSM with std_logic_vector as state memory
    subtype  stdlogicvector2 is std_logic_vector(1 downto 0);
    constant LED_OFF : stdlogicvector2 := "00";
    constant LED1_ON : stdlogicvector2 := "01";
    constant LED2_ON : stdlogicvector2 := "10";
    signal state : stdlogicvector2 := LED_OFF;
    --With enum:
    --type state_type is (LED_OFF, LED1_ON, LED2_ON);
    --signal state : state_type; etc.
    
    -- LED3 & LED4 common trigger signal
    signal trig34  : std_logic;
    -- LEDs intern
    signal led3int : std_logic;
    signal led4int : std_logic;
    
    -- FSM with std_logic_vector as state memory
    subtype  stdlogicvector4 is std_logic_vector(3 downto 0);
    constant LED00 : stdlogicvector4 := "0000";
    constant LED13 : stdlogicvector4 := "0101";
    constant LED14 : stdlogicvector4 := "1001";
    constant LED23 : stdlogicvector4 := "0110";
    constant LED24 : stdlogicvector4 := "1010";
    signal state4 : stdlogicvector4 := LED00;
    
    begin
    
    TYPE0 : if GEN_TYPE = 0 generate
    
        led12 : process (clk) is
        begin
            if rising_edge(clk) then
                -- Downcounter as a timebase
                if (rst = '1') then
                    -- We start at 0 so overflow at nexk clock cycle resets FSM
                    cnt <= (others => '0');
                elsif (cnt(cnt'high) = '1') then
                    cnt <= std_logic_vector(to_signed((crystal_khz * period_ms) - 2 , cnt'length));
                else
                    cnt <= std_logic_vector(unsigned(cnt) - 1);
                end if;
                -- FSM for LED1 and LED2 - 2 x DFF
                if (stop = '1') then
                    -- 'stop' as common reset
                    state <= LED_OFF;
                else
                    case state is
                        when LED_OFF =>
                            if (start = '1') then
                                state <= LED1_ON;
                            end if;
                        when LED1_ON =>
                            if (cnt(cnt'high) = '1') then
                                state <= LED2_ON;
                            end if;
                        when LED2_ON =>
                            if (cnt(cnt'high) = '1') then
                                state <= LED1_ON;
                            end if;
                        when others =>
                            state <= LED_OFF;
                    end case;
                end if;
                -- LED3, LED4 - 2 x DFF
                if (state = LED_OFF) then
                    led3int <= '0';
                    led4int <= '0';
                elsif (trig34 = '1') then
                    led3int <= not led3int;
                    led4int <= led3int;
                end if;
            end if;
        end process;
    
        -- Trig pulse for LED3 and LED4
        trig34 <= state(1) and cnt(cnt'high);
    
        -- Outputs from DFFs
        led1 <= state(0);
        led2 <= state(1);
        led3 <= led3int;
        led4 <= led4int;
    
    end generate TYPE0;
    
    TYPE1 : if GEN_TYPE = 1 generate
    
        led1234 : process (clk) is
        begin
            if rising_edge(clk) then
                -- Downcounter as a timebase
                if (rst = '1') then
                    -- We start at 0 so overflow at nexk clock cycle resets FSM
                    cnt <= (others => '0');
                elsif (cnt(cnt'high) = '1') then
                    cnt <= std_logic_vector(to_signed((crystal_khz * period_ms) - 2 , cnt'length));
                else
                    cnt <= std_logic_vector(unsigned(cnt) - 1);
                end if;
                -- FSM for 4 x LED - 4 x DFF
                if (stop = '1') then
                    -- 'stop' as common reset
                    state4 <= LED00;
                else
                    case state4 is
                        when LED00 =>
                            if (start = '1') then
                                state4 <= LED13;
                            end if;
                        when LED13 =>
                            if (cnt(cnt'high) = '1') then
                                state4 <= LED14;
                            end if;
                        when LED14 =>
                            if (cnt(cnt'high) = '1') then
                                state4 <= LED23;
                            end if;
                        when LED23 =>
                            if (cnt(cnt'high) = '1') then
                                state4 <= LED24;
                            end if;
                        when LED24 =>
                            if (cnt(cnt'high) = '1') then
                                state4 <= LED13;
                            end if;
                        when others =>
                            state4 <= LED00;
                    end case;
                end if;
            end if;
        end process;
    
        -- Outputs from DFFs
        led1 <= state4(0);
        led2 <= state4(1);
        led3 <= state4(2);
        led4 <= state4(3);
    
    end generate TYPE1;
    
    end rtl;
  • 5. 3. 2025 16:47

    fanoush

    Hmm je zajimave ze nikdo z kritiku opravdu konkretne neuvedl priklad jak se to teda pise dobre ani neposlal zadny konkretni link na spravny priklad.

    blikani LED https://github.com/martin-beran/fpga/blob/mb50_v1/led_blink_vhdl/blink.vhd ma celkem 69 radku, to je opravdu takovy problem napsat tech par radku jak je to teda podle kritiku spravne, misto te spousty obecnych poucujicich ale nepomahajicich komentaru ktere urcite zabraly vic casu napsat.

  • 5. 3. 2025 21:38

    Martin Beran

    Hmm je zajimave ze nikdo z kritiku opravdu konkretne neuvedl priklad jak se to teda pise dobre ani neposlal zadny konkretni link na spravny priklad. blikani LED https://github.com/martin-beran/fpga/blob/mb50_v1/led_blink_vhdl/blink.vhd ma celkem 69 radku

    Mě hlavně udivuje, jak se tu všichni pořád točí na tom jednom souboru obsahujícím starý experiment a ignorují dalších skoro 9000 řádků VHDL v repozitáři.

  • 6. 3. 2025 9:51

    fanoush

    tak to bych chapal ze se nikdo nebude poustet do 9000 radku, ale na trivialnim pripade s LED by to snad melo byt idealni ukazat jak je to dobre

    Ja jsem teda taky hlavne programator a kdyz jsem videl vhdl a verilog tak mi prislo ze na vhdl je muj zivot uz prilis kratky. A asi bych delal stejne chyby protoze ten HW zaklad nemam. Takze bych opravdu ocenil kdyby nekdo byl schopen ten rozdil v pristupu na tomhle konkretnim prikladu s LED ukazat abych videl obe verze vedle sebe.

  • 6. 3. 2025 11:00

    Martin Beran

    tak to bych chapal ze se nikdo nebude poustet do 9000 radku, ale na trivialnim pripade s LED by to snad melo byt idealni ukazat jak je to dobre

    Hned ve druhém odstavci první části tohoto článku píšu: "Tento seriál nemá za cíl sloužit jako výukový materiál pro jazyk VHDL..." Celý seriál jsem pojal jako popis mojí cesty od nuly, kdy jsem jen tušil, že existují věci jako FPGA a VHDL, až k jednoduchému funkčnímu CPU podle vlastního návrhu a kolem něj postaveného počítače. Asi jsem měl víc zdůraznit, že ten první kousek VHDL nebyl myšlen jako ukázka správného optimálního kódu, ale jako demonstrace, jak vypadá zdrojový kód a co z toho syntetizér vygeneruje (ty dva obrázky zapojení).

    Nemám nic proti tomu, naopak pouvažuji za přínosné, když někdo ukáže na konkrétní chyby v tomto kódu a navrhne lepší řešení, to vše nejlépe s ukázkou kódu a s vysvětlením, aby se jak autor, tak i ostatní čtenáři mohli poučit a aby ty chyby někdo další nezačal napodobovat. Timto děkuji "radioing" za velmi pěkné vysvětlení lepší implementace čítače.

    Já se jen trochu ohrazuju proti tvrzením, založeným pouze na tomto jednom zdrojáku, že autor dělá všechno špatně, nechápe rozdíl mezi popisem obvodu a programováním, měl by si nejdřív přečíst nějaký tutoriál, má (špatně) zafixované, co je proces a state machine, atd. Určitě je spousta chyb a nedokonalostí i v těch dalších 9000 řádcích kódu, na druhou stranu ale ty obvody nějak fungují, včetně toho výsledného počítače, tak asi nemůže být úplně všechno úplně špatně.

  • 13. 3. 2025 12:01

    Pomalu

    Především musím poděkovat za hezký seriál na téma, které mě vždy zajímalo ale reálně jsem se k němu skoro nedostal.
    FPGA jsem měl jen jeden semestr na VŠ a od té doby nic. Jen si tak matně vzpomínam že nám říkaly něco jako když prostředí hlásí latch tak je to špatně. Potom ještě něco jako že by hodiny neměly být generovány klasickou logikou, ale že by se mělo takovým signál hradlovat hodinový signál a že by se hodinový signál měl detekovat hranou, né úrovní. Možná že si to pamatuji špatně, nebo už to dnes neplatí...

    Mám takový návrh na pokračování seriálu, občas zabloudím na projekt lidí co se zabývají FPGA a všiml jsem si že někteří používají framework Litex, což je python obal na VHDL (nebo spíš Verilog) a dělají s tím docela šílené věci jako SOC s RISC-V, DDR a na tom rozchodí Linux a další volovinky. Myslím že se s frameworkem dá dojít dál než jen s čistým VHDL. Asi bych to trochu připodobnil k čistému PHP versus Nette / Symfony.

  • 14. 3. 2025 16:32

    Martin Beran

    Mám takový návrh na pokračování seriálu, občas zabloudím na projekt lidí co se zabývají FPGA a všiml jsem si že někteří používají framework Litex, což je python obal na VHDL (nebo spíš Verilog)

    Podíval jsem se na web projektu a vypadá zajímavě. Já ale o tomto frameworku jinak nic nevím, což není úplně nejlepší stav pro psaní článků. Ale třeba se toho chopí někdo jiný...

    dělají s tím docela šílené věci jako SOC s RISC-V, DDR

    Je s tím asi dost práce a vyžaduje to nějaké znalosti, ale zase jako úplná šílenost mi to nepřipadá.

    a na tom rozchodí Linux a další volovinky

    Když už mají CPU, dostatek RAM, nějaké úložiště (například SD karty nebo SATA) a nějakou grafiku nebo aspoň sériový port pro konzoli, tak by Linux nemusel být velký problém.

    Myslím že se s frameworkem dá dojít dál než jen s čistým VHDL.

    Spíš bych řekl, že s frameworkem se dá dojít do cíle rychleji, když není potřeba všechno vyvíjet od nejnižší úrovně. Já jsem se naopak ve svém projektu počítače MB50 snažil všechno dělat bez použití existujících komponent, i když pro části hardwaru jako je VGA, PS/2, nebo RS232 by se existující implementace daly docela snadno najít.