~ubuntu-branches/ubuntu/dapper/simulavr/dapper

« back to all changes in this revision

Viewing changes to src/disp-vcd/vcd.c

  • Committer: Bazaar Package Importer
  • Author(s): Shaun Jackman
  • Date: 2004-04-10 13:54:17 UTC
  • Revision ID: james.westby@ubuntu.com-20040410135417-zywapjyz252y65se
Tags: upstream-0.1.2.1
ImportĀ upstreamĀ versionĀ 0.1.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: vcd.c,v 1.3 2003/12/01 05:48:35 troth Exp $
 
3
 *
 
4
 ****************************************************************************
 
5
 *
 
6
 * simulavr-vcd - A vcd file writer as display process for simulavr.
 
7
 * Copyright (C) 2002  Carsten Beth
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License as published by
 
11
 * the Free Software Foundation; either version 2 of the License, or
 
12
 * (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
22
 *
 
23
 ****************************************************************************
 
24
 */
 
25
 
 
26
/* WARNING: This code is a hack and needs major improvements. */
 
27
 
 
28
#include <stdio.h>
 
29
#include <stdlib.h>
 
30
#include <string.h>
 
31
#include <errno.h>
 
32
#include <time.h>
 
33
#include "vcd.h"
 
34
 
 
35
#include "config.h"
 
36
 
 
37
int vcd_read_config (char *config_file_name);
 
38
 
 
39
/* from config_parser.c */
 
40
 
 
41
extern int parse_config (FILE * infile);
 
42
 
 
43
/* Definitions for debugging (Add -DENABLE_DEBUG=1 to compile command to
 
44
   enable debugging output). */
 
45
 
 
46
#ifndef ENABLE_DEBUG
 
47
#  define ENABLE_DEBUG 0
 
48
#endif
 
49
 
 
50
#if ENABLE_DEBUG == 1
 
51
#  define DEBUG_FKT_CALL( x ) x;
 
52
#else
 
53
#  define DEBUG_FKT_CALL( x )
 
54
#endif
 
55
 
 
56
int frequency = 0;
 
57
 
 
58
char *vcd_file_name = NULL;
 
59
FILE *vcd_file = NULL;
 
60
 
 
61
/* Number of clocks (time = 1/f * clk) */
 
62
 
 
63
unsigned int clk = 0;
 
64
 
 
65
/* Dump tables are used to store the information which signals has to be
 
66
   written to the vcd file.  We define one char for each signal. Each Signal
 
67
   with a dump table value != 0 will be written. */
 
68
 
 
69
char *io_reg_dump_table;
 
70
char *reg_dump_table;
 
71
char *sram_dump_table;
 
72
char sp_dump_table;
 
73
char pc_dump_table;
 
74
 
 
75
/* A signal is an entry in the vcd file which has to be traced. */
 
76
 
 
77
typedef struct t_signal
 
78
{
 
79
    char *name;                 /* Visible name */
 
80
    char *shortcut;             /* Short name which is written in vcd file */
 
81
    int addr;                   /* Address of signal */
 
82
    unsigned int width;         /* Width of the traced signal */
 
83
    t_signal_type type;         /* vcd type of the traced signal */
 
84
    struct t_signal *next;      /* Pointer to the next signal */
 
85
} t_signal;
 
86
 
 
87
/* There are several kinds of signals. */
 
88
 
 
89
t_signal *io_reg_signals = NULL;
 
90
t_signal *reg_signals = NULL;
 
91
t_signal *sram_signals = NULL;
 
92
t_signal *other_signals = NULL;
 
93
 
 
94
struct
 
95
{
 
96
    int sram_size;
 
97
    int eeprom_size;
 
98
} sizes;
 
99
 
 
100
t_signal *
 
101
vcd_new_signal (t_signal **signals, char *name, char *shortcut, int addr,
 
102
                unsigned int width, t_signal_type type)
 
103
{
 
104
    t_signal *new;
 
105
 
 
106
    /* Allocate memory for new signal */
 
107
    new = (t_signal *)malloc (sizeof (t_signal));
 
108
 
 
109
    /* If there is a name, make a copy */
 
110
    if (name)
 
111
    {
 
112
        new->name = (char *)malloc (strlen (name));
 
113
        strcpy (new->name, name);
 
114
    }
 
115
    else
 
116
        name = NULL;
 
117
 
 
118
    /* If there is a shortcut, make a copy */
 
119
    if (shortcut)
 
120
    {
 
121
        new->shortcut = (char *)malloc (strlen (shortcut));
 
122
        strcpy (new->shortcut, shortcut);
 
123
    }
 
124
    else
 
125
        shortcut = NULL;
 
126
 
 
127
    /* Copy the other values */
 
128
    new->addr = addr;
 
129
    new->width = width;
 
130
    new->type = type;
 
131
 
 
132
    /* Link to signal list */
 
133
    new->next = *signals;
 
134
    *signals = new;
 
135
 
 
136
    return (new);
 
137
}
 
138
 
 
139
void
 
140
vcd_free_signals (t_signal **signals)
 
141
{
 
142
    t_signal *p;
 
143
 
 
144
    while (*signals)
 
145
    {
 
146
        /* Remove from list */
 
147
        p = *signals;
 
148
        *signals = (*signals)->next;
 
149
 
 
150
        /* Free memory */
 
151
        if (p->name)
 
152
            free (p->name);
 
153
        if (p->shortcut)
 
154
            free (p->shortcut);
 
155
        free (p);
 
156
    }
 
157
}
 
158
 
 
159
/* Close a vcd_file */
 
160
 
 
161
void
 
162
vcd_close (void)
 
163
{
 
164
    if (vcd_file && vcd_file != stdout)
 
165
    {
 
166
        fclose (vcd_file);
 
167
        vcd_file = NULL;
 
168
    }
 
169
}
 
170
 
 
171
/* Open a vcd_file by name. If name is "-" stdout will be used to write to. */
 
172
 
 
173
int
 
174
vcd_open (char *vcd_file_name)
 
175
{
 
176
    if (!vcd_file_name)
 
177
    {
 
178
        fprintf (stderr, "unvalid VCD file name: (NULL)\n");
 
179
        return (0);
 
180
    }
 
181
 
 
182
    /* Possibly close an opened vcd file */
 
183
    if (vcd_file)
 
184
        vcd_close ();
 
185
 
 
186
    /* Open a VCD file */
 
187
    if (strcmp (vcd_file_name, "-") == 0)
 
188
        vcd_file = stdout;
 
189
    else
 
190
    {
 
191
        vcd_file = fopen (vcd_file_name, "w");
 
192
        if (!vcd_file)
 
193
        {
 
194
            fprintf (stderr, "open VCD file failed: %s\n", strerror (errno));
 
195
            return (0);
 
196
        }
 
197
    }
 
198
 
 
199
    return (1);
 
200
}
 
201
 
 
202
/* Close files and free memory. */
 
203
 
 
204
void
 
205
vcd_exit (void)
 
206
{
 
207
    vcd_close ();
 
208
 
 
209
    if (io_reg_dump_table)
 
210
        free (io_reg_dump_table);
 
211
 
 
212
    if (reg_dump_table)
 
213
        free (reg_dump_table);
 
214
 
 
215
    if (sram_dump_table)
 
216
        free (sram_dump_table);
 
217
 
 
218
    vcd_free_signals (&io_reg_signals);
 
219
    vcd_free_signals (&reg_signals);
 
220
    vcd_free_signals (&sram_signals);
 
221
    vcd_free_signals (&other_signals);
 
222
 
 
223
    if (vcd_file_name)
 
224
        free (vcd_file_name);
 
225
}
 
226
 
 
227
/* Initialize dump tables, parse config file and open vcd file. */
 
228
 
 
229
int
 
230
vcd_init (int sram_size, int eeprom_size)
 
231
{
 
232
    DEBUG_FKT_CALL (fprintf
 
233
                    (stderr, "vcd_init( %i, %i )\n", sram_size, eeprom_size));
 
234
 
 
235
    atexit (vcd_exit);
 
236
 
 
237
    sizes.sram_size = sram_size;
 
238
    sizes.eeprom_size = eeprom_size;
 
239
 
 
240
    /* Initialize dump tables */
 
241
    io_reg_dump_table = (char *)calloc (64, sizeof (char));
 
242
    reg_dump_table = (char *)calloc (32, sizeof (char));
 
243
    sram_dump_table = (char *)calloc (sram_size, sizeof (char));
 
244
    sp_dump_table = 0;
 
245
    pc_dump_table = 0;
 
246
 
 
247
    if (!io_reg_dump_table || !reg_dump_table || !sram_dump_table)
 
248
    {
 
249
        fprintf (stderr, "virtual memory exhausted\n");
 
250
        exit (1);
 
251
    }
 
252
 
 
253
    /* Parse configuration file */
 
254
    if (!vcd_read_config ("vcd.cfg"))
 
255
        return (0);
 
256
 
 
257
    /* Open vcd file */
 
258
    if (!vcd_open (vcd_file_name))
 
259
        return (0);
 
260
 
 
261
    return (1);
 
262
}
 
263
 
 
264
/***************************************************************/
 
265
 
 
266
/* Write the current date and time to the vcd file */
 
267
 
 
268
int
 
269
vcd_write_time (void)
 
270
{
 
271
    time_t current_time = time (NULL);
 
272
 
 
273
    if (!vcd_file)
 
274
        return (0);
 
275
 
 
276
    fprintf (vcd_file, "$date\n");
 
277
    fprintf (vcd_file, "  %s", ctime (&current_time));
 
278
    fprintf (vcd_file, "$end\n");
 
279
    fprintf (vcd_file, "\n");
 
280
 
 
281
    return (1);
 
282
}
 
283
 
 
284
/* Write the version to the vcd file */
 
285
 
 
286
int
 
287
vcd_write_version (void)
 
288
{
 
289
    if (!vcd_file)
 
290
        return (0);
 
291
 
 
292
    fprintf (vcd_file, "$version\n");
 
293
    fprintf (vcd_file, "  simulavr vcd dumper version %s\n", VCD_VERSION);
 
294
    fprintf (vcd_file, "$end\n");
 
295
    fprintf (vcd_file, "\n");
 
296
 
 
297
    return (1);
 
298
}
 
299
 
 
300
/* Write the timescale to the vcd file. The timescale is always 1 ns. */
 
301
 
 
302
int
 
303
vcd_write_timescale (void)
 
304
{
 
305
    if (!vcd_file)
 
306
        return (0);
 
307
 
 
308
    fprintf (vcd_file, "$timescale\n");
 
309
    fprintf (vcd_file, "  1ns\n");
 
310
    fprintf (vcd_file, "$end\n");
 
311
    fprintf (vcd_file, "\n");
 
312
 
 
313
    return (1);
 
314
}
 
315
 
 
316
int
 
317
vcd_bind_io_reg_shortcut (char *io_reg_name, int io_reg_addr)
 
318
{
 
319
    t_signal *p;
 
320
    char name[100];
 
321
    char shortcut[100];
 
322
 
 
323
    DEBUG_FKT_CALL (fprintf
 
324
                    (stderr, "vcd_bind_io_register_shortcut( %s, %i )\n",
 
325
                     io_reg_name, io_reg_addr));
 
326
 
 
327
    if (!io_reg_signals)
 
328
        return (0);
 
329
 
 
330
    /* Generate a name and shortcut */
 
331
    snprintf (name, 100 - 1, "%x_%s", io_reg_addr, io_reg_name);
 
332
    snprintf (shortcut, 100 - 1, "ioreg%x", io_reg_addr);
 
333
 
 
334
    /* Count io_reg_signals to search for matching names or addresses */
 
335
    for (p = io_reg_signals; p; p = p->next)
 
336
    {
 
337
        /* Does the addresses or names match? */
 
338
        if ((p->addr == io_reg_addr)
 
339
            || (p->name && (strcmp (p->name, io_reg_name) == 0)))
 
340
        {
 
341
            /* Mark register as used */
 
342
            io_reg_dump_table[io_reg_addr] = 1;
 
343
 
 
344
            /* Change the signals name */
 
345
            if (p->name)
 
346
                free (p->name);
 
347
            p->name = (char *)malloc (strlen (name));
 
348
            strcpy (p->name, name);
 
349
 
 
350
            /* Copy the address */
 
351
            p->addr = io_reg_addr;
 
352
 
 
353
            /* Copy the shortcut */
 
354
            if (p->shortcut)
 
355
                free (p->shortcut);
 
356
            p->shortcut = (char *)malloc (strlen (shortcut));
 
357
            strcpy (p->shortcut, shortcut);
 
358
        }
 
359
 
 
360
    }
 
361
 
 
362
    return (1);
 
363
}
 
364
 
 
365
/* Set the controlers clock frequency. */
 
366
 
 
367
void
 
368
vcd_set_frequency (int f)
 
369
{
 
370
    DEBUG_FKT_CALL (fprintf (stderr, "vcd_set_frequency( %i )\n", f));
 
371
 
 
372
    frequency = f;
 
373
}
 
374
 
 
375
/* Set the file name which sould be used for the vcd file. */
 
376
 
 
377
void
 
378
vcd_set_file_name (char *name)
 
379
{
 
380
    DEBUG_FKT_CALL (fprintf (stderr, "vcd_set_file_name( %s )\n", name));
 
381
 
 
382
    if (vcd_file_name)
 
383
        free (vcd_file_name);
 
384
 
 
385
    vcd_file_name = name;
 
386
}
 
387
 
 
388
/* Mark a io-register for tracing. This function can be called either with an
 
389
   io_reg_name or an io_reg_addr. */
 
390
 
 
391
int
 
392
vcd_trace_io_reg (char *io_reg_name, int io_reg_addr)
 
393
{
 
394
    vcd_new_signal (&io_reg_signals, io_reg_name, NULL, io_reg_addr, 8,
 
395
                    ST_REGISTER);
 
396
 
 
397
    return 0;                   /* FIXME: why wasn't this returning
 
398
                                   anything? */
 
399
}
 
400
 
 
401
/* Mark register reg_num for tracing. */
 
402
 
 
403
int
 
404
vcd_trace_reg (int reg_num)
 
405
{
 
406
    char name[100];
 
407
    char shortcut[100];
 
408
 
 
409
    /* Generate a name and shortcut */
 
410
    snprintf (name, 100 - 1, "REG_%02x", reg_num);
 
411
    snprintf (shortcut, 100 - 1, "reg%x", reg_num);
 
412
 
 
413
    vcd_new_signal (&reg_signals, name, shortcut, -1, 8, ST_REGISTER);
 
414
 
 
415
    /* mark register as used */
 
416
    reg_dump_table[reg_num] = 1;
 
417
 
 
418
    return 0;                   /* FIXME: why wasn't this returning
 
419
                                   anything? */
 
420
}
 
421
 
 
422
/* Mark sram[sram_addr] for tracing. */
 
423
 
 
424
int
 
425
vcd_trace_sram (int sram_addr)
 
426
{
 
427
    char name[30];
 
428
    char shortcut[30];
 
429
 
 
430
    if ((sram_addr < 0) || (sram_addr > sizes.sram_size - 1))
 
431
        return (0);
 
432
 
 
433
    /* Generate name and shortcut */
 
434
    sprintf (name, "SRAM_%02x", sram_addr);
 
435
    sprintf (shortcut, "sram%x", sram_addr);
 
436
 
 
437
    vcd_new_signal (&sram_signals, name, shortcut, -1, 8, ST_REGISTER);
 
438
 
 
439
    /* mark sram cell as used */
 
440
    sram_dump_table[sram_addr] = 1;
 
441
 
 
442
    return 0;                   /* FIXME: why wasn't this returning
 
443
                                   anything? */
 
444
}
 
445
 
 
446
/* Mark stack pointer for tracing. */
 
447
 
 
448
int
 
449
vcd_trace_sp (void)
 
450
{
 
451
    vcd_new_signal (&other_signals, "SP", "sp", -1, 16, ST_REGISTER);
 
452
 
 
453
    /* mark sp cell as used */
 
454
    sp_dump_table = 1;
 
455
 
 
456
    return 0;                   /* FIXME: why wasn't this returning
 
457
                                   anything? */
 
458
}
 
459
 
 
460
/* Mark program counter for tracing. */
 
461
 
 
462
int
 
463
vcd_trace_pc (void)
 
464
{
 
465
    vcd_new_signal (&other_signals, "PC", "pc", -1, 16, ST_REGISTER);
 
466
 
 
467
    /* mark pc cell as used */
 
468
    pc_dump_table = 1;
 
469
 
 
470
    return 0;                   /* FIXME: why wasn't this returning
 
471
                                   anything? */
 
472
}
 
473
 
 
474
/* Read an parse the config file. */
 
475
 
 
476
int
 
477
vcd_read_config (char *config_file_name)
 
478
{
 
479
    FILE *config_file;
 
480
 
 
481
    DEBUG_FKT_CALL (fprintf
 
482
                    (stderr, "vcd_read_config( %s )\n", config_file_name));
 
483
 
 
484
    config_file = fopen (config_file_name, "r");
 
485
    if (!config_file)
 
486
    {
 
487
        fprintf (stderr, "open config file failed: %s\n", strerror (errno));
 
488
        return (0);
 
489
    }
 
490
 
 
491
    if (!parse_config (config_file))
 
492
    {
 
493
        fprintf (stderr, "error while reading config file\n");
 
494
        fclose (config_file);
 
495
        return (0);
 
496
    }
 
497
 
 
498
    fclose (config_file);
 
499
    return (1);
 
500
}
 
501
 
 
502
/* Write signal declarations to the vcd file. */
 
503
 
 
504
void
 
505
vcd_write_signals (t_signal *signals, char *module_name)
 
506
{
 
507
    if (signals)
 
508
    {
 
509
        fprintf (vcd_file, "$scope module %s $end\n", module_name);
 
510
 
 
511
        for (; signals; signals = signals->next)
 
512
            if (signals->shortcut)
 
513
                fprintf (vcd_file, "$var reg       %i %s    %s   $end\n",
 
514
                         signals->width, signals->shortcut, signals->name);
 
515
 
 
516
        fprintf (vcd_file, "$upscope $end\n");
 
517
        fprintf (vcd_file, "\n");
 
518
    }
 
519
}
 
520
 
 
521
/* Write the header to the vcd file. */
 
522
 
 
523
int
 
524
vcd_write_header (void)
 
525
{
 
526
    DEBUG_FKT_CALL (fprintf (stderr, "vcd_write_header()\n"));
 
527
 
 
528
    if (!vcd_file)
 
529
        return (0);
 
530
 
 
531
    /* Rewind file */
 
532
    fseek (vcd_file, 0, SEEK_SET);
 
533
 
 
534
    vcd_write_time ();
 
535
    vcd_write_version ();
 
536
    vcd_write_timescale ();
 
537
 
 
538
    vcd_write_signals (io_reg_signals, "io_register");
 
539
    vcd_write_signals (reg_signals, "register");
 
540
    vcd_write_signals (sram_signals, "sram");
 
541
    vcd_write_signals (other_signals, "other");
 
542
 
 
543
    fprintf (vcd_file, "$enddefinitions $end\n");
 
544
    fprintf (vcd_file, "\n");
 
545
 
 
546
    /* Go back to the end of the vcd-file */
 
547
    fseek (vcd_file, 0, SEEK_END);
 
548
 
 
549
    return (1);
 
550
}
 
551
 
 
552
/* Write a 8 bit binary value to the vcd file. */
 
553
 
 
554
void
 
555
vcd_write_bit8 (unsigned char val)
 
556
{
 
557
    int i;
 
558
 
 
559
    fputc ('b', vcd_file);      /* write binary signature */
 
560
    for (i = 0x80; i > 0; i /= 2) /* shift bit in i for masking */
 
561
        fputc (((val & i) != 0) + '0', vcd_file); /* write masked bit */
 
562
}
 
563
 
 
564
/* Write a 16 bit binary value to the vcd file. */
 
565
 
 
566
void
 
567
vcd_write_bit16 (unsigned short val)
 
568
{
 
569
    int i;
 
570
 
 
571
    fputc ('b', vcd_file);      /* write binary signature */
 
572
    for (i = 0x8000; i > 0; i /= 2) /* shift bit in i for masking */
 
573
        fputc (((val & i) != 0) + '0', vcd_file); /* write masked bit */
 
574
}
 
575
 
 
576
/* Write io-register to the vcd file. */
 
577
 
 
578
int
 
579
vcd_write_io_reg (int io_reg_addr, unsigned char val)
 
580
{
 
581
    DEBUG_FKT_CALL (fprintf
 
582
                    (stderr, "io_vcd_write_reg( %i, %i )\n", io_reg_addr,
 
583
                     val));
 
584
 
 
585
    if (!vcd_file)
 
586
        return (0);
 
587
 
 
588
    if (!io_reg_dump_table[io_reg_addr])
 
589
        return (0);
 
590
 
 
591
    vcd_write_clock ();
 
592
    vcd_write_bit8 (val);
 
593
    fprintf (vcd_file, " ioreg%x\n", io_reg_addr); /* write identifier */
 
594
 
 
595
    fflush (vcd_file);          /* for debug only */
 
596
 
 
597
    return (1);
 
598
}
 
599
 
 
600
/* Write register to the vcd file. */
 
601
 
 
602
int
 
603
vcd_write_reg (int reg_num, unsigned char val)
 
604
{
 
605
    DEBUG_FKT_CALL (fprintf
 
606
                    (stderr, "vcd_write_reg( %i, %i )\n", reg_num, val));
 
607
 
 
608
    if (!vcd_file)
 
609
        return (0);
 
610
 
 
611
    if (!reg_dump_table[reg_num])
 
612
        return (0);
 
613
 
 
614
    vcd_write_clock ();
 
615
    vcd_write_bit8 (val);
 
616
    fprintf (vcd_file, " reg%x\n", reg_num); /* write identifier */
 
617
 
 
618
    fflush (vcd_file);          /* for debug only */
 
619
 
 
620
    return (1);
 
621
}
 
622
 
 
623
/* Write sram to the vcd file. */
 
624
 
 
625
int
 
626
vcd_write_sram (int sram_addr, unsigned char val)
 
627
{
 
628
    DEBUG_FKT_CALL (fprintf
 
629
                    (stderr, "vcd_write_sram( %i, %i )\n", sram_addr, val));
 
630
 
 
631
    if (!vcd_file)
 
632
        return (0);
 
633
 
 
634
    if ((sram_addr < 0) || (sram_addr > sizes.sram_size - 1))
 
635
        return (0);
 
636
 
 
637
    if (!sram_dump_table[sram_addr])
 
638
        return (0);
 
639
 
 
640
    vcd_write_clock ();
 
641
    vcd_write_bit8 (val);
 
642
    fprintf (vcd_file, " sram%x\n", sram_addr); /* write identifier */
 
643
 
 
644
    fflush (vcd_file);          /* for debug only */
 
645
 
 
646
    return (1);
 
647
}
 
648
 
 
649
/* Write stack pointer to the vcd file. */
 
650
 
 
651
int
 
652
vcd_write_sp (int sp)
 
653
{
 
654
    static unsigned int written_sp = -1;
 
655
 
 
656
    DEBUG_FKT_CALL (fprintf (stderr, "vcd_write_sp( %i )\n", sp));
 
657
 
 
658
    if (!vcd_file)
 
659
        return (0);
 
660
 
 
661
    if (!sp_dump_table || (sp == written_sp))
 
662
        return (1);
 
663
 
 
664
    written_sp = sp;
 
665
 
 
666
    vcd_write_clock ();
 
667
    vcd_write_bit16 (sp);
 
668
    fprintf (vcd_file, " sp\n"); /* write identifier */
 
669
 
 
670
    fflush (vcd_file);          /* for debug only */
 
671
 
 
672
    return (1);
 
673
}
 
674
 
 
675
/* Write program counter to the vcd file. */
 
676
 
 
677
int
 
678
vcd_write_pc (int pc)
 
679
{
 
680
    DEBUG_FKT_CALL (fprintf (stderr, "vcd_write_pc( %i )\n", pc));
 
681
 
 
682
    if (!vcd_file)
 
683
        return (0);
 
684
 
 
685
    if (!pc_dump_table)
 
686
        return (0);
 
687
 
 
688
    vcd_write_clock ();
 
689
    vcd_write_bit16 (pc);
 
690
    fprintf (vcd_file, " pc\n"); /* write identifier */
 
691
 
 
692
    fflush (vcd_file);          /* for debug only */
 
693
 
 
694
    return (1);
 
695
}
 
696
 
 
697
/* Set the current time. */
 
698
 
 
699
inline int
 
700
vcd_set_clock (unsigned int c)
 
701
{
 
702
    clk = c;
 
703
 
 
704
    return 0;                   /* FIXME: why wasn't this returning
 
705
                                   anything? */
 
706
}
 
707
 
 
708
/* Write current time to the vcd file. */
 
709
 
 
710
int
 
711
vcd_write_clock (void)
 
712
{
 
713
    static unsigned int written_clk = -1;
 
714
    static unsigned int factor = 1e9;
 
715
 
 
716
    if (!vcd_file)
 
717
        return (0);
 
718
 
 
719
    /* Have we already written the current time? */
 
720
    if (clk == written_clk)
 
721
        return (1);
 
722
    written_clk = clk;
 
723
 
 
724
    /* Write the current time */
 
725
    fprintf (vcd_file, "#%i\n", clk * (factor / frequency));
 
726
 
 
727
    fflush (vcd_file);          /* for debug only */
 
728
 
 
729
    return (1);
 
730
}