<?=code?>
<?

  func type(bits) {
     if (bits=1)
       return "std_logic";
     else
       return "std_logic_vector("+(bits-1)+" downto 0)";
  }

  func bitSum(ports) {
     bitSum:=0;
     for (i:=0;i<sizeOf(ports);i++)
       bitSum=bitSum + ports[i].bits;
     return bitSum;
  }

  func getBitIndex(pos,bits) {
     if (bits=1)
       return pos;
     else
       return (pos+bits-1)+" downto "+pos;
  }

?>
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;

entity stdIOInterface is end;

architecture stdIOInterface_a of stdIOInterface is

  function chr(sl: std_logic) return character is
    variable c: character;
  begin
      case sl is
         when 'U' => c:= 'U';
         when 'X' => c:= 'X';
         when '0' => c:= '0';
         when '1' => c:= '1';
         when 'Z' => c:= 'Z';
         when 'W' => c:= 'W';
         when 'L' => c:= 'L';
         when 'H' => c:= 'H';
         when '-' => c:= '-';
      end case;
    return c;
  end chr;

  function str(slv: std_logic_vector) return string is
     variable result : string (1 to slv'length);
     variable r : integer;
  begin
     r := slv'length;
     for i in slv'range loop
        result(r) := chr(slv(i));
        r := r - 1;
     end loop;
     return result;
  end str;

  component <?=entityName?>
    port (
<?

  for (i:=0;i<sizeOf(inputs);i++)
      print("      ",inputs[i].name," : in ",type(inputs[i].bits),";\n");

  outCount:=sizeOf(outputs);
  for (i:=0;i<outCount;i++) {
      print("      ",outputs[i].name," : out ",type(outputs[i].bits));
      if (i<outCount-1)
        print(";\n");
  }


?> );
  end component;

<?

  for (i:=0;i<sizeOf(inputs);i++)
      print("  signal in_",inputs[i].name," : ",type(inputs[i].bits),";\n");
  for (i:=0;i<sizeOf(outputs);i++)
      print("  signal out_",outputs[i].name," : ",type(outputs[i].bits),";\n");

?>
  signal mainIn : std_logic_vector(<?=bitSum(inputs)-1?> downto 0);
  signal mainOut : std_logic_vector(<?=bitSum(outputs)-1?> downto 0);

begin
  UserCode: <?=entityName?> port map (
<?

  for (i:=0;i<sizeOf(inputs);i++)
      print("    ",inputs[i].name," => in_",inputs[i].name,",\n");
  for (i:=0;i<sizeOf(outputs);i++) {
      print("    ",outputs[i].name," => out_",outputs[i].name);
      if (i<outCount-1)
        print(",\n");
  }

?>
  );

<?

  pos:=0;
  for (i:=0;i<sizeOf(inputs);i++) {
      print("  in_",inputs[i].name," <= mainIn(",getBitIndex(pos, inputs[i].bits),");\n");
      pos=pos+inputs[i].bits;
  }
  pos=0;
  for (i:=0;i<sizeOf(outputs);i++) {
      print("  mainOut(",getBitIndex(pos, outputs[i].bits),") <= out_",outputs[i].name,";\n");
      pos=pos+outputs[i].bits;
  }

?>

	process
		variable ll: line;

	begin
		write(ll, string'(""));
		while (ll.all /= "End") loop
			deallocate(ll);
			readline(input, ll);
			for i in ll'range loop
				case ll(i) is
					when '0' => mainIn(i-1) <= '0';
					when '1' => mainIn(i-1) <= '1';
					when 'Z' => mainIn(i-1) <= 'Z';
					when ' ' =>  next;
					when others => next;
				end case;
			end loop;
			wait for 1 ns;
			deallocate(ll);
			write(ll, "Digital:" & string'(str(mainOut)));
			writeline(output, ll);
		end loop;
		wait;
	end process;
end;