SATA3和M.2接口的固态 玩绝地求生放固态硬盘差别大吗

403 Forbidden
403 Forbidden基于FPGA的DDR3 SDRAM控制器用户接口设计 | 电子创新网赛灵思中文社区1168人阅读
上一篇讲到了通过Zynq内部FPGA采集ov7725摄像头的图像数据,并将RAW8视频数据通过双线性插值法恢复为RGB888视频格式,这一篇的内容就是将RBG888视频数据通过PS的HP端口传送到DDR3进行视频缓存,然后再读出,进行VGA视频显示
AMBA协议简介
AMBA 协议是用于连接和管理片上系统 (SoC) 中功能模块的开放标准和片上互连规范。
它有助于首次开发带有大量控制器和外设的多处理器设计。
AMBA 通过使用 AXI、AHB、APB 和 ATB 的规范对 SoC 模块的共同主干进行定义,这有助于设计的重复使用。
AMBA 4 是最新增添到 AMBA 系列中的规范,增加了三个新接口协议:AXI4 有助于最大化性能和能效;AXI4-Lite 和 AXI4-Stream 是 FPGA 中实现的理想选择。
AMBA 4 规范在 AMBA 3 规范的基础上另外新增了三个接口协议。
AXI4 协议是对 AXI3 的更新,在用于多个主接口时,可提高互连的性能和利用率。它包括以下增强功能:
对于突发长度,最多支持 256 位
发送服务质量信号
支持多区域接口
AXI4-Lite 是 AXI4 协议的子协议,适用于与组件中更简单且更小的控件寄存器式的接口通信。AXI4-Lite 接口的主要功能如下:
所有事务的突发长度均为 1
所有数据存取的大小均与数据总线的宽度相同
不支持独占访问
AXI4-Stream
AXI4-Stream 协议可用于从主接口到辅助接口的单向数据传输,可显著降低信号路由速率。该协议的主要功能如下:
使用同一组共享线支持单数据流和多数据流
在同一互连内支持多个数据宽度
FPGA 中实现的理想选择
Zynq内部 PL与PS数据交互,主要使用了AXI4 AXI4-Lite总线协议,AXI4主要进行PL,PS之间批量数据交互,AXI4-Lite总线主要用于控制协议以及小量数据交互。由于FPGA采集到的摄像头视频数据要传送到PS部分的DDR,数据量较大,则可以直接通过AXI4总线将数据传送到PS部分,Xilinx的开发工具提供DMA,VDMA等IP Core可以很方便的完成这类任务,而且功能完善,缺点是如果发生问题,调试不太方便,毕竟对于用户来说就是个黑盒子,本设计没有使用IP,而是写了一个简单的S2MM和MM2S的HDL
BLOCK DESIGN&
PS部分用到了一个GP0口,一个HP0口,一个HP2口。GP口用于控制VDMA,HP口用于视频数据传输。看到这,也许有人会问,
1.为什么要用两个HP口,用一个不也行吗
用一个HP口确实可以,这里面只是为了区分清楚数据流向,所以用了两个HP口,一个只用于写,一个只用于读
2.为什么不用HP0和HP1,而是用HP0和HP2
还是那句话,用HP0和HP1确实也可以,但是在PS内部,HP0和HP1在通往DDR的路上是公用一个端口,HP2和HP3也是公用一个端口,所以也是为了区分清楚数据流向(或者可以说笔者有洁癖)所以才分开使用
3.为什么不直接通过HP端口读写,还要加入interconnect做什么
由于ps部分的HP口是AXI3协议,直接读写也没问题,但是为了规范,则通过interconnect将AXI3转换为AXI4
4.为什么使用axi_apb_bridge
axi_lite总线读写稍微有点儿小麻烦,所以转换成比较简单的apb总线
S2MM VDMA设计
block design中axi_interconnect_1 slave端口设置为WRITE ONLY 模块axi4_s2mm_video_dma通过这个端口对DDR进行写操作。
写操作流程图:
写操作burst时序图:
axi4_s2mm_video_dma模块就是按照时序图来实现的,下面对此模块进行一下讲述
模块端口如下:
下面是参数部分:
parameter&[31:0]&&APB_BASE_ADDR&&=&32'h,&&parameter&[31:0]&&DMA_DEST_ADDR0&=&32'h1c000000,&&parameter&[31:0]&&DMA_DEST_ADDR1&=&32'h1c200000,&&parameter&[31:0]&&DMA_DEST_ADDR2&=&32'h1c400000,&&parameter&[8:0]&&&C_DATA_WIDTH&=&9'd32,&&parameter&[12:0]&&STRIDE&&&&&&&=&13'd1920,&&parameter&[12:0]&&WIDTH&&&&&&&&=&13'd1920,&&parameter&[12:0]&&HEIGHT&&&&&&&=&13'd1080&&
parameter [31:0]
APB_BASE_ADDR
= 32'h,
parameter [31:0]
DMA_DEST_ADDR0 = 32'h1c000000,
parameter [31:0]
DMA_DEST_ADDR1 = 32'h1c200000,
parameter [31:0]
DMA_DEST_ADDR2 = 32'h1c400000,
parameter [8:0]
C_DATA_WIDTH = 9'd32,
parameter [12:0]
= 13'd1920,
parameter [12:0]
= 13'd1920,
parameter [12:0]
= 13'd1080
APB_BASE_ADDR : apb slave地址
DMA_DEST_ADDR0 : 传送目标地址0
DMA_DEST_ADDR1 : 传送目标地址1
DMA_DEST_ADDR2 : 传送目标地址2
端口包括 AXI4总线信号,APB总线信号,video信号
APB总线的使用:通过简单的修改代码,可以让ARM控制VDMA进行一帧图像的传输,传输完成以后自动停止,并在IRQ_F2P_pin引脚产生一个中断信号,此信号可以连接到PS的中断控制器,PS在接收到中断以后,向中断寄存器写1就可清除中断标志。
但Zedboard ov7725工程中并没有使用单帧传输模式,而是连续传输,如
reg&[1:0]&DMA_WRITE_STATUS;&&assign&IRQ_F2P_pin&=&DMA_WRITE_STATUS[1];&&//&write&dma&busy&status&configuration&&always&@(posedge&M_APB_PCLK_pin)&&begin&&&&&if&(!M_APB_PRESETN_pin)&begin&&&&&&&&DMA_WRITE_STATUS[0]&&=&1'b0;&&&&&end&&&&&else&if(dma_frame_write_end)&begin&&&&&&&&DMA_WRITE_STATUS[0]&&=&1'b0;&&&&&end&&&&&else&if(M_APB_PSEL_pin&&&&M_APB_PWRITE_pin&&&&M_APB_PENABLE_pin)&begin&&&&&&&&if&(M_APB_PADDR_pin==APB_BASE_ADDR&&&&M_APB_PWDATA_pin[0]&&&&!DMA_WRITE_STATUS[0])&begin&&&&&&&&&&&DMA_WRITE_STATUS[0]&&=&1'b1;&&&&&&&&end&&&&&end&&end&&
reg [1:0] DMA_WRITE_STATUS;
assign IRQ_F2P_pin = DMA_WRITE_STATUS[1];
// write dma busy status configuration
always @(posedge M_APB_PCLK_pin)
if (!M_APB_PRESETN_pin) begin
DMA_WRITE_STATUS[0] &= 1'b0;
else if(dma_frame_write_end) begin
DMA_WRITE_STATUS[0] &= 1'b0;
else if(M_APB_PSEL_pin && M_APB_PWRITE_pin && M_APB_PENABLE_pin) begin
if (M_APB_PADDR_pin==APB_BASE_ADDR && M_APB_PWDATA_pin[0] && !DMA_WRITE_STATUS[0]) begin
DMA_WRITE_STATUS[0] &= 1'b1;
wire&dma_write_&&reg&process_start_&&always&@(posedge&v_video_clk)&&&&&begin&&&&&&if(!axi_rstn)&&&&&&begin&&&&&&&&&&v_video_data_r&&=&24'd0;&&&&&&&&&&v_timing_vsync_r&&=&1'b0;&&&&&&&&&&v_timing_hsync_r&&=&1'b0;&&&&&&&&&&v_timing_active_video_r&&=&1'b0;&&&&&&&&&&process_start&&=&1'b0;&&&&&&&&&&//process_start_pre&&=&1'b0;&&&&&&&&&&process_start_pre&&=&1'b1;&&&&&&end&&&&&&else&&&&&&begin&&&&&&&&&&v_video_data_r&&=&v_video_data_i;&&&&&&&&&&v_timing_vsync_r&&=&v_timing_vsync_i;&&&&&&&&&&v_timing_hsync_r&&=&v_timing_hsync_i;&&&&&&&&&&v_timing_active_video_r&&=&v_timing_active_video_i;&&&&&&&&&&if(dma_write_start)&&&&&&&&&&&&&&process_start_pre&&=&1'b1;&&&&&&&&&&if((~v_timing_vsync_r)&&&&v_timing_vsync_i&&&&process_start_pre)begin&&&&&&&&&&&&&&process_start&&=&1'b1;&&&&&&&&&&&&&&//process_start_pre&&=&1'b0;&&&&&&&&&&end&&&&&&&&&&else&if(dma_frame_write_end)&&&&&&&&&&&&&&process_start&&=&1'b0;&&&&&&end&&end&&
wire dma_write_
reg process_start_
always @(posedge v_video_clk)
if(!axi_rstn)
v_video_data_r &= 24'd0;
v_timing_vsync_r &= 1'b0;
v_timing_hsync_r &= 1'b0;
v_timing_active_video_r &= 1'b0;
process_start &= 1'b0;
//process_start_pre &= 1'b0;
process_start_pre &= 1'b1;
v_video_data_r &= v_video_data_i;
v_timing_vsync_r &= v_timing_vsync_i;
v_timing_hsync_r &= v_timing_hsync_i;
v_timing_active_video_r &= v_timing_active_video_i;
if(dma_write_start)
process_start_pre &= 1'b1;
if((~v_timing_vsync_r) && v_timing_vsync_i && process_start_pre)begin
process_start &= 1'b1;
//process_start_pre &= 1'b0;
else if(dma_frame_write_end)
process_start &= 1'b0;
cross_clk&cross_clk1&&&&&(&&&&&&&&.clkin&&&(axi_clk),&&&&&&&&.din&&&&&(frame_last),&&&&&&&&.clkout&&(v_video_clk),&&&&&&&&.dout&&&&(dma_frame_write_end)&&&&&);&&
cross_clk cross_clk1
(axi_clk),
(frame_last),
(v_video_clk),
(dma_frame_write_end)
cross_clk&cross_clk2&&&&&(&&&&&&&&.clkin&&&(M_APB_PCLK_pin),&&&&&&&&.din&&&&&(DMA_WRITE_STATUS[0]),&&&&&&&&.clkout&&(v_video_clk),&&&&&&&&.dout&&&&(dma_write_start)&&&&&);&&
cross_clk cross_clk2
(M_APB_PCLK_pin),
(DMA_WRITE_STATUS[0]),
(v_video_clk),
(dma_write_start)
如果想使用单帧模式,可以把上面代码中注释的部分process_start_pre信号稍加修改即可。
在VIDEO信号中,真正起作用的只有3个信号
v_timing_vsync_i 此信号的上升沿代表一帧数据开始,这个信号可以用来做AXI写操作开始信号
v_timing_active_video_i 视频数据有效信号,只有有效的视频信号才会被传输
v_video_data_i 24bit RGB888视频信号
在视频信号与AXI信号之间加入一个位宽32bit,深度128的fifo进行数据缓存,视频数据写fifo,AXI总线读fifo。在fifo的应用上面,有一点是需要注意的,那就是rd_en读使能信号,rd_en拉高,并且在读时钟的下一个上升沿fifo内的数据才会出现在dout信号线上。根据AXI协议规范,为了防止产生死锁,WVALID不能等待WREADY,而WREADY可以等待WVALID,这样便会在写操作的时候出现一个问题,就是WVALID拉高,但是此时WREADY不一定是拉高的,而WREADY又控制着fifo
rd_en何时拉高,笔者的解决办法就是,在WVALID拉高以后,rd_en拉高一个时钟周期然后拉低,这样在下一个读时钟的上升沿,fifo内的数据就出现在dout信号线上了,然后等待着WREADY,具体实现可以看我的代码,信号stall就是做这个用处的。
还有一个需要注意的地方,由于这个是个人写的简单VDMA,burst长度是固定的为16,所以传输数据的长度必须是16的整数倍,而且传输位宽是32bit。
别的就不说了,就是用状态机来实现AXI时序罢了,直接上代码
/*-----------------------------------------------------------------------&&&&CONFIDENTIAL&IN&CONFIDENCE&&This&confidential&and&proprietary&software&may&be&only&used&as&authorized&&by&a&licensing&agreement&from&EEPROM&.&&In&the&event&of&publication,&the&following&notice&is&applicable:&&Copyright&(C)&2013-20xx&EEPROM&Corporation&&The&entire&notice&above&must&be&reproduced&on&all&authorized&copies.&&Author&&&&&&&&&&&&&&:&&&&&&&EEPROM&&Technology&blogs&&&&:&&&&&&&http://blog.csdn.net/zhangyu_eeprom&&Email&Address&&&&&&&:&&&&&&&&&Filename&&&&&&&&&&&&:&&&&&&&axi4_s2mm_video_dma.v&&Data&&&&&&&&&&&&&&&&:&&&&&&&&&Description&&&&&&&&&:&&&&&&&axi4_s2mm_video_dma.&&Modification&History&&&&:&&Data&&&&&&&&&&&&By&&&&&&&&&&Version&&&&&&&&&Change&Description&&=========================================================================&&-------------------------------------------------------------------------&&&&&&&&&&&&------&&&&&------&&&&------|&&&------|&&&&&&/-------\&&&&&&&&&&&&|&&&&&&&&&&|&&&&&&&&&&|&&&&&|&&&|&&&&&|&&&&&/&&&&&&&&&\&&&&&&/-\&&&&&/-\&&&&&&&&&|------&&&&|------&&&&|-----|&&&|-----|&&&&/&&&&&&&&&&&\&&&&/&&&\&&&/&&&\&&&&&&&&&|&&&&&&&&&&|&&&&&&&&&&|&&&&&&&&&|&\&&&&&&&&\&&&&&&&&&&&/&&&/&&&&&\_/&&&&&\&&&&&&&&&|------&&&&|------&&&&|&&&&&&&&&|&&\&&&&&&&&\&&&&&&&&&/&&&/&&&&&&&&&&&&&&&\&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&|&&&&&&&&&|&&&\&&&&&&&&\-------/&&-----------------------------------------------------------------------*/&&&&&&&&&module&axi4_s2mm_video_dma&#(&&&&&parameter&[31:0]&&APB_BASE_ADDR&&=&32'h,&&&&&parameter&[31:0]&&DMA_DEST_ADDR0&=&32'h1c000000,&&&&&parameter&[31:0]&&DMA_DEST_ADDR1&=&32'h1c200000,&&&&&parameter&[31:0]&&DMA_DEST_ADDR2&=&32'h1c400000,&&&&&parameter&[8:0]&&&C_DATA_WIDTH&=&9'd32,&&&&&parameter&[12:0]&&STRIDE&&&&&&&=&13'd1920,&&&&&parameter&[12:0]&&WIDTH&&&&&&&&=&13'd1920,&&&&&parameter&[12:0]&&HEIGHT&&&&&&&=&13'd1080&&&&&)&&&&&(&&&&&input&&&&&&&&&&&&&axi_clk,&&&&&input&&&&&&&&&&&&&axi_rstn,&&&&&output&&&&&&&&&&&&IRQ_F2P_pin,&&&&&&&&&&&&&&&&&input&&&&&&&&&&&&&M_APB_PCLK_pin,&&&&&input&&&&&&&&&&&&&M_APB_PRESETN_pin,&&&&&input&&&[31:0]&&&&M_APB_PADDR_pin,&&&&&input&&&&&&&&&&&&&M_APB_PSEL_pin,&&&&&input&&&&&&&&&&&&&M_APB_PENABLE_pin,&&&&&input&&&&&&&&&&&&&M_APB_PWRITE_pin,&&&&&input&&&[31:0]&&&&M_APB_PWDATA_pin,&&&&&output&&&&&&&&&&&&M_APB_PREADY_pin,&&&&&output&[31:0]&&&&&M_APB_PRDATA_pin,&&&&&output&&&&&&&&&&&&M_APB_PSLVERR_pin,&&&&&&&&&&input&&&&&&&&&&&&v_video_clk,&&&&&&&&&&&input&&&&&&&&&&&&v_timing_hsync_i,&&&&&input&&&&&&&&&&&&v_timing_vsync_i,&&&&&input&&&&&&&&&&&&v_timing_hblank_i,&&&&&input&&&&&&&&&&&&v_timing_vblank_i,&&&&&input&&&&&&&&&&&&v_timing_active_video_i,&&&&&input&&&[23:0]&&&v_video_data_i,&&&&&&&&&&&input&&&&&&&&&&&&&S_AXI_AWREADY_pin,&&&&&input&&&&&&&&&&&&&S_AXI_BVALID_pin,&&&&&input&&&&&&&&&&&&&S_AXI_WREADY_pin,&&&&&input&&&[1:0]&&&&&S_AXI_BRESP_pin,&&&&&input&&&[5:0]&&&&&S_AXI_BID_pin,&&&&&output&reg&&&&&&&&S_AXI_AWVALID_pin,&&&&&output&&&&&&&&&&&&S_AXI_BREADY_pin,&&&&&output&&&&&&&&&&&&S_AXI_WLAST_pin,&&&&&output&reg&&&&&&&&S_AXI_WVALID_pin,&&&&&output&[1:0]&&&&&&S_AXI_AWBURST_pin,&&&&&output&[1:0]&&&&&&S_AXI_AWLOCK_pin,&&&&&output&[2:0]&&&&&&S_AXI_AWSIZE_pin,&&&&&output&[2:0]&&&&&&S_AXI_AWPROT_pin,&&&&&output&reg&[31:0]&S_AXI_AWADDR_pin,&&&&&output&reg&[C_DATA_WIDTH-1:0]&&&&&S_AXI_WDATA_pin,&&&&&output&[3:0]&&&&&&S_AXI_AWCACHE_pin,&&&&&output&[3:0]&&&&&&S_AXI_AWLEN_pin,&&&&&output&[3:0]&&&&&&S_AXI_AWQOS_pin,&&&&&output&[7:0]&&&&&&S_AXI_WSTRB_pin,&&&&&output&[5:0]&&&&&&S_AXI_AWID_pin,&&&&&output&[5:0]&&&&&&S_AXI_WID_pin&&&&&);&&/******************************************/&&&&&reg&[23:0]&&&v_video_data_r;&&reg&&&&&&&&&&v_timing_vsync_r;&&reg&&&&&&&&&&v_timing_active_video_r;&&reg&&&&&&&&&&process_&//&first&vsync&rising&&reg&&&&&&&&&&[1:0]frame_&&wire&&&&&&&&&line_&&wire&&&&&&&&&frame_&&reg&&&&&&&&&&frame_last_r;&&reg&&&&&&&&&&[12:0]&&reg&&&&&&&&&&[12:0]&&reg&&&&&&&&&&[4:0]axi_write_&&reg&&&&&&&&&&axi_write_&&reg&&&&&&&&&&axi_addr_&&reg&&&&&&&&&&[31:0]prev_line_&&wire&&&&&&&&&&&reg&&&&&&&&&&[4:0]read_fifo_&&reg&&&&&&&&&&fifo_rd_&&wire&&&&&&&&&dma_frame_write_&&wire&&&&&&&&&dma_line_write_&&reg&&&&&&&&&&v_timing_hsync_r;&&reg&&&&&&&&&&[12:0]write_fifo_&&/************fifo**************/&&reg&&&fifo_wr_&&wire&&fifo_rd_&&wire&&fifo_&&wire&&fifo_&&wire&&fifo_&&wire&&[9:0]&fifo_rd_data_&&wire&&[9:0]&fifo_wr_data_&&wire&&[31:0]&fifo_&&/******************************/&&/******************************/&&&&/*&&*&APB&bus&&*/&&reg&[1:0]&DMA_WRITE_STATUS;&&assign&IRQ_F2P_pin&=&DMA_WRITE_STATUS[1];&&//&write&dma&busy&status&configuration&&always&@(posedge&M_APB_PCLK_pin)&&begin&&&&&if&(!M_APB_PRESETN_pin)&begin&&&&&&&&DMA_WRITE_STATUS[0]&&=&1'b0;&&&&&end&&&&&else&if(dma_frame_write_end)&begin&&&&&&&&DMA_WRITE_STATUS[0]&&=&1'b0;&&&&&end&&&&&else&if(M_APB_PSEL_pin&&&&M_APB_PWRITE_pin&&&&M_APB_PENABLE_pin)&begin&&&&&&&&if&(M_APB_PADDR_pin==APB_BASE_ADDR&&&&M_APB_PWDATA_pin[0]&&&&!DMA_WRITE_STATUS[0])&begin&&&&&&&&&&&DMA_WRITE_STATUS[0]&&=&1'b1;&&&&&&&&end&&&&&end&&end&&//&write&dma&interrupt&configuration,&write&'1'&to&clear&interrupt&&always&@(posedge&M_APB_PCLK_pin)&&begin&&&&&if&(!M_APB_PRESETN_pin)&begin&&&&&&&&DMA_WRITE_STATUS[1]&&=&1'b0;&&&&&end&&&&&else&if(dma_frame_write_end)&begin&&&&&&&&DMA_WRITE_STATUS[1]&&=&1'b1;&&&&&end&&&&&else&if(M_APB_PSEL_pin&&&&M_APB_PWRITE_pin&&&&M_APB_PENABLE_pin)&begin&&&&&&&&if&(M_APB_PADDR_pin==APB_BASE_ADDR&&&&M_APB_PWDATA_pin[1]&&&&DMA_WRITE_STATUS[1])&begin&&&&&&&&&&&DMA_WRITE_STATUS[1]&&=&1'b0;&&&&&&&&end&&&&&end&&end&&//------------------------------------------------------&&//&APB&output&&//------------------------------------------------------&&assign&M_APB_PRDATA_pin&=&{28'h0000,frame_num,DMA_WRITE_STATUS};&&assign&M_APB_PREADY_pin&=&1'b1;&&assign&M_APB_PSLVERR_pin&=&1'b0;&&&&&&&/*******************************************/&&&&&wire&dma_write_&&reg&process_start_&&always&@(posedge&v_video_clk)&&&&&begin&&&&&&if(!axi_rstn)&&&&&&begin&&&&&&&&&&v_video_data_r&&=&24'd0;&&&&&&&&&&v_timing_vsync_r&&=&1'b0;&&&&&&&&&&v_timing_hsync_r&&=&1'b0;&&&&&&&&&&v_timing_active_video_r&&=&1'b0;&&&&&&&&&&process_start&&=&1'b0;&&&&&&&&&&//process_start_pre&&=&1'b0;&&&&&&&&&&process_start_pre&&=&1'b1;&&&&&&end&&&&&&else&&&&&&begin&&&&&&&&&&v_video_data_r&&=&v_video_data_i;&&&&&&&&&&v_timing_vsync_r&&=&v_timing_vsync_i;&&&&&&&&&&v_timing_hsync_r&&=&v_timing_hsync_i;&&&&&&&&&&v_timing_active_video_r&&=&v_timing_active_video_i;&&&&&&&&&&if(dma_write_start)&&&&&&&&&&&&&&process_start_pre&&=&1'b1;&&&&&&&&&&if((~v_timing_vsync_r)&&&&v_timing_vsync_i&&&&process_start_pre)begin&&&&&&&&&&&&&&process_start&&=&1'b1;&&&&&&&&&&&&&&//process_start_pre&&=&1'b0;&&&&&&&&&&end&&&&&&&&&&else&if(dma_frame_write_end)&&&&&&&&&&&&&&process_start&&=&1'b0;&&&&&&end&&end&&cross_clk&cross_clk1&&&&&(&&&&&&&&.clkin&&&(axi_clk),&&&&&&&&.din&&&&&(frame_last),&&&&&&&&.clkout&&(v_video_clk),&&&&&&&&.dout&&&&(dma_frame_write_end)&&&&&);&&cross_clk&cross_clk2&&&&&(&&&&&&&&.clkin&&&(M_APB_PCLK_pin),&&&&&&&&.din&&&&&(DMA_WRITE_STATUS[0]),&&&&&&&&.clkout&&(v_video_clk),&&&&&&&&.dout&&&&(dma_write_start)&&&&&);&&always&@(posedge&v_video_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&write_fifo_num&&&&=&13'h0;&&&&&&else&if(fifo_wr_en&&&&(write_fifo_num&!=&(WIDTH&-&1)))&&&&&&&&&&write_fifo_num&&&&=&write_fifo_num&+&1;&&&&&&else&if(fifo_wr_en&&&&(write_fifo_num&==&(WIDTH&-&1)))&&&&&&&&&&write_fifo_num&&&&=&13'h0;&&end&&always&@(posedge&v_video_clk)&&begin&&&&&&if(!axi_rstn)begin&&&&&&&&&&fifo_wr_en&=&1'b0;&&&&&&end&&&&&&else&begin&&&&&&if((fifo_wr_en&==&1'b0)&&&&process_start&&&&v_timing_active_video_i&&&&(write_fifo_num&!=&(WIDTH&-&1)))&&&&&&&&&&fifo_wr_en&=&1'b1;&&&&&&else&if(write_fifo_num&==&(WIDTH&-&1))&&&&&&&&&&fifo_wr_en&=&1'b0;&&&&&&else&if(!process_start)&&&&&&&&&&fifo_wr_en&=&1'b0;&&&&&&end&&end&&&&fifo_axi32bit&u_fifo_axi32bit&(&&&&.wr_clk(v_video_clk),&&&&&&&&&&&&&&&&&&&.rd_clk(axi_clk),&&&&&&&&&&&&&&&&&&&&&.din({v_video_data_r,8'h00}),&&&&&&&&&&&&&&&&&&&.wr_en(fifo_wr_en),&&&&&&&&&&&&&&&&&&&&&.rd_en(fifo_rd_en),&&&&&&&&&&&&&&&&&&&&&.dout(fifo_dout),&&&&&&&&&&&&&&&&&&&&&&&.full(fifo_full),&&&&&&&&&&&&&&&&&&&&&&&.empty(fifo_empty),&&&&&&&&&&&&&&&&&&&&&.valid(fifo_valid),&&&&&&&&&&&&&&&&&&&&&.rd_data_count(fifo_rd_data_count),&&&&&.wr_data_count(fifo_wr_data_count)&&&&);&&&&&//------------------------------------------------------&&&&&//&AXI&bus&&&&&//------------------------------------------------------&&assign&S_AXI_AWID_pin&&&&&&=&6'b000000;&&assign&S_AXI_AWLEN_pin&&&&&=&4'&&&&&//burst&length:&16&&assign&S_AXI_AWSIZE_pin&&&&=&3'b010;&&&//size:&4byte&&&&&&&assign&S_AXI_AWBURST_pin&&&=&2'b01;&&&&//incr&&&&&&&&&&&&&&assign&S_AXI_AWLOCK_pin&&&&=&2'b00;&&assign&S_AXI_AWCACHE_pin&&&=&4'b0011;&////&&assign&S_AXI_AWPROT_pin&&&&=&3'b000;&&assign&S_AXI_AWQOS_pin&&&&&=&4'b0000;&&assign&S_AXI_BREADY_pin&&&&=&1'b1;&&assign&S_AXI_WSTRB_pin&&&&&=&8'b;&&assign&S_AXI_WID_pin&&&&&&&=&0;&&&&&&&&parameter&&&IDLE&&&&&&&&=&4'b0000;&&parameter&&&CHECK_FIFO&&=&4'b0001;&&parameter&&&AXI_WRITE&&&=&4'b0011;&&parameter&&&NEXT_WRITE&&=&4'b0111;&&parameter&&&NEXT_LINE&&&=&4'b1111;&&parameter&&&NEXT_FRAME&&=&4'b1110;&&parameter&&&FINISH&&&&&&=&4'b1100;&&&&reg&[3:0]w_&&reg&[3:0]w_&&&&&&&&&always&@(posedge&axi_clk)&&begin&&&&&&if(!axi_rstn)&&&&&&begin&&&&&&&&&&w_cs&&=&IDLE;&&&&&&end&&&&&&else&&&&&&begin&&&&&&&&&&w_cs&&=&w_&&&&&&end&&end&&&&always&@(*)&begin&&&&&&case(w_cs)&&&&&&&&&&IDLE:&begin&&&&&&&&&&&&&&if(process_start)&&&&&&&&&&&&&&&&&&w_ns&&=&CHECK_FIFO;&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&w_ns&&=&w_&&&&&&&&&&end&&&&&&&&&&CHECK_FIFO:&begin&&&&&&&&&&&&&&if(fifo_rd_data_count&&=&10'h10)&&&&&&&&&&&&&&&&&&w_ns&&=&AXI_WRITE;&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&w_ns&&=&w_&&&&&&&&&&end&&&&&&&&&&AXI_WRITE:&begin&&&&&&&&&&&&&&if(axi_addr_ok&&&&axi_write_ok&&&&~line_last)&&&&&&&&&&&&&&&&&&w_ns&&=&NEXT_WRITE;&&&&&&&&&&&&&&else&if(axi_addr_ok&&&&axi_write_ok&&&&line_last&&&&~frame_last)&&&&&&&&&&&&&&&&&&w_ns&&=&NEXT_LINE;&&&&&&&&&&&&&&else&if(axi_addr_ok&&&&axi_write_ok&&&&line_last&&&&frame_last)&&&&&&&&&&&&&&&&&&w_ns&&=&NEXT_FRAME;&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&w_ns&&=&w_&&&&&&&&&&end&&&&&&&&&&NEXT_WRITE:&begin&&&&&&&&&&&&&&w_ns&&=&CHECK_FIFO;&&&&&&&&&&end&&&&&&&&&&NEXT_LINE:&begin&&&&&&&&&&&&&&w_ns&&=&CHECK_FIFO;&&&&&&&&&&end&&&&&&&&&&NEXT_FRAME:&begin&//&pro&&&&&&&&&&&&&&if(frame_num&&&32'h11)&&&&&&&&&&&&&&&&&&w_ns&&=&CHECK_FIFO;&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&w_ns&&=&FINISH;&&&&&&&&&&end&&&&&&&&&&FINISH:&begin&&&&&&&&&&&&&&w_ns&&=&FINISH;&&&&&&&&&&end&&&&&&&&&&default:&begin&&&&&&&&&&&&&&w_ns&&=&w_&&&&&&&&&&end&&&&&&endcase&&end&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&begin&&&&&&&&&&read_fifo_num&&&&&=&5'h0;&&&&&&&&&&fifo_rd_ok&&&&&&&=&1'b0;&&&&&&end&&&&&&else&if(w_ns&!=&AXI_WRITE)&begin&&&&&&&&&&read_fifo_num&&&&&=&5'h0;&&&&&&&&&&fifo_rd_ok&&&&&&&=&1'b0;&&&&&&end&&&&&&else&if(fifo_rd_en&&&&(read_fifo_num&!=&5'hf))&begin&&&&&&&&&&read_fifo_num&&&&&=&read_fifo_num&+&1;&&&&&&&&&&fifo_rd_ok&&&&&&&=&1'b0;&&&&&&end&&&&&&else&if(fifo_rd_en&&&&(read_fifo_num&==&5'hf))&begin&&&&&&&&&&read_fifo_num&&&&&=&5'h0;&&&&&&&&&&fifo_rd_ok&&&&&&&=&1'b1;&&&&&&end&&end&&assign&&fifo_rd_en&&&&&&=&(w_ns&==&AXI_WRITE&&&&~stall&&&&!fifo_rd_ok)?&1'b1&:&1'b0;&&assign&&stall&&&&&&&&&&&=&(w_cs&==&AXI_WRITE&&&&~axi_write_ok&&&&S_AXI_WVALID_pin&&&&~S_AXI_WREADY_pin)?&1'b1&:&1'b0;&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&begin&&&&&&&&&&S_AXI_AWVALID_pin&&=&1'b0;&&&&&&&&&&axi_addr_ok&&=&1'b0;&&&&&&end&&&&&&else&if(w_ns&==&AXI_WRITE&&&&w_cs&!=&AXI_WRITE)&begin&&&&&&&&&&S_AXI_AWVALID_pin&&=&1'b1;&&&&&&&&&&axi_addr_ok&&=&1'b0;&&&&&&end&&&&&&else&if(S_AXI_AWREADY_pin)&begin&&&&&&&&&&S_AXI_AWVALID_pin&&=&1'b0;&&&&&&&&&&axi_addr_ok&&=&1'b1;&&&&&&end&&end&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&S_AXI_WVALID_pin&&&=&1'b0;&&&&&&else&if((S_AXI_WREADY_pin&&&S_AXI_WVALID_pin)&&&&(axi_write_num&==&5'hf))&&&&&&&&&&S_AXI_WVALID_pin&&&=&1'b0;&&&&&&else&if(w_cs&==&AXI_WRITE&&&&~axi_write_ok)&&&&&&&&&&S_AXI_WVALID_pin&&&=&1'b1;&&end&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&S_AXI_WDATA_pin&&&&=&32'h0;&&&&&&else&if(!stall)&&&&&&&&&&S_AXI_WDATA_pin&&&&=&{fifo_dout[7:0],fifo_dout[15:8],fifo_dout[23:16],fifo_dout[31:24]};//{8'h33,8'h22,8'h11,8'h00};&&end&&wire&[31:0]&dma_tran_&&assign&dma_tran_addr&=&(frame_num&==&2'b00)?&DMA_DEST_ADDR0&:&(frame_num&==&2'b01)?&DMA_DEST_ADDR1&:&DMA_DEST_ADDR2;&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&S_AXI_AWADDR_pin&&&=&32'h0;&&&&&&else&if(w_cs&==&IDLE&&&&w_ns&==&CHECK_FIFO)&&&&&&&&&&S_AXI_AWADDR_pin&&&=&dma_tran_&&&&&&else&if(w_cs&==&NEXT_WRITE&&&&w_ns&==&CHECK_FIFO)&&&&&&&&&&S_AXI_AWADDR_pin&&&=&S_AXI_AWADDR_pin&+&8'h40;&//16&*&1byte&&&&&&else&if(w_cs&==&NEXT_LINE&&&&&w_ns&==&CHECK_FIFO)&&&&&&&&&&S_AXI_AWADDR_pin&&&=&prev_line_start&+&STRIDE;&&&&&&else&if(w_cs&==&NEXT_FRAME&&&&w_ns&==&CHECK_FIFO)&&&&&&&&&&S_AXI_AWADDR_pin&&&=&dma_tran_&&end&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&prev_line_start&&=&32'h0;&&&&&&else&if(w_cs&==&IDLE&&&&w_ns&==&CHECK_FIFO)&&&&&&&&&&prev_line_start&&=&dma_tran_&&&&&&else&if(w_cs&==&NEXT_LINE&&&&&w_ns&==&CHECK_FIFO)&&&&&&&&&&prev_line_start&&=&prev_line_start&+&STRIDE;&&&&&&else&if(w_cs&==&NEXT_FRAME&&&&w_ns&==&CHECK_FIFO)&&&&&&&&&&prev_line_start&&=&dma_tran_&&end&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&begin&&&&&&&&&&axi_write_num&&&&&=&5'h0;&&&&&&&&&&axi_write_ok&&&&&=&1'b0;&&&&&&end&&&&&&else&if(w_ns&!=&AXI_WRITE)&begin&&&&&&&&&&axi_write_num&&&&&=&5'h0;&&&&&&&&&&axi_write_ok&&&&&=&1'b0;&&&&&&end&&&&&&else&if((S_AXI_WREADY_pin&&&S_AXI_WVALID_pin)&&&&(axi_write_num&!=&5'hf))&begin&&&&&&&&&&axi_write_num&&&&&=&axi_write_num&+&1;&&&&&&&&&&axi_write_ok&&&&&=&1'b0;&&&&&&end&&&&&&else&if((S_AXI_WREADY_pin&&&S_AXI_WVALID_pin)&&&&(axi_write_num&==&5'hf))&begin&&&&&&&&&&axi_write_num&&&&&=&5'h0;&&&&&&&&&&axi_write_ok&&&&&=&1'b1;&&&&&&end&&end&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&frame_num&&&&&=&2'b00;&&&&&&else&if(process_start&&&&frame_last&&&&~frame_last_r)&&&&&&begin&&&&&&&&&&if(frame_num&!=&2'b10)&&&&&&&&&&&&&&frame_num&&&&&=&frame_num&+&1;&&&&&&&&&&else&&&&&&&&&&&&&&&frame_num&&&&&=&2'b00;&&&&&&end&&end&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&hcount&&&=&13'h0;&&&&&&else&if(w_ns&==&NEXT_LINE)&&&&&&&&&&hcount&&&=&13'h0;&&&&&&else&if(w_ns&==&NEXT_FRAME)&&&&&&&&&&hcount&&&=&13'h0;&&&&&&else&if(w_ns&==&NEXT_WRITE)&&&&&&&&&&hcount&&&=&hcount&+&16;&&end&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&vcount&&&=&13'h0;&&&&&&else&if(w_ns&==&NEXT_FRAME)&&&&&&&&&&vcount&&&=&13'h0;&&&&&&else&if(w_ns&==&NEXT_LINE)&&&&&&&&&&vcount&&&=&vcount&+&1;&&end&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&frame_last_r&&&&&=&1'b0;&&&&&&else&&&&&&&&&&frame_last_r&&&&&=&frame_&&end&&assign&&line_last&&&=&(hcount&==&(WIDTH&-&16)&)?&1'b1&:&1'b0;&&assign&&frame_last&&=&(vcount&==&(HEIGHT&-&1)&)?&1'b1&:&1'b0;&&&&assign&&S_AXI_WLAST_pin&&&=&(axi_write_num&==&5'hf)?&1'b1&:&1'b0;&&&&&&endmodule&&
/*-----------------------------------------------------------------------
CONFIDENTIAL IN CONFIDENCE
This confidential and proprietary software may be only used as authorized
by a licensing agreement from EEPROM .
In the event of publication, the following notice is applicable:
Copyright (C) 2013-20xx EEPROM Corporation
The entire notice above must be reproduced on all authorized copies.
Technology blogs
http://blog.csdn.net/zhangyu_eeprom
Email Address
axi4_s2mm_video_dma.v
Description
axi4_s2mm_video_dma.
Modification History :
Change Description
=========================================================================
-------------------------------------------------------------------------
-----------------------------------------------------------------------*/
module axi4_s2mm_video_dma #(
parameter [31:0]
APB_BASE_ADDR
= 32'h,
parameter [31:0]
DMA_DEST_ADDR0 = 32'h1c000000,
parameter [31:0]
DMA_DEST_ADDR1 = 32'h1c200000,
parameter [31:0]
DMA_DEST_ADDR2 = 32'h1c400000,
parameter [8:0]
C_DATA_WIDTH = 9'd32,
parameter [12:0]
= 13'd1920,
parameter [12:0]
= 13'd1920,
parameter [12:0]
= 13'd1080
IRQ_F2P_pin,
M_APB_PCLK_pin,
M_APB_PRESETN_pin,
M_APB_PADDR_pin,
M_APB_PSEL_pin,
M_APB_PENABLE_pin,
M_APB_PWRITE_pin,
M_APB_PWDATA_pin,
M_APB_PREADY_pin,
output [31:0]
M_APB_PRDATA_pin,
M_APB_PSLVERR_pin,
v_video_clk,
v_timing_hsync_i,
v_timing_vsync_i,
v_timing_hblank_i,
v_timing_vblank_i,
v_timing_active_video_i,
v_video_data_i,
S_AXI_AWREADY_pin,
S_AXI_BVALID_pin,
S_AXI_WREADY_pin,
S_AXI_BRESP_pin,
S_AXI_BID_pin,
output reg
S_AXI_AWVALID_pin,
S_AXI_BREADY_pin,
S_AXI_WLAST_pin,
output reg
S_AXI_WVALID_pin,
output [1:0]
S_AXI_AWBURST_pin,
output [1:0]
S_AXI_AWLOCK_pin,
output [2:0]
S_AXI_AWSIZE_pin,
output [2:0]
S_AXI_AWPROT_pin,
output reg [31:0] S_AXI_AWADDR_pin,
output reg [C_DATA_WIDTH-1:0]
S_AXI_WDATA_pin,
output [3:0]
S_AXI_AWCACHE_pin,
output [3:0]
S_AXI_AWLEN_pin,
output [3:0]
S_AXI_AWQOS_pin,
output [7:0]
S_AXI_WSTRB_pin,
output [5:0]
S_AXI_AWID_pin,
output [5:0]
S_AXI_WID_pin
/******************************************/
reg [23:0]
v_video_data_r;
v_timing_vsync_r;
v_timing_active_video_r;
process_ // first vsync rising
[1:0]frame_
frame_last_r;
[4:0]axi_write_
axi_write_
[31:0]prev_line_
[4:0]read_fifo_
dma_frame_write_
dma_line_write_
v_timing_hsync_r;
[12:0]write_fifo_
/************fifo**************/
[9:0] fifo_rd_data_
[9:0] fifo_wr_data_
[31:0] fifo_
/******************************/
/******************************/
reg [1:0] DMA_WRITE_STATUS;
assign IRQ_F2P_pin = DMA_WRITE_STATUS[1];
// write dma busy status configuration
always @(posedge M_APB_PCLK_pin)
if (!M_APB_PRESETN_pin) begin
DMA_WRITE_STATUS[0] &= 1'b0;
else if(dma_frame_write_end) begin
DMA_WRITE_STATUS[0] &= 1'b0;
else if(M_APB_PSEL_pin && M_APB_PWRITE_pin && M_APB_PENABLE_pin) begin
if (M_APB_PADDR_pin==APB_BASE_ADDR && M_APB_PWDATA_pin[0] && !DMA_WRITE_STATUS[0]) begin
DMA_WRITE_STATUS[0] &= 1'b1;
// write dma interrupt configuration, write '1' to clear interrupt
always @(posedge M_APB_PCLK_pin)
if (!M_APB_PRESETN_pin) begin
DMA_WRITE_STATUS[1] &= 1'b0;
else if(dma_frame_write_end) begin
DMA_WRITE_STATUS[1] &= 1'b1;
else if(M_APB_PSEL_pin && M_APB_PWRITE_pin && M_APB_PENABLE_pin) begin
if (M_APB_PADDR_pin==APB_BASE_ADDR && M_APB_PWDATA_pin[1] && DMA_WRITE_STATUS[1]) begin
DMA_WRITE_STATUS[1] &= 1'b0;
//------------------------------------------------------
// APB output
//------------------------------------------------------
assign M_APB_PRDATA_pin = {28'h0000,frame_num,DMA_WRITE_STATUS};
assign M_APB_PREADY_pin = 1'b1;
assign M_APB_PSLVERR_pin = 1'b0;
/*******************************************/
wire dma_write_
reg process_start_
always @(posedge v_video_clk)
if(!axi_rstn)
v_video_data_r &= 24'd0;
v_timing_vsync_r &= 1'b0;
v_timing_hsync_r &= 1'b0;
v_timing_active_video_r &= 1'b0;
process_start &= 1'b0;
//process_start_pre &= 1'b0;
process_start_pre &= 1'b1;
v_video_data_r &= v_video_data_i;
v_timing_vsync_r &= v_timing_vsync_i;
v_timing_hsync_r &= v_timing_hsync_i;
v_timing_active_video_r &= v_timing_active_video_i;
if(dma_write_start)
process_start_pre &= 1'b1;
if((~v_timing_vsync_r) && v_timing_vsync_i && process_start_pre)begin
process_start &= 1'b1;
//process_start_pre &= 1'b0;
else if(dma_frame_write_end)
process_start &= 1'b0;
cross_clk cross_clk1
(axi_clk),
(frame_last),
(v_video_clk),
(dma_frame_write_end)
cross_clk cross_clk2
(M_APB_PCLK_pin),
(DMA_WRITE_STATUS[0]),
(v_video_clk),
(dma_write_start)
always @(posedge v_video_clk) begin
if(!axi_rstn)
write_fifo_num
&= 13'h0;
else if(fifo_wr_en && (write_fifo_num != (WIDTH - 1)))
write_fifo_num
&= write_fifo_num + 1;
else if(fifo_wr_en && (write_fifo_num == (WIDTH - 1)))
write_fifo_num
&= 13'h0;
always @(posedge v_video_clk)
if(!axi_rstn)begin
fifo_wr_en = 1'b0;
else begin
if((fifo_wr_en == 1'b0) && process_start && v_timing_active_video_i && (write_fifo_num != (WIDTH - 1)))
fifo_wr_en = 1'b1;
else if(write_fifo_num == (WIDTH - 1))
fifo_wr_en = 1'b0;
else if(!process_start)
fifo_wr_en = 1'b0;
fifo_axi32bit u_fifo_axi32bit (
.wr_clk(v_video_clk),
.rd_clk(axi_clk),
.din({v_video_data_r,8'h00}),
.wr_en(fifo_wr_en),
.rd_en(fifo_rd_en),
.dout(fifo_dout),
.full(fifo_full),
.empty(fifo_empty),
.valid(fifo_valid),
.rd_data_count(fifo_rd_data_count),
.wr_data_count(fifo_wr_data_count)
//------------------------------------------------------
// AXI bus
//------------------------------------------------------
assign S_AXI_AWID_pin
= 6'b000000;
assign S_AXI_AWLEN_pin
//burst length: 16
assign S_AXI_AWSIZE_pin
= 3'b010;
//size: 4byte
assign S_AXI_AWBURST_pin
= 2'b01;
assign S_AXI_AWLOCK_pin
= 2'b00;
assign S_AXI_AWCACHE_pin
= 4'b0011; ////
assign S_AXI_AWPROT_pin
= 3'b000;
assign S_AXI_AWQOS_pin
= 4'b0000;
assign S_AXI_BREADY_pin
= 1'b1;
assign S_AXI_WSTRB_pin
= 8'b;
assign S_AXI_WID_pin
= 4'b0000;
CHECK_FIFO
= 4'b0001;
= 4'b0011;
NEXT_WRITE
= 4'b0111;
= 4'b1111;
NEXT_FRAME
= 4'b1110;
= 4'b1100;
reg [3:0]w_
reg [3:0]w_
always @(posedge axi_clk)
if(!axi_rstn)
w_cs &= IDLE;
w_cs &= w_
always @(*) begin
case(w_cs)
IDLE: begin
if(process_start)
= CHECK_FIFO;
CHECK_FIFO: begin
if(fifo_rd_data_count &= 10'h10)
= AXI_WRITE;
AXI_WRITE: begin
if(axi_addr_ok && axi_write_ok && ~line_last)
= NEXT_WRITE;
else if(axi_addr_ok && axi_write_ok && line_last && ~frame_last)
= NEXT_LINE;
else if(axi_addr_ok && axi_write_ok && line_last && frame_last)
= NEXT_FRAME;
NEXT_WRITE: begin
= CHECK_FIFO;
NEXT_LINE: begin
= CHECK_FIFO;
NEXT_FRAME: begin // pro
if(frame_num & 32'h11)
= CHECK_FIFO;
FINISH: begin
default: begin
always @(posedge axi_clk) begin
if(!axi_rstn) begin
read_fifo_num
&= 5'h0;
fifo_rd_ok
&= 1'b0;
else if(w_ns != AXI_WRITE) begin
read_fifo_num
&= 5'h0;
fifo_rd_ok
&= 1'b0;
else if(fifo_rd_en && (read_fifo_num != 5'hf)) begin
read_fifo_num
&= read_fifo_num + 1;
fifo_rd_ok
&= 1'b0;
else if(fifo_rd_en && (read_fifo_num == 5'hf)) begin
read_fifo_num
&= 5'h0;
fifo_rd_ok
&= 1'b1;
fifo_rd_en
= (w_ns == AXI_WRITE && ~stall && !fifo_rd_ok)? 1'b1 : 1'b0;
= (w_cs == AXI_WRITE && ~axi_write_ok && S_AXI_WVALID_pin && ~S_AXI_WREADY_pin)? 1'b1 : 1'b0;
always @(posedge axi_clk) begin
if(!axi_rstn) begin
S_AXI_AWVALID_pin &= 1'b0;
axi_addr_ok &= 1'b0;
else if(w_ns == AXI_WRITE && w_cs != AXI_WRITE) begin
S_AXI_AWVALID_pin &= 1'b1;
axi_addr_ok &= 1'b0;
else if(S_AXI_AWREADY_pin) begin
S_AXI_AWVALID_pin &= 1'b0;
axi_addr_ok &= 1'b1;
always @(posedge axi_clk) begin
if(!axi_rstn)
S_AXI_WVALID_pin
&= 1'b0;
else if((S_AXI_WREADY_pin & S_AXI_WVALID_pin) && (axi_write_num == 5'hf))
S_AXI_WVALID_pin
&= 1'b0;
else if(w_cs == AXI_WRITE && ~axi_write_ok)
S_AXI_WVALID_pin
&= 1'b1;
always @(posedge axi_clk) begin
if(!axi_rstn)
S_AXI_WDATA_pin
&= 32'h0;
else if(!stall)
S_AXI_WDATA_pin
&= {fifo_dout[7:0],fifo_dout[15:8],fifo_dout[23:16],fifo_dout[31:24]};//{8'h33,8'h22,8'h11,8'h00};
wire [31:0] dma_tran_
assign dma_tran_addr = (frame_num == 2'b00)? DMA_DEST_ADDR0 : (frame_num == 2'b01)? DMA_DEST_ADDR1 : DMA_DEST_ADDR2;
always @(posedge axi_clk) begin
if(!axi_rstn)
S_AXI_AWADDR_pin
&= 32'h0;
else if(w_cs == IDLE && w_ns == CHECK_FIFO)
S_AXI_AWADDR_pin
&= dma_tran_
else if(w_cs == NEXT_WRITE && w_ns == CHECK_FIFO)
S_AXI_AWADDR_pin
&= S_AXI_AWADDR_pin + 8'h40; //16 * 1byte
else if(w_cs == NEXT_LINE
&& w_ns == CHECK_FIFO)
S_AXI_AWADDR_pin
&= prev_line_start + STRIDE;
else if(w_cs == NEXT_FRAME && w_ns == CHECK_FIFO)
S_AXI_AWADDR_pin
&= dma_tran_
always @(posedge axi_clk) begin
if(!axi_rstn)
prev_line_start &= 32'h0;
else if(w_cs == IDLE && w_ns == CHECK_FIFO)
prev_line_start &= dma_tran_
else if(w_cs == NEXT_LINE
&& w_ns == CHECK_FIFO)
prev_line_start &= prev_line_start + STRIDE;
else if(w_cs == NEXT_FRAME && w_ns == CHECK_FIFO)
prev_line_start &= dma_tran_
always @(posedge axi_clk) begin
if(!axi_rstn) begin
axi_write_num
&= 5'h0;
axi_write_ok
&= 1'b0;
else if(w_ns != AXI_WRITE) begin
axi_write_num
&= 5'h0;
axi_write_ok
&= 1'b0;
else if((S_AXI_WREADY_pin & S_AXI_WVALID_pin) && (axi_write_num != 5'hf)) begin
axi_write_num
&= axi_write_num + 1;
axi_write_ok
&= 1'b0;
else if((S_AXI_WREADY_pin & S_AXI_WVALID_pin) && (axi_write_num == 5'hf)) begin
axi_write_num
&= 5'h0;
axi_write_ok
&= 1'b1;
always @(posedge axi_clk) begin
if(!axi_rstn)
&= 2'b00;
else if(process_start && frame_last && ~frame_last_r)
if(frame_num != 2'b10)
&= frame_num + 1;
&= 2'b00;
always @(posedge axi_clk) begin
if(!axi_rstn)
&= 13'h0;
else if(w_ns == NEXT_LINE)
&= 13'h0;
else if(w_ns == NEXT_FRAME)
&= 13'h0;
else if(w_ns == NEXT_WRITE)
&= hcount + 16;
always @(posedge axi_clk) begin
if(!axi_rstn)
&= 13'h0;
else if(w_ns == NEXT_FRAME)
&= 13'h0;
else if(w_ns == NEXT_LINE)
&= vcount + 1;
always @(posedge axi_clk) begin
if(!axi_rstn)
frame_last_r
&= 1'b0;
frame_last_r
= (hcount == (WIDTH - 16) )? 1'b1 : 1'b0;
frame_last
= (vcount == (HEIGHT - 1) )? 1'b1 : 1'b0;
S_AXI_WLAST_pin
= (axi_write_num == 5'hf)? 1'b1 : 1'b0;
MM2S VDMA设计
AXI读流程图:
读时序图:
AXI读数据就比较简单了,只要在AXI和video之间加入个fifo进行一下缓存就可以了,只要时序是对的,直接上代码
/*-----------------------------------------------------------------------&&&&CONFIDENTIAL&IN&CONFIDENCE&&This&confidential&and&proprietary&software&may&be&only&used&as&authorized&&by&a&licensing&agreement&from&EEPROM&.&&In&the&event&of&publication,&the&following&notice&is&applicable:&&Copyright&(C)&2013-20xx&EEPROM&Corporation&&The&entire&notice&above&must&be&reproduced&on&all&authorized&copies.&&Author&&&&&&&&&&&&&&:&&&&&&&EEPROM&&Technology&blogs&&&&:&&&&&&&http://blog.csdn.net/zhangyu_eeprom&&Email&Address&&&&&&&:&&&&&&&&&Filename&&&&&&&&&&&&:&&&&&&&axi4_mm2s_video_dma.v&&Data&&&&&&&&&&&&&&&&:&&&&&&&&&Description&&&&&&&&&:&&&&&&&axi4_mm2s_video_dma.&&Modification&History&&&&:&&Data&&&&&&&&&&&&By&&&&&&&&&&Version&&&&&&&&&Change&Description&&=========================================================================&&-------------------------------------------------------------------------&&&&&&&&&&&&------&&&&&------&&&&------|&&&------|&&&&&&/-------\&&&&&&&&&&&&|&&&&&&&&&&|&&&&&&&&&&|&&&&&|&&&|&&&&&|&&&&&/&&&&&&&&&\&&&&&&/-\&&&&&/-\&&&&&&&&&|------&&&&|------&&&&|-----|&&&|-----|&&&&/&&&&&&&&&&&\&&&&/&&&\&&&/&&&\&&&&&&&&&|&&&&&&&&&&|&&&&&&&&&&|&&&&&&&&&|&\&&&&&&&&\&&&&&&&&&&&/&&&/&&&&&\_/&&&&&\&&&&&&&&&|------&&&&|------&&&&|&&&&&&&&&|&&\&&&&&&&&\&&&&&&&&&/&&&/&&&&&&&&&&&&&&&\&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&|&&&&&&&&&|&&&\&&&&&&&&\-------/&&-----------------------------------------------------------------------*/&&&&&&&module&axi4_mm2s_video_dma&#(&&&&&parameter&[31:0]&&DMA_DEST_ADDR0&=&32'h1c000000,&&&&&parameter&[31:0]&&DMA_DEST_ADDR1&=&32'h1c200000,&&&&&parameter&[31:0]&&DMA_DEST_ADDR2&=&32'h1c400000,&&&&&parameter&[8:0]&&&C_DATA_WIDTH&=&9'd32,&&&&&parameter&[12:0]&&STRIDE&&&&&&&=&12'd1920,&&&&&parameter&[12:0]&&WIDTH&&&&&&&&=&12'd1920,&&&&&parameter&[12:0]&&HEIGHT&&&&&&&=&12'd1080&&&&&)&&&&&(&&&&&input&&&&&&&&&&&&&axi_clk,&&&&&input&&&&&&&&&&&&&axi_rstn,&&&&&&&&&input&&&&&&&&&&&&v_video_clk,&&&&&&&&&&&input&&&&&&&&&&&&v_timing_hsync_i,&&&&&input&&&&&&&&&&&&v_timing_vsync_i,&&&&&input&&&&&&&&&&&&v_timing_hblank_i,&&&&&input&&&&&&&&&&&&v_timing_vblank_i,&&&&&input&&&&&&&&&&&&v_timing_active_video_i,&&&&&&&&&&output&&reg&&&&&&&v_timing_hsync_o,&&&&&output&&reg&&&&&&&v_timing_vsync_o,&&&&&output&&reg&&&&&&&v_timing_hblank_o,&&&&&output&&reg&&&&&&&v_timing_vblank_o,&&&&&output&&reg&&&&&&&v_timing_active_video_o,&&&&&&&&&&output&[23:0]&&&&&v_video_o,&&&&&&&&&&&&&&&&&input&&&&&&&&&&&&&S_AXI_ARREADY_pin,&&&&&input&&&&&&&&&&&&&S_AXI_RLAST_pin,&&&&&input&&&&&&&&&&&&&S_AXI_RVALID_pin,&&&&&input&&&[1:0]&&&&&S_AXI_RRESP_pin,&&&&&input&&&[C_DATA_WIDTH-1:0]&&&&S_AXI_RDATA_pin,&&&&&input&&&[5:0]&&&&&S_AXI_RID_pin,&&&&&output&&&&&&&&&&&&S_AXI_ARVALID_pin,&&&&&&output&&&&&&&&&&&&S_AXI_RREADY_pin,&&&&&output&[1:0]&&&&&&S_AXI_ARBURST_pin,&&&&&output&[1:0]&&&&&&S_AXI_ARLOCK_pin,&&&&&output&[2:0]&&&&&&S_AXI_ARSIZE_pin,&&&&&output&[2:0]&&&&&&S_AXI_ARPROT_pin,&&&&&output&reg&[31:0]&S_AXI_ARADDR_pin,&&&&&output&[3:0]&&&&&&S_AXI_ARCACHE_pin,&&&&&output&[3:0]&&&&&&S_AXI_ARLEN_pin,&&&&&output&[3:0]&&&&&&S_AXI_ARQOS_pin,&&&&&output&[5:0]&&&&&&S_AXI_ARID_pin&&&&&);&&/******************************/&&wire&frame_&&wire&line_&&reg&process_start&=&1'b0;&&wire&[9:0]&&&reg&[31:0]prev_line_&&reg&[1:0]frame_&&reg&[12:0]&&reg&[12:0]&&reg&frame_last_r;&&wire&[31:0]&dma_tran_&&wire&dma_frame_read_&&&&reg&v_timing_hsync_r;&&reg&v_timing_vsync_r;&&reg&v_timing_hblank_r;&&reg&v_timing_vblank_r;&&reg&v_timing_active_video_r;&&reg&v_timing_active_video_d1;&&reg&v_timing_active_video_d2;&&/************fifo**************/&&wire&&fifo_wr_&&reg&&&fifo_rd_&&wire&&fifo_&&wire&&fifo_&&wire&&fifo_&&wire&&[6:0]&fifo_rd_data_&&wire&&[6:0]&fifo_wr_data_&&wire&&[31:0]&fifo_&&/******************************/&&&&assign&fifo_wr_en&=&S_AXI_RVALID_pin&&&S_AXI_RREADY_&&//assign&fifo_rd_en&=&process_start&&&v_timing_active_video_r;&&assign&v_video_o&=&fifo_dout[31:8];&&fifo_axi32bit&u_fifo_axi32bit&(&&&&.wr_clk(axi_clk),&&&&&&&&&&&&&&&&&&&&&.rd_clk(v_video_clk),&&&&&&&&&&&&&&&&&&&.din({S_AXI_RDATA_pin[7:0],S_AXI_RDATA_pin[15:8],S_AXI_RDATA_pin[23:16],S_AXI_RDATA_pin[31:24]}),&&&&&&&&&&&&&&&&&&.wr_en(fifo_wr_en),&&&&&&&&&&&&&&&&&&&&&.rd_en(fifo_rd_en),&&&&&&&&&&&&&&&&&&&&&.dout(fifo_dout),&&&&&&&&&&&&&&&&&&&&&&&.full(fifo_full),&&&&&&&&&&&&&&&&&&&&&&&.empty(fifo_empty),&&&&&&&&&&&&&&&&&&&&&.valid(fifo_valid),&&&&&&&&&&&&&&&&&&&&&.rd_data_count(fifo_rd_data_count),&&&&&.wr_data_count(fifo_wr_data_count)&&&&);&&&&&&&&&&always&@(posedge&v_video_clk)&&&begin&&&&&&v_timing_hsync_r&&&&&&&&&=&v_timing_hsync_i;&&&&&&&&&&&&&v_timing_vsync_r&&&&&&&&&=&v_timing_vsync_i;&&&&&&&&&&&&&v_timing_hblank_r&&&&&&&&=&v_timing_hblank_i;&&&&&&&&&&&&v_timing_vblank_r&&&&&&&&=&v_timing_vblank_i;&&&&&&&&&&&&v_timing_active_video_r&&=&v_timing_active_video_i;&&&&&&&&&&&&v_timing_hsync_o&&&&&&&&&=&v_timing_hsync_r;&&&&&&&&&&&&&v_timing_vsync_o&&&&&&&&&=&v_timing_vsync_r;&&&&&&&&&&&&&v_timing_hblank_o&&&&&&&&=&v_timing_hblank_r;&&&&&&&&&&&&v_timing_vblank_o&&&&&&&&=&v_timing_vblank_r;&&&&&&&&&&&&v_timing_active_video_o&&=&v_timing_active_video_r;&&&&&&&&&&&&v_timing_active_video_d1&&=&v_timing_active_video_r;&&&&&&v_timing_active_video_d2&&=&v_timing_active_video_d1;&&end&&&&reg&[1:0]&process_start_r;&&always&@(posedge&v_video_clk)&&&begin&&&&&&if(!axi_rstn)begin&&&&&&&&&&process_start&&=&1'b0;&&&&&&end&&&&&&else&if(~v_timing_vsync_r&&&&v_timing_vsync_i)&&&&&&begin&&&&&&&&&&process_start&&=&1'b1;&&&&&&end&&&&&&else&if(dma_frame_read_end)&&&&&&&&&&process_start&&=&1'b0;&&end&&&&&cross_clk&cross_clk1&&&&&(&&&&&&&&.clkin&&&(axi_clk),&&&&&&&&.din&&&&&(frame_last),&&&&&&&&.clkout&&(v_video_clk),&&&&&&&&.dout&&&&(dma_frame_read_end)&&&&&);&&reg&&&reg&[12:0]&invalid_&&reg&[12:0]&invalid_cnt_&&reg&[12:0]&fifo_read_&&&&always&@(posedge&v_video_clk)&&begin&&&&&&if(!axi_rstn)&&&&&&begin&&&&&&end&&&&&&&&else&if(v_timing_active_video_r&==&1'b0&||&fifo_read_num&==&(WIDTH&-&2))&&&&&&begin&&&&&&&&&&fifo_rd_en&&=&1'b0;&&&&&&end&&&&&&else&if(v_timing_active_video_r&&&&fifo_read_num&&&(WIDTH&-&2))&&&&&&&&&&fifo_rd_en&&=&1'b1;&&end&&always&@(posedge&v_video_clk)&&begin&&&&&&if(!axi_rstn)&&&&&&begin&&&&&&&&&&fifo_read_num&&=&13'd0;&&&&&&end&&&&&&else&if(v_timing_active_video_d2&&&&fifo_read_num&!=&(WIDTH&-&1))&&&&&&&&&&fifo_read_num&&=&fifo_read_num&+&1;&&&&&&else&if(!v_timing_active_video_d2&&&&fifo_read_num&==&(WIDTH&-&1))&&&&&&&&&&fifo_read_num&&=&13'd0;&&end&&//------------------------------------------------------&&//&AXI&bus&&//------------------------------------------------------&&assign&S_AXI_ARID_pin&&&&&&=&6'b000000;&&assign&S_AXI_ARLEN_pin&&&&&=&4'&&&&&//burst&length:&16&&assign&S_AXI_ARSIZE_pin&&&&=&3'b010;&&&//size:&4byte&&assign&S_AXI_ARBURST_pin&&&=&2'b01;&&&&//incr&&assign&S_AXI_ARLOCK_pin&&&&=&2'b00;&&assign&S_AXI_ARCACHE_pin&&&=&4'b0011;&/////&&assign&S_AXI_ARPROT_pin&&&&=&3'b000;&&assign&S_AXI_ARQOS_pin&&&&&=&4'b0000;&&&&&&&&&&&&parameter&&&IDLE&&&&&&&&=&4'b0000;&&parameter&&&SEND_ADDR&&&=&4'b0001;&&parameter&&&WAIT_DATA&&&=&4'b0011;&&parameter&&&WAIT_FIFO&&&=&4'b0111;&&parameter&&&NEXT_READ&&&=&4'b1111;&&parameter&&&NEXT_LINE&&&=&4'b1110;&&parameter&&&NEXT_FRAME&&=&4'b1100;&&reg&[3:0]r_&&reg&[3:0]r_&&&&assign&&space&&&=&127&-&fifo_wr_data_count[6:0];&&always&@(posedge&axi_clk)&&begin&&&&&&if(!axi_rstn)&&&&&&begin&&&&&&&&&&r_cs&&=&IDLE;&&&&&&end&&&&&&else&&&&&&begin&&&&&&&&&&r_cs&&=&r_&&&&&&end&&end&&&&always&@(*)&begin&&&&&&case(r_cs)&&&&&&&&&&IDLE:&begin&&&&&&&&&&&&&&if(process_start)&&&&&&&&&&&&&&&&&&r_ns&&=&SEND_ADDR;&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&r_ns&&=&r_&&&&&&&&&&end&&&&&&&&&&SEND_ADDR:&begin&&&&&&&&&&&&&&if(S_AXI_ARREADY_pin&&&S_AXI_ARVALID_pin)&&&&&&&&&&&&&&&&&&r_ns&&=&WAIT_DATA;&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&r_ns&&=&r_&&&&&&&&&&end&&&&&&&&&&WAIT_DATA:&begin&&&&&&&&&&&&&&if(S_AXI_RREADY_pin&&&S_AXI_RVALID_pin&&&S_AXI_RLAST_pin&&&(space&&&10'h12))&&&&&&&&&&&&&&&&&&r_ns&&=&WAIT_FIFO;&&&&&&&&&&&&&&else&if(S_AXI_RREADY_pin&&&S_AXI_RVALID_pin&&&S_AXI_RLAST_pin&&&(~line_last))&&&&&&&&&&&&&&&&&&r_ns&&=&NEXT_READ;&&&&&&&&&&&&&&else&if(S_AXI_RREADY_pin&&&S_AXI_RVALID_pin&&&S_AXI_RLAST_pin&&&(&line_last)&&&(~frame_last))&&&&&&&&&&&&&&&&&&r_ns&&=&NEXT_LINE;&&&&&&&&&&&&&&else&if(S_AXI_RREADY_pin&&&S_AXI_RVALID_pin&&&S_AXI_RLAST_pin&&&(&line_last)&&&(&frame_last))&&&&&&&&&&&&&&&&&&r_ns&&=&NEXT_FRAME;&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&r_ns&&=&r_&&&&&&&&&&end&&&&&&&&&&WAIT_FIFO:&begin&&&&&&&&&&&&&&if((space&&=&10'h11)&&&(~line_last))&&&&&&&&&&&&&&&&&&r_ns&&=&NEXT_READ;&&&&&&&&&&&&&&else&if((space&&=&10'h11)&&&(&line_last)&&&(~frame_last))&&&&&&&&&&&&&&&&&&r_ns&&=&NEXT_LINE;&&&&&&&&&&&&&&else&if((space&&=&10'h11)&&&(&line_last)&&&(&frame_last))&&&&&&&&&&&&&&&&&&r_ns&&=&NEXT_FRAME;&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&r_ns&&=&r_&&&&&&&&&&end&&&&&&&&&&NEXT_READ:&begin&&&&&&&&&&&&&&r_ns&&=&SEND_ADDR;&&&&&&&&&&end&&&&&&&&&&NEXT_LINE:&begin&&&&&&&&&&&&&&r_ns&&=&SEND_ADDR;&&&&&&&&&&end&&&&&&&&&&NEXT_FRAME:&begin&&&&&&&&&&&&&&r_ns&&=&IDLE;//SEND_ADDR&&&&&&&&&&end&&&&&&&&&&default:&begin&&&&&&&&&&&&&&r_ns&&=&r_&&&&&&&&&&end&&&&&&endcase&&end&&/************test***************/&&&&/***************************/&&assign&dma_tran_addr&=&(frame_num&==&2'b00)?&DMA_DEST_ADDR0&:&(frame_num&==&2'b01)?&DMA_DEST_ADDR1&:&DMA_DEST_ADDR2;&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&prev_line_start&&=&32'h0;&&&&&&else&if(r_cs&==&IDLE&&&&r_ns&==&SEND_ADDR)&&&&&&&&&&prev_line_start&&=&dma_tran_&&&&&&else&if(r_cs&==&NEXT_LINE&&&&r_ns&==&SEND_ADDR)&&&&&&&&&&prev_line_start&&=&prev_line_start&+&STRIDE;&&&&&&else&if(r_cs&==&NEXT_FRAME&&&&r_ns&==&IDLE)//SEND_ADDR&&&&&&&&&&prev_line_start&&=&dma_tran_&&end&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&S_AXI_ARADDR_pin&&&=&32'h0;&&&&&&else&if(r_cs&==&IDLE&&&&r_ns&==&SEND_ADDR)&&&&&&&&&&S_AXI_ARADDR_pin&&&=&dma_tran_&&&&&&else&if(r_cs&==&NEXT_READ&&&&r_ns&==&SEND_ADDR)&&&&&&&&&&S_AXI_ARADDR_pin&&&=&S_AXI_ARADDR_pin&+&8'h40;&&&&&&else&if(r_cs&==&NEXT_LINE&&&&r_ns&==&SEND_ADDR)&&&&&&&&&&S_AXI_ARADDR_pin&&&=&prev_line_start&+&STRIDE;&&&&&&else&if(r_cs&==&NEXT_FRAME&&&&r_ns&==&IDLE)//SEND_ADDR&&&&&&&&&&S_AXI_ARADDR_pin&&&=&dma_tran_&&end&&&&assign&&S_AXI_ARVALID_pin&=&(r_cs&==&SEND_ADDR)?&1'b1&:&1'b0;&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&hcount&&&=&13'h0;&&&&&&else&if((r_cs&==&IDLE&||&r_cs&==&NEXT_LINE&||&r_cs&==&NEXT_FRAME)&&&&(r_ns&==&SEND_ADDR))//SEND_ADDR&&&&&&&&&&hcount&&&=&13'h0;&&&&&&else&if(r_cs&==&NEXT_READ&&&&r_ns&==&SEND_ADDR)&&&&&&&&&&hcount&&&=&hcount&+&16;&&end&&&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&vcount&&&=&13'h0;&&&&&&else&if(r_cs&==&NEXT_FRAME&&&&r_ns&==&IDLE)//SEND_ADDR&&&&&&&&&&vcount&&&=&13'h0;&&&&&&else&if(r_cs&==&NEXT_LINE&&&&r_ns&==&SEND_ADDR)&&&&&&&&&&vcount&&&=&vcount&+&1;&&end&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&begin&&&&&&&&&&frame_num&&&&&=&2'b00;&&&&&&end&&&&&&else&if(/*process_start&&&&*/frame_last&&&&~frame_last_r)&&&&&&begin&&&&&&&&&&if(frame_num&!=&2'b10)&&&&&&&&&&&&&&frame_num&&&&&=&frame_num&+&1;&&&&&&&&&&else&&&&&&&&&&&&&&&frame_num&&&&&=&2'b00;&&&&&&end&&end&&always&@(posedge&axi_clk)&begin&&&&&&if(!axi_rstn)&&&&&&&&&&frame_last_r&&&&&=&1'b0;&&&&&&else&&&&&&&&&&&frame_last_r&&&&&=&frame_&&end&&assign&&line_last&&&=&(hcount&==&(WIDTH&-&16)&)?&1'b1&:&1'b0;&&assign&&frame_last&&=&(vcount&==&(HEIGHT&-&1)&)?&1'b1&:&1'b0;&&assign&&S_AXI_RREADY_pin&=&1'b1;&&&&&&&&&&&endmodule&&
/*-----------------------------------------------------------------------
CONFIDENTIAL IN CONFIDENCE
This confidential and proprietary software may be only used as authorized
by a licensing agreement from EEPROM .
In the event of publication, the following notice is applicable:
Copyright (C) 2013-20xx EEPROM Corporation
The entire notice above must be reproduced on all authorized copies.
Technology blogs
http://blog.csdn.net/zhangyu_eeprom
Email Address
axi4_mm2s_video_dma.v
Description
axi4_mm2s_video_dma.
Modification History :
Change Description
=========================================================================
-------------------------------------------------------------------------
-----------------------------------------------------------------------*/
module axi4_mm2s_video_dma #(
parameter [31:0]
DMA_DEST_ADDR0 = 32'h1c000000,
parameter [31:0]
DMA_DEST_ADDR1 = 32'h1c200000,
parameter [31:0]
DMA_DEST_ADDR2 = 32'h1c400000,
parameter [8:0]
C_DATA_WIDTH = 9'd32,
parameter [12:0]
= 12'd1920,
parameter [12:0]
= 12'd1920,
parameter [12:0]
= 12'd1080
v_video_clk,
v_timing_hsync_i,
v_timing_vsync_i,
v_timing_hblank_i,
v_timing_vblank_i,
v_timing_active_video_i,
v_timing_hsync_o,
v_timing_vsync_o,
v_timing_hblank_o,
v_timing_vblank_o,
v_timing_active_video_o,
output [23:0]
v_video_o,
S_AXI_ARREADY_pin,
S_AXI_RLAST_pin,
S_AXI_RVALID_pin,
S_AXI_RRESP_pin,
[C_DATA_WIDTH-1:0]
S_AXI_RDATA_pin,
S_AXI_RID_pin,
S_AXI_ARVALID_pin,
S_AXI_RREADY_pin,
output [1:0]
S_AXI_ARBURST_pin,
output [1:0]
S_AXI_ARLOCK_pin,
output [2:0]
S_AXI_ARSIZE_pin,
output [2:0]
S_AXI_ARPROT_pin,
output reg [31:0] S_AXI_ARADDR_pin,
output [3:0]
S_AXI_ARCACHE_pin,
output [3:0]
S_AXI_ARLEN_pin,
output [3:0]
S_AXI_ARQOS_pin,
output [5:0]
S_AXI_ARID_pin
/******************************/
wire frame_
wire line_
reg process_start = 1'b0;
wire [9:0]
reg [31:0]prev_line_
reg [1:0]frame_
reg [12:0]
reg [12:0]
reg frame_last_r;
wire [31:0] dma_tran_
wire dma_frame_read_
reg v_timing_hsync_r;
reg v_timing_vsync_r;
reg v_timing_hblank_r;
reg v_timing_vblank_r;
reg v_timing_active_video_r;
reg v_timing_active_video_d1;
reg v_timing_active_video_d2;
/************fifo**************/
[6:0] fifo_rd_data_
[6:0] fifo_wr_data_
[31:0] fifo_
/******************************/
assign fifo_wr_en = S_AXI_RVALID_pin & S_AXI_RREADY_
//assign fifo_rd_en = process_start & v_timing_active_video_r;
assign v_video_o = fifo_dout[31:8];
fifo_axi32bit u_fifo_axi32bit (
.wr_clk(axi_clk),
.rd_clk(v_video_clk),
.din({S_AXI_RDATA_pin[7:0],S_AXI_RDATA_pin[15:8],S_AXI_RDATA_pin[23:16],S_AXI_RDATA_pin[31:24]}),
.wr_en(fifo_wr_en),
.rd_en(fifo_rd_en),
.dout(fifo_dout),
.full(fifo_full),
.empty(fifo_empty),
.valid(fifo_valid),
.rd_data_count(fifo_rd_data_count),
.wr_data_count(fifo_wr_data_count)
always @(posedge v_video_clk)
v_timing_hsync_r
&= v_timing_hsync_i;
v_timing_vsync_r
&= v_timing_vsync_i;
v_timing_hblank_r
&= v_timing_hblank_i;
v_timing_vblank_r
&= v_timing_vblank_i;
v_timing_active_video_r &= v_timing_active_video_i;
v_timing_hsync_o
&= v_timing_hsync_r;
v_timing_vsync_o
&= v_timing_vsync_r;
v_timing_hblank_o
&= v_timing_hblank_r;
v_timing_vblank_o
&= v_timing_vblank_r;
v_timing_active_video_o &= v_timing_active_video_r;
v_timing_active_video_d1 &= v_timing_active_video_r;
v_timing_active_video_d2 &= v_timing_active_video_d1;
reg [1:0] process_start_r;
always @(posedge v_video_clk)
if(!axi_rstn)begin
process_start &= 1'b0;
else if(~v_timing_vsync_r && v_timing_vsync_i)
process_start &= 1'b1;
else if(dma_frame_read_end)
process_start &= 1'b0;
cross_clk cross_clk1
(axi_clk),
(frame_last),
(v_video_clk),
(dma_frame_read_end)
reg [12:0] invalid_
reg [12:0] invalid_cnt_
reg [12:0] fifo_read_
always @(posedge v_video_clk)
if(!axi_rstn)
else if(v_timing_active_video_r == 1'b0 || fifo_read_num == (WIDTH - 2))
fifo_rd_en &= 1'b0;
else if(v_timing_active_video_r && fifo_read_num & (WIDTH - 2))
fifo_rd_en &= 1'b1;
always @(posedge v_video_clk)
if(!axi_rstn)
fifo_read_num &= 13'd0;
else if(v_timing_active_video_d2 && fifo_read_num != (WIDTH - 1))
fifo_read_num &= fifo_read_num + 1;
else if(!v_timing_active_video_d2 && fifo_read_num == (WIDTH - 1))
fifo_read_num &= 13'd0;
//------------------------------------------------------
// AXI bus
//------------------------------------------------------
assign S_AXI_ARID_pin
= 6'b000000;
assign S_AXI_ARLEN_pin
//burst length: 16
assign S_AXI_ARSIZE_pin
= 3'b010;
//size: 4byte
assign S_AXI_ARBURST_pin
= 2'b01;
assign S_AXI_ARLOCK_pin
= 2'b00;
assign S_AXI_ARCACHE_pin
= 4'b0011; /////
assign S_AXI_ARPROT_pin
= 3'b000;
assign S_AXI_ARQOS_pin
= 4'b0000;
= 4'b0000;
= 4'b0001;
= 4'b0011;
= 4'b0111;
= 4'b1111;
= 4'b1110;
NEXT_FRAME
= 4'b1100;
reg [3:0]r_
reg [3:0]r_
= 127 - fifo_wr_data_count[6:0];
always @(posedge axi_clk)
if(!axi_rstn)
r_cs &= IDLE;
r_cs &= r_
always @(*) begin
case(r_cs)
IDLE: begin
if(process_start)
= SEND_ADDR;
SEND_ADDR: begin
if(S_AXI_ARREADY_pin & S_AXI_ARVALID_pin)
= WAIT_DATA;
WAIT_DATA: begin
if(S_AXI_RREADY_pin & S_AXI_RVALID_pin & S_AXI_RLAST_pin & (space & 10'h12))
= WAIT_FIFO;
else if(S_AXI_RREADY_pin & S_AXI_RVALID_pin & S_AXI_RLAST_pin & (~line_last))
= NEXT_READ;
else if(S_AXI_RREADY_pin & S_AXI_RVALID_pin & S_AXI_RLAST_pin & ( line_last) & (~frame_last))
= NEXT_LINE;
else if(S_AXI_RREADY_pin & S_AXI_RVALID_pin & S_AXI_RLAST_pin & ( line_last) & ( frame_last))
= NEXT_FRAME;
WAIT_FIFO: begin
if((space &= 10'h11) & (~line_last))
= NEXT_READ;
else if((space &= 10'h11) & ( line_last) & (~frame_last))
= NEXT_LINE;
else if((space &= 10'h11) & ( line_last) & ( frame_last))
= NEXT_FRAME;
NEXT_READ: begin
= SEND_ADDR;
NEXT_LINE: begin
= SEND_ADDR;
NEXT_FRAME: begin
= IDLE;//SEND_ADDR
default: begin
/************test***************/
/***************************/
assign dma_tran_addr = (frame_num == 2'b00)? DMA_DEST_ADDR0 : (frame_num == 2'b01)? DMA_DEST_ADDR1 : DMA_DEST_ADDR2;
always @(posedge axi_clk) begin
if(!axi_rstn)
prev_line_start &= 32'h0;
else if(r_cs == IDLE && r_ns == SEND_ADDR)
prev_line_start &= dma_tran_
else if(r_cs == NEXT_LINE && r_ns == SEND_ADDR)
prev_line_start &= prev_line_start + STRIDE;
else if(r_cs == NEXT_FRAME && r_ns == IDLE)//SEND_ADDR
prev_line_start &= dma_tran_
always @(posedge axi_clk) begin
if(!axi_rstn)
S_AXI_ARADDR_pin
&= 32'h0;
else if(r_cs == IDLE && r_ns == SEND_ADDR)
S_AXI_ARADDR_pin
&= dma_tran_
else if(r_cs == NEXT_READ && r_ns == SEND_ADDR)
S_AXI_ARADDR_pin
&= S_AXI_ARADDR_pin + 8'h40;
else if(r_cs == NEXT_LINE && r_ns == SEND_ADDR)
S_AXI_ARADDR_pin
&= prev_line_start + STRIDE;
else if(r_cs == NEXT_FRAME && r_ns == IDLE)//SEND_ADDR
S_AXI_ARADDR_pin
&= dma_tran_
S_AXI_ARVALID_pin = (r_cs == SEND_ADDR)? 1'b1 : 1'b0;
always @(posedge axi_clk) begin
if(!axi_rstn)
&= 13'h0;
else if((r_cs == IDLE || r_cs == NEXT_LINE || r_cs == NEXT_FRAME) && (r_ns == SEND_ADDR))//SEND_ADDR
&= 13'h0;
else if(r_cs == NEXT_READ && r_ns == SEND_ADDR)
&= hcount + 16;
always @(posedge axi_clk) begin
if(!axi_rstn)
&= 13'h0;
else if(r_cs == NEXT_FRAME && r_ns == IDLE)//SEND_ADDR
&= 13'h0;
else if(r_cs == NEXT_LINE && r_ns == SEND_ADDR)
&= vcount + 1;
always @(posedge axi_clk) begin
if(!axi_rstn)
&= 2'b00;
else if(/*process_start && */frame_last && ~frame_last_r)
if(frame_num != 2'b10)
&= frame_num + 1;
&= 2'b00;
always @(posedge axi_clk) begin
if(!axi_rstn)
frame_last_r
&= 1'b0;
frame_last_r
= (hcount == (WIDTH - 16) )? 1'b1 : 1'b0;
frame_last
= (vcount == (HEIGHT - 1) )? 1'b1 : 1'b0;
S_AXI_RREADY_pin = 1'b1;
当然,读过程也和写过程一样,burst长度是固定的16,所以读数据长度也要能被16整除才可以
注意:在做AXI总线读写的时候,一定要注意大小端的问题。
DMA操作其实就是直接操作AXI总线进行DDR数据搬移,只要满足AXI总线协议就可以了,自己写DMA可以灵活定制功能,减小设计面积,更加可调式。本文中的设计只是很拙劣的设计,就是按照时序拼出来的,如果哪位能给提出些建议,或者有更好的方案,还望不吝赐教
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3371次
排名:千里之外
原创:10篇

我要回帖

更多关于 绝地求生放在固态 的文章

 

随机推荐