- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After update to Quartus 4.2 and Nios 1.1
I have a problem with an 8-Bit Slave (user logic) the adress lines are connected as follows CPU A 9 8 7 6 5 4 3 2 1 0 8-BIT SLAVE A 7 6 5 4 3 2 1 0 - - with Quartus 4.1 NIOS 1.0 data was written and read with IOWR(baseadd,add,data); IORD(baseadd,add); everything worked fine. after update to Quartus 4.2 NIOS 1.1 I've get the following wrong values at the address lines. by using IORD: BYTE hfce1_read(HFCE1 *pi,BYTE add) { BYTE data; data=IORD(pi->baseadd,add); return data; } 0x0080d0e8 <hfce1_read>: addi sp,sp,-12 0x0080d0ec <hfce1_read+4>: stw fp,8(sp) 0x0080d0f0 <hfce1_read+8>: mov fp,sp 0x0080d0f4 <hfce1_read+12>: stw r4,0(fp) 0x0080d0f8 <hfce1_read+16>: mov r2,r5 0x0080d0fc <hfce1_read+20>: stb r2,4(fp) 0x0080d100 <hfce1_read+24>: ldw r4,0(fp) 0x0080d104 <hfce1_read+28>: ldbu r2,4(fp) 0x0080d108 <hfce1_read+32>: slli r3,r2,2 0x0080d10c <hfce1_read+36>: ldw r2,4(r4) 0x0080d110 <hfce1_read+40>: add r2,r3,r2 0x0080d114 <hfce1_read+44>: ldwio r2,0(r2) 0x0080d118 <hfce1_read+48>: stb r2,5(fp) 0x0080d11c <hfce1_read+52>: ldbu r2,5(fp) 0x0080d120 <hfce1_read+56>: ldw fp,8(sp) 0x0080d124 <hfce1_read+60>: addi sp,sp,12 0x0080d128 <hfce1_read+64>: ret (A2 of CPU is connected to A0 of slave) CPU A 9 8 7 6 5 4 3 2 1 0 8-BIT SLAVE A 7 6 5 4 3 2 1 0 - - add=0x04 0 0 0 0 0 0 0 1 0 0 (measured CPU Address bus) if I read e.g. add=0x04, the address bus of the cpu is 0x??????04 and this is add=0x01 at slave, which is wrong ------------------------------------------------------------------------------- part from ptf file MODULE HFCE1_0 { class = "altera_avalon_user_defined_interface"; class_version = "2.5"; SYSTEM_BUILDER_INFO { Instantiate_In_System_Module = "0"; Is_Enabled = "1"; Date_Modified = "--unknown--"; View { MESSAGES { } Is_Collapsed = "1"; } Clock_Source = "clk"; } WIZARD_SCRIPT_ARGUMENTS { Imported_Wait = "0"; Nios_Gen_Waits = "1"; Simulate_Imported_HDL = "0"; Port_Type = "Avalon Slave"; HDL_Import = "0"; Timing_Units = "ns"; Unit_Multiplier = "1"; Setup_Value = "40"; Hold_Value = "40"; Wait_Value = "160"; Address_Width = "32"; Module_List = ""; Show_Streaming = "1"; Show_Latency = "0"; Technology = "User Logic"; File_Count = "0"; Port_Count = "6"; Component_Desc = "HFCE1"; Module_Name = ""; } SLAVE avalonS { SYSTEM_BUILDER_INFO { Bus_Type = "avalon_tristate"; Address_Alignment = "native"; Address_Width = "8"; Data_Width = "8"; Has_IRQ = "1"; Base_Address = "0x00903000"; Has_Base_Address = "1"; Read_Wait_States = "160.0ns"; Write_Wait_States = "160.0ns"; Setup_Time = "40.0ns"; Hold_Time = "40.0ns"; Is_Memory_Device = "0"; Uses_Tri_State_Data_Bus = "1"; Is_Enabled = "1"; MASTERED_BY ext_ram_bus/tristate_master { priority = "1"; } IRQ_MASTER cpu/data_master { IRQ_Number = "4"; } } PORT_WIRING { PORT address { direction = "input"; width = "8"; type = "address"; is_shared = "1"; } PORT write_n { direction = "input"; width = "1"; type = "write_n"; is_shared = "1"; } PORT read_n { direction = "input"; width = "1"; type = "read_n"; is_shared = "1"; } PORT data { direction = "inout"; width = "8"; type = "data"; is_shared = "1"; } PORT chipselect_n { direction = "input"; width = "1"; type = "chipselect_n"; } PORT irq_n { direction = "output"; width = "1"; type = "irq_n"; } } } MASTER avalonM { SYSTEM_BUILDER_INFO { Bus_Type = "avalon"; Data_Width = "32"; Address_Width = "8"; Max_Address_Width = "32"; Is_Enabled = "0"; } } SLAVE ahbS { SYSTEM_BUILDER_INFO { Bus_Type = "AHB"; Has_IRQ = "0"; Has_Base_Address = "1"; Address_Width = "10"; Data_Width = "32"; Base_Address = "--unknown--"; Address_Alignment = "native"; Read_Wait_States = "0"; Write_Wait_States = "0"; Is_Enabled = "0"; } } MASTER ahbM { SYSTEM_BUILDER_INFO { Bus_Type = "AHB"; Address_Width = "32"; Max_Address_Width = "32"; Data_Width = "32"; Interrupts_Enabled = "1"; Irq_Scheme = "Individual_requests"; Is_Enabled = "0"; } } HDL_INFO { Imported_HDL_Files = ""; } }Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes this was discussed in another thread. To solve this problem add an extra bit to the address width (called Address_Width) in the class.ptf file for that component. In Quartus 4.1 an extra bit was added to the address (one more then there should have been) and with Quartus 4.2 this is fixed (so if it was connected to that extra bit then it will not be connected after the upgrade). So when you make this change you are compensating by adding an extra bit (to get back to where you started with Quartus 4.1)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Fischer,
Yes, I had the same problem and solved this by multiplying all address offsets in my headerfiles (not base addresses) . All byte ports need a multiplication by 4, all 16-bit ports need a multiplikation by 2. Mike [ see other thread ... (http://www.niosforum.com/forum/index.php?act=st&f=2&t=903) ]- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your reply,
I'm a little bit confused, what is wrong. First the part of the ptf file for this component is equal to that of Quartus 4.1 (only one additional line " Clock_Source = "clk"; " looking at io.h .. /* Native bus access functions */ # define __IO_CALC_ADDRESS_NATIVE(BASE, REGNUM) ((void *)(((alt_u8*)BASE) + ((REGNUM) * (SYSTEM_BUS_WIDTH/8)))) # define IORD(BASE, REGNUM) __builtin_ldwio (__IO_CALC_ADDRESS_NATIVE ((BASE), (REGNUM)))# define IOWR(BASE, REGNUM, DATA) __builtin_stwio (__IO_CALC_ADDRESS_NATIVE ((BASE), (REGNUM)), (DATA)) .. by using IORD(..) __IO_CALC_ADDRESS_NATIVE already makes a multiplication of register * 4 the base adress of my component is 0x903000 IORD(baseadd,0x01) results in __builtin_ldwio(0x903004) which should read Register 1 of my slave the first time I get A0=1 of my slave (A2 of CPU) is by reading IORD(baseadd,0x10) results in __builtin_ldwio(0x903040) but the addtress bus of the cpu is 0x????04 Multiplication of all offsets by 4, before calling IORD is a workaround, but no slolution. is the above ptf file correct for this component ? is this a bug in SOPC Buider 4.2 ? Quartus 4.2 ? NIOS 1.1 ? is it only a project conversion problem from 4.1 to 4.2 ? (I regenerated the system in SOPC Builder 4.2 and recompiled with Quartus 4.2)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm not happy with the update to Quartus 4.2 and NIOS 1.1
I received the following answer from Altera for my problem with user logic, but I do not understand this answer. ------------------------------------------------------------------------------ Problem: "Why does my embedded system fail to compile after upgrading to Quartus II version 4.2 due to an address width mismatch?" Solution: "In previous versions of Quartus II, SOPC Builder created an extra most significant address bit for registered slave peripherals (also called native peripherals) connected to an Avalon Tri-State Bridge. If this bridge has only native slave devices connected to it then some designers may have connected this extra address bit in their design to a peripheral. This extra address bit no longer exists if the embedded system is regenerated using Quartus II version 4.2. If a design is using the extra address bit and the Quartus II software is upgraded to version 4.2 then a compilation error will occur due to the most significant address bit not being connected. This issue can be corrected without the need to modify software or hardware interconnects. If the peripheral affected by this issue is connected to an interface to user logic, then increasing the address width by one (in the interface to user logic) will correct the issue. If the peripheral affected by this issue is a custom component, edit the "class.ptf" file for that component by increasing the value called "Address_Width" by one." ------------------------------------------------------------------------------ 1. the design could be regenerated and compiled with Quartus 4.2 without error 2. the bridge has additional ram and flash connected. 3. I entered 8 address bits in SOPC builder and I connected exactly 8 address bits from the address bus to my user logic. (which extra address bit ???, how can I see this in a shared address bus? ) again: I have an 8 bit avalon register slave. address bus is shared with SRAM AND FLASH Address A[9..2] are connected to A[7..0] of 8 bit slave Interface to user logic: PORTNAME WIDTH DIRECTION SHARED TYPE address 8 input yes address write_n 1 input yes write_n read_n 1 input yes read_n data 8 inout yes data chipselect_n 1 input --- chipselect_n irq_n 1 output --- irq_n IORD and IOWR do not output the cortrect address on the bus. is this a bug in SOPC Buider 4.2 ? Quartus 4.2 ? NIOS 1.1 ? is it only a project conversion problem from 4.1 to 4.2 ? (I regenerated the system in SOPC Builder 4.2 and recompiled with Quartus 4.2)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This was an issue with the SOPC Builder that came with Quartus II version 4.1 The desciption that you were sent only applies if a user connected the extra address bit to the peripheral. When you upgrade to Quartus II version 4.2 that address bit is no longer present so you have two options. 1) The fix that was outlined in your correspondence from Altera, or 2) regenerate, connect the address bits correctly, and align your address space to the peripheral correctly in software(so I recommend you do the first one).
Also as MiR stated, to talk to your peripheral you have to be word aligned, even though you are talking to an 8 bit peripheral, the data on the Nios II side is 32 bit. An example of this is if you have an 8-bit peripheral, and you talk to external native registers called "A", "B", and "C" with the base address of the peripheral specified at "base". Then you access the peripheral reading and writing at the following addresses: A <---> base B <---> base + 4 (next word) C <---> base + 8 (next word) So you may have run into either issue. If it looks like the address bits are properly aligned then the answer that you were sent from Altera was a different issue. I recommend looking at the link that MiR provided since there is a lot of discussion in their about this. Let us know if you are still running into problems.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is the setting, which I made in SOPC Builder, wrong ?
I only can say that I connected A9..A2 of the address bus(A22..A0) to A7..A0 of the 8 bit slave. The size of the address bus did not change with respect to Quartus 4.1 (same problem as niosIIuser) A <---> base B <---> base + 4 (next word) C <---> base + 8 (next word) this should be done by (A=0,B=1,C=2) IORD(base,A) <--> base IORD(base,http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/cool.gif <--> base+4 IORD(base,C) <--> base+8- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, then this is correct you probably have run into the second issue I describbed. When I used +4 and +8 those are the word alignments on the Nios side, but the peripheral itself will be knocking off the two lsbs of the address. I have lost track in this long post what the peripheral is but I seem to recall it's some 8 bit native peripheral. Because it is an 8 bit device it byte offsets of 1, 2, and 3 all map to the same address on the peripheral side (you are just lining up the 8 lsbs of the data from the avalon bus to the 8 data bits of your peripheral so trying to write to bits 31..8 doesn't really make much sense). Here is an example that I hope clarifies this (well at least I attach a link to a document that explains this if my example doesn't do the job):
I have some piece of logic that I want to connect to the interface to user logic. My data width is 8 bits, and I have 6 registers to write to externally. The IUL will connect address bits 5..3 from the avalon bus to bits 2..0 on the external interface (where you connect your hardware). So I would access these registers in my software from offsets of 0, 4, 8, 12, 16, 20. But on my external interface I'll see addresses of 0, 1, 2, 3, 4, 5 (because the avalon addresses 5..3 were mapped to external addresses 2..0). So address bits going from the avalon bus to the external bus are simply being shifted to the right by two bits (the two lsbs are not used because they are not necessary with a 32 bit master writing to an 8 bit slave). This may seem odd but it serves a very important purpose when it comes to masters of different widths trying to use a peripheral like this. Using that example lets say another master of only 16 bits is used. In this case to properly align the address bits only the first lsb will be knocked off (so an address shift by 1 bit to the right). The IUL knowns to do the proper shifting depending on the data width of the master (so with the 32 bit master it'll access offsets of 4, 8, 12, etc... and the 16 bit master will access the peripheral at offsets of 2, 4, 6, etc...) But looking at the external addresses going to the peripheral, the offsets will be always 1, 2, 3, 4, etc..... (so your hardware pepripheral is transparent to the width of the master). I recommend taking a look at this document "Avalon Bus Specification", http://www.altera.com/literature/manual/mn..._avalon_bus.pdf (http://www.altera.com/literature/manual/mnl_avalon_bus.pdf) <page 100>. It has a table showing what I explained, only it probably makes more sense since describing hardware in plain text is tricky. Let me know if this is making sense or I have just steered you down the wrong path further.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the problem still exists, can someone from ALTERA please check what the problem
is, setup of user logic wrong ? physical connection to 8 Bit slave wrong ? IORD, IOWR problem ? conversion problem ? the proposed workaround: multiply the register * 4 before calling IORD and IOWR, results in a multiplication by 16 for __builtin_ldwio ??? (see macro IORD in io.h) what will be a workaround, and what I have to change with next software version ? should I go back to Quartus 4.1 and NIOS 1.0 ???- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
IORD and IOWR does the multiplication by 4 for you (it's a macro). So if you use those then you don't need to multiply it (MiR was probably talking directly to the peripheral and had to do the multiplication factor of 4 manually).
Can you probe the address pins and figure out what is coming out? If you write to the base address of the peripheral you should see an address of 0 come out of the system, if you write to base + 4 then you should see address 1 come out of the system, .... and so on.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the adress lines are connected as follows
CPU A[9..2] to 8-BIT SLAVE A[7..0] BASE 0x903000 correct behavior should be (is with Quartus 4.1 Nios 1.0) : function systemadd(CPU) add at slave IORD(BASE,0x00) 0x????00 0x00 IORD(BASE,0x01) 0x????04 0x01 IORD(BASE,0x02) 0x????08 0x02 IORD(BASE,0x03) 0x????0C 0x03 .. IORD(BASE,0x10) 0x????40 0x10 wrong behavior is (measured): function ldwio r2,0(r2) systemadd(CPU) add at slave IORD(BASE,0x00) r2=0x903000 0x????00 0x00 IORD(BASE,0x01) r2=0x903004 0x????01 0x00 IORD(BASE,0x02) r2=0x903008 0x????02 0x00 IORD(BASE,0x03) r2=0x90300C 0x????03 0x00 IORD(BASE,0x04) r2=0x903010 0x????04 0x01 (by debugging assembly code, i can see that r2 has the correct value before ldwio)- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page