FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
6355 Discussions

How to implement DE0 SDRAM as 2-port RAM

Altera_Forum
Honored Contributor II
7,730 Views

I currently use the tiny bit of memory on the FPGA for a computer vision project but it's way too limited. I have a stand-alone SDRAM controller from Altera (partially pasted below) but I need one more layer above that which implements this controller as a 2-port RAM entity. It seems like overkill to use QSYS with NiosII though, plus I'm not very familiar with it. What's resource will help me implement this controller as a 2-port RAM entity in the simplest way possible? 

 

entity sdr_sdram is generic( ASIZE : integer := 23; DSIZE : integer := 32; ROWSIZE : integer := 12; COLSIZE : integer := 9; BANKSIZE : integer := 2; ROWSTART : integer := 9; COLSTART : integer := 0; BANKSTART : integer := 20 ); port( CLK : in std_logic; --System Clock RESET_N : in std_logic; --System Reset ADDR : in std_logic_vector(ASIZE - 1 downto 0); --Address for controller requests CMD : in std_logic_vector(2 downto 0); --Controller command CMDACK : out std_logic; --Controller command acknowledgement DATAIN : in std_logic_vector(DSIZE - 1 downto 0); --Data input DATAOUT : out std_logic_vector(DSIZE - 1 downto 0); --Data output DM : in std_logic_vector(DSIZE / 8 - 1 downto 0); --Data mask input SA : out std_logic_vector(11 downto 0); --SDRAM address output BA : out std_logic_vector(1 downto 0); --SDRAM bank address CS_N : out std_logic_vector(1 downto 0); --SDRAM Chip Selects CKE : out std_logic; --SDRAM clock enable RAS_N : out std_logic; --SDRAM Row address Strobe CAS_N : out std_logic; --SDRAM Column address Strobe WE_N : out std_logic; --SDRAM write enable DQ : inout std_logic_vector(DSIZE - 1 downto 0); --SDRAM data bus DQM : out std_logic_vector(DSIZE / 8 - 1 downto 0) --SDRAM data mask lines ); end sdr_sdram;  

 

I need a wrapper so that this SDRAM controller is implemented like this: 

 

Inst_frame_buffer : entity work.sdram_wrapper_frame_buffer PORT MAP( rdaddress => rdaddress, -- IN std_logic_vector(18 downto 0); rdclock => clk_vga, -- IN std_logic; q => rddata, -- OUT std_logic_vector(11 downto 0) wrclock => camera_pclk, -- IN std_logic; wraddress => wraddress, -- IN std_logic_vector(18 downto 0); data => wrdata, -- IN std_logic_vector(11 downto 0); wren => wren -- IN std_logic; );
0 Kudos
48 Replies
Altera_Forum
Honored Contributor II
1,398 Views

 

--- Quote Start ---  

 

What's resource will help me implement this controller as a 2-port RAM entity in the simplest way possible? 

 

--- Quote End ---  

 

The SDRAM interface has only one port, so you can only use it as 1-port RAM. 

 

What you are probably after is multiple-master access to the common resource. This is possible if the two devices (masters) access the SDRAM at a rate that is slower than the SDRAM interface maximum performance. Eg., two devices accessing 100MHz SDRAM at an effective data rate of say 10MHz would work fine. 

 

Multi-master arbitration of the SDRAM interface would be done automatically for you if you use Qsys. 

 

Here's an SDRAM example to get you started. 

 

http://www.alteraforum.com/forum/showthread.php?t=45927 

 

This does not use NIOS II. It uses the JTAG interface to allow your PC to access the SDRAM. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

I checked that out. I don't where to begin to modify it to be what I need it to be though. Ideally it would all be in VHDL, no JTAG, no TCL, and the SDRAM size is different for the DE0-nano vs my regular DE0 board. Can I hire someone to make a quick VHDL wrapper for the Altera SDRAM controller I have as a 1-Port RAM entity that has multiple-master access functionality? I don't mind doing it with Qsys either but I would need a tutorial that doesn't use a JTAG interface or NiosII. It seems odd that this is such a hard thing to find..

0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

 

--- Quote Start ---  

The SDRAM size is different for the DE0-nano vs my regular DE0 board. 

 

--- Quote End ---  

 

You can start Qsys and modify the SDRAM parameters. 

 

 

--- Quote Start ---  

 

