A7 的 DDR3 IP 核外围添加 FIFO 接口控制器的实现

设计任务

本章节将会在已经完成的 IP 核读、写模块基础上添加 FIFO 接口,对于读、 写端都会添加一组 FIFO,其中包括命令端 FIFO和数据端FIFO。

设计目的:

之前的课程我们完成了 IP 核的读、写控制,但是无论是读还是写,每次都只能发送一次命令和一次突发的数据,也就是说在读或者写的过程中,当再来一次读或者写的命令时,我们的控制器是没有办法执行的,为了解决掉这个问题,我 们可以加存储器将没有办法及时执行的命令和数据缓存起来,当本次操作结束后, 可以从缓冲器内取下一次需要执行的命令和数据,这样就可以防止命令和数据丢失。

FIFO 接口实现:

1、总体框架介绍

我们先给出加完 FIFO 的总体框架,然后再细分析每个环节,添加 FIFO 的结构框架如图 1 所示。如图 1 所示,我们添加了 4 个模块,其中 rd_data_fifo_ctrl 为 读数据的缓冲 fifo、rd_cmd_fifo_ctrl 为读命令的缓冲 fifo、wr_data_fifo_ctrl 为写 数据的缓冲 fifo、wr_cmd_fifo_ctrl 为写命令的缓冲 fifo。 当读、写命令FIFO 中有命令时,对应的 empty 信号将会为低电平,因此我们可以将读、写命令FIFO的empty信号取反后作为仲裁模块的rd_req和wr_req。同时,仲裁模块输出的读、写开始信号可以作为读、写命令 FIFO 的读使能,根 据仲裁模块输出的读、写开始信号可以读出读、写命令 FIFO 内的命令、地址、 突发长度等,A7_rd_ctrl 和 A7_wr_ctrl 模块根据命令 FIFO 读出的信息可以进行相应的操作。 A7_rd_ctrl 模块读出的数据可以存入到 rd_data_fifo_ctrl,因此 rd_data_valid 可以作为 rd_data_fifo_ctrl 的写使能,rd_data_128bit 可以作为 rd_data_fifo_ctrl 的 写数据。A7_wr_ctrl 模块输入的数据可以从 rd_data_fifo_ctrl 中读出,因此 data_req 可以作为 wr_data_fifo_ctrl 的读使能,data_128bit 可以作为 wr_data_fifo_ctrl 的读数据。

A7 的 DDR3 IP 核外围添加 FIFO 接口控制器的实现_第1张图片

 

2、各个模块变量说明

下面对四个新加入的模块的端口进行说明,首先我们先对读端的命令 FIFO 和数据 FIFO 进行说明。为了方便我们区分读写模块,此处我用 p1 代表读,p2 代表写。

A7 的 DDR3 IP 核外围添加 FIFO 接口控制器的实现_第2张图片

 

 

A7 的 DDR3 IP 核外围添加 FIFO 接口控制器的代码实现

module fifo(
    input          wire                  init_calib_complete,
    input          wire                  ui_clk,
    //p1_data
    input          wire                  p1_rd_clk,
    input          wire                  p1_rd_en,
    input          wire                  rd_data_valid,
    input          wire  [127:0]         rd_data_128bit,
    output         wire                  p1_rd_empty,
    output         wire                  p1_rd_full,
    output         wire  [127:0]         p1_rd_data,
    output         wire                  p1_rd_count,

    //p1_cmd
    input          wire                  p1_cmd_clk,
    input          wire                  p1_cmd_en,
    input          wire  [2:0]           p1_cmd_intr,
    input          wire  [6:0]           p1_cmd_bl,
    input          wire  [27:0]          p1_cmd_addr,
    input          wire                  rd_cmd_start,
    output         wire                  p1_cmd_empty,
    output         wire                  p1_cmd_full,       
    output         wire  [2:0]           rd_cmd_intr,
    output         wire  [27:0]          rd_cmd_addr,
    output         wire  [6:0]           rd_cmd_bl,

    //p2_data
    input          wire                  p2_wr_clk,
    input          wire                  p2_wr_en,
    input          wire  [127:0]         p2_wr_data,
    input          wire  [15:0]          p2_wr_mask,
    input          wire                  data_req,
    output         wire  [15:0]             wr_mask,
    output         wire  [127:0]         data_128bit,
    output         wire                  p2_wr_empty,
    output         wire                  p2_wr_full,
    output         wire                  p2_wr_count,

    //p2_cmd
    input          wire                  p2_cmd_clk,
    input          wire                  p2_cmd_en,
    input          wire  [2:0]           p2_cmd_intr,
    input          wire  [6:0]           p2_cmd_bl,
    input          wire  [27:0]          p2_cmd_addr,
    input          wire                  wr_cmd_start,
    output         wire                  p2_cmd_empty,
    output         wire                  p2_cmd_full,       
    output         wire  [2:0]           wr_cmd_intr,
    output         wire  [27:0]          wr_cmd_addr,
    output         wire  [6:0]           wr_cmd_bl
    );


