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