Examples and design pattern for VHDL verification
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.

125 lines
3.2 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. library std;
  5. use std.env.all;
  6. library osvvm;
  7. use osvvm.NamePkg.all ;
  8. use osvvm.TranscriptPkg.all ;
  9. use osvvm.OsvvmGlobalPkg.all ;
  10. use osvvm.AlertLogPkg.all ;
  11. use osvvm.RandomPkg.all ;
  12. use osvvm.CoveragePkg.all ;
  13. use osvvm.MemoryPkg.all ;
  14. entity osvvm_fsm_psl_coverage is
  15. end entity osvvm_fsm_psl_coverage;
  16. architecture sim of osvvm_fsm_psl_coverage is
  17. type t_fsm_state is (IDLE, ADDR, DATA);
  18. signal s_fsm_state : t_fsm_state;
  19. signal s_clk : std_logic := '0';
  20. signal s_reset_n : std_logic := '0';
  21. signal s_state_cover : unsigned(2 downto 0);
  22. shared variable sv_cover : CovPType;
  23. begin
  24. s_clk <= not(s_clk) after 5 ns;
  25. s_reset_n <= '1' after 20 ns;
  26. FsmP : process (s_reset_n, s_clk) is
  27. begin
  28. if (s_reset_n = '0') then
  29. s_fsm_state <= IDLE;
  30. elsif (rising_edge(s_clk)) then
  31. case s_fsm_state is
  32. when IDLE => s_fsm_state <= ADDR;
  33. when ADDR => s_fsm_state <= DATA;
  34. when DATA => s_fsm_state <= IDLE;
  35. when others =>
  36. null;
  37. end case;
  38. end if;
  39. end process FsmP;
  40. -- psl endpoint E_IDLE_ADDR is {s_fsm_state = IDLE; s_fsm_state = ADDR}@s_clk'active;
  41. -- psl endpoint E_ADDR_DATA is {s_fsm_state = ADDR; s_fsm_state = DATA}@s_clk'active;
  42. -- psl endpoint E_DATA_IDLE is {s_fsm_state = DATA; s_fsm_state = IDLE}@s_clk'active;
  43. EndpointRegP : process is
  44. begin
  45. s_state_cover <= (others => '0');
  46. if (E_IDLE_ADDR) then
  47. s_state_cover(0) <= '1';
  48. end if;
  49. if (E_ADDR_DATA) then
  50. s_state_cover(1) <= '1';
  51. end if;
  52. if (E_DATA_IDLE) then
  53. s_state_cover(2) <= '1';
  54. end if;
  55. wait until rising_edge(s_clk);
  56. end process;
  57. sv_cover.AddBins("IDLE->ADDR", GenBin(1));
  58. sv_cover.AddBins("ADDR->DATA", GenBin(2));
  59. sv_cover.AddBins("DATA->IDLE", GenBin(4));
  60. sv_cover.AddBins(ALL_ILLEGAL);
  61. CovCollectP : process is
  62. begin
  63. wait until s_reset_n = '1' and rising_edge(s_clk);
  64. -- we have to wait another cycle because endpoints are delayed by one cycle
  65. -- if we don't wait, we get an illegal BIN hit in second cycle after released reset
  66. wait until rising_edge(s_clk);
  67. loop
  68. wait until rising_edge(s_clk);
  69. sv_cover.ICover(to_integer(s_state_cover));
  70. end loop;
  71. end process CovCollectP;
  72. FinishP : process is
  73. begin
  74. wait until s_clk'active;
  75. if (sv_cover.IsCovered) then
  76. Log("FSM full covered :)", ALWAYS);
  77. sv_cover.SetName("FSM state coverage report");
  78. sv_cover.WriteBin;
  79. stop(0);
  80. end if;
  81. end process FinishP;
  82. -- psl default clock is rising_edge(s_clk);
  83. -- psl IDLE_ADDR : assert always (s_fsm_state = IDLE and s_reset_n = '1') -> next (s_fsm_state = ADDR) abort not(s_reset_n)
  84. -- report "FSM error: IDLE should be followed by ADDR state";
  85. -- psl ADDR_DATA : assert always (s_fsm_state = ADDR and s_reset_n = '1') -> next (s_fsm_state = DATA) abort not(s_reset_n);
  86. -- report "FSM error: ADDR should be followed by DATA state";
  87. -- psl DATA_IDLE : assert always (s_fsm_state = DATA and s_reset_n = '1') -> next (s_fsm_state = IDLE) abort not(s_reset_n);
  88. -- report "FSM error: DATA should be followed by IDLE state";
  89. end architecture sim;