Merge branch 'master' into verilog-ams
This commit is contained in:
commit
988fc70368
|
|
@ -484,6 +484,7 @@ NetNet* NetEBDiv::synthesize(Design*des, NetScope*scope)
|
||||||
lsig->vector_width(),
|
lsig->vector_width(),
|
||||||
rsig->vector_width());
|
rsig->vector_width());
|
||||||
div->set_line(*this);
|
div->set_line(*this);
|
||||||
|
div->set_signed(has_sign());
|
||||||
des->add_node(div);
|
des->add_node(div);
|
||||||
|
|
||||||
connect(div->pin_DataA(), lsig->pin(0));
|
connect(div->pin_DataA(), lsig->pin(0));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2005 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -16,9 +16,6 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
|
||||||
#ident "$Id: net_modulo.cc,v 1.9 2005/09/15 22:54:47 steve Exp $"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
||||||
|
|
@ -69,6 +66,16 @@ Link& NetModulo::pin_Result()
|
||||||
return pin(0);
|
return pin(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetModulo::set_signed(bool flag)
|
||||||
|
{
|
||||||
|
signed_flag_ = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetModulo::get_signed() const
|
||||||
|
{
|
||||||
|
return signed_flag_;
|
||||||
|
}
|
||||||
|
|
||||||
const Link& NetModulo::pin_Result() const
|
const Link& NetModulo::pin_Result() const
|
||||||
{
|
{
|
||||||
return pin(0);
|
return pin(0);
|
||||||
|
|
@ -93,25 +100,3 @@ const Link& NetModulo::pin_DataB() const
|
||||||
{
|
{
|
||||||
return pin(2);
|
return pin(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: net_modulo.cc,v $
|
|
||||||
* Revision 1.9 2005/09/15 22:54:47 steve
|
|
||||||
* Fix bug configuring NetModulo pins.
|
|
||||||
*
|
|
||||||
* Revision 1.8 2005/03/12 06:43:35 steve
|
|
||||||
* Update support for LPM_MOD.
|
|
||||||
*
|
|
||||||
* Revision 1.7 2004/02/18 17:11:56 steve
|
|
||||||
* Use perm_strings for named langiage items.
|
|
||||||
*
|
|
||||||
* Revision 1.6 2003/03/06 00:28:41 steve
|
|
||||||
* All NetObj objects have lex_string base names.
|
|
||||||
*
|
|
||||||
* Revision 1.5 2002/08/12 01:34:59 steve
|
|
||||||
* conditional ident string using autoconfig.
|
|
||||||
*
|
|
||||||
* Revision 1.4 2002/08/11 23:47:04 steve
|
|
||||||
* Add missing Log and Ident strings.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -1176,6 +1176,9 @@ class NetModulo : public NetNode {
|
||||||
unsigned width_a() const;
|
unsigned width_a() const;
|
||||||
unsigned width_b() const;
|
unsigned width_b() const;
|
||||||
|
|
||||||
|
void set_signed(bool);
|
||||||
|
bool get_signed() const;
|
||||||
|
|
||||||
Link& pin_DataA();
|
Link& pin_DataA();
|
||||||
Link& pin_DataB();
|
Link& pin_DataB();
|
||||||
Link& pin_Result();
|
Link& pin_Result();
|
||||||
|
|
@ -1192,6 +1195,8 @@ class NetModulo : public NetNode {
|
||||||
unsigned width_r_;
|
unsigned width_r_;
|
||||||
unsigned width_a_;
|
unsigned width_a_;
|
||||||
unsigned width_b_;
|
unsigned width_b_;
|
||||||
|
|
||||||
|
bool signed_flag_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
2
t-dll.cc
2
t-dll.cc
|
|
@ -1782,7 +1782,7 @@ void dll_target::lpm_modulo(const NetModulo*net)
|
||||||
unsigned wid = net->width_r();
|
unsigned wid = net->width_r();
|
||||||
|
|
||||||
obj->width = wid;
|
obj->width = wid;
|
||||||
obj->u_.arith.signed_flag = 0;
|
obj->u_.arith.signed_flag = net->get_signed()? 1 : 0;
|
||||||
|
|
||||||
const Nexus*nex;
|
const Nexus*nex;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1170,6 +1170,8 @@ static void draw_lpm_add(ivl_lpm_t net)
|
||||||
case IVL_LPM_MOD:
|
case IVL_LPM_MOD:
|
||||||
if (dto == IVL_VT_REAL)
|
if (dto == IVL_VT_REAL)
|
||||||
type = "mod.r";
|
type = "mod.r";
|
||||||
|
else if (ivl_lpm_signed(net))
|
||||||
|
type = "mod.s";
|
||||||
else
|
else
|
||||||
type = "mod";
|
type = "mod";
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
65
vvp/arith.cc
65
vvp/arith.cc
|
|
@ -144,13 +144,25 @@ void vvp_arith_div::wide4_(vvp_net_ptr_t ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_vector2_t b2 (op_b_);
|
vvp_vector2_t b2 (op_b_);
|
||||||
if (b2.is_NaN()) {
|
if (b2.is_NaN() || b2.is_zero()) {
|
||||||
vvp_send_vec4(ptr.ptr()->out, x_val_, 0);
|
vvp_send_vec4(ptr.ptr()->out, x_val_, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_vector2_t res2 = a2 / b2;
|
bool negate = false;
|
||||||
vvp_send_vec4(ptr.ptr()->out, vector2_to_vector4(res2, wid_), 0);
|
if (signed_flag_) {
|
||||||
|
if (a2.value(a2.size()-1)) {
|
||||||
|
a2 = -a2;
|
||||||
|
negate = true;
|
||||||
|
}
|
||||||
|
if (b2.value(b2.size()-1)) {
|
||||||
|
b2 = -b2;
|
||||||
|
negate = !negate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vvp_vector2_t res = a2 / b2;
|
||||||
|
if (negate) res = -res;
|
||||||
|
vvp_send_vec4(ptr.ptr()->out, vector2_to_vector4(res, wid_), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vvp_arith_div::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
void vvp_arith_div::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||||
|
|
@ -180,17 +192,34 @@ void vvp_arith_div::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||||
the operands for now, and remember to put the sign back
|
the operands for now, and remember to put the sign back
|
||||||
later. */
|
later. */
|
||||||
if (signed_flag_) {
|
if (signed_flag_) {
|
||||||
|
unsigned long sign_mask = 0;
|
||||||
|
if (op_a_.size() != 8 * sizeof(unsigned long)) {
|
||||||
|
sign_mask = -1UL << op_a_.size();
|
||||||
|
}
|
||||||
if (op_a_.value(op_a_.size()-1)) {
|
if (op_a_.value(op_a_.size()-1)) {
|
||||||
a = (-a) & ~ (-1UL << op_a_.size());
|
a = (-a) & ~sign_mask;
|
||||||
negate = !negate;
|
negate = !negate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sign_mask = 0;
|
||||||
|
if (op_b_.size() != 8 * sizeof(unsigned long)) {
|
||||||
|
sign_mask = -1UL << op_b_.size();
|
||||||
|
}
|
||||||
if (op_b_.value(op_b_.size()-1)) {
|
if (op_b_.value(op_b_.size()-1)) {
|
||||||
b = (-b) & ~ (-1UL << op_b_.size());
|
b = (-b) & ~sign_mask;
|
||||||
negate = ! negate;
|
negate = ! negate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (b == 0) {
|
||||||
|
vvp_vector4_t xval (wid_);
|
||||||
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1)
|
||||||
|
xval.set_bit(idx, BIT4_X);
|
||||||
|
|
||||||
|
vvp_send_vec4(ptr.ptr()->out, xval, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long val = a / b;
|
unsigned long val = a / b;
|
||||||
if (negate)
|
if (negate)
|
||||||
val = -val;
|
val = -val;
|
||||||
|
|
@ -229,12 +258,23 @@ void vvp_arith_mod::wide_(vvp_net_ptr_t ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_vector2_t b2 (op_b_);
|
vvp_vector2_t b2 (op_b_);
|
||||||
if (b2.is_NaN()) {
|
if (b2.is_NaN() || b2.is_zero()) {
|
||||||
vvp_send_vec4(ptr.ptr()->out, x_val_, 0);
|
vvp_send_vec4(ptr.ptr()->out, x_val_, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool negate = false;
|
||||||
|
if (signed_flag_) {
|
||||||
|
if (a2.value(a2.size()-1)) {
|
||||||
|
a2 = -a2;
|
||||||
|
negate = true;
|
||||||
|
}
|
||||||
|
if (b2.value(b2.size()-1)) {
|
||||||
|
b2 = -b2;
|
||||||
|
}
|
||||||
|
}
|
||||||
vvp_vector2_t res = a2 % b2;
|
vvp_vector2_t res = a2 % b2;
|
||||||
|
if (negate) res = -res;
|
||||||
vvp_send_vec4(ptr.ptr()->out, vector2_to_vector4(res, res.size()), 0);
|
vvp_send_vec4(ptr.ptr()->out, vector2_to_vector4(res, res.size()), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,14 +305,21 @@ void vvp_arith_mod::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||||
the operands for now, and remember to put the sign back
|
the operands for now, and remember to put the sign back
|
||||||
later. */
|
later. */
|
||||||
if (signed_flag_) {
|
if (signed_flag_) {
|
||||||
|
unsigned long sign_mask = 0;
|
||||||
|
if (op_a_.size() != 8 * sizeof(unsigned long)) {
|
||||||
|
sign_mask = -1UL << op_a_.size();
|
||||||
|
}
|
||||||
if (op_a_.value(op_a_.size()-1)) {
|
if (op_a_.value(op_a_.size()-1)) {
|
||||||
a = (-a) & ~ (-1UL << op_a_.size());
|
a = (-a) & ~sign_mask;
|
||||||
negate = !negate;
|
negate = !negate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sign_mask = 0;
|
||||||
|
if (op_b_.size() != 8 * sizeof(unsigned long)) {
|
||||||
|
sign_mask = -1UL << op_b_.size();
|
||||||
|
}
|
||||||
if (op_b_.value(op_b_.size()-1)) {
|
if (op_b_.value(op_b_.size()-1)) {
|
||||||
b = (-b) & ~ (-1UL << op_b_.size());
|
b = (-b) & ~sign_mask;
|
||||||
negate = ! negate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -979,7 +979,7 @@ void compile_arith_div_r(char*label, unsigned argc, struct symb_s*argv)
|
||||||
make_arith(arith, label, argc, argv);
|
make_arith(arith, label, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compile_arith_mod(char*label, long wid,
|
void compile_arith_mod(char*label, long wid, bool signed_flag,
|
||||||
unsigned argc, struct symb_s*argv)
|
unsigned argc, struct symb_s*argv)
|
||||||
{
|
{
|
||||||
assert( wid > 0 );
|
assert( wid > 0 );
|
||||||
|
|
@ -990,7 +990,7 @@ void compile_arith_mod(char*label, long wid,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_arith_ *arith = new vvp_arith_mod(wid, false);
|
vvp_arith_ *arith = new vvp_arith_mod(wid, signed_flag);
|
||||||
|
|
||||||
make_arith(arith, label, argc, argv);
|
make_arith(arith, label, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ extern void compile_arith_cast_real(char*label, bool signed_flag,
|
||||||
unsigned argc, struct symb_s*argv);
|
unsigned argc, struct symb_s*argv);
|
||||||
extern void compile_arith_div(char*label, long width, bool signed_flag,
|
extern void compile_arith_div(char*label, long width, bool signed_flag,
|
||||||
unsigned argc, struct symb_s*argv);
|
unsigned argc, struct symb_s*argv);
|
||||||
extern void compile_arith_mod(char*label, long width,
|
extern void compile_arith_mod(char*label, long width, bool signed_flag,
|
||||||
unsigned argc, struct symb_s*argv);
|
unsigned argc, struct symb_s*argv);
|
||||||
extern void compile_arith_mult(char*label, long width,
|
extern void compile_arith_mult(char*label, long width,
|
||||||
unsigned argc, struct symb_s*argv);
|
unsigned argc, struct symb_s*argv);
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,7 @@
|
||||||
".arith/div.s" { return K_ARITH_DIV_S; }
|
".arith/div.s" { return K_ARITH_DIV_S; }
|
||||||
".arith/mod" { return K_ARITH_MOD; }
|
".arith/mod" { return K_ARITH_MOD; }
|
||||||
".arith/mod.r" { return K_ARITH_MOD_R; }
|
".arith/mod.r" { return K_ARITH_MOD_R; }
|
||||||
|
".arith/mod.s" { return K_ARITH_MOD_S; }
|
||||||
".arith/mult" { return K_ARITH_MULT; }
|
".arith/mult" { return K_ARITH_MULT; }
|
||||||
".arith/mult.r" { return K_ARITH_MULT_R; }
|
".arith/mult.r" { return K_ARITH_MULT_R; }
|
||||||
".arith/pow" { return K_ARITH_POW; }
|
".arith/pow" { return K_ARITH_POW; }
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ static struct __vpiModPath*modpath_dst = 0;
|
||||||
|
|
||||||
%token K_A K_ALIAS K_ALIAS_S K_ALIAS_R
|
%token K_A K_ALIAS K_ALIAS_S K_ALIAS_R
|
||||||
%token K_ARITH_ABS K_ARITH_DIV K_ARITH_DIV_R K_ARITH_DIV_S K_ARITH_MOD
|
%token K_ARITH_ABS K_ARITH_DIV K_ARITH_DIV_R K_ARITH_DIV_S K_ARITH_MOD
|
||||||
%token K_ARITH_MOD_R
|
%token K_ARITH_MOD_R K_ARITH_MOD_S
|
||||||
%token K_ARITH_MULT K_ARITH_MULT_R K_ARITH_SUB K_ARITH_SUB_R
|
%token K_ARITH_MULT K_ARITH_MULT_R K_ARITH_SUB K_ARITH_SUB_R
|
||||||
%token K_ARITH_SUM K_ARITH_SUM_R K_ARITH_POW K_ARITH_POW_R K_ARITH_POW_S
|
%token K_ARITH_SUM K_ARITH_SUM_R K_ARITH_POW K_ARITH_POW_R K_ARITH_POW_S
|
||||||
%token K_ARRAY K_ARRAY_I K_ARRAY_R K_ARRAY_S K_ARRAY_PORT
|
%token K_ARRAY K_ARRAY_I K_ARRAY_R K_ARRAY_S K_ARRAY_PORT
|
||||||
|
|
@ -288,7 +288,7 @@ statement
|
||||||
|
|
||||||
| T_LABEL K_ARITH_MOD T_NUMBER ',' symbols ';'
|
| T_LABEL K_ARITH_MOD T_NUMBER ',' symbols ';'
|
||||||
{ struct symbv_s obj = $5;
|
{ struct symbv_s obj = $5;
|
||||||
compile_arith_mod($1, $3, obj.cnt, obj.vect);
|
compile_arith_mod($1, $3, false, obj.cnt, obj.vect);
|
||||||
}
|
}
|
||||||
|
|
||||||
| T_LABEL K_ARITH_MOD_R T_NUMBER ',' symbols ';'
|
| T_LABEL K_ARITH_MOD_R T_NUMBER ',' symbols ';'
|
||||||
|
|
@ -296,6 +296,11 @@ statement
|
||||||
compile_arith_mod_r($1, obj.cnt, obj.vect);
|
compile_arith_mod_r($1, obj.cnt, obj.vect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
| T_LABEL K_ARITH_MOD_S T_NUMBER ',' symbols ';'
|
||||||
|
{ struct symbv_s obj = $5;
|
||||||
|
compile_arith_mod($1, $3, true, obj.cnt, obj.vect);
|
||||||
|
}
|
||||||
|
|
||||||
| T_LABEL K_ARITH_MULT T_NUMBER ',' symbols ';'
|
| T_LABEL K_ARITH_MULT T_NUMBER ',' symbols ';'
|
||||||
{ struct symbv_s obj = $5;
|
{ struct symbv_s obj = $5;
|
||||||
compile_arith_mult($1, $3, obj.cnt, obj.vect);
|
compile_arith_mult($1, $3, obj.cnt, obj.vect);
|
||||||
|
|
|
||||||
|
|
@ -3085,7 +3085,7 @@ bool of_LOADI_WR(vthread_t thr, vvp_code_t cp)
|
||||||
static void do_verylong_mod(vthread_t thr, vvp_code_t cp,
|
static void do_verylong_mod(vthread_t thr, vvp_code_t cp,
|
||||||
bool left_is_neg, bool right_is_neg)
|
bool left_is_neg, bool right_is_neg)
|
||||||
{
|
{
|
||||||
bool out_is_neg = left_is_neg != right_is_neg;
|
bool out_is_neg = left_is_neg;
|
||||||
int len=cp->number;
|
int len=cp->number;
|
||||||
unsigned char *a, *z, *t;
|
unsigned char *a, *z, *t;
|
||||||
a = new unsigned char[len+1];
|
a = new unsigned char[len+1];
|
||||||
|
|
|
||||||
|
|
@ -2020,6 +2020,21 @@ static void div_mod (vvp_vector2_t dividend, vvp_vector2_t divisor,
|
||||||
remainder = vvp_vector2_t(dividend, mask.size());
|
remainder = vvp_vector2_t(dividend, mask.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vvp_vector2_t operator - (const vvp_vector2_t&that)
|
||||||
|
{
|
||||||
|
vvp_vector2_t neg(that);
|
||||||
|
if (neg.wid_ == 0) return neg;
|
||||||
|
|
||||||
|
const unsigned words = (neg.wid_ + neg.BITS_PER_WORD-1) /
|
||||||
|
neg.BITS_PER_WORD;
|
||||||
|
for (unsigned idx = 0 ; idx < words ; idx += 1) {
|
||||||
|
neg.vec_[idx] = ~neg.vec_[idx];
|
||||||
|
}
|
||||||
|
neg += vvp_vector2_t(1, neg.wid_);
|
||||||
|
|
||||||
|
return neg;
|
||||||
|
}
|
||||||
|
|
||||||
vvp_vector2_t operator / (const vvp_vector2_t÷nd,
|
vvp_vector2_t operator / (const vvp_vector2_t÷nd,
|
||||||
const vvp_vector2_t&divisor)
|
const vvp_vector2_t&divisor)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -564,6 +564,7 @@ class vvp_vector4array_aa : public vvp_vector4array_t, public automatic_hooks_s
|
||||||
*/
|
*/
|
||||||
class vvp_vector2_t {
|
class vvp_vector2_t {
|
||||||
|
|
||||||
|
friend vvp_vector2_t operator - (const vvp_vector2_t&);
|
||||||
friend vvp_vector2_t operator + (const vvp_vector2_t&,
|
friend vvp_vector2_t operator + (const vvp_vector2_t&,
|
||||||
const vvp_vector2_t&);
|
const vvp_vector2_t&);
|
||||||
friend vvp_vector2_t operator * (const vvp_vector2_t&,
|
friend vvp_vector2_t operator * (const vvp_vector2_t&,
|
||||||
|
|
@ -619,6 +620,7 @@ extern bool operator >= (const vvp_vector2_t&, const vvp_vector2_t&);
|
||||||
extern bool operator < (const vvp_vector2_t&, const vvp_vector2_t&);
|
extern bool operator < (const vvp_vector2_t&, const vvp_vector2_t&);
|
||||||
extern bool operator <= (const vvp_vector2_t&, const vvp_vector2_t&);
|
extern bool operator <= (const vvp_vector2_t&, const vvp_vector2_t&);
|
||||||
extern bool operator == (const vvp_vector2_t&, const vvp_vector2_t&);
|
extern bool operator == (const vvp_vector2_t&, const vvp_vector2_t&);
|
||||||
|
extern vvp_vector2_t operator - (const vvp_vector2_t&);
|
||||||
extern vvp_vector2_t operator + (const vvp_vector2_t&, const vvp_vector2_t&);
|
extern vvp_vector2_t operator + (const vvp_vector2_t&, const vvp_vector2_t&);
|
||||||
extern vvp_vector2_t operator * (const vvp_vector2_t&, const vvp_vector2_t&);
|
extern vvp_vector2_t operator * (const vvp_vector2_t&, const vvp_vector2_t&);
|
||||||
extern vvp_vector2_t operator / (const vvp_vector2_t&, const vvp_vector2_t&);
|
extern vvp_vector2_t operator / (const vvp_vector2_t&, const vvp_vector2_t&);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue