FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
6365 Discussions

Wrong address range for custom IP in SOPC

Altera_Forum
Honored Contributor II
2,168 Views

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!!
0 Kudos
24 Replies
Altera_Forum
Honored Contributor II
112 Views

Please show your code, it's difficult to guess where the problem comes from without it...

0 Kudos
Altera_Forum
Honored Contributor II
112 Views

Hi, 

 

The answer to your problem lies in the interconnect fabric geberated by the SoPC builder. To quote form the Avlaon Spec (where it describes the address port of an Avalon Slave, Table 3.1): 

 

"Specifies an offset into the slave address space. Each 

slave address value selects a word of slave data. For 

example, address= 0 selects the first <slave data width> 

bits of slave data; address=1 selects the second <slave 

data width> bits of slave data." 

 

Therefore, in your Avalon Slave, your address port should contain enough bits to address all the words in your address space - irrespective of the width of the word. So if you have 512 8 bit words or 512 64 bit words, your address port will still be 9 bits.  

 

When SoPC builds your system, it looks at the word width and the address width and then generates the required logic to connect to the Avalon bus master. The Avalon Bus master always addresses bytes. To qute from tabel 4.3 in the spec (The Master address port): 

 

"The  

address signal represents a byte address 

 

regardless of the data-width of the master. The 

value of the address must be aligned to the data 

width. To write to specific bytes within a data word, 

the master must use the byteenable signal. 

Masters always issue byte addresses, regardless 

of the data width of the master or slave port. The 

system interconnect fabric translates this address 

into a word address in the slave’s address space 

so that each slave access is for a word of data from 

the perspective of the slave. 

 

So your 512 x 64 bit slave, will aways occupy 4096 bytes, or 12 bits, in the master address space. If the Avalon bus master is 32 bits wide (as is the case when using Nios), you will need to do two consecutive accesses to write to your slave. You may need to use the byteenable lines so that the interconnect fabric can show you when it is writing to the upper 32 bits and when it is writing to the lower 32 bits.  

 

Also look at table 3.3 of the Avalon spec. for an example for a 32 bit master writing to a 64 bit slave. 

 

Regards, 

Niki  

 

 

0 Kudos
Altera_Forum
Honored Contributor II
112 Views

hey sorry i couldnt reply earlier but thanks alot for the detailed reply.. niki.... i did end up getting it to work using flags and offsets.. :D 

 

i am stuck at another place.. i know always stuck somewhere..  

 

i want a piece of code to be repeated 32 times.. i obviously cant use while or for in verilog..  

 

i have written the following for the whole process to repeat..  

 

///////////////////// code ///////////////////////////// 

 

always @ (posedge CLOCK_50)  

begin 

 

if(bit_1 < 32 && bit_1 >= 0) 

begin 

count_di <= 1;  

end 

else  

begin  

count_di <= 0; 

end  

 

end // of always.. for count 

 

//// the above part is for performing the while operation //// 

 

/////////// main code////////////  

 

always @ (posedge CLOCK_50) // each 20nsec  

 

begin  

 

if(ready_di ==1 )  

 

begin 

 

bit_1 = 6'd32; 

la = 0; 

la_temp = 0; 

ty_c = {32'd0,py1};//ty}; 

tx_c = {1'b0,px1,31'd0};  

 

 

end  

 

 

 

if ( count_di != 0 )  

 

begin 

 

diff = ty_c - tx_c; 

 

la_temp = la_temp << 1; 

 

if( !diff[63] )  

begin 

 

ty_c = diff; 

la_temp[0] = 1'd1; 

 

end 

 

la = la_temp; 

 

tx_c = tx_c >> 1; 

bit_1 = bit_1 - 1'b1; 

 

end 

 

if(bit_1 == 0 && la >0) 

begin  

 

temp3= (la*la); 

 

temp4 = px1-qx1; 

 

qx1 = temp3 - temp4;  

 

 

end 

 

//////////////////// end of code///////////////////////// 

 

the above is the not the entire code just a subset of it .. 

 

my problem / doubt.. 

 

the above piece of code works fine and i am getting the output correct too.. but it doesnt happen all at once.. 

 

I mean when the configure thew FPGA and run Nios II.. I actually have to run Nios II 32 times to see the output..which is obviously not right.  

 

i want the whole loop to be done at once i hope u all understand what i m trying to say..  

 

Please do help me out here..  

Thanks again. 

 

you all are very helpful..
0 Kudos
Altera_Forum
Honored Contributor II
112 Views

Hi clggrad, 

 

You probably have already found a solution. I am not that familiar with Verilog, but what I can gather from your code is that you want a fair amount of processing to happen instantaniously and that each iteration depends on the results from the previous iteration. Although it may be possible to describe this as a huge blob of logic, it would probably not be very practical. A registered processing loop as you have implemented is a better approach since it allows you to re-use the resources. You can optimize the performance by unrolling the loop slightly (say 2 or 4 time). This way you will get an answer after 16 or 8 clock cycles.  

 

Regards, 

Niki
0 Kudos
Reply