⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rx_client_fifo.v

📁 基于FPGA的防火墙系统设计.rar
💻 V
📖 第 1 页 / 共 3 页
字号:
  end
   
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      frame_count <= 9'd0;
    else
      begin
      if (frame_transmitted_pulse == 1'b1 && ll_frame_received == 1'b0)
        frame_count <= frame_count - 1;
      else if (frame_transmitted_pulse == 1'b0 && ll_frame_received == 1'b1)
        frame_count <= frame_count + 1;
      end
  end
   
  // **If the FIFO is expanded to use more BRAM, ensure frame count signals are
  // wide enough to count the maximum number of frames that can be stored in FIFO** 
  assign frame_in_fifo = (frame_count == 9'd0) ? 1'b0 : 1'b1;		

  //---------------------------------------------------------------------------
  // Hold the frame_in_fifo signal until the frame has actually been 
  // transmitted. This will be used to gate the data_valid output.
  //---------------------------------------------------------------------------
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      frame_in_fifo_held <= 1'b0;
    else if ((frame_in_progress == 1'b1 && read_data_valid_int == 1'b0) | frame_in_fifo == 1'b1)
      frame_in_fifo_held <= frame_in_fifo;
  end

  //--------------------------------------------------------------------
  // Generate a signal to indicate when the fifo is in the process of
  // transmitting a frame.
  //--------------------------------------------------------------------
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      frame_in_progress <= 1'b0;
    else if ((dst_rdy_in_n == 1'b0 && read_data_valid_pipe[0] == 1'b0) || frame_in_fifo_held == 1'b0) 
      frame_in_progress <= 1'b0;
    else if (frame_transmitted == 1'b1)
      frame_in_progress <= 1'b1;
  end
  
  //--------------------------------------------------------------------
  // At the start of each frame we need to clock the first byte of  
  // data from the memory as we have to change this as soon as ack is 
  // received. 
  //--------------------------------------------------------------------
  assign queue = frame_in_fifo & !read_data_valid_pipe[0];

  //--------------------------------------------------------------------
  // We have to calculate the occupancy of the fifo as we need to drop  
  // frames when it is about to overflow. This will be calculated on  
  // the rx clock and so we need to get the read_addr into the rx clock  
  // domain. To do this we first convert the tx_addr to gray codes as 
  // this helps to counter problems with the 2 addresses being on 
  // different clock domains. This gray code representation of the  
  // read_addr is then clocked onto the rx_clk and converted back to 
  // binary.  The binary version can then be compared to to the 
  // rx_addr on the rx_clk.
  // **If the FIFO is expanded to use more BRAM, increase read_addr_gray,
  // rx_read_addr_gray and rx_read_addr_bin size as required ** 
  //--------------------------------------------------------------------

  // Convert read address to gray codes.
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      read_addr_gray <= 12'h001;
    else
      begin 
      read_addr_gray[11] <= read_addr_reg[11];
      read_addr_gray[10] <= read_addr_reg[11] ^ read_addr_reg[10];	   
      read_addr_gray[9]  <= read_addr_reg[10] ^ read_addr_reg[9];
      read_addr_gray[8]  <= read_addr_reg[9]  ^ read_addr_reg[8];
      read_addr_gray[7]  <= read_addr_reg[8]  ^ read_addr_reg[7];
      read_addr_gray[6]  <= read_addr_reg[7]  ^ read_addr_reg[6];
      read_addr_gray[5]  <= read_addr_reg[6]  ^ read_addr_reg[5];
      read_addr_gray[4]  <= read_addr_reg[5]  ^ read_addr_reg[4];
      read_addr_gray[3]  <= read_addr_reg[4]  ^ read_addr_reg[3];
      read_addr_gray[2]  <= read_addr_reg[3]  ^ read_addr_reg[2];
      read_addr_gray[1]  <= read_addr_reg[2]  ^ read_addr_reg[1];
      read_addr_gray[0]  <= read_addr_reg[1]  ^ read_addr_reg[0];
      end
  end

  // Clock this onto the rx_clk.
  always @(posedge rx_clk)
  begin
    if (rx_reset == 1'b1)
      rx_read_addr_gray <= 12'h000;
    else if (rx_enable == 1'b1)
      rx_read_addr_gray <= read_addr_gray;
  end

  // Convert this back to binary.
  always @(posedge rx_clk)
  begin
    if (rx_reset == 1'b1)
      rx_read_addr_bin <= 12'h000;
    else if (rx_enable == 1'b1)
      begin
      rx_read_addr_bin[11] <= rx_read_addr_gray[11];
      rx_read_addr_bin[10] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10];
      rx_read_addr_bin[9]  <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
                            ^ rx_read_addr_gray[9];
      rx_read_addr_bin[8]  <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
                            ^ rx_read_addr_gray[9]  ^ rx_read_addr_gray[8];
      rx_read_addr_bin[7]  <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
                            ^ rx_read_addr_gray[9]  ^ rx_read_addr_gray[8]
                            ^ rx_read_addr_gray[7];
      rx_read_addr_bin[6]  <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
                            ^ rx_read_addr_gray[9]  ^ rx_read_addr_gray[8]
                            ^ rx_read_addr_gray[7]  ^ rx_read_addr_gray[6];
      rx_read_addr_bin[5]  <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
                            ^ rx_read_addr_gray[9]  ^ rx_read_addr_gray[8]
                            ^ rx_read_addr_gray[7]  ^ rx_read_addr_gray[6]
                            ^ rx_read_addr_gray[5];
      rx_read_addr_bin[4]  <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
                            ^ rx_read_addr_gray[9]  ^ rx_read_addr_gray[8]
                            ^ rx_read_addr_gray[7]  ^ rx_read_addr_gray[6]
                            ^ rx_read_addr_gray[5]  ^ rx_read_addr_gray[4];       
      rx_read_addr_bin[3]  <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
                            ^ rx_read_addr_gray[9]  ^ rx_read_addr_gray[8]
                            ^ rx_read_addr_gray[7]  ^ rx_read_addr_gray[6]
                            ^ rx_read_addr_gray[5]  ^ rx_read_addr_gray[4]
                            ^ rx_read_addr_gray[3];
      rx_read_addr_bin[2]  <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
                            ^ rx_read_addr_gray[9]  ^ rx_read_addr_gray[8]
                            ^ rx_read_addr_gray[7]  ^ rx_read_addr_gray[6]
                            ^ rx_read_addr_gray[5]  ^ rx_read_addr_gray[4]
                            ^ rx_read_addr_gray[3]  ^ rx_read_addr_gray[2];
      rx_read_addr_bin[1]  <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
                            ^ rx_read_addr_gray[9]  ^ rx_read_addr_gray[8]
                            ^ rx_read_addr_gray[7]  ^ rx_read_addr_gray[6]
                            ^ rx_read_addr_gray[5]  ^ rx_read_addr_gray[4]
                            ^ rx_read_addr_gray[3]  ^ rx_read_addr_gray[2]
                            ^ rx_read_addr_gray[1];
      rx_read_addr_bin[0]  <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
                            ^ rx_read_addr_gray[9]  ^ rx_read_addr_gray[8]
                            ^ rx_read_addr_gray[7]  ^ rx_read_addr_gray[6]
                            ^ rx_read_addr_gray[5]  ^ rx_read_addr_gray[4]
                            ^ rx_read_addr_gray[3]  ^ rx_read_addr_gray[2]
                            ^ rx_read_addr_gray[1]  ^ rx_read_addr_gray[0];
      end
  end

  // Set the full flag to go up when the rx address is 16 bytes 
  // away from the tx address.
  always @(posedge rx_clk)
  begin
    if (rx_reset == 1'b1)
      rx_addr_sub <= 12'h000;
    else if (rx_enable == 1'b1)
      rx_addr_sub <= rx_read_addr_bin - rx_addr_reg;
  end

  assign full_pulse = (rx_addr_sub < 12'd16 && rx_addr_sub > 12'd1) ? 1'b1 : 1'b0;

  //---------------------------------------------------------------------------
  // Fifo status indicates the amount of memory space used.
  // This needs to be calculated on the read clock domain and so rx_addr must
  // be converted to the read clock domain via gray code.
  // **If the FIFO is expanded to use more BRAM, increase rx_addr_gray,
  // ll_rx_addr_gray and ll_rx_addr_bin size as required ** 
  //---------------------------------------------------------------------------
  // Convert the rx address to gray codes.
  always @(posedge rx_clk)
  begin
    if (rx_reset == 1'b1)
      rx_addr_gray <= 12'h000;
    else if (rx_enable == 1'b1)
      begin
      rx_addr_gray[11] <= rx_addr_reg[11];
      rx_addr_gray[10] <= rx_addr_reg[11] ^ rx_addr_reg[10];
      rx_addr_gray[9]  <= rx_addr_reg[10] ^ rx_addr_reg[9];
      rx_addr_gray[8]  <= rx_addr_reg[9]  ^ rx_addr_reg[8];
      rx_addr_gray[7]  <= rx_addr_reg[8]  ^ rx_addr_reg[7];
      rx_addr_gray[6]  <= rx_addr_reg[7]  ^ rx_addr_reg[6];
      rx_addr_gray[5]  <= rx_addr_reg[6]  ^ rx_addr_reg[5];
      rx_addr_gray[4]  <= rx_addr_reg[5]  ^ rx_addr_reg[4];
      rx_addr_gray[3]  <= rx_addr_reg[4]  ^ rx_addr_reg[3];
      rx_addr_gray[2]  <= rx_addr_reg[3]  ^ rx_addr_reg[2];
      rx_addr_gray[1]  <= rx_addr_reg[2]  ^ rx_addr_reg[1];
      rx_addr_gray[0]  <= rx_addr_reg[1]  ^ rx_addr_reg[0];
      end
  end

  // Clock this onto the read clock.
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      ll_rx_addr_gray <= 12'h000;
    else
      ll_rx_addr_gray <= rx_addr_gray;
  end

  // Convert this back to binary.
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      ll_rx_addr_bin <= 12'h000;
    else
      begin
      ll_rx_addr_bin[11] <=   ll_rx_addr_gray[11];
      ll_rx_addr_bin[10] <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10];
      ll_rx_addr_bin[9]  <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
                            ^ ll_rx_addr_gray[9];
      ll_rx_addr_bin[8]  <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
                            ^ ll_rx_addr_gray[9]  ^ ll_rx_addr_gray[8];
      ll_rx_addr_bin[7]  <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
                            ^ ll_rx_addr_gray[9]  ^ ll_rx_addr_gray[8]
                            ^ ll_rx_addr_gray[7];
      ll_rx_addr_bin[6]  <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
                            ^ ll_rx_addr_gray[9]  ^ ll_rx_addr_gray[8]
                            ^ ll_rx_addr_gray[7]  ^ ll_rx_addr_gray[6];
      ll_rx_addr_bin[5]  <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
                            ^ ll_rx_addr_gray[9]  ^ ll_rx_addr_gray[8]
                            ^ ll_rx_addr_gray[7]  ^ ll_rx_addr_gray[6]
                            ^ ll_rx_addr_gray[5];
      ll_rx_addr_bin[4]  <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
                            ^ ll_rx_addr_gray[9]  ^ ll_rx_addr_gray[8]
                            ^ ll_rx_addr_gray[7]  ^ ll_rx_addr_gray[6]
                            ^ ll_rx_addr_gray[5]  ^ ll_rx_addr_gray[4];       
      ll_rx_addr_bin[3]  <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
                            ^ ll_rx_addr_gray[9]  ^ ll_rx_addr_gray[8]
                            ^ ll_rx_addr_gray[7]  ^ ll_rx_addr_gray[6]
                            ^ ll_rx_addr_gray[5]  ^ ll_rx_addr_gray[4]
                            ^ ll_rx_addr_gray[3];
      ll_rx_addr_bin[2]  <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
                            ^ ll_rx_addr_gray[9]  ^ ll_rx_addr_gray[8]
                            ^ ll_rx_addr_gray[7]  ^ ll_rx_addr_gray[6]
                            ^ ll_rx_addr_gray[5]  ^ ll_rx_addr_gray[4]
                            ^ ll_rx_addr_gray[3]  ^ ll_rx_addr_gray[2];
      ll_rx_addr_bin[1]  <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
                            ^ ll_rx_addr_gray[9]  ^ ll_rx_addr_gray[8]
                            ^ ll_rx_addr_gray[7]  ^ ll_rx_addr_gray[6]
                            ^ ll_rx_addr_gray[5]  ^ ll_rx_addr_gray[4]
                            ^ ll_rx_addr_gray[3]  ^ ll_rx_addr_gray[2]
                            ^ ll_rx_addr_gray[1];
      ll_rx_addr_bin[0]  <=   ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
                            ^ ll_rx_addr_gray[9]  ^ ll_rx_addr_gray[8]
                            ^ ll_rx_addr_gray[7]  ^ ll_rx_addr_gray[6]
                            ^ ll_rx_addr_gray[5]  ^ ll_rx_addr_gray[4]
                            ^ ll_rx_addr_gray[3]  ^ ll_rx_addr_gray[2]
                            ^ ll_rx_addr_gray[1]  ^ ll_rx_addr_gray[0];
      end
  end
  
  // Calculate FIFO occupancy
  assign fifo_status_full = ll_rx_addr_bin - read_addr_reg + 1;

  // Truncate to give 4 bit signal
  assign fifo_status_out = fifo_status_full[11:8];

  //---------------------------------------------------------------------------
  // Hold this signal until the good/bad indicator that signals the 
  // end of the frame arrives.
  //---------------------------------------------------------------------------
  always @(posedge rx_clk)
  begin
    if (rx_reset == 1'b1)
      overflow_int_held <= 1'b0;
    else if (rx_enable == 1'b1)
      begin    
      if (full_pulse == 1'b1)
        overflow_int_held <= 1'b1;
      else if (rx_good_frame_reg == 1'b1 || rx_bad_frame_reg == 1'b1)
        overflow_int_held <= 1'b0; 
      end
  end

  // Assign overflow output signal
  assign overflow = overflow_int_held;

  //---------------------------------------------------------------------------
  // Register the rx and read addresses on their respective clocks. These 
  // are then input to the overflow processes above.
  // **If the FIFO is expanded to use more BRAM, increase rx_addr_reg and
  // read_addr_reg size as required ** 
  //---------------------------------------------------------------------------  
  always @(posedge rx_clk)
  begin
    if (rx_reset == 1'b1)
      rx_addr_reg <= 12'h000;
    else if (rx_enable == 1'b1)
      rx_addr_reg <= rx_addr;
  end

  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      read_addr_reg <= 12'h001;
    else if (read_addr_enable_int == 1'b1)
      read_addr_reg <= read_addr_int;
  end


endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -