• SDR SDRAM读写控制器————读数据模块设计


     =================================================

     目录

      1、SDR SDRAM读写控制器————整体概述

      2、SDR SDRAM读写控制器————上电模块设计

      3、SDR SDRAM读写控制器————刷新模块设计  

      4、SDR SDRAM读写控制器————定时器模块设计

      5、SDR SDRAM读写控制器————写数据模块设计

      6、SDR SDRAM读写控制器————读数据模块设计

      7、SDR SDRAM读写控制器————主控制机模块设计

     =================================================

    读数据模块时序图:

    读数据模块状态转移图:

    读数据模块程序设计:

    `include "../rtl/head.v"
    
    //读状态机
    module rd_fsm(
                clk         ,//100MHz的时钟线 
                capture_clk ,//捕获时钟 理论上是180度相位
                soft_rst_n  ,//软复位 
                rd_en       ,//读数据使能
                rd_done     ,//完成读出数据操作标志
                row         ,//行地址
                col         ,//列地址
                ba          ,//Bank地址 
                rdata       ,//读出的数据
                rd_bus      ,//读数据模块的总线
                sdr_dq       //从SDR输出的数据
    );
    
    input  clk, capture_clk, soft_rst_n ;
    input  rd_en                        ;
    output reg rd_done                  ;
    input  [12:0] row                   ;
    input  [9:0]  col                   ;
    input  [1:0]  ba                    ;
    output wire [31:0] rdata             ;
    output [19:0] rd_bus                ;
    input  [15:0] sdr_dq                ;
    
    reg    [15:0] dq_cap                ;
    reg    [15:0] dq_syn                ;
    reg    load_l                       ;
    reg    load_h                       ;
    reg    [12:0] rd_a                  ;
    reg    [1:0]  rd_ba                 ;
    reg    [3:0]  rd_cmd                ;
    reg    rd_cke                       ;
    reg    [5:0]  cnt                   ;
    reg    [2:0]  state                 ;
    
    localparam s0 = 3'b000;
    localparam s1 = 3'b001;
    localparam s2 = 3'b011;
    localparam s3 = 3'b111;
    localparam s4 = 3'b110;
    
    /*================================================*/
    
    
    assign rd_bus = {rd_cmd, rd_a, rd_ba, rd_cke};//组装总线
    
    always @ (posedge clk)
    begin
        if (!soft_rst_n)//同步复位
            begin 
                rd_done <= 0    ;//管理输出端口
                rd_cmd  <= `NOP ;
                rd_a    <= 0    ;
                rd_ba   <= 0    ;
                rd_cke  <= 1    ;
                load_l  <= 0    ;
                load_h  <= 0    ;
                cnt     <= 0    ;
                state   <= s0   ;
            end
        else
            case (state)
                s0: if (!rd_en) 
                        state  <= s0   ; 
                     else begin //读数据模块打开
                        rd_cmd <= `ACT ;//发送激活命令给SDR
                        rd_a   <= row  ;//发送行地址给SDR
                        rd_ba  <= ba   ;//发送Bank地址给给SDR
                        rd_done<= 0    ;//
                        state  <= s1   ;
                     end
                s1: if (cnt < `tRCD - 1)//经过TRCD的周期
                        begin
                            rd_cmd <= `NOP    ;
                            cnt    <= cnt + 1 ;
                            state  <= s1      ;
                        end
                      else begin 
                            rd_cmd     <= `RD   ;//发送读数据命令
                            cnt        <= 0     ;
                            rd_ba      <= ba    ;//发送Bank地址
                            rd_a[9:0]  <= col   ;//发送列地址
                            rd_a[10]   <= 1     ;//自动管理purchage
                            state      <= s2    ;
                       end
               s2: if (cnt < `CL + `SL - 1)//经过CL(列选通潜伏期)+SL个周期后
                        begin
                            rd_cmd     <= `NOP    ;
                            cnt        <= cnt + 1 ;
                            state      <= s2      ;
                        end
                      else begin
                            load_l     <= 1       ;//装配低16bit数据
                            cnt        <= 0       ;
                            state      <= s3      ;
                      end
                s3: begin
                            load_l     <= 0       ;
                            load_h     <= 1       ;//装配高16bit数据
                            state      <= s4      ;
                     end
                s4: begin
                            rd_done    <= 1       ;//发出完成读出数据的反馈信号
                            load_h     <= 0       ;
                            state      <= s0      ;
                     end
            endcase
    end
    
    //sdr_dq是来自SDR_CLK时钟域,需要先用capture_clk捕获,理论上SDR_CLK和capture_clk都是180度相位
    //此时的sdr_dq数据与capture_clk是中心对齐
    always @ (posedge capture_clk)
        begin: CAP_REG 
            dq_cap <= sdr_dq;
        end
    //此时的dq_cap数据与CLK是中心对齐
    always @ (posedge clk)
        begin: SYN_REG
            dq_syn <= dq_cap;
        end
    
    reg [15:0] rdata_lr;
    reg [15:0] rdata_hr;
    always @ (posedge clk)
        begin:FIT
            if (!soft_rst_n)begin
                rdata_lr <= 16'b0             ;
                rdata_hr <= 16'b0             ;
                end
            else if (load_l)//如果需要装配低16bit数据时候 
                rdata_lr <= dq_syn            ;
            else if (load_h)//如果需要装配高16bit数据的时候
                rdata_hr <= dq_syn            ;
        end
    
    assign rdata   = {rdata_hr, rdata_lr};//rdata再给Avalon总线上的local_rdata,输出到总线上
    endmodule 
    
    
    
      

    参考视频链接: 至芯科技李凡老师FPGA课堂:SDRAM控制器设计(超级经典)-学习视频教程-腾讯课堂

    参考文档: Micron的MT48LC16M16A2器件文档

  • 相关阅读:
    布尔值
    字典及字典的索引
    列表及列表的索引
    python之基本数据类型
    python之变量
    一个python程序运行的三大步骤
    编程语言分类与介绍
    应用程序的启动流程
    爬虫之PyQuery的base了解
    Django:web认识,jinja2模块,如何安装Django
  • 原文地址:https://www.cnblogs.com/weitter/p/14595906.html
Copyright © 2020-2023  润新知