Kodutöö #1 - simuleerimine

Matriklinumber: 999999-le vastava funktsioonide süsteemi tõeväärtus-tabel oleks järgmine:

0000 1-00
0001 01-0
0010 11-1
0011 0-01
0100 1110
0101 1010
0110 -111
0111 01-0
1000 0011
1001 -10-
1010 -0-1
1011 1001
1100 11-0
1101 0-10
1110 -000
1111 1011

Seda tabelit kirjeldav VHDL-kood oleks järgmine (vt. ka VHDL faili):

library IEEE; use IEEE.std_logic_1164.all;
entity f_system is
  port ( x1, x2, x3, x4: in std_logic;
         y1, y2, y3, y4: out std_logic );
end entity f_system;

library IEEE; use IEEE.std_logic_1164.all;
architecture tabel of f_system is
begin
  process (x1, x2, x3, x4)
    variable in_word, out_word: std_logic_vector (3 downto 0);
  begin
    in_word := x1 & x2 & x3 & x4;
    case  in_word  is
      when "0000" => out_word := "1-00";
      when "0001" => out_word := "01-0";
      when "0010" => out_word := "11-1";
      when "0011" => out_word := "0-01";
      when "0100" => out_word := "1110";
      when "0101" => out_word := "1010";
      when "0110" => out_word := "-111";
      when "0111" => out_word := "01-0";
      when "1000" => out_word := "0011";
      when "1001" => out_word := "-10-";
      when "1010" => out_word := "-0-1";
      when "1011" => out_word := "1001";
      when "1100" => out_word := "11-0";
      when "1101" => out_word := "0-10";
      when "1110" => out_word := "-000";
      when "1111" => out_word := "1011";
      when others => out_word := "----";
    end case;
    y1 <= out_word(3);    y2 <= out_word(2);
    y3 <= out_word(1);    y4 <= out_word(0);
  end process;
end architecture tabel;

9-väärtuseline IEEE loogika (std_logic) on kasutusel määramatuste pärast, muidu võiks kasutada lihtsalt tüüpi bit (vrdl. varasema ja mitte nii põhjaliku simuleerimisega näidislahenduse koodiga).

Tespingi VHDL-kood oleks järgmine (vt. ka VHDL faili):

library IEEE; use IEEE.std_logic_1164.all;
entity test is
end entity test;

library IEEE; use IEEE.std_logic_1164.all;
architecture bench of test is
  signal x1, x2, x3, x4: std_logic;
  signal y1, y2, y3, y4: std_logic;
  component f_system
    port ( x1, x2, x3, x4: in std_logic;
           y1, y2, y3, y4: out std_logic );
  end component;
begin
  -- Input signaals (after every 10 ns)
  x1 <= '0' after 0 ns, '1' after 80 ns, '0' after 160 ns;
  x2 <= '0' after 0 ns, '1' after 40 ns, '0' after 80 ns, '1' after 120 ns;
  x3 <= '0' after 0 ns, '1' after 20 ns, '0' after 40 ns, '1' after 60 ns,
        '0' after 80 ns, '1' after 100 ns, '0' after 120 ns, '1' after 140 ns;
  x4 <= '0' after 0 ns, '1' after 10 ns, '0' after 20 ns, '1' after 30 ns,
        '0' after 40 ns, '1' after 50 ns, '0' after 60 ns, '1' after 70 ns,
        '0' after 80 ns, '1' after 90 ns, '0' after 100 ns, '1' after 110 ns,
        '0' after 120 ns, '1' after 130 ns, '0' after 140 ns, '1' after 150 ns;

  -- System of Boolean functions
  U1: f_system port map (x1, x2, x3, x4, y1, y2, y3, y4);
end architecture bench;

Kõige lihtsam ModelSim'i kasutamise juhend oleks alljärgnev (keerukam juhend on siin):
käsk "cad" abil valida Mentor Graphics,
käsk "vsim" paneb simulaatori tööle.
Simulaatori töötades "File->New->Library..." abil luua teek "work" (kui pole varem loodud),
"Compile->Compile..." abil kompileerida nii funktsioonide süsteem kui ka testpink.
"Simulate->Start Simulation..." alt valida "work" seest "test" (veenduda, et "Enable optimization" oleks lubatud).
Aktiveerige alam-aken "Objects" ja "Add->To Wave->Signal in Design" lisab kõik signaalid lainekuju aknasse.
Simulaatori käsureal "run -all" teostab simuleerimise.
Aktiveerige alam-aken "Wave" ja menüüst "Wave->Zoom->Zoom Full" täidab akna ühtlaselt tulemustega.

Võrrelge tulemusi lähteülesandega.

tabel


Korrake seda sama (kompileerimine & simuleerimine) espresso tulemusest saadud funktsioonide süsteemiga (vt. ka VHDL faili):

library IEEE; use IEEE.std_logic_1164.all;
entity f_system is
  port ( x1, x2, x3, x4: in std_logic;
         y1, y2, y3, y4: out std_logic );
end entity f_system;

library IEEE; use IEEE.std_logic_1164.all;
architecture espresso of f_system is
begin
  y1 <= ((not x1) and x2 and (not x3) and x4) or
        (x2 and (not x3) and (not x4)) or
        ((not x1) and (not x4)) or (x1 and x3);
  y2 <= not( ((not x1) and x2 and (not x3) and x4) or
             (x1 and (not x2) and (not x4)) or (x1 and x3) );
  y3 <= (x2 and (not x3) and (not x4)) or (x2 and x4) or
        ((not x1) and x3 and (not x4)) or (x1 and (not x2) and (not x4));
  y4 <= (x1 and x3 and x4) or ((not x2) and x3) or
        ((not x1) and x3 and (not x4)) or (x1 and (not x2) and (not x4));
end architecture espresso; 

Võrrelge tulemusi lähteülesandega (simulatsiooniga).
NB! Failis on entity välja kommenteeritud, et vältida konflikti tabelis olevaga, kui simuleeritakse mitut varianti korraga. Kui esimesena simuleerida tabelit ja siis espresso tulemust, kasutab simulaator esimesena kompileeritud entity-t.

espr


Korrake seda sama ka loogika-tehete tasemel oleva optimeeritud skeemiga (vt. ka VHDL faili):

library IEEE; use IEEE.std_logic_1164.all;
entity f_system is
  port ( x1, x2, x3, x4: in std_logic;
         y1, y2, y3, y4: out std_logic );
end entity f_system;

library IEEE; use IEEE.std_logic_1164.all;
architecture opti of f_system is
  signal x2i, t1i, t2i, t3x, t3i, t4i, t5i, t6: std_logic;
  signal t7, t8x, t8, t68i, t9i, t19, t197i: std_logic;
begin
  x2i <= not (x2 and x2);

  t1i <= t4i or x1 or x3;
  t2i <= not (x1 and x3 and x4);
  t3x <= not (x3 or x4);
  t3i <= not (x2  and t3x);
  t4i <= not (x2 and x4);
  t5i <= not (x2i and x3);
  t6 <= t7  and x3;
  t7 <= not (x1 or x4);
  t8x <= not (x2 or x4);
  t8 <= x1 and t8x;
  t68i <= not (t6 or t8);
  t9i <= not (x1 and x3);
  t19 <= not (t1i and t9i);
  t197i <= not (t19 or t7);

  y1 <= not (t197i and t3i);
  y2 <= not (t19 or t8);
  y3 <= not (t3i and t4i and t68i);
  y4 <= not (t2i and t5i and t68i);
end architecture opti;

Võrrelge tulemusi lähteülesandega.

opti


