Laboratorium 10 Temat: Zaawansowane jednostki testowe. Operacje na plikach. Funkcje. 1. W języku VHDL zdefiniowano mechanizm odczytywania i zapisywania danych z i do plików. Pliki te mogą być wykorzystywane do gromadzenia danych testowych lub do zapamiętywania wyników procesu symulacji w celu ich dalszej analizy. Przydatne funkcje umieszczone są w pakiecie textio biblioteki STD i pakiecie std_logic_textio biblioteki IEEE. 2. Odczyt z pliku. Aby odczytać dane testowe z pliku naleŝy zdefiniować następujące obiekty: a) uchwyt do pliku (ang. handle): file in_file : text is in "plik_we.txt" co oznacza: obiekt file, in_file - uchwyt do wejściowego (is in) pliku tekstowego (:text) o nazwie plik_we.txt b) linię: variable in_line : line; - zmienna in_line typu line. Odczyt z pliku następuje dwuetapowo: etap1: odczyt z pliku do linii readline(in_file,in_line); etap2: odczyt z linii do std_logic_vector read(in_line, signal); lub hread(in_line, signal); róŝnica pomiędzy read, a hread polega na tym, Ŝe hread odczytuje dane w notacji hexadecymalnej (wartość 1 w tym przypadku zostanie zapisana do std_logic_vector jako 0001 a F jako 1111 ) 3. Zapis do pliku. Przy zapisywaniu do pliku podobnie jak przy odczycie naleŝy zdefiniować uchwyt do pliku (tym razem wyjściowego - is out) oraz linię (zmienną typu line). Zapis do pliku równieŝ odbywa się dwuetapowo, tzn: etap1: zapis do linii, write(out_line, signal); etap2: zapis z linii do pliku, writeline(out_file, out_line); W przypadku zapisu do pliku istnieje konieczność konwersji typów. Do plików tekstowych powinny być zapisywane wartości typu character lub string, a nie std_logic czy std_logic_vector. W tym celu przed zapisaniem wartości sygnałów do linii poddaje je się konwersji typów. Wygodnie jest zdefiniować funkcje konwersji: funkcja conv_to_char (konwersja std_logic => character) : FUNCTION conv_to_char (sig: std_logic) RETURN character IS CASE sig IS END CASE; WHEN '1' WHEN '0' WHEN 'Z' END conv_to_char; => RETURN '1'; => RETURN '0'; => RETURN 'Z'; WHEN others => RETURN 'X';
funkcja conv_to_string (konwersja std_logic_vector => string) : FUNCTION conv_to_string (inp: std_logic_vector; length: integer) RETURN string IS VARIABLE s : string(1 TO length); FOR i IN 0 TO (length 1) LOOP s(length-i) := conv_to_char(inp(i)); END LOOP; RETURN s; END conv_to_string; 4. Przykładowa realizacja w języku VHDL a) pliki.vhd: library IEEE; use IEEE.std_logic_1164.all; entity pliki is port( a,b : in std_logic_vector(7 downto 0); x,z : out std_logic_vector(7 downto 0); clk : in std_logic; reset ); end pliki; : in std_logic architecture pliki_a of pliki is end pliki_a; signal c,d : std_logic_vector(7 downto 0); rejestr: process (reset,clk) if (reset = '0') then c <= (others => '0'); d <= (others => '0'); x <= (others => '0'); z <= (others => '0'); elsif (clk'event and clk='1') then c(7 downto 4) <= a (3 downto 0); c(3 downto 0) <= a (7 downto 4); x <= c; z <= d; end if; end process rejestr; d(7 downto 4) <= b (3 downto 0); d(3 downto 0) <= b (7 downto 4);
b) pliki_tb.vhd: library std, ieee; use ieee.std_logic_1164.all; use std.textio.all; use ieee.std_logic_textio.all; entity tb_pliki is end tb_pliki; architecture tb_pliki_a of tb_pliki is component pliki is port( a,b : in std_logic_vector(7 downto 0); x,z : out std_logic_vector(7 downto 0); clk : in std_logic; reset : in std_logic ); end component; -------- definicja stałych czasowych --------- constant period : time := 20 ns; constant p10 : time := period/10; constant edge : time := period-p10; -------- definicja sygnałów --------- signal s_a, s_b, s_x, s_z : std_logic_vector(7 downto 0); signal s_clk signal s_reset signal strobe -------- mapowanie portów --------- lut: pliki port map( s_a, s_b, s_x, s_z, s_clk, s_reset); -------- taktowanie układu proces: zegar --------- zegar :process s_clk <= '0'; wait for period/2; s_clk <= '1'; wait for period/2; end process zegar; -------- wczytywnie danych z pliku proces: input --------- input: process file infile :text is in "wejscie"; variable line_in :line; variable bytes :std_logic_vector(15 downto 0); s_reset <= '0'; s_a <= "00000000"; s_b <= "00000000"; wait for 1.5 * period; s_reset <= '1'; wait for 1.5 * period; wait until (s_clk'event and s_clk='0'); wait for p10; while not (endfile(infile)) loop readline(infile, line_in); hread(line_in, bytes); s_a <= bytes(15 downto 8); s_b <= bytes(7 downto 0); wait for 3*period; end loop; assert false severity failure; end process input;
-------- opóźnienie sygnału strobującego --------- strobe <= TRANSPORT s_clk AFTER edge; -------- zapis danych do pliku proces: output -------- output: PROCESS (strobe) variable str :string(1 to 40); variable lineout :line; variable init_file :std_logic := '1'; file outfile :text is out "wyjscie"; -------- funkcja konwersji: std_logic => character -------- FUNCTION conv_to_char (sig: std_logic) RETURN character IS CASE sig IS WHEN '1' => return '1'; WHEN '0' => return '0'; WHEN 'Z' => return 'Z'; WHEN others => return 'X'; END CASE; END conv_to_char; -------- funkcja konwersji: std_logic_vector => string -------- FUNCTION conv_to_string (inp: std_logic_vector; length: integer) RETURN string IS VARIABLE s : string(1 TO length); FOR i IN 0 TO (length-1) LOOP s(length-i) := conv_to_char(inp(i)); END LOOP; RETURN s; END conv_to_string; ------------------------------------- -------- nagłówek pliku wyjściowego (podział kolumn) -------- IF init_file = '1' THEN str:="clk "; str:=" reset "; str:=" a "; str:=" b "; str:=" x "; str:=" z "; str:=" "; init_file := '0'; END IF; -------- zapis danych do pliku wyjsciowego wyjscie -------- IF (strobe'event AND strobe='0') THEN str := (others => ' '); str(1) := conv_to_char(s_clk); str(2) := ' '; str(3) := conv_to_char(s_reset); str(4) := ' '; str(5 to 12) := conv_to_string(s_a,8); str(13) := ' '; str(14 to 21) := conv_to_string(s_b,8); str(22) := ' '; str(23 to 30) := conv_to_string(s_x,8); str(31) := ' '; str(32 to 39) := conv_to_string(s_z,8); str(40) := ' '; write(lineout,str); writeline(outfile,lineout); END IF; END PROCESS output; END tb_pliki_a;
3. Zadania do realizacji: a) Przeprowadzić symulację przykładowego kodu z wykorzystaniem plików (plik wejsciowy powinien znajdować się w katalogu głównym projektu, tam równieŝ znajdzie się plik wyjsciowy po przeprowadzeniu symulacji). b) Przeprowadzić symulację z wykorzystaniem plików dla układu z Laboratorium nr 2 (sumator 4-bitowy). Rew. 2007, P.M. Szecówka