一、模块说明
在FPGA设计中,经常要用到帧接口和流接口,有时候需要帧接口到流接口的跨时钟处理,依据这种需求开发帧转流跨时钟处理模块
二、frame_to_stream跨时钟处理
module frame_to_stream
(
input wr_clk,
input wr_rstn,
input i_vsync,
input i_hsync,
input i_data_vld,
input[63:0] i_data,
input rd_clk,
input rd_rstn,
input[31:0] i_high,
input[31:0] i_width,
output reg o_vld,
output reg o_sof,
output reg o_last,
output[63:0] o_data,
input i_ready
);
reg[1:0] vsync_r;
reg[1:0] hsync_r;
reg[1:0] data_vld_r;
reg[63:0] data_r[1:0];
always@(posedge wr_clk)begin
vsync_r <= {vsync_r[0],i_vsync};
hsync_r <= {hsync_r[0],i_hsync};
data_vld_r <= {data_vld_r[0],i_data_vld};
data_r[0] <= i_data;
data_r[1] <= data_r[0];
end
wire fifo_wr_en;
wire fifo_full;
wire fifo_wr_err;
wire[63:0]fifo_din;
assign fifo_wr_en = vsync_r[1] & hsync_r[1] & data_vld_r[1];
assign fifo_wr_err = fifo_wr_en & fifo_full;
assign fifo_din = data_r[1];
wire fifo_rd_en;
wire[63:0]fifo_dout;
wire fifo_empty;
wire fifo_rd_err;
reg[31:0]col_cnt;
reg[31:0]row_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