這個模塊主要用到一個fifo來做數(shù)據緩存,只要注意一下stream協(xié)議的握手操作即可,由于stream協(xié)議比較簡單,這里就不多說了。至此,video數(shù)據就轉換到了stream數(shù)據。
(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做數(shù)據緩存,然后根據外部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),協(xié)議部分完全沒有改動,這里拿他當做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
評論