česky english Vítejte, dnes je čtvrtek 18. duben 2024

Diskové soubory ve VHDL

DPS 3/2017 | Články
Autor: Tomáš Majer

Při simulaci FPGA projektu, který zpracovává nějaký datový tok, může být v simulaci celého projektu výhodné mít příslušný datový proud uložen v diskovém souboru (dále pouze slovo „soubor“). Vzniklá situace může vypadat např. podle obr. 1, kdy projektem v FPGA jest digitální filtr, který zpracovává vzniklý číslicový signál z A/D převodníku, a zpracovaný signál je odeslán do D/A převodníku.

Popsaná situace při simulaci VHDL projektu pak vypadá podle obr. 2, kdy reálný vstupní digitální signál získaný např. z osciloskopu je uložen ve vstupním souboru a výstupní digitální signál k ověření např. v MATLABu se zapíše do výstupního souboru.

Obr. 1 Reálný systém, Obr. 2 Simulace VHDL projektu

I když o jazyku VHDL bylo napsáno mnoho nejrůznější literatury, tak o použití souborů v něm se literatura zmiňuje jenom okrajově a o datovém formátu v nich není téměř nikde nic uvedeno. Tento článek se zabývá právě použitím souborů ve VHDL (na obr. 2 v červeně orámované části) a měl by čtenáři tuto problematiku trochu ozřejmit.

Funkce jazyka VHDL pro práci se soubory

Všechny popsané funkce (kromě deklarací) pro práci se soubory jsou sekvenčního charakteru. Lze je tedy (snad kromě funkce otevření souboru) použít v těle sekvenčního příkazu „Process“. Skutečnost, že všechny operace se soubory nejsou syntetizovatelné do FPGA obvodu, snad ani nemusím uvádět.

Při zápisu do souboru lze použít funkce uvedené v tabulce 1, zatímco při čtení ze souboru funkce uvedené v tabulce 2.

Tabulka 1, 2

V deklarační části architektury se deklaruje typ souboru, kterému se současně přiřazuje typ proměnné, která se zapisuje, resp. čte. Dále se deklaruje proměnná soubor, které se přiřazuje název souboru na disku počítače a současně se stanovuje způsob práce se souborem. Proměnná soubor se používá ke komunikaci se souborem i v ostatních instrukcích. Dále se soubor otevře v režimu čtení nebo zápisu či v režimu připsání dat za konec souboru. Potom se do souboru provádí zápis, resp. se z něj čte, a na konci jeho použití se soubor uzavře. Deklarace typu soubor a proměnné soubor mohou vypadat třeba následovně:

  • Type diskovySouborA is file of integer;
  • Type linkaB is file of std_logic;
  • Type sberniceC is file of bit_vector;

Poznámka: Všimněte si, že v deklaraci typu souboru sberniceC není deklarována bitová šíře fyzického vektoru.

  • File souborX: diskovySouborA open write_mode is “hodnoty.bin”;
  • File souborY: linkaB;
  • File souborZ: sberniceC;

Soubor je zpravidla na disku fyzicky umístěn v hlavním adresáři projektu. U různých simulátorů může být umístění souboru různé. Je tedy nutné před spuštěním simulace umístění souboru prověřit, zvláště při čtení souboru.

Otevření souboru je možné dvěmi různými způsoby. Buď je možné otevřít soubor už při jeho deklaraci (viz diskovySouborA), nebo je možné soubor otevřít až v těle příslušného procesu, např. takto:

  • file_open (souborY, “data.bin”, read_mode);
  • Variable statusSoubor :
  • FILE_OPEN_STATUS;
  • file_open (statusSoubor, souborZ, “info.dat”, append_mode);

Při otevírání souboru je možné využít příznakovou proměnnou statusSoubor typu FILE_OPEN_STATUS, do které se ukládá informace o úspěšnosti operace otevření souboru. Tato proměnná může nabývat dokumentovaných hodnot OPEN_OK, STATUS_ERROR, NAME_ERROR, MODE_ERROR, ale i jiných, které dokumentovány nejsou. Prakticky ale platí, že pokud proměnná statusSoubor je různá od OPEN_ OK, pak došlo při otevření souboru k chybě.

Příklad práce se souborem

Práce se souborem (čtení, resp. zápis) je možná pouze v režimu „sériového proudu čtených, resp. zapisovaných, dat“. Na rozdíl od jiných programovacích jazyků (C, C++) jazyk VHDL neumožňuje pohyb po souboru pomocí nějakého ukazatele, dále neumožňuje vpisovat, přepisovat nebo číst či mazat data bez uzavření souboru a opětovného otevření v příslušném módu. Používají se k tomu dvě instrukce bez příznakových proměnných:

  • write (souborX, dataI);
  • read (souborY, dataR);

Další velmi důležitou instrukcí je instrukce test konce souboru, která se používá při čtení dat ze souboru:

  • Variable testSouboru : boolean;
  • testSouboru := endfile (souborY);

Pokud při čtení dat ze souboru je dosaženo jeho konce a tato situace není testována, pak při pokusu o čtení za koncem souboru simulace skončí chybou (většinou zhroucením simulátoru). Toto lze ošetřit napsáním takového procesu, který při dosažení konce souboru buď generuje nějaká defaultní data, nebo začne číst soubor od začátku.

