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.

152 lines
4.9 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. --+ including vhdl 2008 libraries
  4. --+ These lines can be commented out when using
  5. --+ a simulator with built-in VHDL 2008 support
  6. --library ieee_proposed;
  7. -- use ieee_proposed.standard_additions.all;
  8. -- use ieee_proposed.std_logic_1164_additions.all;
  9. library libvhdl;
  10. use libvhdl.AssertP.all;
  11. package SimP is
  12. procedure wait_cycles (signal clk : in std_logic; n : in natural);
  13. procedure spi_master ( data_in : in std_logic_vector; data_out : out std_logic_vector;
  14. signal sclk : inout std_logic; signal ste : out std_logic;
  15. signal mosi : out std_logic; signal miso : in std_logic;
  16. dir : in natural range 0 to 1; cpol : in natural range 0 to 1;
  17. cpha : in natural range 0 to 1; period : in time);
  18. procedure spi_slave ( data_in : in std_logic_vector; data_out : out std_logic_vector;
  19. signal sclk : in std_logic; signal ste : in std_logic;
  20. signal mosi : in std_logic; signal miso : out std_logic;
  21. dir : in natural range 0 to 1; cpol : in natural range 0 to 1;
  22. cpha : in natural range 0 to 1);
  23. end package SimP;
  24. package body SimP is
  25. -- wait for n rising edges on clk
  26. procedure wait_cycles (signal clk : in std_logic; n : in natural) is
  27. begin
  28. for i in 1 to n loop
  29. wait until rising_edge(clk);
  30. end loop;
  31. end procedure wait_cycles;
  32. -- configurable spi master which supports all combinations of cpol & cpha
  33. procedure spi_master ( data_in : in std_logic_vector; data_out : out std_logic_vector;
  34. signal sclk : inout std_logic; signal ste : out std_logic;
  35. signal mosi : out std_logic; signal miso : in std_logic;
  36. dir : in natural range 0 to 1; cpol : in natural range 0 to 1;
  37. cpha : in natural range 0 to 1; period : in time) is
  38. begin
  39. assert_equal(data_in'length, data_out'length, spi_master'simple_name & ": data_in & data_out must have same length!");
  40. sclk <= std_logic'val(cpol+2);
  41. ste <= '0';
  42. if (cpha = 0) then
  43. for i in data_in'range loop
  44. if (dir = 0) then
  45. mosi <= data_in(data_in'high - i);
  46. else
  47. mosi <= data_in(i);
  48. end if;
  49. wait for period/2;
  50. sclk <= not(sclk);
  51. if (dir = 0) then
  52. data_out(data_out'high - i) := miso;
  53. else
  54. data_out(i) := miso;
  55. end if;
  56. wait for period/2;
  57. sclk <= not(sclk);
  58. end loop;
  59. wait for period/2;
  60. else
  61. mosi <= '1';
  62. wait for period/2;
  63. for i in data_in'range loop
  64. sclk <= not(sclk);
  65. if (dir = 0) then
  66. mosi <= data_in(data_in'high - i);
  67. else
  68. mosi <= data_in(i);
  69. end if;
  70. wait for period/2;
  71. sclk <= not(sclk);
  72. if (dir = 0) then
  73. data_out(data_out'high - i) := miso;
  74. else
  75. data_out(i) := miso;
  76. end if;
  77. wait for period/2;
  78. end loop;
  79. end if;
  80. ste <= '1';
  81. mosi <= '1';
  82. wait for period/2;
  83. end procedure spi_master;
  84. -- configurable spi slave which supports all combinations of cpol & cpha
  85. procedure spi_slave ( data_in : in std_logic_vector; data_out : out std_logic_vector;
  86. signal sclk : in std_logic; signal ste : in std_logic;
  87. signal mosi : in std_logic; signal miso : out std_logic;
  88. dir : in natural range 0 to 1; cpol : in natural range 0 to 1;
  89. cpha : in natural range 0 to 1) is
  90. variable v_cpol : std_logic := std_logic'val(cpol+2);
  91. begin
  92. assert_equal(data_in'length, data_out'length, spi_slave'simple_name & ": data_in & data_out must have same length!");
  93. miso <= 'Z';
  94. wait until ste = '0';
  95. if (cpha = 0) then
  96. for i in data_in'range loop
  97. if (dir = 0) then
  98. miso <= data_in(data_in'high - i);
  99. else
  100. miso <= data_in(i);
  101. end if;
  102. wait until sclk'event and sclk = not(v_cpol);
  103. if (dir = 0) then
  104. data_out(data_out'high - i) := mosi;
  105. else
  106. data_out(i) := mosi;
  107. end if;
  108. wait until sclk'event and sclk = v_cpol;
  109. end loop;
  110. else
  111. for i in data_in'range loop
  112. wait until sclk'event and sclk = not(v_cpol);
  113. if (dir = 0) then
  114. miso <= data_in(data_in'high - i);
  115. else
  116. miso <= data_in(i);
  117. end if;
  118. wait until sclk'event and sclk = v_cpol;
  119. if (dir = 0) then
  120. data_out(data_out'high - i) := mosi;
  121. else
  122. data_out(i) := mosi;
  123. end if;
  124. end loop;
  125. end if;
  126. wait until ste = '1';
  127. miso <= 'Z';
  128. end procedure spi_slave;
  129. end package body SimP;