cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
changyun
Visitor
Visitor
23,123 Views
Registered: ‎07-14-2009

How to use larger BRAM in a MicroBlaze project?

Jump to solution

Does anyone has an idea how can I use larger BRAM (more than 64K) in a MicroBlaze project? From the MicroBlaze user guide, it looks like I need to generate

a new BRAM module using core generator. I did that and now I have vhdl source file for 128K BRAM module and need to incorporate this module into my project.

I checked the Create or Import Peripheral Wizard. Seems it can incorporate peripheral modules which connect to PLB.  But in my case, I want to replace the default 64K BRAM

in XPS using my 128K one and connect it to LMB. Is there any way to do that? Or is there any way I can go to enlarge the BRAM size?  Thanks.

 

 

0 Kudos
1 Solution

Accepted Solutions
goran
Xilinx Employee
Xilinx Employee
21,540 Views
Registered: ‎08-06-2007

Hi,

 

If you're making your memories to have contiguous addresses, you can make the memory to be as one contiguous memory block in the linker script.

 

In the linker script you will most likely have something like this:

 

MEMORY
{
   ilmb_cntlr_dlmb_cntlr : ORIGIN = 0x00000050, LENGTH = 0x00001FB0
   DDR2_SDRAM_C_MPMC_BASEADDR : ORIGIN = 0x50000000, LENGTH = 0x10000000
}

If you have extended the lmb_bram to be 96kbyte by using multiple lmb_bram_if_cntlr, you can change the LENGTH in the linker script.

like this: 

 

   ilmb_cntlr_dlmb_cntlr : ORIGIN = 0x00000050, LENGTH = 0x00017FB0

 

Göran

 

View solution in original post

0 Kudos
85 Replies
jmonteiro-dme
Explorer
Explorer
22,453 Views
Registered: ‎05-15-2009

EDK->System Assembly View->Addresses->

 

Increase data local memory bus (dlmb)  and instruction local memory bus (ilmb) BRAM controller's address range, hence changing the memory space to, say, 128K of both equally. Don't forget to re-generate the linker script of your application.

 

Best,

JM

0 Kudos
changyun
Visitor
Visitor
22,448 Views
Registered: ‎07-14-2009

I tried yesterday but did not work. Maybe forgot to regenerate the linker script. I will try again. Thx. 

 

Bests,

Changyun 

0 Kudos
goran
Xilinx Employee
Xilinx Employee
22,397 Views
Registered: ‎08-06-2007

Hi,

 

There is no need to use the core generator.

 

If you want more BRAM on the LMB bus, just add more lmb_bram_if_cntlr and connect them to new bram_module.

Each lmb_bram_if_cntlr can handle 64kbyte so just add more of them.

 

The same if the BRAM is on the OPB or PLB, just add the bram_controller for that bus and a new bram_module.

 

This can be done in the normal system assembly view in XPS.

 

Göran

 

Message Edited by goran_bilski on 07-15-2009 01:25 PM
0 Kudos
changyun
Visitor
Visitor
22,386 Views
Registered: ‎07-14-2009

Hi,

 

I added in one more bram_block and one more lmb_bram_if_cntlr, generate addresses in system assembly view. In SDK, I did xilinx tools->synchronize with hardware, re-generate

linker script, compile, generate the elf file.  Then updated bitstream in XPS, downloaded bitstream to the board. But seems the software did not really execute (even in my linker script,

I did not use the newly added BRAM block). Is there any missing steps?

 

Thanks. 

 

Bests,

Changyun 

0 Kudos
goran
Xilinx Employee
Xilinx Employee
22,370 Views
Registered: ‎08-06-2007

Hi,

 

Did you connect them to MicroBlaze?

 

Can you post the .mhs?

 

If you only added one more lmb_bram_if_cntlr, did you connect it to the ILMB or DLMB interface on MicroBlaze?

 

Do you need more BRAM for code or for data?

If you added it for code, you need to add another lmb_bram_if_cntlr so that the data side can have access to this bram.

Data need access to the instruction memory if you want to download to it or setting soft breakpoints.

 

Göran

Message Edited by goran_bilski on 07-16-2009 08:33 AM
0 Kudos
changyun
Visitor
Visitor
22,352 Views
Registered: ‎07-14-2009

Hi,

 

It works now. I regenerated the libraries and BSPs then it works now. Thanks a lot for your help.

 

Bests,

Changyun  

0 Kudos
thirdeye
Explorer
Explorer
21,172 Views
Registered: ‎05-30-2008

Göran,

 

My EDK executable .data section is ~ 84K. I have a 64 K BRAM but I cannot fit this section into this BRAM. Is there any way to split code sections into smaller sections for using multiple BRAMs to store a given section?

 

Thank you,

Josh 

0 Kudos
goran
Xilinx Employee
Xilinx Employee
21,154 Views
Registered: ‎08-06-2007

Hi,

 

Just add another 32k lmb_bram controller and make the address align with the 64k BRAM block.

This makes MicroBlaze to have a contiguous memory region of 96 K which should be enough for your application.

 

Göran

0 Kudos
thirdeye
Explorer
Explorer
21,146 Views
Registered: ‎05-30-2008

Great, however, the Linker Script generator does not allow me to use this as one location since my individual memories cannot hold the .data section without splitting it up.

 

I have attempted to setup the linker script manually, but there ar emany things I am unsure about.

 

Is ther any way to"merge" these such that the linker script generator can see them as one?

 

Any other ideas?

0 Kudos
goran
Xilinx Employee
Xilinx Employee
21,541 Views
Registered: ‎08-06-2007

Hi,

 

If you're making your memories to have contiguous addresses, you can make the memory to be as one contiguous memory block in the linker script.

 

In the linker script you will most likely have something like this:

 

MEMORY
{
   ilmb_cntlr_dlmb_cntlr : ORIGIN = 0x00000050, LENGTH = 0x00001FB0
   DDR2_SDRAM_C_MPMC_BASEADDR : ORIGIN = 0x50000000, LENGTH = 0x10000000
}

If you have extended the lmb_bram to be 96kbyte by using multiple lmb_bram_if_cntlr, you can change the LENGTH in the linker script.

like this: 

 

   ilmb_cntlr_dlmb_cntlr : ORIGIN = 0x00000050, LENGTH = 0x00017FB0

 

Göran

 

View solution in original post

0 Kudos
thirdeye
Explorer
Explorer
16,207 Views
Registered: ‎05-30-2008
Great I will try that - thank you.
0 Kudos
hamze
Adventurer
Adventurer
15,609 Views
Registered: ‎11-09-2010

hi,

I have exactly the same problem, and I came to this point like you,

although I manually changed the size of Memory in linker script, compiler again say that .text does not fit in memory,

 

//--------------------------

ELF file    : D:/Ar_SDK/Debug/Ar_SDK.elf
ERROR:EDK - elfcheck failed!
The following sections did not fit into Processor BRAM memory:
    Section .text (0x50 - 0x14E67)

//--------------------------

 

 

although it shows no compile error, but when I want to program elf file, it says :

 

//--------------------------

Programming the FPGA failed due to errors from elfcheck

//--------------------------

 

it seems that there is some whereelse but linker script that tell compiler maximum amount of a section is 64 K,

did you have any progress?

0 Kudos
thirdeye
Explorer
Explorer
15,606 Views
Registered: ‎05-30-2008

 


@hamze wrote:

hi,

I have exactly the same problem, and I came to this point like you,

although I manually changed the size of Memory in linker script, compiler again say that .text does not fit in memory,

 

//--------------------------

ELF file    : D:/Ar_SDK/Debug/Ar_SDK.elf
ERROR:EDK - elfcheck failed!
The following sections did not fit into Processor BRAM memory:
    Section .text (0x50 - 0x14E67)

