Modelsim - Problema de verificación extraño con DDR y Xilinx UNISIM

3

Estoy haciendo la verificación del componente VHDL usando OVM y encontré problemas serios. He encontrado que el problema está en un componente específico y un entorno creado específicamente para él. Es un convertidor de interfaz de RGMII a interno (de DDR a SDR) que utiliza componentes UNISIM de Xilinx para simular el comportamiento especial de las partes de chips FPGA.

BUFG_inst : BUFG
port map (
    O => INTERNAL_CLK,
    I => RGMII_CLK
);

IDDRDATA0_inst: IDDR
generic map (
    DDR_CLK_EDGE => "SAME_EDGE_PIPELINED",
    INIT_Q1 => '0',
    INIT_Q2 => '0',
    SRTYPE  => "SYNC"
)
port map (
    Q1 => data(0),
    Q2 => data(4),
    C  => INTERNAL_CLK,
    CE => CE,
    D  => RGMII_DATA(0),
    R  => RST,
    S  => '0'
);
-- several more instantiations

Genero transacciones y las envío a DUT utilizando el controlador:

forever
begin
my_transaction tx;

@(posedge dut_vi.clock); 
seq_item_port.get(tx);

dut_vi.ctl   = tx.ctl;
dut_vi.reset = tx.reset;
dut_vi.data  = tx.data;

@(negedge dut_vi.clock); 
seq_item_port.get(tx);

dut_vi.ctl   = tx.ctl;
dut_vi.reset = tx.reset;
dut_vi.data  = tx.data;
end

En la onda de Modelsim, esta entrada (ver los puertos de entrada del DUT) está bien ... Pero internamente, toma el valor de datos anterior; por ejemplo, el valor anterior de CTL era 0, en el flanco ascendente es 1, pero las muestras de DUT con aumento supera ese 0 anterior ya que no se actualizó dentro de modelsim.

Intenté usar "little hack":

TMP_CLK <= RGMII_CLK after 1ps;

BUFG_inst : BUFG
port map (
    O => INTERNAL_CLK,
    I => TMP_CLK
);

Resolvió el problema (parcialmente). El DUT ahora estaba muestreando valores correctos. Pero creó problemas con la salida y el monitor. Ahora todo es correcto en wave, pero el monitor ve valores incorrectos (pero solo algunas veces, generalmente con el inicio del paquete, la señal válida cambió de 0 a 1). Así que es un problema similar al de la entrada. Mi monitor se ve así:

forever
begin
dut_out_transaction tx;

@(posedge dut_out_vi.clock);          
tx = dut_out_transaction::type_id::create("tx");

tx.dv    = dut_out_vi.dv;
tx.err   = dut_out_vi.err;
tx.sof   = dut_out_vi.sof;
tx.eof   = dut_out_vi.eof;
tx.data  = dut_out_vi.data;

$display("DUT_OUT EOF: %b", dut_out_vi.eof);

if (dut_out_vi.eof == 1)  // this never happens
    ovm_report_info("out_monitor", "EOF");

aport.write(tx);
end

Como es un error similar, probé un hack similar. Agregué # 1ps justo después de @ (posedge dut_out_vi.clock); y realmente ayudó ... Pero surgió un nuevo problema: ahora el monitor nunca ve la señal EOF en 1, aunque está en 1 en ola varias veces.

Uso Modelsim 10.5 con resolución de 1ps. ¿Alguna idea de qué podría estar causándolo o cómo solucionarlo?

    
pregunta David Novák

1 respuesta

1

Finalmente lo resolví: el problema estaba en la biblioteca unisim de Xilinx. Por alguna razón, hay un retraso de 100ps (que no debería estar en la simulación de comportamiento) en IDDR. Por lo tanto, la solución es esperar en el monitor (en realidad tengo dos, para entrada y salida de DUT):

forever
begin
  my_transaction tx;

  @(posedge dut_vi.clock);
  #1ps
  tx = my_transaction::type_id::create("tx");

  tx.ctl   = dut_vi.ctl;
  tx.reset = dut_vi.reset;
  tx.data  = dut_vi.data;

  aport.write(tx);

  @(negedge dut_vi.clock);
  #1ps
  tx = my_transaction::type_id::create("tx");

  tx.ctl   = dut_vi.ctl;
  tx.reset = dut_vi.reset;
  tx.data  = dut_vi.data;

  aport.write(tx);
end

y segundo:

forever
begin
  dut_out_transaction tx;

  @(posedge dut_out_vi.clock);
  #101ps   // simulation hack
  tx = dut_out_transaction::type_id::create("tx");

  tx.dv    = dut_out_vi.dv;
  tx.err   = dut_out_vi.err;
  tx.sof   = dut_out_vi.sof;
  tx.eof   = dut_out_vi.eof;
  tx.data  = dut_out_vi.data;
end

En el monitor de entrada, tengo que esperar 1ps (no entendí por qué) y en la salida, tengo que esperar 101ps debido a la demora dentro de IDDR (verifiqué el código). De esta manera, el marcador obtiene los datos correctos.

    
respondido por el David Novák

Lea otras preguntas en las etiquetas