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.

161 lines
5.5 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. package wishbone_pkg is
  9. type t_slv_array is array (natural range <>) of std_logic_vector;
  10. type t_wb_syscon is record
  11. Reset : std_logic;
  12. Clk : std_logic;
  13. end record;
  14. type t_wb_master is record
  15. Cyc : std_logic;
  16. Stb : std_logic;
  17. We : std_logic;
  18. Lock : std_logic;
  19. Adr : std_logic_vector;
  20. Dat : std_logic_vector;
  21. Sel : std_logic_vector;
  22. Tgc : std_logic_vector;
  23. Tga : std_logic_vector;
  24. Tgd : std_logic_vector;
  25. end record;
  26. type t_wb_slave is record
  27. Ack : std_logic;
  28. Err : std_logic;
  29. Rty : std_logic;
  30. Dat : std_logic_vector;
  31. Tgd : std_logic_vector;
  32. end record;
  33. function to_string(wb : t_wb_master) return string;
  34. function to_string(wb : t_wb_slave) return string;
  35. procedure log_wishbone (signal clk : std_logic; master : t_wb_master; slave : t_wb_slave);
  36. procedure cycle (signal syscon : in t_wb_syscon;
  37. signal master : out t_wb_master;
  38. signal slave : in t_wb_slave;
  39. Wen : in std_logic;
  40. Adr : in std_logic_vector;
  41. WDat : in std_logic_vector;
  42. RDat : out std_logic_vector);
  43. procedure single_cycle (signal syscon : in t_wb_syscon;
  44. signal master : out t_wb_master;
  45. signal slave : in t_wb_slave;
  46. Wen : in std_logic;
  47. Adr : in std_logic_vector;
  48. WDat : in std_logic_vector;
  49. RDat : out std_logic_vector);
  50. procedure block_cycle (signal syscon : in t_wb_syscon;
  51. signal master : out t_wb_master;
  52. signal slave : in t_wb_slave;
  53. Wen : in std_logic;
  54. Adr : in t_slv_array;
  55. WDat : in t_slv_array;
  56. RDat : out t_slv_array);
  57. end package wishbone_pkg;
  58. package body wishbone_pkg is
  59. procedure cycle (signal syscon : in t_wb_syscon;
  60. signal master : out t_wb_master;
  61. signal slave : in t_wb_slave;
  62. Wen : in std_logic;
  63. Adr : in std_logic_vector;
  64. WDat : in std_logic_vector;
  65. RDat : out std_logic_vector) is
  66. begin
  67. master.Cyc <= '1';
  68. master.Stb <= '1';
  69. master.We <= Wen;
  70. master.Adr <= Adr;
  71. master.Dat <= WDat;
  72. wait until rising_edge(syscon.Clk) and (slave.Ack or slave.Err or slave.Rty) = '1';
  73. RDat := slave.Dat;
  74. end procedure cycle;
  75. procedure single_cycle (signal syscon : in t_wb_syscon;
  76. signal master : out t_wb_master;
  77. signal slave : in t_wb_slave;
  78. Wen : in std_logic;
  79. Adr : in std_logic_vector;
  80. WDat : in std_logic_vector;
  81. RDat : out std_logic_vector) is
  82. begin
  83. cycle(syscon, master, slave, Wen, Adr, WDat, RDat);
  84. master.Cyc <= '0';
  85. master.Stb <= '0';
  86. master.We <= '0';
  87. master.Adr <= (master.Adr'range => '0');
  88. master.Dat <= (master.Dat'range => '0');
  89. wait until rising_edge(syscon.Clk);
  90. end procedure single_cycle;
  91. procedure block_cycle (signal syscon : in t_wb_syscon;
  92. signal master : out t_wb_master;
  93. signal slave : in t_wb_slave;
  94. Wen : in std_logic;
  95. Adr : in t_slv_array;
  96. WDat : in t_slv_array;
  97. RDat : out t_slv_array) is
  98. begin
  99. assert Adr'length = WDat'length and WDat'length = RDat'length;
  100. for i in Adr'low to Adr'high-1 loop
  101. cycle(syscon, master, slave, Wen, Adr(i), WDat(i), RDat(i));
  102. end loop;
  103. single_cycle(syscon, master, slave, Wen, Adr(Adr'high), WDat(WDat'high), RDat(RDat'high));
  104. end procedure block_cycle;
  105. function to_string(wb : t_wb_master) return string is
  106. begin
  107. return "Cyc: " & to_string(wb.Cyc) & LF &
  108. "Stb: " & to_string(wb.Stb) & LF &
  109. "We: " & to_string(wb.We) & LF &
  110. "Lock: " & to_string(wb.Lock) & LF &
  111. "Adr: " & to_hstring(wb.Adr) & LF &
  112. "Dat: " & to_hstring(wb.Dat) & LF &
  113. "Sel: " & to_hstring(wb.Sel) & LF &
  114. "Tgc: " & to_hstring(wb.Tgc) & LF &
  115. "Tga: " & to_hstring(wb.Tga) & LF &
  116. "Tgd: " & to_hstring(wb.Tgd);
  117. end function to_string;
  118. function to_string(wb : t_wb_slave) return string is
  119. begin
  120. return "Ack: " & to_string(wb.Ack) & LF &
  121. "Err: " & to_string(wb.Err) & LF &
  122. "Rty: " & to_string(wb.Rty) & LF &
  123. "Dat: " & to_hstring(wb.Dat) & LF &
  124. "Tgd: " & to_hstring(wb.Tgd);
  125. end function to_string;
  126. procedure log_wishbone (signal clk : std_logic; master : t_wb_master; slave : t_wb_slave) is
  127. begin
  128. wait until rising_edge(clk);
  129. report "Wishbone master:" & LF & to_string(master);
  130. report "Wishbone slave:" & LF & to_string(slave);
  131. end procedure log_wishbone;
  132. end package body wishbone_pkg;