Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

why can't I write in the memory?

Status
Not open for further replies.

hamidkavianathar

Member level 5
Joined
Mar 6, 2016
Messages
89
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
804
why can't I write into the memory?

hi guys
I want to write something into a memory. I using Kintex7 FPGA and vivado. I'm writing into memory according to this figure.
Capture.PNG


but the app_wdf_rdy is always low. could you tell me, what should I do?



here is my source code:

Code:
`timescale 1ns / 1ps
//`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 09/25/2016 09:56:26 AM
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module top(
    input wire clk_50,
    output led1,
    output led2,
    output led3,
    output led4,
    output led5,
    
    // Memory interface ports
    output [15:0] ddr3_addr,  // output [15:0]        ddr3_addr
    output [2:0] ddr3_ba,  // output [2:0]        ddr3_ba
    output  ddr3_cas_n,  // output            ddr3_cas_n
    output [0:0] ddr3_ck_n,  // output [0:0]        ddr3_ck_n
    output [0:0] ddr3_ck_p,  // output [0:0]        ddr3_ck_p
    output [0:0] ddr3_cke,  // output [0:0]        ddr3_cke
    output ddr3_ras_n,  // output            ddr3_ras_n
    output ddr3_reset_n,  // output            ddr3_reset_n
    output ddr3_we_n,  // output            ddr3_we_n
    inout [31:0] ddr3_dq,  // inout [63:0]        ddr3_dq
    inout [3:0] ddr3_dqs_n,  // inout [7:0]        ddr3_dqs_n
    inout [3:0] ddr3_dqs_p,  // inout [7:0]        ddr3_dqs_p
    //output init_calib_complete,  // output            init_calib_complete
      
    output [0:0] ddr3_cs_n,  // output [0:0]        ddr3_cs_n
    output [3:0] ddr3_dm,  // output [7:0]        ddr3_dm
    output [0:0] ddr3_odt  // output [0:0]        ddr3_odt

    );

parameter state_0 = 0;
parameter state_read = 1;
parameter state_write = 2;
//parameter state_read_r = 3;
//parameter state_write_r = 4;
//parameter state_compare = 5;

reg [1:0] current_state = state_0;
reg [1:0] next_state;
   
