SDRAM——仲裁模块及小封装

在这里插入图片描述
在这里插入图片描述

`timescale  1ns/1ns
module  sdram_arbit
(
    input   wire            sys_clk     ,   //系统时钟
    input   wire            sys_rst_n   ,   //复位信号
//sdram_init
    input   wire    [3:0]   init_cmd    ,   //初始化阶段命令
    input   wire            init_end    ,   //初始化结束标志
    input   wire    [1:0]   init_ba     ,   //初始化阶段Bank地址
    input   wire    [12:0]  init_addr   ,   //初始化阶段数据地址
//sdram_auto_ref
    input   wire            aref_req    ,   //自刷新请求
    input   wire            aref_end    ,   //自刷新结束
    input   wire    [3:0]   aref_cmd    ,   //自刷新阶段命令
    input   wire    [1:0]   aref_ba     ,   //自动刷新阶段Bank地址
    input   wire    [12:0]  aref_addr   ,   //自刷新阶段数据地址
//sdram_write
    input   wire            wr_req      ,   //写数据请求	来自fifo
    input   wire    [1:0]   wr_ba       ,   //写阶段Bank地址
    input   wire    [15:0]  wr_data     ,   //写入SDRAM的数据
    input   wire            wr_end      ,   //一次写结束信号
    input   wire    [3:0]   wr_cmd      ,   //写阶段命令
    input   wire    [12:0]  wr_addr     ,   //写阶段数据地址
    input   wire            wr_sdram_en ,
//sdram_read
    input   wire            rd_req      ,   //读数据请求	来自fifo
    input   wire            rd_end      ,   //一次读结束
    input   wire    [3:0]   rd_cmd      ,   //读阶段命令
    input   wire    [12:0]  rd_addr     ,   //读阶段数据地址
    input   wire    [1:0]   rd_ba       ,   //读阶段Bank地址

    output  reg             aref_en     ,   //自刷新使能	给到刷新模块
    output  reg             wr_en       ,   //写数据使能	给到写模块
    output  reg             rd_en       ,   //读数据使能	给到读模块

    output  wire            sdram_cke   ,   //SDRAM时钟使能	  最终给到SDRAM的命令
    output  wire            sdram_cs_n  ,   //SDRAM片选信号	  最终给到SDRAM的命令
    output  wire            sdram_ras_n ,   //SDRAM行地址选通 最终给到SDRAM的命令
    output  wire            sdram_cas_n ,   //SDRAM列地址选通 最终给到SDRAM的命令
    output  wire            sdram_we_n  ,   //SDRAM写使能	  最终给到SDRAM的命令
    output  reg     [1:0]   sdram_ba    ,   //SDRAM Bank地址  最终给到SDRAM的命令
    output  reg     [12:0]  sdram_addr  ,   //SDRAM地址总线   最终给到SDRAM的命令
    inout   wire    [15:0]  sdram_dq        //SDRAM数据总线 双最终给到SDRAM的命令向数据线
);

//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//

//parameter define
parameter   IDLE    =   5'b0_0001   ,   //初始状态
            ARBIT   =   5'b0_0010   ,   //仲裁状态
            AREF    =   5'b0_0100   ,   //自动刷新状态
            WRITE   =   5'b0_1000   ,   //写状态
            READ    =   5'b1_0000   ;   //读状态
parameter   CMD_NOP =   4'b0111     ;   //空操作指令

//reg   define
reg     [3:0]   sdram_cmd   ;   //写入SDRAM命令
reg     [4:0]   state       ;   //状态机状态

//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//

//state:状态机状态
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        state   <=  IDLE;
    else    case(state)
        IDLE:   if(init_end == 1'b1)
                    state   <=  ARBIT;
                else
                    state   <=  IDLE;
        ARBIT:if(aref_req == 1'b1)
                    state   <=  AREF;
                else    if(wr_req == 1'b1)
                    state   <=  WRITE;
                else    if(rd_req == 1'b1)
                    state   <=  READ;
                else
                    state   <=  ARBIT;
        AREF:   if(aref_end == 1'b1)
                    state   <=  ARBIT;
                else
                    state   <=  AREF; 
        WRITE:  if(wr_end == 1'b1)
                    state   <=  ARBIT;
                else
                    state   <=  WRITE;
        READ:   if(rd_end == 1'b1)
                    state   <=  ARBIT;
                else
                    state   <=  READ;
        default:state   <=  IDLE;
    endcase

//aref_en:自动刷新使能
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        aref_en  <=  1'b0;
    else    if((state == ARBIT) && (aref_req == 1'b1))
        aref_en  <=  1'b1;
    else    if(aref_end == 1'b1)
        aref_en  <=  1'b0;

//wr_en:写数据使能
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        wr_en   <=  1'b0;
    else    if((state == ARBIT) && (aref_req == 1'b0) && (wr_req == 1'b1))
        wr_en   <=  1'b1;
    else    if(wr_end == 1'b1)
        wr_en   <=  1'b0;

//rd_en:读数据使能
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        rd_en   <=  1'b0;
    else    if((state == ARBIT) && (aref_req == 1'b0)  && (rd_req == 1'b1))
        rd_en   <=  1'b1;
    else    if(rd_end == 1'b1)
        rd_en   <=  1'b0;

//sdram_cmd:写入SDRAM命令;sdram_ba:SDRAM Bank地址;sdram_addr:SDRAM地址总线
always@(*)
    case(state) 
        IDLE: begin
            sdram_cmd   <=  init_cmd;
            sdram_ba    <=  init_ba;
            sdram_addr  <=  init_addr;
        end
        AREF: begin
            sdram_cmd   <=  aref_cmd;
            sdram_ba    <=  aref_ba;
            sdram_addr  <=  aref_addr;
        end
        WRITE: begin
            sdram_cmd   <=  wr_cmd;
            sdram_ba    <=  wr_ba;
            sdram_addr  <=  wr_addr;
        end
        READ: begin
            sdram_cmd   <=  rd_cmd;
            sdram_ba    <=  rd_ba;
            sdram_addr  <=  rd_addr;
        end
        default: begin
            sdram_cmd   <=  CMD_NOP;
            sdram_ba    <=  2'b11;
            sdram_addr  <=  13'h1fff;
        end
    endcase

//SDRAM时钟使能
assign  sdram_cke = 1'b1;
//SDRAM数据总线	不是写就高阻
assign  sdram_dq = (wr_sdram_en == 1'b1) ? wr_data : 16'bz;
//片选信号,行地址选通信号,列地址选通信号,写使能信号
assign  {sdram_cs_n, sdram_ras_n, sdram_cas_n, sdram_we_n} = sdram_cmd;

endmodule

`timescale  1ns/1ns
module  sdram_ctrl
(
    input   wire            sys_clk         ,   //系统时钟
    input   wire            sys_rst_n       ,   //复位信号,低电平有效
//SDRAM写端口
    input   wire            sdram_wr_req    ,   //写SDRAM请求信号
    input   wire    [23:0]  sdram_wr_addr   ,   //SDRAM写操作的地址
    input   wire    [9:0]   wr_burst_len    ,   //写sdram时数据突发长度
    input   wire    [15:0]  sdram_data_in   ,   //写入SDRAM的数据
    output  wire            sdram_wr_ack    ,   //写SDRAM响应信号
//SDRAM读端口
    input   wire            sdram_rd_req    ,   //读SDRAM请求信号
    input   wire    [23:0]  sdram_rd_addr   ,   //SDRAM读操作的地址
    input   wire    [9:0]   rd_burst_len    ,   //读sdram时数据突发长度
    output  wire    [15:0]  sdram_data_out  ,   //从SDRAM读出的数据
    output  wire            init_end        ,   //SDRAM 初始化完成标志
    output  wire            sdram_rd_ack    ,   //读SDRAM响应信号
//FPGA与SDRAM硬件接口
    output  wire            sdram_cke       ,   // SDRAM 时钟有效信号
    output  wire            sdram_cs_n      ,   // SDRAM 片选信号
    output  wire            sdram_ras_n     ,   // SDRAM 行地址选通
    output  wire            sdram_cas_n     ,   // SDRAM 列地址选通
    output  wire            sdram_we_n      ,   // SDRAM 写使能
    output  wire    [1:0]   sdram_ba        ,   // SDRAM Bank地址
    output  wire    [12:0]  sdram_addr      ,   // SDRAM 地址总线
    inout   wire    [15:0]  sdram_dq            // SDRAM 数据总线
);

