Trying to verify Verilog/VHDL designs with formal methods and tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
3.5 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. entity alu is
  5. generic (
  6. Width : natural := 8;
  7. Formal : boolean := true
  8. );
  9. port (
  10. Reset_n_i : in std_logic;
  11. Clk_i : in std_logic;
  12. Opc_i : in std_logic_vector(1 downto 0);
  13. DinA_i : in std_logic_vector(Width-1 downto 0);
  14. DinB_i : in std_logic_vector(Width-1 downto 0);
  15. Dout_o : out std_logic_vector(Width-1 downto 0);
  16. OverFlow_o : out std_logic
  17. );
  18. end entity alu;
  19. architecture rtl of alu is
  20. subtype t_opc is std_logic_vector(Opc_i'range);
  21. constant c_add : t_opc := "00";
  22. constant c_sub : t_opc := "01";
  23. constant c_and : t_opc := "10";
  24. constant c_or : t_opc := "11";
  25. begin
  26. process (Reset_n_i, Clk_i) is
  27. variable v_result : std_logic_vector(Width downto 0);
  28. begin
  29. if (Reset_n_i = '0') then
  30. v_result := (others => '0');
  31. Dout_o <= (others => '0');
  32. OverFlow_o <= '0';
  33. elsif (rising_edge(Clk_i)) then
  34. case Opc_i is
  35. when c_add =>
  36. v_result := std_logic_vector(unsigned('0' & DinA_i) +
  37. unsigned('0' & DinB_i));
  38. when c_sub =>
  39. v_result := std_logic_vector(unsigned('0' & DinA_i) -
  40. unsigned('0' & DinB_i));
  41. when c_and => v_result := ('0', DinA_i and DinB_i);
  42. when c_or => v_result := ('0', DinA_i or DinB_i);
  43. when others => null;
  44. end case;
  45. Dout_o <= v_result(Width-1 downto 0);
  46. OverFlow_o <= v_result(Width);
  47. end if;
  48. end process;
  49. FormalG : if Formal generate
  50. function max(a, b: std_logic_vector) return unsigned is
  51. begin
  52. if unsigned(a) > unsigned(b) then
  53. return unsigned(a);
  54. else
  55. return unsigned(b);
  56. end if;
  57. end function max;
  58. begin
  59. default clock is rising_edge(Clk_i);
  60. -- Initial reset
  61. INITIAL_RESET : restrict {not Reset_n_i[*2]; Reset_n_i[+]}[*1];
  62. -- Asynchronous (unclocked) Reset asserts
  63. AFTER_RESET : process (all) is
  64. begin
  65. if (not Reset_n_i) then
  66. RESET_DOUT : assert Dout_o = (Dout_o'range => '0');
  67. RESET_OVFL : assert OverFlow_o = '0';
  68. end if;
  69. end process AFTER_RESET;
  70. ADD_OP : assert always Reset_n_i and Opc_i = c_add ->
  71. next unsigned(Dout_o) = unsigned(prev(DinA_i)) + unsigned(prev(DinB_i)) abort not Reset_n_i;
  72. SUB_OP : assert always Reset_n_i and Opc_i = c_sub ->
  73. next unsigned(Dout_o) = unsigned(prev(DinA_i)) - unsigned(prev(DinB_i)) abort not Reset_n_i;
  74. AND_OP : assert always Reset_n_i and Opc_i = c_and ->
  75. next Dout_o = (prev(DinA_i) and prev(DinB_i)) abort not Reset_n_i;
  76. OR_OP : assert always Reset_n_i and Opc_i = c_or ->
  77. next Dout_o = (prev(DinA_i) or prev(DinB_i)) abort not Reset_n_i;
  78. OVERFLOW_ADD : assert always Reset_n_i and Opc_i = c_add and (unsigned(DinA_i) + unsigned(DinB_i)) < max(DinA_i, DinB_i) ->
  79. next OverFlow_o abort not Reset_n_i;
  80. 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) ->
  81. next not OverFlow_o abort not Reset_n_i;
  82. OVERFLOW_SUB : assert always Reset_n_i and Opc_i = c_sub and (unsigned(DinA_i) - unsigned(DinB_i)) > unsigned(DinA_i) ->
  83. next OverFlow_o abort not Reset_n_i;
  84. NOT_OVERFLOW_SUB : assert always Reset_n_i and Opc_i = c_sub and (unsigned(DinA_i) - unsigned(DinB_i)) <= unsigned(DinA_i) ->
  85. next not OverFlow_o abort not Reset_n_i;
  86. end generate FormalG;
  87. end architecture rtl;