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

📄 rx_client_fifo.v

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

  // Block Ram for upper address space (rx_addr(11) = '1')
  RAMB16_S9_S9 ramgen_u
    (
      .WEA   (rx_mem_enable_u),
      .ENA   (rx_enable),
      .SSRA  (rx_reset),
      .CLKA  (rx_clk),
      .ADDRA (rx_addr[10:0]),
      .DIA   (rx_data_reg),
      .DIPA  (rx_dv_dv),
      .WEB   (GND),
      .ENB   (read_mem_enable_u),  
      .SSRB  (ll_reset),
      .CLKB  (read_clock_in),
      .ADDRB (read_addr[10:0]),
      .DIB   (GND_BUS[7:0]),
      .DIPB  (GND_BUS[0:0]),
      .DOB   (read_data_int_u),
      .DOPB  (read_dv_dv_u));

  //---------------------------------------------------------------------------
  // Enable the read from each Block Ram
  // **If the FIFO is expanded to use more BRAM, create read_mem_enable signals
  // for each BRAM, using read_addr[max:11]**
  //---------------------------------------------------------------------------
  assign read_mem_enable_u = read_addr_enable_int & read_addr[11];
  assign read_mem_enable_l = read_addr_enable_int & !read_addr[11];
  
  //---------------------------------------------------------------------------
  // 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 read_addr_reg[max:11]**
  //---------------------------------------------------------------------------
  assign read_data_int       = read_addr_reg[11] ? read_data_int_u : read_data_int_l;
  
  assign read_data_valid_int = read_addr_reg[11] ? read_dv_dv_u[0] : read_dv_dv_l[0];

  //---------------------------------------------------------------------------
  // The block ram output data is registered in the data pipe whenever valid
  // data is being read from the block ram
  //---------------------------------------------------------------------------
  assign read_pipe_enable     = read_addr_enable_reg_int;
  
  //---------------------------------------------------------------------------
  // Register the output of the Block Ram in a data pipe.
  //---------------------------------------------------------------------------
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      begin
      read_data_pipe[1]         <= 8'h00;
      read_data_pipe[0]         <= 8'h00;
      end
    else
      begin
      if (read_pipe_enable == 1'b1)
	begin
        read_data_pipe[0]       <= read_data_int;
        read_data_pipe[1]       <= read_data_pipe[0];
	end
      end
  end

  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      begin
      read_data_valid_pipe[0]   <= 8'h00;
      read_data_valid_pipe[1]   <= 8'h00;
      end 
    else
      begin
      if (read_pipe_enable == 1'b1)
	begin
        read_data_valid_pipe[0] <= read_data_valid_int;
        read_data_valid_pipe[1] <= read_data_valid_pipe[0];
        end
      end
  end

  //---------------------------------------------------------------------------
  // Construct the local link control signals from the state of data in the
  // output data and data valid pipe.  All control signals are active low.
  //---------------------------------------------------------------------------
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
    begin
      sof_out_n_int      <= 1'b1;
      eof_out_n_int      <= 1'b1;
      src_rdy_out_n_int  <= 1'b1;
      end
    else
      begin
      if (read_pipe_enable == 1'b1)
	begin
        eof_out_n_int     <= read_data_valid_int | !read_data_valid_pipe[0];
        sof_out_n_int     <= read_data_valid_pipe[1] | !read_data_valid_pipe[0];
        src_rdy_out_n_int <= !read_data_valid_pipe[0];
        end
      end
  end
  
  //---------------------------------------------------------------------------
  // Generate control signal to indicate when a frame is in the process of
  // being tranmitted on the interface.
  //---------------------------------------------------------------------------
  // sending frame signal goes high at sof and low at eof
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      sending_frame <= 1'b0;
    else if (read_pipe_enable == 1'b1 && read_data_valid_pipe[1] == 1'b0 && read_data_valid_pipe[0] == 1'b1)
      sending_frame <= 1'b1;
    else if (read_pipe_enable == 1'b1 && read_data_valid_int == 1'b0 && read_data_valid_pipe[0] == 1'b1)
      sending_frame <= 1'b0;
  end

  // register sending_frame signal but only register a zero signal when data is
  // being being accepted by upstream user.  This ensures the signal stays high
  // until the eof signal has been read by the user.
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      sending_frame_reg <= 1'b0;
    else if (sending_frame == 1'b1)
      sending_frame_reg <= 1'b1;
    else if (sending_frame == 1'b0 && dst_rdy_in_n == 1'b0)
      sending_frame_reg <= 1'b0;
  end

  //---------------------------------------------------------------------------
  // Assign Local-link Output Signals
  // All control signals are active low
  //---------------------------------------------------------------------------
  assign data_out      = read_data_pipe[1];
  assign rem_out       = 1'b1;
  assign sof_out_n     = sof_out_n_int;
  assign eof_out_n     = eof_out_n_int;
  assign src_rdy_out_n = src_rdy_out_n_int | !(sending_frame | sending_frame_reg);

  //---------------------------------------------------------------------------
  // We need to drop bad frames. 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 a bad frame occuring we can go back to its' first 
  // byte and write over it with the next frame. By looking at the 
  // rx_data_valid signal we can see when the gap between the frames is and 
  // go back to this address when a bad frame indicator is sent.
  // **If the FIFO is expanded to use more BRAM, increase start_addr size as
  // required ** 
  //--------------------------------------------------------------------------- 
  always @(posedge rx_clk)
  begin
    if (rx_reset == 1'b1)
      start_addr        <= 12'h000;
    else if (rx_enable == 1'b1)
      begin
      if (rx_good_frame_reg == 1'b1 && overflow_int_held == 1'b0)
        // End address of the last good frame.
        start_addr        <= rx_addr;
      end
  end 
   
  //---------------------------------------------------------------------------
  // Now do the rx_addr generation. We want to count up basically when 
  // rx_data_valid is high. We also want one cycle where data valid is 
  // low to seperate the frames. So we'll count up when data_valid or 
  // data_valid_reg is high.
  // **If the FIFO is expanded to use more BRAM, increase rx_addr_int size as
  // required ** 
  //---------------------------------------------------------------------------
  always @(posedge rx_clk)
  begin
    if (rx_reset == 1'b1)
      rx_addr_int <= 12'h000;
    else if (rx_enable == 1'b1)
      begin
      if (overflow_int_held == 1'b1 || rx_bad_frame_reg == 1'b1)
	rx_addr_int <= start_addr;
      else if (rx_addr_enable == 1'b1)
	rx_addr_int <= rx_addr + 1;
      end 
  end

  //--------------------------------------------------------------------
  // The receiver address counter is enabled when the data_valid or 
  // the registered data_valid is high. This will enable the frame data 
  // and 1 extra empty byte to be stored.
  //-------------------------------------------------------------------- 
  assign rx_addr_enable = (rx_data_valid | rx_data_valid_reg) & rx_enable;
  assign rx_addr        = rx_addr_int;

  //---------------------------------------------------------------------------
  // A signal that indicates that there has been a frame received
  //---------------------------------------------------------------------------
  always @(posedge rx_clk)
  begin
    if (rx_reset == 1'b1)
      frame_received_toggle <= 1'b0;
    else if (rx_enable == 1'b1)
      begin
      if (rx_good_frame_reg == 1'b1 && overflow_int_held == 1'b0)
        frame_received_toggle <= !(frame_received_toggle);
      end
  end

  //---------------------------------------------------------------------------
  // Now on to the read side.
  // read_addr will count up when there is a data to be transmitted
  // **If the FIFO is expanded to use more BRAM, increase rx_addr_int size as
  // required **   
   //---------------------------------------------------------------------------
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      read_addr_int <= 12'h001;
    else if (read_addr_enable_int == 1'b1)
      read_addr_int <= read_addr + 1;
  end

  assign read_addr = read_addr_int;
  
  //--------------------------------------------------------------------
  // The read address counter is enabled when there is a frame 
  // in the FIFO, the data_valid output from the block memory is high, 
  // the frame is being transmitted, 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.
  //--------------------------------------------------------------------  
  assign read_addr_enable = queue ? 1'b1 : (
                      ((frame_in_progress == 1'b1 || frame_transmitted == 1'b1) &&
                       (read_data_valid_int == 1'b1 || frame_in_fifo == 1'b1) && frame_in_fifo_held == 1'b1) ? 1'b1 : 1'b0);
   
  // The enable signal is held low if the upstream local link user is not
  // accepting data, to hold the output of the bram until data at the interface
  // is accepted
  assign read_addr_enable_int = read_addr_enable & !dst_rdy_in_n; 
                        
  //---------------------------------------------------------------------------
  // Register the address enable signal for use as the data pipe enable.
  //---------------------------------------------------------------------------
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      read_addr_enable_reg <= 1'b0;
    else if (dst_rdy_in_n == 1'b0)
      read_addr_enable_reg <= read_addr_enable;
  end

  // The pipe enable signal is held low if when the upstream local link user is
  // not acceptiong data.
  assign read_addr_enable_reg_int = read_addr_enable_reg & !dst_rdy_in_n;

  //---------------------------------------------------------------------------
  // A signal that indicates that there has been a frame transmitted
  //---------------------------------------------------------------------------
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      frame_transmitted <= 1'b0;
    else if (dst_rdy_in_n == 1'b0 && frame_in_fifo == 1'b1 && read_data_valid_int == 1'b1 && read_data_valid_pipe[0] == 1'b0)
      frame_transmitted <= 1'b1;
    else
      frame_transmitted <= 1'b0;
  end

  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      frame_transmitted_reg <= 1'b0;
    else
      frame_transmitted_reg <= frame_transmitted;                                   
  end 

  // ensure that the frame transmitted signal is only one clock cycle long
  assign frame_transmitted_pulse = frame_transmitted & !frame_transmitted_reg;
     
  //--------------------------------------------------------------------
  // 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_received_toggle 
  // signal is the frame_received_toggle signal re-clocked onto 
  // tx_clk. The ll_frame_received signal is asserted for 1 cycle when 
  // an edge is detected on ll_frame_received_toggle.
  //--------------------------------------------------------------------
  always @(posedge read_clock_in)
  begin
    if (ll_reset == 1'b1)
      begin
      ll_frame_received_toggle <= 3'b000;
      ll_frame_received        <= 1'b0;
      end
    else
      begin
      ll_frame_received_toggle[0] <= frame_received_toggle;
      ll_frame_received_toggle[1] <= ll_frame_received_toggle[0];
      ll_frame_received_toggle[2] <= ll_frame_received_toggle[1];
      ll_frame_received           <= ll_frame_received_toggle[2] ^ ll_frame_received_toggle[1];
      end

⌨️ 快捷键说明

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