File: plimfil.c

package info (click to toggle)
gplcver 2.12a-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 7,604 kB
  • ctags: 9,129
  • sloc: ansic: 126,201; sh: 1,539; makefile: 86; perl: 22
file content (151 lines) | stat: -rw-r--r-- 3,793 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* Copyright (c) 1994-2003 Pragmatic C Software Corp. */

/* 
 * example illustrating using PLI tf_ utility routines to fill memory
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "veriuser.h"
#include "cv_veriuser.h"

/* define this to use Cver's immediate assign tf_strputp routine */
/* #define __HAS_STRPUTP__ */

int memsiz, memwid, last_i;
FILE *memval_s;

/* local prototypes */
int intsize(int, int);
static void plisetupmemfill(int, int);
static void check_plimemfill(int, int);
static void plimemfill(int, int);

int intsize(int data, int reason)
{
 return(32);
}

/*
 * routine to setup memory filling routine - set param to 0 on error else 1
 * function: $plisetupmemfill(memsiz, memwid)
 */
static void plisetupmemfill(int data, int reason)
{
 char *chp;

 /* get file name as + verilog argument */
 if ((chp = mc_scan_plusargs("memfile+")) == NULL || strcmp(chp, "") == 0)
  {
   tf_error("missing or empty +memfile+[file name] memory file argument");
   tf_putp(0, 0);
   return;
  }
 /* open the file */
 if ((memval_s = fopen(chp, "r")) == NULL)
  {  
   tf_error("unable to open +memfile+ memory file %s", chp); 
   tf_putp(0, 0);
   return;
  }
 /* need memory size for checking */
 memsiz = tf_getp(1);
 memwid = tf_getp(2);
 tf_putp(0, 1);
 /* assume memory goes from 1 to size */
 last_i = 0; 
}

/*
 * check the fill memory user PLI function
 * notice calling tf_error here will inhibit simulation
 * probably sould also check 2nd index argument 
 */
static void check_plimemfill(int data, int reason)
{
 struct t_tfexprinfo xinfo;

 if (tf_nump() != 2)
  {
   tf_error("$pli_memfill has %d arguments - 2 required", tf_nump());
   return;
  }
 tf_exprinfo(1, &xinfo);
 if (xinfo.expr_type != TF_RWMEMSELECT)
  {
   tf_error("$pli_memfill first argument not read/write memory select");
   return;
  }
}

/*
 * routine to set memory 
 * function: $pli_memfill(mem[i], i)
 */
static void plimemfill(int data, int reason)
{
 int i;
 char memval[1024];

 i = tf_getp(2);
 if (i < 0 || i > memsiz) 
  {
   tf_error("cannot fill memory location %d - memory has only %d cells");
   tf_putp(0, 0);
   return;
  }
 if (fscanf(memval_s, "%s", memval) != 1)
  {
   /* problably should access OS error name here */
   tf_error("error reading memory value for cell %d", i);
   tf_putp(0, 0);
   return;
  }
 /* probably should add code to check for memval as legal binary number */
 /* but can be any width since putp assignment will widen or truncate */

 /* make sure index i is legal - since must have used i in memory select */
 /* only for checking */
 if (i != last_i + 1)
  {
   tf_error("memory index %d non in sequence - %d expected", i, last_i + 1);
   tf_putp(0, 0);
   return;
  }
 last_i = i;

 /* this is #0, in Cver you would use extension routine tf_strputp */
 /* it is identical to tf_strdelputp except string assignment immediate */
#ifdef __HAS_STRPUTP__
 /* notice need final delay type parameter since may need to cancel */
 /* events if delay form used elsewhere */
 printf("*** using tf_strputp\n"); 
 if (tf_strputp(1, memwid, 'b', memval) == 0)
#else
 if (tf_strdelputp(1, memwid, 'b', memval, 0, 0) == 0)
#endif
  {
   tf_error("strdelput of index memory failed");
   tf_putp(0, 0);
   return;
  }
 tf_putp(0, 1);
}

/* example that goes in user code */
s_tfcell veriusertfs[] = 
{ 
 { userfunction, 0, 0, (int (*)()) intsize, (int (*)()) plisetupmemfill, 0,
   "$pli_setupmemfill", 0},
 { userfunction, 0, (int (*)()) check_plimemfill, (int (*)()) intsize,
  (int (*)()) plimemfill, 0, "$pli_memfill", 0},
 /* -- add extra entries here -- */
 {0} /* -- this line must always be last -- */
};

/* dummy +loadpli1 boostrap routine - return old style veriusertfs tab */
s_tfcell *pli1_compat_bootstrap(void)
{
 return(veriusertfs);
}