//--------------------------

 

 

although it shows no compile error, but when I want to program elf file, it says :

 

//--------------------------

Programming the FPGA failed due to errors from elfcheck

//--------------------------

 

it seems that there is some whereelse but linker script that tell compiler maximum amount of a section is 64 K,

did you have any progress?


 

Ah, yes, I was unable to ever do this using SDK. It appears you are using SDK. I ended up putting my software project in EDK and building from there - then it worked.

 

Xilinx still has a long long way to go before their tools have consistency and work the way Xilinx says they should. You can usually do anything but you just have to find out a hack to get it to work. Simple changes like this could be made, but Xilinx usually fails to fix issues like this in new releases of software tools - instead adding functionality like "SDK will be your only option in the next release" while SDK still has integration issues with EDK. I have been repeatedly frustrated with the tools and show stoppers like this, but the tools are pretty powerful - you just gotta figure out how to get things done. This forum has been my saving grace.

 

Let me know if switching the software project to EDK and building it in there works for you. If not I'll dig up my old project and see if I can figure it out.

0 Kudos
hamze
Adventurer
Adventurer
15,579 Views
Registered: ‎11-09-2010

thanks,

it worked!

I moved whole my software project from SDK on eclipse to EDK inside,  now manually changing size of BRAM in the linker script file makes no compile error. I programed it on board and it runs normally.

if possible I will try to find a solution for SDK, because it is better environment for software development,

 

 

 

0 Kudos
hamze
Adventurer
Adventurer
15,576 Views
Registered: ‎11-09-2010

hi goran,

manually changing size fo memory in linker script ask you said worked inside EDK software environment,

but exactly the same change does not work in SDK eclipse environment, it is still say that .text does not fit in section,

SDK is a better enrivonment for software development, do you have any solution for this?

0 Kudos
thirdeye
Explorer
Explorer
15,566 Views
Registered: ‎05-30-2008

 


@hamze wrote:

thanks,

it worked!

I moved whole my software project from SDK on eclipse to EDK inside,  now manually changing size of BRAM in the linker script file makes no compile error. I programed it on board and it runs normally.

if possible I will try to find a solution for SDK, because it is better environment for software development,

 

 

 


 

Great! I am glad that worked for you.

 

Yes it would be nice to have it work in SDK. You would think SDK would be smarter, but I guess that is the problem - it is "smarter" and knows you're trying to trick it.

 

I just hope that Xilinx makes this work in SDK before disabling EDK software development entirely. I always find issues like this puzzling because it seems that software too large to fit in one BRAM block must be a very common issue. It seems like something like this would have been resolved years ago, but maybe it is not as common as I expect.

 

Adding software to PROM files (if not in BRAMs) is another problematic process I would expect to be common and with a  clear solution, but this is a buggy, tricky, and poorly documented issue as well.

 

Happy coding,

Josh

0 Kudos
hamze
Adventurer
Adventurer
15,394 Views
Registered: ‎11-09-2010

hi

I prefer to work in SDK because it allows software and hardware engineers work separately ( and also backuping software and hardware projects separately )

I think I found a solution for SDK. Solution contains these steps :

  1. Elf check removed from SDK settings. ( end of list in  properties\cc++build\settings\ ). then after build elf will made with no error.
  2. Run data2mem to update bit file with elf file from cmd line manually ( e.g  data2mem -bm edkBmmFile_bd.bmm -bt soctop.bit -bd executable.elf tag microblaze_0 -o b download.bit  )
  3. Run impact to program bit file to fpga from cmd line manually ( e.g impact.exe -batch d:\file.cmd  ).
0 Kudos
thirdeye
Explorer
Explorer
15,388 Views
Registered: ‎05-30-2008

Thanks for posting your solution - that is great.

 

What would really be great is if Xilinx would post things like that or better yet, make SDK just work in this configuration. I don't mind running things on command line, but c'mon Xilinx, don't make us figure out how to "hack" the tools to make them work.

 

