小梅哥的这个ZYNQ开发板上的DDR3位于PS侧,PL侧想要使用DDR3作为缓存的话,得通过HP接口来与PS侧的DDR3控制进行通信。
本次实验在小梅哥OV5640工程的基础上,通过修改VDMA的S2MM端的模块而来的。
将VMDA的帧缓存区设为1,关闭帧同步的功能后,其实和DMA差不多。
一、需要自定义的ip核
这里列出的为自己写的IP核。小梅哥的工程里还用到了其它的自定义的IP核,这里就不列出了。
1、串口接收图像数据模块
该模块调用了之前写的串口8位接收模块,详情可点击查看。
此外,本模块还调用16位宽、深度为1024的带数据计数的普通FIFO核
该模块主要的思想就是将接收到的两个8位的数据拼接位1个16位的数据并存入FIFO中,
当存入的数据达到LINE_LENGTH(800)的时候,在收到从接口的准备信号时一次性写入VMDA中,再通过VMDA将数据写到DDR3中。
此外该模块在应用的时候要封装成带AXI4_Stream 接口的IP核,具体封装过程可网上找教程。
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: GDUT
// Engineer: Lclone
//
// Create Date: 2023/02/07 20:38:34
// Design Name:
// Module Name: Img_Rx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Img_Rx
# (parameter RX_BAUD = 115200,
parameter CLK_FQC = 50_000_000,
parameter LINE_LENGTH = 800)
(
input Uart_Rx,
//---------------------------
input m_clk,
input m_axis_aresetn,
output [15:0] m_axis_tdata,
output reg m_axis_tlast,
input m_axis_tready,
output reg m_axis_tvalid
);
wire [7:0] Uart_Data;
wire Rx_done;
reg Rx_done_r;
reg Rx_done_cnt;
reg [15:0] Uart_Data_16;
wire [9:0] fifo_data_count;
reg [9:0] out_data_count;
reg m_axis_tvalid_r;
always @(posedge m_clk) Rx_done_r <= Rx_done;
always @(posedge m_clk) m_axis_tvalid <= m_axis_tvalid_r;
always @(posedge m_clk or negedge m_axis_aresetn) begin
if(m_axis_aresetn == 0)
Uart_Data_16 <= 0;
else if(Rx_done == 1)
Uart_Data_16 <= {Uart_Data_16[7:0],Uart_Data};
end
always @(posedge m_clk or negedge m_axis_aresetn) begin
if(m_axis_aresetn == 0)
Rx_done_cnt <= 0;
else if(Rx_done == 1)
Rx_done_cnt <= Rx_done_cnt + 1'b1;
else
Rx_done_cnt <= Rx_done_cnt;
end
always @(posedge m_clk or negedge m_axis_aresetn) begin
if(m_axis_aresetn == 0)
m_axis_tvalid_r <= 0;
else if(m_axis_tready == 1 & fifo_data_count >= LINE_LENGTH)
m_axis_tvalid_r <= 1'b1;
else if(fifo_data_count <= 1)
m_axis_tvalid_r <= 0;
else
m_axis_tvalid_r <= m_axis_tvalid_r;
end
always @(posedge m_clk or negedge m_axis_aresetn) begin
if(m_axis_aresetn == 0)
out_data_count <= 0;
else if(out_data_count == LINE_LENGTH - 1)
out_data_count <= 0;
else if(m_axis_tvalid_r & m_axis_tready)
out_data_count <= out_data_count + 1'b1;
else
out_data_count <= out_data_count;
end
always @(posedge m_clk or negedge m_axis_aresetn) begin
if(m_axis_aresetn == 0)
m_axis_tlast <= 0;
else if(out_data_count == LINE_LENGTH - 1)
m_axis_tlast <= 1;
else
m_axis_tlast <= 0;
end
uart_byte_rx
# (
.RX_BAUD (RX_BAUD),
.CLK_FQC (CLK_FQC))
uart_byte_rx_inst
(
.Clk (m_clk),
.Rst_n (m_axis_aresetn),
.Uart_rx (Uart_Rx),
.Data (Uart_Data),
.Rx_done (Rx_done)
);
fifo_generator_0 fifo_generator_0_inst (
.clk(m_clk), // input wire clk
.srst(~m_axis_aresetn), // input wire srst
.din(Uart_Data_16), // input wire [15 : 0] din
.wr_en(~Rx_done_cnt & Rx_done_r), // input wire wr_en
.rd_en(m_axis_tvalid_r & m_axis_tready), // input wire rd_en
.dout(m_axis_tdata), // output wire [15 : 0] dout
.full(), // output wire full
.empty(), //