TB simulation error's

Status
Not open for further replies.

Kgonz

Newbie level 5
Joined
Mar 9, 2023
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
221
Hello, i am trying to learn how to implement an SPI Slave for work. this is the my first time writing any module so i decided to try to build a test bench around someones slave module i found online. i wrote the test bench but when i go to simulation i get a bunch of signals showing U and im not sure why i also receive a warning coming from the test bench. im not really sure what the problem is any help is appreciated Ive attached all relevant information below.

SPI SLAVE

  1. --------------------------------------------------------------------------------
  2. -- PROJECT: SPI SLAVE FOR FPGA
  3. --------------------------------------------------------------------------------
  4. -- AUTHORS: Jakub Cabal <jakubcabal@gmail.com>
  5. -- LICENSE: The MIT License, please read LICENSE file
  6. -- WEBSITE: https://github.com/jakubcabal/spi-fpga
  7. --------------------------------------------------------------------------------

  8. library IEEE;
  9. use IEEE.STD_LOGIC_1164.ALL;
  10. use IEEE.NUMERIC_STD.ALL;
  11. use IEEE.MATH_REAL.ALL;

  12. -- THE SPI SLAVE MODULE SUPPORT ONLY SPI MODE 0 (CPOL=0, CPHA=0)!!!

  13. entity SPI_SLAVE1 is
  14. Generic (
  15. WORD_SIZE : natural := 8 -- size of transfer word in bits, must be power of two
  16. );
  17. Port (
  18. CLK : in std_logic; -- system clock
  19. RST : in std_logic; -- high active synchronous reset
  20. -- SPI SLAVE INTERFACE
  21. SCLK : in std_logic; -- SPI clock
  22. CS_N : in std_logic; -- SPI chip select, active in low
  23. MOSI : in std_logic; -- SPI serial data from master to slave
  24. MISO : out std_logic; -- SPI serial data from slave to master
  25. -- USER INTERFACE
  26. DIN : in std_logic_vector(WORD_SIZE-1 downto 0); -- data for transmission to SPI master
  27. DIN_VLD : in std_logic; -- when DIN_VLD = 1, data for transmission are valid
  28. DIN_RDY : out std_logic; -- when DIN_RDY = 1, SPI slave is ready to accept valid data for transmission
  29. DOUT : out std_logic_vector(WORD_SIZE-1 downto 0); -- received data from SPI master
  30. DOUT_VLD : out std_logic -- when DOUT_VLD = 1, received data are valid
  31. );
  32. end entity;

  33. architecture RTL of SPI_SLAVE1 is

  34. constant BIT_CNT_WIDTH : natural := natural(ceil(log2(real(WORD_SIZE))));

  35. signal sclk_meta : std_logic;
  36. signal cs_n_meta : std_logic;
  37. signal mosi_meta : std_logic;
  38. signal sclk_reg : std_logic;
  39. signal cs_n_reg : std_logic;
  40. signal mosi_reg : std_logic;
  41. signal spi_clk_reg : std_logic;
  42. signal spi_clk_redge_en : std_logic;
  43. signal spi_clk_fedge_en : std_logic;
  44. signal bit_cnt : unsigned(BIT_CNT_WIDTH-1 downto 0);
  45. signal bit_cnt_max : std_logic;
  46. signal last_bit_en : std_logic;
  47. signal load_data_en : std_logic;
  48. signal data_shreg : std_logic_vector(WORD_SIZE-1 downto 0);
  49. signal slave_ready : std_logic;
  50. signal shreg_busy : std_logic;
  51. signal rx_data_vld : std_logic;

  52. begin

  53. -- -------------------------------------------------------------------------
  54. -- INPUT SYNCHRONIZATION REGISTERS
  55. -- -------------------------------------------------------------------------

  56. -- Synchronization registers to eliminate possible metastability.
  57. sync_ffs_p : process (CLK)
  58. begin
  59. if (rising_edge(CLK)) then
  60. sclk_meta <= SCLK;
  61. cs_n_meta <= CS_N;
  62. mosi_meta <= MOSI;
  63. sclk_reg <= sclk_meta;
  64. cs_n_reg <= cs_n_meta;
  65. mosi_reg <= mosi_meta;
  66. end if;
  67. end process;

  68. -- -------------------------------------------------------------------------
  69. -- SPI CLOCK REGISTER
  70. -- -------------------------------------------------------------------------

  71. -- The SPI clock register is necessary for clock edge detection.
  72. spi_clk_reg_p : process (CLK)
  73. begin
  74. if (rising_edge(CLK)) then
  75. if (RST = '1') then
  76. spi_clk_reg <= '0';
  77. else
  78. spi_clk_reg <= sclk_reg;
  79. end if;
  80. end if;
  81. end process;

  82. -- -------------------------------------------------------------------------
  83. -- SPI CLOCK EDGES FLAGS
  84. -- -------------------------------------------------------------------------

  85. -- Falling edge is detect when sclk_reg=0 and spi_clk_reg=1.
  86. spi_clk_fedge_en <= not sclk_reg and spi_clk_reg;
  87. -- Rising edge is detect when sclk_reg=1 and spi_clk_reg=0.
  88. spi_clk_redge_en <= sclk_reg and not spi_clk_reg;

  89. -- -------------------------------------------------------------------------
  90. -- RECEIVED BITS COUNTER
  91. -- -------------------------------------------------------------------------

  92. -- The counter counts received bits from the master. Counter is enabled when
  93. -- falling edge of SPI clock is detected and not asserted cs_n_reg.
  94. bit_cnt_p : process (CLK)
  95. begin
  96. if (rising_edge(CLK)) then
  97. if (RST = '1') then
  98. bit_cnt <= (others => '0');
  99. elsif (spi_clk_fedge_en = '1' and cs_n_reg = '0') then
  100. if (bit_cnt_max = '1') then
  101. bit_cnt <= (others => '0');
  102. else
  103. bit_cnt <= bit_cnt + 1;
  104. end if;
  105. end if;
  106. end if;
  107. end process;

  108. -- The flag of maximal value of the bit counter.
  109. bit_cnt_max <= '1' when (bit_cnt = WORD_SIZE-1) else '0';

  110. -- -------------------------------------------------------------------------
  111. -- LAST BIT FLAG REGISTER
  112. -- -------------------------------------------------------------------------

  113. -- The flag of last bit of received byte is only registered the flag of
  114. -- maximal value of the bit counter.
  115. last_bit_en_p : process (CLK)
  116. begin
  117. if (rising_edge(CLK)) then
  118. if (RST = '1') then
  119. last_bit_en <= '0';
  120. else
  121. last_bit_en <= bit_cnt_max;
  122. end if;
  123. end if;
  124. end process;

  125. -- -------------------------------------------------------------------------
  126. -- RECEIVED DATA VALID FLAG
  127. -- -------------------------------------------------------------------------

  128. -- Received data from master are valid when falling edge of SPI clock is
  129. -- detected and the last bit of received byte is detected.
  130. rx_data_vld <= spi_clk_fedge_en and last_bit_en;

  131. -- -------------------------------------------------------------------------
  132. -- SHIFT REGISTER BUSY FLAG REGISTER
  133. -- -------------------------------------------------------------------------

  134. -- Data shift register is busy until it sends all input data to SPI master.
  135. shreg_busy_p : process (CLK)
  136. begin
  137. if (rising_edge(CLK)) then
  138. if (RST = '1') then
  139. shreg_busy <= '0';
  140. else
  141. if (DIN_VLD = '1' and (cs_n_reg = '1' or rx_data_vld = '1')) then
  142. shreg_busy <= '1';
  143. elsif (rx_data_vld = '1') then
  144. shreg_busy <= '0';
  145. else
  146. shreg_busy <= shreg_busy;
  147. end if;
  148. end if;
  149. end if;
  150. end process;

  151. -- The SPI slave is ready for accept new input data when cs_n_reg is assert and
  152. -- shift register not busy or when received data are valid.
  153. slave_ready <= (cs_n_reg and not shreg_busy) or rx_data_vld;
  154. -- The new input data is loaded into the shift register when the SPI slave
  155. -- is ready and input data are valid.
  156. load_data_en <= slave_ready and DIN_VLD;

  157. -- -------------------------------------------------------------------------
  158. -- DATA SHIFT REGISTER
  159. -- -------------------------------------------------------------------------

  160. -- The shift register holds data for sending to master, capture and store
  161. -- incoming data from master.
  162. data_shreg_p : process (CLK)
  163. begin
  164. if (rising_edge(CLK)) then
  165. if (load_data_en = '1') then
  166. data_shreg <= DIN;
  167. elsif (spi_clk_redge_en = '1' and cs_n_reg = '0') then
  168. data_shreg <= data_shreg(WORD_SIZE-2 downto 0) & mosi_reg;
  169. end if;
  170. end if;
  171. end process;

  172. -- -------------------------------------------------------------------------
  173. -- MISO REGISTER
  174. -- -------------------------------------------------------------------------

  175. -- The output MISO register ensures that the bits are transmit to the master
  176. -- when is not assert cs_n_reg and falling edge of SPI clock is detected.
  177. miso_p : process (CLK)
  178. begin
  179. if (rising_edge(CLK)) then
  180. if (load_data_en = '1') then
  181. MISO <= DIN(WORD_SIZE-1);
  182. elsif (spi_clk_fedge_en = '1' and cs_n_reg = '0') then
  183. MISO <= data_shreg(WORD_SIZE-1);
  184. end if;
  185. end if;
  186. end process;

  187. -- -------------------------------------------------------------------------
  188. -- ASSIGNING OUTPUT SIGNALS
  189. -- -------------------------------------------------------------------------
  190. DIN_RDY <= slave_ready;
  191. DOUT <= data_shreg;
  192. DOUT_VLD <= rx_data_vld;

  193. end architecture;
TB for SPI SLAVE

  1. library IEEE;
  2. use IEEE.std_logic_1164.all;
  3. use IEEE.numeric_std.all;
  4. use IEEE.MATH_REAL.ALL;

  5. entity Spi_practice2_tb is
  6. end Spi_practice2_tb;

  7. architecture bench of Spi_practice2_tb is

  8. constant WORD_SIZE : integer := 8;
  9. constant clock_period: time := 10 ns;
  10. constant BIT_CNT_WIDTH : natural:= natural(ceil(log2(real(WORD_SIZE))));

  11. component SPI_SLAVE1
  12. port(
  13. CLK,RST,SCLK,CS_N,MOSI,DIN_VLD: in std_logic;
  14. MISO,DIN_RDY,DOUT_VLD: out std_logic;
  15. DIN: in std_logic_vector(WORD_SIZE-1 downto 0);
  16. DOUT: out std_logic_vector(WORD_SIZE-1 downto 0)
  17. );
  18. end component;

  19. signal CLK,RST,SCLK,CS_N,MOSI,DIN_VLD: std_logic;
  20. signal MISO,DIN_RDY,DOUT_VLD: std_logic;
  21. signal DIN: std_logic_vector(WORD_SIZE-1 downto 0);
  22. signal DOUT: std_logic_vector(WORD_SIZE-1 downto 0);
  23. signal stop_the_clock:boolean;


  24. signal sclk_meta : std_logic;
  25. signal cs_n_meta : std_logic;
  26. signal mosi_meta : std_logic;
  27. signal sclk_reg : std_logic;
  28. signal cs_n_reg : std_logic;
  29. signal mosi_reg : std_logic;
  30. signal spi_clk_reg : std_logic;
  31. signal spi_clk_redge_en : std_logic;
  32. signal spi_clk_fedge_en : std_logic;
  33. signal bit_cnt : unsigned(BIT_CNT_WIDTH-1 downto 0);
  34. signal bit_cnt_max : std_logic;
  35. signal last_bit_en : std_logic;
  36. signal load_data_en : std_logic;
  37. signal data_shreg : std_logic_vector(WORD_SIZE-1 downto 0);
  38. signal slave_ready : std_logic;
  39. signal shreg_busy : std_logic;
  40. signal rx_data_vld : std_logic;


  41. begin
  42. PM: entity work.SPI_SLAVE1
  43. port map (CLK => CLK,
  44. RST => RST,
  45. SCLK => SCLK,
  46. CS_N => CS_N,
  47. MOSI => MOSI,
  48. DIN => DIN,
  49. DIN_VLD => DIN_VLD,
  50. MISO => MISO,
  51. DIN_RDY => DIN_RDY,
  52. DOUT => DOUT,
  53. DOUT_VLD => DOUT_VLD);

  54. process
  55. begin
  56. RST <= '1';
  57. RST <= '0';
  58. wait for clock_period;
  59. spi_clk_fedge_en <= '1';
  60. cs_n_reg <= '0';
  61. wait for clock_period;
  62. DIN_VLD <= '1';
  63. cs_n_reg <= '1';
  64. rx_data_vld <= '1';
  65. wait;
  66. end process;

  67. process -- clock generation
  68. begin
  69. while not stop_the_clock loop
  70. CLK <= '0';
  71. wait for clock_period / 2;
  72. CLK <= '1';
  73. wait for clock_period / 2;
  74. end loop;
  75. wait;


  76. end process;
  77. end;
 

Attachments

  • Screenshot 2023-04-04 083755.png
    11.4 KB · Views: 86
  • Screenshot 2023-04-04 083918.png
    261.5 KB · Views: 90

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…