• 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 msfm(
            local_wdata       ,//1、Avalon总线 写数据 32bit
            local_rdata       ,//2、Avalon总线 读数据 32bit
            local_write       ,//3、Avalon总线 写命令
            local_addr        ,//4、Avalon总线 读写地址
            local_read        ,//5、Avalon总线 读命令
            local_ready       ,//6、Avalon总线 local_ready为1表示当前无读写操作,为0表示当前正在进行读写操作
            local_rddatavalid ,//7、Avalon总线 需要的数据刚刚读出
            
            init_done         ,//完成上电操作
            ref_done          ,//完成刷新操作
            wr_done           ,//完成写数据操作
            rd_done           ,//完成读数据操作
            row               ,//输出行地址
            col               ,//输出列地址
            ba                ,//输出Bank地址线
            wdata             ,//把Avalon总线上的写数据发送到写模块
            rdata             ,//从DDR读出的数据读出到Avalon总线上
            clk               ,//100Mhz时钟
            soft_rst_n        ,//软复位
            init_en           ,//使能上电模块
            ref_en            ,//使能刷新模块
            rt_en             ,//使能刷新计算器
            wr_en              ,//写数据使能
            rd_en             ,//读数据使能
            rt_flag           ,//计算器计满的标志 固定周期进行刷新操作
            smux               //多路选择器开关
    );
    
    input      [31:0]  local_wdata         ;
    output reg [31:0]  local_rdata         ;
    input      [24:0]  local_addr          ;
    input              local_write         ;
    input              local_read          ;
    output reg         local_ready         ;
    output reg         local_rddatavalid   ;
    input      [31:0]  rdata               ;
    
    input init_done        ;
    input ref_done         ;
    input wr_done          ;
    input rd_done          ;
    
    input clk              ;
    input soft_rst_n       ;
    input rt_flag          ;
    
    output reg [12:0] row         ;
    output reg [9:0]  col         ;
    output reg [1:0]  ba          ;
    output reg [31:0] wdata       ;                       
    output reg        init_en     ;
    output reg        ref_en      ;
    output reg        rt_en       ;
    output reg        wr_en       ;
    output reg        rd_en       ;
    output reg [1:0] smux         ;
    
    reg [3:0]  state       ; 
      
    parameter s0 = 4'b0000  ;
    parameter s1 = 4'b0001  ;
    parameter s2 = 4'b0011  ;
    parameter s3 = 4'b0010  ;
    parameter s4 = 4'b0110  ;
    parameter s5 = 4'b0111  ;
    parameter s6 = 4'b1111  ;
    
    always @(posedge clk)begin 
     if(!soft_rst_n)begin//同步复位           
         ref_en            <= 1'b0      ;//管理输出端口
         rt_en             <= 1'b0      ;
         init_en           <= 1'b0      ;
         wr_en             <= 1'b0      ;
         rd_en             <= 1'b0      ;
         wdata             <= 32'd0     ;
         row               <= 13'd0     ;
         col               <= 10'd0     ;
         ba                <= 2'd0      ;
         smux              <= `MUX_INIT ;
         state             <= s0        ;
         local_ready       <= 1'b0      ;
         local_rddatavalid <= 1'b0      ;
         local_rdata       <= 0         ;
     end
     else  
        case(state)
            s0: begin
                 state         <= s1       ;
                 init_en       <= 1        ;//执行上电操作
                 end
    
            s1:if(!init_done)begin
                   init_en     <= 1'b0     ;
                   state       <= s1       ;
               end
                else begin//完成上电后
                   rt_en       <= 1        ;//打开刷新计算器模块的使能
                   smux        <= `MUX_REF ;//多路选择器选择刷新的bus
                   local_ready <= 1        ;
                   state       <= s2       ;
                end
            
            s2: begin
                   ref_en      <=   1'b1  ;//打开刷新模块的使能
                   state       <=   s3    ;
                 end
                 
            s3:if(!ref_done)begin
                   ref_en      <= 1'b0    ;
                   state       <= s3      ;
                end
                else begin//完成刷新操作后
                   state       <= s4      ;
                end
                       
                  
            s4: if(!rt_flag)begin//如果在刷新计数周期的空闲时间里,可以执行读写操作
                    if(local_write)
                         begin//如果Avalon总线上的写命令有打开 执行写操作
                               state       <= s5                ;
                               wr_en       <= 1'b1              ;//打开写使能模块
                               row         <= local_addr[22:10] ;//发送给写模块的行地址
                               col         <= local_addr[9:0]   ;//发送给写模块的列地址
                               ba          <= local_addr[24:23] ;//发送给写模块的Bank地址
                               local_ready <= 0                 ;//向外部发出此时SDR控制器忙的信息
                               wdata       <= local_wdata       ;//Avalon总线上的写数据发送给写模块,再由写模块发送给SDR
                               smux        <= `MUX_WR           ;//多路选择器选择写数据模块的bus
                           end 
                       else if(local_read)//如果Avalon总线上的读命令有打开 执行读操作
                           begin
                               state       <= s6                ;
                               smux        <= `MUX_RD              ;//多路选择器选择读数据模块的bus
                               rd_en       <= 1'b1              ;//打开读使能模块
                               row         <= local_addr[22:10] ;
                               col         <= local_addr[9:0]   ;
                               ba          <= local_addr[24:23] ;
                               local_ready <= 0                 ;
                               local_rddatavalid <= 0           ;
                           end
                       else begin//既没有写数据请求,也没有读数据请求
                               state       <= s4                ;
                       end
                end     
                else begin//到了该刷新的时间,应该执行刷新操作
                       ref_en      <= 1'b1              ;//打开刷新模块使能开关
                       state       <= s3                ;
                end
                 
            
            s5:if(!wr_done)begin
                      wr_en        <= 1'b0              ;
                      state        <= s5                ;
                 end
                 else begin//如果已经完成写数据操作
                      smux         <= `MUX_REF          ;//多路选择器重新回到刷新的bus
                      local_ready  <= 1'b1              ;//标志已经完成写操作
                      state        <= s4                ;
                 end
            s6:if(!rd_done)begin
                      rd_en <= 0;
                      state <= s6;
                end
                else begin//完成数据的读出
                      rd_en <= 0;
                      state       <= s4          ;
                      smux        <= `MUX_REF    ;
                      local_ready <= 1'b1        ;
                      local_rddatavalid <= 1'b1  ;
                      local_rdata <= rdata       ;
            end
            default:
                      state <= s0;
        endcase
    end
    
    endmodule 

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

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

  • 相关阅读:
    Http record java
    Java String constructed from byte array has bad length
    Schema
    Scale-up(纵向扩展) vs Scale-out(横向扩展)
    数据同步
    JDBC and Oracle conn.commit and conn.setAutocommit not working properly
    DGIM
    Github Blog 搭建手册
    软件探索(一)
    经典书单 —— 人文社科
  • 原文地址:https://www.cnblogs.com/weitter/p/14595925.html
Copyright © 2020-2023  润新知