异步fifo设计(四)

这篇文章主要是上篇文章的verilog代码实现,现在将代码贴上:

module fifo #(parameter size_data=8,
              parameter size_addr=4)
(input wr_inc,wr_clk,wr_rst,
 input rd_inc,rd_clk,rd_rst,
 input [size_data-1:0]wr_data,
 output wr_full,rd_empty,
 output [size_data-1:0]rd_data);
 
 wire [size_addr-1:0] wr_addr,rd_addr;
 wire [size_addr:0]wr_ptr,rd_ptr,wq2_rd_ptr,rq2_wr_ptr;
 
 
 cmp      m1(rd_ptr,wr_ptr,wr_rst,full_flag,empty_flag);
 ram_fifo m2(wr_clk,wr_addr,wr_data,wr_inc,rd_addr,rd_data);
 rd_empty m3(rd_clk,rd_inc,rd_rst,empty_flag,rd_empty,rd_ptr);
 wr_full  m4(wr_clk,wr_rst,wr_inc,full_flag,wr_ptr,wr_full);
endmodule

module fifo_ram(wr_clk,wr_addr,wr_data,wr_inc,rd_addr,rd_data);
parameter size_addr=4;
parameter size_data=8;
parameter depth=1<

module cmp(rd_ptr,wr_ptr,wr_rst,full_flag,empty_flag);
parameter size_addr=4;
parameter size_data=8;
parameter high=1;
input [size_addr-1:0]rd_ptr,wr_ptr;
input wr_rst;
output full_flag,empty_flag;
wire   full_flag,empty_flag;

wire dir_set,dir_clr;
reg dir;
wire equal_ptr;

assign equal_ptr=(rd_ptr==wr_ptr);

assign dir_set=~(wr_ptr[size_addr-1]^rd_ptr[size_addr-2])& ~(wr_ptr[size_addr-2]^rd_ptr[size_addr-1]);
assign dir_dir=~((~(wr_ptr[size_addr-2]^rd_ptr[size_addr-1])&(wr_ptr[size_addr-1]^rd_ptr[size_addr-2]))|(!wr_rst));

always@(dir_set or dir_dir)
begin
 if(!dir_set)dir=1;
 else if(!dir_clr) dir=0;
 else dir=high;
end

assign full_flag=~(dir&&equal_ptr);
assign empty_flag=~(~dir&&equal_ptr);
endmodule


module rd_empty (rd_clk,rd_inc,rd_rst,empty_flag,rd_empty,rd_ptr);
parameter size_addr=4;
parameter size_data=8;

input rd_clk,rd_inc,rd_rst;
input empty_flag;
output [size_addr-1:0]rd_ptr;
output rd_empty;
reg [size_addr-1:0]rd_ptr;
reg rd_empty;
reg rd_empty_temp;

reg  [size_addr-1:0] rd_bin;
wire [size_addr-1:0] rd_bin_next,rd_grey_next;

assign rd_bin_next=rd_bin+(rd_inc&(!rd_empty));
assign rd_grey_next=rd_bin_next<<1 ^ rd_bin_next;

always@(posedge rd_clk or negedge rd_rst)
begin
 if(!rd_rst) 
 begin
 rd_ptr<=0;
 rd_bin<=0;
 end
 else
begin
 rd_bin<=rd_bin_next;
 rd_ptr<=rd_grey_next;
 end
end

always@(posedge rd_clk or negedge empty_flag)
begin
 if(!empty_flag) {rd_empty,rd_empty_temp}<=2'b11;//空状态
 else {rd_empty,rd_empty_temp}<={rd_empty_temp,~empty_flag};//同步器
end

endmodule


module wr_ful(wr_clk,wr_rst,wr_inc,full_flag,wr_ptr,wr_full);
parameter size_addr=4;
parameter size_data=8;
input wr_clk,wr_rst,wr_inc;
input full_flag;
output [size_addr-1:0] wr_ptr;
output wr_full;
reg  [size_addr-1:0] wr_ptr;
reg  wr_full;
reg  wr_full_temp;

reg [size_addr-1:0] wr_bin;
wire[size_addr-1:0] wr_bin_next,wr_grey_next;

assign wr_bin_next=wr_bin+(wr_inc & (!wr_full));
assign wr_grey_next=wr_bin_next<<1 ^ wr_bin_next;

always@(posedge wr_clk or negedge wr_rst)
begin
if(!wr_rst)
begin
  wr_bin<=0;
  wr_ptr<=0;
end
else
begin
 wr_bin<=wr_bin_next;
 wr_ptr<=wr_grey_next;
end
end

always@(posedge wr_clk or negedge full_flag or negedge wr_rst)//注意不能忽略写复位
begin
 if(!full_flag) {wr_full,wr_full_temp}<=2'b11;
 else if(!wr_rst) {wr_full,wr_full_temp}<=2'b00;
 else {wr_full,wr_full_temp}<={wr_full_temp,~full_flag};
end
endmodule




你可能感兴趣的:(verilog,IC模块设计)