Add code generator hooks for latches

Add code generator hooks missing from the previous
patches that add latch synthesis support.
This commit is contained in:
Alan Feldstein 2007-06-27 14:39:06 -07:00 committed by Stephen Williams
parent f600e774d5
commit 3d0a2aba2c
9 changed files with 59 additions and 2 deletions

View File

@ -3,6 +3,7 @@
// Class NetLatch member-function definitions
#include "NetLatch.h" // NetLatch class definition
#include "target.h" // target_t structure definition
// constructor
NetLatch::NetLatch( NetScope *scope, perm_string name, unsigned width )
@ -11,6 +12,11 @@ NetLatch::NetLatch( NetScope *scope, perm_string name, unsigned width )
{
} // end NetLatch constructor
unsigned NetLatch::width() const
{
return ( pin_count() - 1U ) / 2U;
} // end function width
Link &NetLatch::pin_Data( unsigned w )
{
unsigned pn = 1 + 2 * w;
@ -29,3 +35,9 @@ Link &NetLatch::pin_Gate()
{
return pin( 0 );
} // end function pin_Q
bool NetLatch::emit_node( target_t *driverPtr ) const
{
driverPtr->lpm_latch( this );
return true;
} // end function emit_node

View File

@ -18,6 +18,8 @@ class NetLatch : public NetNode
public:
NetLatch( NetScope *, perm_string, unsigned );
unsigned width() const;
Link &pin_Data( unsigned );
Link &pin_Q( unsigned );
Link &pin_Gate();
@ -25,6 +27,8 @@ class NetLatch : public NetNode
const Link &pin_Data( unsigned ) const;
const Link &pin_Q( unsigned ) const;
const Link &pin_Gate() const;
virtual bool emit_node( target_t * ) const;
}; // end class NetLatch
#endif

View File

@ -230,6 +230,7 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_DEMUX = 16,
IVL_LPM_DIVIDE = 12,
IVL_LPM_FF = 3,
IVL_LPM_LATCH = 17,
IVL_LPM_MOD = 13,
IVL_LPM_MULT = 4,
IVL_LPM_MUX = 5,

View File

@ -231,7 +231,6 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope, bool sync_flag,
}
des->add_node( latchPtr );
delete latchPtr;
}
catch ( bad_alloc &memoryAllocationException )
@ -1083,7 +1082,7 @@ bool NetCase::synth_async_1hot_(Design*des, NetScope*scope, bool sync_flag,
/*
* Handle synthesis for an asynchronous condition statement. If we get
* here, we know that the CE of a DFF has already been filled, so the
* condition expression goes to the select of an asynchronous mux.
* condition expression goes to the select of an asynchronous mux, unless a latch is inferred in which case it goes to the latch's gate input.
*/
bool NetCondit::synth_async(Design*des, NetScope*scope, bool sync_flag,
struct sync_accounting_cell*nex_ff,

View File

@ -1084,6 +1084,8 @@ extern "C" unsigned ivl_lpm_width(ivl_lpm_t net)
case IVL_LPM_FF:
case IVL_LPM_RAM:
return net->u_.ff.width;
case IVL_LPM_LATCH:
return net->u_.latch.width;
case IVL_LPM_DECODE:
case IVL_LPM_MUX:
return net->u_.mux.width;

View File

@ -33,6 +33,9 @@
#endif
# include <stdlib.h>
#include <new> // standard operator new
using std::bad_alloc;
#if defined(__WIN32__)
inline ivl_dll_t ivl_dlopen(const char *name)
@ -1734,6 +1737,30 @@ void dll_target::lpm_ff(const NetFF*net)
}
}
void dll_target::lpm_latch( const NetLatch *latchPtr )
{
try
{
ivl_lpm_s *objPtr = new ivl_lpm_s;
objPtr->type = IVL_LPM_LATCH;
objPtr->name = latchPtr->name();
objPtr->scope = find_scope( des_, latchPtr->scope() );
assert( objPtr->scope ); // C++ programmers prefer using exceptions rather than assertions.
objPtr->u_.latch.width = latchPtr->width();
objPtr->nattr = latchPtr->attr_cnt();
objPtr->attr = fill_in_attributes( latchPtr );
scope_add_lpm( objPtr->scope, objPtr );
}
catch ( bad_alloc &memoryAllocationException )
{
cerr << "Exception occurred: " << memoryAllocationException.what() << endl;
}
} // end function lpm_latch
void dll_target::lpm_ram_dq(const NetRamDq*net)
{
ivl_memory_t mem = find_memory(des_, net->mem());

View File

@ -80,6 +80,7 @@ struct dll_target : public target_t, public expr_scan_t {
bool lpm_demux(const NetDemux*);
void lpm_divide(const NetDivide*);
void lpm_ff(const NetFF*);
void lpm_latch( const NetLatch * );
void lpm_modulo(const NetModulo*);
void lpm_mult(const NetMult*);
void lpm_mux(const NetMux*);
@ -328,6 +329,10 @@ struct ivl_lpm_s {
ivl_expr_t sset_value;
} ff;
struct ivl_lpm_latch_s {
unsigned width;
} latch;
struct ivl_lpm_mux_s {
unsigned width;
unsigned size;

View File

@ -133,6 +133,11 @@ void target_t::lpm_ff(const NetFF*)
"Unhandled NetFF." << endl;
}
void target_t::lpm_latch( const NetLatch * )
{
cerr << "target (" << typeid( *this ).name() << "): Unhandled NetLatch." << endl;
}
void target_t::lpm_mult(const NetMult*)
{
cerr << "target (" << typeid(*this).name() << "): "

View File

@ -23,6 +23,7 @@
#endif
# include "netlist.h"
#include "NetLatch.h"
/*
* This header file describes the types and constants used to describe
@ -84,6 +85,7 @@ struct target_t {
virtual void lpm_divide(const NetDivide*);
virtual void lpm_modulo(const NetModulo*);
virtual void lpm_ff(const NetFF*);
virtual void lpm_latch( const NetLatch * );
virtual void lpm_mult(const NetMult*);
virtual void lpm_mux(const NetMux*);
virtual void lpm_ram_dq(const NetRamDq*);