Koncept pokročilého návrhu ve VHDL INP - cvičení 2
Ještě k problematice proměnná vs. signál
architecture behv of Cnt is begin process (CLK,RST,CE) variable value: std_logic_vector(3 downto 0); begin if (RST = '1') then value := (others => '0'); elsif (CLK'event and CLK = '1') then if CE='1' then value := value + 1; end if; end if; DOUT <= value; end process; end behv;
architecture Citac_arch of Citac is signal value: std_logic_vector(7 downto 0); begin process (CLK,RST,CE) begin if RST = '1' then value <= (others => '0'); elsif CLK'event and CLK = '1' then if CE='1' then value <= value + 1; end if; end if; DOUT <= value; end process; 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) 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 addr vygenerování nejvyšší adresy paměti Cnt Mem • Signál CLEAR v log. 1 způsobí nulování registru a čítače • CLK synchronizuje činnost sekvenčních val reg_out stop obvodů – čítače a registru • Po kompletním průchodu pamětí obsahuje Add Reg (a jeho výstup – signál SUM) součet 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 port ( 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 begin RES <= A + B; end behav_add;
CLEAR CLK
Cnt
Mem
A
B Add Res Reg SUM
Model čítače (Cnt)
entity Cnt is port ( 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 begin cnt_proc: process(CLK, CLEAR) variable cnt_val: std_logic_vector(2 downto 0); begin 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 CLEAR STOP <= '1'; CLK end if; end if; CNT <= cnt_val; end process; end behav_cnt;
CNT STOP
Mem
Add Reg SUM
Model paměti (Mem - ROM)
entity Mem is port ( ADDR: in std_logic_vector(2 downto 0); VAL: out std_logic_vector(7 downto 0) ); end Mem; architecture behav_mem of Mem is
begin mem: process(ADDR) begin 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 process; end behav_mem; CLK
Cnt
ADDR
Mem
VAL Add Reg SUM
Model registru (Reg)
entity Reg is port ( 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;
Cnt
begin reg: process(CLK, CLEAR) begin if CLEAR = '1' then DOUT <= X"00"; -- hexadecimalni zapis elsif CLK'event and CLK = '1' and W_PROTECT = '0' then DOUT <= DIN; end if; end process; CLEAR end behav_reg;
CLK
Mem W_PROTECT
architecture behav_reg of Reg is
Add DIN Reg DOUT SUM
entity Acc is port ( 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 port ( 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;
Acc strukturně signal signal signal signal signal
addr: std_logic_vector(2 downto 0); val: std_logic_vector(7 downto 0); add_out: std_logic_vector(7 downto 0); reg_out: std_logic_vector(7 downto 0); stop: std_logic;
begin add_inst: mem_inst: cnt_inst: reg_inst:
Add Mem Cnt Reg
port port port port
map(A => map(ADDR map(CLK, map(CLK,
val, B => reg_out, RES => add_out); => addr, VAL => val); CLEAR, addr, stop); CLEAR, stop, add_out, reg_out);
SUM <= reg_out; component Cnt is port ( CLK: in std_logic; CLEAR: in std_logic; CNT: out std_logic_vector(2 downto 0); STOP: out std_logic ); end component;
end behav_acc;
addr
stop
component Mem is port ( ADDR: in std_logic_vector(2 downto 0); VAL: out std_logic_vector(7 downto 0) ); end component; component Reg is port ( 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;
Cnt
Mem val
reg_out
Add add_out CLEAR CLK
Reg SUM
Acc behaviorálně
entity Acc is port ( CLK: in std_logic; CLEAR: in std_logic; SUM: out std_logic_vector(7 downto 0) ); end Acc;
with addr select val <= "00000001" "00000010" "00000011" "00000111" "00001111" "00011111" "00111111" "01111111" "00000000"
when when when when when when when when when
"000", "001", "010", "011", "100", "101", "110", "111", others;
add_out <= reg_out + val; architecture behav_acc of Acc is SUM <= reg_out; signal signal signal signal signal
addr: std_logic_vector(2 downto 0); val: std_logic_vector(7 downto 0); add_out: std_logic_vector(7 downto 0); reg_out: std_logic_vector(7 downto 0); stop: std_logic;
end behav_acc;
Cnt
begin cnt: process(CLK, CLEAR) begin 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'; end if; end if; end process;
addr
stop
Mem val
reg_out
Add add_out CLEAR CLK
reg: process(CLK, CLEAR) begin if CLEAR = '1' then reg_out <= X"00"; -- hexadecimalni zapis elsif clk'event and clk = '1' and stop = '0' then reg_out <= add_out; end if; end process;
Reg SUM
library IEEE; use IEEE.std_logic_1164.all;
Test benche
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;
příklad posuvného registru z 2. cvičení
architecture behv of SReg8 is
8 DIN CLK RESET LOAD SHIFT
begin sreg: process(CLK, RESET, SHIFT) variable value: std_logic_vector(7 downto 0); begin 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); end if; end if; DOUT <= value(0); end process; end behv;
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; architecture behv of Shifter_tb is constant period: time := 10 ns; signal signal signal signal
clk: std_logic := '0'; reset, load, shift: std_logic; din: std_logic_vector(7 downto 0); 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;
begin uut: Shifter port map(clk, reset, load, shift, din, dout); clk <= not clk after period / 2; test: process begin reset <= '1'; load <= '0'; shift <= '0'; din <= "11001011"; wait until clk'event reset <= '0'; load <= '1'; wait until clk'event load <= '0'; wait until clk'event wait until clk'event wait until clk'event wait until clk'event shift <= '1'; wait; end process; end behv;
and clk = '1';
and clk = '1'; and and and and
clk clk clk clk
= = = =
'1'; '1'; '1'; '1';
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
Output Logic
Outputs
• Mealyho automat
• Výstup závisí na stavu a vstupu
Inputs
Next State Logic
Current St. Register
Příklad FSM: Handshake
komunikace mezi zařízeními formou vztahu dotaz-odpověď
entity HANDSHAKE_FSM is port ( 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;
Příklad FSM: Handshake Moorův model
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; begin -- Registr obsahujici aktualni stav proc_cstate : process (CLK, RST, next_state) begin if RST = '1' then cur_state <= s_idle; elsif CLK'event AND CLK='1' then cur_state <= next_state; end if; end process proc_cstate; -- Logika pro vypocet nasledujiciho stavu nstate_logic : process (cur_state, RQ, DRDY) begin 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; end if;
-- ----- stav WAIT ----when s_wait => if DRDY='1' then next_state <= s_data; else next_state <= s_wait; end if; -- ----- stav DATA ----when s_data => if RQ='1' then next_state <= s_data; else next_state <= s_next; end if; -- ----- 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) begin 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) begin case cur_state is when S1 => if inputs = ... then outputs <= ...; elsif inputs = ... then outputs <= ...; . . . else outputs <= ...; end if; when S2 => if inputs = ... end if; . . . when Sn => ... when others => null; end case; end process output_logic;