volcado de paquetes Ethernet en la memoria FPGA dañada

6

Soy un principiante en la programación de Verilog y FPGA. Mi experiencia es el desarrollo de software C / C ++.   Estoy desarrollando un módulo FPGA que básicamente lee los paquetes de la red Ethernet y luego interactúa con un proceso que se ejecuta en el software. Para empezar, escribí un módulo snooper de paquetes, que descargaría el siguiente paquete en su memoria cuando se habilita una señal.

Cuando leo el paquete volcado usando la interfaz Avalon-MM con mi módulo, los primeros 4 bytes parecen estar dañados. Otros bytes son los esperados.

En mi caso de prueba, los primeros 4 bytes de la memoria volcada son siempre 0x76696365 Luego modifiqué mi código para copiar los primeros 4 bytes del paquete en un registro separado. Cuando consulté este registro, obtengo el valor esperado, que es igual a 0xf531a en mi prueba. Pero aún así, el desplazamiento 0 de la memoria de volcado de paquetes es 0x76696365.

Estoy pegando el código verilog para su referencia. ¿Alguna sugerencia sobre cómo depurar este problema?

module packet_snooper #(
  parameter MAC_ERROR_WIDTH = 6,
  parameter MAC_DATA_WIDTH  = 32,  // 32 or 64
  parameter CSR_ADDRESS_BITS = 12,
  parameter CSR_DATABUS_WIDTH = 32
) (
    input mac_clk,
    input app_clk,
    input reset_n_mac,
    input reset_n_app,

    // Avalon-ST interface from the MAC (can be 32-bits at 312.5MHz or 64-bits at 156.25Mhz)
    input                                stream_in_startofpacket,
    input                                stream_in_endofpacket,
    input                                stream_in_valid,
    output                               stream_in_ready,
    input [MAC_DATA_WIDTH-1:0]           stream_in_data,
    input [2-1:0] stream_in_empty,
    input [MAC_ERROR_WIDTH-1:0]          stream_in_error,

    // out
    output                                stream_out_startofpacket,
    output                                stream_out_endofpacket,
    output                                stream_out_valid,
    input                                 stream_out_ready,
    output [MAC_DATA_WIDTH-1:0]           stream_out_data,
    output [2-1:0] stream_out_empty,
    output [MAC_ERROR_WIDTH-1:0]          stream_out_error,

    // Avalon-MM bus
    input  [CSR_ADDRESS_BITS-1:0]       avs_csr_address,
    input                               avs_csr_read,
    input                               avs_csr_write,
    input  [CSR_DATABUS_WIDTH-1:0]      avs_csr_writedata,
    output reg [CSR_DATABUS_WIDTH-1:0]  avs_csr_readdata,
    output                              avs_csr_waitrequest
  );

parameter CSR_MODULE_ID = 32'h20001001;
parameter CSR_REG_LOAD_PACKET = 10'd1;
parameter CSR_REG_PACKET_LEN  = 10'd2;
parameter CSR_REG_DEBUG  = 10'd3;
parameter CSR_REG_DEBUG_NUM_SOP  = 10'd4;
parameter CSR_REG_PKT_BUF_BASE = 10'd5;

parameter PKT_BUFFER_BYTES = 2048;

reg dump_next_packet;
reg [2:0] resync_dnp;
reg resync_dnp_rising_edge;
reg resync_dnp_rising_edge_hold;
reg dump_pkt;
wire valid_dump;
reg [3:0] debug_sop;
reg [3:0] debug_eop;
reg [3:0] debug_ready;
reg [3:0] debug_valid;
reg [3:0] debug_ready_valid;
wire [31:0] debug_register;
reg [31:0] sop;
reg [31:0] num_sop;

reg [MAC_DATA_WIDTH-1:0] pkt_buffer [9:0];                     //((PKT_BUFFER_BYTES<<3)/MAC_DATA_WIDTH):0
reg [31:0] pkt_len;

//passthrough data
assign stream_out_startofpacket = stream_in_startofpacket;
assign stream_out_endofpacket = stream_in_endofpacket;
assign stream_out_valid = stream_in_valid;
assign stream_in_ready = stream_out_ready;
assign stream_out_data = stream_in_data;
assign stream_out_empty = stream_in_empty;
assign stream_out_error = stream_in_error;

assign avs_csr_waitrequest = 0;

