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.

90 lines
2.5 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. use work.pkg.all;
  5. entity psl_prev is
  6. port (
  7. clk : in std_logic
  8. );
  9. end entity psl_prev;
  10. architecture psl of psl_prev is
  11. signal valid : std_logic;
  12. signal a : std_logic;
  13. signal di, do : std_logic_vector(3 downto 0);
  14. signal cnt : std_logic_vector(3 downto 0);
  15. begin
  16. -- 01234567890123
  17. SEQ_VALID : sequencer generic map ("____-_-_-_-_-_") port map (clk, valid);
  18. SEQ_A : sequencer generic map ("-__--__--__--_") port map (clk, a);
  19. SEQ_DI : hex_sequencer generic map ("00011223344556") port map (clk, di);
  20. SEQ_DO : hex_sequencer generic map ("00001020304050") port map (clk, do);
  21. SEQ_CNT : hex_sequencer generic map ("0123456789ABCDEF") port map (clk, cnt);
  22. -- All is sensitive to rising edge of clk
  23. default clock is rising_edge(clk);
  24. -- This assertion holds
  25. PREV_0_a : assert always (valid -> a = prev(a));
  26. -- This assertion should hold
  27. PREV_1_a : assert always (valid -> di = prev(di));
  28. -- Workaround needed before prev() was implemented
  29. -- With VHDL glue logic generating the
  30. -- previous value of di and simple comparing the two values
  31. d_reg : block is
  32. signal di_prev : std_logic_vector(di'range);
  33. begin
  34. process (clk) is
  35. begin
  36. if rising_edge(clk) then
  37. di_prev <= di;
  38. end if;
  39. end process;
  40. PREV_2_a : assert always (valid -> di = di_prev);
  41. end block d_reg;
  42. -- Using prev() with additional parameter i, should return
  43. -- the value of the expression in the i-th previous cycle
  44. -- prev(a) = prev(a, 1)
  45. -- This assertion holds
  46. PREV_3_a : assert always (valid -> a = prev(a, 1));
  47. -- Using prev() with additional parameter i, should return
  48. -- the value of the expression in the i-th previous cycle
  49. -- This assertion holds
  50. PREV_4_a : assert always (valid -> a = prev(a, 4));
  51. -- Some kind of pipeline data check, checks if do is
  52. -- equal to di one cycle before when valid holds
  53. -- This assertion holds
  54. PREV_5_a : assert always (valid -> do = prev(di, 1));
  55. -- Example for a simple counter check
  56. -- This assertion holds
  57. PREV_6_a : assert always ((cnt /= x"F") -> next (unsigned(cnt) = unsigned(prev(cnt)) + 1));
  58. -- Check parts of a vector
  59. -- This assertion should hold
  60. PREV_7_a : assert always (valid -> di(1 downto 0) = prev(di(1 downto 0)));
  61. -- Stop simulation after longest running sequencer is finished
  62. -- Simulation only code by using pragmas
  63. -- synthesis translate_off
  64. stop_sim(clk, 14);
  65. -- synthesis translate_on
  66. end architecture psl;