Operation of "IsTriggered" function in HDL simulations

Hi, all
I’m confused about how to use “IsTriggered” while I’m doing an HDL simulation of Opal Kelly frontpanel.

In top module(Framework)

assign ep61data[31:0] = fpga_to_asic_trig_out[31:0];

okTriggerOut fpga_to_asic_to(.okHE(okHE), .okEH(okEHx[ 5*65 +: 65 ]), .ep_addr(8’h61), .ep_clk(okClk), .ep_trigger(ep61data));

fpga_to_asic u_fpga_to_asic(
    .clk                  ( okClk                  ),
    .rstn                 ( rstn                 ),
    .op_mode              ( op_mode              ),
    .flag_op_start        ( flag_op_start        ),
    .flag_meas_stop       ( flag_meas_stop       ),
    .wr_data_from_pc      ( wr_data_from_pc      ),
    .wr_row_addr_from_pc  ( wr_row_addr_from_pc  ),
    .wr_col_addr_from_pc  ( wr_col_addr_from_pc  ),
    .rd_row_addr_from_pc  ( rd_row_addr_from_pc  ),
    .rd_col_addr_from_pc  ( rd_col_addr_from_pc  ),
    .wl_from_pc           ( wl_from_pc           ),
    .imc_row_addr_from_pc ( imc_row_addr_from_pc ),
    .imc_col_addr_from_pc ( imc_col_addr_from_pc ),
    .gp_in                ( GP_IN                ),
    .op_code              ( OP_CODE              ),
    .op_en                ( OP_EN                ),
    .trigger_out          ( fpga_to_asic_trig_out)
);

As above, I assigned wire properly passed and the triggerOut was instantiated.

In Test Fixture(Testbench)

wr_done = 0;
UpdateTriggerOuts;
while (wr_done==0) begin
UpdateTriggerOuts;
wr_done = IsTriggered(8’h61, 32’h0000_0000);
$display(“WR operation is not finished”);
end

I wanted to check that WR(write) operation has done with triggerout.
And I saw “trigger out [1]” raise on waveform after the WR operation has done, but why isn’t it working?
I have tried with various mask values like

“wr_done = IsTriggered(8’h61, 32’h0000_0000);”
“wr_done = IsTriggered(8’h61, 32’h0000_0001);”
“wr_done = IsTriggered(8’h61, 32’h0000_0002);”
“wr_done = IsTriggered(8’h61, 0);”
“wr_done = IsTriggered(8’h61, 1);”
“wr_done = IsTriggered(8’h61, 2);”

And all of those not working…
Please help. If need whole source HDL, I’ll send with emails.

Additional questions

  • Does “IsTriggered(…, MASK)” mean if you put 32’h0000_0000 in MASK, you don’t use a mask?
  • Should I use “IsTriggered (8’h61, 32’h0000_0002)” rather than “IsTriggered (8’h61, 32’h0000_0001)” to check “wire 8’h61 [1]”?

Hello and welcome!

Masks are used to select certain bits in a value. Masks are implemented as an AND operation, so a Mask of 32’h0000_0001 would give you the LSB ([0]) of a bus, while 32’h0000_0002 would give you the 2nd LSB ([1]) of a bus. You may consider a quick read on bitmasks if you need any clarification.

I suspect your issue may be because of the back to back UpdateTriggerOuts calls.
If you check the documentation here, you’ll see it says, “This method is called to query the XEM to determine if any TriggerOuts have been activated since the last call.”

As a result, your trigger may be getting cleared out because you update the triggers twice before checking its result.

I removed the “UpdateTriggerOuts” before while loop, and everything is now working as intended.
Thanks for the helpful reply!

1 Like

As a follow up to this question, I am currently using the okTriggerIn interface to start my FSM and the okTriggerOut interface to initiate data transfer from FPGA via okPipeOut.

When I use clock frequencies lower than or equal to 100 MHz, I am able to start the FSM and read data on the PC. However, for a particular spec, I run my FSM at a 168MHz clock.

I tie the ep_clk port of okTriggerIn to okClk and use an async FIFO to transfer this to the 168MHz frequency domain for starting the FSM. However, the FSM doesn’t get triggered. Note that timing has been closed for the design and in simulation, I see the trigger signal on the 168MHz side.

Is there a recommended way to handle/debug this?

Also, can I tie the 168MHz clock directly to ep_clock port of okTriggerIn and okTriggerOut? In simulation, I am unable to see the trigger getting generated at this clock frequency.

Yes, you should tie ep_clock port to the desired clock domain of the trigger.

From the documentation: “The okTriggerIn provides EP_CLK and EP_TRIGGER as interface signals. The Trigger In endpoint produces a single-cycle trigger pulse on any of EP_TRIGGER which is synchronized to the clock signal EP_CLK. Therefore, the single-cycle does not necessarily have to be a single host interface cycle. Rather, the module takes care of crossing the clock boundary properly.”