Change the VPI call process so that loaded .vpi modules
use a function table instead of implicit binding.
This commit is contained in:
parent
e28b7f06c5
commit
7009dc8d9b
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: README.txt,v 1.27 2001/06/07 03:09:03 steve Exp $
|
||||
* $Id: README.txt,v 1.28 2001/06/15 03:28:30 steve Exp $
|
||||
*/
|
||||
|
||||
VVP SIMULATION ENGINE
|
||||
|
|
@ -296,28 +296,44 @@ data bus, bit 0 is the lsb of the first word, bit 20 is the lsb of the
|
|||
second word.
|
||||
|
||||
Structural read access is implemented in terms of address and data
|
||||
ports. An address port is the concatinations of the smallest number of
|
||||
address bits required to express each address range. The addresses
|
||||
applied to the address port are expected to be withing the ranges
|
||||
specified.
|
||||
ports. The addresses applied to the address port are expected to be
|
||||
withing the ranges specified, not based at zero.
|
||||
|
||||
An port is a vector of functors that is wide enough to accept all
|
||||
address bits and at least as wide as the requested subset of the data
|
||||
port.
|
||||
A read port is a vector of functors that is wide enough to accept all
|
||||
provided address bits and at least as wide as the requested subset of
|
||||
the data port.
|
||||
|
||||
<label> .mem/port <memid>, <msb>,<lsb>, <symbols_list> ;
|
||||
<label> .mem/port <memid>, <msb>,<lsb>, <aw>, <addr_bits> ;
|
||||
|
||||
<label> identifies the vector of output functors, to allow connections
|
||||
to the data output. <memid> is the label of the memory. <msb>,<lsb>
|
||||
select a part of the data width. These are not relative to the data
|
||||
port range defined for the memory. The LSB of the data word if here
|
||||
port range defined for the memory. The LSB of the data word is here
|
||||
referred to as 0, regardless to the range specified in the memory
|
||||
definition. The <symbols_list> connects to the address inputs of this
|
||||
port.
|
||||
definition. <addr_bits> is a list of symbols, which connect to the
|
||||
address inputs of this port. There are <aw> address bits (<aw> may
|
||||
become a list of numbers, when multi-index memory ports become
|
||||
supported).
|
||||
|
||||
Any address change, or any change in the addressed memory contents is
|
||||
imediately propagated to the port outputs.
|
||||
|
||||
A write port is a superset of a read port. It is a vector of functors
|
||||
that is wide enough to accept the address bits, an event input, a
|
||||
write enable input, and the data inputs.
|
||||
|
||||
<label> .mem/port <memid>, <msb>,<lsb>, <aw>, <addr_bits>,
|
||||
<event>, <we>, <data> ;
|
||||
|
||||
<event> is an event functor that triggers a write, if the <we> input
|
||||
is true. <data> is a list of symbols that connect to the data input
|
||||
port. For asynchronous transparent write operation, connect
|
||||
<event> to C<z>, the RAM will transparently follow any changes on
|
||||
address and data lines, while <we> is true.
|
||||
|
||||
There is no Verilog construct that calls for a structural write port
|
||||
to a memory, but synthesis may ask for lpm_ram_d[pq] objects.
|
||||
|
||||
To initialize a memory, use:
|
||||
|
||||
.mem/init <memid>[<start>],
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.cc,v 1.74 2001/06/10 17:12:51 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.75 2001/06/15 03:28:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
|
|
@ -612,6 +612,7 @@ void compile_memory(char *label, char *name, int msb, int lsb,
|
|||
|
||||
void compile_memory_port(char *label, char *memid,
|
||||
unsigned msb, unsigned lsb,
|
||||
unsigned naddr,
|
||||
unsigned argc, struct symb_s *argv)
|
||||
{
|
||||
vvp_memory_t mem = memory_find(memid);
|
||||
|
|
@ -624,21 +625,25 @@ void compile_memory_port(char *label, char *memid,
|
|||
assert (msb < memory_data_width(mem));
|
||||
unsigned nbits = msb-lsb+1;
|
||||
|
||||
unsigned awidth = memory_addr_width(mem);
|
||||
unsigned nfun = (awidth + 3)/4;
|
||||
bool writable = argc >= (naddr + 2 + nbits);
|
||||
|
||||
unsigned nfun = naddr;
|
||||
if (writable)
|
||||
nfun += 2 + nbits;
|
||||
assert(nfun == argc);
|
||||
nfun = (nfun+3)/4;
|
||||
if (nfun < nbits)
|
||||
nfun = nbits;
|
||||
|
||||
vvp_ipoint_t ix = functor_allocate(nfun);
|
||||
|
||||
assert(argc == awidth);
|
||||
define_functor_symbol(label, ix);
|
||||
free(label);
|
||||
|
||||
inputs_connect(ix, argc, argv);
|
||||
free(argv);
|
||||
|
||||
memory_port_new(mem, ix, nbits, lsb);
|
||||
memory_port_new(mem, ix, nbits, lsb, naddr, writable);
|
||||
}
|
||||
|
||||
void compile_memory_init(char *memid, unsigned i, unsigned char val)
|
||||
|
|
@ -1335,6 +1340,10 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
|
|||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.75 2001/06/15 03:28:31 steve
|
||||
* Change the VPI call process so that loaded .vpi modules
|
||||
* use a function table instead of implicit binding.
|
||||
*
|
||||
* Revision 1.74 2001/06/10 17:12:51 steve
|
||||
* Instructions can forward reference functors.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.h,v 1.25 2001/06/07 03:09:03 steve Exp $"
|
||||
#ident "$Id: compile.h,v 1.26 2001/06/15 03:28:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
|
@ -108,6 +108,7 @@ extern void compile_memory(char *label, char *name, int lsb, int msb,
|
|||
|
||||
extern void compile_memory_port(char *label, char *memid,
|
||||
unsigned lsb, unsigned msb,
|
||||
unsigned naddr,
|
||||
unsigned argc, struct symb_s *argv);
|
||||
|
||||
extern void compile_memory_init(char *memid, unsigned idx, unsigned char val);
|
||||
|
|
@ -190,6 +191,10 @@ extern void compile_net(char*label, char*name,
|
|||
|
||||
/*
|
||||
* $Log: compile.h,v $
|
||||
* Revision 1.26 2001/06/15 03:28:31 steve
|
||||
* Change the VPI call process so that loaded .vpi modules
|
||||
* use a function table instead of implicit binding.
|
||||
*
|
||||
* Revision 1.25 2001/06/07 03:09:03 steve
|
||||
* Implement .arith/sub subtraction.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
|
||||
; This sample demonstrates memory, also including index register
|
||||
; arithmetic.
|
||||
; arithmetic. And a memory write port
|
||||
|
||||
main .scope "example";
|
||||
|
||||
|
|
@ -36,12 +36,20 @@ memory .mem "memory", 8,2, 27,5 ;
|
|||
;;; An address/data port.
|
||||
;
|
||||
; reg [4:0] a;
|
||||
; reg we;
|
||||
; event wclk;
|
||||
; reg [5:0] di;
|
||||
; wire [5:0] d = memory[a][8:3];
|
||||
; reg [6:0] m;
|
||||
|
||||
a .var "a", 4,0;
|
||||
we .var "we", 0,0;
|
||||
wclk .event "wclk";
|
||||
di .var "di", 5,0;
|
||||
d .net "d", 5,0, mem[0],mem[1],mem[2],mem[3],mem[4],mem[5];
|
||||
mem .mem/port memory, 6,1, a[0],a[1],a[2],a[3],a[4];
|
||||
mem .mem/port memory, 6,1,
|
||||
5, a[0],a[1],a[2],a[3],a[4],
|
||||
wclk, we, di[0],di[1],di[2],di[3],di[4],di[5];
|
||||
m .var "m", 6,0;
|
||||
|
||||
;;; The data port mem[] does not connect to the LSB of the memory.
|
||||
|
|
@ -76,6 +84,7 @@ m .var "m", 6,0;
|
|||
; always
|
||||
; begin
|
||||
; #5 $display("a:%b d:%b", a, d);
|
||||
; -> wclk;
|
||||
; #5 a <= a+1;
|
||||
; end
|
||||
|
||||
|
|
@ -85,6 +94,8 @@ always ;
|
|||
|
||||
%vpi_call "$display", "a:%b d:%b", a, d;
|
||||
|
||||
%set wclk, 0;
|
||||
|
||||
%delay 5;
|
||||
|
||||
%load 10, a[0];
|
||||
|
|
@ -109,8 +120,18 @@ always ;
|
|||
;
|
||||
; initial
|
||||
; begin
|
||||
; we = 0;
|
||||
; di = 'b 10zx10;
|
||||
; a = 0;
|
||||
; #320;
|
||||
; #220;
|
||||
; $readmemh("memory.hex", memory);
|
||||
; #30;
|
||||
; we = 1;
|
||||
; #5;
|
||||
; $display("write to a=%b", a);
|
||||
; #5;
|
||||
; we = 0;
|
||||
; #60;
|
||||
; memory[23] <= 'b 1xz01;
|
||||
; #320;
|
||||
; m = memory[9];
|
||||
|
|
@ -121,6 +142,13 @@ always ;
|
|||
|
||||
.scope main;
|
||||
initial ;
|
||||
%set we, 0;
|
||||
%set di[0], 0;
|
||||
%set di[1], 1;
|
||||
%set di[2], 2;
|
||||
%set di[3], 3;
|
||||
%set di[4], 0;
|
||||
%set di[5], 1;
|
||||
%set a[0], 0;
|
||||
%set a[1], 0;
|
||||
%set a[2], 0;
|
||||
|
|
@ -129,7 +157,13 @@ initial ;
|
|||
|
||||
%delay 220;
|
||||
%vpi_call "$readmemh", "memory.hex", memory;
|
||||
%delay 100;
|
||||
%delay 30;
|
||||
%set we, 1;
|
||||
%delay 5;
|
||||
%vpi_call "$display", "write to a=%b", a;
|
||||
%delay 5;
|
||||
%set we, 0;
|
||||
%delay 60;
|
||||
|
||||
;;; Memories are indexed by index register 3. The index register
|
||||
;;; points to the bit position in the memory. Each memory word
|
||||
|
|
|
|||
140
vvp/memory.cc
140
vvp/memory.cc
|
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: memory.cc,v 1.3 2001/05/08 23:59:33 steve Exp $"
|
||||
#ident "$Id: memory.cc,v 1.4 2001/06/15 03:28:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include "memory.h"
|
||||
|
|
@ -37,7 +37,6 @@ struct vvp_memory_s
|
|||
|
||||
// Address port properties:
|
||||
unsigned size; // total number of data words
|
||||
unsigned awidth; // total number of address bits
|
||||
unsigned a_idxs; // number of address indices
|
||||
vvp_memory_index_t a_idx; // vector of address indices
|
||||
|
||||
|
|
@ -55,18 +54,12 @@ unsigned memory_data_width(vvp_memory_t mem)
|
|||
return mem->width;
|
||||
}
|
||||
|
||||
unsigned memory_addr_width(vvp_memory_t mem)
|
||||
{
|
||||
return mem->awidth;
|
||||
}
|
||||
|
||||
#define VVP_MEMORY_NO_ADDR ((int)0x80000000)
|
||||
|
||||
struct vvp_memory_index_s
|
||||
{
|
||||
int first; // first memory address
|
||||
unsigned size; // number of valid addresses
|
||||
unsigned awidth; // width of address port
|
||||
};
|
||||
|
||||
struct vvp_memory_port_s : public vvp_fobj_s
|
||||
|
|
@ -76,11 +69,16 @@ struct vvp_memory_port_s : public vvp_fobj_s
|
|||
|
||||
vvp_memory_t mem;
|
||||
vvp_ipoint_t ix;
|
||||
|
||||
unsigned naddr;
|
||||
|
||||
vvp_memory_port_t next;
|
||||
int cur_addr;
|
||||
vvp_memory_bits_t cur_bits;
|
||||
int bitoff;
|
||||
int nbits;
|
||||
unsigned bitoff;
|
||||
unsigned nbits;
|
||||
|
||||
bool writable;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -142,7 +140,6 @@ void memory_new(vvp_memory_t mem, char *name, int msb, int lsb,
|
|||
assert(mem->a_idxs);
|
||||
|
||||
mem->size = 1;
|
||||
mem->awidth = 0;
|
||||
for (unsigned i=0; i < mem->a_idxs; i++)
|
||||
{
|
||||
vvp_memory_index_t x = mem->a_idx + i;
|
||||
|
|
@ -156,19 +153,6 @@ void memory_new(vvp_memory_t mem, char *name, int msb, int lsb,
|
|||
x->size = lsw - msw + 1;
|
||||
x->first = msw;
|
||||
}
|
||||
int m = lsw ^ msw;
|
||||
x->awidth = 0;
|
||||
if (m < 0)
|
||||
{
|
||||
if (lsw < 0)
|
||||
m = ~lsw | msw;
|
||||
else
|
||||
m = lsw | ~msw;
|
||||
x->awidth++;
|
||||
}
|
||||
for (int c=1; c<m; c<<=1)
|
||||
x->awidth ++;
|
||||
mem->awidth += x->awidth;
|
||||
mem->size *= x->size;
|
||||
}
|
||||
|
||||
|
|
@ -182,19 +166,25 @@ void memory_new(vvp_memory_t mem, char *name, int msb, int lsb,
|
|||
|
||||
|
||||
void memory_port_new(vvp_memory_t mem, vvp_ipoint_t ix,
|
||||
unsigned nbits, unsigned bitoff)
|
||||
unsigned nbits, unsigned bitoff,
|
||||
unsigned naddr, bool writable)
|
||||
{
|
||||
vvp_memory_port_t a = new struct vvp_memory_port_s;
|
||||
|
||||
a->mem = mem;
|
||||
a->ix = ix;
|
||||
a->naddr = naddr;
|
||||
a->writable = writable;
|
||||
a->nbits = nbits;
|
||||
a->bitoff = bitoff;
|
||||
|
||||
a->next = mem->addr_root;
|
||||
a->mem->addr_root = a;
|
||||
|
||||
unsigned nfun = (a->mem->awidth+3)/4;
|
||||
unsigned nfun = naddr;
|
||||
if (writable)
|
||||
nfun += 2 + nbits;
|
||||
nfun = (nfun+3)/4;
|
||||
if (nfun < nbits)
|
||||
nfun = nbits;
|
||||
|
||||
|
|
@ -225,25 +215,14 @@ void memory_init_nibble(vvp_memory_t mem, unsigned idx, unsigned char val)
|
|||
inline static
|
||||
vvp_memory_bits_t get_word(vvp_memory_t mem, int addr)
|
||||
{
|
||||
if (addr == VVP_MEMORY_NO_ADDR)
|
||||
return 0x0;
|
||||
|
||||
// Compute the word index into the bits array.
|
||||
unsigned waddr = 0;
|
||||
for (unsigned i = 0; i<mem->a_idxs; i++)
|
||||
{
|
||||
vvp_memory_index_t x = mem->a_idx + i;
|
||||
unsigned iwaddr = (addr - x->first) & ((1<<x->awidth) - 1);
|
||||
waddr *= x->size;
|
||||
// This fails for negative
|
||||
if (iwaddr >= x->size)
|
||||
return 0x0;
|
||||
waddr += iwaddr;
|
||||
addr >>= x->awidth;
|
||||
}
|
||||
|
||||
assert(waddr < mem->size);
|
||||
|
||||
|
||||
assert(mem->a_idxs==1);
|
||||
unsigned waddr = addr - mem->a_idx[0].first;
|
||||
|
||||
if (waddr >= mem->size)
|
||||
return 0x0;
|
||||
|
||||
return mem->bits + waddr*mem->fwidth;
|
||||
}
|
||||
|
||||
|
|
@ -294,7 +273,7 @@ bool update_addr_bit(vvp_memory_port_t addr, vvp_ipoint_t ip)
|
|||
{
|
||||
unsigned abit = ip - addr->ix;
|
||||
|
||||
assert(abit >= 0 && abit < addr->mem->awidth);
|
||||
assert(abit >= 0 && abit < addr->naddr);
|
||||
|
||||
int old = addr->cur_addr;
|
||||
|
||||
|
|
@ -319,7 +298,7 @@ static
|
|||
void update_addr(vvp_memory_port_t addr)
|
||||
{
|
||||
addr->cur_addr = 2;
|
||||
for (unsigned i=0; i < addr->mem->awidth; i++)
|
||||
for (unsigned i=0; i < addr->naddr; i++)
|
||||
{
|
||||
update_addr_bit(addr, addr->ix+i);
|
||||
if (addr->cur_addr == VVP_MEMORY_NO_ADDR)
|
||||
|
|
@ -332,7 +311,7 @@ void update_data(vvp_memory_port_t data,
|
|||
vvp_memory_bits_t bits)
|
||||
{
|
||||
assert(data);
|
||||
for (int i=0; i < data->nbits; i++)
|
||||
for (unsigned i=0; i < data->nbits; i++)
|
||||
{
|
||||
vvp_ipoint_t dx = ipoint_index(data->ix, i);
|
||||
functor_t df = functor_index(dx);
|
||||
|
|
@ -345,17 +324,6 @@ void update_data(vvp_memory_port_t data,
|
|||
}
|
||||
}
|
||||
|
||||
void vvp_memory_port_s::set(vvp_ipoint_t i, functor_t f, bool push)
|
||||
{
|
||||
if (update_addr_bit(this, i))
|
||||
update_data(this, cur_bits);
|
||||
}
|
||||
|
||||
unsigned vvp_memory_port_s::get(vvp_ipoint_t i, functor_t f)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
static
|
||||
void update_data_ports(vvp_memory_t mem, int addr, int bit,
|
||||
unsigned char val)
|
||||
|
|
@ -365,11 +333,10 @@ void update_data_ports(vvp_memory_t mem, int addr, int bit,
|
|||
{
|
||||
if (addr == a->cur_addr)
|
||||
{
|
||||
vvp_memory_port_t d = a; // historic
|
||||
int i = bit - d->bitoff;
|
||||
if (i >= 0 && i < d->nbits)
|
||||
unsigned i = bit - a->bitoff;
|
||||
if (i < a->nbits)
|
||||
{
|
||||
vvp_ipoint_t ix = ipoint_index(d->ix, i);
|
||||
vvp_ipoint_t ix = ipoint_index(a->ix, i);
|
||||
functor_t df = functor_index(ix);
|
||||
if (df->oval != val)
|
||||
{
|
||||
|
|
@ -382,6 +349,55 @@ void update_data_ports(vvp_memory_t mem, int addr, int bit,
|
|||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
void write_event(vvp_memory_port_t p)
|
||||
{
|
||||
unsigned we = functor_get_input(p->ix + p->naddr + 1);
|
||||
if (!we)
|
||||
return;
|
||||
|
||||
for (unsigned i=0; i < p->nbits; i++)
|
||||
{
|
||||
unsigned val = functor_get_input(p->ix + p->naddr + 2 + i);
|
||||
if (set_bit(p->cur_bits, i + p->bitoff, val))
|
||||
{
|
||||
// if a write would change the memory bit, but <we> is
|
||||
// undefined (x or z), set the bit to x.
|
||||
if (we > 1)
|
||||
{
|
||||
set_bit(p->cur_bits, i + p->bitoff, 2);
|
||||
val = 2;
|
||||
}
|
||||
update_data_ports(p->mem, p->cur_addr, i + p->bitoff, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_memory_port_s::set(vvp_ipoint_t i, functor_t f, bool push)
|
||||
{
|
||||
if (i < ix+naddr)
|
||||
{
|
||||
if (update_addr_bit(this, i))
|
||||
update_data(this, cur_bits);
|
||||
}
|
||||
|
||||
// An event at ix+naddr always sets the value 0, and triggeres a write.
|
||||
// If the write event port is 3, then it's not connected, and the
|
||||
// write port is transparent, controlled by ix+naddr+1, the write enable.
|
||||
|
||||
if (i == ix+naddr
|
||||
|| (writable && functor_get_input(ix+naddr) == 3))
|
||||
{
|
||||
assert(writable);
|
||||
write_event(this);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned vvp_memory_port_s::get(vvp_ipoint_t i, functor_t f)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
// %set/mem
|
||||
|
||||
|
|
|
|||
11
vvp/memory.h
11
vvp/memory.h
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: memory.h,v 1.2 2001/05/08 23:59:33 steve Exp $"
|
||||
#ident "$Id: memory.h,v 1.3 2001/06/15 03:28:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include "pointers.h"
|
||||
|
|
@ -38,7 +38,9 @@ typedef struct vvp_memory_index_s *vvp_memory_index_t;
|
|||
void memory_new(vvp_memory_t mem, char *name, int lsb, int msb,
|
||||
unsigned idxs, long *idx);
|
||||
void memory_port_new(vvp_memory_t mem, vvp_ipoint_t ix,
|
||||
unsigned nbits, unsigned bitoff);
|
||||
unsigned nbits, unsigned bitoff,
|
||||
unsigned naddr, bool writable);
|
||||
|
||||
void memory_init_nibble(vvp_memory_t mem, unsigned idx, unsigned char val);
|
||||
|
||||
void memory_set(vvp_memory_t mem, unsigned idx, unsigned char val);
|
||||
|
|
@ -46,7 +48,6 @@ unsigned memory_get(vvp_memory_t mem, unsigned idx);
|
|||
void schedule_memory(vvp_memory_t mem, unsigned idx,
|
||||
unsigned char val, unsigned delay);
|
||||
|
||||
unsigned memory_addr_width(vvp_memory_t mem);
|
||||
unsigned memory_size(vvp_memory_t mem);
|
||||
char *memory_name(vvp_memory_t mem);
|
||||
unsigned memory_data_width(vvp_memory_t mem);
|
||||
|
|
@ -60,6 +61,10 @@ vvp_memory_t memory_create(char *label);
|
|||
|
||||
/*
|
||||
* $Log: memory.h,v $
|
||||
* Revision 1.3 2001/06/15 03:28:31 steve
|
||||
* Change the VPI call process so that loaded .vpi modules
|
||||
* use a function table instead of implicit binding.
|
||||
*
|
||||
* Revision 1.2 2001/05/08 23:59:33 steve
|
||||
* Add ivl and vvp.tgt support for memories in
|
||||
* expressions and l-values. (Stephan Boettcher)
|
||||
|
|
|
|||
10
vvp/parse.y
10
vvp/parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: parse.y,v 1.29 2001/06/07 03:09:03 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.30 2001/06/15 03:28:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -139,8 +139,8 @@ statement
|
|||
| T_LABEL K_MEM T_STRING ',' T_NUMBER ',' T_NUMBER ',' numbers ';'
|
||||
{ compile_memory($1, $3, $5, $7, $9.cnt, $9.nvec); }
|
||||
|
||||
| T_LABEL K_MEM_P T_SYMBOL ',' T_NUMBER ',' T_NUMBER ',' symbols ';'
|
||||
{ compile_memory_port($1, $3, $5, $7, $9.cnt, $9.vect); }
|
||||
| T_LABEL K_MEM_P T_SYMBOL ',' T_NUMBER ',' T_NUMBER ',' T_NUMBER ',' symbols ';'
|
||||
{ compile_memory_port($1, $3, $5, $7, $9, $11.cnt, $11.vect); }
|
||||
|
||||
| mem_init_stmt
|
||||
|
||||
|
|
@ -458,6 +458,10 @@ int compile_design(const char*path)
|
|||
|
||||
/*
|
||||
* $Log: parse.y,v $
|
||||
* Revision 1.30 2001/06/15 03:28:31 steve
|
||||
* Change the VPI call process so that loaded .vpi modules
|
||||
* use a function table instead of implicit binding.
|
||||
*
|
||||
* Revision 1.29 2001/06/07 03:09:03 steve
|
||||
* Implement .arith/sub subtraction.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue