zoukankan      html  css  js  c++  java
  • SDRAM--Verilog及仿真(1)

    (1)初始化

    器件原理:

    SDRAM(Synchronous Dynamic Random Access Memory)同步动态随机存储器。

    SDRAM的存储方式可以看成是几张表格,其中每张表格如图所示,向SDRAM写入数据就是存放在当中的格子,通过行地址和列地址可以准备找到存储单元。

    SDRAM的总存储容量是:表格的张数 x 行地址数 x 列地址数 x 每个格子的容量。其中这里所使用的sdram型号的总存储容量是:4张 x 2M x 16bits

     所使用的sdram器件型号的结构:

    引脚介绍:

    sdram_clk

    SDRAM 芯片时钟

    上升沿

    sdram_cke

    SDRAM 时钟有效

    高电平有效

    sdram_cs_n

    SDRAM 片选

    低电平有效

    sdram_ras_n

    SDRAM 行有效

    低电平有效

    sdram_cas_n

    SDRAM 列有效

    低电平有效

    sdram_we_n

    SDRAM 写有效

    低电平有效

    [1:0]sdram_ba

    SDRAM Bank地址

    四张不同的表格:00、01、10、11

    [11:0]sdram_addr

    SDRAM 地址总线

     

    [15:0]sdram_data

    SDRAM 数据

    双向inout

    [1:0]sdram_dqm

    SDRAM 数据掩码

     

    bank+地址总线:

    从这个时序图可以知道,初始化用到的命令有NOP、PRE、REF、MSET。

    ①输入稳定期200μs

    ②所用L-Bank预充电

    ③8个刷新周期

    ④模式寄存器设置(MRS:Mode Register Set)

     其中A9、A6、A5、A4、A3、A2、A1、A0是根据这里的SDRAM设置的。

    操作模式A9:选择突发读/突发写方式,因此0。

    潜伏期A6、A5、A4:潜伏期是3,因此011。

    突发长度A3、A2、A1、A0:选择顺序突发方式,并且突发长度是4,因此0010。

    综上所述,地址总线已经确定是00000_011_0010。

    综合代码设计:

    sdram_init.v模块:

    module sdram_init(
    input sys_clk,
    input sys_rst_n,
    
    output reg [3:0]cmd,
    output [11:0]sdram_addr,
    output init_end_flag
    );
    
    localparam NOP=4'b0111;
    localparam PRE=4'b0010;
    localparam REF=4'b0001;
    localparam MSET=4'b0000;
    
    reg [13:0]cnt_200us;
    reg [3:0]cmd_cnt;
    
    always @(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
    cnt_200us<=14'd0;
    else if(cnt_200us < 14'd10000)
    cnt_200us<=cnt_200us+1'b1;
    end
    
    always @(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
    cmd_cnt<=4'd0;
    else if(cnt_200us == 14'd10000 && init_end_flag == 1'b0)
    cmd_cnt<=cmd_cnt+1'b1;
    end
    
    always @(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
    cmd<=NOP;
    else if(cnt_200us == 14'd10000)
    case(cmd_cnt)
    0:cmd<=PRE;
    1:cmd<=REF;
    5:cmd<=REF;
    9:cmd<=MSET;
    default:cmd<=NOP;
    endcase
    end
    
    assign init_end_flag=(cmd_cnt>=4'd10)?1'b1:1'b0;
    assign sdram_addr=(cmd == MSET)?12'b00000_011_0010:12'b0100_0000_0000;
    endmodule 

    top.v模块:

    module top(
    input sys_clk,
    input sys_rst_n,
    
    output sdram_clk,
    output sdram_cke,
    output sdram_cs_n,
    output sdram_ras_n,
    output sdram_cas_n,
    output sdram_we_n,
    output [1:0]sdram_ba,
    output [11:0]sdram_addr,
    output [1:0]sdram_dqm,
    output [15:0]sdram_data
    );
    wire [11:0]init_addr;
    wire init_end_flag;
    wire [3:0]init_cmd;
    
    assign {sdram_cs_n,sdram_ras_n,sdram_cas_n,sdram_we_n}=init_cmd;
    assign sdram_clk=~sys_clk;
    assign sdram_cke=1'b1;
    assign sdram_ba=2'b00;
    assign sdram_addr=init_addr;
    assign sdram_dqm=2'b00;
    
    sdram_init u_sdram_init(
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n),
    .cmd            (init_cmd),
    .sdram_addr     (init_addr),
    .init_end_flag  (init_end_flag)
    );
    endmodule 

    仿真代码设计:

    由于SDRAM器件复杂,所以借用了别人已经设计好的SDRAM模型sdram_model_plus.v,并且改动其中内容如下:

    激励文件sdram_init_tb.v:

    `timescale 1ns/1ns
    module sdram_init_tb;
    reg sys_clk;
    reg sys_rst_n;
    wire sdram_clk;
    wire sdram_cke;
    wire sdram_cs_n;
    wire sdram_ras_n;
    wire sdram_cas_n;
    wire sdram_we_n;
    wire [1:0]sdram_ba;
    wire [11:0]sdram_addr;
    wire [1:0]sdram_dqm;
    wire [15:0]sdram_data;
    
    top u_top(
    .sys_clk     (sys_clk),
    .sys_rst_n   (sys_rst_n),
    .sdram_clk   (sdram_clk),
    .sdram_cke   (sdram_cke),
    .sdram_cs_n  (sdram_cs_n),
    .sdram_ras_n (sdram_ras_n),
    .sdram_cas_n (sdram_cas_n),
    .sdram_we_n  (sdram_we_n),
    .sdram_ba    (sdram_ba),
    .sdram_addr  (sdram_addr),
    .sdram_dqm   (sdram_dqm),
    .sdram_data  (sdram_data)
    );
    
    sdram_model_plus u_model_plus(
    .Dq      (sdram_data),
    .Addr    (sdram_addr),
    .Ba      (sdram_ba),
    .Clk     (sdram_clk),
    .Cke     (sdram_cke),
    .Cs_n    (sdram_cs_n),
    .Ras_n   (sdram_ras_n),
    .Cas_n   (sdram_cas_n),
    .We_n    (sdram_we_n),
    .Dqm     (sdram_dqm),
    .Debug   (1'b1)
    );
    
    initial begin
    sys_clk=1;
    sys_rst_n=0;
    #30 sys_rst_n=1;
    end
    always #10 sys_clk=~sys_clk;
    
    endmodule 

    结果:Modelsim打印信息,表明sdram初始化的设计实现了。

    run 201us,之后Modelsim的打印信息:

    # at time 200050 ns PRE : Bank = ALL
    # at time 200070 ns AREF : Auto Refresh
    # at time 200150 ns AREF : Auto Refresh
    # at time 200230 ns LMR : Load Mode Register
    # CAS Latency = 3
    # Burst Length = 4
    # Burst Type = Sequential
    # Write Burst Mode = Programmed Burst Length

    观看波形:因为命令只有在sdram_init.v模块中,因此点击这个观看波形:

    tb文件中30ns之后,复位信号才拉高,因此等下一个上升沿就是200us+40ns了,此时稳定期200us过去,命令4'b0111跳转到命令4'b0010。

    assign sdram_addr=(cmd == MSET)?12'b00000_011_0010:12'b0100_0000_0000;

    命令和地址都符合设计。

  • 相关阅读:
    Tomcat基本使用
    XML、java解释XML、XML约束
    配置文件的读取
    jdbc操作数据库以及防止sql注入
    java中的枚举类
    maven阿里云中央仓库
    spring boot&&cloud干货系列
    数据库 锁机制
    MySql的优化步骤
    MYSQL 索引无效和索引有效的详细介绍
  • 原文地址:https://www.cnblogs.com/FPGAer/p/13997916.html
Copyright © 2011-2022 走看看