-- VHDL Entity HEIRV32_test.heirv32_tb.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE2332101)
--          at - 14:52:58 18.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY heirv32_tb IS
-- Declarations

END heirv32_tb ;





-- VHDL Entity HEIRV32_test.universalTester.interface
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 16:01:58 24.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY universalTester IS
    GENERIC( 
        c_btnsNb : positive := 2
    );
    PORT( 
        btns : OUT    std_ulogic_vector (c_btnsNb-1 DOWNTO 0);
        clk  : OUT    std_ulogic;
        en   : OUT    std_ulogic;
        rst  : OUT    std_ulogic
    );

-- Declarations

END universalTester ;





LIBRARY std;
  USE std.textio.all;
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

PACKAGE testUtils IS

  --============================================================================
  -- console output
  --

  procedure print(value : string);


  --============================================================================
  -- string manipulation
  --

                                                      -- conversion to lowercase
  function lc(value : string) return string;
  procedure lc(value : inout line);
                                                      -- conversion to uppercase
  function uc(value : string) return string;
  procedure uc(value : inout line);
                                            -- expand a string to a given length
  function pad(
    value           : string;
    string_length   : natural;
    fill_char       : character := ' ';
    right_justify   : boolean := false
  ) return string;
                     -- remove separator characters at beginning and end of line
  procedure rm_side_separators(
    value : inout line;
    separators : in string
  );
  procedure rm_side_separators(
    value : inout line
  );
                           -- remove multiple occurences of separator characters
  procedure trim_line(
    value : inout line;
    separators : in string
  );

  procedure trim_line(
    value : inout line
   );
                                -- remove all occurences of separator characters
  procedure rm_all_separators(
    value : inout line;
    separators : in string
  );

  procedure rm_all_separators(
    value : inout line
  );
                                                   -- find and remove first word
  procedure read_first(
    value : inout line;
    separators : in string;
    first : out line
  );

  procedure read_first(
    value : inout line;
    first : out line
   );
                                                    -- find and remove last word
  procedure read_last(
    value : inout line;
    separators : in string;
    last : out line
  );

  procedure read_last(
    value : inout line;
    last : out line
   );


  --============================================================================
  -- formatted string output
  --
  -- format codes:
  --  code  integer real std_logic std_(u)logic_vector (un)signed time
  --    b       v            v               v              v           binary
  --    c                                                               character
  --    d       v     v      v               v              v           decimal
  --    e                                                               real numbers, with power of 10 exponent
  --    f       v     v                                                 fixed point real numbers
  --    s                                                               string
  --    ts                                                          v   time in seconds
  --    tm                                                          v   time in milliseconds
  --    tu                                                          v   time in microseconds
  --    tn                                                          v   time in nanoseconds
  --    tp                                                          v   time in picoseconds
  --    x       v            v               v              v           hexadecimal
  --    X       v            v               v              v           hexadecimal with upper-case letters

  function sprintf(format : string; value : integer          ) return string;
  function sprintf(format : string; value : real             ) return string;
  function sprintf(format : string; value : std_logic        ) return string;
  function sprintf(format : string; value : std_ulogic_vector) return string;
  function sprintf(format : string; value : std_logic_vector ) return string;
  function sprintf(format : string; value : unsigned         ) return string;
  function sprintf(format : string; value : signed           ) return string;
  function sprintf(format : string; value : time             ) return string;

  --============================================================================
  -- formatted string input
  --
  subtype nibbleUlogicType is std_ulogic_vector(3 downto 0);
  subtype nibbleUnsignedType is unsigned(3 downto 0);

  function sscanf(value : character) return natural;
  function sscanf(value : character) return nibbleUlogicType;
  function sscanf(value : character) return nibbleUnsignedType;
  function sscanf(value : string   ) return natural;
  function sscanf(value : string   ) return unsigned;
  function sscanf(value : string   ) return std_ulogic_vector;
  function sscanf(value : string   ) return time;

  procedure sscanf(value : inout line; time_val : out time);

END testUtils;




