File: plimfil2.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 (158 lines) | stat: -rw-r--r-- 4,036 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
152
153
154
155
156
157
158
/* 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"

int memsiz, memwid, last_i;
FILE *memval_s;
struct t_tfnodeinfo ninfo;
struct t_tfexprinfo xinfo;

/* static prototypes */
static int intsize(int, int);
static void plisetupmemfil2(int, int);
static void check_plimemfil2(int, int);
static void plimemfil2(int, int);

static 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 plisetupmemfil2(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);
 if (memwid > 32)
  {
   tf_error("for tf_propagatep routine can only use scanf for < 32 bits");
   tf_putp(0, 0);
   return;
  }
 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_plimemfil2(int data, int reason)
{
 if (tf_nump() != 2)
  {
   tf_error("$pli_memfil2 has %d arguments - 2 required", tf_nump());
   return;
  }
 /* this associates nodeinfo struct with argument */
 tf_nodeinfo(1, &ninfo);
 if (ninfo.node_type != TF_MEMORY_NODE)
  {
   tf_error("$pli_memfil2 first argument not read/write memory select");
   return;
  }
}

/*
 * routine to set memory using tf_propagatep method  
 *
 * must be 32 bits or less otherwise would need to write vecval manipulation
 * routines
 *
 * function: $pli_memfil2(mem[i], i)
 * here tfputp would be better choice since only allows non x/z forms 
 */
static void plimemfil2(int data, int reason)
{
 int i;
 unsigned memval;
 struct t_vecval *vecp;

 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, "%u", &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;

 tf_exprinfo(1, &xinfo);
 /* set value  - using 32 bit value else would need string to 0*/
 vecp = xinfo.expr_value_p;
 vecp[0].avalbits = (int) memval;
 vecp[0].bvalbits = 0;
 /* do assign - notice this forces re-evaluate of argument during assign */
 /* SJM 12/20/02 - following LRM, fail is 1 not 0 */
 if (tf_propagatep(1) == 1)
  {  
   tf_error("tf_propagatep of indexed memory failed");
   tf_putp(0, 0);
  }
 else tf_putp(0, 1);
}

/* example that goes in user code */
s_tfcell veriusertfs[] = 
{ 
 { userfunction, 0, 0, (int (*)()) intsize, (int (*)()) plisetupmemfil2, 0,
  "$pli_setupmemfil2", 0},
 { userfunction, 0, (int (*)()) check_plimemfil2, (int (*)()) intsize,
  (int (*)()) plimemfil2, 0, "$pli_memfil2", 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);
}