post sim: simulation verhaelt sich leider nicht wie gewuenscht
authorBernhard Urban <lewurm@gmail.com>
Sun, 11 Apr 2010 15:07:21 +0000 (17:07 +0200)
committerBernhard Urban <lewurm@gmail.com>
Sun, 11 Apr 2010 15:22:19 +0000 (17:22 +0200)
nachdem ich schon den ganzen nachmittag verschissen hab, die postlayout simulation zum laufen zu
kriegen, hier mal eine zusammenfassung meiner erkenntnisse:

* quartus erstellt simulationsdaten (wenn das tcl-skript verwendet wird) fuer modelsim im
  verzeichnis ~hwmod/quartus/calc/simulation/modelsim
* modelsim starten
* change directory (z.b. ~hwmod/sim/post)
* File -> New -> Lib
* Compile -> Compile und folgende files kompilieren
o ~hwmod/quartus/calc/simulation/modelsim/calc.vho
o ~hwmod/src/gen_pkg.vhd
o ~hwmod/src/alu_tb_post.vhd
* Simulate -> Start Simulation
o in den tab "SDF" wechseln und die datei ~hwmod/quartus/calc/simulation/modelsim/calc_vhd.sdo
  waehlen und in das feld "apply to region" "/bla" eingeben ("bla" ist dabei die instanz in der
  testbench)
o nun unter dem tab "Design" work -> alu_tb -> sim und die testbench waehlen und die simulation
  starten

das groesste problem war dabei, dass die entity in der calc.vho zu folgende wird:
> ENTITY  alu IS
> PORT (
>  sys_clk : IN std_logic;
>  sys_res_n : IN std_logic;
>  \opcode.NOP\ : IN std_logic;
>  \opcode.SUB\ : IN std_logic;
>  \opcode.ADD\ : IN std_logic;
>  \opcode.MUL\ : IN std_logic;
>  \opcode.DIV\ : IN std_logic;
>  \opcode.DONE\ : IN std_logic;
>  op1 : IN std_logic_vector(31 DOWNTO 0);
>  op2 : IN std_logic_vector(31 DOWNTO 0);
>  op3 : OUT std_logic_vector(31 DOWNTO 0);
>  do_calc : IN std_logic;
>  calc_done : OUT std_logic
>  );
> END alu;

statt wie original:
> package gen_pkg is
>         type alu_ops is (NOP, SUB, ADD, MUL, DIV, DONE);
>         constant CBITS : integer := 32;
>         subtype csigned is signed((CBITS-1) downto 0);
> end package gen_pkg;
>
> entity alu is
>         port
>         (
>                 sys_clk : in std_logic;
>                 sys_res_n : in std_logic;
>                 opcode : in alu_ops;
>                 op1 : in csigned;
>                 op2 : in csigned;
>                 op3 : out csigned;
>                 do_calc : in std_logic;
>                 calc_done : out std_logic
>         );
> end entity alu;

das hat die folge dass man die testbench der beh-sim nicht verwenden kann UND dass ein ewig lange
fehlerliste kommt, wodurch es schwer war, festzustellen worin die fehlerursache ueberhaupt nun liegt.

es ist auch nicht besonders praktisch wie sich die entity defintion entartet... trotzdem hab ich mal
die testbench der beh-sim dafuer angepasst. die simulation dazu verhaelt sich leider nicht
gewuenscht, und ich hab im moment auch keine ahnung woran das liegen koennte :/

src/alu_tb_post.vhd [new file with mode: 0644]

