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.

277 lines
8.9 KiB

  1. -- Simple wishbone verification IP
  2. -- For use with GHDL only
  3. -- Suitable for simulation & formal verification
  4. -- Copyright 2021 by Torsten Meissner (programming@goodcleanfun.de)
  5. library ieee;
  6. use ieee.std_logic_1164.all;
  7. use ieee.numeric_std.all;
  8. library wishbone;
  9. use wishbone.wishbone_pkg.all;
  10. entity wishbone_vip is
  11. generic (
  12. MODE : string := "CLASSIC";
  13. ASSERTS : boolean := true;
  14. COVERAGE : boolean := true
  15. );
  16. port (
  17. -- syscon signals
  18. WbSysCon : in t_wb_syscon;
  19. -- master signals
  20. WbMaster : in t_wb_master;
  21. -- slave signals
  22. WbSlave : in t_wb_slave
  23. );
  24. end entity wishbone_vip;
  25. architecture verification of wishbone_vip is
  26. function count_ones (data : in std_logic_vector) return natural is
  27. variable v_return : natural := 0;
  28. begin
  29. for i in data'range loop
  30. if (to_x01(data(i)) = '1') then
  31. v_return := v_return + 1;
  32. end if;
  33. end loop;
  34. return v_return;
  35. end function count_ones;
  36. function one_hot (data : in std_logic_vector) return boolean is
  37. begin
  38. return count_ones(data) = 1;
  39. end function one_hot;
  40. function one_hot_0 (data : in std_logic_vector) return boolean is
  41. begin
  42. return count_ones(data) <= 1;
  43. end function one_hot_0;
  44. alias Clk is WbSysCon.Clk;
  45. alias Reset is WbSysCon.Reset;
  46. signal s_wb_slave_resp : std_logic_vector(2 downto 0);
  47. begin
  48. s_wb_slave_resp <= WbSlave.Rty & WbSlave.Err & WbSlave.Ack;
  49. -- Static interface checks
  50. -- Always enabled, regardless of generic ASSERTS setting
  51. MODE_a : assert MODE = "CLASSIC"
  52. report "ERROR: Unsupported mode"
  53. severity failure;
  54. DATA_MS_WIDTH_a : assert WbMaster.Dat'length = 8 or WbMaster.Dat'length = 16 or
  55. WbMaster.Dat'length = 32 or WbMaster.Dat'length = 64
  56. report "ERROR: Invalid Master Data length"
  57. severity failure;
  58. DATA_SM_WIDTH_a : assert WbSlave.Dat'length = 8 or WbSlave.Dat'length = 16 or
  59. WbSlave.Dat'length = 32 or WbSlave.Dat'length = 64
  60. report "ERROR: Invalid Slave Data length"
  61. severity failure;
  62. DATA_EQUAL_WIDTH_a : assert WbMaster.Dat'length = WbSlave.Dat'length
  63. report "ERROR: Master & Slave Data don't have equal length"
  64. severity failure;
  65. default clock is rising_edge(Clk);
  66. ASSERTS_G : if ASSERTS generate
  67. signal s_wb_master : t_wb_master(Adr(WbMaster.Adr'range),
  68. Dat(WbMaster.Dat'range),
  69. Sel(WbMaster.Sel'range),
  70. Tgc(WbMaster.Tgc'range),
  71. Tga(WbMaster.Tga'range),
  72. Tgd(WbMaster.Tgd'range));
  73. signal s_wb_slave : t_wb_slave(Dat(WbSlave.Dat'range),
  74. Tgd(WbSlave.Tgd'range));
  75. begin
  76. -- Create copies of bus signals
  77. process (Clk) is
  78. begin
  79. if rising_edge(Clk) then
  80. s_wb_master <= WbMaster;
  81. s_wb_slave <= WbSlave;
  82. end if;
  83. end process;
  84. sequence s_stb_not_term is {WbMaster.Stb = '1' and s_wb_slave_resp = "000"};
  85. -- RULE 3.20
  86. -- Synchonous reset
  87. STB_RESET_a : assert always Reset -> next not WbMaster.Stb;
  88. CYC_RESET_a : assert always Reset -> next not WbMaster.Cyc;
  89. -- RULE 3.25
  90. STB_CYC_0_a : assert always WbMaster.Stb -> WbMaster.Cyc;
  91. STB_CYC_1_a : assert always WbMaster.Stb and not s_wb_master.Stb ->
  92. WbMaster.Cyc until not WbMaster.Stb;
  93. -- RULE 3.35
  94. ACK_ERR_RTY_CYC_STB_a : assert always one_hot(s_wb_slave_resp) ->
  95. s_wb_master.Cyc and s_wb_master.Stb;
  96. -- RULE 3.45
  97. ACK_ERR_RTY_ONEHOT_a : assert always one_hot_0(s_wb_slave_resp);
  98. -- RULE 3.50
  99. ACK_ERR_RTY_STB_a : assert always one_hot(s_wb_slave_resp) -> WbMaster.Stb;
  100. -- RULE 3.60
  101. ADR_STABLE_STB_a : assert always s_stb_not_term |=> WbMaster.Adr = s_wb_master.Adr;
  102. DAT_STABLE_STB_a : assert always s_stb_not_term |=> WbMaster.Dat = s_wb_master.Dat;
  103. SEL_STABLE_STB_a : assert always s_stb_not_term |=> WbMaster.Sel = s_wb_master.Sel;
  104. WE_STABLE_STB_a : assert always s_stb_not_term |=> WbMaster.We = s_wb_master.We;
  105. TGC_STABLE_STB_a : assert always s_stb_not_term |=> WbMaster.Tgc = s_wb_master.Tgc;
  106. TGA_STABLE_STB_a : assert always s_stb_not_term |=> WbMaster.Tga = s_wb_master.Tga;
  107. TGD_STABLE_STB_a : assert always s_stb_not_term |=> WbMaster.Tgd = s_wb_master.Tgd;
  108. end generate ASSERTS_G;
  109. COVERAGE_G : if COVERAGE generate
  110. CLASSIC_G : if MODE = "CLASSIC" generate
  111. -- Non waited single cycles, async slave termination or slave knows
  112. -- address in advance or it doesn't matter
  113. sequence s_single_read (boolean resp) is {
  114. not WbMaster.Cyc;
  115. WbMaster.Cyc and not WbMaster.Stb[*];
  116. {resp} &&
  117. {WbMaster.Cyc and WbMaster.Stb and not WbMaster.We}[+];
  118. not WbMaster.Cyc
  119. };
  120. sequence s_single_write (boolean resp) is {
  121. not WbMaster.Cyc;
  122. WbMaster.Cyc and not WbMaster.Stb[*];
  123. {resp} &&
  124. {WbMaster.Cyc and WbMaster.Stb and WbMaster.We}[+];
  125. not WbMaster.Cyc
  126. };
  127. SINGLE_READ_ACKED_c : cover s_single_read(WbSlave.Ack)
  128. report "Single read with ack finished";
  129. SINGLE_READ_ERROR_c : cover s_single_read(WbSlave.Err)
  130. report "Single read with error finished";
  131. SINGLE_READ_RETRY_c : cover s_single_read(WbSlave.Rty)
  132. report "Single read with retry finished";
  133. SINGLE_WRITE_ACKED_c : cover s_single_write(WbSlave.Ack)
  134. report "Single write with ack finished";
  135. SINGLE_WRITE_ERROR_c : cover s_single_write(WbSlave.Err)
  136. report "Single write with error finished";
  137. SINGLE_WRITE_RETRY_c : cover s_single_write(WbSlave.Rty)
  138. report "Single write with retry finished";
  139. -- Waited single cycles, slave termination at least one cycle after stb
  140. -- is asswerted
  141. sequence s_single_waited_read (boolean resp) is {
  142. not WbMaster.Cyc;
  143. WbMaster.Cyc and not WbMaster.Stb[*];
  144. {s_wb_slave_resp = "000"[+]; resp} &&
  145. {WbMaster.Cyc and WbMaster.Stb and not WbMaster.We}[+];
  146. not WbMaster.Cyc
  147. };
  148. sequence s_single_waited_write (boolean resp) is {
  149. not WbMaster.Cyc;
  150. WbMaster.Cyc and not WbMaster.Stb[*];
  151. {s_wb_slave_resp = "000"[+]; resp} &&
  152. {WbMaster.Cyc and WbMaster.Stb and WbMaster.We}[+];
  153. not WbMaster.Cyc
  154. };
  155. SINGLE_READ_WAITED_ACKED_c : cover s_single_waited_read(WbSlave.Ack)
  156. report "Single waited read with ack finished";
  157. SINGLE_READ_WAITED_ERROR_c : cover s_single_waited_read(WbSlave.Err)
  158. report "Single waited read with error finished";
  159. SINGLE_READ_WAITED_RETRY_c : cover s_single_waited_read(WbSlave.Rty)
  160. report "Single waited read with retry finished";
  161. SINGLE_WRITE_WAITED_ACKED_c : cover s_single_waited_write(WbSlave.Ack)
  162. report "Single waited write with ack finished";
  163. SINGLE_WRITE_WAITED_ERROR_c : cover s_single_waited_write(WbSlave.Err)
  164. report "Single waited write with error finished";
  165. SINGLE_WRITE_WAITED_RETRY_c : cover s_single_waited_write(WbSlave.Rty)
  166. report "Single waited write with retry finished";
  167. -- Block cycles, not distinguished between waited & non-waited
  168. -- We don't cover each possible combination of slave termination
  169. -- during block cycles, as there are a lot for longer block cycles
  170. sequence s_block_read (boolean resp) is {
  171. not WbMaster.Cyc;
  172. {WbMaster.Cyc and not WbMaster.Stb[*];
  173. {s_wb_slave_resp = "000"[*]; resp} &&
  174. {WbMaster.Cyc and WbMaster.Stb and not WbMaster.We}[+]}[*2 to inf];
  175. not WbMaster.Cyc
  176. };
  177. sequence s_block_write (boolean resp) is {
  178. not WbMaster.Cyc;
  179. {WbMaster.Cyc and not WbMaster.Stb[*];
  180. {s_wb_slave_resp = "000"[*]; resp} &&
  181. {WbMaster.Cyc and WbMaster.Stb and WbMaster.We}[+]}[*2 to inf];
  182. not WbMaster.Cyc
  183. };
  184. BLOCK_READ_ACKED_c : cover s_block_read(one_hot(s_wb_slave_resp))
  185. report "Block read finished";
  186. BLOCK_WRITE_ACKED_c : cover s_block_write(one_hot(s_wb_slave_resp))
  187. report "Block write finished";
  188. -- Read-modified-write cycles, not distinguished between waited & non-waited
  189. -- We don't cover each possible combination of slave termniation
  190. -- during read-modified-write cycles
  191. sequence s_rmw_read (boolean resp) is {
  192. not WbMaster.Cyc;
  193. {WbMaster.Cyc and not WbMaster.Stb[*];
  194. {s_wb_slave_resp = "000"[*]; resp} &&
  195. {WbMaster.Cyc and WbMaster.Stb and not WbMaster.We}[+]};
  196. {WbMaster.Cyc and not WbMaster.Stb[*];
  197. {s_wb_slave_resp = "000"[*]; resp} &&
  198. {WbMaster.Cyc and WbMaster.Stb and WbMaster.We}[+]};
  199. not WbMaster.Cyc
  200. };
  201. READ_MODIFIED_WRITE_ACKED_c : cover s_rmw_read(one_hot(s_wb_slave_resp))
  202. report "Read-modified-write finished";
  203. end generate CLASSIC_G;
  204. end generate COVERAGE_G;
  205. end architecture verification;