Koncept pokročilého návrhu ve VHDL INP - cvičení 2
architecture behv of Cnt is process (CLK,RST,CE) variable value: std_logic_vector(3 downto 0 if (RST = '1') then value := (others => '0' elsif (CLK'event and CLK = '1') then if CE='1' then value := value + 1; DOUT <= value; end behv; Ještě k problematice proměnná vs. signál architecture Citac_arch of Citac is signal value: std_logic_vector(7 downto 0 process (CLK,RST,CE) if RST = '1' then value <= (others => '0' elsif CLK'event and CLK = '1' then if CE='1' then value <= value + 1; DOUT <= value; end architecture Citac_arch;
Obvodová realizace algoritmů Specifikace algoritmu (slovní popis, diagram apod.) Dekompozice, identifikace funkčních bloků Blokové schéma, schéma zapojení, RTL Popis pomocí VHDL Syntéza obvodu (automatizováno)
Modelování komplexních obvodů Strukturní popis Využití konstrukce VHDL component Instance komponent a jejich propojení pomocí signálů (konstrukce port map) Komponenta jako ``black box Behaviorální popis Popis algoritmů funkčních bloků (procesy) Komunikace (propojení) procesů přes signály Kombinace předchozích Komponenty, instance komponent, procesy, signály
Příklad: iterační součet posloupnosti Čítač (Cnt) generuje adresy celého rozsahu paměti (Mem) Hodnoty (val) z paměti jsou sčítány sčítačkou (Add) a mezivýsledek uchován v registru (Reg) Signál stop, zabraňující přepsání finálního výsledku v Reg, je aktivován po vygenerování nejvyšší adresy paměti addr Cnt Signál CLEAR v log. 1 způsobí nulování Mem registru a čítače CLK synchronizuje činnost sekvenčních obvodů čítače a registru Po kompletním průchodu pamětí obsahuje Reg (a jeho výstup signál SUM) součet stop val Add reg_out všech jejích hodnot add_out CLEAR CLK Reg SUM
Model sčítačky (Add) library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; use IEEE.std_logic_arith.all; entity Add is A: in std_logic_vector(7 downto 0 B: in std_logic_vector(7 downto 0 RES: out std_logic_vector(7 downto 0) end Add; architecture behav_add of Add is RES <= A + B; end behav_add; CLEAR CLK Cnt Mem A B Add Res Reg SUM
Model čítače (Cnt) entity Cnt is CLK: in std_logic; CLEAR: in std_logic; CNT: out std_logic_vector(2 downto 0 STOP: out std_logic end Cnt; architecture behav_cnt of Cnt is cnt_proc: process(clk, CLEAR) variable cnt_val: std_logic_vector(2 downto 0 STOP <= '0'; if CLEAR = '1' then cnt_val := "000"; elsif CLK'event and CLK = '1' then if cnt_val < "111" then cnt_val := cnt_val + 1; else STOP <= '1'; CLEAR CLK CNT <= cnt_val; end behav_cnt; Cnt CNT STOP Mem Add Reg SUM
Model paměti (Mem - ROM) entity Mem is ADDR: in std_logic_vector(2 downto 0 VAL: out std_logic_vector(7 downto 0) end Mem; architecture behav_mem of Mem is mem: process(addr) case ADDR is when "000" => VAL <= "00000001"; when "001" => VAL <= "00000010"; when "010" => VAL <= "00000011"; when "011" => VAL <= "00000111"; when "100" => VAL <= "00001111"; when "101" => VAL <= "00011111"; when "110" => VAL <= "00111111"; when "111" => VAL <= "01111111"; when others => VAL <= "00000000"; end case; CLEAR end behav_mem; CLK Cnt ADDR Mem VAL Add Reg SUM
Model registru (Reg) entity Reg is CLK: in std_logic; CLEAR: in std_logic; W_PROTECT: in std_logic; DIN: in std_logic_vector(7 downto 0 DOUT: out std_logic_vector(7 downto 0) end Reg; architecture behav_reg of Reg is Cnt Mem reg: process(clk, CLEAR) if CLEAR = '1' then DOUT <= X"00"; -- hexadecimalni zapis elsif CLK'event and CLK = '1' and W_PROTECT = '0' then DOUT <= DIN; CLEAR end behav_reg; CLK W_PROTECT Add DIN Reg DOUT SUM
entity Acc is CLK: in std_logic; CLEAR: in std_logic; SUM: out std_logic_vector(7 downto 0) end Acc; architecture behav_acc of Acc is component Add is A: in std_logic_vector(7 downto 0 B: in std_logic_vector(7 downto 0 RES: out std_logic_vector(7 downto 0) end component; component Cnt is CLK: in std_logic; CLEAR: in std_logic; CNT: out std_logic_vector(2 downto 0 STOP: out std_logic end component; component Mem is ADDR: in std_logic_vector(2 downto 0 VAL: out std_logic_vector(7 downto 0) end component; component Reg is CLK: in std_logic; CLEAR: in std_logic; W_PROTECT: in std_logic; DIN: in std_logic_vector(7 downto 0 DOUT: out std_logic_vector(7 downto 0) end component; signal addr: std_logic_vector(2 downto 0 signal val: std_logic_vector(7 downto 0 signal add_out: std_logic_vector(7 downto 0 signal reg_out: std_logic_vector(7 downto 0 signal stop: std_logic; add_inst: Add port map(a => val, B => reg_out, RES => add_out mem_inst: Mem port map(addr => addr, VAL => val cnt_inst: Cnt port map(clk, CLEAR, addr, stop reg_inst: Reg port map(clk, CLEAR, stop, add_out, reg_out SUM <= reg_out; end behav_acc; CLEAR CLK Acc strukturně Cnt addr stop Mem val Add Reg SUM reg_out add_out
Acc behaviorálně entity Acc is CLK: in std_logic; CLEAR: in std_logic; SUM: out std_logic_vector(7 downto 0) end Acc; architecture behav_acc of Acc is signal addr: std_logic_vector(2 downto 0 signal val: std_logic_vector(7 downto 0 signal add_out: std_logic_vector(7 downto 0 signal reg_out: std_logic_vector(7 downto 0 signal stop: std_logic; cnt: process(clk, CLEAR) if CLEAR = '1' then addr <= "000"; stop <= '0'; elsif clk'event and clk = '1' then if addr < "111" then addr <= addr + 1; stop <= '0'; else stop <= '1'; CLEAR CLK reg: process(clk, CLEAR) if CLEAR = '1' then reg_out <= X"00"; -- hexadecimalni zapis elsif clk'event and clk = '1' and stop = '0' then reg_out <= add_out; Cnt with addr select val <= "00000001" when "000", "00000010" when "001", "00000011" when "010", "00000111" when "011", "00001111" when "100", "00011111" when "101", "00111111" when "110", "01111111" when "111", "00000000" when others; add_out <= reg_out + val; SUM <= reg_out; end behav_acc; addr stop Mem val Add Reg SUM reg_out add_out
library IEEE; use IEEE.std_logic_1164.all; entity SReg8 is port( CLK: in std_logic; RESET: in std_logic; LOAD: in std_logic; SHIFT: in std_logic; DIN: in std_logic_vector(7 downto 0 DOUT: out std_logic end SReg8; architecture behv of SReg8 is sreg: process(clk, RESET, SHIFT) variable value: std_logic_vector(7 downto 0 if RESET = '1' then value := (others => '0' elsif LOAD = '1' then value := DIN; elsif CLK'event and CLK = '1' then if SHIFT = '1' then value := '0' & value(7 downto 1 DOUT <= value(0 end behv; Test benche příklad posuvného registru z 2. cvičení DIN CLK RESET LOAD SHIFT 8 SReg8 DOUT DIN (data in) vstupní data CLK (clock) hodinový vstup RST(reset) asynchronní reset DOUT (data output) výstupní bit (LSB)
Test bench + ukázka simulace SReg8 library IEEE; use IEEE.std_logic_1164.all; entity Shifter_tb is end Shifter_tb; uut: Shifter port map(clk, reset, load, shift, din, dout clk <= not clk after period / 2; architecture behv of Shifter_tb is constant period: time := 10 ns; signal clk: std_logic := '0'; signal reset, load, shift: std_logic; signal din: std_logic_vector(7 downto 0 signal dout: std_logic; component Shifter is port( CLK: in std_logic; RESET: in std_logic; LOAD: in std_logic; SHIFT: in std_logic; DIN: in std_logic_vector(7 downto 0 DOUT: out std_logic end component; test: process reset <= '1'; load <= '0'; shift <= '0'; din <= "11001011"; wait until clk'event and clk = '1'; reset <= '0'; load <= '1'; wait until clk'event and clk = '1'; load <= '0'; wait until clk'event and clk = '1'; wait until clk'event and clk = '1'; wait until clk'event and clk = '1'; wait until clk'event and clk = '1'; shift <= '1'; wait; end behv;
Konečné stavové automaty (FSM) Moorův automat Výstup závisí pouze na stavu Inputs Next State Logic Current St. Register Output Logic Outputs Mealyho automat Výstup závisí na stavu a vstupu Inputs Next State Logic Current St. Register Output Logic Outputs
Příklad FSM: Handshake komunikace mezi zařízeními formou vztahu dotaz-odpověď
entity HANDSHAKE_FSM is CLK : in std_logic; RST : in std_logic; -- Handshake rozhrani RQ : in std_logic; ACK : out std_logic; -- Datove rozhrani DRDY : in std_logic; DNEXT : out std_logic end HANDSHAKE_FSM; architecture behavioral of HANDSHAKE_FSM is -- Signaly reprezentujici stav type tstate is ( s_idle, s_wait, s_data, s_next signal cur_state, next_state : tstate; -- Registr obsahujici aktualni stav proc_cstate : process (CLK, RST, next_state) if RST = '1' then cur_state <= s_idle; elsif CLK'event AND CLK='1' then cur_state <= next_state; end process proc_cstate; -- Logika pro vypocet nasledujiciho stavu nstate_logic : process (cur_state, RQ, DRDY) next_state <= s_idle; case cur_state is -- ----- stav IDLE ----- when s_idle => if RQ='1' then next_state <= s_wait; else next_state <= s_idle; Příklad FSM: Handshake Moorův model -- ----- stav WAIT ----- when s_wait => if DRDY='1' then next_state <= s_data; else next_state <= s_wait; -- ----- stav DATA ----- when s_data => if RQ='1' then next_state <= s_data; else next_state <= s_next; -- ----- stav NEXT ----- when s_next => next_state <= s_idle; when others => null; end case; end process nstate_logic; -- Logika pro vypocet vystupnich hodnot output_logic : process (cur_state) DNEXT <= '0'; ACK <= '0'; case cur_state is when s_data => ACK <= '1'; when s_next => DNEXT <= '1'; when others => null; end case; end process output_logic; end behavioral;
Princip Mealyho modelu ve VHDL (pouze obecně) -- Logika pro vypocet vystupnich hodnot output_logic : process (cur_state, inputs) case cur_state is when S1 => if inputs =... then outputs <=...; elsif inputs =... then outputs <=...;... else outputs <=...; when S2 => if inputs =...... when Sn =>... when others => null; end case; end process output_logic;