[J-core] ROM image generator.
D. Jeff Dionne
Jeff at SE-Instruments.com
Tue Nov 19 16:52:31 UTC 2019
For this case there are a few things that come to mind:
- Lattice tools don’t properly elaborate some constructs.
Normally, we would just have the entity that instantiates the Block RAM read a file... possibly even just the ELF file directly (yes, VHDL to read and parse ELF is somewhere in our repos). Unfortunately, Lattice doesn’t know how to do this (e.g. Xilinx ISE does) and so conv.c came out of frustration.
- Latrice elaboration will assign a constant to a ROM.
But even though the whole ice40 port is a little hack to prove J1 is feasible (as opposed to the very large J2 designs J-Core is normally used in), I wanted it to at least be a little ‘clean’. So, putting the ROM init contents in a separate package seemed like a good compromise, instead of just listing the values inline in the instantiation.
- The package should be general, and contain no implementation details, except about the code itself.
So exporting constants from the package seem to make a lot of sense. I’d go so far as to make conv.c create constants for entry point, length, stack etc. Prob. never used, but who cares, it doesn’t take long.
- Use the VHDL language features.
In this case, it’s not even VHDL specific, but the best thing to do is to explicitly set only those elements that are non zero. Then in the instantiation entity, add (others => x”000000000”). In the package, maybe even make it sparse. Then just make the init array just as long as the ROM data. If it’s too long, it’ll fail when you synthesise as needed, but you don’t need to keep the package and the instantiation in sync.
I’ll try and find a few min to make an example today....
> On Nov 18, 2019, at 07:30, Rob Landley <rob at landley.net> wrote:
> We have ram.sh which calls make -C testrom, calls sh2-elf-size for no reason,
> uses sh2-elf-objcopy on a binary it magically knows the name of out of the
> subdir (will generic objcopy not work?) to de-ELF it, and then builds and calls
> conf.c to turn that into a vhdl initializer for an sram block so it can pretend
> to be a boot ROM for ice40.
> I was thinking I should modify conv.c to have 8 constants per line instead of
> one so when we check in the generated file (so as not to require people to have
> sh2-elf installed in order to build the bitstream), it doesn't DOMINATE THE DIFF
> quite so much. (Pages and pages and pages of change...)
> But the other thing I noticed is we have a hardwired ROM size in conv.c and
> another hardwired ROM size in cpu_simple_sram.vhd, and they have to match. The
> "type rom_t is array (0 to 16383)" has to match "generic (ADDR_WIDTH : natural
> := 15);".
> (They have to match in a slightly non-obvious way: rom_t is array of 32 bit
> values, ADDR_WIDTH is number of 16 bit instructions, so 1<<15 is 32768 16 bit
> _instructions_ stored in 16384 32-bit words.)
> Anywhat, I want to have rom.sh objcopy the binary, figure out how big the result
> is (with power of 2 round up, of course), write out a ROM that big, and then
> have cpu_simple_sram.vhd use that value, so whatever binary you feed rom.sh
> (which should be a command line argument) just works. (At least in simulation,
> the lattice tools will still run out of RAM if it's too big, only the little
> ones are initializable.)
> Except then cpu_simple_sram needs to import something to get ADDR_WIDTH, and
> just "use work.ram_init;" seems dubious? (Can I do that? It's got a package in
> it, not just definitions: use work.ram_init.ADDR_WIDTH maybe?)
> Also, we should have the testrom dir's Makfilie do the objcopy. Also, we should
> check in the resulting -o binary file as the generated thing we commit to the
> repo instead of the VHDL, and have lattice_whatsis.sh call conv.c and recreate
> the vhd file from the binary each build.
> And we might want to break down and have a top level Makefile at some point, if
> we've got it in the subdirectory...
> J-core mailing list
> J-core at lists.j-core.org
More information about the J-core