08-21-2014 03:19 AM
I have currently implemented a component using kcpsm6 and 2k insturctions for a spartan6 based project.
Since the other components in the project occupy all the BRAMs, I am forced to switch to slice based distributed rom instead of block ram.
The current template set has an example for a 256 instructions rom.
Can someone help me create a ROM_form template file for 2048 instructions using distributed rom ?
I see that the coe file is not generated by the assembler anymore, so I dont see a possibility to give this as input to core generator.
Thanks a lot in advance for your pointers.
08-21-2014 06:25 AM
Thanks for sharing your interesting situation on this forum. If you haven’t already done so, it would make sense to develop your PicoBlaze code as much as possible using a BRAM based program memory and only switch over to Slice-based ROM when your code is stable. That way you can use JTAG Loader for rapid code development.
The largest natural size of Sliced-based ROM is 256 instructions. Each Slice contains 4 LUTs. Each LUT holds 64 bits of information and these are combined into a 256 bit ROM by the dedicated multiplexers also contained in each Slice. Finally the output from those combining multiplexers is registered by one of the flip-flops in the Slice to make the memory synchronous (like a BRAM). A PicoBlaze instruction is 18-bits wide so it takes 18 Slices to make a 256 instruction memory.
To implement a 2048 instruction memory we would need to have 8 of those 256 instruction memory blocks and then combine their 18-bit outputs using an (18-bit wide) 8-to-1 multiplexer. The optimum total size would be (8 x 18) + 9 = 144 Slices. So first of all check that you have enough spare Slices.
Also be aware that a Slice-based memory of that size will almost certainly be slower than that of a BRAM-based memory. Under normal conditions a program memory can only have (and must have) a single pipeline stage so that it behaves in the same was as a BRAM. If you do have issues meeting performance then have a look at page 122 of ‘KCPSM6_User_Guide_31March14.pdf’ to see a way in which the SLEEP control of KCPSM6 can be exploited to allow program memory to have more pipeline stages.
You are correct in saying that the KCPSM6 assembler doesn’t generate a COE file but it does generate a HEX file. Although this is primarily intended for use with JTAG Loader it is just a simple list of the op-codes of the program. According to the memory core documentation, “Coefficients can be separated by a space, a comma, or by placing one value in each line with a carriage return”. Some time ago I generated a memory core in which I specified each initial value on a separate line so I see no reason why a HEX file cannot be used as a COE file; just insert “memory_initialization_vector =” at the first line to get things started. If the memory generator complains about there being 4096 values specified then you’ll have to delete the last 2048 that you are not actually using (hint – Use an ADDRESS and INST directives to force the assembler to put a recognisable value at the end of the 2K memory space to make it easier to know where to start deleting).
I hope this gives you a way forward. It will be great to hear how you get on.
08-28-2014 10:19 PM
I've updated the generic Picoblaze ROM included with Opbasm to provide a choice of BRAM or distributed RAM implementation with a new STYLE generic. This component uses inferred memory to get a flexible implementation that is portable across Xilinx families and different memory sizes without having to manage different templates. Instead of a template that is filled in by the assembler, it reads the .mem or .hex ROM listings directly during synthesis. If you wish to continue using the KCPSM assembler you can use a dummy template and copy the picoblaze_rom.vhdl file into your project.
You can download the updated generic ROM direct from the Mercurial repository. I have not updated the packaged archive files with the new code.
Instantiate the generic ROM as follows:
generic map (
ROM_FILE => "my_rom.mem", -- Path relative to project root
STYLE => "DISTRIBUTED"
) port map (
Clock => clk,
Enable => bram_enable,
Address => address(10 downto 0), -- Slice address bus down to 11-bits to get 2K
Instruction => instruction