Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16604 Discussions

switching Bidirectional I/Os in FPGA

Altera_Forum
Honored Contributor II
1,608 Views

Hi, 

 

My project requires switching of SDRAM control and data signals between two DSP processors. Well, both the processors have their own SDRAM controller and signals. The Cyclone II FPGA is used to switch the SDRAM between the two processors. Under default conditions, processor1 will have control of the SDRAM. Under certain conditions, processor two will take control. Its more like shared memory between 2 processors. I've managed to switch the address and control lines of the SDRAM between the two processors, but the data bus poses a problem. Since it is a bidirectional bus (I/O), just a simple multiplexing logic does not suffice. The simulation results show that the data from the processors is not getting routed. The output is always unknown X. This is with the simple multiplex logic using a control signal.  

 

I need to connect the data bus between the two processors so that data can flow in both ways...input and output. Could any one give me some ideas for this?
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
567 Views

Yes, you need to drive the output enable for the bidir pins properly. This requires an SDRAM controller (more or less) to be present in the FPGA. 

 

Rather than relying on the SDRAM controllers in the DSPs, you would make things much easier by using a simpler memory interface, like asynchronous SRAM to transfer data to/from FPGA - and implement a state machine + SDRAM controller in the FPGA.
0 Kudos
Altera_Forum
Honored Contributor II
567 Views

Thanks for the reply. Well, I've thought of that solution too.. SDRAM controller in FPGA. But am tryin to use less resources and improve the timings with existing setup. So am really looking at just switching the SDRAM signals between the processors. I've also tried a bidirectional switching of the data bus based on the CS# and WE# signals, but still the simulations dont show up correctly. 

 

Moreover, the SDRAM controllers available from Altera and others have their own local side which does not match the processors local side which i use. I even tried modifying the SDRAM controller but not working out though! 

 

If you got any SDR SDRAM core with a simple local side interface (Addr, Data, RD/Wr#, CS#, OE#) please share them. Else if you've got a design doc on SDR SDRAM controller that would suffice too. I searched the web for SDRAM controller documentation, but didnt get any good one which details the exact state machine.
0 Kudos
Altera_Forum
Honored Contributor II
567 Views

Altera has an old reference design which can be modified to use a custom interface, here (http://www.altera.com/support/refdesigns/sys-sol/computing/ref-sdr-sram.html). 

 

If you want to read more about SDRAM, just download a datasheet from a manufacturer, like micron (pdf) (http://download.micron.com/pdf/datasheets/dram/sdram/256msdram.pdf). Googling for "sdram state machine" returns some links with state diagrams, also. 

 

Probably you will have to write your own glue logic to hook onto your DSP memory interface, which might not be exactly trivial if you intend to use the SDRAM as a boot memory. 

 

You say the simulation returns wrong results, and the output are undefined. Can you give some details about your simulation setup, testbench and stimulus?
0 Kudos
Altera_Forum
Honored Contributor II
567 Views

Thanks. I've already checked out the Ref design at Altera. But thats got a custom interface with respect to the command bus. The controller gets its commands from the external processor and only decodes these commands into the SDRAM commands.  

 

Now, if I have to use this in my design, I need to write the state machine for the commands b'coz the DSP processors dont have that command bus. I need to write the state machine for the Read/Write transactions based on the WR# and RD# signals from the processor. That's ok, but what bout the Burst transfers. How will the controller know if the transaction is burst read or burst write and issue the necessary commands? 

 

I've also checked out the state machines that Google returns in the web search, but these state that they are the simplified ones. Anyways, returning the switching problem, in the code I've written a bidirectional buffer for the SDRAM data bus. This buffer is controlled by the chipselect and WE# signals to determine the data direction for a read or write. 

 

In the testbench, I've driven the necessary SDRAM signals from the processor side and am switching these to the FPGA output that goes to the SDRAM chips. All the other control signals and address (RAS,CAS,CKE,etc) come out correctly. That is, they are switched from one of the processors selected and routed to the SDRAM chip. But the Data bus is always at an high-impedance 'Z' value. I've made sure that the test bench drives the waveforms correctly, the CS# and WE#. But still no go!
0 Kudos
Altera_Forum
Honored Contributor II
567 Views

I still think you have a problem with the simulation. So is the simulated data bus undefined, or high-z? 

 

You did not say which tool you use for simulation. Do you have a correct model for the Cyclone II output buffer? If you see no change in data output when you switch OE on and off, something is wrong with the model or the stimulus... 

 

About burst accesses, no Altera controller that I know of uses burst access for SDR SDRAM.
0 Kudos
Altera_Forum
Honored Contributor II
567 Views

Well, I've used ModelSim and also the built-in simulator in Quartus II. Both show the same results, a high-Z value in the bidirectional data bus. What I'm trying to do is to switch the data bus from one processor to the other and also control the data flow on the data bus for the read and write transactions. Here's the code snippet" 

 

assign fpga_sdram_d = (sdram_cs_n == 1'b0 && bf_swe_n == 1'b0) ? bf_data : {32{1'bz}}; assign bf_read_data = (sdram_cs_n == 1'b0 && bf_swe_n == 1'b1) ? fpga_sdram_d : {32{1'bz}}; assign fpga_sdram_d = (sdram_cs_n == 1'b1 && ts_sdwe_n == 1'b0) ? ts_data : {32{1'bz}}; assign ts_read_data = (sdram_cs_n == 1'b1 && ts_sdwe_n == 1'b1) ? fpga_sdram_d : {32{1'bz}}; assign bf_data = bf_read_data; assign ts_data = ts_read_data;  

 

Legends: 

 

fpga_sdram_d - data bus (i/O) from FPGA to SDRAM (inout) 

ts_data - Data bus from TS201 DSP to FPGA (inout) 

bf_data - Data bus from BF561 to FPGA (inout) 

 

ts_read_data - internal data signals for TS201 

bf_read_data - internal data bus for BF561 

 

As you can see, I'm trying to control the data bus direction for Read/Write based on the WE# and CS# signals. This is a simple code and should work. But in the simulations, always show the data bus (fpga_sdram_d) as High-Z.
0 Kudos
Altera_Forum
Honored Contributor II
567 Views

You cannot have two net assignments to the same signal (fpga_sdram_d), try combining them into a single assign statement. Check your Quartus warning messages. Maybe combine all assigns into a combinatorial 'case' statement?

0 Kudos
Reply