Add LATCH to target interface
This commit is contained in:
parent
0e537c5465
commit
35a61b4680
14
ivl_target.h
14
ivl_target.h
|
|
@ -336,7 +336,8 @@ typedef enum ivl_lpm_type_e {
|
|||
IVL_LPM_SUB = 8,
|
||||
IVL_LPM_SUBSTITUTE=39,
|
||||
/* IVL_LPM_RAM = 9, / obsolete */
|
||||
IVL_LPM_UFUNC = 14
|
||||
IVL_LPM_UFUNC = 14,
|
||||
IVL_LPM_LATCH = 40
|
||||
} ivl_lpm_type_t;
|
||||
|
||||
/* The path edge type is the edge type used to select a specific
|
||||
|
|
@ -1313,6 +1314,11 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
|
|||
* single ivl_lpm_data input are the same with, ivl_lpm_width. This
|
||||
* device carries a vector like other LPM devices.
|
||||
*
|
||||
* - Latch (IVL_LPM_LATCH)
|
||||
* This data is an asynchronous latch. The ivl_lpm_q output and
|
||||
* single ivl_lpm_data input are the same with, ivl_lpm_width. This
|
||||
* device carries a vector like other LPM devices.
|
||||
*
|
||||
* - Memory port (IVL_LPM_RAM) (deprecated in favor of IVL_LPM_ARRAY)
|
||||
* These are structural ports into a memory device. They represent
|
||||
* address/data ports of a memory device that the context can hook to
|
||||
|
|
@ -1428,18 +1434,18 @@ extern unsigned ivl_lpm_negedge(ivl_lpm_t net);
|
|||
extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net);
|
||||
/* IVL_LPM_UFUNC */
|
||||
extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net);
|
||||
/* IVL_LPM_FF */
|
||||
/* IVL_LPM_FF IVL_LPM_LATCH*/
|
||||
extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net);
|
||||
/* IVL_LPM_ADD IVL_LPM_CONCAT IVL_LPM_FF IVL_LPM_PART IVL_LPM_MULT
|
||||
IVL_LPM_MUX IVL_LPM_POW IVL_LPM_SHIFTL IVL_LPM_SHIFTR IVL_LPM_SUB
|
||||
IVL_LPM_UFUNC IVL_LPM_SUBSTITUTE */
|
||||
IVL_LPM_UFUNC IVL_LPM_SUBSTITUTE IVL_LPM_LATCH*/
|
||||
extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_POW IVL_LPM_SUB IVL_LPM_CMP_EQ
|
||||
IVL_LPM_CMP_EEQ IVL_LPM_CMP_EQX IVL_LPM_CMP_EQZ IVL_LPM_CMP_NEE */
|
||||
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_PART IVL_LPM_POW
|
||||
IVL_LPM_SUB IVL_LPM_UFUNC IVL_LPM_CMP_EEQ IVL_LPM_CMP_EQX
|
||||
IVL_LPM_CMP_EQZ IVL_LPM_CMP_NEE IVL_LPM_SUBSTITUTE */
|
||||
IVL_LPM_CMP_EQZ IVL_LPM_CMP_NEE IVL_LPM_SUBSTITUTE IVL_LPM_LATCH*/
|
||||
extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net);
|
||||
extern ivl_drive_t ivl_lpm_drive0(ivl_lpm_t net);
|
||||
extern ivl_drive_t ivl_lpm_drive1(ivl_lpm_t net);
|
||||
|
|
|
|||
|
|
@ -1148,6 +1148,8 @@ extern "C" ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net)
|
|||
switch (net->type) {
|
||||
case IVL_LPM_FF:
|
||||
return net->u_.ff.we;
|
||||
case IVL_LPM_LATCH:
|
||||
return net->u_.latch.we;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
|
|
@ -1220,6 +1222,9 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
|
|||
case IVL_LPM_FF:
|
||||
assert(idx == 0);
|
||||
return net->u_.ff.d.pin;
|
||||
case IVL_LPM_LATCH:
|
||||
assert(idx == 0);
|
||||
return net->u_.latch.d.pin;
|
||||
|
||||
case IVL_LPM_CONCAT:
|
||||
case IVL_LPM_CONCATZ:
|
||||
|
|
@ -1344,6 +1349,8 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net)
|
|||
|
||||
case IVL_LPM_FF:
|
||||
return net->u_.ff.q.pin;
|
||||
case IVL_LPM_LATCH:
|
||||
return net->u_.latch.q.pin;
|
||||
|
||||
case IVL_LPM_MUX:
|
||||
return net->u_.mux.q;
|
||||
|
|
|
|||
39
t-dll.cc
39
t-dll.cc
|
|
@ -2051,6 +2051,45 @@ void dll_target::lpm_ff(const NetFF*net)
|
|||
nexus_lpm_add(obj->u_.ff.d.pin, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
}
|
||||
|
||||
void dll_target::lpm_latch(const NetLatch*net)
|
||||
{
|
||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||
obj->type = IVL_LPM_LATCH;
|
||||
obj->name = net->name();
|
||||
obj->scope = find_scope(des_, net->scope());
|
||||
assert(obj->scope);
|
||||
FILE_NAME(obj, net);
|
||||
|
||||
obj->width = net->width();
|
||||
|
||||
scope_add_lpm(obj->scope, obj);
|
||||
|
||||
const Nexus*nex;
|
||||
|
||||
/* If there is a clock enable, then connect it up to the FF
|
||||
device. */
|
||||
if (net->pin_Enable().is_linked()) {
|
||||
nex = net->pin_Enable().nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->u_.latch.we = nex->t_cookie();
|
||||
assert(obj->u_.latch.we);
|
||||
nexus_lpm_add(obj->u_.latch.we, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
} else {
|
||||
obj->u_.latch.we = 0;
|
||||
}
|
||||
|
||||
nex = net->pin_Q().nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->u_.latch.q.pin = nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.latch.q.pin, obj, 0,
|
||||
IVL_DR_STRONG, IVL_DR_STRONG);
|
||||
|
||||
nex = net->pin_Data().nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->u_.latch.d.pin = nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.latch.d.pin, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make the NetMult object into an IVL_LPM_MULT node.
|
||||
*/
|
||||
|
|
|
|||
13
t-dll.h
13
t-dll.h
|
|
@ -76,6 +76,7 @@ struct dll_target : public target_t, public expr_scan_t {
|
|||
void lpm_compare(const NetCompare*);
|
||||
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*);
|
||||
|
|
@ -388,6 +389,18 @@ struct ivl_lpm_s {
|
|||
ivl_expr_t aset_value;
|
||||
ivl_expr_t sset_value;
|
||||
} ff;
|
||||
struct ivl_lpm_latch_s {
|
||||
unsigned negedge_flag :1;
|
||||
ivl_nexus_t we;
|
||||
union {
|
||||
ivl_nexus_t*pins;
|
||||
ivl_nexus_t pin;
|
||||
} q;
|
||||
union {
|
||||
ivl_nexus_t*pins;
|
||||
ivl_nexus_t pin;
|
||||
} d;
|
||||
} latch;
|
||||
|
||||
struct ivl_lpm_mux_s {
|
||||
unsigned size;
|
||||
|
|
|
|||
Loading…
Reference in New Issue