Thread: [myhdl-list] how is it with gtkwave and tracing interfaces?
Brought to you by:
jandecaluwe
From: David B. <da...@be...> - 2016-01-31 11:16:10
|
Dear All, based on my previous question on how to do efficiently testbench I have made a small demo register, including a testbench to see the signals in the gtkwave (see below). It is a combination of Marcel's and Christopher's approaches. In addition I have added an interface having reset and clock signals. The testbench how it is below works fine, and in GTKwave under i_dut I have all the signals, including a reset and clock, so ... satisfaction. How, I want to pass the interface into the DUT, hence line self.args = (self.rc.ClkxC, self.rc.ResetxRN, self.DxD, self.DxE, self.QxD) becomes self.args = (self.rc, self.DxD, self.DxE, self.QxD) and register declaration: def register(ClkxC, ResetxRN, DxD, DxE, QxD): @always_seq(ClkxC.posedge, ResetxRN) becomes def register(rc, DxD, DxE, QxD): @always_seq(rc.ClkxC.posedge, rc.ResetxRN) and now the mystery comes. I can run such testbench, and it runs again fine. Problem is, when looking on gtkwave signals, the interface signals are not there. Hence I cannot see ClkxC and I cannot see ResetxRN. I can somehow see the clock, as i_dut instantiates ClockList with register ClockList(0), which indeed contains the clock. ResetxRN however disappeared. Why is that? And how can I avoid this? thanks .d. -------------------------------------------------------------------------------- # really disgusting way how to link relative import sys sys.path.append('/home/belohrad/git/didt/MyHDL/rhea') from myhdl import * import unittest from functools import wraps from rhea.system.clock import * from rhea.system.reset import * class RC(object): def __init__(self): self.ClkxC = Clock(0, frequency=160e6) self.ResetxRN = Reset(0, active = 0, async=True) def register(ClkxC, ResetxRN, DxD, DxE, QxD): @always_seq(ClkxC.posedge, ResetxRN) def ilogic(): if DxE: QxD.next = DxD return ilogic, _trace = False # decorator to trace problematic function def trace(func): func.trace = True return func #decorator with main bench initialization def myhdltest(func): @wraps(func) def wrapper(self): def testbench(): @instance def clockGen(): yield self.rc.ClkxC.gen() @instance def reset(): yield self.rc.ResetxRN.pulse( (10,12,18) ) @instance def stimulus(): yield func(self) raise StopSimulation i_dut = self.dut(*self.args) return i_dut, stimulus, reset, clockGen #tracedec = getattr(wrapper, 'trace', None) # True or None #tracesel = getattr(self, 'trace', None) # True or None #tracecmd = _trace # True or False #trace = (x for x in (tracedec, tracesel, tracecmd) if x is not None).next() g = traceSignals(testbench) #if trace else self.dut(*self.args) Simulation(g).run() return wrapper class testRegister(unittest.TestCase): def setUp(self): # prepare instance of the item self.DxD, self.QxD = [Signal(intbv(0)[8:]) for x in xrange(2)] self.DxE = Signal(bool(0)) self.rc = RC() # test instance self.args = (self.rc.ClkxC, self.rc.ResetxRN, self.DxD, self.DxE, self.QxD) self.dut=register @trace @myhdltest def testRegister(self): # stimulus self.rc.ClkxC.next = 0 self.DxD.next = 0 self.DxE.next = 1 yield join(self.rc.ClkxC.posedge, self.rc.ResetxRN.posedge) # reset stage finished self.DxD.next = 1 for i in range(10): yield (self.rc.ClkxC.posedge) self.DxD.next = 0 yield(delay(150)) unittest.main() |
From: Marcel H. <1he...@in...> - 2016-01-31 11:38:35
Attachments:
signature.asc
|
Hmmm. When I open gtkwave and look at the i_dut instance, I can see 5 signals: ClkxC, DxD[7:0], DxE, QxD[7:0], ResetxRn so.. i don't get your problem, sorry :/ Greetings Marcel On 31.01.2016 11:42, David Belohrad wrote: > Dear All, > > based on my previous question on how to do efficiently testbench I have made a small demo register, including a testbench to see the signals in the gtkwave (see below). It is a combination of Marcel's and Christopher's approaches. In addition I have added an interface having reset and clock signals. > > The testbench how it is below works fine, and in GTKwave under i_dut I have all the signals, including a reset and clock, so ... satisfaction. > > How, I want to pass the interface into the DUT, hence line > > self.args = (self.rc.ClkxC, self.rc.ResetxRN, self.DxD, self.DxE, self.QxD) > > becomes > > self.args = (self.rc, self.DxD, self.DxE, self.QxD) > > and register declaration: > > def register(ClkxC, ResetxRN, DxD, DxE, QxD): > @always_seq(ClkxC.posedge, ResetxRN) > > becomes > > def register(rc, DxD, DxE, QxD): > @always_seq(rc.ClkxC.posedge, rc.ResetxRN) > > > and now the mystery comes. I can run such testbench, and it runs again fine. Problem is, when looking on gtkwave signals, the interface signals are not there. Hence I cannot see ClkxC and I cannot see ResetxRN. I can somehow see the clock, as i_dut instantiates ClockList with register ClockList(0), which indeed contains the clock. ResetxRN however disappeared. > > Why is that? And how can I avoid this? > > thanks > > .d. > > > > -------------------------------------------------------------------------------- > # really disgusting way how to link relative > import sys > sys.path.append('/home/belohrad/git/didt/MyHDL/rhea') > > from myhdl import * > import unittest > from functools import wraps > from rhea.system.clock import * > from rhea.system.reset import * > > class RC(object): > def __init__(self): > self.ClkxC = Clock(0, frequency=160e6) > self.ResetxRN = Reset(0, active = 0, async=True) > > > def register(ClkxC, ResetxRN, DxD, DxE, QxD): > @always_seq(ClkxC.posedge, ResetxRN) > def ilogic(): > if DxE: > QxD.next = DxD > return ilogic, > > _trace = False > > # decorator to trace problematic function > def trace(func): > func.trace = True > return func > > #decorator with main bench initialization > def myhdltest(func): > @wraps(func) > def wrapper(self): > > def testbench(): > @instance > def clockGen(): > yield self.rc.ClkxC.gen() > > @instance > def reset(): > yield self.rc.ResetxRN.pulse( (10,12,18) ) > > @instance > def stimulus(): > yield func(self) > raise StopSimulation > > i_dut = self.dut(*self.args) > return i_dut, stimulus, reset, clockGen > > #tracedec = getattr(wrapper, 'trace', None) # True or None > #tracesel = getattr(self, 'trace', None) # True or None > #tracecmd = _trace # True or False > #trace = (x for x in (tracedec, tracesel, tracecmd) if x is not None).next() > > g = traceSignals(testbench) #if trace else self.dut(*self.args) > Simulation(g).run() > > return wrapper > > > class testRegister(unittest.TestCase): > > def setUp(self): > # prepare instance of the item > > self.DxD, self.QxD = [Signal(intbv(0)[8:]) for x in xrange(2)] > self.DxE = Signal(bool(0)) > self.rc = RC() > > # test instance > self.args = (self.rc.ClkxC, self.rc.ResetxRN, self.DxD, self.DxE, self.QxD) > self.dut=register > > > > @trace > @myhdltest > def testRegister(self): > > # stimulus > self.rc.ClkxC.next = 0 > self.DxD.next = 0 > self.DxE.next = 1 > yield join(self.rc.ClkxC.posedge, self.rc.ResetxRN.posedge) > > # reset stage finished > self.DxD.next = 1 > for i in range(10): > yield (self.rc.ClkxC.posedge) > self.DxD.next = 0 > yield(delay(150)) > > > > unittest.main() > > ------------------------------------------------------------------------------ > Site24x7 APM Insight: Get Deep Visibility into Application Performance > APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month > Monitor end-to-end web transactions and take corrective actions now > Troubleshoot faster and improve end-user experience. Signup Now! > http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140 > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: David B. <da...@be...> - 2016-01-31 12:55:29
|
did you run it with interface modification? the test bench I attached does not use interface and runs just fine. when you modify it as I have described in my last email, I.e calling register using self.rc instead of clock and reset, gtkwave does not show me the interface signals. On January 31, 2016 12:44:38 Marcel Hellwig <1he...@in...> wrote: > Hmmm. When I open gtkwave and look at the i_dut instance, I can see 5 > signals: ClkxC, DxD[7:0], DxE, QxD[7:0], ResetxRn > > so.. i don't get your problem, sorry :/ > > Greetings > Marcel > > On 31.01.2016 11:42, David Belohrad wrote: >> Dear All, >> >> based on my previous question on how to do efficiently testbench I have >> made a small demo register, including a testbench to see the signals in the >> gtkwave (see below). It is a combination of Marcel's and Christopher's >> approaches. In addition I have added an interface having reset and clock >> signals. >> >> The testbench how it is below works fine, and in GTKwave under i_dut I have >> all the signals, including a reset and clock, so ... satisfaction. >> >> How, I want to pass the interface into the DUT, hence line >> >> self.args = (self.rc.ClkxC, self.rc.ResetxRN, self.DxD, self.DxE, self.QxD) >> >> becomes >> >> self.args = (self.rc, self.DxD, self.DxE, self.QxD) >> >> and register declaration: >> >> def register(ClkxC, ResetxRN, DxD, DxE, QxD): >> @always_seq(ClkxC.posedge, ResetxRN) >> >> becomes >> >> def register(rc, DxD, DxE, QxD): >> @always_seq(rc.ClkxC.posedge, rc.ResetxRN) >> >> >> and now the mystery comes. I can run such testbench, and it runs again >> fine. Problem is, when looking on gtkwave signals, the interface signals >> are not there. Hence I cannot see ClkxC and I cannot see ResetxRN. I can >> somehow see the clock, as i_dut instantiates ClockList with register >> ClockList(0), which indeed contains the clock. ResetxRN however disappeared. >> >> Why is that? And how can I avoid this? >> >> thanks >> >> .d. >> >> >> >> -------------------------------------------------------------------------------- >> # really disgusting way how to link relative >> import sys >> sys.path.append('/home/belohrad/git/didt/MyHDL/rhea') >> >> from myhdl import * >> import unittest >> from functools import wraps >> from rhea.system.clock import * >> from rhea.system.reset import * >> >> class RC(object): >> def __init__(self): >> self.ClkxC = Clock(0, frequency=160e6) >> self.ResetxRN = Reset(0, active = 0, async=True) >> >> >> def register(ClkxC, ResetxRN, DxD, DxE, QxD): >> @always_seq(ClkxC.posedge, ResetxRN) >> def ilogic(): >> if DxE: >> QxD.next = DxD >> return ilogic, >> >> _trace = False >> >> # decorator to trace problematic function >> def trace(func): >> func.trace = True >> return func >> >> #decorator with main bench initialization >> def myhdltest(func): >> @wraps(func) >> def wrapper(self): >> >> def testbench(): >> @instance >> def clockGen(): >> yield self.rc.ClkxC.gen() >> >> @instance >> def reset(): >> yield self.rc.ResetxRN.pulse( (10,12,18) ) >> >> @instance >> def stimulus(): >> yield func(self) >> raise StopSimulation >> >> i_dut = self.dut(*self.args) >> return i_dut, stimulus, reset, clockGen >> >> #tracedec = getattr(wrapper, 'trace', None) # True or None >> #tracesel = getattr(self, 'trace', None) # True or None >> #tracecmd = _trace # True or False >> #trace = (x for x in (tracedec, tracesel, tracecmd) if x is not None).next() >> >> g = traceSignals(testbench) #if trace else self.dut(*self.args) >> Simulation(g).run() >> >> return wrapper >> >> >> class testRegister(unittest.TestCase): >> >> def setUp(self): >> # prepare instance of the item >> >> self.DxD, self.QxD = [Signal(intbv(0)[8:]) for x in xrange(2)] >> self.DxE = Signal(bool(0)) >> self.rc = RC() >> >> # test instance >> self.args = (self.rc.ClkxC, self.rc.ResetxRN, self.DxD, self.DxE, self.QxD) >> self.dut=register >> >> >> >> @trace >> @myhdltest >> def testRegister(self): >> >> # stimulus >> self.rc.ClkxC.next = 0 >> self.DxD.next = 0 >> self.DxE.next = 1 >> yield join(self.rc.ClkxC.posedge, self.rc.ResetxRN.posedge) >> >> # reset stage finished >> self.DxD.next = 1 >> for i in range(10): >> yield (self.rc.ClkxC.posedge) >> self.DxD.next = 0 >> yield(delay(150)) >> >> >> >> unittest.main() >> >> ------------------------------------------------------------------------------ >> Site24x7 APM Insight: Get Deep Visibility into Application Performance >> APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month >> Monitor end-to-end web transactions and take corrective actions now >> Troubleshoot faster and improve end-user experience. Signup Now! >> http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140 >> _______________________________________________ >> myhdl-list mailing list >> myh...@li... >> https://lists.sourceforge.net/lists/listinfo/myhdl-list >> > > > > > > ---------- > ------------------------------------------------------------------------------ > Site24x7 APM Insight: Get Deep Visibility into Application Performance > APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month > Monitor end-to-end web transactions and take corrective actions now > Troubleshoot faster and improve end-user experience. Signup Now! > http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140 > > > ---------- > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: David B. <da...@be...> - 2016-01-31 18:43:35
|
ok, try this one. Do you see rc.ClkxC and rc.ResetxRN under i_dut in gtkwave? I don't # really disgusting way how to link relative import sys sys.path.append('/home/belohrad/git/didt/MyHDL/rhea') from myhdl import * import unittest from functools import wraps from rhea.system.clock import * from rhea.system.reset import * class RC(object): def __init__(self): self.ClkxC = Clock(0, frequency=160e6) self.ResetxRN = Reset(0, active = 0, async=True) def register(rc, DxD, DxE, QxD): @always_seq(rc.ClkxC.posedge, rc.ResetxRN) def ilogic(): if DxE: QxD.next = DxD return ilogic, _trace = False # decorator to trace problematic function def trace(func): func.trace = True return func #decorator with main bench initialization def myhdltest(func): @wraps(func) def wrapper(self): def testbench(): @instance def clockGen(): yield self.rc.ClkxC.gen() @instance def reset(): yield self.rc.ResetxRN.pulse( (10,12,18) ) @instance def stimulus(): yield func(self) raise StopSimulation i_dut = self.dut(*self.args) return i_dut, stimulus, reset, clockGen #tracedec = getattr(wrapper, 'trace', None) # True or None #tracesel = getattr(self, 'trace', None) # True or None #tracecmd = _trace # True or False #trace = (x for x in (tracedec, tracesel, tracecmd) if x is not None).next() g = traceSignals(testbench) #if trace else self.dut(*self.args) Simulation(g).run() return wrapper class testRegister(unittest.TestCase): def setUp(self): # prepare instance of the item self.DxD, self.QxD = [Signal(intbv(0)[8:]) for x in xrange(2)] self.DxE = Signal(bool(0)) self.rc = RC() # test instance self.args = (self.rc, self.DxD, self.DxE, self.QxD) self.dut=register @trace @myhdltest def testRegister(self): # stimulus self.rc.ClkxC.next = 0 self.DxD.next = 0 self.DxE.next = 1 yield join(self.rc.ClkxC.posedge, self.rc.ResetxRN.posedge) # reset stage finished self.DxD.next = 1 for i in range(10): yield (self.rc.ClkxC.posedge) self.DxD.next = 0 yield(delay(150)) unittest.main() |
From: Christopher F. <chr...@gm...> - 2016-01-31 21:40:13
|
On 1/31/16 6:59 AM, David Belohrad wrote: > ok, try this one. Do you see rc.ClkxC and rc.ResetxRN under i_dut in > gtkwave? I don't In your `i_dut` instance the generators access the `ClkxC` and `ResetxRN` ports, they don't access the interface, these are the local variables the tracer decides to traces these (as seen in the hierarchy). (from VCD file): $var reg 1 # ClkxC $end $var reg 1 $ ResetxRN $end I imagine if you pass `rc` and use `rc.*` in the `i_dut` instance you will see the interface hierarchy? I modified it to reference clock and reset in the testbench function. def wrapper(self): rc = self.rc clock = self.rc.ClkxC reset = self.rc.ResetxRN def testbench(): @instance def doreset(): yield reset.pulse( (10, 12, 18) ) @instance def stimulus(): yield func(self) raise StopSimulation i_clk = clock.gen() i_dut = self.dut(*self.args) return i_dut, i_clk, stimulus, doreset I use interfaces quite extensively and typically don't run into tracing issues - not sure what might be different here ... > > # really disgusting way how to link relative import sys > sys.path.append('/home/belohrad/git/didt/MyHDL/rhea') You can get around this by using in the rhea directory. >> python setup.py develop > > from myhdl import * > import unittest from functools > import wraps > from rhea.system.clock import * > from rhea.system.reset import * The intended use is from rhea.system import Clock, Reset In Python3 the above won't work. Regards, Chris |
From: David B. <da...@be...> - 2016-02-01 08:49:49
|
I have just played around. With the proposed modification it gives still the same results. e.g. i_dut exported signals are only DxD, DxE and QxD. No clock, no reset. Then I started to play with the register definition, and some surprise comes: 1) Using this declaration the reset and clock is not exported (in fact, only signals which are directly used in the generator function are exported): @always_seq(rc.ClkxC.posedge, rc.ResetxRN) def ilogic(): if DxE: QxD.next = DxD 2) if I modify the decorator not using always_seq, but only always as follows: def register(rc, DxD, DxE, QxD): @always(rc.ClkxC, rc.ResetxRN) def ilogic(): if rc.ResetxRN == 0: QxD.next = 0 elif rc.ClkxC.posedge: if DxE: QxD.next = DxD return ilogic, I can see in gtkwave all variables, including reset and clock, which are exported as rc_ClkxC and rc_ResetxRN. It almost seems to me like the always_seq decorator just does not recognize rc.ClkxC.posedge and rc.ResetxRN as (interface) signals and thus does not export them. Or do I miss something? many thanks for your feedback .d. ---------------------------------------------- Dr. David Belohrad, Div. BE-BI C.E.R.N. Site de Prevessin, F-01631 CERN CEDEX http://www.cern.ch Dav...@ce... Tel +41.22.76.76318 Fax +41.22.76.69056 GSM +41.75.411.3455 ---------------------------------------------- Christopher Felton <chr...@gm...> writes: > On 1/31/16 6:59 AM, David Belohrad wrote: >> ok, try this one. Do you see rc.ClkxC and rc.ResetxRN under i_dut in >> gtkwave? I don't > > In your `i_dut` instance the generators access > the `ClkxC` and `ResetxRN` ports, they don't access > the interface, these are the local variables the > tracer decides to traces these (as seen in the hierarchy). > > (from VCD file): > $var reg 1 # ClkxC $end > $var reg 1 $ ResetxRN $end > > I imagine if you pass `rc` and use `rc.*` in the > `i_dut` instance you will see the interface hierarchy? > > > I modified it to reference clock and reset in the > testbench function. > > > def wrapper(self): > rc = self.rc > clock = self.rc.ClkxC > reset = self.rc.ResetxRN > > def testbench(): > @instance > def doreset(): > yield reset.pulse( (10, 12, 18) ) > > @instance > def stimulus(): > yield func(self) > raise StopSimulation > > i_clk = clock.gen() > i_dut = self.dut(*self.args) > > return i_dut, i_clk, stimulus, doreset > > > I use interfaces quite extensively and typically > don't run into tracing issues - not sure what might > be different here ... > >> >> # really disgusting way how to link relative import sys >> sys.path.append('/home/belohrad/git/didt/MyHDL/rhea') > > You can get around this by using in the rhea > directory. > > >> python setup.py develop > >> >> from myhdl import * >> import unittest from functools > > import wraps >> from rhea.system.clock import * >> from rhea.system.reset import * > > The intended use is > > from rhea.system import Clock, Reset > > In Python3 the above won't work. > > Regards, > Chris > > > ------------------------------------------------------------------------------ > Site24x7 APM Insight: Get Deep Visibility into Application Performance > APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month > Monitor end-to-end web transactions and take corrective actions now > Troubleshoot faster and improve end-user experience. Signup Now! > http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140 > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list |