📄 fifo_generator_v2_0.v
字号:
//Write not successful ideal_wr_ack <= 0; ideal_overflow <= 1; //FIFO is really not close to full, so change flag status. ideal_full <= 1'b0; ideal_almost_full <= 1'b0; ideal_wr_count <= num_write_words[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH]; end //(tmp_wr_listsize == 0) end else begin //If the FIFO is full, do NOT perform the write, // update flags accordingly if ((tmp_wr_listsize + C_RATIO_R - 1)/C_RATIO_R >= C_FIFO_WR_DEPTH) begin //write unsuccessful - do not change contents //Do not acknowledge the write ideal_wr_ack <= 0; //throw an overflow error ideal_overflow <= 1; //Reminder that FIFO is still full ideal_full <= 1'b1; ideal_almost_full <= 1'b1; ideal_wr_count <= num_write_words[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH]; //If the FIFO is one from full end else if ((tmp_wr_listsize + C_RATIO_R - 1)/C_RATIO_R == C_FIFO_WR_DEPTH-1) begin //Add value on DIN port to FIFO write_fifo; next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH; //Write successful, so issue acknowledge // and no error ideal_wr_ack <= 1; ideal_overflow <= 0; //This write is CAUSING the FIFO to go full ideal_full <= 1'b1; ideal_almost_full <= 1'b1; ideal_wr_count <= num_write_words[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH]; //If the FIFO is 2 from full end else if ((tmp_wr_listsize + C_RATIO_R - 1)/C_RATIO_R == C_FIFO_WR_DEPTH-2) begin //Add value on DIN port to FIFO write_fifo; next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH; //Write successful, so issue acknowledge // and no error ideal_wr_ack <= 1; ideal_overflow <= 0; //Still 2 from full ideal_full <= 1'b0; //2 from full, and writing, so set almost_full ideal_almost_full <= 1'b1; ideal_wr_count <= num_write_words[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH]; //If the FIFO is not close to being full end else if ((tmp_wr_listsize + C_RATIO_R - 1)/C_RATIO_R < C_FIFO_WR_DEPTH-2) begin //Add value on DIN port to FIFO write_fifo; next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH; //Write successful, so issue acknowledge // and no error ideal_wr_ack <= 1; ideal_overflow <= 0; //Not even close to full. ideal_full <= 1'b0; ideal_almost_full <= 1'b0; ideal_wr_count <= num_write_words[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH]; end end end else begin //(WR_EN == 1'b1) //If user did not attempt a write, then do not // give ack or err ideal_wr_ack <= 0; ideal_overflow <= 0; //Implied statements: //ideal_empty <= ideal_empty; //ideal_almost_empty <= ideal_almost_empty; //Check for full if ((tmp_wr_listsize + C_RATIO_R - 1)/C_RATIO_R >= C_FIFO_WR_DEPTH) ideal_full <= 1'b1; else ideal_full <= 1'b0; //Check for almost_full if ((tmp_wr_listsize + C_RATIO_R - 1)/C_RATIO_R >= C_FIFO_WR_DEPTH-1) ideal_almost_full <= 1'b1; else ideal_almost_full <= 1'b0; ideal_wr_count <= num_write_words[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH]; end end /********************************************************* * Programmable FULL flags *********************************************************/ //Single Programmable Full Constant Threshold if (C_PROG_FULL_TYPE==1) begin if (RST) begin prog_full_d <= C_PROG_FULL_RESET_VAL; // If we will be going at or above C_PROG_FULL_THRESH_ASSERT_VAL // threshold on the next clock cycle, then assert // PROG_FULL. There may be pending reads that haven't caught // up yet, but we need to assume the worst end else if ((num_write_words >= C_PROG_FULL_THRESH_ASSERT_VAL-1) && WR_EN) begin prog_full_d <= 1'b1; // If we are at or above the C_PROG_FULL_THRESH_ASSERT_VAL, then // assert PROG_FULL end else if (num_write_words >= C_PROG_FULL_THRESH_ASSERT_VAL) begin prog_full_d <= 1'b1; // If we are below the C_PROG_FULL_THRESH_NEGATE_VAL, then // de-assert PROG_FULL end else if (num_write_words < C_PROG_FULL_THRESH_ASSERT_VAL) begin prog_full_d <= 1'b0; end //Two Programmable Full Constant Thresholds end else if (C_PROG_FULL_TYPE==2) begin if (RST) begin prog_full_d <= C_PROG_FULL_RESET_VAL; // If we will be going at or above C_PROG_FULL_THRESH_ASSERT_VAL // threshold on the next clock cycle, then assert // PROG_FULL. There may be pending reads that haven't caught // up yet, but we need to assume the worst end else if ((num_write_words == C_PROG_FULL_THRESH_ASSERT_VAL-1) && WR_EN) begin prog_full_d <= 1'b1; // If we are at or above the C_PROG_FULL_THRESH_ASSERT_VAL, then // assert PROG_FULL end else if (num_write_words >= C_PROG_FULL_THRESH_ASSERT_VAL) begin prog_full_d <= 1'b1; // If we are below the C_PROG_FULL_THRESH_NEGATE_VAL, then // de-assert PROG_FULL end else if (num_write_words < C_PROG_FULL_THRESH_NEGATE_VAL) begin prog_full_d <= 1'b0; end //Single Programmable Full Threshold Input end else if (C_PROG_FULL_TYPE==3) begin if (RST) begin prog_full_d <= C_PROG_FULL_RESET_VAL; // If we will be going at or above C_PROG_FULL_THRESH_ASSERT_VAL // threshold on the next clock cycle, then assert // PROG_FULL. There may be pending reads that haven't caught // up yet, but we need to assume the worst end else if ((num_write_words == PROG_FULL_THRESH-1) && WR_EN) begin prog_full_d <= 1'b1; // If we are at or above the PROG_FULL_THRESH_ASSERT, then // assert PROG_FULL end else if (num_write_words >= PROG_FULL_THRESH) begin prog_full_d <= 1'b1; // If we are below the PROG_FULL_THRESH_NEGATE, then // de-assert PROG_FULL end else if (num_write_words < PROG_FULL_THRESH) begin prog_full_d <= 1'b0; end //Two Programmable Full Threshold Inputs end else if (C_PROG_FULL_TYPE==4) begin if (RST) begin prog_full_d <= C_PROG_FULL_RESET_VAL; // If we will be going at or above PROG_FULL_THRESH_ASSERT // threshold on the next clock cycle, then assert // PROG_FULL. There may be pending reads that haven't caught // up yet, but we need to assume the worst end else if ((num_write_words == PROG_FULL_THRESH_ASSERT-1) && WR_EN) begin prog_full_d <= 1'b1; // If we are at or above the PROG_FULL_THRESH_ASSERT, then // assert PROG_FULL end else if (num_write_words >= PROG_FULL_THRESH_ASSERT) begin prog_full_d <= 1'b1; // If we are below the PROG_FULL_THRESH_NEGATE, then // de-assert PROG_FULL end else if (num_write_words < PROG_FULL_THRESH_NEGATE) begin prog_full_d <= 1'b0; end end ideal_prog_full <= prog_full_d; num_wr_bits <= next_num_wr_bits; rd_ptr_wrclk_q <= rd_ptr_wrclk; rd_ptr_wrclk <= rd_ptr; ideal_wr_count_q <= ideal_wr_count; end // write always always @(posedge RD_CLK or posedge RST) begin : gen_fifo_r /****** Reset fifo (case 1)***************************************/ if (RST) begin num_rd_bits <= 0; next_num_rd_bits <= 0; rd_ptr <= C_RD_DEPTH -1; wr_ptr_rdclk <= C_WR_DEPTH -1; ideal_dout <= dout_reset_val; ideal_valid <= 1'b0; ideal_underflow <= 1'b0; ideal_empty <= 1'b1; ideal_almost_empty <= 1'b1; ideal_rd_count <= 0; ideal_rd_count_q <= 0; ideal_prog_empty <= 1'b1; end else begin //Determine the current number of words in the FIFO tmp_rd_listsize = (C_RATIO_W > 1) ? num_rd_bits/C_DIN_WIDTH : num_rd_bits/C_DOUT_WIDTH; wr_ptr_rdclk_next = wr_ptr; if (wr_ptr_rdclk < wr_ptr_rdclk_next) begin next_num_rd_bits = num_rd_bits + C_DIN_WIDTH*(wr_ptr_rdclk +C_WR_DEPTH - wr_ptr_rdclk_next); end else begin next_num_rd_bits = num_rd_bits + C_DIN_WIDTH*(wr_ptr_rdclk - wr_ptr_rdclk_next); end /*****************************************************************/ // Read Operation - Read Latency 1 /*****************************************************************/ if (C_PRELOAD_LATENCY==1) begin if (RD_EN == 1'b1) begin if (ideal_empty == 1'b1) begin //If the FIFO is completely empty, and is reporting empty if (tmp_rd_listsize/C_RATIO_W <= 0) begin //Do not change the contents of the FIFO //Do not acknowledge the read from empty FIFO ideal_valid <= 1'b0; //Throw an underflow error ideal_underflow <= 1'b1; //Reminder that FIFO is still empty ideal_empty <= 1'b1; ideal_almost_empty <= 1'b1; ideal_rd_count <= num_read_words[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH]; end // if (tmp_rd_listsize <= 0) //If the FIFO is one from empty, but it is reporting empty else if (tmp_rd_listsize/C_RATIO_W == 1) begin //Do not change the contents of the FIFO //Do not acknowledge the read from empty FIFO ideal_valid <= 1'b0; //Throw an underflow error ideal_underflow <= 1'b1; //Note that FIFO is no longer empty, but is almost empty (has one word left) ideal_empty <= 1'b0; ideal_almost_empty <= 1'b1; ideal_rd_count <= num_read_words[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH]; end // if (tmp_rd_listsize == 1) //If the FIFO is two from empty, and is reporting empty else if (tmp_rd_listsize/C_RATIO_W == 2) begin //Do not change the contents of the FIFO //Do not acknowledge the read from empty FIFO ideal_valid <= 1'b0; //Throw an underflow error ideal_underflow <= 1'b1; //Fifo has two words, so is neither empty or almost empty ideal_empty <= 1'b0; ideal_almost_empty <= 1'b0; ideal_rd_count <= num_read_words[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH]; end // if (tmp_rd_listsize == 2) //If the FIFO is not close to empty, but is reporting that it is // Treat the FIFO as empty this time, but unset EMPTY flags. if ((tmp_rd_listsize/C_RATIO_W > 2) && (tmp_rd_listsize/C_RATIO_W<C_FIFO_RD_DEPTH)) begin //Do not change the contents of the FIFO //Do not acknowledge the read from empty FIFO ideal_valid <= 1'b0; //Throw an underflow error ideal_underflow <= 1'b1; //Note that the FIFO is No Longer Empty or Almost Empty ideal_empty <= 1'b0; ideal_almost_empty <= 1'b0; ideal_rd_count <= num_read_words[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH]; end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1)) end // else: if(ideal_empty == 1'b1) else //if (ideal_empty == 1'b0) begin //If the FIFO is completely full, and we are successfully reading from it if (tmp_rd_listsize/C_RATIO_W >= C_FIFO_RD_DEPTH) begin //Read the value from the FIFO read_fifo; next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH; //Acknowledge the read from the FIFO, no error ideal_valid <= 1'b1; ideal_underflow <= 1'b0; //Not close to empty ideal_empty <= 1'b0; ideal_almost_empty <= 1'b0; ideal_rd_count <= num_read_words[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH]; end // if (tmp_rd_listsize == C_FIFO_RD_DEPTH) //If the FIFO is not close to being empty else if ((tmp_rd_listsize/C_RATIO_W > 2) && (tmp_rd_listsize/C_RATIO_W<=C_FIFO_RD_DEPTH)) begin //Read the value from the FIFO read_fifo; next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH; //Acknowledge the read from the FIFO, no error ideal_valid <= 1'b1; ideal_underflow <= 1'b0; //Not close to empty ideal_empty <= 1'b0; ideal_almost_empty <= 1'b0; ideal_rd_count <= num_read_words[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH]; end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1)) //If the FIFO is two from empty else if (tmp_rd_listsize/C_RATIO_W == 2) begin //Read the value from the FIFO read_fifo; next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -