Adición en verilog: la simulación no coincide con la síntesis

1

Vengo de un origen muy predominante en VHDL y recientemente he estado haciendo mucha más codificación en SystemVerilog. He notado un par de comportamientos extraños que no entiendo completamente.

Resumen

En el siguiente ejemplo, estoy realizando una adición de varias señales. Sé que esto es particularmente ineficiente (y probablemente de mal estilo), pero lo estoy usando para demostrar el tipo de problema que he encontrado recientemente.

// Main add (inside synchronous process)
// all signals are 32b logic or reg (except for 64, which is a 'define)
dma_ins.dest    <= sdram_addr + slice_address + slice_offset - 64;
                   0x3800 0000  0x0001 0000     0x0000 0050

Cuando ejecuto este complemento en la simulación, obtengo el resultado correcto. En síntesis, es incorrecto.

Simulación: 0x38010010
Síntesis: 0x38008008

El valor de síntesis es un cambio a la derecha (0x8008 en lugar de 0x10010).

Para determinar el valor de síntesis, estoy escribiendo las cuatro señales para depurar los registros. El DMA también termina en la dirección incorrecta en el SDRAM en hardware.

Para solucionar este problema, hice lo siguiente:

dma_ins.dest        <= sdram_addr;
dma_ins.dest[26:15] <= queue_prop_new[0].contig_head; // non-shifted versions of slice address 
dma_ins.dest[14:4]  <= queue_prop_new[0].contig_hoffset - 4; // and slice offset

Probablemente me esté perdiendo algo con respecto a las definiciones de tipo SystemVerilog, pero no estoy seguro de qué. He añadido algunos detalles a continuación.

Detalle

Las señales que se suman se definen de la siguiente manera:

// SDRAM ADDR (synchronus process, 32b reg)
sdram_addr <= 32'h38000000 

// SLICE ADDRESS (asynchronus combinitorial assign) 
// slice address: 32b logic
// queue_prop_new[0].contig_head: 12b logic: value of 0x02
// 32768 is a 'define that has been substituted.
assign slice_address = (queue_prop_new[0].contig_head <<($clog2(32768)-1));
// (slice_address = 0x02 << 15 = 0x10000)

// SLICE OFFSET
// slice_offset: 32b logic
// queue_prop_new[0].contig_hoffset:  11b logic: value of 0x05
// 16 is a substituted 'define
assign slice_offset = (queue_prop_new[0].contig_hoffset<<($clog2(16)-1));
// (slice_offset = 0x05 << 4 = 0x50)
    
pregunta stanri

1 respuesta

2

Las expresiones ($clog2(32768)-1) y ($clog2(16)-1) me parecen sospechosas. ¿No producen el 14 y el 3, respectivamente, en lugar del 15 y el 4 que deseas?

Pero no puedo explicar por qué el simulador está obteniendo el resultado "correcto".

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas