bithead

BMM Files

Recommended Posts

Executive summary:

 

I have a BMM file that looks like this:

 

ADDRESS_SPACE jram RAMB16 [0x00000000:0x00003fff]
    BUS_BLOCK
         j1/ram [15:0]; 
    END_BUS_BLOCK; 
END_ADDRESS_SPACE; 
 
Data2Mem gives the following error:
 
ADDRESS_SPACE was defined as 0x00004000 bytes, but the ADDRESS_RANGE total is 0x00000800 bytes.
 
Wha? I don't have an ADDRESS_SPACE element.
 
I want to merge a MEM file that is 4k bytes long, 16 bits wide, into a BRAM that is of the same dimensions. How do I say that in a BMM file?
 
Longer story:

 

Finally got my Papilio Pro.  Thanks to the Papilio Loader update, everything seems to be working fine, and I've been able to get the stuff that had been working on the Papilio One 500 over to the Pro.

 

My problem is that I'm struggling with using data2mem and a BMM file to load the block RAM I'm using in a project.

 

I'm using the J1 Forth processor in a project. I've got it running and talking over the serial line.

 

The original author of the J1 processor divides the RAM into 8 2-bit chunks, and provides this BMM file that data2mem seems to be fine with:

 

ADDRESS_SPACE jram RAMB16 [0x00020000:0x00023fff]
    BUS_BLOCK
         j1/ram[7].ram [15:14]; 
         j1/ram[6].ram [13:12]; 
         j1/ram[5].ram [11:10]; 
         j1/ram[4].ram [9:8]; 
         j1/ram[3].ram [7:6]; 
         j1/ram[2].ram [5:4]; 
         j1/ram[1].ram [3:2]; 
         j1/ram[0].ram [1:0]; 
    END_BUS_BLOCK; 
END_ADDRESS_SPACE; 
 
In the process of porting to the Pro, I needed to use Spartan 6 specific block ram, so I used the IP core generator to make me a 16 bit wide block RAM, and I hooked that up. Ran great, I was able to get everything working on the Pro as it did on the One.
 
The problem is this -- I want to be able to merge a new set of RAM values into the bitstream without regenerating the RAM core to get it to read the COE file where I've got the current contents defined.  Right now the process of loading a new program for the processor goes like this:
 
write Forth code
cross compile it, producing a MEM file and a COE file containing the new memory image (I hope to use the MEM file for merging)
Force the RAM core to be regenerated so it will reread the COE file
Go through the Synthesis/Implementation/Bitgen cycle
load it onto the Pro
...then I run my tests and get one more debugging step in (I think I'm close to isolating a bug related to the math being done in the Forth core).
 
All of the steps are relatively fast, except for the "Force the IP Core to be regenerated" and the "synth/imp/bitgen" part, even on a fast machine, these are slow steps.
 
All the documentation I'm reading leads me to believe I can just regen the bit file with data2mem, if only I could get the BMM file format correct.
 
Help!? -- I would really really like to decrease the amount of time it takes to load a new image into the block ram. I really don't want to go through the synth/imp/bitgen cycle every time I need to load a different set of bytes.
 
Background:
 
By day I'm a software development lead, and I've already been bitten by the "software guy tries to write hardware" problem a few times, but I'm pretty sure this is just a "help me figure out how to properly construct a BMM file" problem.
 
I am not a complete idiot in these matters, but I do recognize that I am out of my area of expertise.

Share this post


Link to post
Share on other sites

I have also been playing with the j1 forth processor on Papilio. I got it working pretty

easily.

 

But I have not been able to get it to compile with the xilinx tools, or to run data2mem

with the Papilio Pro. I'm pretty new to all this, so that isn't surprising.

 

Let me know what you find out. I'd love to try it.

 

 

Share this post


Link to post
Share on other sites

This might help.... sorry for the length! It is multiple memory spaces, each consisiting of multiple BRAM blocks.

 

 

 
ADDRESS_MAP avrmap PPC405 0
 
    ADDRESS_SPACE rom_code RAMB16 [0x00000000:0x00003fff]
        BUS_BLOCK
            u_program_rom/rom0.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_program_rom/rom1.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_program_rom/rom2.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_program_rom/rom3.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_program_rom/rom4.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_program_rom/rom5.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_program_rom/rom6.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_program_rom/rom7.inst [7:0];
        END_BUS_BLOCK;
    END_ADDRESS_SPACE;
 
    ADDRESS_SPACE rom_wiz RAMB16 [0x00000000:0x00001fff]
        BUS_BLOCK
            u_program_wiz/rom0.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_program_wiz/rom1.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_program_wiz/rom2.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_program_wiz/rom3.inst [7:0];
        END_BUS_BLOCK;
 
    END_ADDRESS_SPACE;
 
    ADDRESS_SPACE rom_gfx1 RAMB16 [0x00000000:0x00001fff]
        BUS_BLOCK
            u_video/char_rom_5ef/rom0.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_video/char_rom_5ef/rom1.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_video/char_rom_5ef/rom2.inst [7:0];
        END_BUS_BLOCK;
 
        BUS_BLOCK
            u_video/char_rom_5ef/rom3.inst [7:0];
        END_BUS_BLOCK;
 
    END_ADDRESS_SPACE;
 
    ADDRESS_SPACE rom_audio1m RAMB16 [0x00000000:0x000007ff]
        BUS_BLOCK
            u_audio/audio_rom_1m/rom0.inst [7:0];
        END_BUS_BLOCK;
 
    END_ADDRESS_SPACE;
 
    ADDRESS_SPACE rom_col4a RAMB16 [0x00000000:0x000007ff]
        BUS_BLOCK
            u_video/col_rom_4a/rom0.inst [7:0];
        END_BUS_BLOCK;
 
    END_ADDRESS_SPACE;
 
    ADDRESS_SPACE rom_col7f RAMB16 [0x00000000:0x000007ff]
        BUS_BLOCK
            u_video/col_rom_7f/rom0.inst [7:0];
        END_BUS_BLOCK;
 
    END_ADDRESS_SPACE;
 
END_ADDRESS_MAP;
C:\Users\Hamster\Projects\FPGA\PapilioPlus\pacman_rel004_sp3e_papilio\build>

Share this post


Link to post
Share on other sites

Thank you for that Hamster! Getting the BMM right is always the hardest part for me too... The error message is completely unhelpful, and I never discovered the BMM documentation until after I got the BMM working.

 

One thing that I found helped with finding the correct net names was to look at the design in the FPGA Editor.

 

Jack.

Share this post


Link to post
Share on other sites

I think you guys are assuming I know a lot more about this stuff than I do -- I need a much simpler BMM file than that. I used the IP Core generator to give a true dual port RAM block that is 16 bits wide and 8192 words deep. (Well, now I'm unsure if the index is counting bytes or 16 bit words, I assume words because that's what I assumed when I typed "8192" into the wizard.)

 

My current attempt, (listed in my original post) was to take the original BMM file that came with the j1 core, and modify that.  The original setup was for 8 bit lanes each 2 bits wide.  I thought if I just deleted all but one lane, and made the bit width go to the full 16 bits I'd be fine. But I get the error I listed in the original post, and this is just when I run the syntax check with data2mem. I'm not specifying a bit file, so even if I have messed up a net reference, I'm assuming that's not the issue I'm dealing with here.

 

But I admit, I don't know the tools.  I've been using PlanAhead for development, as the tools seem more current than the environment provided by ISE, that could be a factor.

 

By day, I'm a software guy. That could be part of the problem. ;)

Share this post


Link to post
Share on other sites

Yes, you are guys are too advanced for me!

 

Could someone post the ram definition? I would like to see an 8K address 16-bit bram

that works with the spartan6. And the bmm file that goes along with that that works with

data2mem.

 

Btw, on the original spartan3 Papilio, I was able to get a new bmm file during the original

synthesis process. When I used that bmm file with data2mem, it worked.

 

Thanks everyone.

 

 

 

 

 

 

 

 

 

 

 

Share this post


Link to post
Share on other sites

pirx: You have actually described exactly the RAM I instantiated. I just used the IP Core Generator to do the dirty work.

 

Well, maybe not EXACTLY the RAM I instantiated.  I needed a true dual port item, so that's what I specified.

Share this post


Link to post
Share on other sites

Hey guys, there is unfortunately no template BMM file we can give you. There are path dependencies involved so the BMM file will depend on the structure of your project. I would recommend that you zip up your project directory here and attach it. I can take a look at it and tell you what I had to do to figure out the correct path and configuration.

 

I'm betting though that if you have read the data2mem documentation you have the BMM file structure correct. You are probably just not getting the path to your memory correct, and the tools do not make that easy, especially when you use the coregen to generate your memory. I've always had to synthesize my design without the BMM file, open the resulting design using FPGA editor, search for the memory nets and then you can see the correct path to add to the BMM file.

 

Jack.

Share this post


Link to post
Share on other sites

Short answer is - don't bother with the IP wizard , use the primitives instead.

 

The IP wizard implemented it as 7x 18kbit BRAM + 1 x 9kbit BRAM, just enough to hold 8640 16-bit words. The primitives as named:

 

 

my_memory/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[0].ram.r/s6_init.ram/TRUE_DP.PRIM9.ram
my_memory/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[1].ram.r/s6_init.ram/TRUE_DP.PRIM18.ram
my_memory/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[2].ram.r/s6_init.ram/TRUE_DP.PRIM18.ram
my_memory/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[3].ram.r/s6_init.ram/TRUE_DP.PRIM18.ram
my_memory/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[4].ram.r/s6_init.ram/TRUE_DP.PRIM18.ram
my_memory/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[5].ram.r/s6_init.ram/TRUE_DP.PRIM18.ram
my_memory/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[6].ram.r/s6_init.ram/TRUE_DP.PRIM18.ram
my_memory/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[7].ram.r/s6_init.ram/TRUE_DP.PRIM18.ram
 
How these are tiled together to form a memory space is anybody's guess, so you will never get the data into the correct place!

Share this post


Link to post
Share on other sites

Hamster, you are awesome.  I'll dig into this more myself.

 

I have to admit, I was reading your site, and the though that came to my mind was "Man, you better get going, this guy is way beyond you right now."

 

I love your stuff. My only complaint is that I've found that Verilog matches my brain better than VHDL, but that may be a temporary condition.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now