/*****************************************************************
*****************************專案描述*****************************
1.輸入報文長度64~2048位元組;
2.輸入報文之間最小間隔為兩拍;
3.輸出報文的前兩拍添加16bit報文長度資訊;
第1拍為報文長度高8位;第2拍為報文長度低8位;第3拍開始為輸入報文;
******************************************************************
*****************************************************************/
module mod_qdr(
// system signals
input sys_clk ,
input sys_rst_n ,
//input
input sop_in , //輸入報文頭指示信號,高有效
input eop_in , //輸入報文尾指示信號,高有效
input vld_in , //輸入報文資料有效信號,高有效
input [7:0] data_in , //輸入報文資料
//output
output reg sop_out , //輸出報文頭指示信號,高有效
output reg eop_out , //輸出報文尾指示信號,高有效
output reg vld_out , //輸出報文資料有效信號,高有效
output wire[7:0] data_out //輸出報文資料
);
reg rst_n_d0 ;
reg rst_n_d1 ;
reg wr_en ;
reg rd_en ;
reg [15:0] data_len ; //報文長度
wire [ 7:0] dout ;
wire full ;
wire empty ;
wire almost_empty;
wire flag ; //報文輸入完畢信號
reg flag_d0 ;
reg flag_d1 ;
assign flag = vld_in && eop_in;
fifo_generator_0 u_fifo (
.clk (sys_clk) , // input wire clk
.srst (rst_n_d1) , // input wire srst
.din (data_in) , // input wire [7 : 0] din
.wr_en (wr_en) , // input wire wr_en
.rd_en (rd_en) , // input wire rd_en
.dout (dout) , // output wire [7 : 0] dout
.full (full) , // output wire full
.empty (empty) , // output wire empty
.almost_empty (almost_empty) // output wire almost_empty
);
//異步復位,同步釋放
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
rst_n_d0 <= 1'b0 ;
else
rst_n_d0 <= 1'b1 ;
end
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
rst_n_d1 <= 1'b0 ;
else
rst_n_d1 <= rst_n_d0 ;
end
//對報文輸入完畢信號flag寄存兩拍,用做輸出報文長度的時刻
always @(posedge sys_clk or negedge rst_n_d1)begin
if(!rst_n_d1)begin
flag_d0 <= 1'b0 ;
flag_d0 <= 1'b0 ;
end
else begin
flag_d0 <= flag ;
flag_d0 <= flag_d0 ;
end
end
//對報文長度計數
always @(posedge sys_clk or negedge rst_n_d1)begin
if(!rst_n_d1)
data_len <= 16'd0 ;
else if(sop_in == 1'b1 && vld_in == 1'b1)
data_len <= 16'd1 ;
else if(eop_in == 1'b1 && vld_in == 1'b1)
data_len <= 16'd0 ;
else if(vld_in == 1'b1)
data_len <= data_len +1'b1;
else
data_len <= 16'd0 ;
end
//data_out:前兩拍輸出報文長度,第3拍開始為輸入的報文資料
always @(posedge sys_clk or negedge rst_n_d1)begin
if(!rst_n_d1)
data_out <= 8'd0 ;
else if(flag_d0)
data_out <= data_len[15:8];
else if(flag_d1)
data_out <= data_len[ 7:0];
else
data_out <= dout ;
end
//rd_en
always @(posedge sys_clk or negedge rst_n_d1)begin
if(!rst_n_d1)
rd_en <= 1'b0 ;
else if(flag_d1)
rd_en <= 1'b1 ;
else if(almost_empty)
rd_en <= 1'b0 ;
/* else
rd_en <= rd_en ; //這樣寫有沒問題??
*/
end
//sop_out
always @(posedge sys_clk or negedge rst_n_d1)begin
if(!rst_n_d1)
sop_out <= 1'b0 ;
else if(flag_d0)
sop_out <= 1'b1 ;
else if(flag_d1)
sop_out <= 1'b0 ;
else
sop_out <= 1'b0 ; //這樣寫有沒問題??
end
//eop_out
always @(posedge sys_clk or negedge rst_n_d1)begin
if(!rst_n_d1)
eop_out <= 1'b0 ;
else if(almost_empty) //empty信號可以這樣使用嗎?
eop_out <= 1'b1 ;
else if(empty)
eop_out <= 1'b0 ;
/* else
eop_out <= eop_out ; //這樣寫有沒問題??
*/
end
//vld_out
always @(posedge sys_clk or negedge rst_n_d1)begin
if(!rst_n_d1)
vld_out <= 1'b0 ;
else if(flag_d0)
vld_out <= 1'b1 ;
else if(almost_empty) //almost_empty信號可以這樣使用嗎?
vld_out <= 1'b0 ;
else
vld_out <= 1'b0 ;
end
endmodule
uj5u.com熱心網友回復:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/283832.html
標籤:硬件設計
上一篇:學習智能家居產品開發
下一篇:ue4右擊,選單顯示超過螢屏頂部