si můžete stáhnou celý projekt, který v druhé a třetí části popisuji, včetně schematu zapojení vlastní součástky. Projekt se jmenuje vývojová deska a pro nedostatek času je nedokončený mám v planu ho někdy dokončit...
Popíšeme si tu jak vytvořit komplexní projekt. Tento projekt obsahuje dva moduly popisující funkci součástky a jeden modul který propojí vše v jeden funkční celek. Nejprve si popíšeme jak propojíme jednotlivé části a potom jednotlivé moduly.
Propojovací modul
-- by HaCeSOFT
--
-- Datum : 7.5.2001
--
--
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
Tady se definují jednotlivé PORTy vlastní součástky!
PORT (clk : IN STD_LOGIC;
reset : IN STD_LOGIC;
G : in std_logic_vector(3 downto 0);
S : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
Q : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
BCD : IN STD_LOGIC_VECTOR(3 DOWNTO 0));
END VYV_DESKA;
Po klíčovém slově ARCHITECTURE následuje definice komponentu, pomocí příkazu COMPONENT s jménem "scitat_multiplex". Následuje standardní popis PORTu, který používá modul "scitat_multiplex"!
COMPONENT scitat_multiplex
PORT (clk : in std_logic;
reset : in std_logic;
bcd1_in : in std_logic_vector(15 downto 0);
Q : out std_logic_vector(6 downto 0);
S : OUT std_logic_vector(3 downto 0));
END COMPONENT;
To samé jako předchozí výklad. Stým rozdílem že definice patří modulu "vstupni_modul1".
PORT (BCD : in std_logic_vector(3 downto 0);
bcd1_out : out std_logic_vector(15 downto 0);
G : in std_logic_vector(3 downto 0));
END COMPONENT;
Nadefinují se vnitřní signály. V našem příkladu se jedná o 16-ti bitovou sběrnici.
Doposud jsme si neřekly co to bude dělat až to zkompilujeme a nahrajeme do součástky.
Jedna se o čtyř místní segmentový LED display, řízený v multiplexním provozu.
Výstupní signál "S" (4 bity) určuje který LED segment se právě zobrazuje.
Výstup "Q" (7 bitů) jsou data která se zobrazují.
Výstup "Q" je zapojen tak že nejnižší byt je segment A a nejvyšší je segment G.
Desetina tečka tímto hardwarem není obsloužena!
Vstupní signál "RESET" (1 bit) je na nulování obvodu.
Na "clk" (1 bit) se připojí generátor periodických impulsu.
Na vstup "BCD" (4 bity) je přivedena informace v kódu BCD co se má na display zobrazit.
A řídicí vstupní signály "G" (4 bity) určuje na který segment se má zobrazit data co jsou na vstupu "BCD".
Tohle je jedna z prvních verzí tohoto display a proto má nějaké nedostatky. Jako
po "reset" signálu zůstane zachován obsah 16-ti bitového vnitřního registru a při adresaci konkrétního LED zobrazovače se informace ukáže na sousedním zobrazovači. Ve verzi kterou už mám hotovou jsou tyto nedostatky odstraněny.
Až bude hotov projekt na kterém pracuji tak to uveřejním opět na internetu s podrobnou dokumentaci. Jedna se o vývojovou desku pro obvody xilinx na bázi obvodu xilinx clpd s pic procesorem.
Tohle všechno se zatím definovalo za klíčovém slově "architekture". Následující příkaz "begin" ukončuje deklaraci.
Tady se propojují jednotlivé moduly v jeden celek. Jinými slovy následující kód je popis na nejnižší úrovni tzv. NETLIST. Můžeme si je opět pojmenovat dle. libosti. První je pojmenován jako "SCITAC". Za ním následuje k jaké COMPONENTe patří následuji NETLIST.
Na levé stravě je název signálu který je použit v modulu,
na pravé straně je jak se jmenuje při propojování modulů.
Za každém propojení je čárka a celá definice propojení je uzavřena v závorkách.
A nezapomeňte tradičně na konci středník!
Mě se to stává dost často a pak se divím co zas tem kompilér chce.
reset => reset,
bcd1_in => bcd1_x,
Q => Q,
S => S);
To samé jako předešlý výklad s názvem "Inst_vstupni_modul1" a patří "COMPONETe vstupni_modul1".
Inst_vstupni_modul1: vstupni_modul1 PORT MAP(
BCD => BCD,
bcd1_out => bcd1_x,
G => G);
END structural;
Modul s názvem "scitat_multiplex".
-- by HaCeSOFT
--
-- Datum : 7.5.2001
--
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Standardní definice "PORTu".
Port (clk : in std_logic;
reset : in std_logic;
bcd1_in : in std_logic_vector(15 downto 0);
Q : out std_logic_vector(6 downto 0);
S : out STD_LOGIC_VECTOR (3 downto 0));
end scitat_multiplex;
Standardní definice "architecture".
Máme tu dva vnitřní signály "S_bin" a "HEX". Všimnete si že nejsou uvedeny při definici "PORTu". Jsou jen pro tento "PROCESS".
signal HEX : std_logic_vector(3 downto 0);
begin
Citlivostní seznam je nastaven na "clk" a "reset".
Při úrovni "reset" = log. 0 nuluje vnitřní sčítač "S_bin", který určuje který segment se právě zobrazuje. "Reset" je nadřazen signálu "clk".
S_bin <= "00";
elsif clk = '1' and clk'event then
S_bin <= S_bin + 1;
Klíčovým slovem "CASE" se definují tabulky. Vstupní proměnná je uvedena hned za příkazem "CASE". Opět před příkazem "CASE" muže byt jak se má tabulka jmenovat. Je to jen pro lepší orientaci.
Výraz when "00" => S <= "0001" se dá přeložit asi takto.
Když (when) "S_bin" = "00" tak přesuň hodnotu "0001" na výstup "S".
when "00" => S <= "0001";
when "01" => S <= "0010";
when "10" => S <= "0100";
when "11" => S <= "1000";
Následující řádek je docela důležitý. Pokud ho nenapíšete tak vám
program WebPack bude pořád hlásit chybu!
A znamená když bude nějaká ostatní kombinace tak udělej. V našem případe "NULL".
Bude na výstupu samé nuly. Tabulka nemusí být definována jako úplná!
when others => NULL;
Tabulka se také musí ukončit.
end case;
case S_bin is
Tady vidíte že nemusíte používat jen konstanty ale i přiřazení. Takže na zaklade proměnné "S_bin" je na výstup "HEX" překopíruje část 16-ti bytového reg.
when "00" => HEX <= bcd1_in (3 downto 0);
when "01" => HEX <= bcd1_in (7 downto 4);
when "10" => HEX <= bcd1_in (11 downto 8);
when "11" => HEX <= bcd1_in (15 downto 12);
when others => NULL;
end case;
Následující tabulka je dekodér BCD kódu na segmentový display.
case HEX is -- dekoder BCD kodu na segmentovy kod.
when "0000" => Q <= "1000000"; --0
when "0001" => Q <= "1111001"; --1
when "0010" => Q <= "0100100"; --2
when "0011" => Q <= "0110000"; --3
when "0100" => Q <= "0011001"; --4
when "0101" => Q <= "0010010"; --5
when "0110" => Q <= "0000010"; --6
when "0111" => Q <= "1111000"; --7
when "1000" => Q <= "0000000"; --8
when "1001" => Q <= "0010000"; --9
when "1010" => Q <= "0001000"; --10
when "1011" => Q <= "0000011"; --11
when "1100" => Q <= "1000110"; --12
when "1101" => Q <= "0100001"; --13
when "1110" => Q <= "0000110"; --14
when "1111" => Q <= "0001110"; --15
when others => NULL;
end case;
end if;
end process;
end behavioral;
Doteďka jsme probíraly modul, který na základě periodického signálu "clk". Zobrazoval obsah vnitřního registru multiplexerového čtyř-místného LED display.
Modul s názvem "Vstupni_modul1"
Tento modul zajišťuje naplnění 16-ti bytového registru.
-- by HaCeSOFT
--
-- Datum : 7.5.2001
--
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Standardní definice "PORTu".
bcd1_out : out std_logic_vector(15 downto 0);
G : in std_logic_vector(3 downto 0));
end Vstupni_modul1;
Nejsou použity žádné vnitřní signály.
begin
Citlivostní seznam je nastaven na vstupní signál "G". Nejprve se přivedou potřebná data na vstup "BCD" a pak se pomocí "G" zapíšou do patřičného registru.
Ještě jsem opomenul že segmentový display 1 je uložen na bytech 0 za 3, druhy na 4 za 7, atd. Tento modul je napsán docela hnusně. Daleko lepší by bylo místo čtyř vstupu pro "G" použít, např. nějakou adresu v binárním kódu (dva vstupy) a pro zápis vstup např. s jménem "ENAGLE" (jeden byt). Celkem toto řešení má tri bity. Místo tohoto řešení kde vstup "G" má čtyři vstupy.
if G =
To je vše.
Na závěr bych měl ještě objasnit proč při zápisu BCD hodnotu do 16-ti bytového reg. na bity 0 za 3, který náleží prvnímu číslicovému zobrazovači se údaj zobrazí na druhem, atd.
To by mě také zajímalo. Ne, dělám si legraci.
Při použití příkazu "IF" nebo "CASE" se použije makrobuňka a uvnitř se nachází klopný obvod. To vychází z architektury xilinx cpld série 9500. A při přepisu z jednoho klopného obvodu na druhý klopný obvod se data objevy až za jeden takt.
Lze to obejít tak, že při "S_bin" = "00" by se měl zobrazovat první zobrazovač ale my místo toho zobrazíme čtvrtý.
Komentáře
Nebyly přidány žádné komentáře.