sync fifo code.doc

advertisement
////TOP LEVEL MODULE////
modulesync_fifo#( parameter addr_width=4,
parameterdata_width=16,
parameter depth=16,
parameteraempty=3,
parameterafull=3)
(
//INPUTS//
inputclk,
inputreset_n,
input flush,
//clock input
//reset
//flush
input [data_width-1:0] write_data,
inputwdata_valid,
inputread_req,
//write data
//write valid data
//read request
//OUTPUTS//
output [data_width-1:0] read_data, //read data
outputrdata_valid,
//read data valid
outputfifo_empty,
//fifo empty flag
outputfifo_aempty,
//fifoalmostempty flag
outputfifo_full,
//fifo full flag
outputfifo_afull,
//fifoalmostempty flag
outputwrite_ack
//write acknowlegment
);
//Internal wires//
wire [addr_width:0] read_ptr;
//read pointer
wire [addr_width:0] write_ptr;
//write pointer
wirerd_en;
//read enable
wirewr_en;
//write enable
write_control_logicwrite_cntl(
.read_ptr(read_ptr),
.flush(flush),
.reset_n(reset_n),
.clk(clk),
.wdata_valid(wdata_valid),
.write_ack(write_ack),
.wr_en(wr_en),
.write_ptr(write_ptr),
.fifo_full(fifo_full),
.fifo_afull(fifo_afull)
);
read_control_logicread_cntl(
.write_ptr(write_ptr),
.clk(clk),
.reset_n(reset_n),
.flush(flush),
.read_req(read_req),
.rd_en(rd_en),
.rdata_valid(rdata_valid),
.fifo_empty(fifo_empty),
.read_ptr(read_ptr),
.fifo_aempty(fifo_aempty)
);
memory_arraymem_arr(
.write_addr(write_ptr[addr_width-1:0]),
.read_addr(read_ptr[addr_width-1:0]),
.wr_en(wr_en),
.rd_en(rd_en),
.clk(clk),
.write_data(write_data),
.read_data(read_data)
);
endmodule
//write control logic//
module write #(
parameteraddr_width=4,
parameterafull=3,
parameter depth=16)
(
// Inputs//
inputclk,
inputreset_n,
input flush,
inputwdata_valid,
input [addr_width:0] read_ptr,
// Outputs//
outputregwrite_ack,
outputwr_en,
outputreg [addr_width:0] write_ptr,
outputfifo_full,
outputregfifo_afull
);
//Internal wires//
wire [addr_width-1:0] write_addr;
wire [addr_width-1:0] read_addr;
//Read and Write addresses from their pointers//
assignread_addr= read_ptr[addr_width-1:0];
assignwrite_addr= write_ptr[addr_width-1:0];
//When fifo is full there will be no write//
assignwr_en= wdata_valid&&(~fifo_full);
//Logic for fifo full status//
//Fifo full is asserted when both pointers are at same address but msb are different//
assign fifo_full=((write_addr==read_addr)&&(write_ptr[addr_width]^read_ptr[addr_width]));
//Logic for almost full status//
always @*
begin
if(write_ptr[addr_width]==read_ptr[addr_width])
fifo_afull=((write_addr-read_addr)>=(depth- afull));
else
fifo_afull=((read_addr-write_addr)<=afull);
end
//Logic for Write pointer//
always @(posedgeclk or negedgereset_n)
begin
if (~reset_n)
begin
write_ptr<={(addr_width+1){1'b0}};
write_ack<=1'b0;
end
else if(flush)
begin
write_ptr<={(addr_width+1){1'b0}};
write_ack<=1'b0;
end
else if(wr_en)
begin
write_ptr<=write_ptr+{{addr_width{1'b0}},1'b1};
write_ack<=1'b1;
end
else
begin
write_ack<=1'b0;
end
end
endmodule
//Read control logic//
module read #(
parameteraddr_width=4,
parameteraempty=3,
parameter depth=16)
(
//Inputs//
inputclk,
inputreset_n,
input flush,
inputread_req,
input [addr_width:0] write_ptr,
//Outputs//
outputrd_en,
outputregrdata_valid,
outputfifo_empty,
outputregfifo_aempty,
outputreg [addr_width:0] read_ptr
);
//Internal wires//
wire [addr_width-1:0] read_addr;
wire [addr_width-1:0] write_addr;
//Read and Write address from their pointers//
assignread_addr=read_ptr[addr_width-1:0];
assignwrite_addr=write_ptr[addr_width-1:0];
//FIFO is empty when read pointer is equal to write pointer//
assignfifo_empty=(read_ptr==write_ptr);
//When FIFO is empty there will be no read//
assignrd_en=read_req&&(~fifo_empty);
// Logic for almost empty flag//
always @*
begin
if (read_ptr[addr_width]==write_ptr[addr_width])
fifo_aempty=((write_addr-read_addr)<= aempty);
else
fifo_aempty=((read_addr-write_addr)>=(depth - aempty));
end
//Logic for Read pointer and read valid data//
always @(posedgeclk or negedgereset_n)
begin
if (~reset_n)
read_ptr<={(addr_width+1){1'b0}};
else if (flush)
read_ptr<={(addr_width+1){1'b0}};
else if (rd_en)
begin
read_ptr<=read_ptr+{{addr_width {1'b0}},1'b1};
rdata_valid<= 1'b1;
end
else
rdata_valid<= 1'b0;
end
endmodule
//Memory array//
module memory #(
parameteraddr_width=4,
parameter depth=16,
parameterdata_width=16)
(
//Inputs//
input [addr_width-1:0] write_addr,
input [addr_width-1:0] read_addr,
inputwr_en,
inputrd_en,
inputclk,
input [data_width-1:0] write_data,
//Output//
outputreg [data_width-1:0] read_data
);
//Register//
reg [data_width-1:0] memory [0:depth-1];
//Write into memory(data-in)//
always@(posedgeclk)
begin
if(wr_en)
memory[write_addr]<= write_data;
end
//Read from memory(data out)//
always@(posedgeclk)
begin
if(rd_en)
begin
read_data<= memory[read_addr];
end
end
endmodule
Download