Thanks again for sharing your solution. Hopefully they'll make this a little more seamless before requiring SDK use for all software designs.

0 Kudos
hamze
Adventurer
Adventurer
15,366 Views
Registered: ‎11-09-2010
I did not test it but having COMBINED BRAM may affect maximum allowed frequency.
or perhaps it is a commercial reason to force buying Virtex family.

anyway second step simply can be placed SDK "post build" to automatically run it. ( properties\cc++build\settings\ in build step tab ).
3rd step is not necessary to be run from cmd, using impact GUI is also ok.
0 Kudos
thirdeye
Explorer
Explorer
12,595 Views
Registered: ‎05-30-2008

Cool - good to know. Thanks.

0 Kudos
alear
Visitor
Visitor
12,439 Views
Registered: ‎06-05-2009

I'm trying to get this to work with a Virtex-5 SX95 that has 11 BRAMs added in XPS.  The addresses are contiguous for each ilmb/dlmb/blockram @ 64K each.

 

I get this error:

----------------------------

ERROR:Data2MEM:31 - Out of bounds code segment for ram space in
'implementation\system_bd.bmm'.
    Memory space 'microblaze_0.lmb_bram_9_combined' occupies
[0x00000000:0x0000FFFF]
    Code segment #3 occupies [0x00000050:0x0002218B]

 

ERROR:Data2MEM:31 - Out of bounds code segment for ram space in'implementation\system_bd.bmm'.    Memory space 'microblaze_0.lmb_bram_9_combined' occupies[0x00000000:0x0000FFFF]    Code segment #3 occupies [0x00000050:0x0002218B]

----------------------------

 

It seems the bmm file still shows the 64K total for ilmb_cntlr_9_dlmb_cntlr_9, which is the base addressed controller in my case.  I also get the error in SDK until I tell it not to do the elf check (as mentioned earlier).  I've adjusted the linker to only show the ilmb_cntlr_9_dlmb_cntlr_9 memory and changed the length to 0x000BFFF.

 

Any suggestions as to why these don't combine into the total conbined size?

 

Thanks,

Alex

0 Kudos
thirdeye
Explorer
Explorer
12,433 Views
Registered: ‎05-30-2008

In your linker script do you have something like:

 

MEMORY
{
   ilmb_cntlr_dlmb_cntlr : ORIGIN = 0x00000050, LENGTH = 0x0000FFB0
   xps_BRAM_cntlr_0 : ORIGIN = 0x10000000, LENGTH = 0x00010000
   xps_BRAM_cntlr_1 : ORIGIN = 0x10010000, LENGTH = 0x00010000
    xps_BRAM_cntlr_both : ORIGIN = 0x10000000, LENGTH = 0x00020000
   MPMC_LPDDR_C_MPMC_BASEADDR : ORIGIN = 0x48000000, LENGTH = 0x08000000
}
followed by something like:
.text : {
   *(.text)
   *(.text.*)
   *(.gnu.linkonce.t.*)
} > xps_BRAM_cntlr_both

 

I'm sure you do, but that is my only suggestion.

 

-Josh

 

alear
Visitor
Visitor
12,420 Views
Registered: ‎06-05-2009

I had my linker slightly different but I think it acomplished the same thing.  I adjusted it to look like yours with each controller shown and one that I made to combine them all (I do have to make that manually, right?).

 

Here's what it looks like now:

 

