其他分享
首页 > 其他分享> > FPGA——VIVADO DDR3 MIG IP核读写接口

FPGA——VIVADO DDR3 MIG IP核读写接口

作者:互联网

一、DDR3


ddrio_mod u_ddrio_mod (
    // Memory interface ports
    .ddr3_addr                      (ddr3_addr          ),  // output [13:0]    ddr3_addr
    .ddr3_ba                        (ddr3_ba            ),  // output [2:0]		ddr3_ba
    .ddr3_cas_n                     (ddr3_cas_n         ),  // output			ddr3_cas_n
    .ddr3_ck_n                      (ddr3_ck_n          ),  // output [0:0]		ddr3_ck_n
    .ddr3_ck_p                      (ddr3_ck_p          ),  // output [0:0]		ddr3_ck_p
    .ddr3_cke                       (ddr3_cke           ),  // output [0:0]		ddr3_cke
    .ddr3_ras_n                     (ddr3_ras_n         ),  // output			ddr3_ras_n
    .ddr3_reset_n                   (ddr3_reset_n       ),  // output			ddr3_reset_n
    .ddr3_we_n                      (ddr3_we_n          ),  // output			ddr3_we_n
    .ddr3_dq                        (ddr3_dq            ),  // inout [15:0]		ddr3_dq
    .ddr3_dqs_n                     (ddr3_dqs_n         ),  // inout [1:0]		ddr3_dqs_n
    .ddr3_dqs_p                     (ddr3_dqs_p         ),  // inout [1:0]		ddr3_dqs_p
    .init_calib_complete            (init_calib_complete),  // output			init_calib_complete
	.ddr3_cs_n                      (ddr3_cs_n          ),  // output [0:0]		ddr3_cs_n
    .ddr3_dm                        (ddr3_dm            ),  // output [1:0]		ddr3_dm
    .ddr3_odt                       (ddr3_odt           ),  // output [0:0]		ddr3_odt

    // Application interface ports
    .app_addr                       (app_addr           ),  // input [27:0]		app_addr
    .app_cmd                        (app_cmd            ),  // input [2:0]		app_cmd (write 000,read 001,write bytes 011)
    .app_en                         (app_en             ),  // input		    app_en
    .app_wdf_data                   (app_wdf_data       ),  // input [127:0]    app_wdf_data
    .app_wdf_end                    (app_wdf_end        ),  // input		    app_wdf_end
    .app_wdf_wren                   (app_wdf_wren       ),  // input		    app_wdf_wren
    .app_rd_data                    (app_rd_data        ),  // output [127:0]   app_rd_data
    .app_rd_data_end                (app_rd_data_end    ),  // output			app_rd_data_end
    .app_rd_data_valid              (app_rd_data_valid  ),  // output			app_rd_data_valid
    .app_rdy                        (app_rdy            ),  // output			app_rdy
    .app_wdf_rdy                    (app_wdf_rdy        ),  // output			app_wdf_rdy
    .app_sr_req                     ('b0                ),  // input			app_sr_req(This input is reserved and should be tied to 0.)
    .app_ref_req                    ('b0                ),  // input			app_ref_req
    .app_zq_req                     ('b0                ),  // input			app_zq_req
    .app_sr_active                  (                   ),  // output			app_sr_active
    .app_ref_ack                    (                   ),  // output			app_ref_ack
    .app_zq_ack                     (                   ),  // output			app_zq_ack

    .ui_clk                         (clk                ),  // output			ui_clk
    .ui_clk_sync_rst                (ui_clk_sync_rst    ),  // output			ui_clk_sync_rst

    .app_wdf_mask                   (app_wdf_mask       ),  // input [15:0]		app_wdf_mask

    // System Clock Ports
    .sys_clk_i                      (sys_clk_i          ),
    .sys_rst                        (sys_rst            )   // input sys_rst
);

二、写

//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/03/05 15:56:56
// Design Name  CNLUZT: 
// Module Name: ddr_wrapp
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module ddr_wrapp(
    //sys port
    clk         ,
    rst_n       ,
    en          ,
    addr        ,
    dat_i       ,
    done        ,
    busy        ,
    //ddrctr interface port
    app_cmd     ,
    app_addr    ,
    app_en      ,
    app_wdf_data,
    app_wdf_end ,
    app_wdf_wren,
    app_rdy     ,
    app_wdf_rdy  
);
//sys param
parameter   ADDR_W  =   28;
parameter   DATA_W  =   128;

//state mechine param
parameter   STATE_W =   3       ,
            IDLE    =   3'b001  ,
            WR      =   3'b010  ,
            ADDR    =   3'b100  ;



//sys port
input                   clk             ;
input                   rst_n           ;
input                   en              ;
input   [ADDR_W-1:0]    addr            ;
input   [DATA_W-1:0]    dat_i           ;
output                  done            ;
output                  busy            ;

//ddrctr interface port
output  [2:0]           app_cmd         ;
output  [ADDR_W-1:0]    app_addr        ;
output                  app_en          ;
output  [DATA_W-1:0]    app_wdf_data    ;
output                  app_wdf_end     ;
output                  app_wdf_wren    ;
input                   app_rdy         ;
input                   app_wdf_rdy     ;

//ddrctr interface signal
reg     [2:0]           app_cmd         = 'b0;
reg     [27:0]          app_addr        = 'b0;
wire                    app_en          ;
reg     [127:0]         app_wdf_data    = 'b0;
wire                    app_wdf_end     ;
wire                    app_wdf_wren    ;

//sys signal
reg                     done            ;
reg                     busy            ;

//state mechine singal
reg     [STATE_W-1:0]   state_c         ;
reg     [STATE_W-1:0]   state_n         ;
wire                    idl2wr_start    ;
wire                    wr2addr_start   ;
wire                    addr2idl_start  ;

//flag singal
wire                    wr_end          ;
wire                    cmd_end         ;

always@(posedge clk or negedge rst_n)begin  
    if(!rst_n)begin   
        state_c <= IDLE;
    end 
    else begin
        state_c <= state_n; 
    end
end

always@(*)begin 
case(state_c)   
    IDLE: begin  
        if(idl2wr_start)begin 
            state_n = WR;
        end
        else begin
            state_n = state_c; 
        end
    end
    WR:begin
        if(wr2addr_start)begin
            state_n = ADDR;
        end
        else begin
            state_n = state_c;
        end
    end
    ADDR:begin
        if(addr2idl_start)begin 
            state_n = IDLE;
        end
        else begin
            state_n = state_c;
        end
    end
    default:begin
        state_n = IDLE;
    end 
    endcase
end

assign idl2wr_start     =   state_c == IDLE   && en;
assign wr2addr_start    =   state_c == WR     && wr_end;
assign addr2idl_start   =   state_c == ADDR   && cmd_end;

//flag
assign wr_end           =   (app_rdy & app_wdf_rdy & app_wdf_wren & state_c == WR);
assign cmd_end          =   (app_rdy & app_wdf_rdy & app_en & (state_c == ADDR));

always @(posedge clk)begin
    if(state_c == IDLE & en)begin
        app_cmd <= 3'b000;
        app_addr <= addr;
        app_wdf_data <= dat_i;
    end
end



assign app_wdf_wren = (state_c == WR)   & app_rdy & app_wdf_rdy;
assign app_wdf_end  = (state_c == WR)   & app_rdy & app_wdf_rdy;
assign app_en       = (state_c == ADDR) & app_rdy & app_wdf_rdy;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        done <= 0;
    else if(cmd_end)
        done <= 1;
    else
        done <= 0;
end

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        busy <= 0;
    else if(state_c == IDLE & en)
        busy <= 1;
    else if(done)
        busy <= 0;
end

endmodule

三、读

//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/03/05 15:56:56
// Design Name: CNLUZT 
// Module Name: ddr_wrapp
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module ddr_rdapp(
    //sys port
    clk                 ,
    rst_n               ,
    en                  ,
    addr                ,
    dat_o               ,
    nd                  ,
    busy                ,
    //ddrctr interface port
    app_cmd             ,
    app_addr            ,
    app_en              ,
    app_rd_data         ,
    app_rd_data_end     ,
    app_rdy             ,
    app_rd_data_valid    
);
//sys param
parameter   ADDR_W  =   28;
parameter   DATA_W  =   128;

//state mechine param
parameter   STATE_W =   3       ,
            IDLE    =   3'b001  ,
            RD      =   3'b010  ,
            ADDR    =   3'b100  ;



//sys port
input                   clk                 ;
input                   rst_n               ;
input                   en                  ;
input   [ADDR_W-1:0]    addr                ;
output  [DATA_W-1:0]    dat_o               ;
output                  nd                  ;
output                  busy                ;

//ddrctr interface port
output  [2:0]           app_cmd             ;
output  [ADDR_W-1:0]    app_addr            ;
output                  app_en              ;
input   [DATA_W-1:0]    app_rd_data         ;
input                   app_rd_data_end     ;
input                   app_rdy             ;
input                   app_rd_data_valid   ;


//ddrctr interface signal
reg     [2:0]           app_cmd         = 'b0;
reg     [27:0]          app_addr        = 'b0;
wire                    app_en              ;

//sys signal
reg     [DATA_W-1:0]    dat_o               ;
reg                     nd                  ;
reg                     busy                ;

//state mechine singal
reg     [STATE_W-1:0]   state_c             ;
reg     [STATE_W-1:0]   state_n             ;
wire                    idl2addr_start      ;
wire                    addr2rd_start       ;
wire                    rd2idl_start        ;

//flag singal
wire                    rd_end              ;
wire                    cmd_end             ;

always@(posedge clk or negedge rst_n)begin  
    if(!rst_n)begin   
        state_c <= IDLE;
    end 
    else begin
        state_c <= state_n; 
    end
end

always@(*)begin 
case(state_c)   
    IDLE: begin  
        if(idl2addr_start)begin 
            state_n = ADDR;
        end
        else begin
            state_n = state_c; 
        end
    end
    ADDR:begin
        if(addr2rd_start)begin 
            state_n = RD;
        end
        else begin
            state_n = state_c;
        end
    end
    RD:begin
        if(rd2idl_start)begin
            state_n = ADDR;
        end
        else begin
            state_n = state_c;
        end
    end
    default:begin
        state_n = IDLE;
    end 
    endcase
end

assign idl2addr_start   =   state_c == IDLE     && en;
assign addr2rd_start    =   state_c == ADDR     && cmd_end;
assign rd2idl_start     =   state_c == RD       && rd_end;

//flag
assign rd_end           =   (app_rdy  & app_rd_data_end & (state_c == RD)   );
assign cmd_end          =   (app_rdy  & app_en          & (state_c == ADDR) );

always @(posedge clk)begin
    if(state_c == IDLE & en)begin
        app_cmd <= 3'b001;
        app_addr <= addr;
    end
end

assign app_en           =   (state_c == ADDR) & app_rdy;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        dat_o <= 0;
    else if((state_c == RD) & app_rd_data_valid)
        dat_o <= app_rd_data;
    else if(nd)
        dat_o <= 0;
end

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        nd <= 0;
    else if(cmd_end)
        nd <= 1;
    else
        nd <= 0;
end

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        busy <= 0;
    else if(state_c == IDLE & en)
        busy <= 1;
    else if(nd)
        busy <= 0;
end

endmodule

标签:wdf,input,FPGA,IP,app,MIG,ddr3,output,data
来源: https://www.cnblogs.com/cnlntr/p/15969553.html