一、模块说明
在FPGA设计中,经常要用到帧接口和流接口,有时候需要帧接口到流接口的跨时钟处理,依据这种需求开发帧转流跨时钟处理模块
二、frame_to_stream跨时钟处理
module frame_to_stream
(
input wr_clk,
input wr_rstn,
input i_vsync,
input i_hsync,
input i_data_vld,
input63:0 i_data,
input rd_clk,
input rd_rstn,
input31:0 i_high,
input31:0 i_width,
output reg o_vld,
output reg o_sof,
output reg o_last,
output63:0 o_data,
input i_ready
);
reg1:0 vsync_r;
reg1:0 hsync_r;
reg1:0 data_vld_r;
reg63:0 data_r1:0;
always@(posedge wr_clk)begin
vsync_r <= {vsync_r0,i_vsync};
hsync_r <= {hsync_r0,i_hsync};
data_vld_r <= {data_vld_r0,i_data_vld};
data_r0 <= i_data;
data_r1 <= data_r0;
end
wire fifo_wr_en;
wire fifo_full;
wire fifo_wr_err;
wire63:0fifo_din;
assign fifo_wr_en = vsync_r1 & hsync_r1 & data_vld_r1;
assign fifo_wr_err = fifo_wr_en & fifo_full;
assign fifo_din = data_r1;
wire fifo_rd_en;
wire63:0fifo_dout;
wire fifo_empty;
wire fifo_rd_err;
reg31:0col_cnt;
reg31:0row_cnt;
assign fifo_rd_err = fifo_rd_en & fifo_empty;
//--------------------------------------------------------------
conv_fifo //fwft_fifo
u_conv_fifo (
.rst ( !wr_rstn || ! rd_rstn ),
.wr_clk ( wr_clk ),
.din ( fifo_din ), //
.wr_en ( fifo_wr_en ), //
.full ( fifo_full ), // output wire full
.rd_clk ( rd_clk ),
.rd_en ( fifo_rd_en ), // input wire rd_en
.dout ( fifo_dout ), //
.empty ( fifo_empty ) // output wire empty
);
//--------------------------------------------------------------
assign fifo_rd_en = !fifo_empty & (i_ready | !o_vld);
always@(posedge rd_clk or negedge rd_rstn)begin
if(rd_rstn==1'b0)begin
o_vld <= 1'b0;
end
else if(fifo_rd_en)begin
o_vld <= 1'b1;
end
else if(o_vld & i_ready)begin
o_vld <= 1'b0;
end
end
always@(posedge rd_clk or negedge rd_rstn)begin
if(rd_rstn==1'b0)begin
col_cnt <='d0;
end
else if(o_vld & i_ready)begin
if(col_cnt==i_width-1)begin
col_cnt <='d0;
end
else begin
col_cnt <= col_cnt + 1'b1;
end
end
end
always@(posedge rd_clk or negedge rd_rstn)begin
if(rd_rstn==1'b0)begin
o_last <='d0;
end
else if(o_vld & i_ready)begin
if(col_cnt==i_width-1)begin
o_last <='d0;
end
else if(col_cnt==i_width-2)begin
o_last <= 1'b1;
end
end
end
always@(posedge rd_clk or negedge rd_rstn)begin
if(rd_rstn==1'b0)begin
row_cnt <='d0;
end
else if(o_vld & i_ready)begin
if(row_cnt==i_high-1 && col_cnt==i_width-1)begin
row_cnt <='d0;
end
else if(col_cnt==i_width-1)begin
row_cnt <=row_cnt + 'd1;
end
end
end
always@(posedge rd_clk or negedge rd_rstn)begin
if(rd_rstn==1'b0)begin
o_sof <='d0;
end
else if(fifo_rd_en)begin
o_sof <='d0;
end
else if(row_cnt==0 && col_cnt==0)begin
o_sof <='d1;
end
end
assign o_data = fifo_dout;
endmodule