|
|
 |
FPGA design from scratch. Part 20
Running our first simulation
Our first testcase will be a simple one. We will start the system clock running at 100MHz. After a few clock cycles we will assert the system reset and watch what happens. Here is the testcase.
We are ready to start.
- Testcase FirstTest.tc selected
- Waveform generation enabled. Dump sst/wlf
- NCSIM used
- Compile/elaborate/simulate in one run selected

Here is the result.

The simulation stops after 110ns displaying the following error message: Input Error : RST on instance * must be asserted for 3 CLKIN clock cycles. It looks to me like the DCM is missing a reset signal. Here starts the debugging phase. Up to now it has been "klipp och klistra" (Swedish for cut and glue) work. Now starts the real engineering work. Let's open the Simvision waveform viewer by clicking the Simvision button in the terminal window, find the dcm_0 and dcm_1 in the design browser, select all signals and open the waveform viewer.


The dcm_1 block has no input clock. Let's dig into the problem. We will use the Simvision Schematic Tracer to help us find our way around in the design. Here is a view of the complete system.

Here is the dcm_1 block in full view.

Here is the explanation, the ddr_feedback clock is missing. We have to add one more clock generator in our testbench.
always begin #DDR_CLK_ClockStart DDR_CLK_FB = 1; #DDR_CLK_ClockWidth DDR_CLK_FB = 0; #(DDR_CLK_ClockPeriod-DDR_CLK_ClockStart-DDR_CLK_ClockWidth); end
We will also add the DDR SDRAM to our simulation model.
Adding the DDR SDRAM
If we take a look at the Xilinx evaluation board we find two Micron DDR SDRAM 46V16M16 organized as 16Mx32. To download a Verilog model of this SDRAM we will go the Micron web page.
Before we connect the DDR SDRAM to the ETC system we will study the SDRAM interface already implemented and try to understand how it works. Here is the Xilinx document describing the interface. This table shows all the external signals in the DDR SDRAM interface.
| Signal | Width | Dir
| Description | | DDR_SDRAM_Clk_pin | 1 | Out
| Clock | | DDR_SDRAM_Clkn_pin | 1 | Out
| Clock inverted
| | DDR_SDRAM_Addr_pin | 0 : 12 | Out
| Address bus
| | DDR_SDRAM_BankAddr_pin | 0 : 1 | Out
| Bank address
| | DDR_SDRAM_CASn_pin | 1 | Out
| Active low column address strobe | | DDR_SDRAM_CKE_pin | 1 | Out
| Clock enable
| | DDR_SDRAM_CSn | 1 | Out
| Active low chip select | | DDR_SDRAM_RASn | 1 | Out
| Active low row address strobe | | DDR_SDRAM_WEn_pin | 1 | Out
| Active low write enable | | DDR_SDRAM_DM_pin | 0 : 3 | Out
| Data mask | | DDR_SDRAM_DQS_pin | 0 : 3 | Inout
| Data strobe both read and write
| | DDR_SDRAM_DQ_pin | 0 : 31
| Inout
| Data bus in/out | Here is an example showing the connection of two 16 bit DDR SDRAMS to the OPB DDR SDRAM controller.
 (Courtesy of Xilinx) Memory organization
OPB DDR SDRAM memory can be accessed as byte (8 bits), halfword (2 bytes), word (4 bytes) or Double word (8 bytes) depending on the size of the bus to which the processor is attached. From the point of view of the OPB, data is organized as big-endian. The bit and byte labeling for the big-endian data types is shown below. To address 32 bit words the address must be incremented by 4 to read the next word. One more observation, the MSB is bit 0 and the LSB is bit 31, opposite to what you may be used to.

The DDR SDRAM Verilog model
Let's see if the Verilog model (ddr.v) matches the OPB interface. Here is the module declaration: module ddr (Dq, Dqs, Addr, Ba, Clk, Clk_n, Cke, Cs_n, Ras_n, Cas_n, We_n, Dm); It seems we a perfect match.
Compilation of the Verilog DDR SDRAM module
We will compile the ddr.v file together with the include file ddr_parameters.vh to the database directory $ETC_VERIFICATION/database/ncsim/userlib/sdram_v1_00_a. The default memory compiled will have 16 bits data width and speed grade sg75Z. Fine for us.
Instantiation of two memory modules
Here is the instantiation that has been added to the EXT_system_testbench.tb.
//$$INSTANTIATION OF EXTERNAL COMPONENTS /*************************************************************************/ /* */ /* E X T E R N A L C O M P O N E N T S */ /* */ /*************************************************************************/
ddr ddr_sdram_16_31 (
.Clk (DDR_SDRAM_Clk_pin), .Clk_n (DDR_SDRAM_Clkn_pin), .Cs_n (DDR_SDRAM_CSn_pin), .Cke (DDR_SDRAM_CKE_pin), .Ba (DDR_SDRAM_BankAddr_pin), .Addr (DDR_SDRAM_Addr_pin), .Ras_n (DDR_SDRAM_RASn_pin), .Cas_n (DDR_SDRAM_CASn_pin), .We_n (DDR_SDRAM_WEn_pin), .Dm (DDR_SDRAM_DM_pin[2:3]), .Dqs (DDR_SDRAM_DQS_pin[2:3]), .Dq (DDR_SDRAM_DQ_pin[16:31]) );
ddr ddr_sdram_0_15 (
.Clk (DDR_SDRAM_Clk_pin), .Clk_n (DDR_SDRAM_Clkn_pin), .Cs_n (DDR_SDRAM_CSn_pin), .Cke (DDR_SDRAM_CKE_pin), .Ba (DDR_SDRAM_BankAddr_pin), .Addr (DDR_SDRAM_Addr_pin), .Ras_n (DDR_SDRAM_RASn_pin), .Cas_n (DDR_SDRAM_CASn_pin), .We_n (DDR_SDRAM_WEn_pin), .Dm (DDR_SDRAM_DM_pin[0:1]), .Dqs (DDR_SDRAM_DQS_pin[0:1]), .Dq (DDR_SDRAM_DQ_pin[0:15]) );
When we rerun our simulation the signals to the memory looks like this. Looks good to me.

If we run the simulation a little bit longer we get the following message.
ETC_SYSTEM_TEST.ddr_sdram_0_15: at time 202273 ns MEMORY: Power Up and Initialization Sequence is complete At time 202373 ns LMR : Load Mode Register At time 202373 ns LMR : Burst Length = 2 At time 202373 ns LMR : CAS Latency = 2
After the power up sequence is complete the auto refresh starts.

Suppressing assert messages in IEEE packages
When we have an 'x" in our simulation the VHDL packages will print millions of assert messages telling you there is an 'x' in your simulation. To suppress these message we can use the following tcl commands to ncsim:
ncsim> set pack_assert_off ieee.NUMERIC_STD ncsim> set pack_assert_off ieee.STD_LOGIC_ARITH
We will add these commands to the TCL input file : $ETC_VERIFICATION/tcl/ncsim_tcl_input.def and they will be executed every time we run ncsim.

Top Next Previous
Posted at 03:38 pm by svenand
|