Download Embedded Systems Trace Solutions
Transcript
10.4. FPGA Design 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 86 -- Read FIFO always loads from SDRAM rd_fifo_din <= DQ_input ; -- Write FIFO always outputs to SDRAM DQ_output <= wr_fifo_dout ; rd_fifo_rst <= not( CLK_locked and DCM_SDRAM_locked ); wr_fifo_rst <= not( CLK_locked and DCM_SDRAM_locked ); CKE <= CLK_locked and DCM_SDRAM_locked ; CS_n <= not( CLK_locked and DCM_SDRAM_locked ); -- address and counter visible outside out_address <= address ; out_counter <= counter ; -- complete visible outside busy <= int_busy ; int_busy <= ’0’ when counter = ’0’ & x" 00000 " and load_counter = ’0’ else ’1 ’; Listing 10.20 shows how the SDRAM data bus is implemented as a tri-state bus controlled by the DQ_output_enable signal. Because the only data written to the read FIFO comes from SDRAM its rd_fifo_din input is directly connected to the data coming from DQ_input, just like the write FIFO output is directly connected to DQ_output. Both FIFOs are held in reset until both clocks locked, because nothing could be done with accumulated data during that time anyway. The SDRAM clock enable (CKE) is high once both clocks locked, and the chip select will be driven low (active) at the same time. This is possible because the OpenOCD+trace design makes no use of the COMMAND INHIBIT or SELF REFRESH commands available when those two lines are deasserted. The last concurrent assignments in sdram_controller.vhd make the current address, counter value, and busy signal accessible outside of the sdram_controller entity. The SDRAM controller is in busy state whenever the counter is not zero (more data to transfer) or when the counter is currently being loaded. Figure 10.11 shows the state machine after initialization completed, when the controller is in IDLE state waiting for requests or AUTO REFRESH cycles. Listing 10.21: sdram_controller.vhd 391 392 393 394 395 396 397 when IDLE => RAS_n <= ’1 ’; CAS_n <= ’1 ’; WE_n <= ’1 ’; int_state <= IDLE ; -- refresh takes precedence if refresh_counter = 0 then