Can I hire someone to make a quick VHDL wrapper for the Altera SDRAM controller I have as a 1-Port RAM entity that has multiple-master access functionality? 

 

--- Quote End ---  

 

Its not the SDRAM that provides the multiple master functionality, its the fabric created by Qsys. When you connect two masters to a slave, the fabric adds arbitration logic. 

 

 

--- Quote Start ---  

 

I don't mind doing it with Qsys either but I would need a tutorial that doesn't use a JTAG interface or NiosII. It seems odd that this is such a hard thing to find.. 

--- Quote End ---  

 

A Qsys system needs at least one master (otherwise there is no point in creating the system), and the two easiest ones to demonstrate in a tutorial are NIOS II or JTAG. 

 

What are you trying to do that is not supported by existing components. Perhaps if you could explain what you are trying to do, people on the forum can suggest options for you to look into. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

Sure. For right now, as a first step, I'm just receiving video from a board camera (ov7670), storing it in a 2-port ram that is being used as a frame buffer (but is using the extremely limited FPGA memory). At the same time the VGA entity is pulling the pixel data from that frame buffer when it needs it and displaying it on a monitor. That's it. Really simple but I need to use SDRAM. I can only store a 160x120 frame with this limited FPGA memory. I don't mind going through a QSYS tutorial to build what I need but it sure seems like I don't need NiosII nor do I need JTAG...

0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

 

--- Quote Start ---  

For right now, as a first step, I'm just receiving video from a board camera (ov7670), storing it in a 2-port ram that is being used as a frame buffer (but is using the extremely limited FPGA memory). At the same time the VGA entity is pulling the pixel data from that frame buffer when it needs it and displaying it on a monitor. That's it. Really simple but I need to use SDRAM. I can only store a 160x120 frame with this limited FPGA memory. I don't mind going through a QSYS tutorial to build what I need but it sure seems like I don't need NiosII nor do I need JTAG... 

--- Quote End ---  

 

 

Its quite possible that you don't need to use a processor, it really comes down to how much intelligence is built into your existing components. 

 

For example, how is "I'm just receiving video from a board camera" implemented? From the looks of the ov7670 data sheet, its a VGA interface. I haven't used VGA, but from the data sheet, it looks basically like a streaming data source. In Altera's world, it can probably be considered an Avalon-ST data source, or it can be manipulated to look like one. You could write that data to SDRAM via a DMA controller, or perhaps some of the Video IP blocks, I have never looked at them, but others on the list should have. 

 

Perhaps start a new topic asking how people deal with VGA data streams, and SDRAM buffering, since that is more specific to what you are really interested in. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

I guess, but the way I originally formed the question removes the need to know the details of the project. It keeps it simple. I just need to use SDRAM as if it was a simple 1-port ram. I already have the controller and the entities the controller instantiates which is written by Altera and designed for the SDRAM chip on the development boards, I just need help with the next layer which does the job of making the interface even simpler. It would just have something like clock, address, ready, write/read, and data. Do you see what I mean? It's hard to believe that using SDRAM as a simple RAM component isn't a very common thing people do regardless of the application. Is there either a QSYS tutorial just for making SDRAM into a simpler RAM component or an SDRAM controller wrapper that already exists, or that I can hire someone to write? This has got to be so easy for someone more experienced than myself..

0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

"simple" is relative. 

 

If your components were re-written to use standard Avalon-MM and Avalon-ST interfaces, then you could "simply" create a Qsys system. 

 

The SDRAM controller interface is that of an Avalon-MM slave. I'm sure you can create an instance all by itself, but that would not provide the dual-ported interface you want. 

 

You could create an Avalon-MM system with the SDRAM controller and two exported Avalon-MM master interfaces, so that Qsys will create the arbitration logic, and then you can interface to the two Avalon-MM master interfaces exported to the top-level. But if you have to interface to two Avalon-MM masters at the top-level, you may as well just create Avalon-MM master components for your existing code, and drop them into a Qsys system. 

 

Basically it comes down to how much time you want to waste "fighting" the tools. Altera and Xilinx have decided to use standardized bus interfaces (Avalon-MM, Avalon-ST, AXI4, AXI4-Lite, AXI4-Stream, etc) so that they can give their end-users system building tools like Qsys. If you have custom logic, then often its easier to modify the code to make it use a standard interface. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

