tb_util_pkg.vhd 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. library std;
  5. use std.textio.all;
  6. use ieee.std_logic_textio.all;
  7. use work.op_pkg.all;
  8. use work.core_pkg.all;
  9. package tb_util_pkg is
  10. -- Generates a clock on the given `clk` signal. Does not return.
  11. procedure clk_generate(signal clk : inout std_logic; constant clk_period : time);
  12. -- Generates a clock on the given `clk` signal. Return when stop becomes true.
  13. procedure clk_generate(signal clk : inout std_logic; constant clk_period : time; signal stop : in boolean);
  14. -- Waits for `num_cycles` cycles of the given period.
  15. procedure timeout(num_cycles : integer; constant clk_period : time);
  16. -- Reads lines from a file until the line isn't empty and doesn't start with a '#'.
  17. impure function get_next_valid_line(file f : text) return line;
  18. -- Converts a character to std_logic.
  19. function str_to_sl(c : character) return std_logic;
  20. -- Converts a bin to std_logic_vector.
  21. function bin_to_slv(bin : string; width : integer) return std_logic_vector;
  22. -- Converts a hex to std_logic_vector.
  23. function hex_to_slv(hex : string; width : integer) return std_logic_vector;
  24. -- Converts a string to a alu_op_type.
  25. function str_to_alu_op(str : string) return alu_op_type;
  26. -- Converts a string to a branch_type.
  27. function str_to_branch(str : string) return branch_type;
  28. -- Converts a string to a memtype_type.
  29. function str_to_mem_op(str : string) return memtype_type;
  30. -- Converts a string to a wbsrc_type.
  31. function str_to_wbs_op(str : string) return wbsrc_type;
  32. -- Trims a string (removes leading and tailing spaces
  33. function trim(str : string) return string;
  34. -- Removes comments (starting with #) from a line
  35. function rm_comment(str : string) return string;
  36. end package;
  37. package body tb_util_pkg is
  38. procedure clk_generate(signal clk : inout std_logic; constant clk_period : time; signal stop : in boolean) is
  39. begin
  40. while not stop loop
  41. clk <= '1', '0' after clk_period / 2;
  42. wait for clk_period;
  43. end loop;
  44. end procedure;
  45. procedure clk_generate(signal clk : inout std_logic; constant clk_period : time) is
  46. begin
  47. loop
  48. clk <= '1', '0' after clk_period / 2;
  49. wait for clk_period;
  50. end loop;
  51. end procedure;
  52. procedure timeout(num_cycles : integer; constant clk_period : time) is
  53. begin
  54. wait for CLK_PERIOD*num_cycles;
  55. end procedure;
  56. function str_to_sl(c : character) return std_logic is
  57. begin
  58. case c is
  59. when '0' =>
  60. return '0';
  61. when '1' =>
  62. return '1';
  63. when 'L' =>
  64. return 'L';
  65. when 'H' =>
  66. return 'H';
  67. when 'X' =>
  68. return 'X';
  69. when 'Z' =>
  70. return 'Z';
  71. when 'W' =>
  72. return 'W';
  73. when '-' =>
  74. return '-';
  75. when 'U' =>
  76. return 'U';
  77. when others =>
  78. return 'U';
  79. end case;
  80. end function;
  81. function max(a,b : integer) return integer is
  82. begin
  83. if a > b then
  84. return a;
  85. else
  86. return b;
  87. end if;
  88. end function;
  89. function trim(str : string) return string is
  90. alias src : string(1 to str'length) is str;
  91. variable ltrim, rtrim : natural;
  92. begin
  93. ltrim := 0;
  94. for i in src'range loop
  95. if src(i) /= ' ' then -- not space
  96. ltrim := i;
  97. exit;
  98. end if;
  99. end loop;
  100. if ltrim = 0 then
  101. return "";
  102. end if;
  103. rtrim := src'right;
  104. for i in src'reverse_range loop
  105. if src(i) /= ' ' then -- not space
  106. rtrim := i;
  107. exit;
  108. end if;
  109. end loop;
  110. return src(ltrim to rtrim);
  111. end function;
  112. function rm_comment(str : string) return string is
  113. begin
  114. for i in str'range loop
  115. if str(i) = '#' then
  116. return trim(str(1 to i-1));
  117. end if;
  118. end loop;
  119. return str;
  120. end function;
  121. function bin_to_slv(bin : string; width : integer) return std_logic_vector is
  122. variable ret_value : std_logic_vector(width-1 downto 0) := (others=>'0');
  123. variable temp : std_logic;
  124. variable j : integer := 0;
  125. begin
  126. for i in bin'high downto bin'low loop
  127. next when bin(i) = ' ';
  128. exit when j >= width;
  129. temp := str_to_sl(bin(i));
  130. ret_value(j) := temp;
  131. j := j+1;
  132. end loop;
  133. return ret_value;
  134. end function;
  135. function hex_to_slv(hex : string; width : integer) return std_logic_vector is
  136. variable ret_value : std_logic_vector(width-1 downto 0) := (others=>'0');
  137. variable temp : std_logic_vector(3 downto 0);
  138. begin
  139. for i in 0 to hex'length-1 loop
  140. case hex(hex'high-i) is
  141. when '0' => temp := x"0";
  142. when '1' => temp := x"1";
  143. when '2' => temp := x"2";
  144. when '3' => temp := x"3";
  145. when '4' => temp := x"4";
  146. when '5' => temp := x"5";
  147. when '6' => temp := x"6";
  148. when '7' => temp := x"7";
  149. when '8' => temp := x"8";
  150. when '9' => temp := x"9";
  151. when 'a' | 'A' => temp := x"a";
  152. when 'b' | 'B' => temp := x"b";
  153. when 'c' | 'C' => temp := x"c";
  154. when 'd' | 'D' => temp := x"d";
  155. when 'e' | 'E' => temp := x"e";
  156. when 'f' | 'F' => temp := x"f";
  157. when others => report "Conversion Error: char: " & hex(hex'high-i) severity error;
  158. end case;
  159. ret_value((i+1)*4-1 downto i*4) := temp;
  160. end loop;
  161. return ret_value;
  162. end function;
  163. impure function get_next_valid_line(file f : text) return line is
  164. variable l : line;
  165. begin
  166. readline(f, l);
  167. while l'length = 0 or l(1) = '#' loop
  168. readline(f, l);
  169. end loop;
  170. return l;
  171. end function;
  172. function str_to_alu_op(str : string) return alu_op_type is
  173. begin
  174. if str = "ALU_NOP" then
  175. return ALU_NOP;
  176. elsif str = "ALU_SLT" then
  177. return ALU_SLT;
  178. elsif str = "ALU_SLTU" then
  179. return ALU_SLTU;
  180. elsif str = "ALU_SLL" then
  181. return ALU_SLL;
  182. elsif str = "ALU_SRL" then
  183. return ALU_SRL;
  184. elsif str = "ALU_SRA" then
  185. return ALU_SRA;
  186. elsif str = "ALU_ADD" then
  187. return ALU_ADD;
  188. elsif str = "ALU_SUB" then
  189. return ALU_SUB;
  190. elsif str = "ALU_AND" then
  191. return ALU_AND;
  192. elsif str = "ALU_OR" then
  193. return ALU_OR;
  194. elsif str = "ALU_XOR" then
  195. return ALU_XOR;
  196. else
  197. -- This shouldn't happen
  198. report "Unknown op-code '" & str & "' -- defaulting to ALU_NOP" severity warning;
  199. return ALU_NOP;
  200. end if;
  201. end function;
  202. function str_to_branch(str : string) return branch_type is
  203. begin
  204. if str = "BR_NOP" then
  205. return BR_NOP;
  206. elsif str = "BR_BR" then
  207. return BR_BR;
  208. elsif str = "BR_CND" then
  209. return BR_CND;
  210. elsif str = "BR_CNDI" then
  211. return BR_CNDI;
  212. else
  213. -- This shouldn't happen
  214. report "Unknown op-code '" & str & "' -- defaulting to BR_NOP" severity warning;
  215. return BR_NOP;
  216. end if;
  217. end function;
  218. function str_to_mem_op(str : string) return memtype_type is
  219. begin
  220. if str = "MEM_W" then
  221. return MEM_W;
  222. elsif str = "MEM_H" then
  223. return MEM_H;
  224. elsif str = "MEM_HU" then
  225. return MEM_HU;
  226. elsif str = "MEM_B" then
  227. return MEM_B;
  228. elsif str = "MEM_BU" then
  229. return MEM_BU;
  230. else
  231. -- This shouldn't happen
  232. report "Unknown op-code '" & str & "' -- defaulting to MEM_W" severity warning;
  233. return MEM_W;
  234. end if;
  235. end function;
  236. function str_to_wbs_op(str : string) return wbsrc_type is
  237. begin
  238. if str = "WBS_ALU" then
  239. return WBS_ALU;
  240. elsif str = "WBS_MEM" then
  241. return WBS_MEM;
  242. elsif str = "WBS_OPC" then
  243. return WBS_OPC;
  244. else
  245. -- This shouldn't happen
  246. report "Unknown op-code '" & str & "' -- defaulting to WBS_ALU" severity warning;
  247. return WBS_ALU;
  248. end if;
  249. end function;
  250. end package body;