例如:
基于米联科的学习资料,分享和学习同步,欢迎大家一起探讨。
提示:这里可以添加技术整体架构
例如:
image_data_gen产生了测试图片,之后进入过W0 FIFO进行视频缓存。每次缓存1024个像素,就往通过FDMA往DDR里面搬运数据。另外VS信号经过滤波采集后用于启动一次写状态机。同理对于图像的输出部分采用HDMI输出,用Vga_lcd_driver产生输出的时序。视频经过R0 FIFO缓存后输出。R0 FIFO也是每次缓存1024个像素数据。
FIFO: First in, First out
代表先进的数据先出 ,后进的数据后出。
DMA:全称Direct Memory Access,即直接存储器访问。DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。当CPU初始化这个传输动作,传输动作本身是由DMA控制器来实现和完成的。DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场过程,通过硬件为RAM和IO设备开辟一条直接传输数据的通道,使得CPU的效率大大提高。
提示:这里可以添加技术细节
//--------一帧图像写入DDR------------
always @(posedge ui_clk) begin
if(!ui_rstn)begin
W_MS <= S_IDLE;
W0_addr <= 21'd0;
pkg_wr_areq <= 1'd0;
W0_FIFO_Rst <= 1'b1;
W0_fcnt <= 0;
W0_bcnt <= 0;
W0_s_rdy <= 1'b0;
W0_Fbuf <= 7'd0;
end
else begin
case(W_MS)
S_IDLE:begin
W0_addr <= 21'd0;
W0_fcnt <= 0;
W0_bcnt <= 11'd0;
W0_s_rdy <= 1'b1;
if(W0_FS) W_MS <= S_RST;
end
S_RST:begin
W0_s_rdy <= 1'b0;
if(W0_fcnt > 8'd30 ) W_MS <= S_DATA1;
W0_FIFO_Rst <= (W0_fcnt < 8'd20);
W0_fcnt <= W0_fcnt +1'd1;
end
S_DATA1:begin
if(W0_bcnt == BURST_TIMES) begin
if(W0_Fbuf == FBUF_SIZE)
W0_Fbuf <= 7'd0;
else
W0_Fbuf <= W0_Fbuf + 1'b1;
W_MS <= S_IDLE;
end
else if(W0_REQ) begin
W0_fcnt <=0;
pkg_wr_areq <= 1'b1;
W_MS <= S_DATA2;
end
end
S_DATA2:begin
pkg_wr_areq <= 1'b0;
if(pkg_wr_last)begin
W_MS <= S_DATA1;
W0_bcnt <= W0_bcnt + 1'd1;
W0_addr <= W0_addr + BURST_SIZE;
end
end
endcase
end
end
//--------一帧图像读出DDR------------
always @(posedge ui_clk) begin
if(!ui_rstn)begin
R_MS <= S_IDLE;
R0_addr <= 21'd0;
pkg_rd_areq <= 1'd0;
R0_fcnt <=0;
R0_bcnt <=0;
R0_FIFO_Rst <= 1'b1;
R0_s_rdy <= 1'b0;
R0_Fbuf <= 7'd0;
end
else begin
case(R_MS)
S_IDLE:begin
R0_addr <= 21'd0;
R0_fcnt <=0;
R0_bcnt <=0;
R0_s_rdy <= 1'b1;
if(R0_FS) R_MS <= S_RST;
end
S_RST:begin
R0_s_rdy <= 1'b0;
if(R0_fcnt > 8'd30 ) R_MS <= S_DATA1;
R0_FIFO_Rst <= (R0_fcnt < 8'd20);
R0_fcnt <= R0_fcnt + 1'd1;
end
S_DATA1:begin
if(R0_bcnt == BURST_TIMES ) begin
R_MS <= S_IDLE;
if(W0_Fbuf == 7'd0)
R0_Fbuf <= FBUF_SIZE;
else
R0_Fbuf <= W0_Fbuf - 1'b1;
end
else if(R0_REQ) begin
pkg_rd_areq <= 1'b1;
R_MS <= S_DATA2;
end
end
S_DATA2:begin
pkg_rd_areq <= 1'b0;
if(pkg_rd_last)begin
R_MS <= S_DATA1;
R0_bcnt <= R0_bcnt + 1'd1;
R0_addr <= R0_addr + BURST_SIZE;
end
end
endcase
end
end
always@(posedge ui_clk)
begin
W0_REQ <= (W0_rcnt >= PKG_SIZE);
R0_REQ <= (R0_wcnt <= PKG_SIZE);
end
上面两端代码,分别表示帧写入和帧写出DDR的代码
截取上面完整代码中部分代码如下:可以看到控制高地址,轻松完成缓存地址切换。
assign pkg_wr_addr = {W0_Fbuf,W0_addr}+ADDR_OFFSET;
assgin pkg_rd_addr ={R0_Fbuf,R0_addr}+ADDR_OFFSET;
提示:这里可以添加总结
例如:
本文主要基于FDMA的ddr图像缓存做了设计。