Pro uzavření souboru se používá instrukce:

  • file_close (souborZ);

která také neobsahuje žádnou příznakovou proměnnou, takže ani neexistuje možnost úspěšnost operace zkontrolovat.

Při práci se soubory může dojít k několika zádrhelům, kdy průběh simulace končí chybou. Problém může nastat při otevření a uzavření souboru, ale i při práci s ním – čtení, zápisu a připsání dat.

  • Kód jazyka VHDL, který do souboru zapisuje a současně z něj čte, většinou nejde ani přeložit.
  • Proces, který soubor čte nebo do něj zapisuje, většinou neobsahuje funkce otevření a uzavření souboru. Otevření souboru je možné přímo v jeho deklaraci, ale do procesu v naprosté většině případů není zaveden žádný signál, který by soubor uzavřel před skončením simulace. Většina simulátorů soubor po ukončení simulace uzavře, ale setkal jsem se i se situací, kdy soubor byl uživateli přístupný až po restartu počítače.
  • Dále může dojít k problému, kdy soubor na disku fyzicky existuje, ale má nepovolené atributy nebo je otevřen jiným programem. Simulace opět končí chybou.
  • Proces se snaží číst, resp. zapisovat, do souboru, který ještě jiný proces neotevřel. Podobně při uzavření – soubor je uzavřen jedním procesem dříve, než je žádoucí. Obecně platí, že otevírat nebo uzavírat soubor v jednom procesu a zapisovat či číst v druhém procesu není zrovna nejšťastnější řešení.

Proces provádějící korektní zápis do souboru vždy s náběžnou hranou hodinového signálu CLK a povolením zápisu signálem WRenable podle obr. 2 vpravo bez havárie simulátoru, který řeší výše uvedené problémy, uvádím v příkladu na vedlejší straně. Pro čtení ze souboru lze napsat podobný bezhavarijní proces.

Číselné a fyzické typy

Nyní se podíváme, jak jsou některé číselné a fyzické typy v souborech binárně zakódovány, aby soubory mohly být předpřipraveny, resp. zpracovány, v nějakém z vyšších programovacích jazyků (C, C++ apod). Příklady zakódování některých typů ukazují tabulky 3 a 4.

Tabulka 3, 4

Číselný typ integer standardně zabírá čtyři byty v diskovém souboru, přičemž data se zapisují ve formátu Intel – nižší byte čísla se zapisuje blíže k začátku souboru. Konvence zápisu Intel platí i pro ostatní typy, kromě fyzických vektorů.

Typ real v 64bitovém rozsahu (Double) nebo v 32bitovém rozsahu (Float) je definován normou IEEE 754. Blíže viz [1]. Simulátory standardně podporují 64bitový rozsah číselného typu real, který v diskovém souboru zabírá 8 bytů. Lze se ale i setkat se simulátory jazyka VHDL podporující pouze 32bitový rozsah tohoto typu. Soubory jsou potom vzájemně nekompatibilní.

Číselné typy mohou mít omezený rozsah hodnot pomocí příkazu range. Tyto omezené číselné typy se nedoporučuje používat v souborech z důvodu nejednoznačnosti. Pokud už je nutné použít omezený číselný typ, pak je vhodné provést nejdříve jeho konverzi na typ se základním rozsahem, případně obráceně.

Jednobitový číselný typ boolean je v souboru reprezentován celým jedním bytem. Podobnou vlastnost využívají i ostatní fyzické typy bit, std_logic a std_ulogic. Poslední dva zmiňované typy nabývají i jiných hodnot než jenom log.0 nebo log.1 podle tabulky 4.

U fyzických vektorů (dále pouze slovo „vektor“) je zakódování složitější. Každý bit vektoru je v souboru reprezentován jedním bytem. Pro typ bit viz tabulka 3 a pro std_logic a std_ulogic viz tabulka 4. LSB bit vektoru, který je deklarován obvyklým zápisem sestupně (tedy n downto 0), je blíže ke konci souboru. MSB bit vektoru k začátku souboru. Tato reprezentace je opačná oproti celočíselným typům. Pro vzestupnou deklaraci vektoru (n to 0) je pořadí bitů opačné.

Dále je před každým vektorem v souboru obsažena čtyřbytová informace typu positive ve formátu Intel o jeho šířce. Z čtyřbytové povahy čísla typu positive je zřejmé, že vektor může být maximálně 65535 bitů široký.

Chceme-li soubor obsahující datový proud vektorů zpracovat ve vyšším programovacím jazyce (C, C++ apod.), je nutné nejdříve z prvních čtyř bytů zjistit šíři vektoru, dále načíst odpovídající datovou část vektoru, pak opět šíři vektoru, ..., a takto postupovat až ke konci souboru. V souborech lze použít i jiné datové typy (např. datové typy string – znakový řetězec, character atd.) než výše zmíněné. Vzhledem k omezenému rozsahu článku jejich popis na stránkách časopisu není možný. Nejlépe asi v [2], příp. [3].

Literatura

[1] Online Binary-Decimal Converter – http://www.binaryconvert.com

[2] Číslicové systémy a jazyk VHDL, Pinkner, Poupa, BEN 2006

[3] Jazyk VHDL, Douša, Skriptum ČVUT 2003