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

📄 tx_client_fifo.v

📁 基于FPGA的防火墙系统设计.rar
💻 V
📖 第 1 页 / 共 4 页
字号:

  //--------------------------------------------------------------------
  // The RAMB16_S9_S9 primitive defines the parity inputs and outputs 
  // as signals of type std_logic_vector(0 downto 0). These are 
  // connected to single bit std_logic signals in the FIFO. The 
  // following line converts between the different types.
  //--------------------------------------------------------------------
  assign data_valid_reg[0] = write_data_valid_reg;

  //---------------------------------------------------------------------------
  // The fifo cannot accept data when delimiting the frame, by writing a zero
  // value of data_valid_reg into the memory. Set dst_rdy_out_n to high when
  // delimiting frame or when when fifo is full.  The signal is also forced to
  // zero when the fifo has overflown, so as to flush rest of frame from
  // upstream source
  //---------------------------------------------------------------------------
  assign dst_rdy_out_n = overflow_int_held ? 1'b0 : (
                        (eof_in_n_reg == 1'b0 && eof_in_n_reg_reg == 1'b1) ? 1'b1 : (
                         memory_full ? 1'b1 : 1'b0));  

  //---------------------------------------------------------------------------
  // The signal byte_accept indicates when input data is valid.  For this to be
  // true both src_rdy_in_n and dst_rdy_out_n must be low.
  // The signal is active high
  //---------------------------------------------------------------------------
  assign byte_accept   = (eof_in_n_reg == 1'b0 && eof_in_n_reg_reg == 1'b1) ? 1'b0 : (
                          memory_full ? 1'b0 : (
                          overflow_int_held ? 1'b0 : (
                          src_rdy_in_n ? 1'b0 : 1'b1 )));

  //---------------------------------------------------------------------------
  // In overflow condition the incoming data is to be ignored until the end of
  // that frame is reached.  Register input data to find end of frame
  //---------------------------------------------------------------------------
  assign overflow_accept = (overflow_eof_in_n_reg == 1'b0 && overflow_eof_in_n_reg_reg == 1'b1) ? 1'b0 : (
                            src_rdy_in_n ? 1'b0 : 1'b1 );

  always @(posedge write_clock_in)
  begin
    if (ll_reset == 1'b1)
      overflow_eof_in_n_reg       <= 1'b1;
    else if (overflow_accept == 1'b1)
      overflow_eof_in_n_reg       <= eof_in_n;
  end

  always @(posedge write_clock_in)
  begin
    if (ll_reset == 1'b1)
      begin
      overflow_eof_in_n_reg_reg      <= 1'b1;
      overflow_eof_in_n_reg_reg_reg  <= 1'b1;
      end
    else
      begin
      overflow_eof_in_n_reg_reg      <= overflow_eof_in_n_reg;
      overflow_eof_in_n_reg_reg_reg  <= overflow_eof_in_n_reg_reg;
      end
  end
  
  //--------------------------------------------------------------------
  // The write enable is asserted when the FIFO is receiving valid data
  // or storing delimiter byte.  Data is written to upper or lower block RAM
  // dependant on the value of the upper address bit
  // **If the FIFO is expanded to use more BRAM, create write_mem_enable signals
  // for to address each BRAM using write_addr[max:11]**
  //-------------------------------------------------------------------- 
  assign write_mem_enable   = write_data_valid_reg | (!eof_in_n_reg_reg & eof_in_n_reg_reg_reg);
  assign write_mem_enable_l = write_mem_enable & !(write_addr[11]);   
  assign write_mem_enable_u = write_mem_enable & write_addr[11];

  //---------------------------------------------------------------------------
  // Now write the registered data and data_valid signals into the memory
  // on the write clock. Starting and stopping the address will control the
  // flow of data into the memory.
  //
  // **If the FIFO is expanded to use more BRAM, instantiate as below.
  // To control the write side, create a write_mem_enable signal for each BRAM as
  // above, data inputs and the write_addr[10:0] are common to all BRAMs.
  // To control the transmit side, create a tx_mem_enable signal for each BRAM as
  // below, and create tx_data_int and tx_dv_dv signals for each BRAM.  Mux
  // data outputs as shown below.  The tx_addr[10:0] is common to all BRAMs.**
  //--------------------------------------------------------------------------- 
  // Block Ram for lower address space (write_addr(11) = 0)
  RAMB16_S9_S9 ramgen_l
    (.WEB   (write_mem_enable_l),
      .ENB   (VCC),
      .SSRB  (ll_reset),
      .CLKB  (write_clock_in),
      .ADDRB (write_addr[10:0]),
      .DIB   (data_in_reg),
      .DIPB  (data_valid_reg),
      .WEA   (GND),
      .ENA   (tx_mem_enable_l),
      .SSRA  (tx_reset),
      .CLKA  (tx_clk),
      .ADDRA (tx_addr[10:0]),
      .DIA   (GND_BUS),
      .DIPA  (GND_BUS[0:0]),
      .DOA   (tx_data_int_l),
      .DOPA  (tx_dv_dv_l));

  // Block Ram for upper address space (write_addr(11) = 1)
  RAMB16_S9_S9 ramgen_u
    (.WEB   (write_mem_enable_u),
      .ENB   (VCC),
      .SSRB  (ll_reset),
      .CLKB  (write_clock_in),
      .ADDRB (write_addr[10:0]),
      .DIB   (data_in_reg),
      .DIPB  (data_valid_reg),
      .WEA   (GND),
      .ENA   (tx_mem_enable_u),
      .SSRA  (tx_reset),
      .CLKA  (tx_clk),
      .ADDRA (tx_addr[10:0]),
      .DIA   (GND_BUS),
      .DIPA  (GND_BUS[0:0]),
      .DOA   (tx_data_int_u),
      .DOPA  (tx_dv_dv_u));

  
  //--------------------------------------------------------------------
  // Choose the output data from the Block RAM given the read address and
  // convert the parity signal from type std_logic_vector to std_logic.
  // **If the FIFO is expanded to use more BRAM, increase the MUX width to take
  // in all BRAM data outputs, and select based on tx_addr_reg[max:11]**
  //--------------------------------------------------------------------
  assign tx_data_valid_int = tx_addr_reg[11] ? tx_dv_dv_u[0] : tx_dv_dv_l[0];

  assign tx_data_int       = tx_addr_reg[11] ? tx_data_int_u : tx_data_int_l;

  //--------------------------------------------------------------------
  // The read enable for the memory is asserted whenever there is a frame in
  // the fifo to be read out.  Data is read from the upper or lower block RAM
  // given by the top bit of the read address.
  // **If the FIFO is expanded to use more BRAM, create tx_mem_enable signals
  // for each BRAM, using tx_addr[max:11]**
  //-------------------------------------------------------------------- 
  assign tx_mem_enable   = ((frame_in_fifo | frame_in_fifo_held) | queue_for_retransmit) & tx_enable;
  assign tx_mem_enable_l = tx_mem_enable & !tx_addr[11];
  assign tx_mem_enable_u = tx_mem_enable & tx_addr[11];
  
  //---------------------------------------------------------------------------
  // Register the output of the block ram.  Derive the client output signals
  // from the data.
  //---------------------------------------------------------------------------
  always @(posedge tx_clk)
  begin
    if (tx_reset == 1'b1)
      begin
      tx_data_pipe      <= 8'h00;
      tx_data_valid_reg <= 1'b0;
      end
    else if (tx_enable == 1'b1)
      begin      
      if (tx_ack == 1'b1 || tx_addr_enable_reg == 1'b1)  
        begin        
        tx_data_pipe      <= tx_data_int;
        tx_data_valid_reg <= tx_data_valid_int;
        end
     end
  end
 
  always @(posedge tx_clk)
  begin
    if (tx_reset == 1'b1)
      tx_data_valid_pipe    <= 1'b0;
    else if (tx_enable == 1'b1)
      tx_data_valid_pipe <= tx_data_valid_int;
  end

  assign tx_data       = tx_data_pipe;
  assign tx_data_valid = tx_data_valid_reg & (frame_in_fifo_held | queue_for_retransmit_held)
                                                                          & !(col_no_retransmit);

  //---------------------------------------------------------------------------
  // We need to drop frames if the FIFO is overloaded. Therefore we have to keep
  // a note of the address in the fifo that the first byte of data has been
  // written to. This means that in the event of an oversize frame being written
  // we can go back to its' first byte and write over it with the next frame.
  // **If the FIFO is expanded to use more BRAM, increase start_addr size as
  // required ** 
  //--------------------------------------------------------------------------- 
  always @(posedge write_clock_in)
  begin
    if (ll_reset == 1'b1)
      start_addr        <= 12'h000;
    else if (eof_in_n_reg_reg == 1'b0 && eof_in_n_reg_reg_reg == 1'b1)
      // end of last good frame
      start_addr        <= write_addr;
  end

  //---------------------------------------------------------------------------
  // Now do the write_addr generation. We want to count up when valid data is
  // being received and also one cycle at the end to delimit the frame.  If the
  // fifo overflows then the write address is set back to the start address.
  // **If the FIFO is expanded to use more BRAM, increase write_addr_int size as
  // required ** 
  //---------------------------------------------------------------------------
  always @(posedge write_clock_in)
  begin
    if (ll_reset == 1'b1)
      write_addr_int <= 12'h0;
    else if (overflow_int_held == 1'b1)
      write_addr_int <= start_addr;
    else if (write_addr_enable == 1'b1)
      write_addr_int <= write_addr + 1;
  end

  assign write_addr   = write_addr_int;
  
  //--------------------------------------------------------------------
  // The write address counter is enabled when write_data_valid is high or 
  // the end of frame is reached. This will enable the frame data 
  // and 1 extra empty byte to be stored.
  //-------------------------------------------------------------------- 
  assign write_addr_enable = write_data_valid | (!eof_in_n_reg & eof_in_n_reg_reg);

  //---------------------------------------------------------------------------
  // A signal that indicates that there has been a frame stored
  //---------------------------------------------------------------------------
  always @(posedge write_clock_in)
  begin
    if (ll_reset == 1'b1)
      frame_received <= 1'b0;
    else
      frame_received <= !(eof_in_n_reg_reg) & eof_in_n_reg_reg_reg;
  end

  //---------------------------------------------------------------------------
  // Now generate the read address on to the tx side.
  // tx_addr will count up when there is a data to be transmitted
  // **If the FIFO is expanded to use more BRAM, increase tx_addr_int and 
  // tx_addr_int_plus size as required **
  //---------------------------------------------------------------------------
  always @(posedge tx_clk)
  begin
    if (tx_reset == 1'b1)
      tx_addr_int <= 12'h001;
    else if (tx_enable == 1'b1)
      begin 
      if (tx_collision_reg == 1'b1 && tx_retransmit_reg == 1'b1)
        tx_addr_int <= tx_start_addr ;
      else if (tx_addr_enable == 1'b1)
        tx_addr_int <= tx_addr + 1 ;
      end
  end

  always @(posedge tx_clk)
  begin
    if (tx_reset == 1'b1)
      tx_addr_int_plus <= 12'h002;
    else if (tx_enable == 1'b1)
      begin 
        if (tx_addr_enable == 1'b1)
          tx_addr_int_plus <= tx_addr + 2;
      end
  end

  //--------------------------------------------------------------------
  // When the acknowledge is received from the MAC the address is
  // incremented. This ensures that the data is output correctly
  //-------------------------------------------------------------------- 
  assign tx_addr = (tx_ack == 1'b1) ? tx_addr_int_plus : tx_addr_int;

  //--------------------------------------------------------------------
  // The transmitter address counter is enabled when there is a frame 
  // in the FIFO, the data_valid output from the block memory is high, 
  // there is an acknowledge or an acknowledge has been received for the 
  // current frame or when the it is necessary to 'queue' the data up. 
  // This may be necessary to get the first byte of the frame at the 
  // output of the circuit, ready for an acknowledge signal from the MAC.
  //--------------------------------------------------------------------  
  assign tx_addr_enable = (((tx_ack | frame_in_progress) & 
                           ((tx_data_valid_int & ((frame_in_fifo & !(queue_for_retransmit_held))
                           | tx_data_valid_pipe)) & frame_in_fifo_held)))
                           | queue | queue_for_retransmit;	    

  //---------------------------------------------------------------------------
  // Register the tx address enable for use on BRAM output data selection
  //---------------------------------------------------------------------------
  always @(posedge tx_clk)
  begin
    if (tx_reset == 1'b1)
      tx_addr_enable_reg <= 1'b0;
    else if (tx_enable == 1'b1) 
      tx_addr_enable_reg <= tx_addr_enable;
  end

  //---------------------------------------------------------------------------
  // A signal that indicates that there has been a frame transmitted
  //---------------------------------------------------------------------------
  always @(posedge tx_clk)
  begin
    if (tx_reset == 1'b1)
      frame_transmitted_toggle <= 1'b0;
    else if (tx_enable == 1'b1)
      begin
      if (tx_ack == 1'b1)
        frame_transmitted_toggle <= !frame_transmitted_toggle;
      end
  end
  
  //---------------------------------------------------------------------------
  // A signal that indicates that there has been a frame has been retransmitted
  //---------------------------------------------------------------------------
  always @(posedge tx_clk)
  begin
    if (tx_reset == 1'b1)
      frame_retransmit_toggle  <= 1'b0;
    else if (tx_enable == 1'b1)
      begin 
      if (tx_retransmit_reg == 1'b1)
        frame_retransmit_toggle  <= !frame_retransmit_toggle; 
      end
  end
    
  //--------------------------------------------------------------------
  // In order to gauge whether there is a frame in the fifo we have to 
  // generate a counter that holds the number of frames that are  
  // present.  If a frame is received then we increment this, if one  
  // is transmitted then we decrement it. The ll_frame_transmitted_toggle 
  // signal is the frame_transmitted_toggle signal re-clocked onto 
  // write_clock, a faster clock. The ll_frame_transmitted signal is
  // asserted for 1 cycle when an edge is detected on
  // ll_frame_transmitted_toggle.
  // This is repeated for the frame_retransmit_toggle
  //--------------------------------------------------------------------
  // Generate frame_transmitted pulse on write clock
  always @(posedge write_clock_in)
  begin
    if (ll_reset == 1'b1)

⌨️ 快捷键说明

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