cmd_fifo cmd_fifo_inst_wr (
  .rst(~init_calib_complete),                  // input wire rst
  .wr_clk(p2_cmd_clk),            // input wire wr_clk
  .rd_clk(ui_clk),            // input wire rd_clk
  .din({p2_cmd_intr,p2_cmd_bl,p2_cmd_addr}),                  // input wire [37 : 0] din
  .wr_en(p2_cmd_en),              // input wire wr_en
  .rd_en(wr_cmd_start),              // input wire rd_en
  .dout({wr_cmd_intr,wr_cmd_bl,wr_cmd_addr}),                // output wire [37 : 0] dout
  .full(p2_cmd_full),                // output wire full
  .empty(p2_cmd_empty),              // output wire empty
  .wr_rst_busy(),  // output wire wr_rst_busy
  .rd_rst_busy()  // output wire rd_rst_busy
);

wr_data_fifo wr_data_fifo_inst (
  .rst(~init_calib_complete),                      // input wire rst
  .wr_clk(p2_wr_clk),                // input wire wr_clk
  .rd_clk(ui_clk),                // input wire rd_clk
  .din({p2_wr_mask,p2_wr_data}),                      // input wire [143 : 0] din
  .wr_en(p2_wr_en),                  // input wire wr_en
  .rd_en(data_req),                  // input wire rd_en
  .dout({wr_mask,data_128bit}),                    // output wire [17 : 0] dout
  .full(p2_wr_full),                    // output wire full
  .empty(p2_wr_empty),                  // output wire empty
  .wr_data_count(p2_wr_count),  // output wire [6 : 0] wr_data_count
  .wr_rst_busy(),      // output wire wr_rst_busy
  .rd_rst_busy()      // output wire rd_rst_busy
);

cmd_fifo cmd_fifo_inst_rd (
  .rst(~init_calib_complete),                  // input wire rst
  .wr_clk(p1_cmd_clk),            // input wire wr_clk
  .rd_clk(ui_clk),            // input wire rd_clk
  .din({p1_cmd_intr,p1_cmd_bl,p1_cmd_addr}),                  // input wire [37 : 0] din
  .wr_en(p1_cmd_en),              // input wire wr_en
  .rd_en(rd_cmd_start),              // input wire rd_en
  .dout({rd_cmd_intr,rd_cmd_bl,rd_cmd_addr}),                // output wire [37 : 0] dout
  .full(p1_cmd_full),                // output wire full
  .empty(p1_cmd_empty),              // output wire empty
  .wr_rst_busy(),  // output wire wr_rst_busy
  .rd_rst_busy()  // output wire rd_rst_busy
);

rd_data_fifo rd_data_fifo_inst (
  .rst(~init_calib_complete),                      // input wire rst
  .wr_clk(ui_clk),                // input wire wr_clk
  .rd_clk(p1_rd_clk),                // input wire rd_clk
  .din(rd_data_128bit),                      // input wire [127: 0] din
  .wr_en(rd_data_valid),                  // input wire wr_en
  .rd_en(p1_rd_en),                  // input wire rd_en
  .dout(p1_rd_data),                    // output wire [127 : 0] dout
  .full(p1_rd_full),                    // output wire full
  .empty(p1_rd_empty),                  // output wire empty
  .rd_data_count(p1_rd_count),  // output wire [6 : 0] rd_data_count
  .wr_rst_busy(),      // output wire wr_rst_busy
  .rd_rst_busy()      // output wire rd_rst_busy
);


endmodule

你可能感兴趣的:(tcp/ip,网络,网络协议)