Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti Praktika návrhu číslicových obvodů Dr.-Ing. Martin Novotný Katedra číslicového návrhu Fakulta informačních technologií ČVUT v Praze Miloš Bečvář, Martin Daněk, Jan Schmidt, Martin Novotný, 2006-2011 1
Plovoucí řádová čárka výpočet filtru: definice filtru TEST_PROCEDURE: process variable XN_1,XN_2: real := 0.0; variable YN_1,YN_2: real := 0.0; procedure FILTER(XN: in real; YN: out real) is variable Y: real; begin -- vypocti dalsi hodnotu Y = A(0)*XN + A(1)*XN_1 + A(2)*XN_2 + B(1)*YN_1 + B(2)*YN_2; -- posun vnitrni stav filtru XN_2:=XN_1; XN_1:=XN; YN_2:=YN_1; YN_1:=Y; -- vrat vysledek YN:=Y; end filter; 2
Plovoucí řádová čárka výpočet filtru: použití (2) variable Y : real; real; begin begin -- -- vypocti odezvu na na impuls FILTER (1.0, (1.0, Y); Y); for for I in in 1 to to 99 99 loop loop FILTER (0.0, (0.0, y); y); end end loop; loop; end end process TEST_PROCEDURE; Poznámky: Procedura nemůže uchovávat hodnoty proměnných mezi dvěma běhy ani způsobovat vedlejší efekty, např. zápisem do globálních proměnných. Výjimkou je případ, kdy je procedura lokálně deklarována uvnitř procesu, pak může přistupovat k proměnným deklarovaným uvnitř procesu. 3
Spojové seznamy implementace paměti Process subtype BYTE BYTE is is std_logic_vector(7 downto 0); 0); type type REGION_TYP is is array(0 to to 31) 31) of of BYTE; BYTE; type type LIST_EL_TYPE; type type LIST_EL_PTR is is access LIST_EL_TYPE; type type LIST_EL_TYPE is is record BASE_ADDR : natural; REGION : REGION_TYP; NEXT_REGION : LIST_EL_PTR; end end record; variable HEAD HEAD : LIST_EL_PTR; begin begin 4
Spojové seznamy implementace paměti (2) procedure GET_REGION (addr: in natural; here: out list_el_ptr) Is variable element: list_el_ptr; Begin element := head; -- jsme na konci seznamu? while (element /= null) loop -- ma tento prvek seznamu hledanou adresu? if (element.base_addr <= addr and addr < element.base_addr + element.region'length) then here := element; return; end if; element := element.next_region; end loop; 5
Spojové seznamy implementace paměti (3) Element := new list_el_typ; element.base_addr := addr / element.region'length; element.next_region := head; head := element; here := element; End get_region; Procedure lookup (addr: in integer; value: out byte) is variable element: list_el_ptr; Begin get_region (addr,element); value:= element.region(addr-element.base_addr); End lookup; 6
Spojové seznamy implementace paměti (4) Procedure set set (addr: in in integer; value: in in byte) byte) is is variable element: list_el_ptr; Begin Begin get_region (addr,element); element.region (addr-element.base_addr):= value; End End set; set; variable val: val: byte; byte; Begin Begin set(10000,"01011100"); lookup(10000,val); assert val="01011100"; End End process; 7
Spojové seznamy implementace paměti (5) Poznámka: Pro implementaci komplexních modelů reálných pamětí ROM, SRAM, FLASH, DRAM, VRAM použijte knihovnu std_developerskit developerskit od firmy ModelTech (viz web). 8
Fork / Join Synchronizace vláken výpočtu. Ve VHDL není tento konstrukt implicitně definován: Package fork_join is is Type Type join_ctl_typ is is (join,fork,run); Type Type branches_typ is is array array (integer range range <>) <>) of of join_ctl_typ; Function join_all (branches: branches_typ) return join_ctl_typ; Function join_one (branches: branches_typ) return join_ctl_typ; Subtype fork_join_all is is join_all join_ctl_typ; Subtype fork_join_one is is join_one join_ctl_typ; End End fork_join; 9
Fork / Join (2) Package body fork_join is Function join_all(branches: branches_typ) return join_ctl_typ is Begin for I in branches'range loop if branches(i) = fork then return fork; end if; if branches(i) = run then return run; end if; end loop; return join; End join_all; 10
Fork / Join (3) Function join_one (branches: branches_typ) return join_ctl_typ is is Begin Begin for for I in in branches'range loop loop if if branches(i) = fork fork then then return fork; fork; end end if; if; if if branches(i) = join join then then return join; join; end end if; if; end end loop; loop; return run; run; End End join_one; End End fork_join; 11
Fork / Join (4) Use work.fork_join.all; Architecture test of bench is Signal fk_jn1:fork_join_all; Begin process begiṉ - Fork fk_jn1 <= fork; wait until fk_jn1 = fork; fk_jn1 <= run; -- vetev 0 fk_jn1 <= join; -- join wait until fk_jn1 = join; end process; branch1: process begin begin -- -- Fork Fork fk_jn1 <= <= fork; fork; wait wait until until fk_jn1 = fork; fork; fk_jn1 <= <= run; run; -- -- vetev vetev 0 fk_jn1 <= <= join; join; -- -- join join wait; wait; end end process branch1; branch1: process begin begin -- -- Fork Fork fk_jn1 <= <= fork; fork; wait wait until until fk_jn1 = fork; fork; fk_jn1 <= <= run; run; -- -- vetev vetev 0 fk_jn1 <= <= join; join; -- -- join join wait; wait; end end process branch1; End End test; test; 12
Stabilita výstupů Procedure load_d0 (data: std_logic) is is Begin Begin rst rst <= <= '0'; '0'; d0 d0 <= <= data; data; d1 d1 <= <= not not data; data; sel sel <= <= '0'; '0'; wait wait until until clk clk = '1'; '1'; assert q'stable (cycle Td) Td) and and qb'stable (cycle Td); Td); wait wait for for Thold; rst rst <= <= 'X'; 'X'; d0 d0 <= <= 'X'; 'X'; d1 d1 <= <= 'X'; 'X'; sel sel <= <= 'X'; 'X'; assert q = data data and and qb qb = not not data; data; wait wait for for cycle cycle Thold Thold Tsetup; End End load_d0; 13