Add CA version of the <-> operator
This commit is contained in:
parent
c003bcc59a
commit
dd80607ceb
|
|
@ -739,6 +739,12 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
|
|||
case CMOS:
|
||||
o << "cmos";
|
||||
break;
|
||||
case EQUIV:
|
||||
o << "<->";
|
||||
break;
|
||||
case IMPL:
|
||||
o << "->";
|
||||
break;
|
||||
case NAND:
|
||||
o << "nand";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -545,13 +545,33 @@ NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ((op() == 'q') || (op() == 'Q')) {
|
||||
NetLogic*olog;
|
||||
perm_string oname = scope->local_symbol();
|
||||
|
||||
/* Create the logic OR/AND gate. This has a single bit output,
|
||||
* with single bit inputs for the two operands. */
|
||||
switch (op()) {
|
||||
case 'a':
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::AND, 1, true);
|
||||
break;
|
||||
case 'o':
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::OR, 1, true);
|
||||
break;
|
||||
case 'q':
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::IMPL, 1, true);
|
||||
break;
|
||||
case 'Q':
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::EQUIV, 1, true);
|
||||
break;
|
||||
default:
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< human_readable_op(op_)
|
||||
<< " is not currently supported in this context." << endl;
|
||||
<< " is not currently supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
olog->set_line(*this);
|
||||
des->add_node(olog);
|
||||
|
||||
netvector_t*osig_tmp = new netvector_t(expr_type());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
|
|
@ -559,21 +579,6 @@ NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
|
||||
NetLogic*olog;
|
||||
perm_string oname = scope->local_symbol();
|
||||
|
||||
/* Create the logic OR/AND gate. This has a single bit output,
|
||||
* with single bit inputs for the two operands. */
|
||||
if (op() == 'o') {
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::OR, 1, true);
|
||||
} else {
|
||||
assert(op() == 'a');
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::AND, 1, true);
|
||||
}
|
||||
|
||||
olog->set_line(*this);
|
||||
des->add_node(olog);
|
||||
|
||||
connect(osig->pin(0), olog->pin(0));
|
||||
|
||||
/* The left and right operands have already been reduced to a
|
||||
|
|
|
|||
|
|
@ -265,6 +265,8 @@ typedef enum ivl_logic_e {
|
|||
IVL_LO_BUFT = 24, /* transparent bufz. (NOT "tri-state") */
|
||||
IVL_LO_BUFZ = 5,
|
||||
IVL_LO_CMOS = 22,
|
||||
IVL_LO_EQUIV = 25,
|
||||
IVL_LO_IMPL = 26,
|
||||
IVL_LO_NAND = 6,
|
||||
IVL_LO_NMOS = 7,
|
||||
IVL_LO_NOR = 8,
|
||||
|
|
@ -280,7 +282,6 @@ typedef enum ivl_logic_e {
|
|||
IVL_LO_RPMOS = 16,
|
||||
IVL_LO_XNOR = 18,
|
||||
IVL_LO_XOR = 19,
|
||||
|
||||
IVL_LO_UDP = 21
|
||||
} ivl_logic_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -2492,9 +2492,9 @@ class NetLiteral : public NetNode {
|
|||
class NetLogic : public NetNode {
|
||||
|
||||
public:
|
||||
enum TYPE { AND, BUF, BUFIF0, BUFIF1, CMOS, NAND, NMOS, NOR, NOT,
|
||||
NOTIF0, NOTIF1, OR, PULLDOWN, PULLUP, RCMOS, RNMOS, RPMOS,
|
||||
PMOS, XNOR, XOR };
|
||||
enum TYPE { AND, BUF, BUFIF0, BUFIF1, CMOS, EQUIV, IMPL, NAND, NMOS,
|
||||
NOR, NOT, NOTIF0, NOTIF1, OR, PULLDOWN, PULLUP, RCMOS,
|
||||
RNMOS, RPMOS, PMOS, XNOR, XOR };
|
||||
|
||||
explicit NetLogic(NetScope*s, perm_string n, unsigned pins,
|
||||
TYPE t, unsigned wid, bool is_cassign__=false);
|
||||
|
|
|
|||
6
t-dll.cc
6
t-dll.cc
|
|
@ -971,6 +971,12 @@ void dll_target::logic(const NetLogic*net)
|
|||
case NetLogic::CMOS:
|
||||
obj->type_ = IVL_LO_CMOS;
|
||||
break;
|
||||
case NetLogic::EQUIV:
|
||||
obj->type_ = IVL_LO_EQUIV;
|
||||
break;
|
||||
case NetLogic::IMPL:
|
||||
obj->type_ = IVL_LO_IMPL;
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
obj->type_ = IVL_LO_NAND;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -501,9 +501,9 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid,
|
|||
emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 1, 0);
|
||||
break;
|
||||
case 'q': // The arguments have already been reduced
|
||||
fprintf(vlog_out, "!");
|
||||
fprintf(vlog_out, "~");
|
||||
emit_expr(scope, oper1, ivl_expr_width(oper1), 0, 1, 0);
|
||||
fprintf(vlog_out, " || ");
|
||||
fprintf(vlog_out, " | ");
|
||||
emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 1, 0);
|
||||
break;
|
||||
case 'Q': // The arguments have already been reduced
|
||||
|
|
|
|||
|
|
@ -694,6 +694,22 @@ static void emit_logic_as_ca(ivl_scope_t scope, ivl_net_logic_t nlogic)
|
|||
assert(inputs == 1);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
break;
|
||||
case IVL_LO_EQUIV:
|
||||
assert(inputs == 2);
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
fprintf(vlog_out, " ~^ ");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LO_IMPL:
|
||||
assert(inputs == 2);
|
||||
fprintf(vlog_out, "(~");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
fprintf(vlog_out, " | ");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LO_NAND:
|
||||
assert(inputs == 2);
|
||||
fprintf(vlog_out, "~(");
|
||||
|
|
|
|||
|
|
@ -421,22 +421,15 @@ static void draw_binary_vec4_lequiv(ivl_expr_t expr)
|
|||
ivl_expr_t le = ivl_expr_oper1(expr);
|
||||
ivl_expr_t re = ivl_expr_oper2(expr);
|
||||
|
||||
/* Push the left expression. Reduce it to a single bit if
|
||||
necessary. */
|
||||
/* The arguments should have already been reduced. */
|
||||
assert(ivl_expr_width(le) == 1);
|
||||
draw_eval_vec4(le);
|
||||
if (ivl_expr_width(le) > 1)
|
||||
fprintf(vvp_out, " %%or/r;\n");
|
||||
|
||||
/* Now push the right expression. Again, reduce to a single
|
||||
bit if necessary. */
|
||||
assert(ivl_expr_width(re) == 1);
|
||||
draw_eval_vec4(re);
|
||||
if (ivl_expr_width(re) > 1)
|
||||
fprintf(vvp_out, " %%or/r;\n");
|
||||
|
||||
fprintf(vvp_out, " %%xnor;\n");
|
||||
|
||||
if (ivl_expr_width(expr) > 1)
|
||||
fprintf(vvp_out, " %%pad/u %u;\n", ivl_expr_width(expr));
|
||||
assert(ivl_expr_width(expr) == 1);
|
||||
}
|
||||
|
||||
static void draw_binary_vec4_land(ivl_expr_t expr)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2020 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -907,6 +907,32 @@ static void draw_udp_in_scope(ivl_net_logic_t lptr)
|
|||
if (need_delay_flag) draw_logic_delay(lptr);
|
||||
}
|
||||
|
||||
static void draw_equiv_impl_in_scope(ivl_net_logic_t lptr)
|
||||
{
|
||||
unsigned ninp;
|
||||
const char *lval;
|
||||
const char *rval;
|
||||
const char*ltype = "?";
|
||||
|
||||
assert(width_of_nexus(ivl_logic_pin(lptr, 0)) == 1);
|
||||
|
||||
assert(ivl_logic_pins(lptr) > 0);
|
||||
ninp = ivl_logic_pins(lptr) - 1;
|
||||
assert(ninp == 2);
|
||||
|
||||
lval = draw_net_input(ivl_logic_pin(lptr, 1));
|
||||
rval = draw_net_input(ivl_logic_pin(lptr, 2));
|
||||
|
||||
if (ivl_logic_type(lptr) == IVL_LO_EQUIV) {
|
||||
ltype = "EQUIV";
|
||||
} else {
|
||||
assert(ivl_logic_type(lptr) == IVL_LO_IMPL);
|
||||
ltype = "IMPL";
|
||||
}
|
||||
|
||||
fprintf(vvp_out, "L_%p .functor %s 1, %s, %s, C4<0>, C4<0>;\n", lptr, ltype, lval, rval);
|
||||
}
|
||||
|
||||
static void draw_logic_in_scope(ivl_net_logic_t lptr)
|
||||
{
|
||||
unsigned pdx;
|
||||
|
|
@ -984,6 +1010,11 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
|
|||
ltype = "BUFIF1";
|
||||
break;
|
||||
|
||||
case IVL_LO_EQUIV:
|
||||
case IVL_LO_IMPL:
|
||||
draw_equiv_impl_in_scope(lptr);
|
||||
return;
|
||||
|
||||
case IVL_LO_NAND:
|
||||
ltype = "NAND";
|
||||
lcasc = "AND";
|
||||
|
|
|
|||
56
vvp/logic.cc
56
vvp/logic.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2020 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -110,6 +110,54 @@ void vvp_fun_and::run_run()
|
|||
ptr->send_vec4(result, 0);
|
||||
}
|
||||
|
||||
vvp_fun_equiv::vvp_fun_equiv()
|
||||
: vvp_fun_boolean_(1)
|
||||
{
|
||||
count_functors_logic += 1;
|
||||
}
|
||||
|
||||
vvp_fun_equiv::~vvp_fun_equiv()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_fun_equiv::run_run()
|
||||
{
|
||||
vvp_net_t*ptr = net_;
|
||||
net_ = 0;
|
||||
|
||||
assert(input_[0].size() == 1);
|
||||
assert(input_[1].size() == 1);
|
||||
|
||||
vvp_bit4_t bit = ~(input_[0].value(0) ^ input_[1].value(0));
|
||||
vvp_vector4_t result (1, bit);
|
||||
|
||||
ptr->send_vec4(result, 0);
|
||||
}
|
||||
|
||||
vvp_fun_impl::vvp_fun_impl()
|
||||
: vvp_fun_boolean_(1)
|
||||
{
|
||||
count_functors_logic += 1;
|
||||
}
|
||||
|
||||
vvp_fun_impl::~vvp_fun_impl()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_fun_impl::run_run()
|
||||
{
|
||||
vvp_net_t*ptr = net_;
|
||||
net_ = 0;
|
||||
|
||||
assert(input_[0].size() == 1);
|
||||
assert(input_[1].size() == 1);
|
||||
|
||||
vvp_bit4_t bit = ~input_[0].value(0) | input_[1].value(0);
|
||||
vvp_vector4_t result (1, bit);
|
||||
|
||||
ptr->send_vec4(result, 0);
|
||||
}
|
||||
|
||||
vvp_fun_buf::vvp_fun_buf(unsigned wid)
|
||||
: input_(wid, BIT4_Z)
|
||||
{
|
||||
|
|
@ -600,6 +648,12 @@ void compile_functor(char*label, char*type, unsigned width,
|
|||
obj = new vvp_fun_bufif(false,false, ostr0, ostr1);
|
||||
strength_aware = true;
|
||||
|
||||
} else if (strcmp(type, "EQUIV") == 0) {
|
||||
obj = new vvp_fun_equiv();
|
||||
|
||||
} else if (strcmp(type, "IMPL") == 0) {
|
||||
obj = new vvp_fun_impl();
|
||||
|
||||
} else if (strcmp(type, "NAND") == 0) {
|
||||
obj = new vvp_fun_and(width, true);
|
||||
|
||||
|
|
|
|||
22
vvp/logic.h
22
vvp/logic.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_logic_H
|
||||
#define IVL_logic_H
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -54,6 +54,26 @@ class vvp_fun_and : public vvp_fun_boolean_ {
|
|||
bool invert_;
|
||||
};
|
||||
|
||||
class vvp_fun_equiv : public vvp_fun_boolean_ {
|
||||
|
||||
public:
|
||||
explicit vvp_fun_equiv();
|
||||
~vvp_fun_equiv();
|
||||
|
||||
private:
|
||||
void run_run();
|
||||
};
|
||||
|
||||
class vvp_fun_impl : public vvp_fun_boolean_ {
|
||||
|
||||
public:
|
||||
explicit vvp_fun_impl();
|
||||
~vvp_fun_impl();
|
||||
|
||||
private:
|
||||
void run_run();
|
||||
};
|
||||
|
||||
/*
|
||||
* The buffer functor is a very primitive functor that takes the input
|
||||
* from port-0 (and only port-0) and retransmits it as a vvp_vector4_t.
|
||||
|
|
|
|||
Loading…
Reference in New Issue