//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//

//wire  define
//sdram_init
wire    [3:0]   init_cmd    ;   //初始化阶段写入sdram的指令
wire    [1:0]   init_ba     ;   //初始化阶段Bank地址
wire    [12:0]  init_addr   ;   //初始化阶段地址数据,辅助预充电操作
//sdram_a_ref
wire            aref_req    ;   //自动刷新请求
wire            aref_end    ;   //自动刷新结束标志
wire    [3:0]   aref_cmd    ;   //自动刷新阶段写入sdram的指令
wire    [1:0]   aref_ba     ;   //自动刷新阶段Bank地址
wire    [12:0]  aref_addr   ;   //地址数据,辅助预充电操作
wire            aref_en     ;   //自动刷新使能
//sdram_write
wire            wr_en       ;   //写使能
wire            wr_end      ;   //一次写结束信号
wire    [3:0]   write_cmd   ;   //写阶段命令
wire    [1:0]   write_ba    ;   //写数据阶段Bank地址
wire    [12:0]  write_addr  ;   //写阶段数据地址
wire            wr_sdram_en ;   //SDRAM写使能
wire    [15:0]  wr_sdram_data;  //写入SDRAM的数据
//sdram_read
wire            rd_en       ;   //读使能
wire            rd_end      ;   //一次突发读结束
wire    [3:0]   read_cmd    ;   //读数据阶段写入sdram的指令
wire    [1:0]   read_ba     ;   //读阶段Bank地址
wire    [12:0]  read_addr   ;   //读阶段数据地址