Oluliselt mugavam oleks, kui saaks omavahel võrrelda mitut eri etappi sama simulatsiooni käigus. Heaks näiteks on alljärgnev testpink, mis lubav korraga simuleerida kolme disaini (algne tabel, espresso tulemus ja optimeeritud skeem). Sama olemi kolme erineva arhitektuuri kasutamine on testpingis kirjas for-klauslite abil (vt. arhitektuuri deklaratiivse osa lõppu). Lisaks sisaldab testpink ka kontrollivat funktsiooni compare_signals, mis jooksvakt võrdleb kolme signaali - erinevuse puhul y1x, y2x, y3x ja/või y4x punane. Sama kood on ka failist leitav:

library IEEE; use IEEE.std_logic_1164.all;
entity test is
end entity test;

library IEEE; use IEEE.std_logic_1164.all;
architecture bench of test is
  signal x1, x2, x3, x4: std_logic;
  signal y1a, y1b, y1c, y2a, y2b, y2c: std_logic;
  signal y3a, y3b, y3c, y4a, y4b, y4c: std_logic;
  signal y1x, y2x, y3x, y4x: std_logic;
  component f_system
    port ( x1, x2, x3, x4: in std_logic;
           y1, y2, y3, y4: out std_logic );
  end component;
  for U1: f_system use entity work.f_system(tabel);
  for U2: f_system use entity work.f_system(espresso);
  for U3: f_system use entity work.f_system(opti);

  function compare_signals (s1, s2, s3: std_logic) return std_logic is
  begin
    if  s1='-'  then
      if  s2/=s3  then  return 'X';  end if;
    else
      if  s1/=s2 or s1/=s3  then  return 'X';  end if;
    end if;
    return '0';
  end function compare_signals;
begin
  -- Input signaals (after every 10 ns)
  x1 <= '0' after 0 ns, '1' after 80 ns, '0' after 160 ns;
  x2 <= '0' after 0 ns, '1' after 40 ns, '0' after 80 ns, '1' after 120 ns;
  x3 <= '0' after 0 ns, '1' after 20 ns, '0' after 40 ns, '1' after 60 ns,
        '0' after 80 ns, '1' after 100 ns, '0' after 120 ns, '1' after 140 ns;
  x4 <= '0' after 0 ns, '1' after 10 ns, '0' after 20 ns, '1' after 30 ns,
        '0' after 40 ns, '1' after 50 ns, '0' after 60 ns, '1' after 70 ns,
        '0' after 80 ns, '1' after 90 ns, '0' after 100 ns, '1' after 110 ns,
        '0' after 120 ns, '1' after 130 ns, '0' after 140 ns, '1' after 150 ns;

  -- System of Boolean functions
  U1: f_system port map (x1, x2, x3, x4, y1a, y2a, y3a, y4a);
  U2: f_system port map (x1, x2, x3, x4, y1b, y2b, y3b, y4b);
  U3: f_system port map (x1, x2, x3, x4, y1c, y2c, y3c, y4c);
  -- y1c<=y1b;  y2c<=y2b;  y3c<=y3b;  y4c<=y4b;
  y1x <= compare_signals (y1a, y1b, y1c);
  y2x <= compare_signals (y2a, y2b, y2c);
  y3x <= compare_signals (y3a, y3b, y3c);
  y4x <= compare_signals (y4a, y4b, y4c);
end architecture bench; 

Võrrelge tulemusi eelnevate simulatsioonidega. Signaalide y1a, y1b ja y1c, y2a, y2b ja y2c, y3a, y3b ja y3c ning y4a, y4b ja y4c õige järjekord on tagatud nende deklrareermise järjekorraga VHDL-failis. Selle tulemusena on hästi näha, kuidas väärtused eri mudelitel kokku langevad. Üksikud punased piigid tekivad VHDL-i delta-viitest, sest signaalid läheva sisendist väljunditesse läbi erineva arvu omistamiste.

Kui simulatsioonide tulemused ei klapi, tuleks viga üles otsida. Silumisnäidis annab ehk ettekujutuse, kuidas seda teha. See on küll tehtud vanema näidislahenduse jaoks, kui vea otsimise põhimõte jääb siiski samaks...

all together