Examples and design pattern for VHDL verification
vhdl
ghdl
osvvm
psl
fpga
testbenches
coverage

osvvm_fsm_coverage.vhd 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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_coverage is
  15. end entity osvvm_fsm_coverage;
  16. architecture sim of osvvm_fsm_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. shared variable sv_cover : CovPType;
  22. procedure fsm_covadd_states (name : in string;
  23. prev : in t_fsm_state;
  24. curr : in t_fsm_state;
  25. covdb : inout CovPType) is
  26. begin
  27. covdb.AddCross(name,
  28. GenBin(t_fsm_state'pos(prev)),
  29. GenBin(t_fsm_state'pos(curr)));
  30. wait;
  31. end procedure fsm_covadd_states;
  32. procedure fsm_covadd_illegal (name : in string;
  33. covdb : inout CovPType) is
  34. begin
  35. covdb.AddCross(ALL_ILLEGAL, ALL_ILLEGAL);
  36. wait;
  37. end procedure fsm_covadd_illegal;
  38. procedure fsm_covcollect (signal reset : in std_logic;
  39. signal clk : in std_logic;
  40. signal state : in t_fsm_state;
  41. covdb : inout CovPType) is
  42. variable v_state : t_fsm_state := t_fsm_state'left;
  43. begin
  44. wait until reset = '1' and rising_edge(clk);
  45. loop
  46. v_state := state;
  47. wait until rising_edge(s_clk);
  48. covdb.ICover((t_fsm_state'pos(v_state), t_fsm_state'pos(state)));
  49. end loop;
  50. end procedure fsm_covcollect;
  51. begin
  52. s_clk <= not(s_clk) after 5 ns;
  53. s_reset_n <= '1' after 20 ns;
  54. FsmP : process (s_reset_n, s_clk) is
  55. begin
  56. if (s_reset_n = '0') then
  57. s_fsm_state <= IDLE;
  58. elsif (rising_edge(s_clk)) then
  59. case s_fsm_state is
  60. when IDLE => s_fsm_state <= ADDR;
  61. when ADDR => s_fsm_state <= DATA;
  62. when DATA => s_fsm_state <= IDLE;
  63. when others =>
  64. null;
  65. end case;
  66. end if;
  67. end process FsmP;
  68. fsm_covadd_states ("IDLE->ADDR", IDLE, ADDR, sv_cover);
  69. fsm_covadd_states ("ADDR->DATA", ADDR, DATA, sv_cover);
  70. fsm_covadd_states ("DATA->IDLE", DATA, IDLE, sv_cover);
  71. fsm_covadd_illegal ("ILLEGAL", sv_cover);
  72. fsm_covcollect (s_reset_n, s_clk, s_fsm_state, sv_cover);
  73. FinishP : process is
  74. begin
  75. wait until s_clk'active;
  76. if (sv_cover.IsCovered) then
  77. Log("FSM full covered :)", ALWAYS);
  78. sv_cover.SetName("FSM state coverage report");
  79. sv_cover.WriteBin;
  80. stop(0);
  81. end if;
  82. end process FinishP;
  83. -- psl default clock is rising_edge(s_clk);
  84. -- psl IDLE_ADDR : assert always (s_fsm_state = IDLE and s_reset_n = '1') -> next (s_fsm_state = ADDR) abort not(s_reset_n)
  85. -- report "FSM error: IDLE should be followed by ADDR state";
  86. -- psl ADDR_DATA : assert always (s_fsm_state = ADDR and s_reset_n = '1') -> next (s_fsm_state = DATA) abort not(s_reset_n);
  87. -- report "FSM error: ADDR should be followed by DATA state";
  88. -- psl DATA_IDLE : assert always (s_fsm_state = DATA and s_reset_n = '1') -> next (s_fsm_state = IDLE) abort not(s_reset_n);
  89. -- report "FSM error: DATA should be followed by IDLE state";
  90. end architecture sim;