frame_to_stream跨时钟处理verilog实现

一、模块说明

在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