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++
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Register write/read

Altera_Forum
Honored Contributor II
1,500 Views

I wrote a simple VHDL component for SOPC builder that just has one 32 bit register. I can read and write it OK, but I have to read it twice to read the value I just wrote. The first read gives me the old value.  

 

Here's the sequence: 

 

write 0x01 to register 

read 0x00 from reg. Why isn't this 0x01? 

read 0x01 from reg. OK now it's right. 

 

write 0x02 to reg. 

read 0x01 from reg. Should be 0x02. 

read 0x02 from reg. correct. 

 

I'm using IORD/WR and there's no cache in the system. I set the read latency to 1 in component editor. Write latency, waits, setup, & hold are set to 0. 

 

 

Here's the VHDL for the register: 

 

signal scratch_reg : std_logic_vector(31 downto 0); 

... 

reg_p : process (CLK, reset_n) is 

begin 

if reset_n = '0' then 

scratch_reg <= (others => &#39;0&#39;); 

elsif CLK&#39;event and CLK = &#39;1&#39; then 

-- WRITE  

if chipselect = &#39;1&#39; and write = &#39;1&#39; then 

scratch_reg <= writedata; 

end if; 

-- READ 

if chipselect = &#39;1&#39; and read = &#39;1&#39; then 

readdata <= scratch_reg; 

end if; 

 

end if; 

end process reg_p; 

 

 

And the C code: 

alt_u32 data;  

... 

scanf("%x", &data); //get write data 

IOWR(SCRATCHPAD_BASE, 0, data); 

printf("SCRATCH set to 0x%08X \n", IORD(SCRATCHPAD_BASE, 0) ); 

printf("SCRATCH set to 0x%08X \n", IORD(SCRATCHPAD_BASE, 0) ); 

 

The first printf prints the old value, the 2nd one prints the correct value. 

 

Any idea where the problem is? 

http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/blink.gif  

 

Thanks in advance for any suggestions.
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
557 Views

The problem is that your peripheral has a read latency of 2. Since readdata is in a clocked process, the output will not be valid until the first clock edge after chip select and read are asserted. This means that the master (the Nios CPU) cannot sample the data until the clock cycle after that (e.g., the second rising clock edge). 

 

In your current implementation, the processor is reading the old value of readdata. That&#39;s why it takes two read cycles to get the correct data. If you change your read latency to 2, you should be all set.
0 Kudos
Altera_Forum
Honored Contributor II
557 Views

I agree with the suggestion of PinnacleDesignConsulting, I also experienced reading the old value because of wrong latency/wait state, but it seems to me that the vhdl code shown has a read latency of 1. 

At least, looking at sample waveform in component editor (SOPC Builder 6.0), address-chipselect-read are asserted in first clock cycle (let&#39;s say cycle 0), and if the readdata is available in the same clock cycle (cycle 0) we have 0 read latency or 0 read wait states. 

If the readdata is available at the next clock cycle (cycle 1) we have 1 read latency or 1 read wait state. 

And so on... 

So if readdata was not clocked we&#39;d have 0 read latency, since readdata is in a clocked process we have 1 read latency (or 1 read wait state). 

Does timing analyzer signal timing error? 

 

 

 

 

 

 

--- Quote Start ---  

originally posted by pinnacledesignconsulting@Nov 17 2006, 04:11 AM 

the problem is that your peripheral has a read latency of 2.  since readdata is in a clocked process, the output will not be valid until the first clock edge after chip select and read are asserted.  this means that the master (the nios cpu) cannot sample the data until the clock cycle after that (e.g., the second rising clock edge). 

 

in your current implementation, the processor is reading the old value of readdata.  that&#39;s why it takes two read cycles to get the correct data.  if you change your read latency to 2, you should be all set. 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=19481) 

--- quote end ---  

 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
557 Views

User error! 

 

Read latency of 1 works. I didn&#39;t delete & re-instantiate the components in SOPC builder, so they were still being compiled with read latency set to 0. 

 

Thanks, 

Chris
0 Kudos
Altera_Forum
Honored Contributor II
557 Views

I don&#39;t believe that read latency and read wait states are equivalent. In this case, 

I think you want to be using wait states, since read latency is associated with pipeline transfers.
0 Kudos
Altera_Forum
Honored Contributor II
557 Views

I just tried this example made this Scrachpad component(it worked well) and then In NIOS II IDE this code didn&#39;t worked there was no printF window and also no scanf windos towrite som value. Actualy I don&#39;t anderstan I tried a diferent code but also without results I cann&#39;t read this value from this component register http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/mad.gif  

 

here is code and it don&#39;t work ! 

 

why there is no Assembler examples of how to write value to custom made component register and then read it or some ather working simple example who is working! 

 

#include <stdio.h># include "system.h"# include "SCRATCHPAD_REGS.H" int main() {    int data;    int file;    data = 55555; //get write data    IOWR(SCRATCHPAD_0_BASE, 0, data);    file = IORD(SCRATCHPAD_0_BASE, 0); }
0 Kudos
Reply