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++
12600 Discussions

Access of 32bit registers using PCIe in SoPC

Altera_Forum
Honored Contributor II
1,210 Views

Hello, I am implementing a PCIe using SoPC builder. One of the BARs should be a configuration BAR with 32bit registers that are setting various parameters of my device. The BAR is 32bit non-prefetchable BAR as I need access the registers only as a single registers (ie. I want to simulate I/O registers). The problem is that when I read a register from PC, it translates to two reads on the Avalon bus. When I read for example offset 0x05, I get 32bit reads from offset 0x04 and 0x05. When I read the offset 0x04, I get the same two reads. I do know that it is possible to read a single 32 bits using PCIe, what should I set to get this right?

0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
541 Views

For various reasons known only to someone at Altera the PCIe is always (effectively) a 64bit master. This means there is a 'bus width adapter' between it and your 32bit slave. 

The bus width adapter always generates all of its slave cycles, even when one of them doesn't require any data (I'd have though it could skip them, possibly at a cost of 1 clock). 

So you need to ensure your slave looks at the byte enable lines, rather than assuming that all transfers are 32 bits.
0 Kudos
Altera_Forum
Honored Contributor II
541 Views

It is also worth noting that PCIe slave transfers are likely to be somewhat lethargic, I've measured about 2us from a ppc. 

You'll need to use something that generates longer PCIe data bursts to get passable performance.
0 Kudos
Altera_Forum
Honored Contributor II
541 Views

Well, the reason for 64bit master is, that the PCIe basically is 64bit oriented protocol. 

 

I am using the byteenables. When I access the register 4, the read occurs on 4 and 5 with byteenables 0xF. Then when I read register 5, the read occurs on 4 and 5 with byteenables 0x0. So that could mean, that the core "caches" the data somehow, but that is totally unacceptable for me - the BAR is 32bit NON-prefetchable, so the PCIe IP should treat it that way.
0 Kudos
Altera_Forum
Honored Contributor II
541 Views

It looks more like the 32bit transfers are always using byte selects 0-3, instead of the second transfer (ie the odd address) using byte selects 4-7. 

 

We had a similar problem, but I think it got fixed properly (the hack was to put the registers on even addresses so that the second cycle didn't matter!)
0 Kudos
Altera_Forum
Honored Contributor II
541 Views

Well that is not a solution for me, because I already have a map of registers and I cannot move it. 

 

But I think that I've found a solution for this - I just created a 64bit interface with 8 byte enables. This behaves correctly, so with some small adapter I can derive a 32bit interface from this that will also work correctly. I really don't know, why the SoPC builder cannot do this same way...
0 Kudos
Altera_Forum
Honored Contributor II
541 Views

The SOPC builder should add a bus width adapter to allow 32 bit masters to access a 64bit slave (that ought to be trivial and not take any extra clock cycles, but ...)

0 Kudos
Altera_Forum
Honored Contributor II
541 Views

Well, but how can add that adapter? Maybe you do not understand my problem correctly. 

 

My system consists of PCIe and custom made component that is MM slave that drives some registers outside the SoPC system (address, data in, data out, byte enables, read and write). When I create this interface as 32bit, the single read from 32bit memory location from PC (through the PCIe) converts to two reads from my registers - so there are two reads from adjacent addresses and both reads have 0xF in byteenables. That is unacceptable for me. 

 

But when I create this interface as 64bit it works correctly. When I issue read from the PC side, it converts to single 64bit read with byteenables of 0x0F or 0xF0 (depending on whether the 32bit address is even or odd). That is exactly what I would expect. Why this is not working also on 32bit interface is really unclear to me...
0 Kudos
Altera_Forum
Honored Contributor II
541 Views

The SOPC builder adds bus width adapters (and clock crossing bridges) where ever it deems them necessary, and doesn't tell you where it has put them!

0 Kudos
Altera_Forum
Honored Contributor II
541 Views

Well then if there is any 64bit to 32bit adapter, it is not working correctly. When there is only a 32bit read, it cannot translate it to full 64bit read.

0 Kudos
Reply