module syncfifo
#(
parameter DWIDTH = 8,
parameter AWIDTH = 8
)
(
input clock, //时钟,上升沿
input rstn, //复位,低电平有效
input [DWIDTH-1:0] din, //写入数据
input wrreq, //写请求,高有效
input rdreq, //读请求,低有效
output reg [DWIDTH-1:0] dout, //读出数据
output full, //FIFO 满指示,高有效
output empty //FIFO 空指示,低有效
);
reg [AWIDTH-1:0] read_addr;
reg [AWIDTH-1:0] write_addr;
wire we;
wire [DWIDTH-1:0] data;
wire [DWIDTH-1:0] q;
reg [AWIDTH:0] counter;
assign full = (read_addr == (write_addr+1)) | (counter>=(1<<AWIDTH)-1);
assign empty = (read_addr == write_addr) | (counter==0);
// write to ram
//=====================
assign we = wrreq & !full;
assign data = din;
always @(posedge clock or negedge rstn)
if(!rstn)
write_addr <= 0;
else if(wrreq & !full)
write_addr <= write_addr + 1'b1;
// read from ram
//=======================
always @(posedge clock or negedge rstn)
if(!rstn) begin
read_addr <= 0;
dout <= 0;
end
else if(rdreq & !empty) begin
read_addr <= read_addr + 1'b1;
dout <= q;
end
// Full Empty
//----------------------
always @(posedge clock or negedge rstn)
if(!rstn) counter <= 0;
else if(wrreq & !rdreq & !full) counter <= counter + 1'b1;
else if(!wrreq & rdreq & !empty) counter <= counter -1;
ram_dual
#(.DWIDTH(DWIDTH),
.AWIDTH(AWIDTH))
u_ram_dual
(
.data (data),
.read_addr (read_addr),
.write_addr (write_addr),
.we (we),
.read_clock (clock),
.write_clock(clock),
.q (q)
);
endmodule
//双口ram模型,可用fpga综合
module ram_dual
#(
parameter DWIDTH = 8,
parameter AWIDTH = 8
)
(
input [DWIDTH-1:0] data,
input [AWIDTH-1:0] read_addr, write_addr,
input we, read_clock, write_clock,
output reg [DWIDTH-1:0] q
);
// Declare the RAM variable
reg [DWIDTH-1:0] ram[(1<<AWIDTH)-1:0];
always @ (posedge write_clock)
begin
// Write
if (we)
ram[write_addr] <= data;
end
always @ (posedge read_clock)
begin
// Read
q <= ram[read_addr];
end
endmodule