Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
820 Views

NIOS II memory writes failing - values being input at wrong addresses (I2C opencore)

Hi, 

 

I'm trying to integrate an I2C core from opencores to my Cyclone IV device. Apparently the version I'm using should just drop into the SOPC and work after being wired to some outputs (alterawiki.com/wiki/I2C_(OpenCores)). The core compiles with no errors or warnings.  

 

My problem is with my NIOS II code. The I2C docs with the core show 6 relevant registers addressed one after another (PRERlo, PRERhi, CTR, TXR, RXR, CR, SR). However, when I attempt to write to these registers I am unable to write to some of them. The write is put into the wrong address whether from my code or manually in debug memory window.  

 

https://www.alteraforum.com/forum/attachment.php?attachmentid=7109  

 

To investigate this I set the registers to initial values in VHDL to see the result in the debug window. This showed that the register addresses for TXR and CR are not what is suggested in the docs.  

 

 

Address 0 1 2 3  

09866160 AA 00 00 00 -- PRERlo 

09866164 00 00 00 00 -- PRERhi 

09866168 BB 00 00 00 -- CTR 

0986616C DD 00 00 00 -- RXR 

09866170 FA 00 00 00 -- SR 

09866174 CC 00 00 00 -- TX 

09866174 EE 00 00 00 -- CR 

 

This would be fine, however, when I attempt to write to address 09866174 (TXR) the value is inserted at 09866164 (PRERhi). Similarly when I write to 09866178 (CR) the value is inserted into 09866168(CTR). This happens whether the write comes from the code or manually from the debug window. This is particularly confusing as writing to these registers works fine in VHDL. 

 

I have attempted to debug this from signal tap also. However, triggers on any of the registers are never implemented. 

 

I'd really appreciate if anyone can point me in the right direction here.  

 

Thanks!
0 Kudos
7 Replies
Altera_Forum
Honored Contributor I
58 Views

In signaltap you should be able to trigger on the "write" signal. 

Could you show us the code you are using to write to the registers? 

Are you sure that 9866160 (in hexadecimal) is the correct base address? 

Is the FPGA configured with the correct .sof image (i.e. did you, in that order, generate the SOPC system, compile the Quartus project and upload the .sof image to the FPGA before doing the test?)
Altera_Forum
Honored Contributor I
58 Views

Thanks for your reply. 

 

I've set up signal tap to try trigger on write (Compiling now).  

 

I'm using:  

 

# define IOWR(base,offset,value) __builtin_stwio ((unsigned int*)BASE + OFFSET, (DATA)); 

IOWR(I2C_MASTER_BASE, 5, 0x1D);  

 

to write to the registers which I think is working because it works fine for some registers and with simple PIO tasks. I am confident that 0x9866160 is the correct address as it is taken from the SOPC builder and based on the fact that when I initiate values into the registers in the VHDL I can see them at this address in the debug window.  

 

I am sure the FPGA is configured in the correct order as I've been working on it for several days now so it's been programmed many times now. However, I am re-compiling right now so will make 100% sure the order is correct. 

 

Thanks for your time, i'll update the situation when I see if I can trigger on write.
Altera_Forum
Honored Contributor I
58 Views

The IOWR macro will bypass the Nios's cache so it should trigger a write to your component. If you still can't synchronize, could you show us which "write" signal you are using? Is it the one from your component's Avalon interface, or is it the internal one, inside the wrapper?

Altera_Forum
Honored Contributor I
58 Views

I am using the 'write' signal from the wrapper. - _sopc:CPU|i2c_master_0:the_i2c_master_0|write 

 

But I also signal tapped the avalon bus 'write' to be sure - _sopc:CPU|cpu:the_cpu|cpu_nios2_oci:the_cpu_nios2_oci|cpu_nios2_avalon_reg:the_cpu_nios2_avalon_reg|write 

 

Neither one shows any change in signal tap.
Altera_Forum
Honored Contributor I
58 Views

It is really strange that you don't see any trigger on the write signal, even on the CPU. I'm not sure which one this second signal is though... can you look for the CPU's data master and find it's write signal? If you still don't see anything there must be something wrong with your Signaltap, because if the CPU never writes anything it just can't work! 

Did you set several triggers in signaltap? If yes it will only trigger when *all* triggers are asserted simultaneously, so you need to make sure you only set one signal as trigger at a time.
Altera_Forum
Honored Contributor I
58 Views

Ah! I'm very sorry I did not know that multiple triggers have to assert simultaneously. With that change I do get a trigger on write. Thank you very much for that lesson! It's been working for me up to now by shear luck! 

 

On the memory write problem, I havn't gotten any further. I have been using the VHDL version of the core as the rest of my code is VHDL so I wanted to keep in VHDL for continuity. However, I decided to throw in the towel for now and use the Verilog version which worked almost straight away when I wired it up. My plan is to implement my application fully with the Verilog core and then maybe come back to the VHDL to try to debug. 

 

Thanks a million for your time.
Altera_Forum
Honored Contributor I
58 Views

I fell into this trap at lease once too, don't worry ;) If you want to be able to trigger on any of several different events, you need to make an "Advanced" type of trigger instead of "Basic".