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.

168 lines
5.5 KiB

  1. -- Copyright (c) 2014 - 2022 by Torsten Meissner
  2. --
  3. -- Licensed under the Apache License, Version 2.0 (the "License");
  4. -- you may not use this file except in compliance with the License.
  5. -- You may obtain a copy of the License at
  6. --
  7. -- https://www.apache.org/licenses/LICENSE-2.0
  8. --
  9. -- Unless required by applicable law or agreed to in writing, software
  10. -- distributed under the License is distributed on an "AS IS" BASIS,
  11. -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. -- See the License for the specific language governing permissions and
  13. -- limitations under the License.
  14. library ieee;
  15. use ieee.std_logic_1164.all;
  16. --+ including vhdl 2008 libraries
  17. --+ These lines can be commented out when using
  18. --+ a simulator with built-in VHDL 2008 support
  19. --library ieee_proposed;
  20. -- use ieee_proposed.standard_additions.all;
  21. -- use ieee_proposed.std_logic_1164_additions.all;
  22. library libvhdl;
  23. use libvhdl.AssertP.all;
  24. package SimP is
  25. procedure wait_cycles (signal clk : in std_logic; n : in natural);
  26. procedure spi_master ( data_in : in std_logic_vector; data_out : out std_logic_vector;
  27. signal sclk : inout std_logic; signal ste : out std_logic;
  28. signal mosi : out std_logic; signal miso : in std_logic;
  29. dir : in natural range 0 to 1; cpol : in natural range 0 to 1;
  30. cpha : in natural range 0 to 1; period : in time);
  31. procedure spi_slave ( data_in : in std_logic_vector; data_out : out std_logic_vector;
  32. signal sclk : in std_logic; signal ste : in std_logic;
  33. signal mosi : in std_logic; signal miso : out std_logic;
  34. dir : in natural range 0 to 1; cpol : in natural range 0 to 1;
  35. cpha : in natural range 0 to 1);
  36. end package SimP;
  37. package body SimP is
  38. -- wait for n rising edges on clk
  39. procedure wait_cycles (signal clk : in std_logic; n : in natural) is
  40. begin
  41. for i in 1 to n loop
  42. wait until rising_edge(clk);
  43. end loop;
  44. end procedure wait_cycles;
  45. -- configurable spi master which supports all combinations of cpol & cpha
  46. procedure spi_master ( data_in : in std_logic_vector; data_out : out std_logic_vector;
  47. signal sclk : inout std_logic; signal ste : out std_logic;
  48. signal mosi : out std_logic; signal miso : in std_logic;
  49. dir : in natural range 0 to 1; cpol : in natural range 0 to 1;
  50. cpha : in natural range 0 to 1; period : in time) is
  51. begin
  52. assert_equal(data_in'length, data_out'length, spi_master'simple_name & ": data_in & data_out must have same length!");
  53. sclk <= std_logic'val(cpol+2);
  54. ste <= '0';
  55. if (cpha = 0) then
  56. for i in data_in'range loop
  57. if (dir = 0) then
  58. mosi <= data_in(data_in'high - i);
  59. else
  60. mosi <= data_in(i);
  61. end if;
  62. wait for period/2;
  63. sclk <= not(sclk);
  64. if (dir = 0) then
  65. data_out(data_out'high - i) := miso;
  66. else
  67. data_out(i) := miso;
  68. end if;
  69. wait for period/2;
  70. sclk <= not(sclk);
  71. end loop;
  72. wait for period/2;
  73. else
  74. mosi <= '1';
  75. wait for period/2;
  76. for i in data_in'range loop
  77. sclk <= not(sclk);
  78. if (dir = 0) then
  79. mosi <= data_in(data_in'high - i);
  80. else
  81. mosi <= data_in(i);
  82. end if;
  83. wait for period/2;
  84. sclk <= not(sclk);
  85. if (dir = 0) then
  86. data_out(data_out'high - i) := miso;
  87. else
  88. data_out(i) := miso;
  89. end if;
  90. wait for period/2;
  91. end loop;
  92. end if;
  93. ste <= '1';
  94. mosi <= '1';
  95. wait for period/2;
  96. end procedure spi_master;
  97. -- configurable spi slave which supports all combinations of cpol & cpha
  98. procedure spi_slave ( data_in : in std_logic_vector; data_out : out std_logic_vector;
  99. signal sclk : in std_logic; signal ste : in std_logic;
  100. signal mosi : in std_logic; signal miso : out std_logic;
  101. dir : in natural range 0 to 1; cpol : in natural range 0 to 1;
  102. cpha : in natural range 0 to 1) is
  103. variable v_cpol : std_logic := std_logic'val(cpol+2);
  104. begin
  105. assert_equal(data_in'length, data_out'length, spi_slave'simple_name & ": data_in & data_out must have same length!");
  106. miso <= 'Z';
  107. wait until ste = '0';
  108. if (cpha = 0) then
  109. for i in data_in'range loop
  110. if (dir = 0) then
  111. miso <= data_in(data_in'high - i);
  112. else
  113. miso <= data_in(i);
  114. end if;
  115. wait until sclk'event and sclk = not(v_cpol);
  116. if (dir = 0) then
  117. data_out(data_out'high - i) := mosi;
  118. else
  119. data_out(i) := mosi;
  120. end if;
  121. wait until sclk'event and sclk = v_cpol;
  122. end loop;
  123. else
  124. for i in data_in'range loop
  125. wait until sclk'event and sclk = not(v_cpol);
  126. if (dir = 0) then
  127. miso <= data_in(data_in'high - i);
  128. else
  129. miso <= data_in(i);
  130. end if;
  131. wait until sclk'event and sclk = v_cpol;
  132. if (dir = 0) then
  133. data_out(data_out'high - i) := mosi;
  134. else
  135. data_out(i) := mosi;
  136. end if;
  137. end loop;
  138. end if;
  139. wait until ste = '1';
  140. miso <= 'Z';
  141. end procedure spi_slave;
  142. end package body SimP;