ok. 1. Which direction should I go in, pure VHDL, or a QSYS-based system? In the really big picture I am porting over a fairly large computer vision application. This is going to get a lot bigger and more complicated than just storing a frame in ram and sending it back out again to a VGA monitor. That's nothing. Eventually motion detection will be implemented which will be followed by a lot of other layers of custom image processing logic on top of that. RAM and FLASH (or an SD CARD) will also have to be used. I also want to do the pixel comparisons in parallel of course, that being one of the main reasons for using an FPGA. 2. So knowing that, does sticking to a purely VHDL system seem totally ridiculous? 

3. Will NiosII have to be involved in a project like this? If so, why? 

4. I have read a little about Avalon-MM and Avalon-ST interfaces but is there a guide that you know of for modifying the code to make it use a standard interface?
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

 

--- Quote Start ---  

ok. 1. Which direction should I go in, pure VHDL, or a QSYS-based system? 

 

--- Quote End ---  

 

It depends on how interconnected your components are, and how reuseable your code is, and how much Altera IP you plan on using. 

 

Many systems can be separated into a "Control Plane" and a "Data Plane", where the "Data Plane" are your high-speed processing blocks (the reason you chose an FPGA), and the "Control Plane" is the part where you configure the data plane, eg., program packet sizes, monitor statistics, set coefficients (stuff that changes on a slower timescale). 

 

As soon as you try and use some Altera IP, there is a pretty good chance to have to use the Avalon-ST or Avalon-MM component interface. At that point you need to decide whether to make your custom components work within the Qsys environment, or whether they'll sit "outside" a Qsys design containing all the Altera IP. 

 

The Avalon-MM/ST interfaces are described in the Avalon Interface Standard and in the Verification IP Users Guide. 

 

If you were going to target both Altera and Xilinx devices, then you should look at the ARM AMBA AXI4 standard interfaces. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

Alright. It seems like QSYS is for projects where the developer wants to use a NiosII processor or JTAG interface. I want to focus on making the wrapper for the SDRAM controller. It is likely only an hour or less of work for someone more experienced than myself. What is the next step in getting assistance in developing this wrapper?

0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

 

--- Quote Start ---  

It seems like QSYS is for projects where the developer wants to use a NiosII processor or JTAG interface. 

 

--- Quote End ---  

 

No, Qsys is for projects where you want to connect Avalon-MM devices together without having to "think" about how all the glue logic is generated. 

 

 

--- Quote Start ---  

I want to focus on making the wrapper for the SDRAM controller. It is likely only an hour or less of work for someone more experienced than myself. What is the next step in getting assistance in developing this wrapper? 

--- Quote End ---  

 

 

Follow along, and lets see if we can get you an SDRAM wrapper ... 

 

1. Download the DE0-nano SDRAM example design 

 

http://www.alteraforum.com/forum/showthread.php?t=45927 

 

This gives us a starting point. Ignore the fact that the DE0 may have different SDRAM. 

 

2. Unzip it and build it per the readme.txt instructions, i.e., 

 

Quartus Tcl: 

tcl> cd {c:\temp\de0_nano_sdram} 

tcl> source scripts/synth.tcl 

 

The build procedure creates the qsys_system.qsys file and "Generates" the Qsys system files. 

 

WRAPPER GENERATION METHOD# 1 

 

3. Look at the generated source 

 

c:\temp\de0_nano_sdram\qsys_system\synthesis\submodules\qsys_system_sdram.v 

 

There's your wrapper code right there. Its got an Avalon-MM slave interface and the SDRAM interface. 

 

WRAPPER GENERATION METHOD# 2 

 

4. Delete the generated source, i.e., delete the folder 

 

c:\temp\de0_nano_sdram\qsys_system\synthesis 

 

5. Start Qsys, open qsys_system.qsys 

 

6. Delete the clock and JTAG master, leaving only the SDRAM component. 

 

7. "Export" all of the SDRAM ports, eg., sdram_clk, sdram_reset, sdram_slave, sdram_mem. 

 

8. Look at the HDL Example - its pretty much identical to the wrapper code (with port name changes) 

 

9. Try to "Generate" this new system and ... failure ... at least on 12.1sp1 as there is no clock defined, which the SDRAM generator must need. 

 

