Hi *, The PINx register is not correctly updated in the (VCD) traceer, when a pin is driven *by a different portpin or even another device* (multicore simulation). It is correctly traced, when the source is a portpin of the same HWPort.
In the attached example, PB1 is periodically toggled and it is connected to PD2, thus the PIND register should change. Compile and run the example like so: > avr-gcc -g -mmcu=atmega644 -std=gnu11 -O2 -Wall -Wextra -Werror -o main.elf > main.c > ./run_simulator.py The attached patch fixes this issue by adding an additional member to Pin, that points to the IOReg<HWPort> owning that Pin. This allows to report-back/update the tracer when the pin changes. (much like pinOfPort does) Patch, minimum working example, and screenshots attached. Cheers, panic
>From 60056018674044a049aba44aa2f1ac545b589475 Mon Sep 17 00:00:00 2001 From: panic <li...@xandea.de> Date: Sun, 11 Jun 2017 18:37:43 +0200 Subject: [PATCH] fix trace of PINx register when driven from another port or second device --- src/hwport.cpp | 4 ++++ src/pin.cpp | 8 ++++++++ src/pin.h | 3 +++ 3 files changed, 15 insertions(+) diff --git a/src/hwport.cpp b/src/hwport.cpp index ab4c4f8..5d5f26b 100644 --- a/src/hwport.cpp +++ b/src/hwport.cpp @@ -61,6 +61,10 @@ HWPort::HWPort(AvrDevice *core, const string &name, bool portToggle, int size): RegisterTraceValue(pintrace[tt]); } + for (unsigned int idx = 0; idx < portSize; ++idx) { + p[idx].pinOfPort = &pin; + p[idx].pinregOfPort = &pin_reg; + } Reset(); } diff --git a/src/pin.cpp b/src/pin.cpp index 0c52157..2f3dc4a 100644 --- a/src/pin.cpp +++ b/src/pin.cpp @@ -28,6 +28,7 @@ #include "pin.h" #include "net.h" +#include "rwmem.h" float AnalogValue::getA(float vcc) { switch(dState) { @@ -69,6 +70,8 @@ void Pin::SetInState(const Pin &p) { } else { *pinOfPort &= 0xff - mask; } + if (pinregOfPort != 0) + pinregOfPort->hardwareChange(*pinOfPort); } std::vector<HasPinNotifyFunction*>::iterator ii; @@ -91,6 +94,7 @@ bool Pin::CalcPin(void) { Pin::Pin(T_Pinstate ps) { pinOfPort = 0; + pinregOfPort = 0; connectedTo = NULL; mask = 0; @@ -120,6 +124,7 @@ Pin::Pin(T_Pinstate ps) { Pin::Pin() { pinOfPort = 0; + pinregOfPort = 0; connectedTo = NULL; mask = 0; @@ -133,6 +138,7 @@ Pin::~Pin() { Pin::Pin( unsigned char *parentPin, unsigned char _mask) { pinOfPort = parentPin; + pinregOfPort = 0; mask = _mask; connectedTo = NULL; @@ -141,6 +147,7 @@ Pin::Pin( unsigned char *parentPin, unsigned char _mask) { Pin::Pin(const Pin& p) { pinOfPort = 0; // don't take over HWPort connection! + pinregOfPort = 0; connectedTo = NULL; // don't take over Net instance! mask = 0; @@ -151,6 +158,7 @@ Pin::Pin(const Pin& p) { Pin::Pin(float analog) { mask = 0; pinOfPort = 0; + pinregOfPort = 0; connectedTo = NULL; analogVal.setA(analog); diff --git a/src/pin.h b/src/pin.h index 06d1eb0..26ff637 100644 --- a/src/pin.h +++ b/src/pin.h @@ -31,6 +31,8 @@ #include "pinnotify.h" class Net; +class HWPort; +template<typename T> class IOReg; #define REL_FLOATING_POTENTIAL 0.55 @@ -97,6 +99,7 @@ class Pin { protected: unsigned char *pinOfPort; //!< points to HWPort::pin or NULL + IOReg<HWPort> *pinregOfPort; unsigned char mask; //!< byte mask for HWPort::pin AnalogValue analogVal; //!< "real" analog voltage value -- 2.1.4
fail.vcd
Description: application/vnd.gtkwave-vcd
#include <avr/io.h> #include <inttypes.h> int main(void) { DDRB = _BV(PB1); for (uint8_t i = 0; i < 10; ++i) PORTB ^= _BV(PB1); return 0; }
pass.vcd
Description: application/vnd.gtkwave-vcd
#!/usr/bin/env python import pysimulavr def main(): elffile = "main.elf" vcdfile = "trace.vcd" dman = pysimulavr.DumpManager.Instance() dman.SetSingleDeviceApp() # get systemclock instance sc = pysimulavr.SystemClock.Instance() clkper = long(1e9/1.0e6) # period in ns, 1.0 MHz print("Create device") dev = pysimulavr.AvrFactory.instance().makeDevice("atmega644") dev.Load(elffile) dev.SetClockFreq(clkper) # clock period in ns! sc.Add(dev) print("Connect pins: PB1 --> PD2") n = pysimulavr.Net() n.Add(dev.GetPin("B1")) n.Add(dev.GetPin("D2")) print("Setup VCD Tracer") signals = [ "+ PORTB.B1-Out", "+ PORTD.PIN" ] dman.addDumpVCD(vcdfile, "\n".join(signals), "ns", False, False) dev.RegisterTerminationSymbol("exit") print("Starting simulation...") dman.start() sc.Run(int(1e8)) dman.stopApplication() now = sc.GetCurrentTime() print("Done after {:d} ns ({:.3f} s)".format(now, now/1e9)) if __name__ == "__main__": main()
_______________________________________________ Simulavr-devel mailing list Simulavr-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/simulavr-devel