当前位置: 首页 > news >正文

dma_ddr 的编写 通过mig控制ddr3

在这里插入图片描述
此外还有别的模块 本模块是 其中一个

`timescale 1ns/1ps
module dma_ctrl (
    input   wire            ui_clk          ,   //100MHZ 用户时钟
    input   wire            ui_rst_n        ,
    //写fifo的写端口    
    input   wire            wf_wr_clk       ,   //由数据产生模块的时钟来决定
    input   wire            wf_wr_en        ,
    input   wire    [15:0]  wf_wr_data      ,
    //读fifo的读端口
    input   wire            rf_rd_clk       ,   //由数据接收模块的时钟来决定
    input   wire            rf_rd_en        ,
    output  wire    [15:0]  rf_rd_data      ,
    output  reg             rf_rd_req       ,   //数据请求接收信号
    //----native接口------  
    //命令控制端口
    output  wire    [27:0]	app_addr        ,      
    output  reg     [2:0]	app_cmd         ,  
    output  reg     		app_en          ,  
    input   wire    		app_rdy         ,  
    //写数据端口
    output  wire    [127:0]	app_wdf_data    ,          
    output  wire    		app_wdf_end     ,          
    output  reg     		app_wdf_wren    ,          
    input   wire    		app_wdf_rdy     ,      
    output  wire    [15:0]	app_wdf_mask    ,          
    //读数据端口
    input   wire    [127:0]	app_rd_data     ,          
    input   wire    		app_rd_data_end ,  
    input   wire    		app_rd_data_vali     
);

parameter FIFO_BURST_LEN = 128; //16*8
parameter ADDR_AMX       = 40000;   //200*200

localparam IDLE    = 3'b001;    //空闲
localparam WR_DATA = 3'b010;    //写
localparam RD_DATA = 3'b100;    //读

reg [2:0] c_state,n_state;

wire [7 : 0] wf_data_count; //写fifo中还剩多少个数据(128bit)

wire [7 : 0] rf_data_count; //读fifo中还剩多少个数据(128bit)

reg [8:0] cnt_addr; //地址计数器 0 - 127

reg [31:0] cnt_wr_data; //写数据个数计数器

reg    [27:0]	app_wr_addr;    //写地址线
reg    [27:0]	app_rd_addr;    //读地址线

reg flag;   //防止程序一上电就进入读数据状态,防止读空
wire wf_rd_en;  

assign wf_rd_en     = app_wdf_wren && app_wdf_rdy;  
assign app_addr     = (c_state == WR_DATA ) ? app_wr_addr : app_rd_addr;
assign app_wdf_end  = app_wdf_wren;
assign app_wdf_mask = 0;

always @(posedge ui_clk ) begin
    if(!ui_rst_n)
        flag <= 0;
    else if(app_wr_addr == ADDR_AMX >> 2)
        flag <= 1;
    else
        flag <= flag;
end

//----三段式状态机。一 。将次态赋值给现态
always @(posedge ui_clk ) begin
    if(!ui_rst_n)
        c_state <= IDLE;
    else
        c_state <= n_state;
end

//----三段式状态机。二 。状态跳转描述
always @(*) begin
    if(!ui_rst_n)
        n_state = IDLE;
    else begin
        case (c_state)
                IDLE    : begin
                    if(wf_data_count > FIFO_BURST_LEN)
                        n_state = WR_DATA;
                    else if(rf_data_count < FIFO_BURST_LEN && flag)
                        n_state = RD_DATA;
                    else
                        n_state = IDLE;
                end
                WR_DATA : begin
                    if(app_en && app_rdy && cnt_addr == FIFO_BURST_LEN - 1)
                        n_state = IDLE;
                    else
                        n_state = WR_DATA;
                end
                RD_DATA : begin
                    if(app_en && app_rdy && cnt_addr == FIFO_BURST_LEN - 1)
                        n_state = IDLE;
                    else
                        n_state = RD_DATA;
                end
            default: n_state = IDLE;
        endcase
    end
end

//----三段式状态机。三 。对中间变量及输出结果赋值
always @(posedge ui_clk ) begin
    if(!ui_rst_n)
        rf_rd_req <= 0;
    else if(rf_data_count > 100)
        rf_rd_req <= 1;
    else
        rf_rd_req <= rf_rd_req;
end

always @(posedge ui_clk ) begin
    if(!ui_rst_n)
        app_wr_addr <= 0;
    else if(c_state == WR_DATA && app_en && app_rdy)begin
        if(app_wr_addr == ADDR_AMX - 8) //固定突发长度:8
            app_wr_addr <= 0;
        else
            app_wr_addr <= app_wr_addr + 8;
    end
    else
        app_wr_addr <= app_wr_addr;
end

always @(posedge ui_clk ) begin
    if(!ui_rst_n)
        app_rd_addr <= 0;
    else if(c_state == RD_DATA && app_en && app_rdy)begin
        if(app_rd_addr == ADDR_AMX - 8) //固定突发长度:8
            app_rd_addr <= 0;
        else
            app_rd_addr <= app_rd_addr + 8;
    end
    else
        app_rd_addr <= app_rd_addr;
end

always @(posedge ui_clk ) begin
    if(!ui_rst_n)
        app_cmd <= 0;
    else if(c_state == WR_DATA)
        app_cmd <= 0;
    else if(c_state == RD_DATA)
        app_cmd <= 1;
    else
        app_cmd <= app_cmd;
end

always @(posedge ui_clk ) begin
    if(!ui_rst_n)
        app_en <= 0;
    else if(c_state == WR_DATA || c_state == RD_DATA)begin
        if(cnt_addr == FIFO_BURST_LEN - 1 && app_rdy)
            app_en <= 0;
        else
            app_en <= 1;
    end
    else
        app_en <= 0;
end

always @(posedge ui_clk ) begin
    if(!ui_rst_n)
        app_wdf_wren <= 0;
    else if(c_state == WR_DATA && app_wdf_rdy)begin
        if(cnt_wr_data == FIFO_BURST_LEN - 1 )
            app_wdf_wren <= 0;
        else
            app_wdf_wren <= 1;
    end
    else
        app_wdf_wren <= 0;
end

always @(posedge ui_clk ) begin
    if(!ui_rst_n)
        cnt_wr_data <= 0;
    else if(c_state == WR_DATA)begin
        if(cnt_wr_data == FIFO_BURST_LEN - 1 && app_wdf_wren && app_wdf_rdy)
            cnt_wr_data <= cnt_wr_data; 
        else if(app_wdf_wren && app_wdf_rdy)    
            cnt_wr_data <= cnt_wr_data + 1;
        else
            cnt_wr_data <= cnt_wr_data;
    end
    else
        cnt_wr_data <= 0;
end

wf_fifo wf_fifo_u (
  .wr_clk(wf_wr_clk),                // input wire wr_clk
  .rd_clk(ui_clk),                // input wire rd_clk
  .din(wf_wr_data),                      // input wire [15 : 0] din
  .wr_en(wf_wr_en),                  // input wire wr_en
  .rd_en(wf_rd_en),                  // input wire rd_en
  .dout(app_wdf_data),                    // output wire [127 : 0] dout
//   .full(full),                    // output wire full
//   .empty(empty),                  // output wire empty
  .rd_data_count(wf_data_count)  // output wire [7 : 0] rd_data_count
);

rf_fifo rf_fifo_u (
  .wr_clk(ui_clk),                // input wire wr_clk
  .rd_clk(rf_rd_clk),                // input wire rd_clk
  .din(app_rd_data),                      // input wire [127 : 0] din
  .wr_en(app_rd_data_vali),                  // input wire wr_en
  .rd_en(rf_rd_en),                  // input wire rd_en
  .dout(rf_rd_data),                    // output wire [15 : 0] dout
//   .full(full),                    // output wire full
//   .empty(empty),                  // output wire empty
  .wr_data_count(rf_data_count)  // output wire [7 : 0] wr_data_count
);
    
endmodule
http://www.dtcms.com/a/20104.html

相关文章:

  • MySQL数据库入门到大蛇尚硅谷宋红康老师笔记 基础篇 part 13
  • 掌握SQL多表连接查询_轻松处理复杂数据关系
  • [0689].第04节:Kafka与第三方的集成 – Kafka集成SpringBoot
  • 《Spring实战》(第6版)第1章 Spring起步
  • 【数据结构】(9) 优先级队列(堆)
  • floodfill算法系列一>太平洋大西洋水流问题
  • 【第3章:卷积神经网络(CNN)——3.6 CNN的高级特性与优化策略】
  • 如何使用 DeepSeek 和 Dexscreener 构建免费的 AI 加密交易机器人?
  • EasyExcel 复杂填充
  • DeepSeek接入网络安全领域,AI高效驱动,重新定义网络防御边界!
  • UniApp 中制作一个横向滚动工具栏
  • MyBatis:动态SQL高级标签使用方法指南
  • 数据管理的四大基石:通俗解读数据中台、数据仓库、数据治理和主数据
  • 《千多桃花一世开》:南胥月为何爱暮悬铃
  • 输电杆塔沉降智能监测系统:如何用数据守护电网安全
  • ASP.NET Core SixLabors.ImageSharp v1.0 的图像实用程序类 web示例
  • uniapp可视化-活动报名表单系统-代码生成器
  • 【云安全】云原生- K8S kubeconfig 文件泄露
  • java中map实现函数式编程的原理
  • LVDS接口总结--(5)IDELAY3仿真
  • CEF132 编译指南 Linux 篇 - 开启 CEF 之旅:框架概览(一)
  • 微信小程序的请求函数封装(ts版本,uniapp开发)
  • 【电路笔记】-双向计数器
  • 【VUE】前端工程化与前端工程化与webpack
  • css简介
  • 哈希表(C语言版)
  • 【stm32】定时器输出PWM波形(hal库)
  • Qt的QPushButton样式设置
  • 半遮挡检测算法 Detecting Binocular Half-Occlusions
  • 19.4.2 -19.4.4 新增、修改、删除数据