wire clk_100; 
wire clk_200; 

          
reg [29:0] app_addr;
reg [2:0] app_cmd;
reg app_en;
reg [511:0] app_wdf_data;
reg app_wdf_end;
reg app_wdf_wren;
wire [255:0] app_rd_data;
wire app_rd_data_end;
wire app_rd_data_valid;
wire app_rdy;
reg app_zq_req;
reg app_sr_req;
reg app_ref_req;
wire app_sr_active;
wire app_ref_ack;
wire app_zq_ack;
reg [63:0] app_wdf_mask;
reg reset;
wire [31:0] count;          
wire init_calib;
reg enable;
reg app_wdf_end;
  clk_wiz_0 instance_name
     (
     // Clock in ports
      .clk_in1(clk_50),      // input clk_in1
      // Clock out ports
      .clk_out1(clk_100),     // output clk_out1
      .clk_out2(clk_200),     // output clk_out2
      // Status and control signals
      .reset(1'b0), // input reset
      .locked());      // output locked 
 
 
 counter counting(
              .clk(clk_100),
              .reset(reset),
              .count(count),
              .en(enable)
              );

        mig_7series_0 u_mig_7series_0 (
      
          // Memory interface ports
          .ddr3_addr                      (ddr3_addr),  // output [15:0]        ddr3_addr
          .ddr3_ba                        (ddr3_ba),  // output [2:0]        ddr3_ba
          .ddr3_cas_n                     (ddr3_cas_n),  // output            ddr3_cas_n
          .ddr3_ck_n                      (ddr3_ck_n),  // output [0:0]        ddr3_ck_n
          .ddr3_ck_p                      (ddr3_ck_p),  // output [0:0]        ddr3_ck_p
          .ddr3_cke                       (ddr3_cke),  // output [0:0]        ddr3_cke
          .ddr3_ras_n                     (ddr3_ras_n),  // output            ddr3_ras_n
          .ddr3_reset_n                   (ddr3_reset_n),  // output            ddr3_reset_n
          .ddr3_we_n                      (ddr3_we_n),  // output            ddr3_we_n
          .ddr3_dq                        (ddr3_dq),  // inout [63:0]        ddr3_dq
          .ddr3_dqs_n                     (ddr3_dqs_n),  // inout [7:0]        ddr3_dqs_n
          .ddr3_dqs_p                     (ddr3_dqs_p),  // inout [7:0]        ddr3_dqs_p
          .init_calib_complete            (init_calib_complete),  // output            init_calib_complete
            
          .ddr3_cs_n                      (ddr3_cs_n),  // output [0:0]        ddr3_cs_n
          .ddr3_dm                        (ddr3_dm),  // output [7:0]        ddr3_dm
          .ddr3_odt                       (ddr3_odt),  // output [0:0]        ddr3_odt

          // Application interface ports
          .app_addr                       (count[29:0]),  // input [29:0]        app_addr
          .app_cmd                        (app_cmd),  // input [2:0]        app_cmd
          .app_en                         (app_en),  // input                app_en
          .app_wdf_data                   (32'hAAAA0000),  // input [511:0]        app_wdf_data
          .app_wdf_end                    (app_wdf_end),  // input                app_wdf_end
          .app_wdf_wren                   (app_wdf_wren),  // input                app_wdf_wren
          .app_rd_data                    (app_rd_data),  // output [511:0]        app_rd_data
          .app_rd_data_end                (app_rd_data_end),  // output            app_rd_data_end
          .app_rd_data_valid              (app_rd_data_valid),  // output            app_rd_data_valid
          .app_rdy                        (app_rdy),  // output            app_rdy
          .app_wdf_rdy                    (app_wdf_rdy),  // output            app_wdf_rdy
          .app_sr_req                     (1'b0),  // input            app_sr_req
          .app_ref_req                    (app_ref_req),  // input            app_ref_req
          .app_zq_req                     (app_zq_req),  // input            app_zq_req
          .app_sr_active                  (),  // output            app_sr_active
          .app_ref_ack                    (app_ref_ack),  // output            app_ref_ack
          .app_zq_ack                     (app_zq_ack),  // output            app_zq_ack
          .ui_clk                         (ui_clk),  // output            ui_clk
          .ui_clk_sync_rst                (),  // output            ui_clk_sync_rst
          .app_wdf_mask                   (app_wdf_mask),  // input [63:0]        app_wdf_mask
          // System Clock Ports
          .sys_clk_i                       (clk_100),
          // Reference Clock Ports
          .clk_ref_i                      (clk_200),
          .sys_rst                        (1'b1) // input sys_rst
          );
   
assign led1 = app_rd_data_valid;
assign led2 = app_rdy;
assign led3 = app_wdf_rdy;
assign led4 = |app_rd_data;
assign led5 = app_rd_data_end;

always @ (posedge ui_clk)
    begin
        current_state <=  next_state;
    end
 
always @( current_state )
    begin
        case( current_state )
            state_0: begin
                        enable <= 1'b0;
                        app_en <= 1'b0;
                        reset <= 1'b1;
                        app_wdf_end <= 1'b0;
                        app_cmd <= 3'b000;
                        app_wdf_wren <= 1'b0;
                        app_zq_req <= 1'b0;
                        app_ref_req <= 1'b0;
                        app_wdf_mask <= 64'h0000000F;
                        if ( init_calib_complete == 1'b1)
                            next_state <= state_write;
                        else
                            next_state <= state_0;
                     end

            state_write: begin
                        //enable <= 1'b0;
                        app_en <= 1'b1;
                        //reset <= 1'b0;
                        app_cmd <= 3'b001;
                        app_wdf_wren <= 1'b1;
                        app_zq_req <= 1'b0;
                        app_ref_req <= 1'b0;
                        app_wdf_mask <= 64'h0000000F;
                        app_wdf_end <= 1'b0;
                        if( app_wdf_rdy == 1'b1 )
                            begin
                                enable <= 1'b1;
                                
                                if( count >= 32'h0000F00 )
                                    begin
                                        next_state <= state_read;
                                        reset <= 1'b1;
                                    end
                                else
                                    begin
                                        next_state <= state_write;
                                        reset <= 1'b0;
                                    end                             
                            end
                        else
                            begin
                                enable <= 1'b0;
                                next_state <= state_write;
                                reset <= 1'b0;
                            end       
                     end


            state_read: begin
                        //enable <= 1'b0;
                        app_en <= 1'b1;
                        app_wdf_end <= 1'b0;
                        //reset <= 1'b0;
                        app_cmd <= 3'b000;
                        app_wdf_wren <= 1'b0;
                        app_zq_req <= 1'b0;
                        app_ref_req <= 1'b0;
                        app_wdf_mask <= 64'h0000000F;
                        app_wdf_end <= 1'b0;
                        if( app_rdy == 1'b1 )
                            begin
                                enable <= 1'b1;
                                
                                if( count >= 32'h0000F00 )
                                    begin
                                        next_state <= state_0;
                                        reset <= 1'b1;
                                    end
                                else
                                    begin
                                        next_state <= state_read;
                                        reset <= 1'b0;
                                    end                             
                            end
                        else
                            begin
                                enable <= 1'b0;
                                next_state <= state_read;
                                reset <= 1'b0;
                            end       
                     end
        endcase
    end
    
 
 

endmodule

- - - Updated - - -

when I assert the app_wdf_end, the app_wdf_rdy gets stuck low, and when I deassert the app_wdf_end signal, it goes high. I just want to write a 32 bits and read it, so I think that I must assert the app_wdf_end signal. I read something in this page:
http://www.xilinx.com/support/answers/37023.html
but it is virtex 6.

thanks.
 
Last edited:

Hi,
I am assuming you are using the Xilinx MIG core.
As to why the app_wdf_rdy gets stuck at LOW is difficult to say from this piece of code. It is a MIG Application Interface signal and in the state-m/c above, you have just shown the use of the signal.
Check you MIG block if it is confirmed that app_wdf_rdy is *never* driven HIGH.

Something I found strange for the "state_write".
Code:
            state_write: begin
                        //enable <= 1'b0;
                        app_en <= 1'b1;
                        //reset <= 1'b0;
                        app_cmd <= 3'b001;
                        app_wdf_wren <= 1'b1;
                        app_zq_req <= 1'b0;
                        app_ref_req <= 1'b0;
                        app_wdf_mask <= 64'h0000000F;
                        app_wdf_end <= 1'b0;
                        if( app_wdf_rdy == 1'b1 )
                            begin

Are you sure the app_cmd <= 3'b001; for WRITE? Please re-check.

I have used the MIG v2.4(rev1) and Table 1-18, Pg90, of ug586 says,
Read is 3'b001
Write is 3'b000

An excerpt from my Verilog code when I was doing a write.
Code:
	case (cur_state)
	
	// Wait for DDR3 ready
	  IDLE: begin 
	    app_addr_o = 28'b0;
		app_cmd_o  = CMD_R;
	    app_en_o   = 1'b0;
	  
        if (init_calib_done_i) begin
          if (app_rdy_i==1'b1 && app_wdf_rdy_i==1'b1) begin  // UI is ready to accept commands & write FIFO ready
			if (SM_stop>SM_STOP_VAL)  // checks the no. of desired SM iterations
		      nxt_state = IDLE; 
		    else 
		      nxt_state = WRITE_CMD_0;			  
		  end 
		  else 
		    nxt_state = IDLE; 
		end   
        else 
          nxt_state = IDLE;		
	  end 
  
	  WRITE_CMD_0: begin               
		app_cmd_o  = CMD_W;
		app_en_o   = 1'b1;
		app_addr_o = ADDRESS_0;    
		app_wdf_data_o = W_DATA_0;
		app_wdf_wren_o = 1'b1;
		app_wdf_end_o  = 1'b1;	
        if (app_rdy_i==1'b1 && app_wdf_rdy_i==1'b1) 		
		  nxt_state = WRITE_CMD_1;  // CMD accepted            
        else
          nxt_state = WRITE_CMD_0;  // CMD retry 
	  end
 
thanks for the reply.
you're right. the write command is 3'b000. I have made a mistake. first app_wdf_rdy is high but after writing 0x55 times it goes low and gets stuck.
excuse me, could you please share all of your code?
thank you.
 
Last edited:

Your FSM doesn't appear to be following the checks for app_rdy when you send a command according to the UG586 descriptions:

app_rdy
This output indicates to you whether the request currently being submitted to the UI is
accepted. If the UI does not assert this signal after app_en is asserted, the current request
must be retried. The app_rdy output is not asserted if:
° PHY/Memory initialization is not yet completed
° All the bank machines are occupied (can be viewed as the command buffer being
full)
- A read is requested and the read buffer is full
- A write is requested and no write buffer pointers are available
° A periodic read is being inserted

You only seem to check this signal in the read state and it should be checked when sending the write command too. The app_wdf_rdy seems to indicate your write data FIFO is full perhaps due to some command failing to be accepted.
 
excuse me, could you please share all of your code?

Although my SM synthesizes successfully, but I am not in a position to share it as it was written in haste just to verify random writes and writes. It might appear haphazard and/or confusing to a 2nd person.
Just follow the sequence of signals as per spec and I am sure you will be successful with the writes and reads. It isn't difficult.
 
thanks you for the reply.
yeah, you are right. I modified my code and it never goes low anymore. Now I have another problem. my write_data is always 32'hAAAA0000 but read_data is completely random. I have shown them is below image:
Capture.PNG
 

Difficult to say with such little waveform info.
e.g.- Memory address is not shown. Are you writing to and *then* reading back from the same location?
You have posted the ILA core screenshot.

Post the MIG application interface signals depicting writes and then reads. See, your state-machine is driving the MIG core, so that must be the 1st point of investigation. If the MIG interface signals are perfectly ok (i.e. conforms to the MIG spec waveforms) and still there are problems, then only go into the investigation for MIG core debug signals.

Xilinx also provides a pattern generator to be used with the UI . Have you tried that piece of code and studied the behavior?
 
Last edited:
all of memory signals are shown in this picture.
img2.PNG

I have connected the address port to a counter.
thank you very much.
 

Next time when someone asks you do post something do everything they ask for or have a better answer than "I have connected the address port to a counter". Are you incrementing the address by 8? Or did you set the lower 3-bits of the app_addr to 0?

The app_addr is in bytes not in the app_wdf_data/app_rd_data words. This is why you should show all the signals requested as we can only guess how you are addressing things. Based on your first post you are masking (app_wdf_mask <= 64'h0000000F;) the lower 4-bytes of app_wdf_data so I'd have to think about what the end result may be with both of these happening (maybe what you are seeing?).

Also how did you perform the writes, give details, e.g.: address, data, the entire process of doing the writes before you started reading.
 
@hamidkavianathar:
DDR3 is a burst-length 8 protocol. For the write side, 8*DQ bits of data must be written the the RAM. Unused bytes are masked off with the DM lines. For the read side, 8*DQ bits of data must be read from the RAM. Unused bytes are ignored by your logic. DDR3 also has a "burst-chop 4" mode, where data is transmitted in burst of 4*DQ bits at a time. However, BC4 does this by inserting idles in between accesses -- bandwidth is approximately halved. (IIRC, the turn-around time between read/write can be improved.) The column address 3 lsb's tend to always be 000 for practical designs as a result. In fact, using non-000 for the three lsb might not be correctly implemented in some memory controllers. For the physical device, you can end up having something read the data out (18, 19, 20, 21, 22, 23, 16, 17) or something else odd.

@ads-ee:
I don't think MIG does addressing in bytes. Perhaps some of the controllers/interfaces did -- mig has changed over the years.
 
This is specifically why in #7 I asked the OP -
Xilinx also provides a pattern generator to be used with the UI . Have you tried that piece of code and studied the behavior?

There was no reply to that question so I assumed the OP has understood the how data and addressing needs to be done by a pattern generator for the MIG DDR3. If someone understands how the MIG DDR3 user interface example_design provided by Xilinx works, then it is not difficult to write a simple pattern gen.

----------------------------------------------------------------------

I have connected the address port to a counter.
thank you very much.
You SS still doesn't give all the signals. I think you misunderstood. I asked you for all the signals which drive the MIG controller core.
 
Last edited:
@ads-ee:
I don't think MIG does addressing in bytes. Perhaps some of the controllers/interfaces did -- mig has changed over the years.

Just ran an old DDR3 simulation of a 4:1 64-bit and it looks like the memory array is written sequentially when supplied with a 512-bit app_wdf_data and an app_addr of 0, 8, 16, 24, 32,...

So the app_addr looks to be in 64-bit words. I find it annoying the documentation doesn't indicate that.
 
Next time when someone asks you do post something do everything they ask for or have a better answer than "I have connected the address port to a counter". Are you incrementing the address by 8? Or did you set the lower 3-bits of the app_addr to 0?

The app_addr is in bytes not in the app_wdf_data/app_rd_data words. This is why you should show all the signals requested as we can only guess how you are addressing things. Based on your first post you are masking (app_wdf_mask <= 64'h0000000F;) the lower 4-bytes of app_wdf_data so I'd have to think about what the end result may be with both of these happening (maybe what you are seeing?).

Also how did you perform the writes, give details, e.g.: address, data, the entire process of doing the writes before you started reading.

I apologize for my late answer. I'm incrementing the address by 4. my write data is a constant word (256'h00AAAA0000). here is all of my code:
Code:
`timescale 1ns / 1ps
//`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 09/25/2016 09:56:26 AM
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module top(
    input wire clk_50,
    output app_rd_data_valid_o,
    output app_rdy_o,
    output app_wdf_rdy_o,
    output app_rd_data_or,
    output app_rd_data_end_o,
   
    // Memory interface ports
    output [15:0] ddr3_addr,  // output [15:0]        ddr3_addr
    output [2:0] ddr3_ba,  // output [2:0]        ddr3_ba
    output  ddr3_cas_n,  // output            ddr3_cas_n
    output [0:0] ddr3_ck_n,  // output [0:0]        ddr3_ck_n
    output [0:0] ddr3_ck_p,  // output [0:0]        ddr3_ck_p
    output [0:0] ddr3_cke,  // output [0:0]        ddr3_cke
    output ddr3_ras_n,  // output            ddr3_ras_n
    output ddr3_reset_n,  // output            ddr3_reset_n
    output ddr3_we_n,  // output            ddr3_we_n
    inout [31:0] ddr3_dq,  // inout [63:0]        ddr3_dq
    inout [3:0] ddr3_dqs_n,  // inout [7:0]        ddr3_dqs_n
    inout [3:0] ddr3_dqs_p,  // inout [7:0]        ddr3_dqs_p
    //output init_calib_complete,  // output            init_calib_complete
      
    output [0:0] ddr3_cs_n,  // output [0:0]        ddr3_cs_n
    output [3:0] ddr3_dm,  // output [7:0]        ddr3_dm
    output [0:0] ddr3_odt  // output [0:0]        ddr3_odt

    );

parameter state_0 = 0;
parameter state_read = 1;
parameter state_write = 2;
parameter enddd = 3;


reg [1:0] current_state = state_0;
reg [1:0] next_state;
   
wire clk_100; 
wire clk_200; 

          
reg [29:0] app_addr;
reg [2:0] app_cmd;
reg app_en;
reg [511:0] app_wdf_data;
reg app_wdf_end;
reg app_wdf_wren;
wire [255:0] app_rd_data;
wire app_rd_data_end;
wire app_rd_data_valid;
wire app_rdy;
reg app_zq_req;
reg app_sr_req;
reg app_ref_req;
wire app_sr_active;
wire app_ref_ack;
wire app_zq_ack;
reg [31:0] app_wdf_mask;
reg reset;
wire [31:0] count;          
wire init_calib;
reg enable;


wire [119:0] ddr3_ila_basic;          
wire [390:0] ddr3_ila_wrpath;          
wire [1023:0] ddr3_ila_rdpath;          
wire [5:0] dbg_pi_counter_read_val;          
wire [8:0] dbg_po_counter_read_val;   

wire [13:0] ddr3_vio_sync_out;
wire dbg_sel_pi_incdec;
wire dbg_sel_po_incdec;
wire [2:0] dbg_byte_sel;

wire dbg_pi_f_inc;
wire dbg_pi_f_dec;
wire dbg_po_f_inc;
wire dbg_po_f_dec;
wire dbg_po_f_stg23_sel;


  clk_wiz_0 instance_name
     (
     // Clock in ports
      .clk_in1(clk_50),      // input clk_in1
      // Clock out ports
      .clk_out1(clk_100),     // output clk_out1
      .clk_out2(clk_200),     // output clk_out2
      // Status and control signals
      .reset(1'b0), // input reset
      .locked());      // output locked 
 
 
 counter counting(
              .clk(ui_clk),
              .reset(reset),
              .count(count),
              .en(enable)
              );

        mig_7series_0 u_mig_7series_0 (
      
          // Memory interface ports
          .ddr3_addr                      (ddr3_addr),  // output [15:0]        ddr3_addr
          .ddr3_ba                        (ddr3_ba),  // output [2:0]        ddr3_ba
          .ddr3_cas_n                     (ddr3_cas_n),  // output            ddr3_cas_n
          .ddr3_ck_n                      (ddr3_ck_n),  // output [0:0]        ddr3_ck_n
          .ddr3_ck_p                      (ddr3_ck_p),  // output [0:0]        ddr3_ck_p
          .ddr3_cke                       (ddr3_cke),  // output [0:0]        ddr3_cke
          .ddr3_ras_n                     (ddr3_ras_n),  // output            ddr3_ras_n
          .ddr3_reset_n                   (ddr3_reset_n),  // output            ddr3_reset_n
          .ddr3_we_n                      (ddr3_we_n),  // output            ddr3_we_n
          .ddr3_dq                        (ddr3_dq),  // inout [63:0]        ddr3_dq
          .ddr3_dqs_n                     (ddr3_dqs_n),  // inout [7:0]        ddr3_dqs_n
          .ddr3_dqs_p                     (ddr3_dqs_p),  // inout [7:0]        ddr3_dqs_p
          .init_calib_complete            (init_calib_complete),  // output            init_calib_complete
            
          .ddr3_cs_n                      (ddr3_cs_n),  // output [0:0]        ddr3_cs_n
          .ddr3_dm                        (ddr3_dm),  // output [7:0]        ddr3_dm
          .ddr3_odt                       (ddr3_odt),  // output [0:0]        ddr3_odt

          // Application interface ports
          .app_addr                       (count[29:0]),  // input [29:0]        app_addr
          .app_cmd                        (app_cmd),  // input [2:0]        app_cmd
          .app_en                         (app_en),  // input                app_en
          .app_wdf_data                   (256'h00AAAA0000),  // input [511:0]        app_wdf_data
          .app_wdf_end                    (app_wdf_end),  // input                app_wdf_end
          .app_wdf_wren                   (app_wdf_wren),  // input                app_wdf_wren
          .app_rd_data                    (app_rd_data),  // output [511:0]        app_rd_data
          .app_rd_data_end                (app_rd_data_end),  // output            app_rd_data_end
          .app_rd_data_valid              (app_rd_data_valid),  // output            app_rd_data_valid
          .app_rdy                        (app_rdy),  // output            app_rdy
          .app_wdf_rdy                    (app_wdf_rdy),  // output            app_wdf_rdy
          .app_sr_req                     (1'b0),  // input            app_sr_req
          .app_ref_req                    (app_ref_req),  // input            app_ref_req
          .app_zq_req                     (app_zq_req),  // input            app_zq_req
          .app_sr_active                  (),  // output            app_sr_active
          .app_ref_ack                    (app_ref_ack),  // output            app_ref_ack
          .app_zq_ack                     (app_zq_ack),  // output            app_zq_ack
          .ui_clk                         (ui_clk),  // output            ui_clk
          .ui_clk_sync_rst                (),  // output            ui_clk_sync_rst
          .app_wdf_mask                   (app_wdf_mask),  // input [63:0]        app_wdf_mask

          // System Clock Ports
          .sys_clk_i                       (clk_100),
          // Reference Clock Ports
          .clk_ref_i                      (clk_200),
          .sys_rst                        (1'b1) // input sys_rst
          );


vio_0 your_instance_name (
  .clk(ui_clk),                // input wire clk
  .probe_out1(begin_sig)  // output wire [0 : 0] probe_out1
);

wire reset1;
wire begin_sig;
   
assign app_rd_data_valid_o = app_rd_data_valid;
assign app_rdy_o = app_rdy;
assign app_wdf_rdy_o = app_wdf_rdy;
assign app_rd_data_or = |app_rd_data;
assign app_rd_data_end_o = app_rd_data_end;

always @ (posedge ui_clk)
    begin
        current_state <=  next_state;
    end
 
always @( current_state )
    begin
        case( current_state )
            state_0: begin
                        enable <= 1'b0;
                        app_en <= 1'b0;
                        reset <= 1'b1;
                        app_wdf_end <= 1'b0;
                        app_cmd <= 3'b000;
                        app_wdf_wren <= 1'b0;
                        app_zq_req <= 1'b0;
                        app_ref_req <= 1'b0;
                        app_wdf_mask <= 64'h0000000F;
                        if ( init_calib_complete == 1'b1 && begin_sig == 1'b1)
                            //next_state <= state_write;
                            next_state <= state_write;
                        else
                            next_state <= state_0;
                     end



            state_write: begin
                        
                        
                        app_zq_req <= 1'b0;
                        app_ref_req <= 1'b0;
                        
                        if( app_wdf_rdy == 1'b1 && app_rdy == 1'b1 )
                            begin
                                enable <= 1'b1;
                                app_en <= 1'b1;
                                //reset <= 1'b0;
                                app_cmd <= 3'b000;
                                app_wdf_wren <= 1'b1;

                                app_wdf_mask <= 64'h0000000F;
                                app_wdf_end <= 1'b1;
                                
                                if( count >= 32'h0000F00 )
                                    begin
                                        next_state <= state_read;
                                        reset <= 1'b1;
                                        enable <= 1'b1;
                                    end
                                else
                                    begin
                                        next_state <= state_write;
                                        reset <= 1'b0;
                                        enable <= 1'b1;
                                    end                             
                            end
                        else
                            begin
                                enable <= 1'b0;
                                app_en <= app_en;
                                
                                app_cmd <= app_cmd;
                                app_wdf_wren <= app_wdf_wren;
                                
                                next_state <= state_write;
                                reset <= 1'b0;
                                app_wdf_end <= 1'b0;
                            end       
                     end


            state_read: begin
                        //enable <= 1'b0;

                        app_zq_req <= 1'b0;
                        app_ref_req <= 1'b0;
                        if( app_rdy == 1'b1 )
                            begin
                                //reset <= 1'b0;
                                app_en <= 1'b1;
                                app_cmd <= 3'b001;
                                app_wdf_wren <= 1'b0;
                                app_wdf_mask <= 64'h0000000F;
                                app_wdf_end <= 1'b0;
                                enable <= 1'b1;
                                
                                if( count >= 32'h0000F00 )
                                    begin
                                        next_state <= state_0;
                                        reset <= 1'b1;
                                        enable <= 1'b1;
                                    end
                                else
                                    begin
                                        next_state <= state_read;
                                        reset <= 1'b0;
                                        enable <= 1'b1;
                                    end                             
                            end
                        else
                            begin
                                enable <= 1'b0;
                                next_state <= state_read;
                                reset <= 1'b0;
                                app_en <= 1'b0;
                            end       
                     end

        endcase
    end
endmodule

and the written code for the counter:

Code:
module counter(
    input clk,
    input en,
    input reset,
    output [31:0] count
    );
assign count = count_val;
reg [31:0] count_val = 32'h00FFFFFF;
always @(posedge clk)
    begin
        if(reset == 1'b1)
            count_val <= 32'h00000000;
        else if ( en == 1'b1 )
            count_val <= count_val + 32'h00000004;
        else
            count_val <= count_val;
    end
endmodule

thanks.

- - - Updated - - -

@hamidkavianathar:
DDR3 is a burst-length 8 protocol. For the write side, 8*DQ bits of data must be written the the RAM. Unused bytes are masked off with the DM lines. For the read side, 8*DQ bits of data must be read from the RAM. Unused bytes are ignored by your logic. DDR3 also has a "burst-chop 4" mode, where data is transmitted in burst of 4*DQ bits at a time. However, BC4 does this by inserting idles in between accesses -- bandwidth is approximately halved. (IIRC, the turn-around time between read/write can be improved.) The column address 3 lsb's tend to always be 000 for practical designs as a result. In fact, using non-000 for the three lsb might not be correctly implemented in some memory controllers. For the physical device, you can end up having something read the data out (18, 19, 20, 21, 22, 23, 16, 17) or something else odd.

thanks for the comment. I'm writing a constant number into the memory but I am reading totally different numbers. and the read is not similar to the written data (256'h00AAAA0000) . I have shown an snapshot of the signals in the below image:
Capture.PNG

- - - Updated - - -

This is specifically why in #7 I asked the OP -


There was no reply to that question so I assumed the OP has understood the how data and addressing needs to be done by a pattern generator for the MIG DDR3. If someone understands how the MIG DDR3 user interface example_design provided by Xilinx works, then it is not difficult to write a simple pattern gen.

I looked at traffic generator but it didn't make sense for me.
 

The code has multiple signals missing from the sensitivity list. This means a simulation could be misleading. You can use "always@(*)" IIRC.

The state machine doesn't define all outputs for all code paths. This will create latches, something that should be avoided. I'm not sure if it actually causes issues in this case though.

Normally, "=" is used vs "<=" for the non-clocked process. This is another simulation issue though.

This look like BL8, so the counter should increment by 8.
 
that is some poor verilog coding style for sure. the sensitivity list alone makes any result you are seeing meaningless.
 
Hi
I found the solution!
memory address was incorrect. @dpaul you were correct, the problem was with my addressing method. you helped me a lot. thank you very much.
Now I have another problem, I want to write into the memory and read from it constantly, but sometimes memory is not ready and therefore I can't do anything with it. do you have any idea?
If I use a queue, will it work?
thanks.

Capture.PNG
 

the memory won't always be ready in MIGs in the last 5 years. There are refreshes and calibration reads that interrupt normal accesses. Previous versions of MIG either did not have these, or had some amount of buffering to avoid this issue.

You can add additional buffering if you want. This is common. However, it does increase latency. As long as your application is not dependent on read latency, you should be ok.
 
memory address was incorrect. @dpaul you were correct, the problem was with my addressing method. you helped me a lot. thank you very much.
Welcome! :)

Now I have another problem, I want to write into the memory and read from it constantly, but sometimes memory is not ready and therefore I can't do anything with it. do you have any idea?
You are restricted by the response signals from the MIG core.
 
Now I have another problem.
sometimes when I read from memory, it returns invalid data, while the "app_rd_data_valid" is high! I have shown it in the below image:
Capture.PNG

I am sure when I am writing to that address the "app_wdf_rdy" and "app_rdy" are high.
thanks.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top