//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//
//------------- sdram_init_inst -------------
sdram_init  sdram_init_inst
(
    .sys_clk    (sys_clk    ),  //系统时钟,频率100MHz
    .sys_rst_n  (sys_rst_n  ),  //复位信号,低电平有效

    .init_cmd   (init_cmd   ),  //初始化阶段写入sdram的指令
    .init_ba    (init_ba    ),  //初始化阶段Bank地址
    .init_addr  (init_addr  ),  //初始化阶段地址数据,辅助预充电操作
    .init_end   (init_end   )   //初始化结束信号
);

//------------- sdram_arbit_inst -------------
sdram_arbit sdram_arbit_inst
(
    .sys_clk    (sys_clk        ),  //系统时钟
    .sys_rst_n  (sys_rst_n      ),  //复位信号
//sdram_init
    .init_cmd   (init_cmd       ),  //初始化阶段命令
    .init_end   (init_end       ),  //初始化结束标志
    .init_ba    (init_ba        ),  //初始化阶段Bank地址
    .init_addr  (init_addr      ),  //初始化阶段数据地址
//sdram_auto_ref
    .aref_req   (aref_req       ),  //自刷新请求
    .aref_end   (aref_end       ),  //自刷新结束
    .aref_cmd   (aref_cmd       ),  //自刷新阶段命令
    .aref_ba    (aref_ba        ),  //自动刷新阶段Bank地址
    .aref_addr  (aref_addr      ),  //自刷新阶段数据地址
//sdram_write
    .wr_req     (sdram_wr_req   ),  //写数据请求
    .wr_end     (wr_end         ),  //一次写结束信号
    .wr_cmd     (write_cmd      ),  //写阶段命令
    .wr_ba      (write_ba       ),  //写阶段Bank地址
    .wr_addr    (write_addr     ),  //写阶段数据地址
    .wr_sdram_en(wr_sdram_en    ),  //SDRAM写使能
    .wr_data    (wr_sdram_data  ),  //写入SDRAM的数据
//sdram_read
    .rd_req     (sdram_rd_req   ),  //读数据请求
    .rd_end     (rd_end         ),  //一次读结束
    .rd_cmd     (read_cmd       ),  //读阶段命令
    .rd_addr    (read_addr      ),  //读阶段数据地址
    .rd_ba      (read_ba        ),  //读阶段Bank地址

    .aref_en    (aref_en        ),  //自刷新使能
    .wr_en      (wr_en          ),  //写数据使能
    .rd_en      (rd_en          ),  //读数据使能

    .sdram_cke  (sdram_cke      ),  //SDRAM时钟使能
    .sdram_cs_n (sdram_cs_n     ),  //SDRAM片选信号
    .sdram_ras_n(sdram_ras_n    ),  //SDRAM行地址选通
    .sdram_cas_n(sdram_cas_n    ),  //SDRAM列地址选通
    .sdram_we_n (sdram_we_n     ),  //SDRAM写使能
    .sdram_ba   (sdram_ba       ),  //SDRAM Bank地址
    .sdram_addr (sdram_addr     ),  //SDRAM地址总线
    .sdram_dq   (sdram_dq       )   //SDRAM数据总线
);