MEMORY
{
   ilmb_cntlr_dlmb_cntlr : ORIGIN = 0x000F0000, LENGTH = 0x00010000
   ilmb_cntlr_2_dlmb_cntlr_2 : ORIGIN = 0x00020000, LENGTH = 0x00010000
   ilmb_cntlr_3_dlmb_cntlr_3 : ORIGIN = 0x000C0000, LENGTH = 0x00010000
   ilmb_cntlr_4_dlmb_cntlr_4 : ORIGIN = 0x00080000, LENGTH = 0x00010000
   ilmb_cntlr_5_dlmb_cntlr_5 : ORIGIN = 0x00030000, LENGTH = 0x00010000
   ilmb_cntlr_7_dlmb_cntlr_7 : ORIGIN = 0x00050000, LENGTH = 0x00010000
   ilmb_cntlr_6_dlmb_cntlr_6 : ORIGIN = 0x000D0000, LENGTH = 0x00010000
   ilmb_cntlr_8_dlmb_cntlr_8 : ORIGIN = 0x00090000, LENGTH = 0x00010000
   ilmb_cntlr_9_dlmb_cntlr_9 : ORIGIN = 0x00000050, LENGTH = 0x0000FFB0
   ilmb_cntlr_10_dlmb_cntlr_10 : ORIGIN = 0x000B0000, LENGTH = 0x00010000
   ilmb_cntlr_11_dlmb_cntlr_11 : ORIGIN = 0x00070000, LENGTH = 0x00010000
   xps_BRAM_cntlr_all : ORIGIN = 0x00000050, LENGTH = 0x000BFFFF
   SRAM_MEM0_BASEADDR : ORIGIN = 0x85400000, LENGTH = 0x00200000
   FLASH_MEM0_BASEADDR : ORIGIN = 0x86000000, LENGTH = 0x02000000
   PLATFORM_FLASH_MEM0_BASEADDR : ORIGIN = 0x82000000, LENGTH = 0x01000000
}

 

with sections like:

 

 

.data : {

   . = ALIGN(4);

   __data_start = .;

   *(.data)

   *(.data.*)

   *(.gnu.linkonce.d.*)

   __data_end = .;

} > xps_BRAM_cntlr_all

 

 

None of the sections reference the individual controllers.  As I mentioned before, I always get the elf error in SDK so (as instructed in another reply) I turn off the error check and use data2mem in a command window.  I get the same error as before though.

 

It looks like the referenced data section in the bmm file shows 64K areas and that's why its failing.  Could there be something I'm not doing right in the hardware to cause this?  One of the previous replies indicated that a change may need to be made manually to the bmm file.  If so, which documentation shows the format of the bmm file?

 

Thanks,

Alex

0 Kudos
thirdeye
Explorer
Explorer
12,415 Views
Registered: ‎05-30-2008

You do have to combine them all manually (add the 'all' memory area to the linker script) - otherwise the defined areas are not large enough.

 

I used a separate set of BRAM_cntlr that is not the ilmb or dlmb just to avoid confusion or potential overlap issues. I don't really know if this makes a difference at all, but it is possible. I just wanted to be safe and sure that I had my own dedicated memory area.

 

I think the real issue is that the memory areas are not actually continuous as you think they are.

 

I think you want something more like:

 

 