assign debug_register = {12'h0, debug_ready_valid, debug_valid, debug_ready, debug_sop, debug_eop};

always @ (posedge mac_clk) begin //{
  if(~reset_n_mac) begin
    debug_ready <= 0;
    debug_valid <= 0;
    debug_ready_valid <= 0;
    debug_sop <= 0;
    debug_eop <= 0;
  end
  else begin 
  if (stream_out_ready)
    debug_ready <= debug_ready + 1;

  if (stream_in_valid)
    debug_valid <= debug_valid + 1;

  if (stream_in_valid && stream_out_ready)
    debug_ready_valid <= debug_ready_valid + 1;

  if (stream_in_valid && stream_in_startofpacket)
    debug_sop <= debug_sop + 1;

  if (stream_in_valid && stream_in_endofpacket)
    debug_eop <= debug_eop + 1;
  end
end //}

always @ (posedge mac_clk) begin //{
  if(~reset_n_mac) begin
    pkt_len <= 0;
    num_sop <= 0;
  end 
  else if(stream_in_valid && stream_out_ready) begin //{
    if (valid_dump) begin //{
      if (stream_in_startofpacket) begin
        pkt_len <= 1;
        pkt_buffer[0] <= stream_in_data;
        sop <= stream_in_data;
        num_sop <= num_sop + 1;
      end
      else begin
        pkt_len <= pkt_len + 1;
        pkt_buffer[pkt_len] <= stream_in_data; /* TODO: Handle stream_in_empty */
      end
    end //}
  end //}
end //}

//read registers
always @ (posedge app_clk) begin //{
  if (avs_csr_read) begin //{
    case(avs_csr_address)
    9'h0             : avs_csr_readdata <= CSR_MODULE_ID;
    CSR_REG_LOAD_PACKET : avs_csr_readdata <= dump_next_packet;
    CSR_REG_PACKET_LEN  : avs_csr_readdata <= (pkt_len <<     $clog2(MAC_DATA_WIDTH/8));
    CSR_REG_DEBUG : avs_csr_readdata <= sop;
    CSR_REG_DEBUG_NUM_SOP: avs_csr_readdata <= num_sop;
    default           : //{
        avs_csr_readdata <= pkt_buffer[avs_csr_address[9:0] - CSR_REG_PKT_BUF_BASE];  //TODO: handle 64-bit width
    //}
    endcase
  end //}
end //}

// write reg
always @ (posedge app_clk) begin //{
  if(~reset_n_app) begin //{
    dump_next_packet <= 0;
  end //}
  else if(avs_csr_write) begin //{
    case(avs_csr_address) 
      CSR_REG_LOAD_PACKET : dump_next_packet <= avs_csr_writedata; 
    endcase
  end //}
end //}

/* Synchronize dump_next_packet with mac_clk */
always @(posedge mac_clk) begin //{
  resync_dnp <= {dump_next_packet, resync_dnp[2:1]};
  resync_dnp_rising_edge <= resync_dnp[1] & !resync_dnp[0];
end //}

/* Hold the edge till current packet dump is complete */
always @ (posedge mac_clk) begin //{
  if(~reset_n_mac) 
    resync_dnp_rising_edge_hold <= 0;
  else if(dump_pkt & stream_in_endofpacket & stream_in_valid)
    resync_dnp_rising_edge_hold <= 0;
  else if(resync_dnp_rising_edge)
    resync_dnp_rising_edge_hold <= 1;
end //}

always @ (posedge mac_clk) begin //{
  if(~reset_n_mac) 
    dump_pkt <= 0;
  else if(dump_pkt & stream_in_endofpacket & stream_in_valid)
    dump_pkt <= 0;
  else if(resync_dnp_rising_edge_hold & stream_in_startofpacket & stream_in_valid)
    dump_pkt <= 1;
end //}

assign valid_dump = stream_in_valid & (dump_pkt || (stream_in_startofpacket & resync_dnp_rising_edge_hold));

endmodule
    
pregunta javed

1 respuesta

1

los bloques siempre múltiples con relojes diferentes a veces crean problemas, así que evite usar varias señales de reloj en el mismo módulo y cree módulos separados para relojes diferentes en la medida de lo posible. Espere que su problema se resuelva.

    
respondido por el Ravi Tiwari

Lea otras preguntas en las etiquetas