tb.vhd 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. use ieee.std_logic_textio.all;
  5. library std; -- for Printing
  6. use std.textio.all;
  7. use work.mem_pkg.all;
  8. use work.op_pkg.all;
  9. use work.core_pkg.all;
  10. use work.tb_util_pkg.all;
  11. entity tb is
  12. end entity;
  13. architecture bench of tb is
  14. constant CLK_PERIOD : time := 10 ns;
  15. signal clk : std_logic;
  16. signal res_n : std_logic := '0';
  17. signal stop : boolean := false;
  18. file input_file : text;
  19. file output_ref_file : text;
  20. type input_t is
  21. record
  22. op : alu_op_type;
  23. A, B : data_type;
  24. end record;
  25. type output_t is
  26. record
  27. R : data_type;
  28. Z : std_logic;
  29. end record;
  30. signal inp : input_t := (
  31. ALU_NOP,
  32. (others => '0'),
  33. (others => '0')
  34. );
  35. signal outp : output_t;
  36. impure function read_next_input(file f : text) return input_t is
  37. variable l : line;
  38. variable result : input_t;
  39. begin
  40. l := get_next_valid_line(f);
  41. result.op := str_to_alu_op(l.all);
  42. l := get_next_valid_line(f);
  43. result.A := bin_to_slv(l.all, inp.A'LENGTH);
  44. l := get_next_valid_line(f);
  45. result.B := bin_to_slv(l.all, inp.B'LENGTH);
  46. return result;
  47. end function;
  48. impure function read_next_output(file f : text) return output_t is
  49. variable l : line;
  50. variable result : output_t;
  51. begin
  52. l := get_next_valid_line(f);
  53. result.R := bin_to_slv(l.all, outp.R'LENGTH);
  54. l := get_next_valid_line(f);
  55. result.Z := str_to_sl(l(1));
  56. return result;
  57. end function;
  58. procedure check_output(output_ref : output_t) is
  59. variable passed : boolean;
  60. begin
  61. passed := (outp = output_ref);
  62. if passed then
  63. report " PASSED: "
  64. & "op=" & to_string(inp.op)
  65. & " A=" & to_string(inp.A)
  66. & " B=" & to_string(inp.B)
  67. severity note;
  68. else
  69. report "FAILED: "
  70. & "op=" & to_string(inp.op)
  71. & " A=" & to_string(inp.A)
  72. & " B=" & to_string(inp.B)
  73. & "** expected: R=" & to_string(output_ref.R) & " Z=" & to_string(output_ref.Z) & lf
  74. & "** actual: R=" & to_string(outp.R) & " Z=" & to_string(outp.Z) & lf
  75. severity error;
  76. end if;
  77. end procedure;
  78. begin
  79. alu_inst : entity work.alu
  80. port map (
  81. op => inp.op,
  82. A => inp.A,
  83. B => inp.B,
  84. R => outp.R,
  85. Z => outp.Z
  86. );
  87. stimulus : process
  88. variable fstatus: file_open_status;
  89. begin
  90. res_n <= '0';
  91. wait until rising_edge(clk);
  92. res_n <= '1';
  93. file_open(fstatus, input_file, "testdata/input.txt", READ_MODE);
  94. timeout(1, CLK_PERIOD);
  95. while not endfile(input_file) loop
  96. inp <= read_next_input(input_file);
  97. timeout(1, CLK_PERIOD);
  98. end loop;
  99. wait;
  100. end process;
  101. output_checker : process
  102. variable fstatus: file_open_status;
  103. variable output_ref : output_t;
  104. begin
  105. file_open(fstatus, output_ref_file, "testdata/output.txt", READ_MODE);
  106. wait until res_n = '1';
  107. timeout(1, CLK_PERIOD);
  108. while not endfile(output_ref_file) loop
  109. output_ref := read_next_output(output_ref_file);
  110. wait until falling_edge(clk);
  111. check_output(output_ref);
  112. wait until rising_edge(clk);
  113. end loop;
  114. stop <= true;
  115. wait;
  116. end process;
  117. generate_clk : process
  118. begin
  119. clk_generate(clk, CLK_PERIOD, stop);
  120. wait;
  121. end process;
  122. end architecture;