////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