此模块由用户指定IP,PORT以及对方的IP(可选),符合上述条件的内容被放在FIFO里,供上层用户执行读取操作。
module fifo_ether2user_if #(
parameter AW = 12 , // NOT LESS THAN 10
)(
input clk,rst,
input [31:0] cfg_my_ip,
input [15:0] cfg_my_port,
input [31:0] cfg_from_ip,
input [15:0] s_udp_len ,
input [7:0] s_udp_din ,
input s_udp_valid,s_udp_sof,s_udp_eof,s_udp_chksum_ok,
input [31:0] s_udp_src_ip,s_udp_dst_ip,
input [15:0] s_udp_src_port,s_udp_dst_port,
output [7:0] m_dout,
output m_valid,
input m_read,
output [15:0] m_len
);
reg [7:0] s_udp_dinr ; always @ ( posedge clk ) s_udp_dinr <= s_udp_din ;
reg s_udp_validr ; always @ ( posedge clk ) s_udp_validr <= s_udp_valid ;
wire if_my_ip = cfg_my_ip == s_udp_dst_ip ;
wire if_my_port = cfg_my_port == s_udp_dst_port ;
wire if_valid_from_ip = (cfg_from_ip==0)?1:(cfg_from_ip == s_udp_src_ip) ;
reg if_fifo_wr_accept ;always @(posedge clk )if (s_udp_valid)if_fifo_wr_accept <= if_my_ip & if_my_port & if_valid_from_ip ;
sc_fifo#(
.AW(AW),
.DW(8)
)sc_fifo(
.clk(clk),
.rst(rst),
.din( s_udp_dinr ),
.wr ( if_fifo_wr_accept & s_udp_validr ),
.full( ),
.dout( m_dout ),
.rd( m_read ),
.empty( empty ),
.fwft_dout( ),
.fifo_cntr( m_len )
);
assign m_valid = ~ empty ;
endmodule
module sc_fifo#(
parameter AW = 5 ,
parameter DW = 64,
parameter ALMOST_FULL = 10 ,
parameter ALMOST_EMPTY = 12
)(
input clk,rst,
input [ DW-1:0] din,
input wr,rd,
output full,empty,
output reg almost_full,
output reg almost_empty,
output reg [ DW-1:0] dout,
output [ DW-1:0] fwft_dout,
output reg [ AW:0] fifo_cntr
);
parameter MAX_FIFO_LEN = (1<<AW ) ;
parameter ALMOST_FULL_LEN = MAX_FIFO_LEN - 10 ;
parameter ALMOST_EMPTY_LEN = 5 ;
reg [ DW-1:0] buff[0: MAX_FIFO_LEN -1] ;
reg [ AW-1:0] wr_ptr, rd_ptr ;
assign full = fifo_cntr == ( MAX_FIFO_LEN ) ;
assign empty = fifo_cntr == 0 ;
always @* almost_full <= fifo_cntr > ALMOST_FULL_LEN ;
always @* almost_empty <= fifo_cntr < ALMOST_EMPTY_LEN ;
wire valid_rd = rd ;
wire valid_wr = wr ;
always@(posedge clk) if (rst) wr_ptr <= 0;else if(valid_wr)wr_ptr<=wr_ptr+1;
always@(posedge clk) if (rst)rd_ptr <= 0 ;else if (valid_rd)rd_ptr <= rd_ptr+1;
always@(posedge clk)
casex ({rst,valid_wr,valid_rd})
3'b1xx : fifo_cntr<=0;
3'b010 : fifo_cntr<=fifo_cntr+1;
3'b001 : fifo_cntr<=fifo_cntr-1;
3'b011 ,3'b000 :fifo_cntr<=fifo_cntr ;
endcase
always@(posedge clk) if (valid_wr) buff[wr_ptr] <=din ;
always@(posedge clk) if (valid_rd) dout <= buff[rd_ptr] ;
assign fwft_dout = buff[rd_ptr] ;
endmodule