From: Stephan Veigl Date: Thu, 28 Jul 2011 16:03:33 +0000 (+0200) Subject: vcd: change VCD time base to 1 ns to handle higher AVR speeds (e.g. 20 MHz / max... X-Git-Tag: v1.0a9~15 X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=de417219e71dd93fa37576677bcfb7915296de9b;p=sx%2Fsimavr.git vcd: change VCD time base to 1 ns to handle higher AVR speeds (e.g. 20 MHz / max. frequency: 1000 MHz) - increase VCD log size to 5kB - add test files Signed-off-by: Stephan Veigl --- diff --git a/simavr/sim/sim_cycle_timers.h b/simavr/sim/sim_cycle_timers.h index a7c9d41..bc4cd14 100644 --- a/simavr/sim/sim_cycle_timers.h +++ b/simavr/sim/sim_cycle_timers.h @@ -38,7 +38,13 @@ static inline avr_cycle_count_t avr_usec_to_cycles(avr_t * avr, uint32_t usec) // converts back a number of cycles to usecs (for usleep) static inline uint32_t avr_cycles_to_usec(avr_t * avr, avr_cycle_count_t cycles) { - return 1000000 * cycles / avr->frequency; + return 1000000L * cycles / avr->frequency; +} + +// converts back a number of cycles to nsecs +static inline uint64_t avr_cycles_to_nsec(avr_t * avr, avr_cycle_count_t cycles) +{ + return (uint64_t)1E6 * (uint64_t)cycles / (avr->frequency/1000); } // converts a number of hz (to megahertz etc) to a number of cycle diff --git a/simavr/sim/sim_vcd_file.c b/simavr/sim/sim_vcd_file.c index 76e709b..76d42e2 100644 --- a/simavr/sim/sim_vcd_file.c +++ b/simavr/sim/sim_vcd_file.c @@ -83,20 +83,22 @@ static char * _avr_vcd_get_signal_text(avr_vcd_signal_t * s, char * out, uint32_ static void avr_vcd_flush_log(avr_vcd_t * vcd) { - if (!vcd->logindex) - return; -// printf("avr_vcd_flush_log %d\n", vcd->logindex); - uint32_t oldbase = 0; // make sure it's different - char out[48]; - #if AVR_VCD_MAX_SIGNALS > 32 uint64_t seen = 0; #else uint32_t seen = 0; #endif - for (int li = 0; li < vcd->logindex; li++) { + uint64_t oldbase = 0; // make sure it's different + char out[48]; + + if (!vcd->logindex) + return; +// printf("avr_vcd_flush_log %d\n", vcd->logindex); + + + for (uint32_t li = 0; li < vcd->logindex; li++) { avr_vcd_log_t *l = &vcd->log[li]; - uint32_t base = avr_cycles_to_usec(vcd->avr, l->when - vcd->start); + uint64_t base = avr_cycles_to_nsec(vcd->avr, l->when - vcd->start); // 1ns base // if that trace was seen in this usec already, we fudge the base time // to make sure the new value is offset by one usec, to make sure we get @@ -108,7 +110,7 @@ static void avr_vcd_flush_log(avr_vcd_t * vcd) if (base > oldbase || li == 0) { seen = 0; - fprintf(vcd->output, "#%uld\n", base); + fprintf(vcd->output, "#%llu\n", base); oldbase = base; } seen |= (1 << l->signal->irq.irq); // mark this trace as seen for this timestamp @@ -150,7 +152,7 @@ int avr_vcd_start(avr_vcd_t * vcd) return -1; } - fprintf(vcd->output, "$timescale 1us $end\n"); + fprintf(vcd->output, "$timescale 1ns $end\n"); // 1ns base fprintf(vcd->output, "$scope module logic $end\n"); for (int i = 0; i < vcd->signal_count; i++) { diff --git a/simavr/sim/sim_vcd_file.h b/simavr/sim/sim_vcd_file.h index 40d7b3c..5392058 100644 --- a/simavr/sim/sim_vcd_file.h +++ b/simavr/sim/sim_vcd_file.h @@ -40,7 +40,7 @@ extern "C" { */ #define AVR_VCD_MAX_SIGNALS 32 -#define AVR_VCD_LOG_SIZE 256 +#define AVR_VCD_LOG_SIZE 5120 typedef struct avr_vcd_signal_t { avr_irq_t irq; // receiving IRQ diff --git a/tests/atmega88_vcd.c b/tests/atmega88_vcd.c new file mode 100644 index 0000000..1894f84 --- /dev/null +++ b/tests/atmega88_vcd.c @@ -0,0 +1,42 @@ +/* + atmega88_example.c + + */ + +#ifndef F_CPU +#define F_CPU 8000000 +#endif +#include +#include +#include +#include +#include +#include + +/* + * This demonstrate how to use the avr_mcu_section.h file + * The macro adds a section to the ELF file with useful + * information for the simulator + */ +#include "avr_mcu_section.h" +AVR_MCU(F_CPU, "atmega88"); + + +int main() +{ + DDRB = 1; + PORTB = 0; + + + // test VCD output for 100us + for(int i=0; i<10; i++) + { + PORTB = 1 ^ PORTB; + _delay_us(100); + } + + + // this quits the simulator, since interupts are off + // this is a "feature" that allows running tests cases and exit + sleep_cpu(); +} diff --git a/tests/test_atmega88_vcd.c b/tests/test_atmega88_vcd.c new file mode 100644 index 0000000..63c788b --- /dev/null +++ b/tests/test_atmega88_vcd.c @@ -0,0 +1,23 @@ +#include "sim_avr.h" +#include "avr_ioport.h" +#include "sim_vcd_file.h" + +#include "tests.h" + +int main(int argc, char **argv) { + tests_init(argc, argv); + + + avr_t *avr = tests_init_avr("atmega88_vcd.axf"); + + avr_vcd_t vcd_file; + avr_vcd_init(avr, "atmega88_vcd.vcd", &vcd_file, 10000); + avr_vcd_add_signal(&vcd_file, avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), IOPORT_IRQ_PIN0), 1, "PB0" ); + avr_vcd_start(&vcd_file); + + tests_run_test(avr, 10000); + + avr_vcd_stop(&vcd_file); + tests_success(); + return 0; +}