Add LATCH to target interface

This commit is contained in:
Johann Klammer 2016-03-10 22:13:27 +01:00 committed by Martin Whitaker
parent 0e537c5465
commit 35a61b4680
4 changed files with 69 additions and 4 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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
View File

@ -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;