UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor xnovak1m
Visitor
5,942 Views
Registered: ‎05-28-2015

Unisim bufg/iddr modelsim problem

Jump to solution

Hi,
I am doing verification of VHDL component using OVM and ran into serious problems. I have found that problem is in one specific component and created environment specifically for it. It's a RGMII to internal interface converter (from DDR to SDR) using Xilinx UNISIM to simulation.

 

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


I generate transactions and send them to DUT using driver:

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


In Modelsim wave, this input (watching DUT input ports) is just fine.. But internally, it takes previous value of data - for example previous value of CTL was 0, on rising edge it's 1, but DUT samples with rising edge that previous 0 as it didn't actualize inside modelsim.

I tried using "little hack":

TMP_CLK <= RGMII_CLK after 1ps;

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

It solved the problem (partially). DUT was now sampling correct values.. But it created problem with output and monitor. Now everything is correct in wave, but monitor sees wrong values (but only sometimes - usually with beginning of packet - valid signal changed from 0 to 1). So it's similar problem as with input. My monitor looks like this:

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

Since it's similar bug, I tried similar hack - I added #1ps right after @(posedge dut_out_vi.clock); and it truly helped.. But new problem arisen - now monitor never sees EOF signal in 1 even though it is in 1 in wave several times.

I use Modelsim 10.4c with resolution of 1ps (as requested by unisims). Any ideas what could be causing it or how to fix it?

Tags (4)
0 Kudos
1 Solution

Accepted Solutions
Visitor xnovak1m
Visitor
10,542 Views
Registered: ‎05-28-2015

Re: Unisim bufg/iddr modelsim problem

Jump to solution

[i][size=12]In reply to [url=https://verificationacademy.com/forums/ovm/problem-dut-ddr-input-sdr-output#question-52720]arakan94[/url]:[/size][/i]

I finally solved it - problem was in Xilinx unisim library. For some reason, there is 100ps delay (which shouldn't be in behavioral simulation) in IDDR..

 

So solution is to wait in monitor (I have actually two - for input and output of 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


and second one:

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


In the input monitor, I have to wait 1ps (didn't figure out why) and in output, I have to wait 101ps due to delay inside IDDR (I checked the code). This way, scoreboard gets correct data.

0 Kudos
1 Reply
Visitor xnovak1m
Visitor
10,543 Views
Registered: ‎05-28-2015

Re: Unisim bufg/iddr modelsim problem

Jump to solution

[i][size=12]In reply to [url=https://verificationacademy.com/forums/ovm/problem-dut-ddr-input-sdr-output#question-52720]arakan94[/url]:[/size][/i]

I finally solved it - problem was in Xilinx unisim library. For some reason, there is 100ps delay (which shouldn't be in behavioral simulation) in IDDR..

 

So solution is to wait in monitor (I have actually two - for input and output of 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


and second one:

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


In the input monitor, I have to wait 1ps (didn't figure out why) and in output, I have to wait 101ps due to delay inside IDDR (I checked the code). This way, scoreboard gets correct data.

0 Kudos