Add the .demux device.
This commit is contained in:
parent
5d41e98c1f
commit
faf7f30283
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: compile.h,v 1.56.2.2 2006/03/12 07:34:21 steve Exp $"
|
||||
#ident "$Id: compile.h,v 1.56.2.3 2006/03/26 23:09:00 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
|
@ -120,6 +120,9 @@ extern void compile_decode_adr(char*label,
|
|||
extern void compile_decode_en(char*label, char*decoder, int slice,
|
||||
struct symb_s enable,
|
||||
struct symb_s mass_enable);
|
||||
extern void compile_demux(char*label, char*decoder, int slice,
|
||||
struct symb_s not_selected,
|
||||
struct symb_s selected);
|
||||
extern void compile_shiftl(char*label, long width,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
extern void compile_shiftr(char*label, long width,
|
||||
|
|
@ -273,6 +276,9 @@ extern void compile_net(char*label, char*name,
|
|||
|
||||
/*
|
||||
* $Log: compile.h,v $
|
||||
* Revision 1.56.2.3 2006/03/26 23:09:00 steve
|
||||
* Add the .demux device.
|
||||
*
|
||||
* Revision 1.56.2.2 2006/03/12 07:34:21 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
|
|
|
|||
120
vvp/decoder.cc
120
vvp/decoder.cc
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ident "$Id: decoder.cc,v 1.1.2.2 2006/03/12 07:34:21 steve Exp $"
|
||||
#ident "$Id: decoder.cc,v 1.1.2.3 2006/03/26 23:09:00 steve Exp $"
|
||||
|
||||
# include "compile.h"
|
||||
# include "functor.h"
|
||||
|
|
@ -67,10 +67,33 @@ struct vvp_decode_adr_s : public functor_s {
|
|||
vvp_ipoint_t ix;
|
||||
const unsigned width;
|
||||
// Keep a list of decode_en objects that reference me.
|
||||
struct vvp_decode_en_s* enable_list;
|
||||
struct vvp_decodable_s* enable_list;
|
||||
};
|
||||
|
||||
struct vvp_decode_en_s : public functor_s {
|
||||
/*
|
||||
* A vvp_decodeable_s object may receive results from an address
|
||||
* decoder. The propagate_decoder_address virtual method is called by
|
||||
* the address decoder for all the associated decodable objects.
|
||||
*/
|
||||
struct vvp_decodable_s {
|
||||
vvp_decodable_s(vvp_decode_adr_s*dec, unsigned s)
|
||||
: decoder(dec), self(s)
|
||||
{
|
||||
enable_next = decoder->enable_list;
|
||||
decoder->enable_list = this;
|
||||
}
|
||||
|
||||
virtual void propagate_decoder_address(unsigned adr) =0;
|
||||
|
||||
struct vvp_decode_adr_s*decoder;
|
||||
const unsigned self;
|
||||
|
||||
struct vvp_decodable_s* enable_next;
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
struct vvp_decode_en_s : public functor_s, public vvp_decodable_s {
|
||||
|
||||
vvp_decode_en_s(vvp_decode_adr_s*dec, unsigned s);
|
||||
|
||||
|
|
@ -78,10 +101,6 @@ struct vvp_decode_en_s : public functor_s {
|
|||
|
||||
void propagate_decoder_address(unsigned adr);
|
||||
|
||||
struct vvp_decode_adr_s*decoder;
|
||||
struct vvp_decode_en_s* enable_next;
|
||||
|
||||
const unsigned self;
|
||||
// This is the enable calculated from the decoder
|
||||
bool decode_en;
|
||||
// This is the enable that arrives from the extra input.
|
||||
|
|
@ -90,6 +109,19 @@ struct vvp_decode_en_s : public functor_s {
|
|||
bool mass_en;
|
||||
};
|
||||
|
||||
struct vvp_demux_s : public functor_s, public vvp_decodable_s {
|
||||
|
||||
vvp_demux_s(vvp_decode_adr_s*dec, unsigned s);
|
||||
|
||||
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
|
||||
void propagate_decoder_address(unsigned adr);
|
||||
|
||||
unsigned char sel_val;
|
||||
unsigned char not_val;
|
||||
bool decode_en;
|
||||
};
|
||||
|
||||
vvp_decode_adr_s::vvp_decode_adr_s(vvp_ipoint_t me, unsigned w)
|
||||
: ix(me), width(w), enable_list(0)
|
||||
{
|
||||
|
|
@ -111,21 +143,17 @@ void vvp_decode_adr_s::set(vvp_ipoint_t i, bool push,
|
|||
|
||||
}
|
||||
|
||||
for (vvp_decode_en_s*cur = enable_list ; cur ; cur = cur->enable_next)
|
||||
for (vvp_decodable_s*cur = enable_list ; cur ; cur = cur->enable_next)
|
||||
cur->propagate_decoder_address(cur_adr);
|
||||
}
|
||||
|
||||
vvp_decode_en_s::vvp_decode_en_s(vvp_decode_adr_s*dec, unsigned s)
|
||||
: self(s)
|
||||
: vvp_decodable_s(dec, s)
|
||||
{
|
||||
enable_next = 0;
|
||||
decode_en = false;
|
||||
extra_en = true;
|
||||
mass_en = false;
|
||||
|
||||
decoder = dec;
|
||||
enable_next = decoder->enable_list;
|
||||
decoder->enable_list = this;
|
||||
}
|
||||
|
||||
void vvp_decode_en_s::set(vvp_ipoint_t i, bool push,
|
||||
|
|
@ -173,6 +201,50 @@ void vvp_decode_en_s::propagate_decoder_address(unsigned adr)
|
|||
put_oval(0, true);
|
||||
}
|
||||
|
||||
vvp_demux_s::vvp_demux_s(vvp_decode_adr_s*dec, unsigned s)
|
||||
: vvp_decodable_s(dec, s)
|
||||
{
|
||||
decode_en = false;
|
||||
sel_val = StX;
|
||||
not_val = StX;
|
||||
}
|
||||
|
||||
void vvp_demux_s::set(vvp_ipoint_t i, bool push,
|
||||
unsigned val, unsigned str)
|
||||
{
|
||||
functor_t ifu = functor_index(i);
|
||||
ifu->put(i, val);
|
||||
|
||||
unsigned port = ipoint_port(i);
|
||||
switch (port) {
|
||||
case 0: // not-selected input
|
||||
not_val = val;
|
||||
break;
|
||||
case 1: // is-selected input
|
||||
sel_val = val;
|
||||
break;
|
||||
}
|
||||
|
||||
if (decode_en)
|
||||
put_oval(sel_val, true);
|
||||
else
|
||||
put_oval(not_val, true);
|
||||
}
|
||||
|
||||
void vvp_demux_s::propagate_decoder_address(unsigned adr)
|
||||
{
|
||||
if (adr == self) {
|
||||
decode_en = true;
|
||||
} else {
|
||||
decode_en = false;
|
||||
}
|
||||
|
||||
if (decode_en)
|
||||
put_oval(sel_val, true);
|
||||
else
|
||||
put_oval(not_val, true);
|
||||
}
|
||||
|
||||
void compile_decode_adr(char*label, unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
unsigned nfun = (argc + 3)/4;
|
||||
|
|
@ -216,8 +288,30 @@ void compile_decode_en(char*label, char*decoder, int slice,
|
|||
free(label);
|
||||
}
|
||||
|
||||
void compile_demux(char*label, char*decoder, int slice,
|
||||
struct symb_s not_selected,
|
||||
struct symb_s selected)
|
||||
{
|
||||
vvp_decode_adr_s*adr = decoder_find(decoder);
|
||||
vvp_demux_s*a = new struct vvp_demux_s(adr, slice);
|
||||
|
||||
vvp_ipoint_t ix = functor_allocate(1);
|
||||
functor_define(ix, a);
|
||||
|
||||
symb_s argv[2];
|
||||
argv[0] = not_selected;
|
||||
argv[1] = selected;
|
||||
inputs_connect(ix, 2, argv);
|
||||
|
||||
define_functor_symbol(label, ix);
|
||||
free(label);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: decoder.cc,v $
|
||||
* Revision 1.1.2.3 2006/03/26 23:09:00 steve
|
||||
* Add the .demux device.
|
||||
*
|
||||
* Revision 1.1.2.2 2006/03/12 07:34:21 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: lexor.lex,v 1.43.2.1 2006/02/19 00:11:36 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.43.2.2 2006/03/26 23:09:00 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -97,6 +97,7 @@
|
|||
".cmp/gt.s" { return K_CMP_GT_S; }
|
||||
".decode/adr" { return K_DECODE_ADR; }
|
||||
".decode/en" { return K_DECODE_EN; }
|
||||
".demux" { return K_DEMUX; }
|
||||
".event" { return K_EVENT; }
|
||||
".event/or" { return K_EVENT_OR; }
|
||||
".functor" { return K_FUNCTOR; }
|
||||
|
|
@ -184,6 +185,9 @@ int yywrap()
|
|||
|
||||
/*
|
||||
* $Log: lexor.lex,v $
|
||||
* Revision 1.43.2.2 2006/03/26 23:09:00 steve
|
||||
* Add the .demux device.
|
||||
*
|
||||
* Revision 1.43.2.1 2006/02/19 00:11:36 steve
|
||||
* Handle synthesis of FF vectors with l-value decoder.
|
||||
*
|
||||
|
|
|
|||
11
vvp/parse.y
11
vvp/parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: parse.y,v 1.60.2.2 2006/03/12 07:34:21 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.60.2.3 2006/03/26 23:09:01 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -60,7 +60,7 @@ extern FILE*yyin;
|
|||
%token K_ARITH_DIV K_ARITH_DIV_S K_ARITH_MOD K_ARITH_MULT
|
||||
%token K_ARITH_SUB K_ARITH_SUM
|
||||
%token K_CMP_EQ K_CMP_NE K_CMP_GE K_CMP_GE_S K_CMP_GT K_CMP_GT_S
|
||||
%token K_DECODE_ADR K_DECODE_EN
|
||||
%token K_DECODE_ADR K_DECODE_EN K_DEMUX
|
||||
%token K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S K_PARAM
|
||||
%token K_RESOLV K_SCOPE K_SHIFTL K_SHIFTR K_THREAD K_TIMESCALE K_UFUNC
|
||||
%token K_UDP K_UDP_C K_UDP_S
|
||||
|
|
@ -274,6 +274,10 @@ statement
|
|||
{ compile_decode_en($1, $3, $5, $7, $9);
|
||||
}
|
||||
|
||||
| T_LABEL K_DEMUX T_SYMBOL ',' T_NUMBER ',' symbol ',' symbol ';'
|
||||
{ compile_demux($1, $3, $5, $7, $9);
|
||||
}
|
||||
|
||||
/* Event statements take a label, a type (the first T_SYMBOL) and a
|
||||
list of inputs. If the type is instead a string, then we have a
|
||||
named event instead. */
|
||||
|
|
@ -646,6 +650,9 @@ int compile_design(const char*path)
|
|||
|
||||
/*
|
||||
* $Log: parse.y,v $
|
||||
* Revision 1.60.2.3 2006/03/26 23:09:01 steve
|
||||
* Add the .demux device.
|
||||
*
|
||||
* Revision 1.60.2.2 2006/03/12 07:34:21 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue