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
Could you post some of your source code? (address decoding for the VHDL/Verilog part, IORD/WR calls for the software part) It would help us finding out what's wrong.
- Altera_Forum
Honored Contributor
--- Quote Start --- Could you post some of your source code? (address decoding for the VHDL/Verilog part, IORD/WR calls for the software part) It would help us finding out what's wrong. --- Quote End --- hey Daixiwien, i am attaching a test code to show what i have been trying to do input read; output [31:0] read_data; output [31:0]qx,qy always @ (posedge CLOCK_50) // each 20nsec begin qx= 0XAAAA; --------------------> output1 32 bits qy= 0XBBBB; ------------------> output 32 bits read_data = qx; read_data = qy; end endmodule S/w part: //SCALAR_POINT_INST - user component name // # define user_comp_read IORD(scalar_point_inst_base,0) unsigned short int yy; //---------------------------------------------------------------- // MAIN PROGRAM //---------------------------------------------------------------- int main(void) { yy = user_comp_read; printf("\n data is %#x \n",yy); } so this basically reads one value.. i know there must be a simple way to get this working its just that i am new to this and having difficulties. I have only included the read part right now .. if you could guide me through it would be great.. also some tips on write also would b great.. - Altera_Forum
Honored Contributor
hey guys figured out where i was going wrong it was the data type i had assigned for it was wrong 'short' was creating all the problems for me ..
thanks u all - Altera_Forum
Honored Contributor
To be able to read two different 32-bit registers, you need to do some address decoding in your verilog code. For example you could assign read_data to qx if the address is 0 and to qy if the address is 1. Then from your software you can access them with IORD(SCALAR_POINT_INST_BASE,0) and IORD(SCALAR_POINT_INST_BASE,1).
- Altera_Forum
Honored Contributor
--- Quote Start --- To be able to read two different 32-bit registers, you need to do some address decoding in your verilog code. For example you could assign read_data to qx if the address is 0 and to qy if the address is 1. Then from your software you can access them with IORD(SCALAR_POINT_INST_BASE,0) and IORD(SCALAR_POINT_INST_BASE,1). --- Quote End --- hey Daixiwen, thanks for the reply... i used case statement for my address decoding, thanks alot for your reply it does clarify things.. .. i guess the same would work for write also ... right ?? i could use if statements and assign write_data to 3 different registers ... right ?? thanks again - Altera_Forum
Honored Contributor
Yes, exactly.
- Altera_Forum
Honored Contributor
hey Daixiwen sorry to trouble you again i seem to be having problems with reading / writing... more than one value i have no clue why i have tried everything possible the code works well as long as its only one value being written or read as soon as i change that to more than one i start getting garbage values. i implemented the address logic like u said.. i have pasted the test code here again please let me know if what i am doing is right or wrong ...
////////////////////////////////// here is the C code in Nios 2 /////////////// int main(void) { printf("enter the values to be passed\n"); for(i=0;i<1;i++) { scanf("%d",&k);iowr(scalar_write_inst_base,i,k); yy= iord_32direct(scalar_write_inst_base,i) ;
printf("\n output data is %#x \n",yy); } //////////////////////////// verilog test code/////////////////////////////// input [1:0] addr_off; ---- for address decoding logic reg [31:0] qx,qy; reg[31:0] temp; input[31:0] write_data; output[31:0] read_data; always @ (posedge CLOCK_50) begin if(addr_off==0) begin qx = write_data; read_data = qx; end else if (addr_off==1) begin qy= write_data; read_data=qy; end end // always /////////////////////////////// end ////////////////////////////////////////// the same code works if i just have one value to read or write but fails if more than 1 which makes me think there is some problem in the address decoding or in the S/w access side.. Please do let me know what am i doing wrong.. Or is there something else i should be taking into account and i havent ?? Thanks again..
- Altera_Forum
Honored Contributor
You must also have some 'read' and 'write' inputs. You should especially only perform the transfer from writedata if the "write" signal is 1. If you don't you can write garbage.
- Altera_Forum
Honored Contributor
--- Quote Start --- You must also have some 'read' and 'write' inputs. You should especially only perform the transfer from writedata if the "write" signal is 1. If you don't you can write garbage. --- Quote End --- hey Daixiwen.. i do have read and write day guess i forgot to include that in the code but i had not implemented the condition.. so you mean to say if write bit is set to 1 then a write transfer should take place write ?? btw.. i did try a few things yesterday and found out it was my width of address signal that was causing all the problems made it 8 now and the read write for more than 1 is working now .. but yes will include the new condition of when write and read signal is one only the transfer should take place.. Thanks again... - Altera_Forum
Honored Contributor
--- Quote Start --- To be able to read two different 32-bit registers, you need to do some address decoding in your verilog code. For example you could assign read_data to qx if the address is 0 and to qy if the address is 1. Then from your software you can access them with IORD(SCALAR_POINT_INST_BASE,0) and IORD(SCALAR_POINT_INST_BASE,1). --- Quote End --- hey i guess i am back with another doubt .. i am able to now write to the component but i am just using the same offset i.e. 0 and i have used flags in verilog to identify the data and store appropriately. my problem is when it comes to read i tried using a count variable to provide delay so that the nios could read and print the values.. well it does that but the output is random what i mean is that at times its right and at times its wrong . I dont know why could any one tell me why ?? 2nnd doubt: when i tried using different offsets for data as mentioned in the quote it works fine for offset 0 only and not any other. i defined address decoding using offsets in verilog but it didnt work. my basic doubt is do i have to write my own 'regs.h' file for my SOPC component if not could please some one help me out .. i guess the whole offset idea is not cear so could some one clarify this please.. thanks alot if any