Com treballar amb VHDL usant programari lliure

Les classes de enginyeria electrònica solen dictar usant eines popietarias, Així que sempre pas algunes hores buscant fer els meus treballs amb programari lliure. Per aquesta raó, he decidit compartir la següent Guia.

Aquest és una aportació de pandacris, convertint-se així en un dels guanyadors de la nostra competència setmanal: «Vaig compartir el que saps sobre Linux«. Felicitacions!

Instal·lant el necessari

Per a compilar i simular els nostres programes farem servir GHDL un compilador lliure basat en GCC. Per veure els resultats de la simulació, farem servir GTKWAVE. Com a editor recomano Geany ja que reconeix gairebé tots els llenguatges de programació.

sue apt-get install ghdl gtkwave geany

Un projecte d'exemple

Utilitzem com a exemple aquest comparador:

Abans de crear un projecte, comencem creant una carpeta on s'allotjaran tots els arxius. En aquest cas, / home / usuari / VHDL. Allà guardarem el codi font dels nostres programes amb extensió .vhd.

Després, vam escriure el nostre programa usant Geany, com es veu en la captura de pantalla.

El guardem com compara.vhd.

No oblideu desar el programa amb l'extensió .vhd perquè Geany reconegui el format i acoloreixi les paraules reservades.

Ara ens caldrà crear els senyals per a la simulació. Per a això, crearem un component que faci servir el bloc anterior i li especificarem els senyals.

les línies A <= «0011» after 0 ns, »0111" after 5 ns, «0111» after 10 ns; són les que configuren els senyals d'entrada en el temps

Guardem els arxius a / home / usuari / VHDL. Després, vam obrir un terminal ja compilar:

ghdl -a compara.vhd

Si no hi ha missatges d'error, la compilació és reeixida.

Ara compilem el "component"

ghdl -a compara_tb.vhd

Si no hi ha errors, vam crear l'executable:

ghdl -i compara_tb

Finalment, resta realitzar la simulació i guardar els resultats en el amb nom "compara.vcd"

ghdl -r compara_tb --vcd = compara.vcd

Per poder veure els resultats farem servir gtkwave:

gtkwave compara.vcd

Un cop obert, assenyalar amb la tecla Ctrl i el ratolí els senyals que ens interessen i pressionar inserir. Després, doble clic als vectors per veure els senyals separades. Després, clic dret en els senyals per triar el format (binari, hex, octal, decimal, etc.)

En cas que sigui necessari, el botó amb forma de lupa amb un quadrat al centre ajusta la gràfica a la pantalla.

ALU: arithmetic and logic unit

Bé, ara fem una mica més interessant: un ALU (aritmethic and logic unit). Serà una unitat lògica, una unitat aritmètica i un multiplexor.

Unitat lògica (LoU.vhdl)

     LIBRARY ieee; USE IEEE.STD_LOGIC_1164.all; USE IEEE.NUMERIC_STD.all;

ENTITY lou IS
PORT (OP1: IN std_logic_vector (7 downto 0);
OP2: IN std_logic_vector (7 downto 0);
procés: IN std_logic_vector (3 downto 0);
res: OUT std_logic_vector (7 downto 0));
END lou;