//------------- sdram_a_ref_inst -------------
sdram_a_ref sdram_a_ref_inst
(
    .sys_clk     (sys_clk   ),  //系统时钟,频率100MHz
    .sys_rst_n   (sys_rst_n ),  //复位信号,低电平有效
    .init_end    (init_end  ),  //初始化结束信号
    .aref_en     (aref_en   ),  //自动刷新使能

    .aref_req    (aref_req  ),  //自动刷新请求
    .aref_cmd    (aref_cmd  ),  //自动刷新阶段写入sdram的指令
    .aref_ba     (aref_ba   ),  //自动刷新阶段Bank地址
    .aref_addr   (aref_addr ),  //地址数据,辅助预充电操作
    .aref_end    (aref_end  )   //自动刷新结束标志
);

//------------- sdram_write_inst -------------
sdram_write sdram_write_inst
(
    .sys_clk        (sys_clk        ),  //系统时钟,频率100MHz
    .sys_rst_n      (sys_rst_n      ),  //复位信号,低电平有效
    .init_end       (init_end       ),  //初始化结束信号
    .wr_en          (wr_en          ),  //写使能

    .wr_addr        (sdram_wr_addr  ),  //写SDRAM地址
    .wr_data        (sdram_data_in  ),  //待写入SDRAM的数据(写FIFO传入)
    .wr_burst_len   (wr_burst_len   ),  //写突发SDRAM字节数

    .wr_ack         (sdram_wr_ack   ),  //写SDRAM响应信号
    .wr_end         (wr_end         ),  //一次突发写结束
    .write_cmd      (write_cmd      ),  //写数据阶段写入sdram的指令
    .write_ba       (write_ba       ),  //写数据阶段Bank地址
    .write_addr     (write_addr     ),  //地址数据,辅助预充电操作
    .wr_sdram_en    (wr_sdram_en    ),  //数据总线输出使能
    .wr_sdram_data  (wr_sdram_data  )   //写入SDRAM的数据
);

//------------- sdram_read_inst -------------
sdram_read  sdram_read_inst
(
    .sys_clk        (sys_clk        ),  //系统时钟,频率100MHz
    .sys_rst_n      (sys_rst_n      ),  //复位信号,低电平有效
    .init_end       (init_end       ),  //初始化结束信号
    .rd_en          (rd_en          ),  //读使能

    .rd_addr        (sdram_rd_addr  ),  //读SDRAM地址
    .rd_data        (sdram_dq       ),  //自SDRAM中读出的数据
    .rd_burst_len   (rd_burst_len   ),  //读突发SDRAM字节数

    .rd_ack         (sdram_rd_ack   ),  //读SDRAM响应信号
    .rd_end         (rd_end         ),  //一次突发读结束
    .read_cmd       (read_cmd       ),  //读数据阶段写入sdram的指令
    .read_ba        (read_ba        ),  //读数据阶段Bank地址
    .read_addr      (read_addr      ),  //地址数据,辅助预充电操作
    .rd_sdram_data  (sdram_data_out )   //SDRAM读出的数据
);

endmodule


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值