Library of reusable VHDL components
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.

146 lines
4.2 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. library osvvm;
  5. use osvvm.RandomPkg.all;
  6. library libvhdl;
  7. use libvhdl.AssertP.all;
  8. use libvhdl.SimP.all;
  9. use libvhdl.UtilsP.all;
  10. entity SimT is
  11. end entity SimT;
  12. architecture sim of SimT is
  13. --* testbench global clock period
  14. constant C_PERIOD : time := 5 ns;
  15. --* SPI data transfer data width
  16. constant C_DATA_WIDTH : natural := 8;
  17. signal s_tests_done : boolean_vector(0 to 1) := (others => false);
  18. signal s_clk : std_logic := '0';
  19. signal s_sclk : std_logic;
  20. signal s_ste : std_logic;
  21. signal s_mosi : std_logic;
  22. signal s_miso : std_logic;
  23. package SlvQueue is new libvhdl.QueueP
  24. generic map (
  25. QUEUE_TYPE => std_logic_vector(C_DATA_WIDTH-1 downto 0),
  26. MAX_LEN => 32,
  27. to_string => to_hstring
  28. );
  29. shared variable sv_mosi_queue : SlvQueue.t_list_queue;
  30. shared variable sv_miso_queue : SlvQueue.t_list_queue;
  31. begin
  32. s_clk <= not(s_clk) after C_PERIOD when not(and_reduce(s_tests_done)) else '0';
  33. QueueInitP : process is
  34. begin
  35. sv_mosi_queue.init(false);
  36. sv_miso_queue.init(false);
  37. wait;
  38. end process QueueInitP;
  39. SimTestP : process is
  40. variable v_time : time;
  41. begin
  42. wait until s_clk = '1';
  43. v_time := now;
  44. wait_cycles(s_clk, 10);
  45. assert (now - v_time) = C_PERIOD * 20
  46. severity failure;
  47. s_tests_done(0) <= true;
  48. report "INFO: wait_cycles() procedure tests finished successfully";
  49. wait;
  50. end process SimTestP;
  51. -- Unit test of spi master procedure, checks all combinations
  52. -- of cpol & cpha against spi slave procedure
  53. SpiMasterP : process is
  54. variable v_send_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0');
  55. variable v_receive_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0');
  56. variable v_queue_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0');
  57. variable v_random : RandomPType;
  58. begin
  59. v_random.InitSeed(v_random'instance_name);
  60. for direction in 0 to 1 loop
  61. for mode in 0 to 3 loop
  62. for i in 0 to 255 loop
  63. v_send_data := v_random.RandSlv(C_DATA_WIDTH);
  64. sv_mosi_queue.push(v_send_data);
  65. spi_master (data_in => v_send_data,
  66. data_out => v_receive_data,
  67. sclk => s_sclk,
  68. ste => s_ste,
  69. mosi => s_mosi,
  70. miso => s_miso,
  71. dir => direction,
  72. cpol => mode / 2,
  73. cpha => mode mod 2,
  74. period => 1 us
  75. );
  76. sv_miso_queue.pop(v_queue_data);
  77. assert_equal(v_receive_data, v_queue_data);
  78. end loop;
  79. end loop;
  80. end loop;
  81. wait;
  82. end process SpiMasterP;
  83. -- Unit test of spi slave procedure, checks all combinations
  84. -- of cpol & cpha against spi master procedure
  85. SpiSlaveP : process is
  86. variable v_send_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0');
  87. variable v_receive_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0');
  88. variable v_queue_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0');
  89. variable v_random : RandomPType;
  90. begin
  91. v_random.InitSeed(v_random'instance_name);
  92. for direction in 0 to 1 loop
  93. for mode in 0 to 3 loop
  94. for i in 0 to 255 loop
  95. v_send_data := v_random.RandSlv(C_DATA_WIDTH);
  96. sv_miso_queue.push(v_send_data);
  97. spi_slave (data_in => v_send_data,
  98. data_out => v_receive_data,
  99. sclk => s_sclk,
  100. ste => s_ste,
  101. mosi => s_mosi,
  102. miso => s_miso,
  103. dir => direction,
  104. cpol => mode / 2,
  105. cpha => mode mod 2
  106. );
  107. sv_mosi_queue.pop(v_queue_data);
  108. assert_equal(v_receive_data, v_queue_data);
  109. end loop;
  110. end loop;
  111. end loop;
  112. report "INFO: All tests of valid spi_master() & spi_slave() combinations finished successfully";
  113. s_tests_done(1) <= true;
  114. wait;
  115. end process SpiSlaveP;
  116. end architecture sim;