123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.numeric_std.all;
- library std;
- use std.textio.all;
- use ieee.std_logic_textio.all;
- use work.op_pkg.all;
- use work.core_pkg.all;
- package tb_util_pkg is
- -- Generates a clock on the given `clk` signal. Does not return.
- procedure clk_generate(signal clk : inout std_logic; constant clk_period : time);
- -- Generates a clock on the given `clk` signal. Return when stop becomes true.
- procedure clk_generate(signal clk : inout std_logic; constant clk_period : time; signal stop : in boolean);
- -- Waits for `num_cycles` cycles of the given period.
- procedure timeout(num_cycles : integer; constant clk_period : time);
- -- Reads lines from a file until the line isn't empty and doesn't start with a '#'.
- impure function get_next_valid_line(file f : text) return line;
- -- Converts a character to std_logic.
- function str_to_sl(c : character) return std_logic;
- -- Converts a bin to std_logic_vector.
- function bin_to_slv(bin : string; width : integer) return std_logic_vector;
- -- Converts a hex to std_logic_vector.
- function hex_to_slv(hex : string; width : integer) return std_logic_vector;
- -- Converts a string to a alu_op_type.
- function str_to_alu_op(str : string) return alu_op_type;
- -- Converts a string to a branch_type.
- function str_to_branch(str : string) return branch_type;
- -- Converts a string to a memtype_type.
- function str_to_mem_op(str : string) return memtype_type;
- -- Converts a string to a wbsrc_type.
- function str_to_wbs_op(str : string) return wbsrc_type;
- -- Trims a string (removes leading and tailing spaces
- function trim(str : string) return string;
- -- Removes comments (starting with #) from a line
- function rm_comment(str : string) return string;
- end package;
- package body tb_util_pkg is
- procedure clk_generate(signal clk : inout std_logic; constant clk_period : time; signal stop : in boolean) is
- begin
- while not stop loop
- clk <= '1', '0' after clk_period / 2;
- wait for clk_period;
- end loop;
- end procedure;
- procedure clk_generate(signal clk : inout std_logic; constant clk_period : time) is
- begin
- loop
- clk <= '1', '0' after clk_period / 2;
- wait for clk_period;
- end loop;
- end procedure;
- procedure timeout(num_cycles : integer; constant clk_period : time) is
- begin
- wait for CLK_PERIOD*num_cycles;
- end procedure;
- function str_to_sl(c : character) return std_logic is
- begin
- case c is
- when '0' =>
- return '0';
- when '1' =>
- return '1';
- when 'L' =>
- return 'L';
- when 'H' =>
- return 'H';
- when 'X' =>
- return 'X';
- when 'Z' =>
- return 'Z';
- when 'W' =>
- return 'W';
- when '-' =>
- return '-';
- when 'U' =>
- return 'U';
- when others =>
- return 'U';
- end case;
- end function;
- function max(a,b : integer) return integer is
- begin
- if a > b then
- return a;
- else
- return b;
- end if;
- end function;
- function trim(str : string) return string is
- alias src : string(1 to str'length) is str;
- variable ltrim, rtrim : natural;
- begin
- ltrim := 0;
- for i in src'range loop
- if src(i) /= ' ' then -- not space
- ltrim := i;
- exit;
- end if;
- end loop;
- if ltrim = 0 then
- return "";
- end if;
- rtrim := src'right;
- for i in src'reverse_range loop
- if src(i) /= ' ' then -- not space
- rtrim := i;
- exit;
- end if;
- end loop;
- return src(ltrim to rtrim);
- end function;
- function rm_comment(str : string) return string is
- begin
- for i in str'range loop
- if str(i) = '#' then
- return trim(str(1 to i-1));
- end if;
- end loop;
- return str;
- end function;
- function bin_to_slv(bin : string; width : integer) return std_logic_vector is
- variable ret_value : std_logic_vector(width-1 downto 0) := (others=>'0');
- variable temp : std_logic;
- variable j : integer := 0;
- begin
- for i in bin'high downto bin'low loop
- next when bin(i) = ' ';
- exit when j >= width;
- temp := str_to_sl(bin(i));
- ret_value(j) := temp;
- j := j+1;
- end loop;
- return ret_value;
- end function;
- function hex_to_slv(hex : string; width : integer) return std_logic_vector is
- variable ret_value : std_logic_vector(width-1 downto 0) := (others=>'0');
- variable temp : std_logic_vector(3 downto 0);
- begin
- for i in 0 to hex'length-1 loop
- case hex(hex'high-i) is
- when '0' => temp := x"0";
- when '1' => temp := x"1";
- when '2' => temp := x"2";
- when '3' => temp := x"3";
- when '4' => temp := x"4";
- when '5' => temp := x"5";
- when '6' => temp := x"6";
- when '7' => temp := x"7";
- when '8' => temp := x"8";
- when '9' => temp := x"9";
- when 'a' | 'A' => temp := x"a";
- when 'b' | 'B' => temp := x"b";
- when 'c' | 'C' => temp := x"c";
- when 'd' | 'D' => temp := x"d";
- when 'e' | 'E' => temp := x"e";
- when 'f' | 'F' => temp := x"f";
- when others => report "Conversion Error: char: " & hex(hex'high-i) severity error;
- end case;
- ret_value((i+1)*4-1 downto i*4) := temp;
- end loop;
- return ret_value;
- end function;
- impure function get_next_valid_line(file f : text) return line is
- variable l : line;
- begin
- readline(f, l);
- while l'length = 0 or l(1) = '#' loop
- readline(f, l);
- end loop;
- return l;
- end function;
- function str_to_alu_op(str : string) return alu_op_type is
- begin
- if str = "ALU_NOP" then
- return ALU_NOP;
- elsif str = "ALU_SLT" then
- return ALU_SLT;
- elsif str = "ALU_SLTU" then
- return ALU_SLTU;
- elsif str = "ALU_SLL" then
- return ALU_SLL;
- elsif str = "ALU_SRL" then
- return ALU_SRL;
- elsif str = "ALU_SRA" then
- return ALU_SRA;
- elsif str = "ALU_ADD" then
- return ALU_ADD;
- elsif str = "ALU_SUB" then
- return ALU_SUB;
- elsif str = "ALU_AND" then
- return ALU_AND;
- elsif str = "ALU_OR" then
- return ALU_OR;
- elsif str = "ALU_XOR" then
- return ALU_XOR;
- else
- -- This shouldn't happen
- report "Unknown op-code '" & str & "' -- defaulting to ALU_NOP" severity warning;
- return ALU_NOP;
- end if;
- end function;
- function str_to_branch(str : string) return branch_type is
- begin
- if str = "BR_NOP" then
- return BR_NOP;
- elsif str = "BR_BR" then
- return BR_BR;
- elsif str = "BR_CND" then
- return BR_CND;
- elsif str = "BR_CNDI" then
- return BR_CNDI;
- else
- -- This shouldn't happen
- report "Unknown op-code '" & str & "' -- defaulting to BR_NOP" severity warning;
- return BR_NOP;
- end if;
- end function;
- function str_to_mem_op(str : string) return memtype_type is
- begin
- if str = "MEM_W" then
- return MEM_W;
- elsif str = "MEM_H" then
- return MEM_H;
- elsif str = "MEM_HU" then
- return MEM_HU;
- elsif str = "MEM_B" then
- return MEM_B;
- elsif str = "MEM_BU" then
- return MEM_BU;
- else
- -- This shouldn't happen
- report "Unknown op-code '" & str & "' -- defaulting to MEM_W" severity warning;
- return MEM_W;
- end if;
- end function;
- function str_to_wbs_op(str : string) return wbsrc_type is
- begin
- if str = "WBS_ALU" then
- return WBS_ALU;
- elsif str = "WBS_MEM" then
- return WBS_MEM;
- elsif str = "WBS_OPC" then
- return WBS_OPC;
- else
- -- This shouldn't happen
- report "Unknown op-code '" & str & "' -- defaulting to WBS_ALU" severity warning;
- return WBS_ALU;
- end if;
- end function;
- end package body;
|