此外还有别的模块 本模块是 其中一个
`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*200localparam 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 - 127reg [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 ) beginif(!ui_rst_n)flag <= 0;else if(app_wr_addr == ADDR_AMX >> 2)flag <= 1;elseflag <= flag;
end//----三段式状态机。一 。将次态赋值给现态
always @(posedge ui_clk ) beginif(!ui_rst_n)c_state <= IDLE;elsec_state <= n_state;
end//----三段式状态机。二 。状态跳转描述
always @(*) beginif(!ui_rst_n)n_state = IDLE;else begincase (c_state)IDLE : beginif(wf_data_count > FIFO_BURST_LEN)n_state = WR_DATA;else if(rf_data_count < FIFO_BURST_LEN && flag)n_state = RD_DATA;elsen_state = IDLE;endWR_DATA : beginif(app_en && app_rdy && cnt_addr == FIFO_BURST_LEN - 1)n_state = IDLE;elsen_state = WR_DATA;endRD_DATA : beginif(app_en && app_rdy && cnt_addr == FIFO_BURST_LEN - 1)n_state = IDLE;elsen_state = RD_DATA;enddefault: n_state = IDLE;endcaseend
end//----三段式状态机。三 。对中间变量及输出结果赋值
always @(posedge ui_clk ) beginif(!ui_rst_n)rf_rd_req <= 0;else if(rf_data_count > 100)rf_rd_req <= 1;elserf_rd_req <= rf_rd_req;
endalways @(posedge ui_clk ) beginif(!ui_rst_n)app_wr_addr <= 0;else if(c_state == WR_DATA && app_en && app_rdy)beginif(app_wr_addr == ADDR_AMX - 8) //固定突发长度:8app_wr_addr <= 0;elseapp_wr_addr <= app_wr_addr + 8;endelseapp_wr_addr <= app_wr_addr;
endalways @(posedge ui_clk ) beginif(!ui_rst_n)app_rd_addr <= 0;else if(c_state == RD_DATA && app_en && app_rdy)beginif(app_rd_addr == ADDR_AMX - 8) //固定突发长度:8app_rd_addr <= 0;elseapp_rd_addr <= app_rd_addr + 8;endelseapp_rd_addr <= app_rd_addr;
endalways @(posedge ui_clk ) beginif(!ui_rst_n)app_cmd <= 0;else if(c_state == WR_DATA)app_cmd <= 0;else if(c_state == RD_DATA)app_cmd <= 1;elseapp_cmd <= app_cmd;
endalways @(posedge ui_clk ) beginif(!ui_rst_n)app_en <= 0;else if(c_state == WR_DATA || c_state == RD_DATA)beginif(cnt_addr == FIFO_BURST_LEN - 1 && app_rdy)app_en <= 0;elseapp_en <= 1;endelseapp_en <= 0;
endalways @(posedge ui_clk ) beginif(!ui_rst_n)app_wdf_wren <= 0;else if(c_state == WR_DATA && app_wdf_rdy)beginif(cnt_wr_data == FIFO_BURST_LEN - 1 )app_wdf_wren <= 0;elseapp_wdf_wren <= 1;endelseapp_wdf_wren <= 0;
endalways @(posedge ui_clk ) beginif(!ui_rst_n)cnt_wr_data <= 0;else if(c_state == WR_DATA)beginif(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;elsecnt_wr_data <= cnt_wr_data;endelsecnt_wr_data <= 0;
endwf_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