[J-core] ROM image generator.

D. Jeff Dionne jeff at SE-Instruments.com
Tue Nov 19 18:23:09 UTC 2019


On Nov 19, 2019, at 11:52, D. Jeff Dionne <Jeff at SE-Instruments.com> wrote:

> I’ll try and find a few min to make an example today….

Unconstrain the type, and make the init array sparse, but constrained:

ibuprofen:rt jeff$ cat ram_init.vhd
-- Machine generated from ram.img.
library ieee;
 use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package bootrom is
  type rom_t is array (natural range <>) of std_logic_vector(31 downto 0);
  constant rom : rom_t(0 to 90) := (
   8  => x"01234567", 9  => x"0000010c", 10 => x"1001fffc", 11 => x"0000010c",
   80 => x"01234567", 90 => x"0000010c", 12 => x"1001fffc", 15 => x"0000010c",
   others => x"00000000");

end package;

package body bootrom is
end package body;
ibuprofen:rt jeff$

Then explicitly constrain the actual ROM instantiation (see the use of NUM_WORDS)

ibuprofen:rt jeff$ cat lattice_ebr.vhd
-- A simple pre-initalized RAM, which reads from a binary file at synthesis time
-- single 32 bit read/write port.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.bootrom.all;

entity simple_ram is
  generic (
    -- 32-bit read/write port.  ADDR_WIDTH is in bytes, not words.
    ADDR_WIDTH : integer := 15 -- default 32k
    );
  port (
    clk : in std_logic;

    en : in std_logic;
    raddr : in std_logic_vector(ADDR_WIDTH - 3 downto 0);
    do : out std_logic_vector(31 downto 0);

    we : in std_logic_vector(3 downto 0);
    waddr : in std_logic_vector(ADDR_WIDTH - 3 downto 0);
    di : in std_logic_vector(31 downto 0)
    );
end simple_ram;

architecture behavioral of simple_ram is
  constant NUM_WORDS : integer :=  2**(ADDR_WIDTH - 2);
  signal ram : rom_t(0 to NUM_WORDS-1) := work.bootrom.rom;
begin

  process (clk, en)
    variable read : std_logic_vector(31 downto 0);
  begin
    if clk'event and clk = '1' and en = '1' then
      if we(3) = '1' then
        ram(to_integer(unsigned(waddr)))(31 downto 24) <= di(31 downto 24);
      end if;
      if we(2) = '1' then
        ram(to_integer(unsigned(waddr)))(23 downto 16) <= di(23 downto 16);
      end if;
      if we(1) = '1' then
        ram(to_integer(unsigned(waddr)))(15 downto 8 ) <= di(15 downto 8 );
      end if;
      if we(0) = '1' then
        ram(to_integer(unsigned(waddr)))(7  downto 0 ) <= di(7  downto 0 );
      end if;
      read := ram(to_integer(unsigned(raddr)));
      do <= read;
    end if;
  end process;
end behavioral;
ibuprofen:rt jeff$

In simulation, this should have the (perhaps dubious) benefit of returning a vector of all “UUU…” if you read part of the RAM that isn’t initialized before it is written.  In FPGA, I’m not sure what it will do until we try and synth it… I suspect it will put something arbitrary in the uninitialized locations and flag a warning, but the tools might just throw a fit instead.  Fixing that would only require something like defining a function to expand the initialization value out to the size of the actual ROM, and I’m too lazy until we prove we really need it.

J.

> 
> Cheers,
> J.



More information about the J-core mailing list