下面展示一些 内联代码片
。
//`include "../../rtl/defines.v" //mike 0201
//`define FFD 1
module fifo_async # (
parameter DATWIDTH = 18,
parameter FIFODEEP = 8,
parameter ADRWIDTH = 3
)
(
input wire rstn,
//write
input wire wclk,
input wire we,
input wire [DATWIDTH-1:0] dati,
//read
input wire rclk,
input wire re,
output reg [DATWIDTH-1:0] dato,
//status
output reg full,
output reg empty
);
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
reg [DATWIDTH-1:0] mem [FIFODEEP-1:0];
wire [ADRWIDTH-1:0] wadr;
reg [ ADRWIDTH:0] wptr_b;
reg [ ADRWIDTH:0] wptr_g;
reg [ ADRWIDTH:0] rptr_g_wsync1;
reg [ ADRWIDTH:0] rptr_g_wsync2;
wire [ ADRWIDTH:0] wptr_b_next;
wire [ ADRWIDTH:0] wptr_g_next;
wire full_flag;
wire [ADRWIDTH-1:0] radr;
reg [ ADRWIDTH:0] rptr_b;
reg [ ADRWIDTH:0] rptr_g;
reg [ ADRWIDTH:0] wptr_g_rsync1;
reg [ ADRWIDTH:0] wptr_g_rsync2;
wire [ ADRWIDTH:0] rptr_b_next;
wire [ ADRWIDTH:0] rptr_g_next;
wire empty_flag;
//------------------------------------------------------------------------
// rptr sync to wclk domain
always @(posedge wclk or negedge rstn)
if (~rstn)
begin
rptr_g_wsync1 <= 0;
rptr_g_wsync2 <= 0;
end
else
begin
rptr_g_wsync1 <= rptr_g;
rptr_g_wsync2 <= rptr_g_wsync1;
end
// fifo write ptr and flag
always @(posedge wclk or negedge rstn)
if (~rstn)
begin
wptr_b <= 0;
wptr_g <= 0;
full <= 0;
end
else
begin
wptr_b <= wptr_b_next;
wptr_g <= wptr_g_next;
full <= full_flag;
end
assign wptr_b_next = (we && ~full) ? (wptr_b + 1'b1) : wptr_b;
assign wptr_g_next = {1'b0, wptr_b_next[ADRWIDTH:1]} ^ wptr_b_next;
assign full_flag = (wptr_g_next == {~rptr_g_wsync2[ADRWIDTH:ADRWIDTH-1], rptr_g_wsync2[ADRWIDTH-2:0]});
assign wadr = wptr_b[ADRWIDTH-1:0];
// wptr sync to rclk domain
always @(posedge rclk or negedge rstn)
if (~rstn)
begin
wptr_g_rsync1 <= 0;
wptr_g_rsync2 <= 0;
end
else
begin
wptr_g_rsync1 <= wptr_g;
wptr_g_rsync2 <= wptr_g_rsync1;
end
// fifo read ptr and flag
always @(posedge rclk or negedge rstn)
if (~rstn)
begin
rptr_b <= 0;
rptr_g <= 0;
empty <= 1;
end
else
begin
rptr_b <= rptr_b_next;
rptr_g <= rptr_g_next;
empty <= empty_flag;
end
assign rptr_b_next = (re && ~empty) ? (rptr_b + 1'b1) : rptr_b;
assign rptr_g_next = {1'b0, rptr_b_next[ADRWIDTH:1]} ^ rptr_b_next;
assign empty_flag = (rptr_g_next == wptr_g_rsync2);
assign radr = rptr_b[ADRWIDTH-1:0];
// fifo access
always @(posedge wclk)
if (we && ~full)
mem[wadr] <= dati;
always@(posedge rclk, negedge rstn)
if(!rstn)
dato <= {DATWIDTH{1'b0}};
else if(re && ~empty)
dato <= mem[radr];
//assign dato = mem[radr];
endmodule
//`undef FFD