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.

153 lines
4.0 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. library libvhdl;
  5. use libvhdl.StringP.all;
  6. use libvhdl.AssertP.all;
  7. use libvhdl.SimP.all;
  8. entity SpiT is
  9. end entity SpiT;
  10. architecture sim of SpiT is
  11. component SpiSlaveE is
  12. generic (
  13. G_DATA_WIDTH : positive := 8;
  14. G_SPI_CPOL : natural range 0 to 1 := 0;
  15. G_SPI_CPHA : natural range 0 to 1 := 0
  16. );
  17. port (
  18. --+ system if
  19. Reset_n_i : in std_logic;
  20. Clk_i : in std_logic;
  21. --+ SPI slave if
  22. SpiSclk_i : in std_logic;
  23. SpiSte_i : in std_logic;
  24. SpiMosi_i : in std_logic;
  25. SpiMiso_o : out std_logic;
  26. --+ local VAI if
  27. Data_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
  28. DataValid_i : in std_logic;
  29. DataAccept_o : out std_logic;
  30. Data_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
  31. DataValid_o : out std_logic;
  32. DataAccept_i : in std_logic
  33. );
  34. end component SpiSlaveE;
  35. constant C_PERIOD : time := 5 ns;
  36. constant C_DATA_WIDTH : natural := 8;
  37. signal s_done : boolean := false;
  38. signal s_clk : std_logic := '0';
  39. signal s_reset_n : std_logic := '0';
  40. signal s_sclk : std_logic;
  41. signal s_ste : std_logic;
  42. signal s_mosi : std_logic;
  43. signal s_miso : std_logic;
  44. subtype t_spi_mode is natural range 0 to 3;
  45. signal s_spi_mode : t_spi_mode;
  46. begin
  47. s_clk <= not(s_clk) after C_PERIOD when not(s_done) else '0';
  48. s_reset_n <= '1' after 100 ns;
  49. -- Unit test of spi master procedure, checks all combinations
  50. -- of cpol & cpha against spi slave procedure
  51. SpiMasterP : process is
  52. variable v_slave_data : std_logic_vector(C_DATA_WIDTH-1 downto 0);
  53. begin
  54. s_sclk <= '1';
  55. s_ste <= '1';
  56. s_mosi <= '1';
  57. s_spi_mode <= 0;
  58. wait until s_reset_n = '1';
  59. for mode in 0 to 3 loop
  60. s_spi_mode <= mode;
  61. for i in 0 to integer'(2**C_DATA_WIDTH-1) loop
  62. spi_master (data_in => std_logic_vector(to_unsigned(i, C_DATA_WIDTH)),
  63. data_out => v_slave_data,
  64. sclk => s_sclk,
  65. ste => s_ste,
  66. mosi => s_mosi,
  67. miso => s_miso,
  68. cpol => mode / 2,
  69. cpha => mode mod 2,
  70. period => 1 us
  71. );
  72. assert_equal(v_slave_data, std_logic_vector(to_unsigned(i, C_DATA_WIDTH)));
  73. end loop;
  74. report "INFO: SPI mode " & integer'image(mode) & " test successfully";
  75. end loop;
  76. report "INFO: SpiSlaveE tests finished successfully";
  77. s_done <= true;
  78. wait;
  79. end process SpiMasterP;
  80. --+ spi ste demultiplexing
  81. SpiSlavesG : for mode in t_spi_mode'low to t_spi_mode'high generate
  82. subtype t_control_array is std_logic_vector(t_spi_mode'low to t_spi_mode'high);
  83. signal s_spislave_ste : t_control_array;
  84. type t_data_array is array (t_spi_mode'low to t_spi_mode'high) of std_logic_vector(C_DATA_WIDTH-1 downto 0);
  85. signal s_din : t_data_array;
  86. signal s_dout : t_data_array;
  87. signal s_dout_valid : t_control_array;
  88. signal s_dout_accept : t_control_array;
  89. begin
  90. s_din(mode) <= std_logic_vector(unsigned(s_dout(mode)) + 1);
  91. s_spislave_ste(mode) <= s_ste when s_spi_mode = mode else '1';
  92. i0_SpiSlaveE : SpiSlaveE
  93. generic map (
  94. G_DATA_WIDTH => 8,
  95. G_SPI_CPOL => mode / 2,
  96. G_SPI_CPHA => mode mod 2
  97. )
  98. port map (
  99. --+ system if
  100. Reset_n_i => s_reset_n,
  101. Clk_i => s_clk,
  102. --+ SPI slave if
  103. SpiSclk_i => s_sclk,
  104. SpiSte_i => s_spislave_ste(mode),
  105. SpiMosi_i => s_mosi,
  106. SpiMiso_o => s_miso,
  107. --+ local VAI if
  108. Data_i => s_din(mode),
  109. DataValid_i => s_dout_valid(mode),
  110. DataAccept_o => s_dout_accept(mode),
  111. Data_o => s_dout(mode),
  112. DataValid_o => s_dout_valid(mode),
  113. DataAccept_i => s_dout_accept(mode)
  114. );
  115. end generate SpiSlavesG;
  116. end architecture sim;