diff --git a/src/alu_tb_post.vhd b/src/alu_tb_post.vhd
new file mode 100644 (file)
index 0000000..795eaa3
--- /dev/null
@@ -0,0 +1,149 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.gen_pkg.all;
+
+entity alu_tb is
+end entity alu_tb;
+
+architecture sim of alu_tb is
+       component alu is
+               port
+               (
+                       sys_clk : in std_logic;
+                       sys_res_n : in std_logic;
+                       \opcode.NOP\ : in std_logic;
+                       \opcode.SUB\ : in std_logic;
+                       \opcode.ADD\ : in std_logic;
+                       \opcode.MUL\ : in std_logic;
+                       \opcode.DIV\ : in std_logic;
+                       \opcode.DONE\ : in std_logic;
+                       op1 : in std_logic_vector(31 downto 0);
+                       op2 : in std_logic_vector(31 downto 0);
+                       op3 : out std_logic_vector(31 downto 0);
+                       do_calc : in std_logic;
+                       calc_done : out std_logic
+               );
+       end component alu;
+
+       signal sys_clk, sys_res_n, do_calc, calc_done : std_logic;
+       signal opcode : alu_ops;
+       signal \opcode.NOP\ : std_logic;
+       signal \opcode.SUB\ : std_logic;
+       signal \opcode.ADD\ : std_logic;
+       signal \opcode.MUL\ : std_logic;
+       signal \opcode.DIV\ : std_logic;
+       signal \opcode.DONE\ : std_logic;
+       signal op1, op2, op3 : std_logic_vector(31 downto 0);
+       signal stop : boolean := false;
+begin
+       bla : alu
+       port map
+       (
+               sys_clk => sys_clk,
+               sys_res_n => sys_res_n,
+               do_calc => do_calc,
+               calc_done => calc_done,
+               op1 => op1,
+               op2 => op2,
+               op3 => op3,
+               \opcode.NOP\ => \opcode.NOP\,
+               \opcode.SUB\ => \opcode.SUB\,
+               \opcode.ADD\ => \opcode.ADD\,
+               \opcode.MUL\ => \opcode.MUL\,
+               \opcode.DIV\ => \opcode.DIV\,
+               \opcode.DONE\ => \opcode.DONE\
+       );
+
+       process
+       begin
+               sys_clk <= '0';
+               wait for 15 ns;
+               sys_clk <= '1';
+               wait for 15 ns;
+               if stop = true then
+                       wait;
+               end if;
+       end process;
+
+       process
+               type alu_testv is record
+                       o1 : cinteger;
+                       o : alu_ops;
+                       o2 : cinteger;
+                       expected : cinteger;
+               end record alu_testv;
+
+               -- ggf. groesse des arrays erhoehen
+               type alu_testv_array is array (natural range 0 to 20) of alu_testv;
+
+               variable testmatrix : alu_testv_array :=
+                       ( 0 => (-5, DIV, 3, -1),
+                         1 => (7, ADD, 3, 10),
+                         2 => (7, SUB, 1, 6),
+                         3 => (7, DIV, 1, 7),
+                         4 => (7, DIV, 3, 2),
+                         5 => (7, ADD, 1, 8),
+                         6 => (7, MUL, 3, 21),
+                         7 => (-7, MUL, 3, -21),
+                         8 => (268435456, MUL, -2, -536870912),
+                         9 => (268435456, MUL, 2**5, 0), -- um fuenf nach links shiften
+                         10 => (268435456 + 5, MUL, 2**5, 160), -- = 5 * (2^5)
+                         11 => (100, DIV, 10, 10),
+                         12 => (100, DIV, 51, 1),
+                         13 => (100, DIV, 49, 2),
+                         14 => (153156, DIV, 3543, 43),
+                         15 => (-153156, DIV, 3543, -43),
+                         16 => (153156, DIV, -3543, -43),
+                         17 => (-153156, DIV, -3543, 43),
+                         others => (0, ADD, 0, 0)
+                       );
+
+       begin
+               sys_res_n <= '0';
+               wait for 50 ns;
+               sys_res_n <= '1';
+
+               for i in testmatrix'range loop
+                       wait for 100 ns;
+                       \opcode.NOP\ <= '0';
+                       \opcode.SUB\ <= '0';
+                       \opcode.ADD\ <= '0';
+                       \opcode.MUL\ <= '0';
+                       \opcode.DIV\ <= '0';
+                       \opcode.DONE\ <= '0';
+                       op1 <= std_logic_vector(to_signed(testmatrix(i).o1,CBITS));
+                       case testmatrix(i).o is
+                               when NOP => \opcode.NOP\ <= '1';
+                               when SUB => \opcode.SUB\ <= '1';
+                               when ADD => \opcode.ADD\ <= '1';
+                               when MUL => \opcode.MUL\ <= '1';
+                               when DIV => \opcode.DIV\ <= '1';
+                               when DONE => \opcode.DONE\ <= '1';
+                       end case;
+                       op2 <= std_logic_vector(to_signed(testmatrix(i).o2,CBITS));
+
+                       -- berechnung kann los gehen
+                       do_calc <= '1';
+
+                       -- warten auf die alu einheit
+                       wait on calc_done;
+
+                       assert op3 = std_logic_vector(to_signed(testmatrix(i).expected,CBITS))
+                               report "" & cinteger'image(testmatrix(i).o1) & 
+                               " " & alu_ops'image(opcode) &
+                               " " & cinteger'image(testmatrix(i).o2) &
+                               "/= " & integer'image(to_integer(signed(op3))) &
+                               " -- erwartet: " & cinteger'image(testmatrix(i).expected);
+
+                       wait for 5 ns;
+                       -- ack it!
+                       do_calc <= '0';
+               end loop;
+
+               assert false
+                       report "alle testfaelle der ALU waren erfolgreich!";
+               stop <= true;
+               wait;
+       end process;
+end architecture sim;