#! /usr/bin/perl

use strict;
use warnings;

if (@ARGV < 1) {
  die "usage: $0 <binary file>\n";
}
my $binfile = $ARGV[0];

open BINFILE, "<", $binfile or die "cannot read \"$binfile\": ";
binmode BINFILE;

print <<EOF;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

ENTITY e_rom IS
    GENERIC (
        addr_width: natural
    );
    PORT (
        clk:    IN  std_logic;
        i_addr: IN  std_logic_vector(addr_width - 1 DOWNTO 0);
        o_data: OUT std_logic_vector(            31 DOWNTO 0)
    );
END ENTITY e_rom;

ARCHITECTURE a_rom OF e_rom IS

    SUBTYPE t_addr IS std_logic_vector(addr_width - 1 DOWNTO 0);
    SUBTYPE t_data IS std_logic_vector(            31 DOWNTO 0);
    TYPE    t_buf  IS ARRAY(0 TO 2 ** addr_width - 1) OF t_data;

    SIGNAL s_buf: t_buf := (
EOF

my $addr = 0;
my $data;
while (read(BINFILE, $data, 4)) {
  my @d = unpack("CCCC", $data);
  printf "        %d => X\"%02X%02X%02X%02X\",\n",
         $addr, $d[3], $d[2], $d[1], $d[0];
  ++$addr;
}

print <<EOF;
        OTHERS => X"00000000"
    );

BEGIN

    p_rom: PROCESS(clk)
    BEGIN
        IF rising_edge(clk) THEN
            o_data <= s_buf(to_integer(unsigned(i_addr)));
        END IF;
    END PROCESS p_rom;

END ARCHITECTURE a_rom;
EOF