alu: besseres geruest
authorBernhard Urban <lewurm@gmail.com>
Fri, 9 Apr 2010 17:04:30 +0000 (19:04 +0200)
committerBernhard Urban <lewurm@gmail.com>
Fri, 9 Apr 2010 21:19:55 +0000 (23:19 +0200)
calc_done geht leider nicht als inout, das hat leider nicht wirklich hin weil sich dann modelsim
aufregt, es seien zwei treiber vorhanden. deshalb gibt es nun ein ack-signal aka. "ack"

selbes problem fuer op2 (man braucht jetzt einen drittes register fuer das ergebnis).

mal schauen ob das doch irgendwie geht... (std_logic vs std_ulogic hab ich noch nicht ganz
durchschaut)

src/alu.do
src/alu.vhd
src/alu_tb.vhd
src/gen_pkg.vhd

index 56ba7f945e9674628321ad592ebbe440285488ea..337baffdacef0cfe694aba56d2f85310bbd7248b 100644 (file)
@@ -10,9 +10,11 @@ add wave do_calc
 add wave calc_done
 add wave stop
 
-#simulation starten (100ms)
-run 100 ms
+#rauszoomen
+wave zoomout 500.0
+
+#simulation starten (1 ms)
+run 1 ms
 
 #ganz nach links scrollen
-#TODO: kommando in der version nicht verfuegbar?!
-#seetime wave 0 ms
+wave seetime 0
index e9db35be5f3794db2cc3a49657405cd193696079..de0b6a6aa32c4c0d95cce84bfe13a4edfb032a28 100644 (file)
@@ -6,42 +6,100 @@ use work.gen_pkg.all;
 entity alu is
        port
        (
-               sys_clk : in std_ulogic;
-               sys_res_n : in std_ulogic;
+               sys_clk : in std_logic;
+               sys_res_n : in std_logic;
                opcode : in alu_ops;
-               op1 : in signed(31 downto 0);
-               op2 : in signed(31 downto 0);
-               op3 : out signed(31 downto 0);
-               do_calc : in std_ulogic;
-               calc_done : out std_ulogic
+               op1 : in csigned;
+               op2 : in csigned;
+               op3 : out csigned;
+               do_calc : in std_logic;
+               ack : in std_logic;
+               calc_done : out std_logic
        );
 end entity alu;
 
 architecture beh of alu is
-       -- signal cnt_int, cnt_next : integer range 0 to CNT_MAX;
-       signal op3_next : signed (31 downto 0);
+       type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDONE);
+       signal state, state_next : ALU_STATE;
+       signal done_intern : std_logic;
 begin
+       -- sync
        process(sys_clk, sys_res_n)
        begin
                if sys_res_n = '0' then
-                       op3 <= (others => '0');
+                       state <= SIDLE;
                elsif rising_edge(sys_clk) then
-                       op3 <= op3_next;
+                       state <= state_next;
                end if;
        end process;
 
-       process(do_calc, opcode, op1, op2)
+       -- next state
+       process(state, opcode, done_intern)
        begin
