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

程序架构:

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器件文档

上一篇:call,apply,bind实现


下一篇:一款基于Spartan-6可向下扩展的软件无线电系统