A slight variation on this is to export an Avalon-MM master from the Qsys system. Your external logic would then control that master interface. Why is this a better option? It allows you to let Qsys generate the SDRAM controller. 

 

Note that an SDRAM controller is not that difficult to write. Its only a state machine and logic. There are probably examples on the OpenCore web site. Its much harder to write a DDR SDRAM controller, so that is one case where you'd definitely want to re-use the Qsys generated DDR controller. In the case of an SDRAM controller, you might want to find a non-Qsys version (Altera used to have an example design, long before the days of Qsys). 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

I finally had time to get back to this.  

 

Method 1 is fine except that JTAG is still in there and the address size is only 13bit which seems way too short for 8Mb. Also the ram size hasn't been changed. The column and row values may also be wrong.  

 

1. For WRAPPER GENERATION METHOD# 2, why remove the clock? Why not leave the clock and SDRAM and just remove the JTAG component?
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

 

--- Quote Start ---  

 

Method 1 is fine except that JTAG is still in there 

 

--- Quote End ---  

 

No its not. Look at the file qsys_system_sdram.v, it is *ONLY* the SDRAM controller component. 

 

 

--- Quote Start ---  

 

and the address size is only 13bit which seems way too short for 8Mb. Also the ram size hasn't been changed. The column and row values may also be wrong.  

 

--- Quote End ---  

 

That would be the "Ignore the fact that the DE0 may have different SDRAM". If you edit the SDRAM controller parameters to match those on the DE0 and then "Generate" the system, the generated .v file will have the parameters you need. 

 

 

--- Quote Start ---  

 

1. For WRAPPER GENERATION METHOD# 2, why remove the clock? Why not leave the clock and SDRAM and just remove the JTAG component? 

 

--- Quote End ---  

 

Now you are starting to see the possibilities :) 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

Using QSYS, I corrected the SDRAM size to 8Mb by correcting hte row and column sizes, fixed the the clock frequency, removed JTAG, added a 100MHz clock generator, and exported it to VHDL. It looks like it will work but I'm still messing with it...

0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

 

--- Quote Start ---  

It looks like it will work but I'm still messing with it... 

--- Quote End ---  

 

I haven't tried this with the SDRAM controller, but with the DDR controller, you can have Qsys generate a testbench, and it will include an DDR SDRAM model. 

 

For DDR SDRAM, I get Qsys to generate a top-level testbench, and then use that as a template for my own testbench. The piece of code I am typically interested in, is the SDRAM model instance, i.e., the fake SDRAM that the SDRAM controller reads/writes to. I then go back to the Qsys system and add a BFM, or I'd connect to the Avalon-MM slave port you're going to export to your top-level design, and use that to generate Avalon-MM transactions. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

I'm having an issue where I want to use one of the FIFO, frame buffer, or 1-port ram IP cores but since I'm not using a NioII, I just have to export everything and end up with even more connections to map. I'm trying to get back to the same position I was in with the on-board FPGA memory where all I have map is a rd_clk, rd_addr, rd_data, wr_clk, wr_addr, and wr_data. (Of course the SDRAM pins will also be mapped to the device.) Is there a way to get what I described?

0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

Seems like I'm making progress.. I have a few questions about entity instance below: 

 

sdram_controller_wire: 

 

1. In the DE0 manual, the size of SDRAM_ADDR is 13bits, [12:0], but the wizard generates a 12 bit vector, [11:0]. Which one is right if the SDRAM size is 8Mb? 

 

2. Do you see anything wrong with the "sdram_controller_wire" block of signals? Like BA or DQM are backwards? 

 

 

sdram_controller_s1: 

 

3. Is chip select just used to enable sdram_controller_s1? 

 

4. What is byte enable for in this instance? 

 

5. Why isn't read_n and write_n one signal instead of two? Does that mean you can write and read at the same time? 

 

 

