Forum Discussion
Wrong address range for custom IP in SOPC
Hello guys,
I would pls like a hint or a wise word on this funny issue that I have related to address ranges. In detail, I have designed my own custom IP core that is a simple slave for the avalon bus. Its like an on-chip ram, but its not a RAM it has some other logic as well. This IP core has an address port ADDRESS_PORT(8 DOWNTO 0). So that is 9 bits for addressing, in other words I want to address 512 words of RAM. The funny thing is that when I add my component on the SOPC builder along with a NIOS some RAM etc. and I do "auto assign base addresses" then the address range that is assigned for my component by SOPC is 12bits! Just to make it more clear, for example if the base address for my component is 0x1000 then the range assigned by SOPC to the component is: 0x1000-0x1FFF! That is 12 bits right? I'm expecting something like that: 0x1000-0x11FF...so 9 bits=512words. What seems to be wrong? Why the SOPC cannot understand the address range correctly since my address port is 9 bits? Thank you for your help!!24 Replies
- Altera_Forum
Honored Contributor
NIOSII has 4 KByte page and frame size. I guess, your "like an on-chip ram" core just mapped into one mem-page.
Digitally yours, Mixa - Altera_Forum
Honored Contributor
Hello cms,
thank you for your time replying! What you are saying makes sense, since with 12bits one can address a 4kB RAM. Supposing that this is true, how is the system going to operate correctly? I mean what happens if NIOS tries to write something at an address beyond 512? Is this the correct or natural way? Is there any way to map my core at only 9bits? Also, if i remove NIOS will the address mapping become "as expected" (of course there will be no master then...) Thanx! - Altera_Forum
Honored Contributor
Oh.. and another question :)
If, you are implying that the minimum addressing is according to the mem page of NIOS then why when I connect a couple of switches (16) the addressing is correct? (0x1000-0x100F 4bits) thx - Altera_Forum
Honored Contributor
The way I understand it, the address lines to a NIOS component represent a word address. So a 9 bit address bus will give you 512 words. Assuming a word size of 32 bits, 512 words is 2048 bytes. Assuming a base address of 0x1000, the range would then be 0x1000-0x17FF.
When working with custom components I have also found the address range does not always come out as expected. I haven't verified this, but I suspect when you edit a component to reduce the size of the address bus, the range used in the memory map is not automatically reduced accordingly. To fix this I have either edited the .tcl file manually (this can be dangerous unless you are really sure what you are doing) or recreated the component from scratch. - Altera_Forum
Honored Contributor
Hi kevin! Thx for your time!
After reading your reply I really think that I'm missing something here...related to how NIOS addresses registers in a slave component eg RAM. Are u implying that NIOS addresses bytes(8bits that is) instead of a whole word? To make things clearer with my custom IP, you may consider it as an on-chip RAM which consists of 512words and each word has 64bits. Now, if, ccording to your reply, NIOS addresses bytes then what I get as address range maked perfectly sense since 512words of 64bits each is 512x8= total=4096 8-bit words. So... if NIOS addresses bytes of course we need 12bits for the address range! But then the whole thing is messed up in my mind! Certain questions arise: 1) How are these 12bits are physically implemented since I only provide an ADDRESS_PORT of only 9 bits? 2)If we assume the above "magically solved" then does it mean that NIOS needs 8cycles to read a single 64bit RAM word?! In other words does NIOS have to give 8 addresses to the address port to get a word(64bits)?? 3) Is the "byte_enable" signal that exists in the avalon_slave interface related to this?? How are all these issues handled? Any documentation? Thank you for your help in advance!! This thing is starting to get much more interesting and difficult than i imagined! - Altera_Forum
Honored Contributor
The addresses shown in SOPC builder are byte addresses. In your C code, components are also accessed using byte base addresses.
However, components are at a low level accessed by the word. The LSB's of the byte address are always assumed to be zero which is why you don't need enough address lines for each byte in the range. The physcial address port uses word addresses. If a master needs to read less than one word, then the byte_enable signals come into play. However, I am fairly new to this myself, so I don't know exactly how this works. I also have no experience with using 64 bit words, so I am not 100% sure how that will play into you situation. - Altera_Forum
Honored Contributor
I'm not even going to bother reading the other replies. How wide is your data bus? This may actually matter. Also, what version of the tools are you using?
You need to make your data bus 32-bits wide regardless of whether you are using all 32-bits or not. This will make your life easier as the NIOS has a 32-bit data bus. If you've got a 9-bit address bus you should end up with 11 bits of address space in SOPC builder. The reason for this is that address is space in SOPC builder is byte addressed. So for each 32-bit word of address in your component you have 4 byte addresses. You don't need to think about this when writing your C code. Altera provides the IOWR and IORD macros. So to write or read to/from your component: IOWR(MY_IP_BASE, <some register address>, <new_data>); and IORD(MY_IP_BASE, <some register address>) The IOWR and IORD macros will convert your desired register address to a byte address and perform the transaction. I have written hundreds of SOPC custom components so I have a fairly firm grasp on how things work. Now as to why you have 12-bits of address space instead of 11. I've only seen this in one case. There used to be a setting for custom user components that specified the addressing scheme (DYNAMIC or NATIVE). I won't go into what that means. Anyway, that setting was deprecated in 7.1 of the tools. With the newer tools (like 8.0 and newer), if the component was somehow set to use the deprecated NATIVE addressing scheme, it would give two extra bits of address space to the component. I'm not sure if this is what is happening to you but if it is then I would guess your data bus is 16-bits wide and you somehow have the deprecated NATIVE parameter assigned to your avalon slave interface. Jake - Altera_Forum
Honored Contributor
Thank you all for your replies!
I have fully understood why i need 12bits of addressing in the SOPC to address my custom IP. As said, my IP has 512words of 64bits each. So physically it needs 9 bits for addressing. These bits ARE provided by the SOPC. NIOS uses dynamic addressing for avaon bus components, since NIOS is 32bits and the components connected to the bus might be 16,or 64 like my case or whatever. In order to make programmers lives easier, NIOS addresses bytes! So 9bits out of the SOPC address line go to the physical address_port of my custom IP and the rest 3bits are picking up the bytes out of the 64bit word coming out on the avalon bus by my IP. 2^3=8 64bits=8x8bytes. As I understand it NIOS presents the 9bit address on the custom IP address_port, then the 64bit word comes out and then using the extra 3 bits NIOS fetches the word in 8 cycles, 1byte each cycle. - Altera_Forum
Honored Contributor
You seem to understand why there is 12 bits of address lines to your component, but I think there is still some confusion on how the component is actually accessed.
To read 64 bits from you component, I think NIOS will perform this in two 32 bit cycles. Try synthesizing the simplest test case you can and then look at the RTL viewer. This can often clear up what is going on at a low level. I just tried this for a simple system with a NIOS processor and a 64 bit wide component. If you trace the 64 bit bus from the component, what you will find is that it is split into two 32 bit halves and fed input a 2:1 mux. The mux is controlled by bit 2 of the address bus. - Altera_Forum
Honored Contributor
Hey everyone.. i am fairly new to Nios II. I have built a custom SOPC component.. now i know i can use IORD and IOWR for accessing data to and from the component...
my problem is well i am unable to write more than one value to my component. for my design i need to write two values and read two values each of 32 bits. Tested the read for one value and it works but unable to read the next value. Please do help me out.. Thanks you all..