diff --git a/vvp/draw_tt.c b/vvp/draw_tt.c index 0c73f0aaf..2c86f5639 100644 --- a/vvp/draw_tt.c +++ b/vvp/draw_tt.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: draw_tt.c,v 1.21 2005/06/12 21:56:16 steve Exp $" +#ident "$Id: draw_tt.c,v 1.22 2005/09/19 21:45:09 steve Exp $" #endif # include @@ -440,6 +440,7 @@ static void draw_NOR(void) printf("};\n"); } +#if 0 static void draw_NOT(void) { unsigned i0, i1, i2, i3; @@ -471,7 +472,8 @@ static void draw_NOT(void) printf("};\n"); } - +#endif +#if 0 static void draw_OR(void) { unsigned i0, i1, i2, i3; @@ -505,6 +507,7 @@ static void draw_OR(void) printf("};\n"); } +#endif static void draw_XNOR(void) { @@ -538,6 +541,7 @@ static void draw_XNOR(void) printf("};\n"); } +#if 0 static void draw_XOR(void) { unsigned i0, i1, i2, i3; @@ -569,6 +573,7 @@ static void draw_XOR(void) printf("};\n"); } +#endif static void draw_TRIAND(void) { @@ -748,12 +753,9 @@ main() draw_EEQ(); draw_NAND(); draw_NOR(); - draw_NOT(); - draw_OR(); draw_TRIAND(); draw_TRIOR(); draw_XNOR(); - draw_XOR(); draw_hex_table(); draw_oct_table(); return 0; @@ -761,6 +763,9 @@ main() /* * $Log: draw_tt.c,v $ + * Revision 1.22 2005/09/19 21:45:09 steve + * Use lazy eval of BUF/NOT/OR/XOR gates. + * * Revision 1.21 2005/06/12 21:56:16 steve * Remove unused ft_MOS truth tables. * diff --git a/vvp/logic.cc b/vvp/logic.cc index cf02a90a5..80f91e999 100644 --- a/vvp/logic.cc +++ b/vvp/logic.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: logic.cc,v 1.33 2005/09/01 04:08:47 steve Exp $" +#ident "$Id: logic.cc,v 1.34 2005/09/19 21:45:09 steve Exp $" #endif # include "logic.h" @@ -149,9 +149,18 @@ void vvp_fun_buf::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit) if (ptr.port() != 0) return; - vvp_vector4_t tmp = bit; - tmp.change_z2x(); - vvp_send_vec4(ptr.ptr()->out, tmp); + if (input_ .eeq( bit )) + return; + + input_ = bit; + net_ = ptr.ptr(); + schedule_generic(this, 0, false); +} + +void vvp_fun_buf::run_run() +{ + input_.change_z2x(); + vvp_send_vec4(net_->out, input_); } vvp_fun_bufz::vvp_fun_bufz() @@ -333,6 +342,104 @@ void vvp_fun_muxz::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit) } } +vvp_fun_not::vvp_fun_not() +{ + count_functors_table += 1; +} + +vvp_fun_not::~vvp_fun_not() +{ +} + +/* + * The buf functor is very simple--change the z bits to x bits in the + * vector it passes, and propagate the result. + */ +void vvp_fun_not::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit) +{ + if (ptr.port() != 0) + return; + + if (input_ .eeq( bit )) + return; + + input_ = bit; + net_ = ptr.ptr(); + schedule_generic(this, 0, false); +} + +void vvp_fun_not::run_run() +{ + vvp_vector4_t result (input_); + + for (unsigned idx = 0 ; idx < result.size() ; idx += 1) { + vvp_bit4_t bitbit = ~ result.value(idx); + result.set_bit(idx, bitbit); + } + + vvp_send_vec4(net_->out, result); +} + +vvp_fun_or::vvp_fun_or(unsigned wid) +: vvp_fun_boolean_(wid) +{ +} + +vvp_fun_or::~vvp_fun_or() +{ +} + +void vvp_fun_or::run_run() +{ + vvp_vector4_t result (input_[0]); + + for (unsigned idx = 0 ; idx < result.size() ; idx += 1) { + vvp_bit4_t bitbit = result.value(idx); + for (unsigned pdx = 1 ; pdx < 4 ; pdx += 1) { + if (input_[pdx].size() < idx) { + bitbit = BIT4_X; + break; + } + + bitbit = bitbit | input_[pdx].value(idx); + } + + result.set_bit(idx, bitbit); + } + + vvp_send_vec4(net_->out, result); +} + +vvp_fun_xor::vvp_fun_xor(unsigned wid) +: vvp_fun_boolean_(wid) +{ +} + +vvp_fun_xor::~vvp_fun_xor() +{ +} + +void vvp_fun_xor::run_run() +{ + vvp_vector4_t result (input_[0]); + + for (unsigned idx = 0 ; idx < result.size() ; idx += 1) { + vvp_bit4_t bitbit = result.value(idx); + for (unsigned pdx = 1 ; pdx < 4 ; pdx += 1) { + if (input_[pdx].size() < idx) { + bitbit = BIT4_X; + break; + } + + bitbit = bitbit ^ input_[pdx].value(idx); + } + + result.set_bit(idx, bitbit); + } + + vvp_send_vec4(net_->out, result); +} + /* * The parser calls this function to create a logic functor. I allocate a * functor, and map the name to the vvp_ipoint_t address for the @@ -347,7 +454,7 @@ void compile_functor(char*label, char*type, unsigned width, bool strength_aware = false; if (strcmp(type, "OR") == 0) { - obj = new table_functor_s(ft_OR); + obj = new vvp_fun_or(width); } else if (strcmp(type, "AND") == 0) { obj = new vvp_fun_and(width); @@ -405,13 +512,13 @@ void compile_functor(char*label, char*type, unsigned width, obj = new table_functor_s(ft_NOR); } else if (strcmp(type, "NOT") == 0) { - obj = new table_functor_s(ft_NOT); + obj = new vvp_fun_not(); } else if (strcmp(type, "XNOR") == 0) { obj = new table_functor_s(ft_XNOR); } else if (strcmp(type, "XOR") == 0) { - obj = new table_functor_s(ft_XOR); + obj = new vvp_fun_xor(width); } else { yyerror("invalid functor type."); @@ -463,6 +570,9 @@ void compile_functor(char*label, char*type, unsigned width, /* * $Log: logic.cc,v $ + * Revision 1.34 2005/09/19 21:45:09 steve + * Use lazy eval of BUF/NOT/OR/XOR gates. + * * Revision 1.33 2005/09/01 04:08:47 steve * Support MUXR functors. * diff --git a/vvp/logic.h b/vvp/logic.h index 510a8e492..cd2b6b0cf 100644 --- a/vvp/logic.h +++ b/vvp/logic.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: logic.h,v 1.23 2005/09/01 04:08:47 steve Exp $" +#ident "$Id: logic.h,v 1.24 2005/09/19 21:45:09 steve Exp $" #endif # include "vvp_net.h" @@ -77,7 +77,7 @@ class vvp_fun_and : public vvp_fun_boolean_ { * The retransmitted vector has all Z values changed to X, just like * the buf(Q,D) gate in Verilog. */ -class vvp_fun_buf: public vvp_net_fun_t { +class vvp_fun_buf: public vvp_net_fun_t, private vvp_gen_event_s { public: explicit vvp_fun_buf(); @@ -86,6 +86,11 @@ class vvp_fun_buf: public vvp_net_fun_t { void recv_vec4(vvp_net_ptr_t p, const vvp_vector4_t&bit); private: + void run_run(); + + private: + vvp_vector4_t input_; + vvp_net_t*net_; }; /* @@ -144,21 +149,57 @@ class vvp_fun_muxr : public vvp_net_fun_t { int select_; }; +class vvp_fun_not: public vvp_net_fun_t, private vvp_gen_event_s { + + public: + explicit vvp_fun_not(); + virtual ~vvp_fun_not(); + + void recv_vec4(vvp_net_ptr_t p, const vvp_vector4_t&bit); + + private: + void run_run(); + + private: + vvp_vector4_t input_; + vvp_net_t*net_; +}; + +class vvp_fun_or : public vvp_fun_boolean_ { + + public: + explicit vvp_fun_or(unsigned wid); + ~vvp_fun_or(); + + private: + void run_run(); +}; + +class vvp_fun_xor : public vvp_fun_boolean_ { + + public: + explicit vvp_fun_xor(unsigned wid); + ~vvp_fun_xor(); + + private: + void run_run(); +}; + // table functor types extern const unsigned char ft_MUXX[]; extern const unsigned char ft_EEQ[]; extern const unsigned char ft_NAND[]; extern const unsigned char ft_NOR[]; -extern const unsigned char ft_NOT[]; -extern const unsigned char ft_OR[]; extern const unsigned char ft_TRIAND[]; extern const unsigned char ft_TRIOR[]; extern const unsigned char ft_XNOR[]; -extern const unsigned char ft_XOR[]; /* * $Log: logic.h,v $ + * Revision 1.24 2005/09/19 21:45:09 steve + * Use lazy eval of BUF/NOT/OR/XOR gates. + * * Revision 1.23 2005/09/01 04:08:47 steve * Support MUXR functors. *