- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.numeric_std.all;
-
-
-
- entity alu is
- generic (
- Width : natural := 8;
- Formal : boolean := true
- );
- port (
- Reset_n_i : in std_logic;
- Clk_i : in std_logic;
- Opc_i : in std_logic_vector(1 downto 0);
- DinA_i : in std_logic_vector(Width-1 downto 0);
- DinB_i : in std_logic_vector(Width-1 downto 0);
- Dout_o : out std_logic_vector(Width-1 downto 0);
- OverFlow_o : out std_logic
- );
- end entity alu;
-
-
-
- architecture rtl of alu is
-
-
- subtype t_opc is std_logic_vector(Opc_i'range);
-
- constant c_add : t_opc := "00";
- constant c_sub : t_opc := "01";
- constant c_and : t_opc := "10";
- constant c_or : t_opc := "11";
-
-
- begin
-
-
- process (Reset_n_i, Clk_i) is
- variable v_result : std_logic_vector(Width downto 0);
- begin
- if (Reset_n_i = '0') then
- v_result := (others => '0');
- Dout_o <= (others => '0');
- OverFlow_o <= '0';
- elsif (rising_edge(Clk_i)) then
- case Opc_i is
- when c_add =>
- v_result := std_logic_vector(unsigned('0' & DinA_i) +
- unsigned('0' & DinB_i));
- when c_sub =>
- v_result := std_logic_vector(unsigned('0' & DinA_i) -
- unsigned('0' & DinB_i));
- when c_and => v_result := ('0', DinA_i and DinB_i);
- when c_or => v_result := ('0', DinA_i or DinB_i);
- when others => null;
- end case;
- Dout_o <= v_result(Width-1 downto 0);
- OverFlow_o <= v_result(Width);
- end if;
- end process;
-
-
- FormalG : if Formal generate
-
- function max(a, b: std_logic_vector) return unsigned is
- begin
- if unsigned(a) > unsigned(b) then
- return unsigned(a);
- else
- return unsigned(b);
- end if;
- end function max;
-
- begin
-
- default clock is rising_edge(Clk_i);
-
- -- Initial reset
- INITIAL_RESET : restrict {not Reset_n_i[*2]; Reset_n_i[+]}[*1];
-
- -- Asynchronous (unclocked) Reset asserts
- AFTER_RESET : process (all) is
- begin
- if (not Reset_n_i) then
- RESET_DOUT : assert Dout_o = (Dout_o'range => '0');
- RESET_OVFL : assert OverFlow_o = '0';
- end if;
- end process AFTER_RESET;
-
- ADD_OP : assert always Reset_n_i and Opc_i = c_add ->
- next unsigned(Dout_o) = unsigned(prev(DinA_i)) + unsigned(prev(DinB_i)) abort not Reset_n_i;
-
- SUB_OP : assert always Reset_n_i and Opc_i = c_sub ->
- next unsigned(Dout_o) = unsigned(prev(DinA_i)) - unsigned(prev(DinB_i)) abort not Reset_n_i;
-
- AND_OP : assert always Reset_n_i and Opc_i = c_and ->
- next Dout_o = (prev(DinA_i) and prev(DinB_i)) abort not Reset_n_i;
-
- OR_OP : assert always Reset_n_i and Opc_i = c_or ->
- next Dout_o = (prev(DinA_i) or prev(DinB_i)) abort not Reset_n_i;
-
- OVERFLOW_ADD : assert always Reset_n_i and Opc_i = c_add and (unsigned(DinA_i) + unsigned(DinB_i)) < max(DinA_i, DinB_i) ->
- next OverFlow_o abort not Reset_n_i;
-
- NOT_OVERFLOW_ADD : assert always Reset_n_i and Opc_i = c_add and (unsigned(DinA_i) + unsigned(DinB_i)) >= max(DinA_i, DinB_i) ->
- next not OverFlow_o abort not Reset_n_i;
-
- OVERFLOW_SUB : assert always Reset_n_i and Opc_i = c_sub and (unsigned(DinA_i) - unsigned(DinB_i)) > unsigned(DinA_i) ->
- next OverFlow_o abort not Reset_n_i;
-
- NOT_OVERFLOW_SUB : assert always Reset_n_i and Opc_i = c_sub and (unsigned(DinA_i) - unsigned(DinB_i)) <= unsigned(DinA_i) ->
- next not OverFlow_o abort not Reset_n_i;
-
- end generate FormalG;
-
-
- end architecture rtl;
|