Modelsim vs. Synplify Pro frustrations

Discussion in 'VHDL' started by Marty Ryba, Aug 27, 2008.

  1. Marty Ryba

    Marty Ryba Guest

    I've had some curious symptoms with a big pile of code (not all mine) that I'd appreciate the community's inputs regarding (if it's frustrated me, it's probably frustrated the rest of you at some time).

    I'm having problems getting consistent behavior in a Modelsim test bench (it did work at some time, but now it seems to generally fail). When I fix it to work in the test bench, then it bombs in synthesis (Modelsim 5.8d, Synplify Pro 8.8.x).

    The signal of interest is a tri-state buffer that holds outbound data just prior to it getting copied into the (tri-state) PCI bus. There was some code to handle alternating between DMA and PIO, but I'm mostly focused on PIO (I'm actually trying to rip out the unused DMA logic without breaking things). So, there's a number of distributed units that may need to drive a readback of various registers in a register map. The vendor's code has structures like the following:

    signal pci_data_out_p : std_logic_vector(63 downto 0);

    read_ver_E_core_id_reg : process(pci_lclk_i, main_rst_h)
    begin
    if (rising_edge(pci_lclk_i) and (main_rst_h = '0') and
    (laddr_latched(7 downto 0) = COREID_OFFSET) and (LRD1WR0 = DIR_READ) and
    (reg_access_req = '1')) then
    pci_data_out_p(7 downto 0)<="00000010"; -- minor revision -002
    pci_data_out_p(23 downto 8)<="0010110011100000"; -- major revision - (G11488 , 0x2CE0 - XC2V4000)
    pci_data_out_p(63 downto 24)<=(others => '0'); -- must do this or the compiler will complain
    else
    pci_data_out_p <= (others => 'Z'); -- default: drive bus to high Z.
    end if;
    end process;

    As you can see, some signals are implied synchronous are in the one test and not in the sensitivity list (apparently this is preferred syntax in the latest VHDL-200x proposals); Synplify generally complains about missing signals in the sensitivity list, but seems to have "done the right thing" in synthesizing the chip (the vendor generally uses ISE 9.x, but wrote code to support both). However, after working for a while, this seems to no longer work in Modelsim (pci_data_out_p transitions back to high-Z on the falling edge, and thus the copy to the actual PCI_DATA pins returns high-Z in the test bench). I didn't quite like this construct anyway given the missing pieces of the sensitivity list. So, I'm trying something like this:

    -- **************************************************************************
    -- Group reading of registers together to get Modelsim and Synplify to
    -- to play nice together
    -- **************************************************************************
    read_ver_E_reg : process(pci_lclk_i)
    begin
    if rising_edge(pci_lclk_i) then
    if (main_rst_h = '0') and (LRD1WR0 = DIR_READ) and (reg_access_req = '1') then
    case laddr_latched(7 downto 0) is
    when DAC_CTRL_OFFSET =>
    pci_data_out_p(7 downto 0) <= dac_ctrl_regval;
    pci_data_out_p(63 downto 8) <= (others => '0');
    when SYNCCTRL_OFFSET =>
    pci_data_out_p(10 downto 0) <= sync_regval_rb;
    pci_data_out_p(63 downto 11)<= (others => '0');
    when COREID_OFFSET =>
    pci_data_out_p(7 downto 0) <= X"02"; -- minor revision - 02
    pci_data_out_p(23 downto 8) <= X"0100"; -- major revision - 100; T10_C1_image00_xx
    pci_data_out_p(63 downto 24)<=(others => '0');
    when others => pci_data_out_p(63 downto 0) <= (others => 'Z');
    end case;
    else
    pci_data_out_p <= (others => 'Z'); -- do I need this?
    end if;
    else
    pci_data_out_p <= (others => 'Z'); -- and this too? This seems to break Modelsim
    end if;
    end process;

    The challenge has been to get the bits right so that Modelsim doesn't prematurely transition the signal back to high-Z before it can be latched over to the output, and get it to synthesize without tri-state mismatches or dreaded "Found combinatorial loop" warnings (they sound too dire to ignore). Any hints for a relative newbie on the "right way" to do it? Oh by the way, several modules below this code contain similar logic for "their" registers.

    Thanks in advance for your sage advice,
    Marty
    martin (dot) ryba (at) verizon (dot) net
    Marty Ryba, Aug 27, 2008
    #1
    1. Advertising

  2. Marty Ryba wrote:
    > (it did work at some time, but now it seems to generally fail). When I
    > fix it to work in the test bench, then it bombs in synthesis (Modelsim
    > 5.8d, Synplify Pro 8.8.x).


    Just a hint on the tools. Please use something else than Synplify 8.8,
    it was a horrible release with many synthesis bugs (might have been
    fixed in the patches). But there are newer versions available, even
    8.9 beta was more stable than 8.8.

    --Kim
    Kim Enkovaara, Aug 27, 2008
    #2
    1. Advertising

  3. Marty Ryba

    Tricky Guest


    >However, after working for a while, this seems to no longer work in Modelsim (pci_data_out_p transitions back to high-Z on the falling edge, and thus the copy to the actual PCI_DATA >pins returns high-Z in the test bench). I didn't quite like this construct anyway given the missing pieces of the sensitivity list. So, I'm trying something like this:


    Modelsim appears to be working fine. The sensitivity list only applies
    in simulation. The "problem" appears to be the else clause on the same
    level as the clock, and the lack of the other signals in the
    sensitivity list.

    >read_ver_E_core_id_reg : process(pci_lclk_i, main_rst_h)
    >begin
    > if (rising_edge(pci_lclk_i) and (main_rst_h = '0') and
    > (laddr_latched(7 downto 0) = COREID_OFFSET) and (LRD1WR0 = DIR_READ) and
    > (reg_access_req = '1')) then
    > pci_data_out_p(7 downto 0)<="00000010"; -- minor revision -002
    > pci_data_out_p(23 downto 8)<="0010110011100000"; -- major revision - (G11488 , 0x2CE0 - XC2V4000)
    > pci_data_out_p(63 downto 24)<=(others => '0'); -- must do this or the compiler will complain
    > else
    > pci_data_out_p <= (others => 'Z'); -- default: drive bus to high Z.
    > end if;
    >end process;


    The sensitivity list tells the simulator (modelsim) when to trigger a
    process. This means the process will evaluate every time the clock
    changes, and in the case of the falling edge, the only possible
    outcome is to set the "pci_data_out_p" to all 'Z'. As for the
    synthesis, Im not surprised this is falling down either, as the
    template you have given (with the else on the same level as the clock)
    isnt really a standard template, so its trying to make some horrible
    logic out of the clock and the other various signals that are not (but
    should be) in the sensitivity list, because the synthesizer doesnt
    care about sensitivity lists. Otherwise it's trying to do what the
    simulator does and set the tri-state to high impedance on every
    falling edge (good luck with that).

    Id try removing the else clause that is on the same level as the
    clock, and keep the ONLY if path to be the rising_edge(pci_lclk_i).
    so, its almost what you've got in the second instance:

    read_ver_E_reg : process(pci_lclk_i)
    begin
    if rising_edge(pci_lclk_i) then
    if (main_rst_h = '0') and (LRD1WR0 = DIR_READ) and (reg_access_req
    = '1') then
    case laddr_latched(7 downto 0) is
    when DAC_CTRL_OFFSET =>
    pci_data_out_p(7 downto 0) <= dac_ctrl_regval;
    pci_data_out_p(63 downto 8) <= (others => '0');
    when SYNCCTRL_OFFSET =>
    pci_data_out_p(10 downto 0) <= sync_regval_rb;
    pci_data_out_p(63 downto 11)<= (others => '0');
    when COREID_OFFSET =>
    pci_data_out_p(7 downto 0) <= X"02"; -- minor revision - 02
    pci_data_out_p(23 downto 8) <= X"0100"; -- major revision -
    100; T10_C1_image00_xx
    pci_data_out_p(63 downto 24)<=(others => '0');
    when others => pci_data_out_p(63 downto 0) <= (others => 'Z');
    end case;
    else
    pci_data_out_p <= (others => 'Z'); -- do I need this?
    end if;
    end if;
    end process;
    Tricky, Aug 27, 2008
    #3
  4. Marty Ryba

    Marty Ryba Guest

    "Tricky" <> wrote in message
    news:...
    > Modelsim appears to be working fine. The sensitivity list only applies
    > in simulation. The "problem" appears to be the else clause on the same
    > level as the clock, and the lack of the other signals in the
    > sensitivity list.
    > read_ver_E_reg : process(pci_lclk_i)
    > begin
    > if rising_edge(pci_lclk_i) then
    > if (main_rst_h = '0') and (LRD1WR0 = DIR_READ) and (reg_access_req
    > = '1') then
    > case laddr_latched(7 downto 0) is
    > when DAC_CTRL_OFFSET =>
    > pci_data_out_p(7 downto 0) <= dac_ctrl_regval;
    > pci_data_out_p(63 downto 8) <= (others => '0');
    > when SYNCCTRL_OFFSET =>
    > pci_data_out_p(10 downto 0) <= sync_regval_rb;
    > pci_data_out_p(63 downto 11)<= (others => '0');
    > when COREID_OFFSET =>
    > pci_data_out_p(7 downto 0) <= X"02"; -- minor revision - 02
    > pci_data_out_p(23 downto 8) <= X"0100"; -- major revision -
    > 100; T10_C1_image00_xx
    > pci_data_out_p(63 downto 24)<=(others => '0');
    > when others => pci_data_out_p(63 downto 0) <= (others => 'Z');
    > end case;
    > else
    > pci_data_out_p <= (others => 'Z'); -- do I need this?
    > end if;
    > end if;
    > end process;


    An update: yes, finally removing that last else clause and getting rid of
    some other junk left over from when I collapsed three of the vendor
    structures into that case statement seems to work. Now I have to debate the
    merits of fixing the vendor's code in some of the sub-modules to have the
    same structure. Right now, the register calls from my code work in both
    Modelsim and Synplify; the calls to the vendor's modules break in simulation
    but work fine in the chip. For the life of me I can't figure out what
    possible switch/library setting changed in my Modelsim setup to cause the
    behavior to change between runs. For even when I used the configuration
    repository to roll back to the precise same code base as I had used earlier,
    it no longer worked and I hadn't (to my knowledge) messed with my Modelsim
    setup. Sigh. Maybe systems engineering is easier after all.

    -Marty
    Marty Ryba, Aug 28, 2008
    #4
  5. Marty Ryba wrote:

    > An update: yes, finally removing that last else clause and getting rid of
    > some other junk left over from when I collapsed three of the vendor
    > structures into that case statement seems to work.


    'Seems to work' as in
    vcom compiled and vsim elaborated without error?
    Or as in the simulation output waves and assertions are correct?

    > Now I have to debate the
    > merits of fixing the vendor's code in some of the sub-modules to have the
    > same structure.


    There's only one side to that debate.

    > Right now, the register calls

    instances?

    > from my code work in both
    > Modelsim and Synplify;
    > the calls to the vendor's modules break in simulation
    > but work fine in the chip.


    The vendor code is broken.
    Hope you didn't pay much for it.
    Unless he is willing to fix it for you,
    it's your code now, and your job to debug it.
    Check it in to version control and start hacking.

    > For the life of me I can't figure out what
    > possible switch/library setting changed in my Modelsim setup to cause the
    > behavior to change between runs. For even when I used the configuration
    > repository to roll back to the precise same code base as I had used earlier,
    > it no longer worked and I hadn't (to my knowledge) messed with my Modelsim
    > setup. Sigh.


    Learn the vcom and vsim command line options.
    Write a .do file or a makefile so
    that your compiles and sims are repeatable.

    Maybe systems engineering is easier after all.

    If this were easy, the boss would have done it already
    and you would be working on something less interesting,
    like a power supply.

    Good luck.

    -- Mike Treseler
    Mike Treseler, Aug 28, 2008
    #5
  6. Marty Ryba wrote:
    > structures into that case statement seems to work. Now I have to debate the
    > merits of fixing the vendor's code in some of the sub-modules to have the
    > same structure. Right now, the register calls from my code work in both
    > Modelsim and Synplify; the calls to the vendor's modules break in simulation
    > but work fine in the chip. For the life of me I can't figure out what
    > possible switch/library setting changed in my Modelsim setup to cause the
    > behavior to change between runs. For even when I used the configuration


    With bad code anything can happen. Possibly for example some event order
    changed and after that the code is not working correctly, because it is
    incorrectly done. The code might work on chip now, but it also might
    break in future tool versions, or after small change to the code.

    Usually the problem is that the code works in simulator, but not on the
    chip tough :) Simulator bugs in RTL simulations are very rare, I have
    seen and debugged few ones but they have usually been in beta test
    versions of the simulators or after some really major changes in
    the tool. With SDF timing simulations the bugs are more common with
    huge designs.

    > repository to roll back to the precise same code base as I had used earlier,
    > it no longer worked and I hadn't (to my knowledge) messed with my Modelsim
    > setup. Sigh. Maybe systems engineering is easier after all.


    Systems engineering is just as hard if the documents are written by
    incompetent people, and the simulation models are written by breaking
    all the rules and by tweaking it to work with certain version of the
    compiler on a certain platform.

    --Kim
    Kim Enkovaara, Aug 28, 2008
    #6
  7. Marty Ryba

    Andy Guest

    On Aug 28, 1:01 am, Kim Enkovaara <> wrote:
    > Marty Ryba wrote:
    > > structures into that case statement seems to work. Now I have to debate the
    > > merits of fixing the vendor's code in some of the sub-modules to have the
    > > same structure. Right now, the register calls from my code work in both
    > > Modelsim and Synplify; the calls to the vendor's modules break in simulation
    > > but work fine in the chip. For the life of me I can't figure out what
    > > possible switch/library setting changed in my Modelsim setup to cause the
    > > behavior to change between runs. For even when I used the configuration

    >
    > With bad code anything can happen. Possibly for example some event order
    > changed and after that the code is not working correctly, because it is
    > incorrectly done. The code might work on chip now, but it also might
    > break in future tool versions, or after small change to the code.
    >
    > Usually the problem is that the code works in simulator, but not on the
    > chip tough :) Simulator bugs in RTL simulations are very rare, I have
    > seen and debugged few ones but they have usually been in beta test
    > versions of the simulators or after some really major changes in
    > the tool. With SDF timing simulations the bugs are more common with
    > huge designs.
    >
    > > repository to roll back to the precise same code base as I had used earlier,
    > > it no longer worked and I hadn't (to my knowledge) messed with my Modelsim
    > > setup. Sigh. Maybe systems engineering is easier after all.

    >
    > Systems engineering is just as hard if the documents are written by
    > incompetent people, and the simulation models are written by breaking
    > all the rules and by tweaking it to work with certain version of the
    > compiler on a certain platform.
    >
    > --Kim


    Since most FPGA architectures don't actually implement internal tri-
    states, it may be that the early tri-state is optimized out in
    converting the tri-state bus into a mux structure (if nobody else is
    driving the bus early). If it is implemented as a real tri-state, the
    part may still appear to work since the tri-state will take a while to
    float off of the original value.

    Either way, not a good situation in HW, since changing something else
    (someone else driving the bus early), or part-part timing variations
    could render it inoperable.

    Andy
    Andy, Aug 28, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jeffrey Silverman

    Slightly OT: MSIE bugs and frustrations

    Jeffrey Silverman, Nov 9, 2004, in forum: HTML
    Replies:
    4
    Views:
    368
    brucie
    Nov 10, 2004
  2. filmil
    Replies:
    0
    Views:
    442
    filmil
    Jun 29, 2007
  3. filmil
    Replies:
    4
    Views:
    710
    Filip Miletic
    Jun 30, 2007
  4. sean_walsh

    Frustrations with Error Logging

    sean_walsh, Jul 30, 2008, in forum: ASP .Net
    Replies:
    1
    Views:
    310
    sloan
    Jul 30, 2008
  5. Sam Takoy

    Frustrations with layouts

    Sam Takoy, Apr 3, 2010, in forum: Java
    Replies:
    6
    Views:
    347
    Roedy Green
    Apr 3, 2010
Loading...

Share This Page