MEMORY
{
   ilmb_cntlr_dlmb_cntlr : ORIGIN = 0x00010000, LENGTH = 0x00010000
   ilmb_cntlr_2_dlmb_cntlr_2 : ORIGIN = 0x00020000, LENGTH = 0x00010000 (0x00010000 + 0x00010000 = 0x20000)
   ilmb_cntlr_3_dlmb_cntlr_3 : ORIGIN = 0x00030000, LENGTH = 0x00010000 (0x00020000 + 0x00010000 = 0x30000)
   ilmb_cntlr_4_dlmb_cntlr_4 : ORIGIN = 0x00040000, LENGTH = 0x00010000 (0x00030000 + 0x00010000 = 0x40000)
   ilmb_cntlr_5_dlmb_cntlr_5 : ORIGIN = 0x00050000, LENGTH = 0x00010000 (0x00040000 + 0x00010000 = 0x50000)
   ilmb_cntlr_7_dlmb_cntlr_7 : ORIGIN = 0x00060000, LENGTH = 0x00010000 (0x00050000 + 0x00010000 = 0x60000)
   ilmb_cntlr_6_dlmb_cntlr_6 : ORIGIN = 0x00070000, LENGTH = 0x00010000 (0x00060000 + 0x00010000 = 0x70000)
   ilmb_cntlr_8_dlmb_cntlr_8 : ORIGIN = 0x00080000, LENGTH = 0x00010000 (0x00070000 + 0x00010000 = 0x80000)
   ilmb_cntlr_9_dlmb_cntlr_9 : ORIGIN = 0x00090000, LENGTH = 0x00010000 (0x00080000 + 0x00010000 = 0x90000)
   ilmb_cntlr_10_dlmb_cntlr_10 : ORIGIN = 0x000A0000, LENGTH = 0x00010000 (0x00090000 + 0x00010000 = 0xA0000)
   ilmb_cntlr_11_dlmb_cntlr_11 : ORIGIN = 0x000B0000, LENGTH = 0x00010000 (0x000A0000 + 0x00010000 = 0xB0000)
   xps_BRAM_cntlr_all : ORIGIN = 0x00010000, LENGTH = 0x000B0000 (0x00010000 * 11 = 0xB0000)
   SRAM_MEM0_BASEADDR : ORIGIN = 0x85400000, LENGTH = 0x00200000
   FLASH_MEM0_BASEADDR : ORIGIN = 0x86000000, LENGTH = 0x02000000
   PLATFORM_FLASH_MEM0_BASEADDR : ORIGIN = 0x82000000, LENGTH = 0x01000000
}

 

FYI - I use google as my hex calculator and converter for this kind of thing.

 

-Josh

thirdeye
Explorer
Explorer
12,412 Views
Registered: ‎05-30-2008

Clearly the addresses need to match the address mappings in EDK itself as well. I suggest these are changed to be continuous.

0 Kudos
alear
Visitor
Visitor
12,407 Views
Registered: ‎06-05-2009

You're completely right about the memory not being contiguous, its not even close and I must have regenerated the addresses recently and didn't notice they had changed so much.  That explains the bmm file inconsistencies as well.

 

Thanks for your help Josh!

0 Kudos
thirdeye
Explorer
Explorer
12,405 Views
Registered: ‎05-30-2008

My pleasure :-)

 

I've spent so much time struggling with Xilinx stuff that I try to help people out with things I've been through.

0 Kudos
fpgause
Observer
Observer
12,302 Views
Registered: ‎11-13-2010
hi iam new to this and iam facing a problem in which i was storing the instruction and video from camera both in external memory and transmitting through Ethernet but it is not working what i guess it may be due to data instruction in external memory .I got of increasing the bram from this forum but do u have any basic docs for this so that i can implement that thing the .elf has reached to156 kB and whether it is required to part-ion the code or not
0 Kudos
thirdeye
Explorer
Explorer
12,279 Views
Registered: ‎05-30-2008

 


@fpgause wrote:
hi iam new to this and iam facing a problem in which i was storing the instruction and video from camera both in external memory and transmitting through Ethernet but it is not working what i guess it may be due to data instruction in external memory .I got of increasing the bram from this forum but do u have any basic docs for this so that i can implement that thing the .elf has reached to156 kB and whether it is required to part-ion the code or not

 

I used to store my programs in DDR, but realized that you then need a bootloader to get the program elf file into DDR just as you load the video data into DDR after the FPGA is loaded. If you do have both in memory you need ot be sure that the things you store in memory to not overlap or you will have corruption. I have had issues where my heap and stack were overwriting video data I stored in memory.

 

I tend to use BRAMS for program storage and heap and stack. I then can use DDR for frame buffers and such. Just to be safe, unless you need all of your memory - I usually start storing my video data at the midpoint of my memory, ie: 64M for 128MB memory. I fyou need more - move it back from there but I do not suggest putting it in the very beginning since it is possible something else is going there also.

 

I have written little test programs to run my firmware and software for a while and then read and print out the ends of my memory range to be sure my data is exactly where I think it is and not overunning bounds or actually not even there.

 

I hope this helps,

Josh

 

0 Kudos