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