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.

258 lines
8.7 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. --+ including vhdl 2008 libraries
  5. --+ These lines can be commented out when using
  6. --+ a simulator with built-in VHDL 2008 support
  7. library ieee_proposed;
  8. use ieee_proposed.standard_additions.all;
  9. use ieee_proposed.std_logic_1164_additions.all;
  10. use ieee_proposed.numeric_std_additions.all;
  11. library osvvm;
  12. use osvvm.RandomPkg.all;
  13. library libvhdl;
  14. use libvhdl.AssertP.all;
  15. use libvhdl.SimP.all;
  16. use libvhdl.QueueP.all;
  17. entity WishBoneT is
  18. end entity WishBoneT;
  19. architecture sim of WishBoneT is
  20. component WishBoneMasterE is
  21. generic (
  22. G_ADR_WIDTH : positive := 8; --* address bus width
  23. G_DATA_WIDTH : positive := 8 --* data bus width
  24. );
  25. port (
  26. --+ wishbone system if
  27. WbRst_i : in std_logic;
  28. WbClk_i : in std_logic;
  29. --+ wishbone outputs
  30. WbCyc_o : out std_logic;
  31. WbStb_o : out std_logic;
  32. WbWe_o : out std_logic;
  33. WbAdr_o : out std_logic_vector(G_ADR_WIDTH-1 downto 0);
  34. WbDat_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
  35. --+ wishbone inputs
  36. WbDat_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
  37. WbAck_i : in std_logic;
  38. WbErr_i : in std_logic;
  39. --+ local register if
  40. LocalWen_i : in std_logic;
  41. LocalRen_i : in std_logic;
  42. LocalAdress_i : in std_logic_vector(G_ADR_WIDTH-1 downto 0);
  43. LocalData_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
  44. LocalData_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
  45. LocalAck_o : out std_logic;
  46. LocalError_o : out std_logic
  47. );
  48. end component WishBoneMasterE;
  49. component WishBoneSlaveE is
  50. generic (
  51. G_ADR_WIDTH : positive := 8; --* address bus width
  52. G_DATA_WIDTH : positive := 8 --* data bus width
  53. );
  54. port (
  55. --+ wishbone system if
  56. WbRst_i : in std_logic;
  57. WbClk_i : in std_logic;
  58. --+ wishbone inputs
  59. WbCyc_i : in std_logic;
  60. WbStb_i : in std_logic;
  61. WbWe_i : in std_logic;
  62. WbAdr_i : in std_logic_vector(G_ADR_WIDTH-1 downto 0);
  63. WbDat_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
  64. --* wishbone outputs
  65. WbDat_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
  66. WbAck_o : out std_logic;
  67. WbErr_o : out std_logic;
  68. --+ local register if
  69. LocalWen_o : out std_logic;
  70. LocalRen_o : out std_logic;
  71. LocalAdress_o : out std_logic_vector(G_ADR_WIDTH-1 downto 0);
  72. LocalData_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
  73. LocalData_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0)
  74. );
  75. end component WishBoneSlaveE;
  76. --* testbench global clock period
  77. constant C_PERIOD : time := 5 ns;
  78. --* Wishbone data width
  79. constant C_DATA_WIDTH : natural := 8;
  80. --* Wishbone address width
  81. constant C_ADDRESS_WIDTH : natural := 8;
  82. --* testbench global clock
  83. signal s_wb_clk : std_logic := '1';
  84. --* testbench global reset
  85. signal s_wb_reset : std_logic := '1';
  86. --+ test done array with entry for each test
  87. signal s_test_done : boolean;
  88. signal s_wb_cyc : std_logic;
  89. signal s_wb_stb : std_logic;
  90. signal s_wb_we : std_logic;
  91. signal s_wb_adr : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
  92. signal s_wb_master_data : std_logic_vector(C_DATA_WIDTH-1 downto 0);
  93. signal s_wb_slave_data : std_logic_vector(C_DATA_WIDTH-1 downto 0);
  94. signal s_wb_ack : std_logic;
  95. signal s_wb_err : std_logic;
  96. signal s_master_local_wen : std_logic;
  97. signal s_master_local_ren : std_logic;
  98. signal s_master_local_adress : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
  99. signal s_master_local_din : std_logic_vector(C_DATA_WIDTH-1 downto 0);
  100. signal s_master_local_dout : std_logic_vector(C_DATA_WIDTH-1 downto 0);
  101. signal s_master_local_ack : std_logic;
  102. signal s_master_local_error : std_logic;
  103. signal s_slave_local_wen : std_logic;
  104. signal s_slave_local_ren : std_logic;
  105. signal s_slave_local_adress : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
  106. signal s_slave_local_dout : std_logic_vector(C_DATA_WIDTH-1 downto 0);
  107. signal s_slave_local_din : std_logic_vector(C_DATA_WIDTH-1 downto 0);
  108. type t_register is array (0 to integer'(2**C_ADDRESS_WIDTH-1)) of std_logic_vector(C_DATA_WIDTH-1 downto 0);
  109. shared variable sv_wishbone_queue : t_list_queue;
  110. begin
  111. --* testbench global clock
  112. s_wb_clk <= not(s_wb_clk) after C_PERIOD/2 when not(s_test_done) else '0';
  113. --* testbench global reset
  114. s_wb_reset <= '0' after C_PERIOD * 5;
  115. WbMasterLocalP : process is
  116. variable v_random : RandomPType;
  117. variable v_wbmaster_data : std_logic_vector(C_DATA_WIDTH-1 downto 0);
  118. begin
  119. v_random.InitSeed(v_random'instance_name);
  120. v_wbmaster_data := (others => '0');
  121. s_master_local_din <= (others => '0');
  122. s_master_local_adress <= (others => '0');
  123. s_master_local_wen <= '0';
  124. s_master_local_ren <= '0';
  125. wait until s_wb_reset = '0';
  126. -- write the wishbone slave registers
  127. for i in 0 to integer'(2**C_ADDRESS_WIDTH-1) loop
  128. v_wbmaster_data := v_random.RandSlv(C_DATA_WIDTH);
  129. s_master_local_din <= v_wbmaster_data;
  130. s_master_local_adress <= std_logic_vector(to_unsigned(i, C_ADDRESS_WIDTH));
  131. s_master_local_wen <= '1';
  132. wait until rising_edge(s_wb_clk);
  133. s_master_local_din <= (others => '0');
  134. s_master_local_adress <= (others => '0');
  135. s_master_local_wen <= '0';
  136. wait until rising_edge(s_wb_clk) and s_master_local_ack = '1';
  137. sv_wishbone_queue.push(v_wbmaster_data);
  138. end loop;
  139. -- read back and check the wishbone slave registers
  140. for i in 0 to integer'(2**C_ADDRESS_WIDTH-1) loop
  141. s_master_local_adress <= std_logic_vector(to_unsigned(i, C_ADDRESS_WIDTH));
  142. s_master_local_ren <= '1';
  143. wait until rising_edge(s_wb_clk);
  144. s_master_local_adress <= (others => '0');
  145. s_master_local_ren <= '0';
  146. wait until rising_edge(s_wb_clk) and s_master_local_ack = '1';
  147. sv_wishbone_queue.pop(v_wbmaster_data);
  148. assert_equal(s_master_local_dout, v_wbmaster_data);
  149. end loop;
  150. report "INFO: Test successfully finished!";
  151. s_test_done <= true;
  152. wait;
  153. end process WbMasterLocalP;
  154. i_WishBoneMasterE : WishBoneMasterE
  155. generic map (
  156. G_ADR_WIDTH => C_ADDRESS_WIDTH,
  157. G_DATA_WIDTH => C_DATA_WIDTH
  158. )
  159. port map (
  160. --+ wishbone system if
  161. WbRst_i => s_wb_reset,
  162. WbClk_i => s_wb_clk,
  163. --+ wishbone outputs
  164. WbCyc_o => s_wb_cyc,
  165. WbStb_o => s_wb_stb,
  166. WbWe_o => s_wb_we,
  167. WbAdr_o => s_wb_adr,
  168. WbDat_o => s_wb_master_data,
  169. --+ wishbone inputs
  170. WbDat_i => s_wb_slave_data,
  171. WbAck_i => s_wb_ack,
  172. WbErr_i => s_wb_err,
  173. --+ local register if
  174. LocalWen_i => s_master_local_wen,
  175. LocalRen_i => s_master_local_ren,
  176. LocalAdress_i => s_master_local_adress,
  177. LocalData_i => s_master_local_din,
  178. LocalData_o => s_master_local_dout,
  179. LocalAck_o => s_master_local_ack,
  180. LocalError_o => s_master_local_error
  181. );
  182. i_WishBoneSlaveE : WishBoneSlaveE
  183. generic map (
  184. G_ADR_WIDTH => C_ADDRESS_WIDTH,
  185. G_DATA_WIDTH => C_DATA_WIDTH
  186. )
  187. port map (
  188. --+ wishbone system if
  189. WbRst_i => s_wb_reset,
  190. WbClk_i => s_wb_clk,
  191. --+ wishbone inputs
  192. WbCyc_i => s_wb_cyc,
  193. WbStb_i => s_wb_stb,
  194. WbWe_i => s_wb_we,
  195. WbAdr_i => s_wb_adr,
  196. WbDat_i => s_wb_master_data,
  197. --* wishbone outputs
  198. WbDat_o => s_wb_slave_data,
  199. WbAck_o => s_wb_ack,
  200. WbErr_o => s_wb_err,
  201. --+ local register if
  202. LocalWen_o => s_slave_local_wen,
  203. LocalRen_o => s_slave_local_ren,
  204. LocalAdress_o => s_slave_local_adress,
  205. LocalData_o => s_slave_local_dout,
  206. LocalData_i => s_slave_local_din
  207. );
  208. WbSlaveLocalP : process (s_wb_clk) is
  209. variable v_register : t_register := (others => (others => '0'));
  210. begin
  211. if (rising_edge(s_wb_clk)) then
  212. if (s_wb_reset = '1') then
  213. v_register := (others => (others => '0'));
  214. s_slave_local_din <= (others => '0');
  215. else
  216. if (s_slave_local_wen = '1') then
  217. v_register(to_integer(unsigned(s_slave_local_adress))) := s_slave_local_dout;
  218. elsif (s_slave_local_ren = '1') then
  219. s_slave_local_din <= v_register(to_integer(unsigned(s_slave_local_adress)));
  220. end if;
  221. end if;
  222. end if;
  223. end process WbSlaveLocalP;
  224. end architecture sim;