-               case opcode is
-                       when ADD => op3_next <= op1 + op2;
-                       when SUB => op3_next <= op1 - op2;
-                       when MUL => op3_next <= op1 * op2;
-                       when DIV => op3_next <= op1 / op2;
-                       when others => op3_next <= (others => '0');
+               -- set a default value for next state
+               state_next <= state;
+               -- next state berechnen
+               case state is
+                       when SIDLE =>
+                               case opcode is
+                                       when ADD =>
+                                               state_next <= SADD;
+                                       when SUB =>
+                                               state_next <= SSUB;
+                                       when MUL =>
+                                               state_next <= SMUL;
+                                       when DIV =>
+                                               state_next <= SDIV;
+                                       when others =>
+                                               state_next <= SIDLE;
+                               end case;
+                       when SADD =>
+                               if done_intern = '1' then
+                                       state_next <= SDONE;
+                               end if;
+                       when SSUB =>
+                               if done_intern = '1' then
+                                       state_next <= SDONE;
+                               end if;
+                       when SMUL =>
+                               if done_intern = '1' then
+                                       state_next <= SDONE;
+                               end if;
+                       when SDIV =>
+                               if done_intern = '1' then
+                                       state_next <= SDONE;
+                               end if;
+                       when SDONE =>
+                               if ack = '1' then
+                                       state_next <= SIDLE;
+                               end if;
+               end case;
+       end process;
+
+       -- output
+       process(state)
+       begin
+               op3 <= (others => '0');
+               calc_done <= '0';
+
+               case state is
+                       when SIDLE =>
+                               done_intern <= '0';
+                       when SADD =>
+                               op3 <= op1 + op2;
+                               done_intern <= '1';
+                       when SSUB =>
+                               op3 <= op1 - op2;
+                               done_intern <= '1';
+                       when SMUL =>
+                               op3 <= op1 * op2;
+                               done_intern <= '1';
+                       when SDIV =>
+                               op3 <= op1 / op2;
+                               done_intern <= '1';
+                       when SDONE =>
+                               done_intern <= '1';
+                               calc_done <= '1';
                end case;
-               --      calc_done <= '1';
-               --else
-               --      calc_done <= '0';
-               --end if;
        end process;
 end architecture beh;
index 576c382492276c02982be221ebd565ac7086b799..df488b60ab9adb8fb5b3a698c1760455b4399e7c 100644 (file)
@@ -13,17 +13,18 @@ architecture sim of alu_tb is
                        sys_clk : in std_logic;
                        sys_res_n : in std_logic;
                        opcode : in alu_ops;
-                       op1 : in signed(31 downto 0);
-                       op2 : in signed(31 downto 0);
-                       op3 : out signed(31 downto 0);
+                       op1 : in csigned;
+                       op2 : in csigned;
+                       op3 : out csigned;
                        do_calc : in std_logic;
+                       ack : in std_logic;
                        calc_done : out std_logic
                );
        end component alu;
 
-       signal sys_clk, sys_res_n, do_calc, calc_done : std_ulogic;
+       signal sys_clk, sys_res_n, do_calc, calc_done, ack : std_logic;
        signal opcode : alu_ops;
-       signal op1, op2, op3, optmp : signed(31 downto 0);
+       signal op1, op2, op3, optmp : csigned;
        signal stop : boolean := false;
 begin
        bla : alu
@@ -32,6 +33,7 @@ begin
                sys_clk => sys_clk,
                sys_res_n => sys_res_n,
                do_calc => do_calc,
+               ack => ack,
                calc_done => calc_done,
                op1 => op1,
                op2 => op2,
@@ -53,18 +55,27 @@ begin
        process
        begin
                sys_res_n <= '0';
-               wait for 100 ns;
+               wait for 50 ns;
                sys_res_n <= '1';
-               wait for 200 ns;
+               wait for 100 ns;
 
                op1(31 downto 0) <= (0 => '1', 1 => '1', 2 => '1', others => '0');
                op2(31 downto 0) <= (0 => '1', 2 => '1', others => '0');
                opcode <= ADD;
-               wait for 30ns;
+
+               wait for 10 ns;
+               -- berechnung kann los gehen
                do_calc <= '1';
-               wait for 300ns;
-               optmp <= op3;
-               wait for 400ns;
+               ack <= '0';
+
+               -- warten auf die alu einheit
+               wait on calc_done;
+
+               -- ack it!
+               do_calc <= '0';
+               ack <= '1';
+
+               wait for 20 ns;
 
                stop <= true;
                wait;
index f2f48712d7bac1efb3b2603c91cadabd5e3d071f..cb87dbab6d977aed99c2750d5559556f4b7fc850 100644 (file)
@@ -1,4 +1,9 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
 package gen_pkg is
        type alu_ops is (NOP, SUB, ADD, MUL, DIV, DONE);
+       subtype csigned is signed(31 downto 0);
 end package gen_pkg;