---
+ Post New Thread
Results 1 to 12 of 12
  1. #1
    Newbie level 4
    Points: 640, Level: 5

    Join Date
    Aug 2009
    Posts
    5
    Helped
    1 / 1
    Points
    640
    Level
    5

    SDRAM controller

    My boss gave me a job is to design a SDRAM controller.

    The SDRAM is produced by the Hitachi and the model is " hm5216165".
    I already design it according to the datasheet .
    However, I encountered a big problem.

    I can use the mode of "single write/single read",but when I ues the mode of "Burst write/Burst read" ,the problem will occure.

    The problem is that when I use "Burst write/Burst read" the address of SDRAM will not change.
    For examle,when I write 4 data("1","2","3","4") and read 4 data from SDRAM,but the result of read out data is ("1","1","1","1").

    I have only read the first data and read the same data.

    I checked many times but still could not find any problems.
    This problem has been confused me for a long time.

    Do not know if there is no one encountered this kind of problem.
    Hope someone can help me solve it. thx....

  2. #2
    Full Member level 1
    Points: 1,968, Level: 10

    Join Date
    Dec 2005
    Location
    Chennai, India
    Posts
    106
    Helped
    8 / 8
    Points
    1,968
    Level
    10

    Re: SDRAM controller

    Can u please post the code. and datasheet of the sdram



    •   Alt19th September 2009, 13:46

      advertising

        
       

  3. #3
    Newbie level 4
    Points: 640, Level: 5

    Join Date
    Aug 2009
    Posts
    5
    Helped
    1 / 1
    Points
    640
    Level
    5

    Re: SDRAM controller

    My SDRAM controller is set at 30 MHz and latency=1 clock.
    I use the verilog.

    ------------------------------------------------------------------------
    `timescale 1ns / 1ps
    //////////////////////////////////////////////////////////////////////////////////
    // Company:
    // Engineer:
    //
    // Create Date: 20:21:49 09/03/2009
    // Design Name:
    // Module Name: sd_ctrl
    // Project Name:
    // Target Devices:
    // Tool versions:
    // Description:
    //
    // Dependencies:
    //
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    //
    //////////////////////////////////////////////////////////////////////////////////
    module sd_ctrl(clk,rst,address,RAS,CAS,WE,CS,CKE,A,DQM,re ad,write,mode,host_data,ready,D,sdread_data);

    input clk,rst;
    //to sdram
    output RAS,CAS,WE,CS,CKE;
    output [11:0]A;
    output [1:0]DQM;

    //from host
    input read,write;
    input [2:0]mode;
    input [19:0]address;
    input [15:0]host_data;
    output ready;
    output [15:0]sdread_data;

    //inout
    inout [15:0]D;

    //element
    reg RAS,CAS,WE,CS,CKE;
    reg [11:0]A;
    reg [1:0]DQM;
    reg ready;
    wire [15:0]D;

    reg [13:0]counter;
    reg [19:0]autorefresh_counter;//auto refresh counter
    reg zero;


    reg [15:0]sdread_data;

    reg [11:0]addr_A;
    reg [9:0]mode_A;

    reg enrefresh,en_autorefresh_counter;
    reg do_write,down_write;
    reg en_write;
    reg en_read;
    reg row,col;

    reg [4:0]state;
    reg [4:0]next;

    //inout line
    assign D=en_write?host_data:16'hzzzz;

    //parameter
    parameter power_on=5'd0;
    parameter precharge_all=5'd1;
    parameter trp1=5'd2;
    parameter mrs=5'd3;
    parameter autorefresh1=5'd4;
    parameter autorefresh_nop1=5'd5;
    parameter autorefresh2=5'd6;
    parameter autorefresh_nop2=5'd7;
    parameter idle=5'd8;
    parameter active=5'd9;
    parameter trcd1=5'd10;
    parameter fsm_write1=5'd11;
    parameter fsm_write2=5'd12;
    parameter fsm_write3=5'd13;
    parameter fsm_write4=5'd14;
    parameter tdal1=5'd15;
    parameter tdal2=5'd16;
    parameter fsm_read=5'd17;
    parameter read_data1=5'd18;
    parameter read_data2=5'd19;
    parameter read_data3=5'd20;
    parameter read_data4=5'd21;
    parameter autoprecharge1=5'd22;
    parameter aautorefresh1=5'd23;
    parameter aautorefresh_nop1=5'd24;
    parameter aautorefresh2=5'd25;
    parameter aautorefresh_nop2=5'd26;


    always @ *//data & address form host to sdram controller
    begin
    addr_A[11]=address[19];// select bank
    case({row,col})
    2'b10:addr_A[10:0]=address[18:8];
    2'b01:addr_A[10:0]={3'b000,address[7:0]};
    default:addr_A[10:0]=11'd0;
    endcase
    end

    always @ *//mode
    begin
    case(mode)
    3'b000:mode_A=10'b1_00_001_0_000;//1
    3'b001:mode_A=10'b0_00_001_0_001;//2
    3'b010:mode_A=10'b0_00_001_0_010;//4
    3'b011:mode_A=10'b0_00_001_0_011;//8
    3'b100:mode_A=10'b0_00_001_0_111;//full page
    default:mode_A=10'b1_00_001_0_000;//1
    endcase
    end

    always @ (posedge clk)//do_write data control
    begin
    if(write)
    do_write<=1'b1;
    else if(down_write)
    do_write<=1'b0;
    end

    always @(posedge clk)// read data from sdram to sdramcrl
    begin
    if(en_read)
    sdread_data<=D;

    end

    always @(posedge clk)//counter
    begin
    if(zero)
    counter<=14'd0;
    else if(rst)
    counter<=14'd0;
    else
    counter<=counter+14'd1;
    end

    always @ (posedge clk)//autorefresh_counter
    begin
    if(en_autorefresh_counter)
    autorefresh_counter<=autorefresh_counter+20'd1;
    else
    autorefresh_counter<=20'd0;
    end

    always @ *//control autorefresh
    begin
    if(autorefresh_counter[19:0]==20'b11101010011001100000) //32ms do auto refresh
    enrefresh<=1'b1;
    else
    enrefresh<=1'b0;
    end

    always @ (posedge clk)//fsm
    begin
    if(rst)
    state <= power_on;
    else
    state <= next;
    end

    always@*//fsm
    begin
    //sdram device deselect
    CKE=1'b1;
    CS=1'b1;
    RAS=1'bx;
    CAS=1'bx;
    WE=1'bx;
    A[11]=1'bx;
    A[10]=1'bx;
    A[9:0]=addr_A[10:0];
    DQM=2'b00;
    //control line
    ready=1'b0;
    zero=1'b1;
    en_autorefresh_counter=1'b0;
    en_write=1'b0;
    down_write=1'b0;
    en_read=1'b0;
    row=1'b0;
    col=1'b0;
    case(state)
    power_on:
    begin
    DQM=2'b11;
    zero=1'b0;
    begin
    if(counter==14'd6000)//wait 200us
    next=precharge_all;
    else
    next=power_on;
    end
    end

    precharge_all:
    begin
    CKE=1'b1;
    CS=1'b0;
    RAS=1'b0;
    CAS=1'b1;
    WE=1'b0;
    A[11]=1'bx;
    A[10]=1'b1;
    A[9:0]=10'bxxxxx_xxxxx;
    DQM=2'b11;
    next=trp1;
    end

    trp1://min 30ns
    begin
    DQM=2'b11;
    next=autorefresh1;
    end


    autorefresh1:
    begin
    CKE=1'b1;
    CS=1'b0;
    RAS=1'b0;
    CAS=1'b0;
    WE=1'b1;
    A[11]=1'bx;
    A[10]=1'bx;
    A[9:0]=10'bxxxxx_xxxxx;
    DQM=2'b11;
    next=autorefresh_nop1;
    end

    autorefresh_nop1://trc min 90
    begin
    DQM=2'b11;
    zero=1'b0;
    begin
    if(counter==14'd2)
    next=autorefresh2;
    else
    next=autorefresh_nop1;
    end
    end

    autorefresh2:
    begin
    CKE=1'b1;
    CS=1'b0;
    RAS=1'b0;
    CAS=1'b0;
    WE=1'b1;
    A[11]=1'bx;
    A[10]=1'bx;
    A[9:0]=10'bxxxxx_xxxxx;
    DQM=2'b11;
    next=autorefresh_nop2;
    end

    autorefresh_nop2://trc min 90
    begin
    DQM=2'b11;
    zero=1'b0;
    begin
    if(counter==14'd2)
    next=mrs;
    else
    next=autorefresh_nop2;
    end
    end

    mrs:
    begin
    CKE=1'b1;
    CS=1'b0;
    RAS=1'b0;
    CAS=1'b0;
    WE=1'b0;
    A[11]=1'b0;
    A[10]=1'b0;
    A[9:0]=mode_A;
    DQM=2'b11;
    next=idle;
    end

    idle:
    begin
    CKE=1'b1;
    CS=1'b0;
    DQM=2'b00;
    en_autorefresh_counter=1'b1;
    ready=1'b1;
    case({enrefresh,read,write})
    3'b100:next=aautorefresh1;
    3'b101:next=aautorefresh1;
    3'b110:next=aautorefresh1;
    3'b111:next=aautorefresh1;

    3'b000:next=idle;
    3'b011:next=idle;
    3'b001:next=active;
    3'b010:next=active;
    default:next=idle;
    endcase
    end

    active://do row precharge
    begin
    CKE=1'b1;
    CS=1'b0;
    RAS=1'b0;
    CAS=1'b1;
    WE=1'b1;
    A[11]=addr_A[11];//active bank A
    A[10]=addr_A[10];
    A[9:0]=addr_A[9:0];
    DQM=2'b00;
    row=1'b1;
    next=trcd1;
    end

    trcd1://trcd min 30
    begin
    DQM=2'b00;
    begin
    if(do_write)
    next=fsm_write1;
    else
    next=fsm_read;
    end
    end

    fsm_write1://write cmd in & write data
    begin
    CKE=1'b1;
    CS=1'b0;
    RAS=1'b1;
    CAS=1'b0;
    WE=1'b0;
    A[11]=addr_A[11];//write in bank A
    A[10]=1'b1;
    A[9:0]=addr_A[9:0];
    DQM=2'b00;
    en_write=1'b1;
    down_write=1'b1;
    col=1'b1;
    next=fsm_write2;
    end

    fsm_write2://nop
    begin
    DQM=2'b00;
    en_write=1'b1;
    next=fsm_write3;
    end

    fsm_write3://nop
    begin
    DQM=2'b00;
    en_write=1'b1;
    next=fsm_write4;
    end

    fsm_write4://nop
    begin
    DQM=2'b00;
    en_write=1'b1;
    next=tdal1;
    end


    tdal1://twr
    begin
    DQM=2'b00;
    next=tdal2;
    end

    tdal2://trp
    begin
    DQM=2'b00;
    next=idle;
    end

    fsm_read://read cmd in
    begin
    CKE=1'b1;
    CS=1'b0;
    RAS=1'b1;
    CAS=1'b0;
    WE=1'b1;
    A[11]=addr_A[11];//read from bank A
    A[10]=1'b1;
    A[9:0]=addr_A[9:0];
    DQM=2'b00;
    en_read=1'b1;
    col=1'b1;
    next=read_data1;
    end

    read_data1://latency=1
    begin
    DQM=2'b00;
    en_read=1'b1;
    next=read_data2;
    end

    read_data2:
    begin
    DQM=2'b00;
    en_read=1'b1;
    next=read_data3;
    end

    read_data3:
    begin
    DQM=2'b00;
    en_read=1'b1;
    next=read_data4;
    end

    read_data4:
    begin
    DQM=2'b00;
    next=autoprecharge1;
    end

    autoprecharge1: //trp min is 30 , do autoprecharge
    begin
    DQM=2'b00;
    next=idle;
    end


    aautorefresh1:
    begin
    CKE=1'b1;
    CS=1'b0;
    RAS=1'b0;
    CAS=1'b0;
    WE=1'b1;
    A[11]=1'bx;
    A[10]=1'bx;
    A[9:0]=10'bxxxxx_xxxxx;
    DQM=2'b11;
    next=aautorefresh_nop1;
    end

    aautorefresh_nop1://trc min 90
    begin
    DQM=2'b11;
    zero=1'b0;
    begin
    if(counter==14'd2)
    next=aautorefresh2;
    else
    next=aautorefresh_nop1;
    end
    end

    aautorefresh2:
    begin
    CKE=1'b1;
    CS=1'b0;
    RAS=1'b0;
    CAS=1'b0;
    WE=1'b1;
    A[11]=1'bx;
    A[10]=1'bx;
    A[9:0]=10'bxxxxx_xxxxx;
    DQM=2'b11;
    next=aautorefresh_nop2;
    end

    aautorefresh_nop2://trc min 90
    begin
    DQM=2'b11;
    zero=1'b0;
    begin
    if(counter==14'd2)
    next=idle;
    else
    next=aautorefresh_nop2;
    end
    end

    endcase
    end

    endmodule

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

    Hope expert can provide advice to tell where I may be wrong.
    thx.....


    1 members found this post helpful.

    •   Alt20th September 2009, 06:54

      advertising

        
       

  4. #4
    Full Member level 5
    Points: 5,234, Level: 17
    leonqin's Avatar
    Join Date
    Nov 2001
    Location
    China
    Posts
    243
    Helped
    5 / 5
    Points
    5,234
    Level
    17

    SDRAM controller

    hi,T think you may try use the refdesign from altera。It is quite easyto understand and powerful



  5. #5
    Junior Member level 2
    Points: 1,106, Level: 7

    Join Date
    Jul 2009
    Location
    Philippines
    Posts
    21
    Helped
    6 / 6
    Points
    1,106
    Level
    7

    SDRAM controller

    it seems like you've kept your CAS always asserted thru the burst read and write... i'd suggest you de-assert cas after fsm_read and fsm_write1.



    •   Alt21st September 2009, 22:05

      advertising

        
       

  6. #6
    Full Member level 1
    Points: 1,968, Level: 10

    Join Date
    Dec 2005
    Location
    Chennai, India
    Posts
    106
    Helped
    8 / 8
    Points
    1,968
    Level
    10

    Re: SDRAM controller

    Try asserting and deasserting cas whenever it reads from the SDRAM. that should work.

    Added after 38 seconds:

    is the burst write working properly?



  7. #7
    Newbie level 4
    Points: 640, Level: 5

    Join Date
    Aug 2009
    Posts
    5
    Helped
    1 / 1
    Points
    640
    Level
    5

    Re: SDRAM controller

    Hi leonqin,
    thanks for your suggestion but my boss asked me use Xilinx.

    Hi mytechface,
    do you mean that CAS should be "low" when read and write?

    And the other time it should be "high"?

    Hi sudhirkv,
    so you mean that I shoude not use "CAS=1'bx"??
    I should give CAS=1'b1 or CAS=1'b0??

    sorry,I am sure that SDRAM controller sent four data to SDRAM properly,but i am not sure that if the SDRAM save data properly.



  8. #8
    Full Member level 1
    Points: 1,968, Level: 10

    Join Date
    Dec 2005
    Location
    Chennai, India
    Posts
    106
    Helped
    8 / 8
    Points
    1,968
    Level
    10

    Re: SDRAM controller

    Yes try with cas low when read or write. Before that please refer to the timing diagram of the attached document.

    This datasheet is applicable for all sdram's.

    Try address as data while checking for the sdram read and write.



  9. #9
    Newbie level 4
    Points: 640, Level: 5

    Join Date
    Aug 2009
    Posts
    5
    Helped
    1 / 1
    Points
    640
    Level
    5

    Re: vlsi mini projects based on fpga design using hdl verilo

    hi sudhirkv,

    I have done as you say and also seen the datasheet but the result is wrong.
    I still can not find why column address does not change.


    What are the reasons can cause this problem?

    thx.........



  10. #10
    Full Member level 1
    Points: 1,968, Level: 10

    Join Date
    Dec 2005
    Location
    Chennai, India
    Posts
    106
    Helped
    8 / 8
    Points
    1,968
    Level
    10

    Re: vlsi mini projects based on fpga design using hdl verilo

    I want to clarify one thing from you,

    what is the sdram u r using, if possible send me the data sheet of your sdram.

    most of the cases there is no need to change the verilog code since it is already optimized. you need to check what configurations u have given in the verilog coding like row address column address burst rate like that.

    How u r checking the CAS and R/W signal.

    Have you tried address as data to the sdram. what is the result u got

    Thanks

    Added after 1 hours 6 minutes:

    sorry i didnt see the attached document on your previous post.


    my suggestions

    try using non blocking statement in all the always blocks .

    other basic settings are ok. i cudnt see any issue on that. please check whether u r meeting the timing specified in the datasheet.

    this should work if all the timings are OK.



  11. #11
    Newbie level 4
    Points: 640, Level: 5

    Join Date
    Aug 2009
    Posts
    5
    Helped
    1 / 1
    Points
    640
    Level
    5

    Re: vlsi mini projects based on fpga design using hdl verilo

    Hi sudhirkv,

    I first want to be properly grateful to u.I know this should work if all the timings are OK.

    and I use modelsim and LA to find the error,but I cannot find any error.
    however, when I take it to another block of sdram for testing,it will be the normal operation.

    The original problem occurs because the sdram not me.
    Thank you for spending so much time to help me debug!

    very grateful to you!!!!!!!!!thx!!!!!



  12. #12
    Full Member level 1
    Points: 1,968, Level: 10

    Join Date
    Dec 2005
    Location
    Chennai, India
    Posts
    106
    Helped
    8 / 8
    Points
    1,968
    Level
    10

    Re: vlsi mini projects based on fpga design using hdl verilo

    So you got the output when u changed the sdram. is that so?.

    Great and all the best



+ Post New Thread
Please login