Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Honored Contributor I
2,056 Views

Dual port RAM shared between Nios and async interface

Hi all, 

I want to upgrade an existing system and I wonder if anyone can give me hints. 

 

I have a board with CIII device with Nios and an external Analog Device DSP: both Nios and DSP need to access a shared memory, which is FPGA onchip RAM. 

The current (working) implementation is:  

- sopc system with Nios and tristate bus 

- external lpm ram component in dual port mode. 

- Nios accesses ram through tristate bus 

- dsp accesses directly to the ram through its Async Memory Interface 

I'd like to eliminate the tristate bus and integrate the ram in sopc system, so that Nios can access it directly with Avalon bus. 

I think I can do it by defining a new onchip ram component and exporting signals of one port; I found something similar in another thread. 

But I think I'd also need some glue logic to connect to dsp AMI. 

 

Question 1: is this way of operation viable? is there a better solution? 

Question 2: is such sopc component already available anywhere? 

 

Thank you 

Regards
0 Kudos
20 Replies
Highlighted
Honored Contributor I
43 Views

Hi, 

if you can use the DSP AMI control signals directly as avalon master signals (even it is an asynchronous interface the signal are related to the a clock) you can use a simple tcl script to export the avalon master signals to the top level. The tcl script creates a component with a master interface where you can connect one slave interface of the dpram. Additionally the master signal are exported. You do not need a HDL file for exporting the signals. You need a small logic for connecting avalon read- and writedata to the dsp databus . If your DSP signals do not match you must create your own avalon master component where you have to convert the DSP signals to avalon master signals. An others solution is to build your own dpram component with one avalon slave interface and one export interface. AFAIK simply exporting one port of the sopc builder dpram is not possible.
0 Kudos
Highlighted
Honored Contributor I
43 Views

HJS, thank you for your reply. 

 

 

--- Quote Start ---  

 

if you can use the DSP AMI control signals directly as avalon master signals (even it is an asynchronous interface the signal are related to the a clock) you can use a simple tcl script to export the avalon master signals to the top level.  

 

--- Quote End ---  

 

I think this is the solution. But I'm not very expert with tcl scripts. Can you suggest me a reference or give me an example. 

 

 

--- Quote Start ---  

 

An others solution is to build your own dpram component with one avalon slave interface and one export interface. AFAIK simply exporting one port of the sopc builder dpram is not possible. 

--- Quote End ---  

 

Infact I tried this before asking here. 

At the moment I'm doing this: I created a lpm dual port ram block with Quartus megawizard; then I defined a new sopc component based on this dp ram, one port connected to Avalon signals and the other exported. 

No problem about the exported signals, since the interface is exactly the same as the current project, with external lpm dp ram block.  

But I'm concerned about the port connected to Avalon bus: I don't know if the direct connection between Avalon and lpm signals is correct. 

I attach the resulting tcl file generated by sopc builder component editor.
0 Kudos
Highlighted
Honored Contributor I
43 Views

Hi, 

 

I attached a tcl script. BTW you can do this easily with the Component Editor (I did this tcl script with the component editor). Just add one master interface. Then on the signal tab just add the signals you want to export and assign them to the avalon master interface signals. 

I do not see any problems in your approach with the direct connection between the avalon slave interface and the dual port ram.
0 Kudos
Highlighted
Honored Contributor I
43 Views

Ok. I got it. It was easier than I expected.  

Before your hints I missed it because I thought I had to explicitly expose signals I wanted to export, which I couldn't do with onchip ram sopc component. Adding the "fake" component with master interface does the trick. 

I'll test both solutions and I'm confident at least one of them will do the job. 

 

Bonus question:  

Now my external master is supposed to access only one dpram port, while Nios master accesses the other side. 

I wonder if I can use the same component to allow the dsp or any other host processor to access the main Avalon bus 

(I don't need this now; just an idea for future projects) 

 

Thank you again HJS
0 Kudos
Highlighted
Honored Contributor I
43 Views

If you used the standard on-chip RAM component in SOPC Builder and created a master to access the second port then you could use a tightly coupled memory connection between the CPU and 2nd memory port (and not have to worry about cache coherency). Creating master logic is pretty easy so you might find this approach to be cleaner and more scalable too.

0 Kudos
Highlighted
Honored Contributor I
43 Views

I think there are two points to consider if you do accesses to the main avalon bus from your host processor.  

1. You have to synchronize the host processor accesses to your avalon clock domain. 

2. Your host processor should have some kind of ready/wait/TA signal.
0 Kudos
Highlighted
Honored Contributor I
43 Views

 

--- Quote Start ---  

I think there are two points to consider if you do accesses to the main avalon bus from your host processor.  

1. You have to synchronize the host processor accesses to your avalon clock domain. 

2. Your host processor should have some kind of ready/wait/TA signal. 

--- Quote End ---  

 

 

Yes, this was implied in the question. 

I'm aware of these requirements. 

Thank you
0 Kudos
Highlighted
Honored Contributor I
43 Views

Hi HJS, 

I implemented your solution and it works perfectly! Thank you again. 

Could you answer one last question? Just because I read Avalon specification but I'm not sure if I understood everything. 

 

Following your hints, I now have a sopc system exporting address,be,cs,rd,wr,writedata input signals and readdata,waitrequest output signals. Connecting to these signals my external processor can now rd/wr data on the onchip dpram. 

Suppose now the bus I connect to needs arbitration, for example because I connected to a multi master bus, or the main Avalon bus, as I asked in the question above. 

Point 1 is ok: host processor is sync to Avalon clock domain 

Regarding point 2, is the waitrequest signal enough to manage master accesses? 

I mean, should host processor simply drive cs, rd or wr, be, addr signals and hold until waitrequest signal is asserted or a more complex handshake logic may be required? 

I want I minimal implementation, then no arbiterlock, pipeline or burst functions 

 

Regards 

Cris
0 Kudos
Highlighted
Honored Contributor I
43 Views

Hi Cris, 

the avalon wait signal should be enough, but it can be a bit more complicated than just using this signal as wait signal for your host. Maybe you have to assert the wait signal for the host processor before you get the wait from the avalon and maybe you have to assert the wait for the host processor longer then the avalon wait is asserted (especially for reads from the host). This depends on the timing of your host processor.
0 Kudos
Highlighted
Honored Contributor I
43 Views

Thank you for replying again 

 

 

--- Quote Start ---  

Maybe you have to assert the wait signal for the host processor before you get the wait from the avalon  

 

--- Quote End ---  

 

I think this is not a problem. My host processor can add a fixed number of wait cycles before it starts polling waitrequest signal. 

 

 

--- Quote Start ---  

 

and maybe you have to assert the wait for the host processor longer then the avalon wait is asserted (especially for reads from the host). This depends on the timing of your host processor. 

--- Quote End ---  

 

This would not be a problem, too. I can add minimal glue logic to generate the reuiqred delay 

 

Regards
0 Kudos
Highlighted
Honored Contributor I
43 Views

Hi, I did not want to create a new thread because I have a very similar problem with my dual port RAM which is shared between NIOS and my async interface. Please let me know if I need to create another thread. 

 

 

First, I am using Quartus II 9.0 SP2 with a CIII device with Nios. I currently need the Nios to write data into a dpram and then my verilog logic block to access the ram to read the data in a different clock domain.  

 

 

The current (working) implementation was:  

- sopc system with Nios and pio bus 

- external lpm ram component in dual port mode. 

- Nios accesses ram through pio bus 

- my verilog logic will access the external lpm ram directly to read. 

 

 

To have a cleaner solution, I'd like the Nios to access the dpram directly with Avalon bus. 

 

 

Following this thread, I added a new onchip ram component with dual-port enabled from SOPC builder. Then using the "new component", I used the conduit to export all I/Os of one port and connected the other port to all "avalon_slave" (clk was to clk_sink). I did not add a avalon master because I still do not understand how that plays a role. 

 

 

Then, I had to tie these pins at the SOPC block diagram: 

inputs 

address2_to_the_dual_port_ram_0[10:0] = verilog logic addr output 

byteenable2_to_the_dual_port_ram_0[3:0] = pulled high 

chipselect2_to_the_dual_port_ram_0 = pulled high 

clk2_to_the_dual_port_ram_0 = clk 

clken2_to_the_dual_port_ram_0 = pulled high 

write2_to_the_dual_port_ram_0 = pulled low 

writedata2_to_the_dual_port_ram_0[31..0] = pulled low 

 

 

outputs 

readdata2_from_the_dual_port_ram_0[31..0] = verilog logic read data input 

 

 

After compilation, I created a new NIOS project and tried to write 0xAB to the ram. 

 

 

int a; 

IOWR(DUAL_PORT_RAM_0_BASE, 0, 0xAB); 

a = IORD(DUAL_PORT_RAM_0_BASE, 0); 

 

 

In debug mode, "int a" is always 0.  

 

 

I must be missing something. Attached is my .v and .tcl files. 

 

 

PS, I also tried adding a new on-chip ram component with only single port to see if I could just write to it. But during NIOS initialization through JTAG, the processor paused with an error. I am not sure why.
0 Kudos
Highlighted
Honored Contributor I
43 Views

The read latency of the slave port that you connected to the CPU is wrong in the .tcl file: 

 

"set_interface_property avalon_slave_0 readLatency 0" 

 

Based on the verilog parameterization of the memory you should set that read latency to 1. There is a input register stage inside the RAM block and the output is not registered so it so the total read latency is 1 for this setup. 

 

By the way if you used Qsys you wouldn't need to do all this stuff to expose one of slave ports of the memory to the top level, you would just click on the 2nd slave port and tell Qsys to export it.
0 Kudos
Highlighted
Honored Contributor I
43 Views

Thanks for your quick reply. I changed the read latency to 1 but it did not help. In my example, "int a" is still 0. Please see attachment to verify.

0 Kudos
Highlighted
Honored Contributor I
43 Views

Ahhhh I see the problem. In the verilog file the first clock enable is not getting hooked up (clock enable isn't part of the Avalon specification). Quartus II grounds disconnected inputs so the memory port had it's clock enable stuck low. The simple fix would be change this line (it's the comment line because that's what actually gets synthesized): 

 

// .clocken0 (clken), 

 

to  

 

// .clocken0 (1'b1), 

 

Since you generated this verilog from SOPC Builder I'm not sure what it did with that clock enable. I have been using SOPC Builder since it was first released and I don't remember clock enable being part of the Avalon-MM specification so there must have been an extra layer of extraction involved. Also it probably would be cleaner to just write verilog by hand than use machine generated code. Signals like chip select and clock enable are not necessary signals so you could have left them out if you coded the file by hand.
0 Kudos
Highlighted
Honored Contributor I
43 Views

Thank you so much. It all works now; I never would have thought that "the commented clk_en" to be the issue. You have made my day. Thanks!

0 Kudos
Highlighted
Honored Contributor I
43 Views

You are welcome. Also as a heads up I discourage people from using the synthesis translate on/off attributes in verilog/VHDL. That is what causes the comment lines from being used as the synthesis source, so I don't recommend doing that because it's confusing. When you write your HDL if you want to have seperate synthesis and simulation code I would split those out into two file sets instead, this is much cleaner in Qsys as well.

0 Kudos
Highlighted
Honored Contributor I
43 Views

The nios tightly coupled data interface does use the clock enable signal (to hold the read data from the previous address when the cycle before that stalls the cpu on an avalon tranfser). 

So there is some lurking support for it in sopc/qsys. 

Using the clock enable also stops sopc from selecting single clock mode, whereupon it silently ignores the OLDDATA flag. 

(In single clock mode 'clock enable' is replaced with the inverted 'address hold'). 

 

The fact that the commented out lines of all the sopc generated files are the ones that are used is somewhat confusing - caused us much confusion.
0 Kudos
Highlighted
Honored Contributor I
43 Views

 

--- Quote Start ---  

 

The fact that the commented out lines of all the sopc generated files are the ones that are used is somewhat confusing - caused us much confusion. 

--- Quote End ---  

 

 

Thanks for the heads up. I have not tried qsys yet. But for future reference, do all qsys generated files use commented out lines as well?
0 Kudos
Highlighted
Honored Contributor I
43 Views

Altera is moving away from that so I wouldn't expect many or any Qsys components to use the synthesis translate on/off functionality. Qsys generates synthesis and simualtion files into seperate directories which is a much cleaner approach.

0 Kudos