I have an EDK design with a MicroBlaze processor and use the External Memory Controller (EMC) to get access to off-chip SRAM.
I access the SRAM from c using a pointer and have a loop in my program that writes a value and increments the pointer to the next address.
As I am using a pointer to type integer it is increased by 4 locations each time I increment it. The SRAM I am accessing however is 32 bits wide so I am not getting access to the full memory capacity. Is there a setting somewhere for the compiler to tell it to increase by 1 address location or am I using the wrong approach.
I am a beginner with this technology so apologies if this is a dumb question.
Since you are pointing to a 32-bit value (int), incrementing a pointer to this a value of this type will add the sizeof(int) to the address. Since MicroBlaze addresses are on byte boundaries, the address will be incremented by 4 (32 bits = 4 bytes).
To increase your address by 1 byte, change the type of the variable you are pointing to to a char, which has sizeof(char) = 1 byte.
I had tried using a char pointer as you suggested but the values I want to write out are 32 bit integers, when I use a char pointer the correct value is not written to SRAM. I have shown a section from the terminal window below that shows this. Have I misinterpreted your suggestion for using a char pointer or can you see a mistake I'm making.
*** Error @ Mem[80F00080]=-128 Expected=128***
*** Error @ Mem[80F00081]=-127 Expected=129*** >>
If I use a pointer but set the addresses manually as below it works. I set the value of i to a large integer value and then increment it for each location but set the address directly in the code.
This code results in the correct display in the terminal window but if I try to put this in a loop to do it automatically how do I get the pointer address to increment the way I need.
The SRAM device I am connecting to has a 19 bit address bus and a 32 bit data bus. Am I right in thinking I should have 2^19 i.e. 524288 addresses each capable of holding 4 bytes therefore 2097152 bytes. This corresponds to the documentation which says the device is 2M. Using the code in my origibal post I am only getting access to a quarter of this.
Again thanks for your assitance, it is much appreciated.
I wonder how you have connected the SRAM to microblaze?
In particular please describe the low order bits of the address bus from the processor, and the low order address bits of the SRAM.
I am guess>I had tried using a char pointer as you suggested but the values I want
If you only do word (4 byte) reads and writes, you probably need something like this:
Address pins CPU SRAM
0 no connection
1 no connection
4 2 etc.
If you need byte reads and writes, then your SRAM must support this, and you use the CPU address bits 0 and 1 to select the byte.
Because the C compiler probably generated a byte write, not a word write
Neither xxxx7E or xxxx7F are word addresses. Word addresses always have the lower 2 bits set to 0, and are not used, as per the description I gave above.
The following code certainly matches my guess that you have not connected the address bus up correctly. That is, you are issuing word writes because you have declared sram_addr_data as an address to an int, yet you are using addresses that are byte addresses (non 0 for two lsbs)
I think the thing you need to grasp is that both byte and word accesses use the same address bits. For words, only every 4th address is valid. i.e. addresses 0, 4, 8, 12, 16, 20, .... This is called aligned access
You can also do byte addressing with these values, and all the ones in between.
Most RISC CPUs run this way. Other CPUs, such as the x86 devices allow un-aligned access, such as a word access from 3, but what actually happens is that the CPU does 2 accesses, to 0 and 4, and then assembles the word from byte 3 in the first word, and bytes 4, 5, and 6 in the second word. Most RISC CPUs dont do this, including microblaze.
If the pointer is an int * then the following
will be incremented by 4, which will point to the next word.
If the pointer is an char * then the following
will be incremented by 1, which will point to the next byte.
Because I think you have not connected the address bus up correctly.
many thanks for your help, using your suggestion I am now able to access the full SRAM device. I had connected addr bit 0 to SRAM addr bit 0 not realising this was incorrect, your description was spot on.