ARCHITECTURE synth2 OF lou IS
SIGNAL a, b: UNSIGNED (op1'range);
SIGNAL c: UNSIGNED (res'range);
Començar
PROCESS (a, b, procés)
Començar
CASE procés IS
WHEN «0000» => c <= RESIZE ((not a), c'length);
WHEN «0001» => c <= RESIZE ((a and b), c'length);
WHEN «0010» => c <= RESIZE ((a or b), c'length);

WHEN «0011» => c <= RESIZE ((a xor b), c'length);
WHEN «0100» => c <= RESIZE ((a nand b), c'length);
WHEN «0101» => c <= RESIZE ((a nor b), c'length);
WHEN Others => null;
END CASE;
END PROCESS;

a <= UNSIGNED (OP1);
b <= UNSIGNED (OP2);
res <= std_logic_vector (c);

END synth2;

Unitat aritmetica (ArU.vhd)

     LIBRARY ieee; USE IEEE.STD_LOGIC_1164.all; USE IEEE.NUMERIC_STD.all;

ENTITY aru IS
PORT (OP1: IN std_logic_vector (7 downto 0);
OP2: IN std_logic_vector (7 downto 0);
procés: IN std_logic_vector (3 downto 0);
res: OUT std_logic_vector (7 downto 0));
END aru;

ARCHITECTURE synth OF aru IS
SIGNAL a, b: UNSIGNED (op1'range);
SIGNAL c: UNSIGNED (res'range);
Començar
PROCESS (a, b, procés)
Començar
CASE procés IS
WHEN «0000» => c <= RESIZE ((a + b), c'length);
WHEN «0001» => c <= RESIZE ((a - b), c'length);
WHEN «0010» => c <= RESIZE ((a * b), c'length);

WHEN «0011» => c <= RESIZE ((a / b), c'length);
WHEN «0100» => c <= RESIZE ((a + «1»), c'length);
WHEN «0101» => c <= RESIZE ((b + «1»), c'length);
WHEN Others => null;
END CASE;
END PROCESS;

a <= UNSIGNED (OP1);
b <= UNSIGNED (OP2);
res <= std_logic_vector (c);

END synth;

Multiplexor (muxVector.vhd)

     LIBRARY ieee; USE IEEE.STD_LOGIC_1164.all; USE IEEE.NUMERIC_STD.all;

ENTITY muxVector IS
PORT (desdeARU: IN std_logic_vector (7 downto 0);
desdeLOU: IN std_logic_vector (7 downto 0);
switch: IN std_logic;
sortida: out std_logic_vector (7 downto 0));
END muxVector;

ARCHITECTURE canvi OF muxVector IS
Començar
with switch select
sortida <= desdeARU when '0', desdeLOU when others;
END canvi;

Component ALU (aluComponente.vhd)

     LIBRARY ieee; USE IEEE.STD_LOGIC_1164.all; USE IEEE.NUMERIC_STD.all;

ENTITY aluComponent IS
END al·luComponent;

ARCHITECTURE entrades_aluComponent OF aluComponent IS

COMPONENT aru
PORT (OP1: IN std_logic_vector (7 downto 0);
OP2: IN std_logic_vector (7 downto 0);
procés: IN std_logic_vector (3 downto 0);
res: OUT std_logic_vector (7 downto 0));
END COMPONENT;

COMPONENT lou
PORT (OP1: IN std_logic_vector (7 downto 0);
OP2: IN std_logic_vector (7 downto 0);
procés: IN std_logic_vector (3 downto 0);
res: OUT std_logic_vector (7 downto 0));
END COMPONENT;

COMPONENT muxVector
PORT (desdeARU: IN std_logic_vector (7 downto 0);
desdeLOU: IN std_logic_vector (7 downto 0);
switch: IN std_logic;
sortida: out std_logic_vector (7 downto 0));
END COMPONENT;

SIGNAL salidaARU: std_logic_vector (7 downto 0);
SIGNAL salidaLOU: std_logic_vector (7 downto 0);
signal Switch: std_logic;
signal procés: std_logic_vector (3 downto 0);
signal sortida: std_logic_vector (7 downto 0);
SIGNAL A: std_logic_vector (7 downto 0);
SIGNAL B: std_logic_vector (7 downto 0);

Començar
u0: aru PORT MAP (A, B, procés, salidaARU);
u1: lou PORT MAP (A, B, procés, salidaLOU);
u2: muxVector PORT MAP (salidaARU, salidaLOU, switch, sortida);

A <= «00000011» after 0 ns, »00000111" after 5 ns, «00000111» after 10 ns, «00001001» after 15 ns, «00000000» after 20 ns, «00000101» after 25 ns, «00001111» after 30 ns, «00000101» after 35 ns;
B <= «00000010» after 0 ns, »00000100" after 5 ns, «00000010» after 10 ns, «00000011» after 15 ns, «00000100» after 20 ns, «00000110» after 25 ns, «00001111» after 30 ns, «00000011» after 35 ns;
switch <= '1' after 0 ns, '0' after 5 ns, '1' after 10 ns, '0' after 15 ns, '1' after 20 ns, '0' after 25 ns, '1' after 30 ns, '0' after 35 ns, '1' after 40 ns;
procés <= «0000» after 0 ns, »0001" after 5 ns, «0010» after 10 ns, «0011» after 15 ns, «0100» after 20 ns, «0101» after 25 ns, «0110» after 30 ns;
END entrades_aluComponent;

Per no perdre temps compilant comandament per comandament mentre treballem en el programa, guardem en la mateixa carpeta un arxiu anomenat compilar.sh amb el següent contingut:

ghdl -a lou.vhd && ghdl -a aru.vhd && ghdl -a muxVector.vhd && ghdl -a aluComponente.vhd && ghdl -i aluComponente && ghdl -r aluComponente --vcd = aluComponente.vcd && gtkwave aluComponente.vcd

Obrir un terminal, entrar a la carpeta i executar l'script:

cd / home / usuari / VHDL sh compilar.sh

Si no hi ha errors s'obrirà gtkwave i podrem veure els senyals:

Aquestes eines m'han estat molt útils i més fàcils d'usar que les eines propietàries que fem servir a classe, les que sospitosament triguen massa per recopilar. Amb ghdl trigo més en canviar de finestra que en compilar.

Més info sobre VHDL

Per als nous en VHDL, aquí tenen un exemple bàsic d'un negador.

Un vídeo d'exemple:
http://www.youtube.com/watch?v=feVMXsyLSOU

Recordin que les últimes versions d'Ubuntu no tenen GHDL en els seus repositoris. Aquest pot descarregar-se per a Linux / Windows des de la pàgina de el projecte:
http://ghdl.free.fr/site/pmwiki.php?n=Main.Download


Deixa el teu comentari

La seva adreça de correu electrònic no es publicarà. Els camps obligatoris estan marcats amb *

*

*

  1. Responsable de les dades: Miguel Ángel Gatón
  2. Finalitat de les dades: Controlar l'SPAM, gestió de comentaris.
  3. Legitimació: El teu consentiment
  4. Comunicació de les dades: No es comunicaran les dades a tercers excepte per obligació legal.
  5. Emmagatzematge de les dades: Base de dades allotjada en Occentus Networks (UE)
  6. Drets: En qualsevol moment pots limitar, recuperar i esborrar la teva informació.

  1.   Nacho va dir

    Hi ha manera que GTKWave et doni el circuit de comportes a què representa?