From c71721ad4d9cea1660498a32fd7353712149e5fb Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Fri, 9 Apr 2010 19:04:30 +0200 Subject: [PATCH] alu: besseres geruest 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 | 10 +++-- src/alu.vhd | 102 +++++++++++++++++++++++++++++++++++++----------- src/alu_tb.vhd | 33 ++++++++++------ src/gen_pkg.vhd | 5 +++ 4 files changed, 113 insertions(+), 37 deletions(-) diff --git a/src/alu.do b/src/alu.do index 56ba7f9..337baff 100644 --- a/src/alu.do +++ b/src/alu.do @@ -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 diff --git a/src/alu.vhd b/src/alu.vhd index e9db35b..de0b6a6 100644 --- a/src/alu.vhd +++ b/src/alu.vhd @@ -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; diff --git a/src/alu_tb.vhd b/src/alu_tb.vhd index 576c382..df488b6 100644 --- a/src/alu_tb.vhd +++ b/src/alu_tb.vhd @@ -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; diff --git a/src/gen_pkg.vhd b/src/gen_pkg.vhd index f2f4871..cb87dba 100644 --- a/src/gen_pkg.vhd +++ b/src/gen_pkg.vhd @@ -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; -- 2.25.1