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
Explorer
Explorer
1,985 Views
Registered: ‎10-05-2010

System Verilog Interface Simulation/Synthesis Mismatch

I am upgrading a legacy design from Spartan6 / Verilog to Artix7 / SystemVerilog, and I'm trying to use interfaces wherever I can to clean up the hierarchy.

 

The original design had several wide buses with status and commands. Within the modules, these buses were broken apart with part-select syntax, and I thought I could hide this in the interface definitions. I discovered that interfaces are working differently in simulation and synthesis. I am using Vivado 2017.3 on Windows.

 

Here is a simple test interface. A 32-bit masterStatus bus is divided into four 8-bit buses.

 

interface statusBus;
    logic [31:0]masterStatus;
    logic [7:0]stat0;
    logic [7:0]stat1;
    logic [7:0]stat2;
    logic [7:0]stat3;

    modport master (output masterStatus);

    modport slave (input .stat0(masterStatus[7:0]), .stat1(masterStatus[15:8]),
                            .stat2(masterStatus[23:16]), .stat3(masterStatus[31:24]));
endinterface

 

 

Now let's define a top level module with a 32-bit status input and four 8-bit outputs:

module top (
    input [31:0]StatusIn,
    output [7:0]stat0Out,
    output [7:0]stat1Out,
    output [7:0]stat2Out,
    output [7:0]stat3Out
);

 

    // Instantiate a status bus
    statusBus topStatus();

 

    // Assign the masterStatus
    assign topStatus.masterStatus = StatusIn;

 

    // Pass this bus to a lower level where the bytes are unpacked and passed back
    test1 t1 (.stat(topStatus.slave), .*);

endmodule // top

 

Now the lower level of the hierarchy.

 

module test1 (
    statusBus stat,
    output [7:0]stat0Out,
    output [7:0]stat1Out,
    output [7:0]stat2Out,
    output [7:0]stat3Out);

 

    `ifdef simulation
        // This assignment works with simulation and gives the result I expected

        // stat.stat0 returns the value of masterStatus[7:0]
        // stat.stat1 returns the value of masterStatus[15:8]

        // stat.stat2 returns the value of masterStatus[23:16]

        // stat.stat3 returns the value of masterStatus[31:24]
        // but in synthesis, it gives [Synth 8-524] part-select[7:0]  out of range of prefix stat1 error
        assign stat0Out = stat.stat0[7:0];
        assign stat1Out = stat.stat1[7:0];
        assign stat2Out = stat.stat2[7:0];
        assign stat3Out = stat.stat3[7:0];
    `else
        // This assignment gives no synthesis error,
        // but in simulation, 

        // stat.stat0 returns the value of masterStatus[7:0]
        // stat.stat1 returns 0

        // stat.stat2 returns 0

        // stat.stat3 returns 0

        assign stat0Out = stat.stat0[7:0];
        assign stat1Out = stat.stat1[15:8];
        assign stat2Out = stat.stat2[23:16];
        assign stat3Out = stat.stat3[31:24];
    `endif

endmodule // test1

 

The comments tell the story. In synthesis,  stat0 must be specified with the range [7:0], stat1 with the range [15:8], stat2 with the range [23:16] and stat3 with the range [31:24] 

 

In simulation stat0, stat1, stat2 and stat3 all must be specified with the range [7:0]

 

 

Here's a testbench to try it out:

module testbench();
    logic [31:0]StatusIn;
    logic [7:0]stat0Out;
    logic [7:0]stat1Out;
    logic [7:0]stat2Out;
    logic [7:0]stat3Out;

    assign StatusIn = 32'h12345678;

    top t (.*);

endmodule // testbench

 

I'd like everything to work the way that the simulation works. Am I asking interfaces to do something that they weren't intended to do, is this a Vivado bug or is there another way to make interfaces work to hide data ranges?

 

---

Joe Samson

Tags (2)
4 Replies
Scholar markcurry
Scholar
1,936 Views
Registered: ‎09-16-2009

Re: System Verilog Interface Simulation/Synthesis Mismatch

Joe,

 

My first reaction was thinking that Vivado did NOT support modport expressions.  But 'lo and behold UG901 lists modport expressions as explicitly SUPPORTED.  I've found UG901 to me quite out-of-date and things listed as not supported (or not even called out at all), are in fact, supported.

 

However, your case is the opposite - listed by Xilinx as supported, but not generating the correct logic.

 

I've used SystemVerilog a lot in Vivado, but not used modport expressions.  Your use case appears valid to me, and it looks like a Vivado bug.  I think your testcase should be looked at by Xilinx developers.  Kudos for creating the small testcase which shows the issue.

 

--Mark

 

0 Kudos
Explorer
Explorer
1,891 Views
Registered: ‎10-05-2010

Re: System Verilog Interface Simulation/Synthesis Mismatch

Thanks, Mark. I have actually found other modport bugs, but this is the simplest one to demonstrate. I have no idea which behavior is actually correct.

 

MODS - Is anyone going to look at this problem?

 

 

---

Joe Samson

0 Kudos
Explorer
Explorer
1,807 Views
Registered: ‎10-05-2010

Re: System Verilog Interface Simulation/Synthesis Mismatch

Still failing in Vivado 2017.4

 

 

---

Joe

0 Kudos
Newbie hubjohn
Newbie
1,476 Views
Registered: ‎03-29-2018

Re: System Verilog Interface Simulation/Synthesis Mismatch

It gets worse, if your interface goes down two levels of heirarchy, the second level will all show up as undriven so the synthesizer grounds all of the signals.

 

You may not notice this (we didn't) until I tried to add an ILA to the signals. At that time, flip-flop outputs and GND were connected, generating CRC errors! Vivado literally created invalid logic.