Examples of using PSL for functional and formal verification of VHDL with GHDL (and SymbiYosys)
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.

135 lines
3.0 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. entity sequencer is
  4. generic (
  5. seq : string
  6. );
  7. port (
  8. clk : in std_logic;
  9. data : out std_logic
  10. );
  11. end entity sequencer;
  12. architecture rtl of sequencer is
  13. signal index : natural := seq'low;
  14. function to_bit (a : in character) return std_logic is
  15. variable ret : std_logic;
  16. begin
  17. case a is
  18. when '0' | '_' => ret := '0';
  19. when '1' | '-' => ret := '1';
  20. when others => ret := 'X';
  21. end case;
  22. return ret;
  23. end function to_bit;
  24. begin
  25. process (clk) is
  26. begin
  27. if rising_edge(clk) then
  28. if (index < seq'high) then
  29. index <= index + 1;
  30. end if;
  31. end if;
  32. end process;
  33. data <= to_bit(seq(index));
  34. end architecture rtl;
  35. library ieee;
  36. use ieee.std_logic_1164.all;
  37. use ieee.numeric_std.all;
  38. entity issue is
  39. port (
  40. clk : in std_logic
  41. );
  42. end entity issue;
  43. architecture psl of issue is
  44. signal a, b, c, d, e, f : std_logic;
  45. begin
  46. -- 012345678901
  47. SEQ_A : entity work.sequencer generic map ("__-_________") port map (clk, a);
  48. -- Next 3 sequences should hold with next[3:5]
  49. -- 012345678901
  50. SEQ_B : entity work.sequencer generic map ("_____-______") port map (clk, b);
  51. SEQ_C : entity work.sequencer generic map ("______-_____") port map (clk, c);
  52. SEQ_D : entity work.sequencer generic map ("_______-____") port map (clk, d);
  53. -- Next two sequences should not hold with next[3:5]
  54. -- 012345678901
  55. SEQ_E : entity work.sequencer generic map ("____-_______") port map (clk, e);
  56. SEQ_F : entity work.sequencer generic map ("________-___") port map (clk, f);
  57. -- All is sensitive to rising edge of clk
  58. default clock is rising_edge(clk);
  59. -- This assertion should hold, but doesn't (GHDL BUG)
  60. NEXT_0_a : assert always (a -> next_e[3 to 5] (b))
  61. report "NEXT_0_a failed";
  62. -- This assertion should hold, but doesn't (GHDL BUG)
  63. NEXT_1_a : assert always (a -> next_e[3 to 5] (c))
  64. report "NEXT_1_a failed";
  65. -- This assertion holds (CORRECT)
  66. NEXT_2_a : assert always (a -> next_e[3 to 5] (d))
  67. report "NEXT_2_a failed";
  68. -- This assertion doesn't hold (CORRECT)
  69. NEXT_3_a : assert always (a -> next_e[3 to 5] (e))
  70. report "NEXT_3_a failed";
  71. -- This assertion doesn't hold (CORRECT)
  72. NEXT_4_a : assert always (a -> next_e[3 to 5] (f))
  73. report "NEXT_4_a failed";
  74. end architecture psl;
  75. library ieee;
  76. use ieee.std_logic_1164.all;
  77. use std.env.all;
  78. entity test_issue is
  79. end entity test_issue;
  80. architecture sim of test_issue is
  81. signal clk : std_logic := '1';
  82. begin
  83. clk <= not clk after 500 ps;
  84. DUT : entity work.issue(psl) port map (clk);
  85. -- stop simulation after 30 cycles
  86. process
  87. variable index : natural := 10;
  88. begin
  89. loop
  90. wait until rising_edge(clk);
  91. index := index - 1;
  92. exit when index = 0;
  93. end loop;
  94. stop(0);
  95. end process;
  96. end architecture sim;