Fixing design, leaving BRAMS variable

Hi,

currently I am about to finish a design for a Spartan 3 chip. The design uses nearly all slices (98%, 5 slices left) and so PAR times are very long. When the design is finished I just want to make changes to the contents of the Block-Rams, leaving everything else untouched. What is the best way to do this? Are relative placement macros needed? If yes I would be very happy if someone could give me a short "recipe" for working with RPMs as this seems to be a quite intricate theme. Maybe there are good explanatory resources on the net, but I haven't found them yet. Also I am still looking for a good way to learn how to actually use the floorplanner - it seems to me like a black art...

Let me finish with a concrete question: Suppose I want to generate a RPM from a hierarchy of modules of the form

module main (....)

wire memconnect

cpu cpu0 (...) mem mem0 (...memconnect...)

endmodule

module cpu (..) endmodule

module mem (..memconnect..)

BRAM bram0 (...)

defparam bram0/...

endmodule

where BRAM is one of the Spartan BRAMs and defparam bram0/.. setting the contents of the BRAM. Is the contents of the BRAM fixed too in the generated RPM? And can I circumvent this by restructuring the modules as

module main (....memconnect..)

inout memconnect;

cpu cpu0 (...)

endmodule

module cpu (..)

endmodule

module mem (..memconnect..)

BRAM bram0 (...)

defparam bram0/...

endmodule

and now building a RPM for main but not for mem?

Thanks in advance for all answers

Jürgen

--
Jürgen Böhm                                            www.aviduratas.de
"At a time when so many scholars in the world are calculating, is it not
desirable that some, who can, dream ?"  R. Thom
Reply to
Jürgen Böhm
Loading thread data ...

Google data2mem HTH., Syms.

Reply to
Symon

It helped, many thanks, and for those, that, by chance, might be reading this thread I will write a bit about what I did.

First of all the authoritative documentation of data2mem seems to be

formatting link

One could wish for more examples than given in this doc, which I first put aside as quite indigestible (maybe I was just too tired). But finally I read it, and after reading through some examples given on the web and in newsgroup discussions it was much better understandable.

To google efficiently it was necessary to use the search-words

address_space bus_block

which are keywords in in the data2mem input .bmm file.

For german readers there is a short but useful explanation at

formatting link

(be warned: there is the typo ADDRESS_BLOCK instead of the correct ADDRESS_SPACE in the example .bmm file shown there).

The essence is, that the syntax to use is

data2mem -bm bmmfile_bd.bmm -bt project.bit -bd newdata.mem -o b final.bit

the files have the following meaning;

1) project.bit is (to fix the ideas) the output of the ISE-workflow, that is a .bit file that when loaded into the fpga performs its inteded configuration. Block RAM contents are included in it. So it is conceivable to modify project.bit in such a way, that only the content of the BRAMs change. This is what data2mem does (when called in the abovementioned way)

2) newdata.mem is a file in a certain format that provides the new data to go into (a selected set of) the BRAMs. It is more or less a Verilog .mem file, consisting of a sequence of whitespace separated elements, that are either @hexnumber or hexnumber. For example

@0000 12 13 1A @000B 12345F @2FCD 23 24 345D ..

might be such a file (of course probably not a very useful one)

3) final.bit is just the modified .bit file with the contents of the selected BRAMs changed. Use impact to transfer it to the fpga and the fpga should work as with the original project.bit and the contents of the selected BRAMs changed.

4) Now to the file bmmfile_bd.bmm. Of course you have noticed, that files

1) and 2) are not sufficient to generate 3). What is missing is a description, how to shuffle the bits from 2) (newdata.mem) into 3) (final.bit). This description is provided by the .bmm file.

In my case the very simple situation, analogous to the example in the data2mem User Guide applied. I had 4 RAMB_16_9 which were addressed as a

32bit wide memory with an address range of 2K words. Address range in words was 0x000 to 0x800 and therefore in bytes 0x000 to 0x1fff (this is of course a trivial observation, but the numbers reappear below)

Pictorially

********** ********** ********* ***********
  • * * * * * * *
  • r3 * * r2 * * r1 * * r0 *
********** ********** ********* ***********

r3 contained the highest byte in every word, r0 the lowest. That is, the bytes, say at byte-address 0, 1, 2, 3 go in r0, r1, r2, r3 at word-address 0.

If your setup is similar, you can copy from the following explanations.

The file bmmfile_bd.bmm that I used was (actually its name was cpu_ram_bd.bmm)

ADDRESS_SPACE cpu_ram RAMB16 [0x00000000:0x00001FFF] BUS_BLOCK main_mem_A/gldata_ram3 [31:24] LOC = X0Y1; main_mem_A/gldata_ram2 [23:16] LOC = X1Y5; main_mem_A/gldata_ram1 [15:8] LOC = X1Y2; main_mem_A/gldata_ram0 [7:0] LOC = X0Y5; END_BUS_BLOCK; END_ADDRESS_SPACE;

You see here in an obvious way the BRAMs called r3,r2,r1,r0 reappearing with their full instance names. The equations LOC = X0Y1; and so on of course give the physical location of the respective BRAM in the final layout. How did I find these out? The answer (using the ISE workflow, which I do) is: I added as a new source to the project the following file cpu_ram.bmm:

ADDRESS_SPACE cpu_ram RAMB16 [0x0000:0x1fff]

BUS_BLOCK main_mem_A/gldata_ram3 [31:24]; main_mem_A/gldata_ram2 [23:16]; main_mem_A/gldata_ram1 [15:8]; main_mem_A/gldata_ram0 [7:0]; END_BUS_BLOCK;

END_ADDRESS_SPACE;

Now starting the usual flow *including generating the .bit file*, the following happens: From the file cpu_ram.bmm *without LOC information* the file cpu_ram_bd.bmm *with the correct LOC information for the design synthesized* is generated. Generating the .bit file is mandatory, as first at this stage the modified _bd.bmm file is generated (the extension _bd is invariably appended).

I will not delve too much into the syntax of .bmm files and the possible ways to specify RAM layouts. In the case above you will recognize the address range, that my 4 RAMs provide collectively in bytes (0x0000 up to 0x1fff) and you will recognize selectors behind the instance names, that obviously convey the idea that byte (i+4*x) is in gldata_rami (i=0..3).

The concrete file newdata.mem which I used had the form:

//@00000000

12345678 EA080100 980B0100 00000000 //@00000010 00000000 00000000 00000000 00000000 //@00000020 ... .... //@00001ff0 00000000 00000000 00000000 00000000

There are a lot different ways to describe the same data using the format conventions of a .mem file. But if I understand everything right, the somewhat redundant form above is equivalent to the shortened one

@000000 12 34 56 78 EA 0A 01 00 ...

(please write a correction, if I am mistaken in that, as I am not totally sure about it)

Hoping that these explanations will be somewhat useful to future users of data2mem, I conclude with

Greetings

Jürgen

--
Jürgen Böhm                                            www.aviduratas.de
"At a time when so many scholars in the world are calculating, is it not
desirable that some, who can, dream ?"  R. Thom
Reply to
Jürgen Böhm

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.