VHDL9 – Variablen und Testbench Coding Style

Werbung
School of
Engineering
Themen:
Variablen
Architecture-Types
School of
Engineering
Variablen
Abstimmanlage: version-A
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY abstimm IS
PORT ( a,b,c : in std_logic;
y: out std_logic);
END abstimm;
ARCHITECTURE comb OF abstimm IS
BEGIN
y <= (a and b) or (a and c) or (b and c);
END comb;
School of
Engineering
Abstimmanlage: version-B
School of
Engineering
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY abstimm_whenelse IS
PORT ( a,b,c : in std_logic;
y: out std_logic);
END abstimm_whenelse;
ARCHITECTURE comb OF abstimm_whenelse IS
SIGNAL x : std_logic_vector (2 DOWNTO 0);
BEGIN
x <= a & b & c;
y <= '1' WHEN ((x="011") or (x="101") or (x="110") or (x="111")) ELSE
'0';
END comb;
Abstimmanlage: version-C
ARCHITECTURE rtl OF abstimm_case IS
BEGIN
comb_log : process(a,b,c)
variable x : std_logic_vector (2 DOWNTO 0);
BEGIN
x := a & b & c;
CASE x IS
WHEN "011" => y <= '1';
WHEN "101" => y <= '1';
WHEN "110" => y <= '1';
WHEN "111" => y <= '1';
WHEN OTHERS => y <= '0';
END CASE;
END PROCESS;
END rtl;
School of
Engineering
Variablen
School of
Engineering
Variablen kann man benutzen, um innerhalb eines Prozesses
oder eines Unterprogramms einen Wert temporär zu speichern
VARIABLE variablen_name : type [:= initialisierung];
Beispiel:
VARIABLE summe : std_logic_vector (2 downto 0) := “101“ ;
Zuweisungsoperator :=
Variablen
School of
Engineering
● Kann man nur in Prozessen oder Unterprogrammen benutzen.
● Werden deshalb zwischen den Zeilen „Prozess“ und „Begin“ definiert.
● Variablen müssen vor Gebrauch initialisiert werden.
● Sind Global nicht verfügbar (ausserhalb des Prozess)
● Will man Variablen ausserhalb eines Prozesses weiterbenutzen, muss
man Sie einem Signal zuweisen.
● Sind nach der Zuweisung sofort gültig, nicht erst beim Verlassen des
Prozesses.
● Können als Index oder temporärer Speicher innerhalb eines
Prozesses benutzt werden.
● Zuweisung durch :=
Variablen: weitere Beispiele
School of
Engineering
Extract from Schaltungsdesign mit VHDL, Lehmann, Wunder, Selz, S.153
ENTITY mult IS
PORT (a, b : IN integer := 0; y : OUT integer) ;
END mult ;
ARCHITECTURE number_one OF mult IS
BEGIN
PROCESS (a,b) -- Aktivierung durch Ereignisse auf a oder b
VARIABLE v1, v2 : integer := 0 ;
BEGIN
v1 := 3 * a + 7 * b ; -- sequent. Variablenzuweisung
v2 := a * b + 5 * v1 ; -- sequent. Variablenzuweisung
y <= v1 + v2 ; -- sequent. Signalzuweisung
END PROCESS ;
END number_one ;
Variablen: weitere Beispiele
School of
Engineering
Extract from lcddriver.vhd (used in GPS_Uhr project)
…
type CHAR_RAM_TYPE is array(0 to 79) of std_logic_vector(7 downto 0);
signal charRAM : CHAR_RAM_TYPE := (others=>x"00");
…
CharRAMWrite : process(clk)
variable add : integer range 0 to 79;
begin
if (clk'event and clk='1') then
if (wen='1') then
add := to_integer(unsigned(charNum));
charRAM(add) <= dIn;
end if;
end if;
end process;
…
Achtung: Eine Variable muss vor Gebrauch zugewiesen werden!
School of
Engineering
Variablen
exp_var: PROCESS (clk, reset)
variable correct_v : std_logic;
begin
IF reset = '1' then
a <= '0';
b <= '0';
ELSIF clk’event AND clk = 1 THEN
correct_v := c and d;
a <= e or correct_v;
b <= f or correct_v;
END IF;
END PROCESS exp_var;
School of
Engineering
Variable korrekt benutzt
correct_v~0
c
d
b~0
b~reg0
PRE
D
clk
f
Q
b
ENA
CLR
a~0
a~reg0
PRE
e
D
Q
ENA
CLR
reset
a
Falsche Benutzung einer Variablen (1)
School of
Engineering
exp_var: PROCESS (clk, reset)
variable incorrect_v : std_logic;
BEGIN
IF reset = '1' THEN
a <= '0';
b <= '0';
ELSIF clk'event AND clk='1' THEN
a <= e or incorrect_v;
b <= f or incorrect_v;
incorrect_v := c and d;
END IF;
END PROCESS exp_var;
Eine Variable muss vor Gebrauch zugewiesen werden!
School of
Engineering
Variable falsch benutzt
\exp_var:incorrect_v
incorrect_v~0
c
d
PRE
D
b~0
b~reg0
PRE
Q
D
Q
b
ENA
ENA
CLR
CLR
a~0
a~reg0
PRE
e
f
D
Q
ENA
CLR
reset
clk
a
Schlechtes Beispiel
School of
Engineering
Extract from lcddriver.vhd (used in GPS_Uhr project)
…
-- Tick Generation
subtype TICK_COUNTER_TYPE is integer range 0 to tickNum;
signal tick: std_logic;
…
TickGen : process(clk)
variable tickCounter : TICK_COUNTER_TYPE;
begin
Generiert Speicher, da Variable
if (clk'event and clk='1') then
vor Initialisierung gebraucht
if (tickCounter = 0) then
tickCounter := TICK_COUNTER_TYPE'high-1;
tick <= '1';
else
tickCounter := tickCounter - 1;
tick <= '0';
end if;
end if;
Für dieses Beispiel nimmt man besser ein Signal
end process;
School of
Engineering
Synthese Tick Counter
Add0
tickCounter~[2..0]
1' h1 -4' hD --
\TickGen:tickCounter[2..0]
SEL
A[3..0]
OUT[3..0]
tick~reg0
PRE
DATAA
3' h3 --
B[3..0]
Equal0
OUT0
D
Q
DATAB
PRE
A[2..0]
3' h0 --
OUT
D
Q
B[2..0]
ENA
ENA
ADDER
clk
MUX21
CLR
EQUAL
CLR
tick
School of
Engineering
Signale vs. Variablen
Signale
Variablen
Existieren global in der
gesamten Architektur
Nur lokal im Prozess lesbar
Werden am Ende des
Prozesses aktualisiert.
Werden immer sofort
aktualisiert
Werden zwischen „Architectur“
und „Begin“ deklarieret
Werden zwischen „Process“
und „Begin“ deklarieret
Zuweisung v <= ‘1‘
Zuweisung v := ‘1‘
Achtung: Eine Variable muss vor Gebrauch zugewiesen werden!
School of
Engineering
Architecture Types
- rtl
(register-transfer-logic: synthesisable)
- behav (behavioural: testbench )
- struct (structural: hierarchy)
Architecture examples: rtl
…extracts of counter.vhd Ueb5-Auf2…
architecture rtl of counter is
signal next_countL: unsigned(3 downto 0);
signal countL:
unsigned(3 downto 0);
begin
comb_increment: process (load,enable,data,countL)
begin
if (load = '1') then
next_countL <= unsigned(data);
elsif (enable = '1') then
next_countL <= countL + 1;
else
next_countL <= countL;
end if;
end process;
reg_increment: process (clk,reset) begin
if (reset = '1') then
countL <= "0000";
elsif(clk'event and clk = '1') then
countL <= next_countL;
end if;
end process;
count <= std_logic_vector(countL);
end rtl;
School of
Engineering
Architecture examples: behav
…extracts of testbench_wuerfel.vhd…
ARCHITECTURE behav OF testbench_wuerfel IS
COMPONENT wuerfel_ifelse
PORT ( Q2, Q1, Q0 : IN std_logic;
A, B, C, D : OUT std_logic );
END COMPONENT;
…
BEGIN
…
STIMULUS: PROCESS
BEGIN
tin <= "000" ; WAIT FOR 10 ns;
tin <= "001" ; WAIT FOR 10 ns;
ASSERT (tout_if = "0001") REPORT "expected tout_if = 0001 " SEVERITY error;
WAIT FOR 100 ns;
tin <= "010" ; WAIT FOR 10 ns;
ASSERT (tout_if = "1000") REPORT "expected tout_if = 1000 " SEVERITY error;
WAIT FOR 100 ns;
ASSERT false REPORT " --- ALL TESTS PASS ---" SEVERITY failure;
WAIT;
END PROCESS;
END behav;
School of
Engineering
Architecture examples: behav
…extracts of testbench_abstimm_case.vhd…
ARCHITECTURE behav OF testbench_abstimm_case IS
COMPONENT abstimm
PORT ( a,b,c : IN std_logic;
y : OUT std_logic );
END COMPONENT;
…
SIGNAL tin : std_logic_vector(2 DOWNTO 0);
SIGNAL tout : std_logic_vector(2 DOWNTO 0);
BEGIN
-- Block Instantiations
dut1: abstimm
PORT MAP(
a => tin(2),
b => tin(1),
c => tin(0),
y => tout(2));
…
School of
Engineering
Architecture examples: behav
School of
Engineering
…extracts of testbench_abstimm_case.vhd…
STIM_CHK: PROCESS
-- DECLARE PROCEDURE TO AVOID REPEATING TEST STATEMENTS
PROCEDURE single_test
(tin_test : IN std_logic_vector;
tout_test: IN std_logic) IS
BEGIN
tin <= tin_test;
WAIT FOR 10 ns;
ASSERT ((tout(2) = tout_test) AND (tout(1) = tout_test) AND (tout(0) = tout_test))
"test failed for 1 or more duts!" SEVERITY error;
WAIT FOR 40 ns;
END PROCEDURE single_test;
BEGIN
single_test("000",'0');
single_test("001",'0');
single_test("010",'0');
single_test("011",'1');
…
-- END SIMULATION
ASSERT false REPORT " --- ALL TESTS PASS ---" SEVERITY failure;
END PROCESS;
END behav;
REPORT
Architecture examples: struct
…extracts of top_max.vhd…
ARCHITECTURE struct OF top_max IS
--------------------------- COMPONENT DECLARATIONS
-------------------------COMPONENT count_updown
GENERIC(n
: natural;
ov_value : unsigned );
PORT (
clock
: in std_logic;
reset_n : in std_logic;
cntup : in std_logic;
count : out std_logic_vector(n-1 downto 0));
END COMPONENT;
COMPONENT sieben_seg_ctrl
PORT(…)
END COMPONENT;
--------------------------- SIGNAL & CONSTANT DECLARATIONS
-------------------------CONSTANT Low : std_logic := '0';
CONSTANT High : std_logic := '1';
CONSTANT breite : natural :=26;
CONSTANT ueberlauf : unsigned := TO_UNSIGNED(49999999,N);
SIGNAL m_count : std_logic_vector(N-1 DOWNTO 0);
School of
Engineering
Architecture examples: struct
…extracts of top_max.vhd…
…
BEGIN
--------------------------- DUT INSTANTIATIONS
-------------------------dut_count: count_updown
GENERIC MAP(
n
=> breite,
ov_value => ueberlauf)
PORT MAP(
clock
=> clock,
reset_n => reset_n,
cntup
=> ctrl,
count
=> m_count);
dut_sseg : sieben_seg_ctrl
PORT MAP(…)
END struct;
School of
Engineering
School of
Engineering
VHDL Fallen
School of
Engineering
VHDL Fallen
Sauber_so: process(s)
BEGIN
If s = '1' THEN x <= '1' ;
ELSE x <= '0';
END IF;
autsch: process(s)
BEGIN
If s = '1' THEN x <= '1' ;
END IF;
END PROCESS;
END PROCESS;
1
2
elegant: process(s)
BEGIN
x <= '0';
If s = '1' THEN x <= '1' ;
END IF;
END PROCESS;
3
25
School of
Engineering
VHDL Fallen
Process: autsch
S
S
X
>1
X
Process: sauber_so
1
2
Latch
Process: elegant
S
X
3
26
Herunterladen