PACKAGE BODY testUtils IS

  --============================================================================
  -- console output
  --

  procedure print(value : string) is
    variable my_line : line;
  begin
    write(my_line, value);
    writeLine(output, my_line);
    deallocate(my_line);
  end print;


  --============================================================================
  -- string manipulation
  --

  ------------------------------------------------------------------------------
  -- change to lowercase
  ------------------------------------------------------------------------------
  procedure lc(value: inout line) is
    variable out_line: line;
  begin
    for index in value'range loop
      if (value(index) >= 'A') and (value(index) <= 'Z') then
        value(index) := character'val(character'pos(value(index))
                                    - character'pos('A')
                                    + character'pos('a')
                                      );
      end if;
    end loop;
  end lc;

  function lc(value: string) return string is
    variable out_line: line;
  begin
    write(out_line, value);
    lc(out_line);
    return(out_line.all);
  end lc;

  ------------------------------------------------------------------------------
  -- change to uppercase
  ------------------------------------------------------------------------------
  procedure uc(value: inout line) is
    variable out_line: line;
  begin
    for index in value'range loop
      if (value(index) >= 'a') and (value(index) <= 'z') then
        value(index) := character'val(character'pos(value(index))
                                    - character'pos('a')
                                    + character'pos('A')
                                      );
      end if;
    end loop;
  end uc;

  function uc(value: string) return string is
    variable out_line: line;
  begin
    write(out_line, value);
    uc(out_line);
    return(out_line.all);
  end uc;

  ------------------------------------------------------------------------------
  -- formatted string output: padding and justifying
  ------------------------------------------------------------------------------
  function pad(
    value           : string;
    string_length   : natural;
    fill_char       : character := ' ';
    right_justify   : boolean := false
  ) return string is
    variable value_line : line;
    variable out_line : line;
    variable value_length : natural;
    variable shift_sign : boolean;
  begin
    write(value_line, value);
    value_length := value_line.all'length;
    if string_length = 0 then
      write(out_line, value_line.all);
    elsif string_length > value_length then
      if right_justify then
        if (value_line.all(value_line.all'left) <= '-') and not(fill_char = ' ') then
          shift_sign := true;
          write(out_line, value_line.all(value_line.all'left));
        end if;
        for index in 1 to string_length-value_length loop
          write(out_line, fill_char);
        end loop;
      end if;
      if shift_sign then
        write(out_line, value_line.all(value_line.all'left+1 to value_line.all'right));
      else
        write(out_line, value_line.all);
      end if;
      if not right_justify then
        for index in 1 to string_length-value_length loop
          write(out_line, fill_char);
        end loop;
      end if;
    elsif string_length < value_length then
      write(out_line, '#');
      write(out_line, value_line.all(value_length-string_length+2 to value_length));
    else
      write(out_line, value_line.all);
    end if;
    deallocate(value_line);
    return(out_line.all);
  end pad;

  ------------------------------------------------------------------------------
  -- remove separator characters at beginning and end of line
  ------------------------------------------------------------------------------
  procedure rm_side_separators(
    value : inout line;
    separators : in string
  ) is
    variable input_line : line    := value;
    variable found      : boolean := false;
    variable position   : integer := 0;
  begin
    -- remove all separators in the beginning
    position := -1;
    for character_index in input_line'range loop
      found := false;
      for separator_index in separators'range loop
        if input_line(character_index) = separators(separator_index) then
          found := true;
        end if;
      end loop;
      if found then
          position := character_index;
      else
          exit;
      end if;
   end loop;
   if position > -1 then
     input_line := new string'( input_line(position+1 to input_line'right) );
   end if;

   -- remove all separators in the end
    position := -1;
    for character_index in input_line'reverse_range loop
      found := false;
      for separator_index in separators'range loop
        if input_line(character_index) = separators(separator_index) then
          found := true;
        end if;
      end loop;
      if found then
          position := character_index;
      else
          exit;
      end if;
   end loop;
   if position > -1 then
     input_line := new string'( input_line(input_line'left to position-1) );
   end if;

   value := input_line;
  end;

  procedure rm_side_separators(value : inout line) is
  begin
    rm_side_separators(value, " :" & ht);
  end;

  ------------------------------------------------------------------------------
  -- remove multiple occurences of separator characters, keeping one single
  ------------------------------------------------------------------------------
  procedure trim_line(
    value : inout line;
    separators : in string
  ) is
    variable input_line: line := value;
    variable output_line: line := new string'("");
    variable is_separator, was_separator : boolean := false;
  begin
    rm_side_separators(input_line);
    for character_index in input_line'range loop
      is_separator := false;
      for separator_index in separators'range loop
        if input_line.all(character_index) = separators(separator_index) then
          is_separator := true;
        end if;
      end loop;
      if not (is_separator and was_separator) then
        write(output_line, input_line.all(character_index));
      end if;
      was_separator := is_separator;
    end loop;

    value := output_line;
  end;

  procedure trim_line(value : inout line) is
  begin
    trim_line(value, " :" & ht);
  end;

  ------------------------------------------------------------------------------
  -- remove all occurences of separator characters
  ------------------------------------------------------------------------------
  procedure rm_all_separators(
    value : inout line;
    separators : in string
  ) is
    variable input_line   : line    := value;
    variable is_separator : boolean := false;
  begin

    -- remove separators from beginn and end of the line
    -- rm_separator_be(value, separators);

    -- empty output line
    value := new string'("");

    -- find all separator symbols
    for character_index in input_line'range loop
      is_separator := false;
      for separator_index in separators'range loop
        if input_line(character_index) = separators(separator_index) then
          is_separator := true;
        end if;
      end loop;
      if not is_separator then
        write(value, input_line.all(character_index));
      end if;
    end loop;

  end;

  procedure rm_all_separators(value : inout line) is
  begin
    rm_all_separators(value, " _." & ht);
  end;

  ------------------------------------------------------------------------------
  -- read first "word" out of a line
  ------------------------------------------------------------------------------
  procedure read_first(
    value : inout line;
    separators : in string;
    first : out line
  ) is
    variable input_line: line;
    variable position: natural := 0;
  begin
    input_line := value;
    for character_index in input_line.all'reverse_range loop
      for separator_index in separators'range loop
        if input_line.all(character_index) = separators(separator_index) then
          position := character_index;
        end if;
      end loop;
    end loop;
    if position > 1 then
      first := new string'(input_line.all(input_line'left to position-1));
	    value := new string'(input_line(position+1 to input_line'right));
    else
      first := new string'(input_line.all);
	    value := new string'("");
    end if;
  end;

  procedure read_first(value : inout line; first : out line) is
  begin
    read_first(value, " :" & ht, first);
  end;

  ------------------------------------------------------------------------------
  -- read last "word" out of a line
  ------------------------------------------------------------------------------
  procedure read_last(
    value : inout line;
    separators : in string;
    last : out line
  ) is
    variable input_line: line := value;
    variable position: natural := 0;
  begin
    for character_index in input_line'range loop
      for separator_index in separators'range loop
        if input_line(character_index) = separators(separator_index) then
          position := character_index;
        end if;
      end loop;
    end loop;
    if position <= input_line'right and
       position >  0                then
      value := new string'(input_line(input_line'left to position-1));
      last  := new string'(input_line(position+1 to input_line'right));
    else
      last := new string'(input_line.all);
    end if;
  end;

  procedure read_last(value : inout line; last : out line) is
  begin
    read_last(value, " :" & ht, last);
  end;


  --============================================================================
  -- formatted string output, internal functions
  --

  ------------------------------------------------------------------------------
  -- get format specification
  ------------------------------------------------------------------------------
  procedure get_format_items(
    format          : string;
    right_justify   : out boolean;
    add_sign        : out boolean;
    fill_char       : out character;
    total_length    : out natural;
    point_precision : out natural;
    format_type     : inout line
  ) is
    variable find_sign : boolean := false;
    variable find_padding : boolean := false;
    variable find_length : boolean := false;
    variable find_precision : boolean := false;
    variable find_type : boolean := false;
    variable right_justify_int : boolean := true;
    variable total_length_int : natural := 0;
    variable point_precision_int : natural := 0;
  begin
    add_sign := false;
    fill_char := ' ';
    for index in 1 to format'length loop
      if find_type then
        write(format_type, format(index));
      end if;
      if find_precision then
        if (format(index) >= '0') and (format(index) <= '9') then
          point_precision_int := 10*point_precision_int + character'pos(format(index)) - character'pos('0');
          if format(index+1) >= 'A' then
            find_precision := false;
            find_type := true;
          end if;
        end if;
      end if;
      if find_length then
        if (format(index) >= '0') and (format(index) <= '9') then
          total_length_int := 10*total_length_int + character'pos(format(index)) - character'pos('0');
        end if;
        if format(index) = '.' then
          find_length := false;
          find_precision := true;
        elsif format(index+1) >= 'A' then
          find_length := false;
          find_type := true;
        end if;
      end if;
      if find_padding then
        if format(index) = '0' then
          if right_justify_int then
            fill_char := '0';
          end if;
        end if;
        find_padding := false;
        if format(index+1) >= 'A' then
          find_type := true;
        else
          find_length := true;
        end if;
      end if;
      if find_sign then
        if format(index) = '-' then
          right_justify_int := false;
        end if;
        if format(index) = '+' then
          add_sign := true;
        end if;
        find_sign := false;
        if format(index+1) <= '-' then
          find_sign := true;
        elsif format(index+1) = '0' then
          find_padding := true;
        elsif format(index+1) >= 'A' then
          find_type := true;
        else
          find_length := true;
        end if;
      end if;
      if format(index) = '%' then
        if format(index+1) <= '-' then
          find_sign := true;
        elsif format(index+1) = '0' then
          find_padding := true;
        elsif format(index+1) >= 'A' then
          find_type := true;
        else
          find_length := true;
        end if;
      end if;
    end loop;
    right_justify := right_justify_int;
    total_length := total_length_int;
    point_precision := point_precision_int;
  end get_format_items;


  ------------------------------------------------------------------------------
  -- formatted string output: converting std_ulogic to character
  ------------------------------------------------------------------------------
  function to_character(value: std_ulogic) return character is
    variable out_value: character;
  begin
    case value is
      when 'U' => out_value := 'U';
      when 'X' => out_value := 'X';
      when '0' => out_value := '0';
      when '1' => out_value := '1';
      when 'Z' => out_value := 'Z';
      when 'W' => out_value := 'W';
      when 'L' => out_value := 'L';
      when 'H' => out_value := 'H';
      when '-' => out_value := '-';
    end case;
    return(out_value);
  end to_character;

  ------------------------------------------------------------------------------
  -- formatted string output: binary integer
  ------------------------------------------------------------------------------
  function sprintf_b(value: std_ulogic_vector) return string is
    variable out_line : line;
  begin
    for index in value'range loop
      write(out_line, to_character(value(index)));
    end loop;
    return(out_line.all);
  end sprintf_b;

  ------------------------------------------------------------------------------
  -- formatted string output: decimal integer
  ------------------------------------------------------------------------------
  function sprintf_d(
    right_justify   : boolean;
    add_sign        : boolean;
    fill_char       : character;
    string_length   : natural;
    value           : integer
  ) return string is
    variable value_line : line;
  begin
    if add_sign and (value >= 0) then
      write(value_line, '+');
    end if;
    write(value_line, value);
    if string_length = 0 then
      return(value_line.all);
    else
      return(pad(value_line.all, string_length, fill_char, right_justify));
    end if;
  end sprintf_d;

  ------------------------------------------------------------------------------
  -- formatted string output: fixed point real
  ------------------------------------------------------------------------------
  function sprintf_f(
    right_justify   : boolean;
    add_sign        : boolean;
    fill_char       : character;
    string_length   : natural;
    point_precision : natural;
    value           : real
  ) return string is
    variable point_precision_int : natural;
    variable integer_part : integer;
    variable decimal_part : natural;
    variable value_line : line;
  begin
    if point_precision = 0 then
      point_precision_int := 6;
    else
      point_precision_int := point_precision;
    end if;
    if value >= 0.0 then
      integer_part := integer(value-0.5);
    else
      integer_part := - integer(-value-0.5);
    end if;
    decimal_part := abs(integer((value-real(integer_part))*(10.0**point_precision_int)));
    if add_sign and (value >= 0.0) then
      write(value_line, '+');
    end if;
    write(value_line, integer_part);
    write(value_line, '.');
    write(value_line, sprintf_d(true, false, '0', point_precision_int, decimal_part));
    if string_length = 0 then
      return(value_line.all);
    else
      return(pad(value_line.all, string_length, fill_char, right_justify));
    end if;
  end sprintf_f;

  ------------------------------------------------------------------------------
  -- formatted string output: hexadecimal integer
  ------------------------------------------------------------------------------
  function sprintf_X(
    extend_unsigned : boolean;
    value           : std_ulogic_vector
  ) return string is
    variable bit_count : positive;
    variable value_line : line;
    variable out_line : line;
    variable nibble: string(1 to 4);
  begin
    bit_count := value'length;
    while (bit_count mod 4) /= 0 loop
      if extend_unsigned then
        write(value_line, to_character('0'));
      else
        write(value_line, to_character(value(value'high)));
      end if;
      bit_count := bit_count + 1;
    end loop;
    write(value_line, sprintf_b(value));
    for index in value_line.all'range loop
      if (index mod 4) = 0 then
        nibble := value_line.all(index-3 to index);
        case nibble is
          when "0000" => write(out_line, 0);
          when "0001" => write(out_line, 1);
          when "0010" => write(out_line, 2);
          when "0011" => write(out_line, 3);
          when "0100" => write(out_line, 4);
          when "0101" => write(out_line, 5);
          when "0110" => write(out_line, 6);
          when "0111" => write(out_line, 7);
          when "1000" => write(out_line, 8);
          when "1001" => write(out_line, 9);
          when "1010" => write(out_line, 'A');
          when "1011" => write(out_line, 'B');
          when "1100" => write(out_line, 'C');
          when "1101" => write(out_line, 'D');
          when "1110" => write(out_line, 'E');
          when "1111" => write(out_line, 'F');
          when others => write(out_line, 'X');
        end case;
      end if;
    end loop;
    return(out_line.all);
  end sprintf_X;


  --============================================================================
  -- formatted string output, interface functions
  --

  ------------------------------------------------------------------------------
  -- integer
  ------------------------------------------------------------------------------
  function sprintf(format : string; value : integer) return string is
    variable right_justify : boolean;
    variable add_sign : boolean;
    variable fill_char : character;
    variable string_length : natural;
    variable point_precision : natural;
    variable format_type : line;
  begin
    get_format_items(format, right_justify, add_sign, fill_char,
                     string_length, point_precision, format_type);
    if format_type.all = "b" then
      if string_length = 0 then
        string_length := 8;
      end if;
      return(sprintf_b(std_ulogic_vector(to_signed(value, string_length+1)(string_length-1 downto 0))));
    elsif format_type.all = "d" then
      return(sprintf_d(right_justify, add_sign, fill_char, string_length, value));
    elsif format_type.all = "f" then
      return(sprintf_f(right_justify, add_sign, fill_char,
                       string_length, point_precision, real(value)));
    elsif (format_type.all = "X") or (format_type.all = "x") then
      if string_length = 0 then
        string_length := 8;
      end if;
      string_length := 4*string_length;
      if format_type.all = "X" then
        return(sprintf_X(false, std_ulogic_vector(to_signed(value, string_length+1)(string_length-1 downto 0))));
      else
        return(lc(sprintf_X(false, std_ulogic_vector(to_signed(value, string_length+1)(string_length-1 downto 0)))));
      end if;
    else
      return("Unhandled format type: '" & format_type.all & "'");
    end if;
  end sprintf;

  ------------------------------------------------------------------------------
  -- real
  ------------------------------------------------------------------------------
  function sprintf(format : string; value : real) return string is
    variable right_justify : boolean;
    variable add_sign : boolean;
    variable fill_char : character;
    variable string_length : natural;
    variable point_precision : natural;
    variable format_type : line;
  begin
    get_format_items(format, right_justify, add_sign, fill_char,
                     string_length, point_precision, format_type);
    if (format_type.all = "d") or (point_precision = 0) then
      return(sprintf_d(right_justify, add_sign, fill_char,
                       string_length, integer(value)));
    elsif format_type.all = "f" then
      return(sprintf_f(right_justify, add_sign, fill_char,
                       string_length, point_precision, value));
    else
      return("Unhandled format type: '" & format_type.all & "'");
    end if;
  end sprintf;

  ------------------------------------------------------------------------------
  -- std_logic
  ------------------------------------------------------------------------------
  function sprintf(format : string; value : std_logic) return string is
    variable right_justify : boolean;
    variable add_sign : boolean;
    variable fill_char : character;
    variable string_length : natural;
    variable point_precision : natural;
    variable format_type : line;
    variable logic_vector: std_logic_vector(1 to 1);
  begin
    get_format_items(format, right_justify, add_sign, fill_char,
                     string_length, point_precision, format_type);
    if (format_type.all = "b") or (format_type.all = "d") or
       (format_type.all = "X") or (format_type.all = "x") then
      logic_vector(1) := value;
      return(sprintf(format, std_ulogic_vector(logic_vector)));
    else
      return("Not a std_logic format: '" & format_type.all & "'");
    end if;
  end sprintf;

  ------------------------------------------------------------------------------
  -- std_ulogic_vector
  ------------------------------------------------------------------------------
  function sprintf(format : string; value : std_ulogic_vector) return string is
    variable right_justify : boolean;
    variable add_sign : boolean;
    variable fill_char : character;
    variable bit_string_length : natural;
    variable point_precision : natural;
    variable format_type : line;
  begin
    get_format_items(format, right_justify, add_sign, fill_char,
                     bit_string_length, point_precision, format_type);
    if format_type.all = "b" then
      return(pad(sprintf_b(value), bit_string_length, fill_char, right_justify));
    elsif format_type.all = "d" then
      return(sprintf_d(right_justify, add_sign, fill_char, bit_string_length, to_integer(unsigned(value))));
    elsif (format_type.all = "X") or (format_type.all = "x") then
      if format_type.all = "X" then
        return(pad(sprintf_X(true, value), bit_string_length, fill_char, right_justify));
      else
        return(lc(pad(sprintf_X(true, value), bit_string_length, fill_char, right_justify)));
      end if;
    else
      return("Not a std_ulogic_vector format: '" & format_type.all & "'");
    end if;
  end sprintf;

  ------------------------------------------------------------------------------
  -- std_logic_vector
  ------------------------------------------------------------------------------
  function sprintf(format : string; value : std_logic_vector) return string is
    variable right_justify : boolean;
    variable add_sign : boolean;
    variable fill_char : character;
    variable string_length : natural;
    variable point_precision : natural;
    variable format_type : line;
  begin
    get_format_items(format, right_justify, add_sign, fill_char,
                     string_length, point_precision, format_type);
    if (format_type.all = "b") or (format_type.all = "d") or
       (format_type.all = "X") or (format_type.all = "x") then
      return(sprintf(format, std_ulogic_vector(value)));
    else
      return("Not a std_logic_vector format: '" & format_type.all & "'");
    end if;
  end sprintf;

  ------------------------------------------------------------------------------
  -- unsigned
  ------------------------------------------------------------------------------
  function sprintf(format : string; value : unsigned) return string is
    variable right_justify : boolean;
    variable add_sign : boolean;
    variable fill_char : character;
    variable string_length : natural;
    variable point_precision : natural;
    variable format_type : line;
  begin
    get_format_items(format, right_justify, add_sign, fill_char,
                     string_length, point_precision, format_type);
    if (format_type.all = "b") or (format_type.all = "d") or
       (format_type.all = "X") or (format_type.all = "x") then
      return(sprintf(format, std_ulogic_vector(value)));
    else
      return("Not an unsigned format: '" & format_type.all & "'");
    end if;
  end sprintf;

  ------------------------------------------------------------------------------
  -- signed
  ------------------------------------------------------------------------------
  function sprintf(format : string; value : signed) return string is
    variable right_justify : boolean;
    variable add_sign : boolean;
    variable fill_char : character;
    variable bit_string_length : natural;
    variable point_precision : natural;
    variable format_type : line;
  begin
    get_format_items(format, right_justify, add_sign, fill_char,
                     bit_string_length, point_precision, format_type);
    if (fill_char = '0') and (value(value'left) = '1') then
      fill_char := '1';
    end if;
    if format_type.all = "b" then
      return(pad(sprintf_b(std_ulogic_vector(value)), bit_string_length, fill_char, right_justify));
    elsif format_type.all = "d" then
      return(sprintf_d(right_justify, add_sign, fill_char, bit_string_length, to_integer(signed(value))));
    elsif (format_type.all = "X") or (format_type.all = "x") then
      if fill_char = '1' then
        fill_char := 'F';
      end if;
      if format_type.all = "X" then
        return(pad(sprintf_X(true, std_ulogic_vector(value)), bit_string_length, fill_char, right_justify));
      else
        return(lc(pad(sprintf_X(true, std_ulogic_vector(value)), bit_string_length, fill_char, right_justify)));
      end if;
    else
      return("Not a signed format: '" & format_type.all & "'");
    end if;
  end sprintf;

  ------------------------------------------------------------------------------
  -- time
  ------------------------------------------------------------------------------
  function sprintf(format : string; value : time) return string is
    variable right_justify : boolean;
    variable add_sign : boolean;
    variable fill_char : character;
    variable string_length : natural;
    variable point_precision : natural;
    variable format_type : line;
    variable scaling : real;
    variable base_time : time;
    variable unit : string(1 to 3);
  begin
    get_format_items(format, right_justify, add_sign, fill_char,
                     string_length, point_precision, format_type);
    if format_type.all(format_type.all'left) = 't' then
      scaling := 10.0**point_precision;
      if format_type.all = "tp" then
        base_time := 1 ps;
        unit := " ps";
      elsif format_type.all = "tn" then
        base_time := 1 ns;
        unit := " ns";
      elsif format_type.all = "tu" then
        base_time := 1 us;
        unit := " us";
      elsif format_type.all = "tm" then
        base_time := 1 ms;
        unit := " ms";
      elsif format_type.all = "ts" then
        base_time := 1 sec;
        unit := " s.";
      else
        return("Undefined time format: '" & format_type.all & "'");
      end if;
      if point_precision = 0 then
        return(sprintf_d(right_justify, add_sign, fill_char,
                         string_length, value/base_time) & unit);
      else
        return(sprintf_f(right_justify, add_sign, fill_char, string_length,
                         point_precision, real(scaling*value/base_time)/scaling) & unit);
      end if;
    else
      return("Not a time format: '" & format_type.all & "'");
    end if;
  end sprintf;


  --============================================================================
  -- formatted string input
  ------------------------------------------------------------------------------

  ------------------------------------------------------------------------------
  -- read a nibble out of a character
  ------------------------------------------------------------------------------
  function sscanf(value : character) return natural is
  begin
    if (value >= '0') and (value <= '9') then
      return(character'pos(value) - character'pos('0'));
    elsif (value >= 'a') and (value <= 'f') then
      return(character'pos(value) - character'pos('a') + 10);
    elsif (value >= 'A') and (value <= 'F') then
      return(character'pos(value) - character'pos('A') + 10);
    else
      return(0);
    end if;
  end sscanf;

  function sscanf(value : character) return nibbleUnsignedType is
  begin
    return(to_unsigned(sscanf(value), nibbleUnsignedType'length));
  end sscanf;

  function sscanf(value : character) return nibbleUlogicType is
    variable unsigned_value : nibbleUnsignedType;
  begin
    unsigned_value := sscanf(value);
    return(std_ulogic_vector(unsigned_value));
  end sscanf;

  ------------------------------------------------------------------------------
  -- read an binary word out of a string
  ------------------------------------------------------------------------------
  function sscanf(value : string) return natural is
    variable integer_value : natural;
  begin
    integer_value := 0;
    for index in value'left to value'right loop
      integer_value := integer_value*16 + sscanf(value(index));
    end loop;
    return(integer_value);
  end;

  function sscanf(value : string) return unsigned is
    variable unsigned_value : unsigned(4*value'length-1 downto 0);
  begin
    unsigned_value := to_unsigned(0,unsigned_value'length);
    for index in value'left to value'right loop
      unsigned_value := shift_left(unsigned_value,4) + to_unsigned(sscanf(value(index)),4);
    end loop;
    return(unsigned_value);
  end;

  function sscanf(value : string) return std_ulogic_vector is
    variable unsigned_value : unsigned(4*value'length-1 downto 0);
  begin
    unsigned_value := sscanf(value);
    return(std_ulogic_vector(unsigned_value));
  end;

  ------------------------------------------------------------------------------
  -- read time from a string
  -- time can be formated as follows:
  --   "1ps" or "1 ps" or " 1 ps " or " 1ps"
  -- possible time units are: hr, min, sec, ms, us, ns, ps, fs
  ------------------------------------------------------------------------------
  procedure sscanf(
     value    : inout line;
     time_val : out time
  ) is
      variable time_line  : line := value;
      variable time_base  : string(1 to 3);
      variable time_value : integer;
      variable time_int   : time;
  begin
    -- remove all spaces and tabs
    rm_all_separators(time_line);

    -- strip time base (3 last characters)
    time_base := time_line(time_line'right-2 to time_line'right);

    -- separate time value and base
    if time_base(2 to 3) = "hr" then
        time_int   := 1 hr;
        time_value := integer'value(time_line(time_line'left to time_line'right -2));
    elsif time_base = "min" then
        time_int   := 1 min;
        time_value := integer'value(time_line(time_line'left to time_line'right -3));
    elsif time_base = "sec" then
        time_int   := 1 sec;
        time_value := integer'value(time_line(time_line'left to time_line'right -3));
    elsif time_base(2 to 3) = "ms" then
        time_int   := 1 ms;
        time_value := integer'value(time_line(time_line'left to time_line'right -2));
    elsif time_base(2 to 3) = "us" then
        time_int   := 1 us;
        time_value := integer'value(time_line(time_line'left to time_line'right -2));
    elsif time_base(2 to 3) = "ns" then
        time_int   := 1 ns;
        time_value := integer'value(time_line(time_line'left to time_line'right -2));
    elsif time_base(2 to 3) = "ps" then
        time_int   := 1 ps;
        time_value := integer'value(time_line(time_line'left to time_line'right -2));
    elsif time_base(2 to 3) = "fs" then
        time_int   := 1 fs;
        time_value := integer'value(time_line(time_line'left to time_line'right -2));
    else
        time_int   := 0 ps;
        time_value := 1;
    end if;

    -- build time from value and base
    time_val := time_int * time_value;

  end;

  function sscanf(value : string) return time is
    variable value_line : line;
    variable time_val   : time;
  begin
    value_line := new string'(value);
    sscanf(value_line, time_val);
    return(time_val);
  end;

END testUtils;




LIBRARY std;
  USE std.textio.ALL;

LIBRARY ieee;
  USE ieee.std_logic_textio.ALL;

LIBRARY Common_test;
  USE Common_test.testutils.all;

ARCHITECTURE test OF universalTester IS

  constant clockPeriod  : time := 1.0/66E6 * 1 sec;
  signal sClock         : std_uLogic := '1';
  signal sReset         : std_uLogic ;

  signal testInfo       : string(1 to 40) := (others => ' ');

BEGIN

 ------------------------------------------------------------------------------
                                                              -- reset and clock
  sReset <= '1', '0' after 3.5*clockPeriod;
  rst <= sReset;

  sClock <= not sClock after clockPeriod/2;
  clk <= transport sClock after 0.9*clockPeriod;

  btns <= (others => '1'), (others=>'0') after 4.15 us;

  process
    -- Wait list
    -- 3 clk for beq
    -- 4 clk for others
    -- 5 clk for lw
  begin
    en <= '0';

    testInfo <= pad("Wait reset", testInfo'length);
    wait until rst = '0';

    while true loop
      en <= '1';

      testInfo <= pad("Running", testInfo'length);
      wait;

    end loop;
  end process;

END ARCHITECTURE test;





-- VHDL Entity HEIRV32.heirv32.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 10:23:07 21.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY heirv32 IS
    GENERIC( 
        g_programFile : string   := "$SIMULATION_DIR/code.txt";
        g_btnsNb      : positive := 2;
        g_dataWidth   : positive := 32
    );
    PORT( 
        btns     : IN     std_ulogic_vector (g_btnsNb-1 DOWNTO 0);
        clk      : IN     std_ulogic;
        en       : IN     std_ulogic;
        rst      : IN     std_ulogic;
        dbg_leds : OUT    std_ulogic_vector (31 DOWNTO 0);
        leds     : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );

-- Declarations

END heirv32 ;





LIBRARY ieee;
USE ieee.std_logic_1164.all;

PACKAGE gates IS

--  constant gateDelay: time := 1 ns;
  constant gateDelay: time := 0.1 ns;

END gates;




-- VHDL Entity gates.transUnsignedUlog.symbol
--
-- Created:
--          by - silvan.zahno.UNKNOWN (WE6996)
--          at - 14:35:04 11.09.2019
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
  USE gates.gates.all;

ENTITY transUnsignedUlog IS
    GENERIC( 
        delay     : time     := gateDelay;
        dataBitNb : positive := 8
    );
    PORT( 
        in1  : IN     unsigned (dataBitNb-1 DOWNTO 0);
        out1 : OUT    std_ulogic_vector (dataBitNb-1 DOWNTO 0)
    );

-- Declarations

END transUnsignedUlog ;





ARCHITECTURE sim OF transUnsignedUlog IS
BEGIN
  out1 <= std_ulogic_vector(in1) after delay;
END ARCHITECTURE sim;




-- VHDL Entity HEIRV32.ALU.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 13:26:28 11.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY ALU IS
    GENERIC( 
        g_datawidth : positive := 32
    );
    PORT( 
        ctrl : IN     std_ulogic_vector (2 DOWNTO 0);
        srcA : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        srcB : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        res  : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        zero : OUT    std_ulogic
    );

-- Declarations

END ALU ;





-- Risc-V ed. 2022 page 250 (pdf page 273)

ARCHITECTURE rtl OF ALU IS

    signal lvec_res : std_ulogic_vector(res'range);

BEGIN

    zero <= '1' when lvec_res = (lvec_res'range => '0') else '0';
    res <= lvec_res;

    alu : process(srcA, srcB, ctrl)
    begin
        case ctrl is
            when "000" => -- add
                lvec_res <= std_ulogic_vector(resize(
                    unsigned(srcA) + unsigned(srcB), lvec_res'length
                ));
            when "001" => -- substract
                lvec_res <= std_ulogic_vector(resize(
                    unsigned(srcA) - unsigned(srcB), lvec_res'length
                ));
            when "010" => -- AND
                lvec_res <= srcA and srcB;
            when "011" => -- OR
                lvec_res <= srcA or srcB;
            when "101" => -- SLT
                if srcA < srcB then
                    lvec_res <= (lvec_res'high downto 1 => '0') & '1';
                else
                    lvec_res <= (lvec_res'high downto 1 => '0') & '0';
                end if;
            when others => -- unknown
                lvec_res <= (others => '-');
        end case;
    end process alu;

END ARCHITECTURE rtl;




-- VHDL Entity HEIRV32.bufferStdULogEnable.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 15:01:42 11.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY bufferStdULogEnable IS
    GENERIC( 
        g_dataWidth : positive := 32
    );
    PORT( 
        clk  : IN     std_ulogic;
        en   : IN     std_uLogic;
        in1  : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        rst  : IN     std_ulogic;
        out1 : OUT    std_ulogic_vector (g_dataWidth - 1 DOWNTO 0)
    );

-- Declarations

END bufferStdULogEnable ;






ARCHITECTURE rtl OF bufferStdULogEnable IS
BEGIN

    buffering:process(rst, CLK)
	begin
		if rst = '1' then
			out1 <= (others=>'0');
		elsif rising_edge(CLK) then
			if EN = '1' then
				out1 <= in1;
			end if;
		end if;
	end process buffering;
	
END ARCHITECTURE rtl;





-- VHDL Entity gates.and2.symbol
--
-- Created:
--          by - silvan.zahno.UNKNOWN (WE6996)
--          at - 14:34:52 11.09.2019
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
LIBRARY gates;
  USE gates.gates.all;

ENTITY and2 IS
    GENERIC( 
        delay : time := gateDelay
    );
    PORT( 
        in1  : IN     std_uLogic;
        in2  : IN     std_uLogic;
        out1 : OUT    std_uLogic
    );

-- Declarations

END and2 ;





ARCHITECTURE sim OF and2 IS
BEGIN
  out1 <= in1 and in2 after delay;
END ARCHITECTURE sim;




-- VHDL Entity HEIRV32.controlUnit.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 15:37:23 24.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY controlUnit IS
    GENERIC( 
        g_datawidth : positive := 32
    );
    PORT( 
        clk        : IN     std_ulogic;
        en         : IN     std_ulogic;
        funct3     : IN     std_ulogic_vector (2 DOWNTO 0);
        funct7     : IN     std_ulogic;
        op         : IN     std_ulogic_vector (6 DOWNTO 0);
        rst        : IN     std_ulogic;
        zero       : IN     std_ulogic;
        ALUControl : OUT    std_ulogic_vector (2 DOWNTO 0);
        ALUSrcA    : OUT    std_ulogic_vector (1 DOWNTO 0);
        ALUSrcB    : OUT    std_ulogic_vector (1 DOWNTO 0);
        IRWrite    : OUT    std_ulogic;
        PCWrite    : OUT    std_ulogic;
        adrSrc     : OUT    std_uLogic;
        immSrc     : OUT    std_ulogic_vector (1 DOWNTO 0);
        memWrite   : OUT    std_ulogic;
        regwrite   : OUT    std_ulogic;
        resultSrc  : OUT    std_ulogic_vector (1 DOWNTO 0)
    );

-- Declarations

END controlUnit ;





-- VHDL Entity gates.or2.symbol
--
-- Created:
--          by - silvan.zahno.UNKNOWN (WE6996)
--          at - 14:35:09 11.09.2019
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
LIBRARY gates;
  USE gates.gates.all;

ENTITY or2 IS
    GENERIC( 
        delay : time := gateDelay
    );
    PORT( 
        in1  : IN     std_uLogic;
        in2  : IN     std_uLogic;
        out1 : OUT    std_uLogic
    );

-- Declarations

END or2 ;





ARCHITECTURE sim OF or2 IS
BEGIN
  out1 <= in1 or in2 after delay;
END ARCHITECTURE sim;




-- VHDL Entity HEIRV32.aluDecoder.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 15:46:03 04.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY aluDecoder IS
    PORT( 
        ALUOp      : IN     std_ulogic_vector (1 DOWNTO 0);
        funct3     : IN     std_ulogic_vector (2 DOWNTO 0);
        funct7     : IN     std_ulogic;
        op         : IN     std_ulogic;
        ALUControl : OUT    std_ulogic_vector (2 DOWNTO 0)
    );

-- Declarations

END aluDecoder ;






ARCHITECTURE rtl OF aluDecoder IS
    signal lsig_rTypeSub : std_ulogic;
BEGIN
    lsig_rTypeSub <= funct7 and op; -- true for R-type substract

    decode : process(op, funct3, funct7, ALUOp, lsig_rTypeSub)
    begin
        case ALUOp is
            when "00" => ALUControl <= "000"; -- addition
            when "01" => ALUControl <= "001"; -- substraction
            when others =>
                case funct3 is -- R-type or I-type
                    when "000" =>
                        if lsig_rTypeSub = '1' then
                            ALUControl <= "001"; -- sub
                        else
                            ALUControl <= "000"; -- add, addi
                        end if;
                    when "010" => ALUControl <= "101"; -- slt, slti
                    when "110" => ALUControl <= "011"; -- or, ori
                    when "111" => ALUControl <= "010"; -- and, andi
                    when others => ALUControl <= "---"; -- unknown
                end case;
        end case;
    end process decode;
END ARCHITECTURE rtl;




-- VHDL Entity HEIRV32.instrDecoder.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 15:47:22 04.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY instrDecoder IS
    PORT( 
        op     : IN     std_ulogic_vector (6 DOWNTO 0);
        immSrc : OUT    std_ulogic_vector (1 DOWNTO 0)
    );

-- Declarations

END instrDecoder ;






ARCHITECTURE rtl OF instrDecoder IS
BEGIN

    decode : process(op)
    begin
        case op is
            when "0000011" => immSrc <= "00"; -- lw
            when "0100011" => immSrc <= "01"; -- sw
            when "0110011" => immSrc <= "--"; -- R-type
            when "1100011" => immSrc <= "10"; -- beq
            when "0010011" => immSrc <= "00"; -- l-type ALU
            when "1101111" => immSrc <= "11"; -- jal
            when others => immSrc <= "--"; -- unknwon
        end case;
    end process decode;

END ARCHITECTURE rtl;




-- VHDL Entity HEIRV32.mainFSM.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE2332101)
--          at - 09:29:07 18.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY mainFSM IS
    PORT( 
        clk       : IN     std_ulogic;
        en        : IN     std_ulogic;
        op        : IN     std_ulogic_vector (6 DOWNTO 0);
        rst       : IN     std_ulogic;
        ALUOp     : OUT    std_ulogic_vector (1 DOWNTO 0);
        ALUSrcA   : OUT    std_ulogic_vector (1 DOWNTO 0);
        ALUSrcB   : OUT    std_ulogic_vector (1 DOWNTO 0);
        IRWrite   : OUT    std_ulogic;
        PCupdate  : OUT    std_uLogic;
        adrSrc    : OUT    std_uLogic;
        branch    : OUT    std_uLogic;
        memWrite  : OUT    std_ulogic;
        regwrite  : OUT    std_ulogic;
        resultSrc : OUT    std_ulogic_vector (1 DOWNTO 0)
    );

-- Declarations

END mainFSM ;





--
-- VHDL Architecture HEIRV32.mainFSM.fsm
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 15:37:29 24.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;
 
ARCHITECTURE fsm OF mainFSM IS

    TYPE STATE_TYPE IS (
        s0_Fetch,
        s1_Decode,
        s2_MemAdr,
        s6_ExecuteR,
        s8_ExecuteI,
        s9_JAL,
        s10_BEQ,
        s3_MemRead,
        s4_MemWB,
        s5_MemWrite,
        s7_ALUWB
    );
 
    -- Declare current and next state signals
    SIGNAL current_state : STATE_TYPE;
    SIGNAL next_state : STATE_TYPE;

BEGIN

    -----------------------------------------------------------------
    clocked_proc : PROCESS ( 
        clk,
        rst
    )
    -----------------------------------------------------------------
    BEGIN
        IF (rst = '1') THEN
            current_state <= s0_Fetch;
        ELSIF (clk'EVENT AND clk = '1') THEN
            current_state <= next_state;
        END IF;
    END PROCESS clocked_proc;
 
    -----------------------------------------------------------------
    nextstate_proc : PROCESS ( 
        current_state,
        en,
        op
    )
    -----------------------------------------------------------------
    BEGIN
        CASE current_state IS
            WHEN s0_Fetch => 
                IF (en = '1') THEN 
                    next_state <= s1_Decode;
                ELSE
                    next_state <= s0_Fetch;
                END IF;
            WHEN s1_Decode => 
                IF ((op = "0000011" OR op = "0100011") AND en = '1') THEN 
                    next_state <= s2_MemAdr;
                ELSIF (op = "0110011" AND en = '1') THEN 
                    next_state <= s6_ExecuteR;
                ELSIF (op = "0010011" AND en = '1') THEN 
                    next_state <= s8_ExecuteI;
                ELSIF (op = "1101111" AND en = '1') THEN 
                    next_state <= s9_JAL;
                ELSIF (op = "1100011" AND en = '1') THEN 
                    next_state <= s10_BEQ;
                ELSIF (en = '1') THEN 
                    next_state <= s0_Fetch;
                ELSE
                    next_state <= s1_Decode;
                END IF;
            WHEN s2_MemAdr => 
                IF (op = "0000011" AND en = '1') THEN 
                    next_state <= s3_MemRead;
                ELSIF (op = "0100011" AND en = '1') THEN 
                    next_state <= s5_MemWrite;
                ELSIF (en = '1') THEN 
                    next_state <= s0_Fetch;
                ELSE
                    next_state <= s2_MemAdr;
                END IF;
            WHEN s6_ExecuteR => 
                IF (en = '1') THEN 
                    next_state <= s7_ALUWB;
                ELSE
                    next_state <= s6_ExecuteR;
                END IF;
            WHEN s8_ExecuteI => 
                IF (en = '1') THEN 
                    next_state <= s7_ALUWB;
                ELSE
                    next_state <= s8_ExecuteI;
                END IF;
            WHEN s9_JAL => 
                IF (en = '1') THEN 
                    next_state <= s7_ALUWB;
                ELSE
                    next_state <= s9_JAL;
                END IF;
            WHEN s10_BEQ => 
                IF (en = '1') THEN 
                    next_state <= s0_Fetch;
                ELSE
                    next_state <= s10_BEQ;
                END IF;
            WHEN s3_MemRead => 
                IF (en = '1') THEN 
                    next_state <= s4_MemWB;
                ELSE
                    next_state <= s3_MemRead;
                END IF;
            WHEN s4_MemWB => 
                IF (en = '1') THEN 
                    next_state <= s0_Fetch;
                ELSE
                    next_state <= s4_MemWB;
                END IF;
            WHEN s5_MemWrite => 
                IF (en = '1') THEN 
                    next_state <= s0_Fetch;
                ELSE
                    next_state <= s5_MemWrite;
                END IF;
            WHEN s7_ALUWB => 
                IF (en = '1') THEN 
                    next_state <= s0_Fetch;
                ELSE
                    next_state <= s7_ALUWB;
                END IF;
            WHEN OTHERS =>
                next_state <= s0_Fetch;
        END CASE;
    END PROCESS nextstate_proc;
 
    -----------------------------------------------------------------
    output_proc : PROCESS ( 
        current_state
    )
    -----------------------------------------------------------------
    BEGIN
        -- Default Assignment
        ALUOp <= "00";
        ALUSrcA <= "00";
        ALUSrcB <= "00";
        IRWrite <= '0';
        PCupdate <= '0';
        adrSrc <= '0';
        branch <= '0';
        memWrite <= '0';
        regwrite <= '0';
        resultSrc <= "00";

        -- Combined Actions
        CASE current_state IS
            WHEN s0_Fetch => 
                adrSrc <= '0' ;
                IRWrite <= '1' ;
                ALUSrcA <= "00" ;
                ALUSrcB <= "10" ;
                ALUOp <= "00" ;
                resultSrc <= "10" ;
                PCupdate <= '1' ;
            WHEN s1_Decode => 
                ALUSrcA <= "01" ;
                ALUSrcB <= "01" ;
                ALUOp <= "00" ;
            WHEN s2_MemAdr => 
                ALUSrcA <= "10" ;
                ALUSrcB <= "01" ;
                ALUOp <= "00" ;
            WHEN s6_ExecuteR => 
                ALUSrcA <= "10" ;
                ALUSrcB <= "00" ;
                ALUOp <= "10" ;
            WHEN s8_ExecuteI => 
                ALUSrcA <= "10" ;
                ALUSrcB <= "01" ;
                ALUOp <= "10" ;
            WHEN s9_JAL => 
                ALUSrcA <= "01" ;
                ALUSrcB <= "10" ;
                ALUOp <= "00" ;
                resultSrc <= "00" ;
                PCupdate <= '1' ;
            WHEN s10_BEQ => 
                ALUSrcA <= "10" ;
                ALUSrcB <= "00" ;
                ALUOp <= "01" ;
                resultSrc <= "00" ;
                branch <= '1' ;
            WHEN s3_MemRead => 
                adrSrc <= '1' ;
                resultSrc <= "00" ;
            WHEN s4_MemWB => 
                resultSrc <= "01" ;
                regwrite <= '1' ;
            WHEN s5_MemWrite => 
                adrSrc <= '1' ;
                resultSrc <= "00" ;
                memWrite <= '1' ;
            WHEN s7_ALUWB => 
                resultSrc <= "00" ;
                regwrite <= '1' ;
            WHEN OTHERS =>
                NULL;
        END CASE;
    END PROCESS output_proc;
 
END fsm;




--
-- VHDL Architecture HEIRV32.controlUnit.struct
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 15:37:23 24.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

LIBRARY HEIRV32;

ARCHITECTURE struct OF controlUnit IS

    -- Architecture declarations

    -- Internal signal declarations
    SIGNAL ALUOp    : std_ulogic_vector(1 DOWNTO 0);
    SIGNAL PCupdate : std_uLogic;
    SIGNAL branch   : std_uLogic;
    SIGNAL out1     : std_uLogic;


    -- Component Declarations
    COMPONENT and2
    GENERIC (
        delay : time := gateDelay
    );
    PORT (
        in1  : IN     std_uLogic ;
        in2  : IN     std_uLogic ;
        out1 : OUT    std_uLogic 
    );
    END COMPONENT;
    COMPONENT or2
    GENERIC (
        delay : time := gateDelay
    );
    PORT (
        in1  : IN     std_uLogic ;
        in2  : IN     std_uLogic ;
        out1 : OUT    std_uLogic 
    );
    END COMPONENT;
    COMPONENT aluDecoder
    PORT (
        ALUOp      : IN     std_ulogic_vector (1 DOWNTO 0);
        funct3     : IN     std_ulogic_vector (2 DOWNTO 0);
        funct7     : IN     std_ulogic ;
        op         : IN     std_ulogic ;
        ALUControl : OUT    std_ulogic_vector (2 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT instrDecoder
    PORT (
        op     : IN     std_ulogic_vector (6 DOWNTO 0);
        immSrc : OUT    std_ulogic_vector (1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT mainFSM
    PORT (
        clk       : IN     std_ulogic ;
        en        : IN     std_ulogic ;
        op        : IN     std_ulogic_vector (6 DOWNTO 0);
        rst       : IN     std_ulogic ;
        ALUOp     : OUT    std_ulogic_vector (1 DOWNTO 0);
        ALUSrcA   : OUT    std_ulogic_vector (1 DOWNTO 0);
        ALUSrcB   : OUT    std_ulogic_vector (1 DOWNTO 0);
        IRWrite   : OUT    std_ulogic ;
        PCupdate  : OUT    std_uLogic ;
        adrSrc    : OUT    std_uLogic ;
        branch    : OUT    std_uLogic ;
        memWrite  : OUT    std_ulogic ;
        regwrite  : OUT    std_ulogic ;
        resultSrc : OUT    std_ulogic_vector (1 DOWNTO 0)
    );
    END COMPONENT;

    -- Optional embedded configurations
    -- pragma synthesis_off
    FOR ALL : aluDecoder USE ENTITY HEIRV32.aluDecoder;
    FOR ALL : and2 USE ENTITY gates.and2;
    FOR ALL : instrDecoder USE ENTITY HEIRV32.instrDecoder;
    FOR ALL : mainFSM USE ENTITY HEIRV32.mainFSM;
    FOR ALL : or2 USE ENTITY gates.or2;
    -- pragma synthesis_on


BEGIN

    -- Instance port mappings.
    U_1 : and2
        GENERIC MAP (
            delay => gateDelay
        )
        PORT MAP (
            in1  => zero,
            in2  => branch,
            out1 => out1
        );
    U_0 : or2
        GENERIC MAP (
            delay => gateDelay
        )
        PORT MAP (
            in1  => out1,
            in2  => PCupdate,
            out1 => PCWrite
        );
    U_2 : aluDecoder
        PORT MAP (
            ALUOp      => ALUOp,
            funct3     => funct3,
            funct7     => funct7,
            op         => op(5),
            ALUControl => ALUControl
        );
    U_4 : instrDecoder
        PORT MAP (
            op     => op,
            immSrc => immSrc
        );
    U_mainFSM : mainFSM
        PORT MAP (
            clk       => clk,
            en        => en,
            op        => op,
            rst       => rst,
            ALUOp     => ALUOp,
            ALUSrcA   => ALUSrcA,
            ALUSrcB   => ALUSrcB,
            IRWrite   => IRWrite,
            PCupdate  => PCupdate,
            adrSrc    => adrSrc,
            branch    => branch,
            memWrite  => memWrite,
            regwrite  => regwrite,
            resultSrc => resultSrc
        );

END struct;




-- VHDL Entity HEIRV32.extend.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE2332101)
--          at - 12:47:32 18.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY extend IS
    GENERIC( 
        g_dataWidth : positive := 32
    );
    PORT( 
        input    : IN     std_ulogic_vector (31 DOWNTO 7);
        src      : IN     std_ulogic_vector (1 DOWNTO 0);
        extended : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );

-- Declarations

END extend ;






ARCHITECTURE rtl OF extend IS
BEGIN

    extend : process(input, src)
    begin
        case src is
            when "00" => -- I-type
                extended <= (12 to 31 => input(31)) &
                    input(31 downto 20);
            when "01" => -- S-types (stores)
                extended <= (12 to 31 => input(31)) &
                    input(31 downto 25) & input(11 downto 7);
            when "10" => -- B-type (branches)
                extended <= (12 to 31 => input(31)) & input(7) &
                    input(30 downto 25) & input(11 downto 8) & '0';
            when "11" => -- J-type (jal)
                extended <= (20 to 31 => input(31)) &
                    input(19 downto 12) & input(20) &
                    input(30 downto 21) & '0';
            when others => -- impossible
                extended <= (others => '-');
        end case;
    end process extend;

END ARCHITECTURE rtl;




-- VHDL Entity HEIRV32.instructionDataMemory.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 18:08:43 18.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY instructionDataMemory IS
    GENERIC( 
        g_dataWidth   : positive := 32;
        g_addrWidth   : positive := 10;
        g_programFile : string   := ""
    );
    PORT( 
        address     : IN     unsigned (g_dataWidth-1 DOWNTO 0);
        clk         : IN     std_ulogic;
        en          : IN     std_ulogic;
        writeData   : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        writeEnable : IN     std_ulogic;
        readData    : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );

-- Declarations

END instructionDataMemory ;





-- VHDL Entity Memory.bram.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 15:51:22 11.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    USE ieee.numeric_std.all;

ENTITY bram IS
    GENERIC( 
        addressBitNb : positive := 8;
        dataBitNb    : positive := 8;
        initFile     : string   := "bramInit.txt"
    );
    PORT( 
        clock     : IN     std_ulogic;
        en        : IN     std_ulogic;
        writeEn   : IN     std_ulogic;
        addressIn : IN     std_ulogic_vector (addressBitNb-1 DOWNTO 0);
        dataIn    : IN     std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        dataOut   : OUT    std_ulogic_vector (dataBitNb-1 DOWNTO 0)
    );

-- Declarations

END bram ;





library ieee;
  use std.textio.all;
  use ieee.std_logic_textio.all;

ARCHITECTURE hexRead OF bram IS
    -- Define ramContent type
  type ramContentType is array(0 to (2**addressBitNb)-1) of std_logic_vector(dataBitNb-1 DOWNTO 0);

  -- Define function to create initvalue signal
  impure function ReadRamContentFromFile(ramContentFilenAme : in string) return ramContentType is
    FILE     ramContentFile     : text is in ramContentFilenAme;
    variable ramContentFileLine : line;
    variable ramContent         : ramContentType;
  begin
    for i in ramContentType'range loop
      readline(ramContentFile, ramContentFileLine);
      HREAD(ramContentFileLine, ramContent(i));
    end loop;
    return ramContent;
  end function;

  -- Declare ramContent signal
  shared variable ramContent: ramContentType := ReadRamContentFromFile(initFile);

BEGIN

  -- Port A
  process(clock)
  begin
    if clock'event and clock='1' then
      if en = '1' then
        if writeEn = '1' then
          dataOut <= dataIn;
          ramContent(to_integer(unsigned(addressIn))) := std_logic_vector(dataIn);
        else
          dataOut <= to_stdulogicvector(ramContent(to_integer(unsigned(addressIn))));
        end if;
      end if;
    end if;
  end process;

END ARCHITECTURE hexRead;




-- VHDL Entity HEIRV32.bramAddrReducer.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE2332111)
--          at - 16:20:19 11.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY bramAddrReducer IS
    GENERIC( 
        g_dataWidth : positive := 32;
        g_addrWidth : positive := 10
    );
    PORT( 
        addrIn  : IN     unsigned (g_dataWidth-1 DOWNTO 0);
        addrOut : OUT    std_ulogic_vector (g_addrWidth-1 DOWNTO 0)
    );

-- Declarations

END bramAddrReducer ;






ARCHITECTURE rtl OF bramAddrReducer IS
BEGIN
	-- +2 to srr(2) the address (as it makes +4)
	addrOut <= std_ulogic_vector(addrIn(addrOut'high+2 downto addrOut'low+2));
END ARCHITECTURE rtl;




--
-- VHDL Architecture HEIRV32.instructionDataMemory.struct
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 15:38:02 24.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

LIBRARY HEIRV32;
LIBRARY Memory;

ARCHITECTURE struct OF instructionDataMemory IS

    -- Architecture declarations

    -- Internal signal declarations
    SIGNAL out1 : std_ulogic_vector(g_addrWidth-1 DOWNTO 0);


    -- Component Declarations
    COMPONENT bramAddrReducer
    GENERIC (
        g_dataWidth : positive := 32;
        g_addrWidth : positive := 10
    );
    PORT (
        addrIn  : IN     unsigned (g_dataWidth-1 DOWNTO 0);
        addrOut : OUT    std_ulogic_vector (g_addrWidth-1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT bram
    GENERIC (
        addressBitNb : positive := 8;
        dataBitNb    : positive := 8;
        initFile     : string   := "bramInit.txt"
    );
    PORT (
        clock     : IN     std_ulogic ;
        en        : IN     std_ulogic ;
        writeEn   : IN     std_ulogic ;
        addressIn : IN     std_ulogic_vector (addressBitNb-1 DOWNTO 0);
        dataIn    : IN     std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        dataOut   : OUT    std_ulogic_vector (dataBitNb-1 DOWNTO 0)
    );
    END COMPONENT;

    -- Optional embedded configurations
    -- pragma synthesis_off
    FOR ALL : bram USE ENTITY Memory.bram;
    FOR ALL : bramAddrReducer USE ENTITY HEIRV32.bramAddrReducer;
    -- pragma synthesis_on


BEGIN

    -- Instance port mappings.
    U_bramAddrReducer : bramAddrReducer
        GENERIC MAP (
            g_dataWidth => g_dataWidth,
            g_addrWidth => g_addrWidth
        )
        PORT MAP (
            addrIn  => address,
            addrOut => out1
        );
    U_bram : bram
        GENERIC MAP (
            addressBitNb => g_addrWidth,
            dataBitNb    => g_dataWidth,
            initFile     => g_programFile
        )
        PORT MAP (
            clock     => clk,
            en        => en,
            writeEn   => writeEnable,
            addressIn => out1,
            dataIn    => writeData,
            dataOut   => readData
        );

END struct;




-- VHDL Entity HEIRV32.instructionForwarder.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE2332101)
--          at - 16:10:50 18.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY instructionForwarder IS
    GENERIC( 
        g_dataWidth : positive := 32
    );
    PORT( 
        irWrite     : IN     std_ulogic;
        readData    : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        instruction : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );

-- Declarations

END instructionForwarder ;






ARCHITECTURE rtl OF instructionForwarder IS
    signal lvec_irMem : std_ulogic_vector(readData'range);
BEGIN

--    forwardIR : process(rst, clk)
--    begin
--        if rst = '1' then
--            lvec_irMem <= (others => '0');
--        elsif rising_edge(clk) then
--            if en = '1' and IRWrite = '1' then
--                lvec_irMem <= readData;
--            end if;
--        end if;
--    end process forwardIR;

    forwardIR : process(readData, irWrite)
    begin
        if irWrite = '1' then
            lvec_irMem <= readData;
        end if;
    end process forwardIR;

    instruction <= lvec_irMem;

END ARCHITECTURE rtl;




-- VHDL Entity HEIRV32.bufferUnsignedEnable.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 13:59:57 27.09.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY bufferUnsignedEnable IS
    GENERIC( 
        g_bitNb : positive := 32
    );
    PORT( 
        clk  : IN     std_ulogic;
        en   : IN     std_ulogic;
        in1  : IN     unsigned (g_bitNb - 1 DOWNTO 0);
        rst  : IN     std_ulogic;
        out1 : OUT    unsigned (g_bitNb - 1 DOWNTO 0)
    );

-- Declarations

END bufferUnsignedEnable ;






ARCHITECTURE rtl OF bufferUnsignedEnable IS
BEGIN

    buffering:process(rst, CLK)
	begin
		if rst = '1' then
			out1 <= (others=>'0');
		elsif rising_edge(CLK) then
			if EN = '1' then
				out1 <= in1;
			end if;
		end if;
	end process buffering;

END ARCHITECTURE rtl;




-- VHDL Entity gates.mux2to1Unsigned.symbol
--
-- Created:
--          by - silvan.zahno.UNKNOWN (WE6996)
--          at - 14:35:12 11.09.2019
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
  USE gates.gates.all;

ENTITY mux2to1Unsigned IS
    GENERIC( 
        dataBitNb : positive := 8;
        delay     : time     := gateDelay
    );
    PORT( 
        in0    : IN     unsigned (dataBitNb-1 DOWNTO 0);
        in1    : IN     unsigned (dataBitNb-1 DOWNTO 0);
        sel    : IN     std_uLogic;
        muxOut : OUT    unsigned (dataBitNb-1 DOWNTO 0)
    );

-- Declarations

END mux2to1Unsigned ;





ARCHITECTURE sim OF mux2to1Unsigned IS

  signal selInt: std_ulogic;

BEGIN

  selInt <= to_X01(sel);

  muxSelect: process(selInt, in0, in1)
  begin
    if selInt = '0' then
      muxOut <= in0 after delay;
    elsif selInt = '1' then
      muxOut <= in1 after delay;
    elsif in0 = in1 then
      muxOut <= in0 after delay;
    else
      muxOut <= (others => 'X') after delay;
    end if;
  end process muxSelect;

END ARCHITECTURE sim;




-- VHDL Entity HEIRV32.registerFile.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 10:23:24 21.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY registerFile IS
    GENERIC( 
        g_dataWidth : positive := 32;
        g_btnsNb    : positive := 2
    );
    PORT( 
        addr1        : IN     std_ulogic_vector (4 DOWNTO 0);
        addr2        : IN     std_ulogic_vector (4 DOWNTO 0);
        addr3        : IN     std_ulogic_vector (4 DOWNTO 0);
        btns         : IN     std_ulogic_vector (g_btnsNb-1 DOWNTO 0);
        clk          : IN     std_ulogic;
        en           : IN     std_ulogic;
        rst          : IN     std_ulogic;
        writeData    : IN     std_ulogic_vector (g_dataWidth - 1 DOWNTO 0);
        writeEnable3 : IN     std_ulogic;
        RD1          : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        RD2          : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        leds         : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );

-- Declarations

END registerFile ;






ARCHITECTURE rtl OF registerFile IS
    -- Bank of register
    type t_registersBank is array (31 downto 0) of
        std_ulogic_vector(31 downto 0);
    -- A bank of registers
    signal larr_registers: t_registersBank;
BEGIN

    -- Clocked write
    process(rst, clk) begin
    if rst = '1' then
        larr_registers <= (others => (others => '0'));
    elsif rising_edge(clk) then
        if writeEnable3 = '1' and en = '1' then
            larr_registers(to_integer(unsigned(addr3))) <= writeData;
        end if;
    end if;
    end process;

    -- Comb. read
    -- Addr 0 wired to 0s
    process(addr1, addr2) begin
        if (to_integer(unsigned(addr1)) = 0) then
            RD1 <= (others => '0');
        elsif (to_integer(unsigned(addr1)) = 31) then -- buttons
            RD1 <= (btns'length to g_datawidth-1 => '0') & btns;
        else
            RD1 <= larr_registers(to_integer(unsigned(addr1)));
        end if;

        if (to_integer(unsigned(addr2)) = 0) then
            RD2 <= (others => '0');
        elsif (to_integer(unsigned(addr2)) = 31) then -- buttons
            RD2 <= (btns'length to g_datawidth-1 => '0') & btns;
        else
            RD2 <= larr_registers(to_integer(unsigned(addr2)));
        end if;
    end process;

    leds <= larr_registers(30);

END ARCHITECTURE rtl;




-- VHDL Entity HEIRV32.mux4To1ULogVec.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 15:23:48 11.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

ENTITY mux4To1ULogVec IS
    GENERIC( 
        g_dataWidth : positive := 32
    );
    PORT( 
        in1  : IN     std_ulogic_vector (g_dataWidth - 1 DOWNTO 0);
        in2  : IN     std_ulogic_vector (g_dataWidth - 1 DOWNTO 0);
        in3  : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        in4  : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        sel  : IN     std_ulogic_vector (1 DOWNTO 0);
        out1 : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );

-- Declarations

END mux4To1ULogVec ;






ARCHITECTURE rtl OF mux4To1ULogVec IS
BEGIN

  muxSelect: process(sel, in1, in2, in3, in4)
  begin
    case to_integer(unsigned(sel)) is
      when 0 => out1 <= in1;
      when 1 => out1 <= in2;
      when 2 => out1 <= in3;
      when 3 => out1 <= in4;
      when others => out1 <= (others => 'X');
    end case;
  end process muxSelect;

END ARCHITECTURE rtl;




-- VHDL Entity gates.transUlogUnsigned.symbol
--
-- Created:
--          by - silvan.zahno.UNKNOWN (WE6996)
--          at - 14:35:05 11.09.2019
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
  USE gates.gates.all;

ENTITY transUlogUnsigned IS
    GENERIC( 
        delay     : time     := gateDelay;
        dataBitNb : positive := 8
    );
    PORT( 
        in1  : IN     std_uLogic_vector (dataBitNb-1 DOWNTO 0);
        out1 : OUT    unsigned (dataBitNb-1 DOWNTO 0)
    );

-- Declarations

END transUlogUnsigned ;





ARCHITECTURE sim OF transUlogUnsigned IS
BEGIN
  out1 <= unsigned(in1) after delay;
END ARCHITECTURE sim;




--
-- VHDL Architecture HEIRV32.heirv32.struct
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 17:45:34 24.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;
LIBRARY gates;
USE gates.gates.all;

LIBRARY HEIRV32;

ARCHITECTURE struct OF heirv32 IS

    -- Architecture declarations
    constant c_dataWidth : positive := g_dataWidth;
    constant c_bramAddrWidth : positive := 10;

    -- Internal signal declarations
    SIGNAL ALUControl  : std_ulogic_vector(2 DOWNTO 0);
    SIGNAL ALUOut      : std_ulogic_vector(c_dataWidth - 1 DOWNTO 0);
    SIGNAL ALUResult   : std_ulogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL ALUSrcA     : std_ulogic_vector(1 DOWNTO 0);
    SIGNAL ALUSrcB     : std_ulogic_vector(1 DOWNTO 0);
    SIGNAL IRWrite     : std_ulogic;
    SIGNAL PC          : unsigned(c_dataWidth - 1 DOWNTO 0);
    SIGNAL PCNext      : unsigned(c_dataWidth - 1 DOWNTO 0);
    SIGNAL PCWrite     : std_ulogic;
    SIGNAL PCu         : std_ulogic_vector(c_dataWidth - 1 DOWNTO 0);
    SIGNAL RD1         : std_ulogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL adr         : unsigned(c_dataWidth-1 DOWNTO 0);
    SIGNAL adrSrc      : std_uLogic;
    SIGNAL data        : std_ulogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL en1         : std_uLogic;
    SIGNAL four_four   : std_ulogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL four_zeros  : std_ulogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL immExt      : std_ulogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL immSrc      : std_ulogic_vector(1 DOWNTO 0);
    SIGNAL instruction : std_ulogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL memWrite    : std_ulogic;
    SIGNAL oldPC       : std_ulogic_vector(c_dataWidth - 1 DOWNTO 0);
    SIGNAL out1        : std_uLogic;
    SIGNAL regwrite    : std_ulogic;
    SIGNAL result      : std_uLogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL resultSrc   : std_ulogic_vector(1 DOWNTO 0);
    SIGNAL srcA        : std_ulogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL srcB        : std_ulogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL writeData   : std_ulogic_vector(c_dataWidth-1 DOWNTO 0);
    SIGNAL zero        : std_ulogic;


    -- Component Declarations
    COMPONENT and2
    GENERIC (
        delay : time := gateDelay
    );
    PORT (
        in1  : IN     std_uLogic ;
        in2  : IN     std_uLogic ;
        out1 : OUT    std_uLogic 
    );
    END COMPONENT;
    COMPONENT mux2to1Unsigned
    GENERIC (
        dataBitNb : positive := 8;
        delay     : time     := gateDelay
    );
    PORT (
        in0    : IN     unsigned (dataBitNb-1 DOWNTO 0);
        in1    : IN     unsigned (dataBitNb-1 DOWNTO 0);
        sel    : IN     std_uLogic ;
        muxOut : OUT    unsigned (dataBitNb-1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT transUlogUnsigned
    GENERIC (
        delay     : time     := gateDelay;
        dataBitNb : positive := 8
    );
    PORT (
        in1  : IN     std_uLogic_vector (dataBitNb-1 DOWNTO 0);
        out1 : OUT    unsigned (dataBitNb-1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT transUnsignedUlog
    GENERIC (
        delay     : time     := gateDelay;
        dataBitNb : positive := 8
    );
    PORT (
        in1  : IN     unsigned (dataBitNb-1 DOWNTO 0);
        out1 : OUT    std_ulogic_vector (dataBitNb-1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT ALU
    GENERIC (
        g_datawidth : positive := 32
    );
    PORT (
        ctrl : IN     std_ulogic_vector (2 DOWNTO 0);
        srcA : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        srcB : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        res  : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        zero : OUT    std_ulogic 
    );
    END COMPONENT;
    COMPONENT bufferStdULogEnable
    GENERIC (
        g_dataWidth : positive := 32
    );
    PORT (
        clk  : IN     std_ulogic ;
        en   : IN     std_uLogic ;
        in1  : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        rst  : IN     std_ulogic ;
        out1 : OUT    std_ulogic_vector (g_dataWidth - 1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT bufferUnsignedEnable
    GENERIC (
        g_bitNb : positive := 32
    );
    PORT (
        clk  : IN     std_ulogic ;
        en   : IN     std_ulogic ;
        in1  : IN     unsigned (g_bitNb - 1 DOWNTO 0);
        rst  : IN     std_ulogic ;
        out1 : OUT    unsigned (g_bitNb - 1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT controlUnit
    GENERIC (
        g_datawidth : positive := 32
    );
    PORT (
        clk        : IN     std_ulogic ;
        en         : IN     std_ulogic ;
        funct3     : IN     std_ulogic_vector (2 DOWNTO 0);
        funct7     : IN     std_ulogic ;
        op         : IN     std_ulogic_vector (6 DOWNTO 0);
        rst        : IN     std_ulogic ;
        zero       : IN     std_ulogic ;
        ALUControl : OUT    std_ulogic_vector (2 DOWNTO 0);
        ALUSrcA    : OUT    std_ulogic_vector (1 DOWNTO 0);
        ALUSrcB    : OUT    std_ulogic_vector (1 DOWNTO 0);
        IRWrite    : OUT    std_ulogic ;
        PCWrite    : OUT    std_ulogic ;
        adrSrc     : OUT    std_uLogic ;
        immSrc     : OUT    std_ulogic_vector (1 DOWNTO 0);
        memWrite   : OUT    std_ulogic ;
        regwrite   : OUT    std_ulogic ;
        resultSrc  : OUT    std_ulogic_vector (1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT extend
    GENERIC (
        g_dataWidth : positive := 32
    );
    PORT (
        input    : IN     std_ulogic_vector (31 DOWNTO 7);
        src      : IN     std_ulogic_vector (1 DOWNTO 0);
        extended : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT instructionDataMemory
    GENERIC (
        g_dataWidth   : positive := 32;
        g_addrWidth   : positive := 10;
        g_programFile : string   := ""
    );
    PORT (
        address     : IN     unsigned (g_dataWidth-1 DOWNTO 0);
        clk         : IN     std_ulogic ;
        en          : IN     std_ulogic ;
        writeData   : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        writeEnable : IN     std_ulogic ;
        readData    : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT instructionForwarder
    GENERIC (
        g_dataWidth : positive := 32
    );
    PORT (
        irWrite     : IN     std_ulogic ;
        readData    : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        instruction : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT mux4To1ULogVec
    GENERIC (
        g_dataWidth : positive := 32
    );
    PORT (
        in1  : IN     std_ulogic_vector (g_dataWidth - 1 DOWNTO 0);
        in2  : IN     std_ulogic_vector (g_dataWidth - 1 DOWNTO 0);
        in3  : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        in4  : IN     std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        sel  : IN     std_ulogic_vector (1 DOWNTO 0);
        out1 : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT registerFile
    GENERIC (
        g_dataWidth : positive := 32;
        g_btnsNb    : positive := 2
    );
    PORT (
        addr1        : IN     std_ulogic_vector (4 DOWNTO 0);
        addr2        : IN     std_ulogic_vector (4 DOWNTO 0);
        addr3        : IN     std_ulogic_vector (4 DOWNTO 0);
        btns         : IN     std_ulogic_vector (g_btnsNb-1 DOWNTO 0);
        clk          : IN     std_ulogic ;
        en           : IN     std_ulogic ;
        rst          : IN     std_ulogic ;
        writeData    : IN     std_ulogic_vector (g_dataWidth - 1 DOWNTO 0);
        writeEnable3 : IN     std_ulogic ;
        RD1          : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        RD2          : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0);
        leds         : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );
    END COMPONENT;

    -- Optional embedded configurations
    -- pragma synthesis_off
    FOR ALL : ALU USE ENTITY HEIRV32.ALU;
    FOR ALL : and2 USE ENTITY gates.and2;
    FOR ALL : bufferStdULogEnable USE ENTITY HEIRV32.bufferStdULogEnable;
    FOR ALL : bufferUnsignedEnable USE ENTITY HEIRV32.bufferUnsignedEnable;
    FOR ALL : controlUnit USE ENTITY HEIRV32.controlUnit;
    FOR ALL : extend USE ENTITY HEIRV32.extend;
    FOR ALL : instructionDataMemory USE ENTITY HEIRV32.instructionDataMemory;
    FOR ALL : instructionForwarder USE ENTITY HEIRV32.instructionForwarder;
    FOR ALL : mux2to1Unsigned USE ENTITY gates.mux2to1Unsigned;
    FOR ALL : mux4To1ULogVec USE ENTITY HEIRV32.mux4To1ULogVec;
    FOR ALL : registerFile USE ENTITY HEIRV32.registerFile;
    FOR ALL : transUlogUnsigned USE ENTITY gates.transUlogUnsigned;
    FOR ALL : transUnsignedUlog USE ENTITY gates.transUnsignedUlog;
    -- pragma synthesis_on


BEGIN
    -- Architecture concurrent statements
    -- HDL Embedded Text Block 1 eb1
    four_zeros <= (c_dataWidth - 1 downto 0 => '0');
    four_four <= std_ulogic_vector(to_unsigned(4, c_dataWidth));

    -- HDL Embedded Text Block 2 eb2
    
    
    dbg_leds(7 downto 0) <= std_ulogic_vector(adr(9 downto 2)); -- no need to read LSBs since does +4 each time
    
    dbg_leds(15 downto 8) <= std_ulogic_vector(instruction(7 downto 0));
    
    dbg_leds(23 downto 16) <= std_ulogic_vector(ALUControl & "000" & resultSrc);
    
    dbg_leds(31 downto 24) <= std_ulogic_vector(regwrite & immSrc & '0' & ALUSrcB & ALUSrcA);


    -- Instance port mappings.
    U_and1 : and2
        GENERIC MAP (
            delay => gateDelay
        )
        PORT MAP (
            in1  => en,
            in2  => PCWrite,
            out1 => out1
        );
    U_and2 : and2
        GENERIC MAP (
            delay => gateDelay
        )
        PORT MAP (
            in1  => en,
            in2  => IRWrite,
            out1 => en1
        );
    U_pcMux : mux2to1Unsigned
        GENERIC MAP (
            dataBitNb => c_dataWidth,
            delay     => gateDelay
        )
        PORT MAP (
            in0    => PC,
            in1    => PCNext,
            sel    => adrSrc,
            muxOut => adr
        );
    U_resultToUnsigned : transUlogUnsigned
        GENERIC MAP (
            delay     => gateDelay,
            dataBitNb => c_dataWidth
        )
        PORT MAP (
            in1  => result,
            out1 => PCNext
        );
    U_0 : transUnsignedUlog
        GENERIC MAP (
            delay     => gateDelay,
            dataBitNb => c_dataWidth
        )
        PORT MAP (
            in1  => PC,
            out1 => PCu
        );
    U_alu : ALU
        GENERIC MAP (
            g_datawidth => c_dataWidth
        )
        PORT MAP (
            ctrl => ALUControl,
            srcA => srcA,
            srcB => srcB,
            res  => ALUResult,
            zero => zero
        );
    U_aluBuffer : bufferStdULogEnable
        GENERIC MAP (
            g_dataWidth => c_dataWidth
        )
        PORT MAP (
            clk  => clk,
            en   => en,
            in1  => ALUResult,
            rst  => rst,
            out1 => ALUOut
        );
    U_pcBuffer : bufferStdULogEnable
        GENERIC MAP (
            g_dataWidth => c_dataWidth
        )
        PORT MAP (
            clk  => clk,
            en   => en1,
            in1  => PCu,
            rst  => rst,
            out1 => oldPC
        );
    U_pcLoadBuffer : bufferUnsignedEnable
        GENERIC MAP (
            g_bitNb => c_dataWidth
        )
        PORT MAP (
            clk  => clk,
            en   => out1,
            in1  => PCNext,
            rst  => rst,
            out1 => PC
        );
    U_controlUnit : controlUnit
        GENERIC MAP (
            g_datawidth => c_dataWidth
        )
        PORT MAP (
            clk        => clk,
            en         => en,
            funct3     => instruction(14 DOWNTO 12),
            funct7     => instruction(30),
            op         => instruction(6 DOWNTO 0),
            rst        => rst,
            zero       => zero,
            ALUControl => ALUControl,
            ALUSrcA    => ALUSrcA,
            ALUSrcB    => ALUSrcB,
            IRWrite    => IRWrite,
            PCWrite    => PCWrite,
            adrSrc     => adrSrc,
            immSrc     => immSrc,
            memWrite   => memWrite,
            regwrite   => regwrite,
            resultSrc  => resultSrc
        );
    U_extend : extend
        GENERIC MAP (
            g_dataWidth => c_dataWidth
        )
        PORT MAP (
            input    => instruction(31 DOWNTO 7),
            src      => immSrc,
            extended => immExt
        );
    U_instrDataMemory : instructionDataMemory
        GENERIC MAP (
            g_dataWidth   => c_dataWidth,
            g_addrWidth   => c_bramAddrWidth,
            g_programFile => g_programFile
        )
        PORT MAP (
            address     => adr,
            clk         => clk,
            en          => en,
            writeData   => writeData,
            writeEnable => memWrite,
            readData    => data
        );
    U_instrForward : instructionForwarder
        GENERIC MAP (
            g_dataWidth => c_dataWidth
        )
        PORT MAP (
            irWrite     => IRWrite,
            readData    => data,
            instruction => instruction
        );
    U_resultSel : mux4To1ULogVec
        GENERIC MAP (
            g_dataWidth => c_dataWidth
        )
        PORT MAP (
            in1  => ALUOut,
            in2  => data,
            in3  => ALUResult,
            in4  => four_zeros,
            sel  => resultSrc,
            out1 => result
        );
    U_srcASel : mux4To1ULogVec
        GENERIC MAP (
            g_dataWidth => c_dataWidth
        )
        PORT MAP (
            in1  => PCu,
            in2  => oldPC,
            in3  => RD1,
            in4  => four_zeros,
            sel  => ALUSrcA,
            out1 => srcA
        );
    U_srcBSel : mux4To1ULogVec
        GENERIC MAP (
            g_dataWidth => c_dataWidth
        )
        PORT MAP (
            in1  => writeData,
            in2  => immExt,
            in3  => four_four,
            in4  => four_zeros,
            sel  => ALUSrcB,
            out1 => srcB
        );
    U_registerFile : registerFile
        GENERIC MAP (
            g_dataWidth => c_dataWidth,
            g_btnsNb    => g_btnsNb
        )
        PORT MAP (
            addr1        => instruction(19 DOWNTO 15),
            addr2        => instruction(24 DOWNTO 20),
            addr3        => instruction(11 DOWNTO 7),
            btns         => btns,
            clk          => clk,
            en           => en,
            rst          => rst,
            writeData    => result,
            writeEnable3 => regwrite,
            RD1          => RD1,
            RD2          => writeData,
            leds         => leds
        );

END struct;




--
-- VHDL Architecture HEIRV32_test.heirv32_tb.universal
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 16:01:58 24.10.2022
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

LIBRARY HEIRV32;
LIBRARY HEIRV32_test;

ARCHITECTURE universal OF heirv32_tb IS

    -- Architecture declarations
    constant c_btnsNb : positive := 4;

    -- Internal signal declarations
    SIGNAL btns : std_ulogic_vector(c_btnsNb-1 DOWNTO 0);
    SIGNAL clk  : std_ulogic;
    SIGNAL en   : std_ulogic;
    SIGNAL rst  : std_ulogic;


    -- Component Declarations
    COMPONENT heirv32
    GENERIC (
        g_programFile : string   := "$SIMULATION_DIR/code.txt";
        g_btnsNb      : positive := 2;
        g_dataWidth   : positive := 32
    );
    PORT (
        btns     : IN     std_ulogic_vector (g_btnsNb-1 DOWNTO 0);
        clk      : IN     std_ulogic ;
        en       : IN     std_ulogic ;
        rst      : IN     std_ulogic ;
        dbg_leds : OUT    std_ulogic_vector (31 DOWNTO 0);
        leds     : OUT    std_ulogic_vector (g_dataWidth-1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT universalTester
    GENERIC (
        c_btnsNb : positive := 2
    );
    PORT (
        btns : OUT    std_ulogic_vector (c_btnsNb-1 DOWNTO 0);
        clk  : OUT    std_ulogic ;
        en   : OUT    std_ulogic ;
        rst  : OUT    std_ulogic 
    );
    END COMPONENT;

    -- Optional embedded configurations
    -- pragma synthesis_off
    FOR ALL : heirv32 USE ENTITY HEIRV32.heirv32;
    FOR ALL : universalTester USE ENTITY HEIRV32_test.universalTester;
    -- pragma synthesis_on


BEGIN

    -- Instance port mappings.
    U_1 : heirv32
        GENERIC MAP (
            g_programFile => "$SIMULATION_DIR/code_bram.txt",
            g_btnsNb      => c_btnsNb,
            g_dataWidth   => 32
        )
        PORT MAP (
            btns     => btns,
            clk      => clk,
            en       => en,
            rst      => rst,
            dbg_leds => OPEN,
            leds     => OPEN
        );
    U_0 : universalTester
        GENERIC MAP (
            c_btnsNb => c_btnsNb
        )
        PORT MAP (
            btns => btns,
            clk  => clk,
            en   => en,
            rst  => rst
        );

END universal;