-- sdram controller sdram_controller : process(clk50, btn(2)) begin if btn(2) = '0' then sdram_controller_s1_address_s <= (others => '0'); elsif rising_edge(clk50) then if (wren = '0') then sdram_controller_s1_address_s <= wraddress; else sdram_controller_s1_address_s <= rdaddress; end if; end if; end process; SDRAM_BA_1 <= sdram_controller_wire_ba_s(1); SDRAM_BA_0 <= sdram_controller_wire_ba_s(0); SDRAM_UDQM <= sdram_controller_wire_dqm_s(1); SDRAM_LDQM <= sdram_controller_wire_dqm_s(0); SDRAM_ADDR <= '0' & sdram_controller_wire_addr_s(11 downto 0); Inst_sdram : entity work.SDRAM_QSYS port map( clk_100mhz_clk => sdram_clk_s, --: in std_logic := '0'; clk.clk reset_reset_n => btn(2), --: in std_logic := '0'; reset.reset_n sdram_controller_wire_addr => sdram_controller_wire_addr_s, --: out std_logic_vector(11 downto 0); sdram_controller_wire.addr sdram_controller_wire_ba => sdram_controller_wire_ba_s, --: out std_logic_vector(1 downto 0); .ba sdram_controller_wire_cas_n => SDRAM_CAS_N, --: out std_logic; .cas_n sdram_controller_wire_cke => SDRAM_CKE, --: out std_logic; .cke sdram_controller_wire_cs_n => SDRAM_CS_N, --: out std_logic; .cs_n sdram_controller_wire_dq => SDRAM_DQ, --: inout std_logic_vector(15 downto 0) := (others => '0'); .dq sdram_controller_wire_dqm => sdram_controller_wire_dqm_s, --: out std_logic_vector(1 downto 0); .dqm sdram_controller_wire_ras_n => SDRAM_RAS_N, --: out std_logic; .ras_n sdram_controller_wire_we_n => SDRAM_WE_N, --: out std_logic; .we_n sdram_controller_s1_address => sdram_controller_s1_address_s, --: in std_logic_vector(21 downto 0) := (others => '0'); sdram_controller_s1.address sdram_controller_s1_byteenable_n => "11", --: in std_logic_vector(1 downto 0) := (others => '0'); .byteenable_n sdram_controller_s1_chipselect => '1', --: in std_logic := '0'; .chipselect sdram_controller_s1_writedata => wrdata, --: in std_logic_vector(15 downto 0) := (others => '0'); .writedata sdram_controller_s1_read_n => wren, --: in std_logic := '0'; .read_n sdram_controller_s1_write_n => not wren, --: in std_logic := '0'; .write_n sdram_controller_s1_readdata => open, --: out std_logic_vector(15 downto 0); .readdata sdram_controller_s1_readdatavalid => open, --: out std_logic; .readdatavalid sdram_controller_s1_waitrequest => open --: out std_logic );
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

 

--- Quote Start ---  

 

1. In the DE0 manual, the size of SDRAM_ADDR is 13bits, [12:0], but the wizard generates a 12 bit vector, [11:0]. Which one is right if the SDRAM size is 8Mb? 

 

--- Quote End ---  

 

Check the data sheet for the SDRAM. Most board designers are conservative and include "extra" address bits to make the board suitable for loading several device sizes. 

 

 

--- Quote Start ---  

 

2. Do you see anything wrong with the "sdram_controller_wire" block of signals? Like BA or DQM are backwards? 

 

--- Quote End ---  

 

What do you mean by backwards? The port direction appears correct - the controller drives those signals. 

 

 

 

--- Quote Start ---  

 

sdram_controller_s1: 

3. Is chip select just used to enable sdram_controller_s1? 

4. What is byte enable for in this instance? 

5. Why isn't read_n and write_n one signal instead of two? Does that mean you can write and read at the same time? 

 

--- Quote End ---  

 

Create a simulation model and use that to answer these questions :) 

 

Its likely that chipselect and read_n need to assert for read, and chipselect and write_n need to assert for write. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

no idea what the two bit byte enable could be for?

0 Kudos
Altera_Forum
Honored Contributor II
1,354 Views

 

--- Quote Start ---  

no idea what the two bit byte enable could be for? 

--- Quote End ---  

 

The byte-enable controls allow you to write to a single byte. Eg., if you have a 16-bit Avalon-MM master, you can write 16-bits, write to the low 8-bits, or write to the high 8-bits. If you have a 32-bit Avalon-MM master, then you can write 32-bits, 16-bits low or high, or any of the four bytes. The byte enables allow you to indicate which bytes get written. The SDRAM controller then passes these though to assert the data mask signals (DQM ). 

 

Again, this is a question that you can answer yourself by creating a simulation of the design. 

 

HINT HINT: Create a simulation! :) 

 

Cheers, 

Dave
0 Kudos
Reply