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) :
Projektowanie układów VLSI
© 2005 Copyright by Tomasz Fałat
FUNCTION
conv_to_char (sig: std_logic)
RETURN
character
IS
BEGIN
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 conv_to_string (konwersja std_logic_vector => string) :
4. Przykładowa realizacja w języku VHDL
a) pliki.vhd:
Projektowanie układów VLSI
© 2005 Copyright by Tomasz Fałat
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
:
in
std_logic
);
end
pliki;
architecture
pliki_a
of
pliki
is
signal
c,d : std_logic_vector(7
downto
0);
begin
rejestr:
process
(reset,clk)
begin
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);
d(7
downto
4) <= b (3
downto
0);
d(3
downto
0) <= b (7
downto
4);
x <= c;
z <= d;
end
if
;
end
process
rejestr;
end
pliki_a;
FUNCTION
conv_to_string (inp: std_logic_vector; length: integer)
RETURN
string
IS
VARIABLE
s : string(1
TO
length);
BEGIN
FOR
i
IN
0
TO
(length – 1)
LOOP
s(length-i) := conv_to_char(inp(i));
END
LOOP
;
RETURN
s;
END
conv_to_string;
b) pliki_tb.vhd:
Projektowanie układów VLSI
© 2005 Copyright by Tomasz Fałat
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
: std_logic;
signal
s_reset
: std_logic;
signal
strobe
: std_logic;
begin
-------- „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
begin
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);
begin
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;
Projektowanie układów VLSI
© 2005 Copyright by Tomasz Fałat
-------- 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
BEGIN
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);
BEGIN
FOR
i
IN
0
TO
(length-1)
LOOP
s(length-i) := conv_to_char(inp(i));
END
LOOP
;
RETURN
s;
END
conv_to_string;
-------------------------------------
BEGIN
-------- nagłówek pliku wyj
ś
ciowego (podział kolumn) --------
IF
init_file = '1'
THEN
str:="clk ";
write(lineout,str); writeline(outfile,lineout);
str:="| reset ";
write(lineout,str); writeline(outfile,lineout);
str:="| | a ";
write(lineout,str); writeline(outfile,lineout);
str:="| | | b ";
write(lineout,str); writeline(outfile,lineout);
str:="| | | | x ";
write(lineout,str); writeline(outfile,lineout);
str:="| | | | | z ";
write(lineout,str); writeline(outfile,lineout);
str:="| | | | | | ";
write(lineout,str); writeline(outfile,lineout);
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
Projektowanie układów VLSI
© 2005 Copyright by Tomasz Fałat