数据FIFO
一、写使能-wr_en,写数据-wdata
//din :8bit
assign wr_en = din_vld ;//din_vld 为数据有效指示信号
assign wdata = {din_sop,din_eop,din};//如果是包文形式,可以将sop和eop写入数据FIFO的数据中,可以保证起始和结束条件与数据始终同步
注意:此刻的写使能和写数据均为组合逻辑,如果其中一个使用了时序逻辑,那么基于同步的原则,另一个也必须进行同步处理
always @(posedge clk or negedge rst_n)begin
if(rst_n==0)begin
wr_en <= 0;
end
else begin
wr_en <= din_vld;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==0)begin
wdata <= 0;
end
else begin
wdata <= {din_sop,din_eop,din};
end
end
二、读使能-rd_en,输出的数据-q[7:0]
assign rd_en = empty == 0;//数据FIFO不为空
//优先使用Show-ahead模式
三、读数据部分(包括din_sop和din_eop)
//dout
always@(posedge clk or negedge rst_n)begin
if(rst_n == 0)begin
dout <= 0;
end
else begin
dout <= q[7:0];
end
end
assign dout_sop_tmp = q[9] && rd_en;
assign dout_eop_tmp = q[8] && rd_en;
//dout_sop
always@(posedge clk or negedge rst_n)begin
if(rst_n == 0)begin
dout_sop <= 0;
end
else begin
dout_sop <= dout_sop_tmp;
end
end
//dout_eop
always@(posedge clk or negedge rst_n)begin
if(rst_n == 0)begin
dout_sop <= 0;
end
else begin
dout_sop <= dout_eop_tmp;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n == 0)begin
dout_vld <= 0;
end
else begin
dout_vld <= rd_en;
end
end
信息FIFO
不需要很大的存储空间,但是可以很方便的告诉数据FIFO什么时候读。例:要求收到eop时输出报文,假如第一个报文长度为200字节,而第二个报文长度小于200字节,若设置读使能为 rd_en = empty == 0 && din_eop;
那么在第一个报文没有输出完时就收到了第二个报文的eop,这时根据rd_en的逻辑该输出下一个报文,但是显然第一个报文并未输出完,就会造成数据的缺失。
根据FIFO的读写隔离原则,使用信息FIFO。
一、写使能和写数据
assign msg_wr_en = din_eop ; //输入一个完整的报文,此处条件可以根据不同需求进行更改
assign msg_wr_wdata = 1 ;//因为此处只是起到一个标识作用,故存储什么都可以,如果有需要存储的,比如报文的长度可以存入信息FIFO
二、读使能
assign msg_rd_en = msg_empty == 0;//信息FIFO不为空,表明数据FIFO中已经有至少一个完整的报文