Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12589 Discussions

QUARTUS 4.2 NIOS 1.1 UPDATE PROBLEM

Altera_Forum
Honored Contributor II
1,635 Views

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 = ""; 

}
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
406 Views

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)

0 Kudos
Altera_Forum
Honored Contributor II
407 Views

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) ]
0 Kudos
Altera_Forum
Honored Contributor II
407 Views

Thanks for your reply, 

 

I&#39;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)
0 Kudos
Altera_Forum
Honored Contributor II
406 Views

I&#39;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)
0 Kudos
Altera_Forum
Honored Contributor II
406 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
407 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
407 Views

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&#39;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&#39;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&#39;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&#39;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&#39;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.
0 Kudos
Altera_Forum
Honored Contributor II
407 Views

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 ???
0 Kudos
Altera_Forum
Honored Contributor II
407 Views

IORD and IOWR does the multiplication by 4 for you (it&#39;s a macro). So if you use those then you don&#39;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.
0 Kudos
Altera_Forum
Honored Contributor II
407 Views

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)
0 Kudos
Reply