diff --git a/examples/clbff.v b/examples/clbff.v index 44b37bd2b..481ca6503 100644 --- a/examples/clbff.v +++ b/examples/clbff.v @@ -74,7 +74,7 @@ module main; // This is mapped to a DFF. Since Q and D are two bits wide, the // code generator actually makes two DFF devices that share a // clock input. - always @(posedge clk) Q = D; + always @(posedge clk) Q <= D; // These attribute commands assign pins to the listed wires. // This can be done to wires and registers, as internally both diff --git a/functor.cc b/functor.cc index b881f4849..2f805f61a 100644 --- a/functor.cc +++ b/functor.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: functor.cc,v 1.20 2000/07/16 04:56:07 steve Exp $" +#ident "$Id: functor.cc,v 1.21 2000/08/01 02:48:41 steve Exp $" #endif # include "functor.h" @@ -201,6 +201,16 @@ int NetAssign::match_proc(proc_match_t*that) return that->assign(this); } +int proc_match_t::assign_nb(NetAssignNB*) +{ + return 0; +} + +int NetAssignNB::match_proc(proc_match_t*that) +{ + return that->assign_nb(this); +} + int proc_match_t::assign_mem(NetAssignMem*) { return 0; @@ -211,6 +221,16 @@ int NetAssignMem::match_proc(proc_match_t*that) return that->assign_mem(this); } +int proc_match_t::assign_mem_nb(NetAssignMemNB*) +{ + return 0; +} + +int NetAssignMemNB::match_proc(proc_match_t*that) +{ + return that->assign_mem_nb(this); +} + int proc_match_t::block(NetBlock*) { cerr << "default (failing) match for block" << endl; @@ -245,6 +265,9 @@ int proc_match_t::event_wait(NetEvWait*) /* * $Log: functor.cc,v $ + * Revision 1.21 2000/08/01 02:48:41 steve + * Support <= in synthesis of DFF and ram devices. + * * Revision 1.20 2000/07/16 04:56:07 steve * Handle some edge cases during node scans. * diff --git a/functor.h b/functor.h index c08b5b3f9..cc89ab1e7 100644 --- a/functor.h +++ b/functor.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: functor.h,v 1.15 2000/07/16 04:56:07 steve Exp $" +#ident "$Id: functor.h,v 1.16 2000/08/01 02:48:42 steve Exp $" #endif /* @@ -81,6 +81,8 @@ struct proc_match_t { virtual int assign(class NetAssign*); virtual int assign_mem(class NetAssignMem*); + virtual int assign_nb(class NetAssignNB*); + virtual int assign_mem_nb(class NetAssignMemNB*); virtual int condit(class NetCondit*); virtual int event_wait(class NetEvWait*); virtual int block(class NetBlock*); @@ -89,6 +91,9 @@ struct proc_match_t { /* * $Log: functor.h,v $ + * Revision 1.16 2000/08/01 02:48:42 steve + * Support <= in synthesis of DFF and ram devices. + * * Revision 1.15 2000/07/16 04:56:07 steve * Handle some edge cases during node scans. * diff --git a/netlist.h b/netlist.h index 7f0b9cbbe..62235596d 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.151 2000/07/30 18:25:44 steve Exp $" +#ident "$Id: netlist.h,v 1.152 2000/08/01 02:48:42 steve Exp $" #endif /* @@ -1180,6 +1180,7 @@ class NetAssignNB : public NetAssign_ { virtual bool emit_proc(ostream&, struct target_t*) const; virtual void emit_node(ostream&, struct target_t*) const; + virtual int match_proc(struct proc_match_t*); virtual void dump(ostream&, unsigned ind) const; virtual void dump_node(ostream&, unsigned ind) const; @@ -1231,6 +1232,7 @@ class NetAssignMemNB : public NetAssignMem_ { explicit NetAssignMemNB(NetMemory*, NetExpr*idx, NetExpr*rv); ~NetAssignMemNB(); + virtual int match_proc(struct proc_match_t*); virtual bool emit_proc(ostream&, struct target_t*) const; virtual void dump(ostream&, unsigned ind) const; @@ -2726,6 +2728,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.152 2000/08/01 02:48:42 steve + * Support <= in synthesis of DFF and ram devices. + * * Revision 1.151 2000/07/30 18:25:44 steve * Rearrange task and function elaboration so that the * NetTaskDef and NetFuncDef functions are created during diff --git a/syn-rules.y b/syn-rules.y index 05f0e6dd0..8caafe8c1 100644 --- a/syn-rules.y +++ b/syn-rules.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: syn-rules.y,v 1.7 2000/07/26 03:52:59 steve Exp $" +#ident "$Id: syn-rules.y,v 1.8 2000/08/01 02:48:42 steve Exp $" #endif /* @@ -38,8 +38,8 @@ struct syn_token_t { int token; - NetAssign*assign; - NetAssignMem*assign_mem; + NetAssign_*assign; + NetAssignMem_*assign_mem; NetProcTop*top; NetEvWait*evwait; NetEvent*event; @@ -54,10 +54,10 @@ static void yyerror(const char*); static Design*des_; static void make_DFF_CE(Design*des, NetProcTop*top, NetEvWait*wclk, - NetEvent*eclk, NetExpr*cexp, NetAssign*asn); + NetEvent*eclk, NetExpr*cexp, NetAssign_*asn); static void make_RAM_CE(Design*des, NetProcTop*top, NetEvWait*wclk, - NetEvent*eclk, NetExpr*cexp, NetAssignMem*asn); -static void make_initializer(Design*des, NetProcTop*top, NetAssign*asn); + NetEvent*eclk, NetExpr*cexp, NetAssignMem_*asn); +static void make_initializer(Design*des, NetProcTop*top, NetAssign_*asn); %} @@ -131,7 +131,7 @@ start /* Various actions. */ static void make_DFF_CE(Design*des, NetProcTop*top, NetEvWait*wclk, - NetEvent*eclk, NetExpr*cexp, NetAssign*asn) + NetEvent*eclk, NetExpr*cexp, NetAssign_*asn) { NetEvProbe*pclk = eclk->probe(0); NetESignal*d = dynamic_cast (asn->rval()); @@ -158,7 +158,7 @@ static void make_DFF_CE(Design*des, NetProcTop*top, NetEvWait*wclk, } static void make_RAM_CE(Design*des, NetProcTop*top, NetEvWait*wclk, - NetEvent*eclk, NetExpr*cexp, NetAssignMem*asn) + NetEvent*eclk, NetExpr*cexp, NetAssignMem_*asn) { NetMemory*mem = asn->memory(); NetExpr*adr_e = asn->index(); @@ -198,7 +198,7 @@ static void make_RAM_CE(Design*des, NetProcTop*top, NetEvWait*wclk, * the initial value for the link and get rid of the assignment * process. */ -static void make_initializer(Design*des, NetProcTop*top, NetAssign*asn) +static void make_initializer(Design*des, NetProcTop*top, NetAssign_*asn) { NetESignal*rsig = dynamic_cast (asn->rval()); assert(rsig); @@ -245,6 +245,18 @@ struct tokenize : public proc_match_t { return 0; } + int assign_nb(NetAssignNB*dev) + { + syn_token_t*cur; + cur = new syn_token_t; + cur->token = dev->bmux() ? S_ASSIGN_MUX : S_ASSIGN; + cur->assign = dev; + cur->next_ = 0; + last_->next_ = cur; + last_ = cur; + return 0; + } + int assign_mem(NetAssignMem*dev) { syn_token_t*cur; @@ -257,6 +269,18 @@ struct tokenize : public proc_match_t { return 0; } + int assign_mem_nb(NetAssignMemNB*dev) + { + syn_token_t*cur; + cur = new syn_token_t; + cur->token = S_ASSIGN_MEM; + cur->assign_mem = dev; + cur->next_ = 0; + last_->next_ = cur; + last_ = cur; + return 0; + } + int condit(NetCondit*dev) { syn_token_t*cur; diff --git a/xnf.txt b/xnf.txt index 8dd7e5f16..dad4d1c09 100644 --- a/xnf.txt +++ b/xnf.txt @@ -101,7 +101,7 @@ Flip-flops, or more specifically DFF devices, are generated to implement behavioral code like this: reg Q; - always @(posedge clk) Q = ; + always @(posedge clk) Q <= ; The edge can be positive or negative, and the expression can be any synthesizeable expression. Furthermore, the register "Q" can have @@ -109,7 +109,7 @@ width, which will cause the appropriate number of flip-flops to be created. A clock enable expression can also be added like so: reg Q; - always @(posedge clk) if () Q = ; + always @(posedge clk) if () Q <= ; The expression can be any synthesizeable expression. @@ -122,13 +122,13 @@ right. The behavioral description that the -Fsynth functor matches to get a synchronous RAM looks very similar to that for a DFF: reg [15:0] M; - always @(posedge clk) if () M[] = ; + always @(posedge clk) if () M[] <= ; Note that in this case the l-value of the assignment is an addressed memory. This statement models writes into the memory. Reads from the device can be modeled with ordinary structural code, i.e.: - assign foo = M[]; + assign foo <= M[]; For the memory to be synthesizeable in the XNF target, the address lines for writes and reads must be connected. This corresponds to the @@ -245,6 +245,9 @@ IBUF, NOT gates cannot be absorbed as in the OPAD case. $Log: xnf.txt,v $ + Revision 1.13 2000/08/01 02:48:42 steve + Support <= in synthesis of DFF and ram devices. + Revision 1.12 2000/07/25 22:49:32 steve memory is not a data type in verilog.