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?