这个模块主要用到一个fifo来做数据缓存,只要注意一下stream协议的握手操作即可,由于stream协议比较简单,这里就不多说了。至此,video数据就转换到了stream数据。
(3)axis转video模块,接口如下:
module axis2video#
(
parameter DW = 32,
parameter WIDTH = 640,
parameter HEIGHT = 480
)
(
input axis_clk,
input axis_aresetn,
// axis
input reg_axis_mm2s_start,
input [DW-1:0] s_axis_tdata,
input s_axis_tvalid,
input s_axis_tlast,
input s_axis_tuser,
output reg s_axis_tready,
// video data
input video_clk,
input video_rst,
input video_hsync_i,
input video_vsync_i,
input video_hblank_i,
input video_vblank_i,
input video_de_i,
output video_hsync_o,
output video_vsync_o,
output video_hblank_o,
output video_vblank_o,
output video_de_o,
output reg[DW-1:0] video_data
);
这个模块相当于xilinx的vid out模块,我这里是简化版的,xilinx的ip写的太复杂了,而且不容易用起来,其实也就是用一个fifo做数据缓存,然后根据外部video时序从fifo读出到输出。
(4)video timing gen模块,接口如下:
module video_timing_gen #
(
parameter SENSOR_ACT_W = 640,
parameter SENSOR_ACT_H = 480,
parameter SENSOR_WIDTH = 800,
parameter SENSOR_HEIGHT = 600,
parameter SENSOR_HSYNC_START = 0,
parameter SENSOR_HSYNC_STOP = 40,
parameter SENSOR_VSYNC_START = 0,
parameter SENSOR_VSYNC_STOP = 4
)
(
input rst_n,
input video_clk,
input [12:0]reg_h_start,
input [12:0]reg_v_start,
output reg vsync,
output reg hsync,
output reg de,
output reg vblank,
output reg hblank
);
此模块产生视频时序,提供给 axis2video模块,相当于xilinx的vtc模块。
(5) axi slave模块,接口如下:
`define C_S_AXI_ADDR_WIDTH 32
module axi_slave #(
parameter integer C_S_AXI_ID_WIDTH = 6,
parameter integer C_S_AXI_DATA_WIDTH = 32
) (
input wire S_AXI_ACLK,
input wire S_AXI_ARESETN,
input wire [C_S_AXI_ID_WIDTH-1:0] S_AXI_AWID,
input wire [`C_S_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR,
input wire [7:0] S_AXI_AWLEN,
input wire [2:0] S_AXI_AWSIZE,
input wire [1:0] S_AXI_AWBURST,
input wire S_AXI_AWVALID,
output wire S_AXI_AWREADY,
input wire [C_S_AXI_DATA_WIDTH-1:0] S_AXI_WDATA,
input wire [C_S_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB,
input wire S_AXI_WLAST,
input wire S_AXI_WVALID,
output wire S_AXI_WREADY,
output wire [C_S_AXI_ID_WIDTH-1:0] S_AXI_BID,
output wire [1:0] S_AXI_BRESP,
output wire S_AXI_BVALID,
input wire S_AXI_BREADY,
input wire [C_S_AXI_ID_WIDTH-1:0] S_AXI_ARID,
input wire [`C_S_AXI_ADDR_WIDTH-1:0] S_AXI_ARADDR,
input wire [7:0] S_AXI_ARLEN,
input wire [2:0] S_AXI_ARSIZE,
input wire [1:0] S_AXI_ARBURST,
input wire S_AXI_ARVALID,
output wire S_AXI_ARREADY,
output wire [C_S_AXI_ID_WIDTH-1:0] S_AXI_RID,
output wire [C_S_AXI_DATA_WIDTH-1:0] S_AXI_RDATA,
output wire [1:0] S_AXI_RRESP,
output wire S_AXI_RLAST,
output wire S_AXI_RVALID,
input wire S_AXI_RREADY
);
这块模块是根据xilinx官方提供的参考设计基础上修改而来的(xapp1168),协议部分完全没有改动,这里拿他当做ddr,具体修改是这样的,
reg [31:0] mem [32’h01000000:0];
用寄存器组来模拟ddr
此模块会根据axi master的时序来计算出要读写的地址
assign write_mem_address = axi_awv_awr_flag ? axi_awaddr: 0;
assign read_mem_address = axi_arv_arr_flag ? axi_araddr: 0;
写操作:mem[write_mem_address>>2] <= #1 S_AXI_WDATA;
读操作:mem_data_out <= mem[read_mem_address>>2];
做此修改以后,这个模块就可以当做ddr来用,为仿真提供了很大的方便
(6)vdma模块,这个就用xilinx的vdma ip,注意,我这里不是在block design里面例化,所以端口需要自己在hdl里面做连接的。
这里还有一个模块是 axi lite master模块,作用是用来配置vdma的寄存器,这个模块也是xilinx提供的,只需要做小量修改即可
always @(write_index)
begin
case (write_index)
// AXI VDMA 0 Set Up
1: awaddr <= 32'h43000030;
2: awaddr <= 32'h43c000ac;
3: awaddr <= 32'h43c000b0;
4: awaddr <= 32'h43c000a8;
5: awaddr <= 32'h43c000a4;
6: awaddr <= 32'h43c000a0;
7: awaddr <= 32'h43000000;
8: awaddr <= 32'h43c0005c;
9: awaddr <= 32'h43c00060;
10: awaddr <= 32'h43c00058;
11: awaddr <= 32'h43c00054;
12: awaddr <= 32'h43c00050;
default: awaddr <= 32'h00000000;
endcase
end
评论
查看更多