| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| 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 |
|
#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 |
|
#3
| |||
| |||
| >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; |
|
#4
| |||
| |||
| "Tricky" <Trickyhead@gmail.com> wrote in message news:d6513c7f-63ae-4ef3-ab71-b657efcb3ab5@k7g2000hsd.googlegroups.com... > 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 |
|
#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 |
|
#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 haveseen 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 |
|
#7
| |||
| |||
| On Aug 28, 1:01*am, Kim Enkovaara <kim.enkova...@iki.fi> wrote: > Marty Ryba wrote: > > structures into that case statement seems to work. Now I have to debatethe > > 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 |
|
#8
| |||
| |||
| On Thu, 28 Aug 2008 00:14:06 GMT, "Marty Ryba" <martin.ryba.nospam@verizon.net> wrote: >"Tricky" <Trickyhead@gmail.com> wrote in message >news:d6513c7f-63ae-4ef3-ab71-b657efcb3ab5@k7g2000hsd.googlegroups.com... >> 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. > >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. Heh. I didn't; I got it just good enough to work at the time. Of course it's coming back to bite me again in a derivative product. If you fix it now it'll be done with. And their practices are currently fresh in your mind; they probably made the same (few) mistake(s) throughout, so it may take less time than you expect. Just my opinion... - Brian |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.