Merge branch 'v10-branch' of github.com:steveicarus/iverilog into v10-branch
This commit is contained in:
commit
c831ce0aae
21
PDelays.cc
21
PDelays.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -26,11 +26,6 @@
|
|||
# include "verinum.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
bool dly_used_no_timescale = false;
|
||||
bool dly_used_timescale = false;
|
||||
bool display_ts_dly_warning = true;
|
||||
|
||||
|
||||
PDelays::PDelays()
|
||||
{
|
||||
delete_flag_ = true;
|
||||
|
|
@ -80,19 +75,7 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
|
|||
{
|
||||
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||
|
||||
/* Print a warning if we find default and `timescale based
|
||||
* delays in the design, since this is likely an error. */
|
||||
if (scope->time_from_timescale()) dly_used_timescale = true;
|
||||
else dly_used_no_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
dly_used_no_timescale && dly_used_timescale) {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
check_for_inconsistent_delays(scope);
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2017 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
|
||||
|
|
@ -252,7 +252,7 @@ void destroy_lexor(void)
|
|||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
46
elab_expr.cc
46
elab_expr.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -1446,6 +1446,13 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!type_is_vectorable(expr_type_)) {
|
||||
cerr << get_fileline() << ": error: The argument to "
|
||||
<< name << " must be a vector type." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: "
|
||||
<< name << " expression is the argument cast to expr_wid=" << expr_wid << endl;
|
||||
|
|
@ -3440,29 +3447,41 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
if (net == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Expecting idents with ntype to be signals." << endl;
|
||||
cerr << get_fileline() << ": error: Unable to bind variable `"
|
||||
<< path_ << "' in `" << scope_path(use_scope) << "'" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! ntype->type_compatible(net->net_type())) {
|
||||
cerr << get_fileline() << ": internal_error: "
|
||||
<< "net type doesn't match context type." << endl;
|
||||
if (const netdarray_t*array_type = dynamic_cast<const netdarray_t*> (ntype)) {
|
||||
if (array_type->type_compatible(net->net_type())) {
|
||||
NetESignal*tmp = new NetESignal(net);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "net type=";
|
||||
// Icarus allows a dynamic array to be initialised with a
|
||||
// single elementary value, so try that next.
|
||||
ntype = array_type->element_type();
|
||||
}
|
||||
|
||||
if (! ntype->type_compatible(net->net_type())) {
|
||||
cerr << get_fileline() << ": error: the type of the variable '"
|
||||
<< path_ << "' doesn't match the context type." << endl;
|
||||
|
||||
cerr << get_fileline() << ": : " << "variable type=";
|
||||
if (net->net_type())
|
||||
net->net_type()->debug_dump(cerr);
|
||||
else
|
||||
cerr << "<nil>";
|
||||
cerr << endl;
|
||||
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "context type=";
|
||||
cerr << get_fileline() << ": : " << "context type=";
|
||||
ivl_assert(*this, ntype);
|
||||
ntype->debug_dump(cerr);
|
||||
cerr << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
ivl_assert(*this, ntype->type_compatible(net->net_type()));
|
||||
|
||||
|
|
@ -5318,9 +5337,8 @@ NetExpr* PENewArray::elaborate_expr(Design*des, NetScope*scope,
|
|||
// expression. Elaborate the expression as an element
|
||||
// type. The run-time will assign this value to each element.
|
||||
const netarray_t*array_type = dynamic_cast<const netarray_t*> (ntype);
|
||||
ivl_type_t elem_type = array_type->element_type();
|
||||
|
||||
init_val = init_->elaborate_expr(des, scope, elem_type, flags);
|
||||
init_val = init_->elaborate_expr(des, scope, array_type, flags);
|
||||
}
|
||||
|
||||
NetENew*tmp = new NetENew(ntype, size, init_val);
|
||||
|
|
@ -5571,6 +5589,10 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode)
|
|||
|
||||
NetExpr* PENumber::elaborate_expr(Design*des, NetScope*, ivl_type_t ntype, unsigned) const
|
||||
{
|
||||
// Icarus allows dynamic arrays to be initialised with a single value.
|
||||
if (const netdarray_t*array_type = dynamic_cast<const netdarray_t*> (ntype))
|
||||
ntype = array_type->element_type();
|
||||
|
||||
const netvector_t*use_type = dynamic_cast<const netvector_t*> (ntype);
|
||||
if (use_type == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -509,8 +509,10 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
|||
|
||||
netclass_t*use_base_class = 0;
|
||||
if (base_class) {
|
||||
ivl_assert(*pclass, scope);
|
||||
use_base_class = scope->find_class(base_class->name);
|
||||
if (scope)
|
||||
use_base_class = scope->find_class(base_class->name);
|
||||
if (use_base_class == 0)
|
||||
use_base_class = des->find_class(base_class->name);
|
||||
if (use_base_class == 0) {
|
||||
cerr << pclass->get_fileline() << ": error: "
|
||||
<< "Base class " << base_class->name
|
||||
|
|
@ -605,13 +607,9 @@ static void elaborate_scope_classes(Design*des, NetScope*scope,
|
|||
|
||||
void elaborate_rootscope_classes(Design*des)
|
||||
{
|
||||
if (pform_classes.empty())
|
||||
return;
|
||||
|
||||
for (map<perm_string,PClass*>::iterator cur = pform_classes.begin()
|
||||
; cur != pform_classes.end() ; ++ cur) {
|
||||
blend_class_constructors(cur->second);
|
||||
elaborate_scope_class(des, 0, cur->second);
|
||||
for (size_t idx = 0 ; idx < pform_classes.size() ; idx += 1) {
|
||||
blend_class_constructors(pform_classes[idx]);
|
||||
elaborate_scope_class(des, 0, pform_classes[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
28
elaborate.cc
28
elaborate.cc
|
|
@ -2374,19 +2374,7 @@ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
|
|||
{
|
||||
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||
|
||||
/* Print a warning if we find default and `timescale based
|
||||
* delays in the design, since this is likely an error. */
|
||||
if (scope->time_from_timescale()) dly_used_timescale = true;
|
||||
else dly_used_no_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
dly_used_no_timescale && dly_used_timescale) {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
check_for_inconsistent_delays(scope);
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
|
|
@ -5434,19 +5422,7 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
|
|||
ndelays = delays.size();
|
||||
if (ndelays > 12) ndelays = 12;
|
||||
|
||||
/* Print a warning if we find default and `timescale based
|
||||
* delays in the design, since this is likely an error. */
|
||||
if (scope->time_from_timescale()) dly_used_timescale = true;
|
||||
else dly_used_no_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
dly_used_no_timescale && dly_used_timescale) {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
check_for_inconsistent_delays(scope);
|
||||
|
||||
/* Elaborate the delay values themselves. Remember to scale
|
||||
them for the timescale/precision of the scope. */
|
||||
|
|
|
|||
|
|
@ -2100,7 +2100,7 @@ void destroy_lexor(void)
|
|||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -1606,7 +1606,7 @@ void destroy_lexor()
|
|||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ static unsigned string_pool_count = 0;
|
|||
StringHeap::StringHeap()
|
||||
{
|
||||
cell_base_ = 0;
|
||||
cell_ptr_ = HEAPCELL;
|
||||
cell_count_ = 0;
|
||||
cell_size_ = 0;
|
||||
cell_ptr_ = 0;
|
||||
}
|
||||
|
||||
StringHeap::~StringHeap()
|
||||
|
|
@ -45,20 +45,24 @@ StringHeap::~StringHeap()
|
|||
const char* StringHeap::add(const char*text)
|
||||
{
|
||||
unsigned len = strlen(text);
|
||||
assert((len+1) <= HEAPCELL);
|
||||
|
||||
unsigned rem = HEAPCELL - cell_ptr_;
|
||||
unsigned rem = cell_size_ - cell_ptr_;
|
||||
if (rem < (len+1)) {
|
||||
cell_base_ = (char*)malloc(HEAPCELL);
|
||||
// release any unused memory
|
||||
if (rem > 0) {
|
||||
cell_base_ = (char*)realloc(cell_base_, cell_ptr_);
|
||||
assert(cell_base_ != 0);
|
||||
}
|
||||
// start new cell
|
||||
cell_size_ = (len+1) > DEFAULT_CELL_SIZE ? len+1 : DEFAULT_CELL_SIZE;
|
||||
cell_base_ = (char*)malloc(cell_size_);
|
||||
cell_ptr_ = 0;
|
||||
assert(cell_base_ != 0);
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
string_pool_count += 1;
|
||||
string_pool = (char **) realloc(string_pool,
|
||||
string_pool_count*sizeof(char **));
|
||||
string_pool[string_pool_count-1] = cell_base_;
|
||||
#endif
|
||||
cell_ptr_ = 0;
|
||||
cell_count_ += 1;
|
||||
assert(cell_base_ != 0);
|
||||
}
|
||||
|
||||
char*res = cell_base_ + cell_ptr_;
|
||||
|
|
@ -66,7 +70,7 @@ const char* StringHeap::add(const char*text)
|
|||
cell_ptr_ += len;
|
||||
cell_base_[cell_ptr_++] = 0;
|
||||
|
||||
assert(cell_ptr_ <= HEAPCELL);
|
||||
assert(cell_ptr_ <= cell_size_);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,11 +78,11 @@ class StringHeap {
|
|||
perm_string make(const char*);
|
||||
|
||||
private:
|
||||
enum { HEAPCELL = 0x10000 };
|
||||
static const unsigned DEFAULT_CELL_SIZE = 0x10000;
|
||||
|
||||
char*cell_base_;
|
||||
unsigned cell_size_;
|
||||
unsigned cell_ptr_;
|
||||
unsigned cell_count_;
|
||||
|
||||
private: // not implemented
|
||||
StringHeap(const StringHeap&);
|
||||
|
|
|
|||
7
main.cc
7
main.cc
|
|
@ -1,5 +1,5 @@
|
|||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 1998-2015 Stephen Williams (steve@icarus.com)";
|
||||
"Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)";
|
||||
|
||||
/*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -1037,9 +1037,8 @@ int main(int argc, char*argv[])
|
|||
pform_dump(out, cur->second);
|
||||
}
|
||||
out << "PFORM DUMP $ROOT CLASSES:" << endl;
|
||||
for (map<perm_string,PClass*>::iterator cur = pform_classes.begin()
|
||||
; cur != pform_classes.end() ; ++ cur) {
|
||||
pform_dump(out, cur->second);
|
||||
for (size_t idx = 0 ; idx < pform_classes.size() ; idx += 1) {
|
||||
pform_dump(out, pform_classes[idx]);
|
||||
}
|
||||
out << "PFORM DUMP PACKAGES:" << endl;
|
||||
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2012-2017 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
|
||||
|
|
@ -165,7 +165,8 @@ bool netclass_t::test_for_missing_initializers() const
|
|||
NetScope*netclass_t::method_from_name(perm_string name) const
|
||||
{
|
||||
NetScope*task = class_scope_->child( hname_t(name) );
|
||||
if (task == 0) return 0;
|
||||
if ((task == 0) && super_)
|
||||
task = super_->method_from_name(name);
|
||||
return task;
|
||||
|
||||
}
|
||||
|
|
|
|||
32
netlist.cc
32
netlist.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -2724,12 +2724,27 @@ DelayType NetProc::delay_type() const
|
|||
|
||||
DelayType NetBlock::delay_type() const
|
||||
{
|
||||
DelayType result = NO_DELAY;
|
||||
// A join_none has no delay.
|
||||
if (type() == PARA_JOIN_NONE) return NO_DELAY;
|
||||
|
||||
for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) {
|
||||
DelayType dt = cur->delay_type();
|
||||
if (dt > result) result = dt;
|
||||
if (dt == DEFINITE_DELAY) break;
|
||||
DelayType result;
|
||||
// A join_any has the minimum delay.
|
||||
if (type() == PARA_JOIN_ANY) {
|
||||
result = DEFINITE_DELAY;
|
||||
for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) {
|
||||
DelayType dt = cur->delay_type();
|
||||
if (dt < result) result = dt;
|
||||
if (dt == NO_DELAY) break;
|
||||
}
|
||||
|
||||
// A begin or join has the maximum delay.
|
||||
} else {
|
||||
result = NO_DELAY;
|
||||
for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) {
|
||||
DelayType dt = cur->delay_type();
|
||||
if (dt > result) result = dt;
|
||||
if (dt == DEFINITE_DELAY) break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -2800,9 +2815,10 @@ DelayType NetPDelay::delay_type() const
|
|||
return DEFINITE_DELAY;
|
||||
} else {
|
||||
if (statement_) {
|
||||
return statement_->delay_type();
|
||||
return combine_delays(ZERO_DELAY,
|
||||
statement_->delay_type());
|
||||
} else {
|
||||
return NO_DELAY;
|
||||
return ZERO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
37
netmisc.cc
37
netmisc.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2017 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
|
||||
|
|
@ -1665,3 +1665,38 @@ NetScope* find_method_containing_scope(const LineInfo&, NetScope*scope)
|
|||
|
||||
return scope;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print a warning if we find a mixture of default and explicit timescale
|
||||
* based delays in the design, since this is likely an error.
|
||||
*/
|
||||
void check_for_inconsistent_delays(NetScope*scope)
|
||||
{
|
||||
static bool used_implicit_timescale = false;
|
||||
static bool used_explicit_timescale = false;
|
||||
static bool display_ts_dly_warning = true;
|
||||
|
||||
if (scope->time_from_timescale())
|
||||
used_explicit_timescale = true;
|
||||
else
|
||||
used_implicit_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
used_explicit_timescale &&
|
||||
used_implicit_timescale) {
|
||||
if (gn_system_verilog()) {
|
||||
cerr << "warning: Found both default and explicit "
|
||||
"timescale based delays. Use" << endl;
|
||||
cerr << " : -Wtimescale to find the design "
|
||||
"element(s) with no explicit" << endl;
|
||||
cerr << " : timescale." << endl;
|
||||
} else {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " : -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
}
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
netmisc.h
12
netmisc.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_netmisc_H
|
||||
#define IVL_netmisc_H
|
||||
/*
|
||||
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -378,10 +378,6 @@ const char *human_readable_op(const char op, bool unary = false);
|
|||
enum const_bool { C_NON, C_0, C_1, C_X };
|
||||
const_bool const_logical(const NetExpr*expr);
|
||||
|
||||
extern bool dly_used_no_timescale;
|
||||
extern bool dly_used_timescale;
|
||||
extern bool display_ts_dly_warning;
|
||||
|
||||
/*
|
||||
* When scaling a real value to a time we need to do some standard
|
||||
* processing.
|
||||
|
|
@ -409,4 +405,10 @@ extern void assign_unpacked_with_bufz(Design*des, NetScope*scope,
|
|||
|
||||
extern NetPartSelect* detect_partselect_lval(Link&pin);
|
||||
|
||||
/*
|
||||
* Print a warning if we find a mixture of default and explicit timescale
|
||||
* based delays in the design, since this is likely an error.
|
||||
*/
|
||||
extern void check_for_inconsistent_delays(NetScope*scope);
|
||||
|
||||
#endif /* IVL_netmisc_H */
|
||||
|
|
|
|||
29
parse.y
29
parse.y
|
|
@ -598,7 +598,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
|
||||
%type <tf_ports> function_item function_item_list function_item_list_opt
|
||||
%type <tf_ports> task_item task_item_list task_item_list_opt
|
||||
%type <tf_ports> tf_port_declaration tf_port_item tf_port_list tf_port_list_opt
|
||||
%type <tf_ports> tf_port_declaration tf_port_item tf_port_item_list tf_port_list tf_port_list_opt
|
||||
|
||||
%type <named_pexpr> modport_simple_port port_name parameter_value_byname
|
||||
%type <named_pexprs> port_name_list parameter_value_byname_list
|
||||
|
|
@ -2044,7 +2044,10 @@ task_declaration /* IEEE1800-2005: A.2.7 */
|
|||
|
||||
| K_task lifetime_opt IDENTIFIER error K_endtask
|
||||
{
|
||||
assert(current_task == 0);
|
||||
if (current_task) {
|
||||
pform_pop_scope();
|
||||
current_task = 0;
|
||||
}
|
||||
}
|
||||
endlabel_opt
|
||||
{ // Last step: check any closing name. This is done late so
|
||||
|
|
@ -2119,10 +2122,16 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
|
|||
|
||||
: port_direction_opt data_type_or_implicit IDENTIFIER dimensions_opt tf_port_item_expr_opt
|
||||
{ vector<pform_tf_port_t>*tmp;
|
||||
NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1;
|
||||
NetNet::PortType use_port_type = $1;
|
||||
if ((use_port_type == NetNet::PIMPLICIT) && (gn_system_verilog() || ($2 == 0)))
|
||||
use_port_type = port_declaration_context.port_type;
|
||||
perm_string name = lex_strings.make($3);
|
||||
list<perm_string>* ilist = list_from_identifier($3);
|
||||
|
||||
if (use_port_type == NetNet::PIMPLICIT) {
|
||||
yyerror(@1, "error: missing task/function port direction.");
|
||||
use_port_type = NetNet::PINPUT; // for error recovery
|
||||
}
|
||||
if (($2 == 0) && ($1==NetNet::PIMPLICIT)) {
|
||||
// Detect special case this is an undecorated
|
||||
// identifier and we need to get the declaration from
|
||||
|
|
@ -2134,7 +2143,6 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
|
|||
port_declaration_context.data_type,
|
||||
ilist);
|
||||
|
||||
|
||||
} else {
|
||||
// Otherwise, the decorations for this identifier
|
||||
// indicate the type. Save the type for any right
|
||||
|
|
@ -2181,8 +2189,15 @@ tf_port_item_expr_opt
|
|||
;
|
||||
|
||||
tf_port_list /* IEEE1800-2005: A.2.7 */
|
||||
: { port_declaration_context.port_type = gn_system_verilog() ? NetNet::PINPUT : NetNet::PIMPLICIT;
|
||||
port_declaration_context.data_type = 0;
|
||||
}
|
||||
tf_port_item_list
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
: tf_port_list ',' tf_port_item
|
||||
tf_port_item_list
|
||||
: tf_port_item_list ',' tf_port_item
|
||||
{ vector<pform_tf_port_t>*tmp;
|
||||
if ($1 && $3) {
|
||||
size_t s1 = $1->size();
|
||||
|
|
@ -2208,11 +2223,11 @@ tf_port_list /* IEEE1800-2005: A.2.7 */
|
|||
{ yyerror(@2, "error: Syntax error in task/function port declaration.");
|
||||
$$ = $3;
|
||||
}
|
||||
| tf_port_list ','
|
||||
| tf_port_item_list ','
|
||||
{ yyerror(@2, "error: NULL port declarations are not allowed.");
|
||||
$$ = $1;
|
||||
}
|
||||
| tf_port_list ';'
|
||||
| tf_port_item_list ';'
|
||||
{ yyerror(@2, "error: ';' is an invalid port declaration separator.");
|
||||
$$ = $1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_parse_api_H
|
||||
#define IVL_parse_api_H
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2017 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
|
||||
|
|
@ -45,7 +45,7 @@ extern std::map<perm_string,PUdp*> pform_primitives;
|
|||
extern std::map<perm_string,data_type_t*> pform_typedefs;
|
||||
extern std::set<enum_type_t*> pform_enum_sets;
|
||||
extern std::map<perm_string,PTaskFunc*> pform_tasks;
|
||||
extern std::map<perm_string,PClass*> pform_classes;
|
||||
extern std::vector<PClass*> pform_classes;
|
||||
extern std::map<perm_string,PPackage*> pform_packages;
|
||||
|
||||
extern void pform_dump(std::ostream&out, const PClass*pac);
|
||||
|
|
|
|||
6
pform.cc
6
pform.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -71,7 +71,7 @@ set<enum_type_t*>pform_enum_sets;
|
|||
/*
|
||||
* Class definitions in the $root scope go here.
|
||||
*/
|
||||
map<perm_string,PClass*> pform_classes;
|
||||
vector<PClass*> pform_classes;
|
||||
|
||||
/*
|
||||
* Task and function definitions in the $root scope go here.
|
||||
|
|
@ -467,7 +467,7 @@ PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name,
|
|||
/* If no scope was found then this is being defined in the
|
||||
* compilation unit scope. */
|
||||
if (scopex == 0) {
|
||||
pform_classes[name] = class_scope;
|
||||
pform_classes.push_back(class_scope);
|
||||
lexical_scope = class_scope;
|
||||
return class_scope;
|
||||
}
|
||||
|
|
|
|||
7
t-dll.cc
7
t-dll.cc
|
|
@ -281,6 +281,13 @@ ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur)
|
|||
return scope;
|
||||
}
|
||||
|
||||
for (map<const NetScope*,ivl_scope_t>::iterator idx = des.root_tasks.begin()
|
||||
; idx != des.root_tasks.end() ; ++ idx) {
|
||||
ivl_scope_t scope = find_scope_from_root(idx->second, cur);
|
||||
if (scope)
|
||||
return scope;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (C) 2011-2017 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -79,11 +79,14 @@ void init_fp_lexor(FILE*fd)
|
|||
yyrestart(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
||||
*/
|
||||
void destroy_fp_lexor()
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ static int eval_darray_new(ivl_expr_t ex)
|
|||
unsigned idx;
|
||||
switch (ivl_type_base(element_type)) {
|
||||
case IVL_VT_BOOL:
|
||||
case IVL_VT_LOGIC:
|
||||
for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) {
|
||||
draw_eval_vec4(ivl_expr_parm(init_expr,idx));
|
||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||
|
|
@ -110,6 +111,11 @@ static int eval_darray_new(ivl_expr_t ex)
|
|||
errors += 1;
|
||||
break;
|
||||
}
|
||||
} else if (init_expr && (ivl_expr_value(init_expr) == IVL_VT_DARRAY)) {
|
||||
ivl_signal_t sig = ivl_expr_signal(init_expr);
|
||||
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
|
||||
fprintf(vvp_out, " %%scopy;\n");
|
||||
|
||||
} else if (init_expr && number_is_immediate(size_expr,32,0)) {
|
||||
/* In this case, there is an init expression, the
|
||||
expression is NOT an array_pattern, and the size
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2018 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
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
# include "verinum.h"
|
||||
# include <iostream>
|
||||
# include <cassert>
|
||||
# include <climits>
|
||||
# include <cmath> // Needed to get pow for as_double().
|
||||
# include <cstdio> // Needed to get snprintf for as_string().
|
||||
# include <algorithm>
|
||||
|
|
@ -1444,7 +1445,8 @@ verinum operator / (const verinum&left, const verinum&right)
|
|||
if (use_len <= (8*sizeof(long) - 1)) {
|
||||
long l = left.as_long();
|
||||
long r = right.as_long();
|
||||
long v = l / r;
|
||||
bool overflow = (l == LONG_MIN) && (r == -1);
|
||||
long v = overflow ? LONG_MIN : l / r;
|
||||
for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
|
||||
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
|
||||
v >>= 1;
|
||||
|
|
@ -1518,7 +1520,8 @@ verinum operator % (const verinum&left, const verinum&right)
|
|||
/* Use native signed modulus to do the work. */
|
||||
long l = left.as_long();
|
||||
long r = right.as_long();
|
||||
long v = l % r;
|
||||
bool overflow = (l == LONG_MIN) && (r == -1);
|
||||
long v = overflow ? 0 : l % r;
|
||||
for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
|
||||
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
|
||||
v >>= 1;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2011-2017 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
|
||||
|
|
@ -751,7 +751,16 @@ yyscan_t prepare_lexor(FILE*fd)
|
|||
return scanner;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
||||
*/
|
||||
void destroy_lexor(yyscan_t scanner)
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy(scanner);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright CERN 2015
|
||||
* Copyright CERN 2016-2018
|
||||
* @author Maciej Suminski (maciej.suminski@cern.ch)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -120,7 +120,7 @@ void preload_std_funcs(void)
|
|||
std::list<InterfacePort*>*fn_integer_args = new std::list<InterfacePort*>();
|
||||
fn_integer_args->push_back(new InterfacePort(&primitive_INTEGER));
|
||||
fn_integer = new SubprogramBuiltin(perm_string::literal("integer"),
|
||||
perm_string::literal("$signed"),
|
||||
perm_string::literal("int'"),
|
||||
fn_integer_args, &primitive_INTEGER);
|
||||
std_subprograms[fn_integer->name()] = fn_integer;
|
||||
|
||||
|
|
|
|||
69
vpi/fstapi.c
69
vpi/fstapi.c
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2015 Tony Bybell.
|
||||
* Copyright (c) 2009-2018 Tony Bybell.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -128,6 +128,7 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
|
|||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#define FST_APIMESS "FSTAPI | "
|
||||
|
||||
/***********************/
|
||||
/*** ***/
|
||||
|
|
@ -193,7 +194,7 @@ if(nam) /* cppcheck warning fix: nam is always defined, so this is not needed */
|
|||
dwRetVal = GetTempPath(MAX_PATH, lpTempPathBuffer);
|
||||
if((dwRetVal > MAX_PATH) || (dwRetVal == 0))
|
||||
{
|
||||
fprintf(stderr, "GetTempPath() failed in "__FILE__" line %d, exiting.\n", __LINE__);
|
||||
fprintf(stderr, FST_APIMESS"GetTempPath() failed in "__FILE__" line %d, exiting.\n", __LINE__);
|
||||
exit(255);
|
||||
}
|
||||
else
|
||||
|
|
@ -201,7 +202,7 @@ if(nam) /* cppcheck warning fix: nam is always defined, so this is not needed */
|
|||
uRetVal = GetTempFileName(lpTempPathBuffer, TEXT("FSTW"), 0, szTempFileName);
|
||||
if (uRetVal == 0)
|
||||
{
|
||||
fprintf(stderr, "GetTempFileName() failed in "__FILE__" line %d, exiting.\n", __LINE__);
|
||||
fprintf(stderr, FST_APIMESS"GetTempFileName() failed in "__FILE__" line %d, exiting.\n", __LINE__);
|
||||
exit(255);
|
||||
}
|
||||
else
|
||||
|
|
@ -803,7 +804,7 @@ if(rc<0)
|
|||
{
|
||||
xc->fseek_failed = 1;
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "Seek to #%"PRId64" (whence = %d) failed!\n", offset, whence);
|
||||
fprintf(stderr, FST_APIMESS"Seek to #%"PRId64" (whence = %d) failed!\n", offset, whence);
|
||||
perror("Why");
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1663,7 +1664,7 @@ if(zerocnt)
|
|||
/* fpos += */ fstWriterVarint(f, (zerocnt << 1)); /* scan-build */
|
||||
}
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "value chains: %d\n", cnt);
|
||||
fprintf(stderr, FST_APIMESS"value chains: %d\n", cnt);
|
||||
#endif
|
||||
|
||||
xc->vchg_mem[0] = '!';
|
||||
|
|
@ -1738,7 +1739,7 @@ if(xc->dump_size_limit)
|
|||
xc2->size_limit_locked = 1;
|
||||
xc2->is_initial_time = 1; /* to trick emit value and emit time change */
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "<< dump file size limit reached, stopping dumping >>\n");
|
||||
fprintf(stderr, FST_APIMESS"<< dump file size limit reached, stopping dumping >>\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -2478,7 +2479,7 @@ if(xc)
|
|||
#ifndef FST_WRITER_PARALLEL
|
||||
if(xc->parallel_enabled)
|
||||
{
|
||||
fprintf(stderr, "ERROR: fstWriterSetParallelMode(), FST_WRITER_PARALLEL not enabled during compile, exiting.\n");
|
||||
fprintf(stderr, FST_APIMESS"fstWriterSetParallelMode(), FST_WRITER_PARALLEL not enabled during compile, exiting.\n");
|
||||
exit(255);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2760,7 +2761,7 @@ if((xc) && (handle <= xc->maxhandle))
|
|||
xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz);
|
||||
if(!xc->vchg_mem)
|
||||
{
|
||||
fprintf(stderr, "FATAL ERROR, could not realloc() in fstWriterEmitValueChange, exiting.\n");
|
||||
fprintf(stderr, FST_APIMESS"Could not realloc() in fstWriterEmitValueChange, exiting.\n");
|
||||
exit(255);
|
||||
}
|
||||
}
|
||||
|
|
@ -2874,7 +2875,7 @@ if((xc) && (handle <= xc->maxhandle))
|
|||
xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz);
|
||||
if(!xc->vchg_mem)
|
||||
{
|
||||
fprintf(stderr, "FATAL ERROR, could not realloc() in fstWriterEmitVariableLengthValueChange, exiting.\n");
|
||||
fprintf(stderr, FST_APIMESS"Could not realloc() in fstWriterEmitVariableLengthValueChange, exiting.\n");
|
||||
exit(255);
|
||||
}
|
||||
}
|
||||
|
|
@ -3119,7 +3120,7 @@ if(rc<0)
|
|||
{
|
||||
xc->fseek_failed = 1;
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "Seek to #%"PRId64" (whence = %d) failed!\n", offset, whence);
|
||||
fprintf(stderr, FST_APIMESS"Seek to #%"PRId64" (whence = %d) failed!\n", offset, whence);
|
||||
perror("Why");
|
||||
#endif
|
||||
}
|
||||
|
|
@ -3748,6 +3749,10 @@ if(!xc->fh)
|
|||
else /* FST_BL_SKIP */
|
||||
{
|
||||
pass_status = 0;
|
||||
if(xc->fh)
|
||||
{
|
||||
fclose(xc->fh); xc->fh = NULL; /* needed in case .hier file is missing and there are no hier sections */
|
||||
}
|
||||
}
|
||||
|
||||
free(mem);
|
||||
|
|
@ -4435,7 +4440,7 @@ if(gzread_pass_status)
|
|||
|
||||
if(rc != Z_OK)
|
||||
{
|
||||
printf("geom uncompress rc = %d\n", rc);
|
||||
fprintf(stderr, FST_APIMESS"fstReaderInit(), geom uncompress rc = %d, exiting.\n", rc);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
|
|
@ -4726,7 +4731,7 @@ for(;;)
|
|||
if((sectype == EOF) || (sectype == FST_BL_SKIP))
|
||||
{
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "<< EOF >>\n");
|
||||
fprintf(stderr, FST_APIMESS"<< EOF >>\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
|
@ -4765,9 +4770,9 @@ for(;;)
|
|||
mem_required_for_traversal = fstReaderUint64(xc->f);
|
||||
mem_for_traversal = malloc(mem_required_for_traversal + 66); /* add in potential fastlz overhead */
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "sec: %u seclen: %d begtim: %d endtim: %d\n",
|
||||
fprintf(stderr, FST_APIMESS"sec: %u seclen: %d begtim: %d endtim: %d\n",
|
||||
secnum, (int)seclen, (int)beg_tim, (int)end_tim);
|
||||
fprintf(stderr, "\tmem_required_for_traversal: %d\n", (int)mem_required_for_traversal);
|
||||
fprintf(stderr, FST_APIMESS"mem_required_for_traversal: %d\n", (int)mem_required_for_traversal);
|
||||
#endif
|
||||
/* process time block */
|
||||
{
|
||||
|
|
@ -4785,7 +4790,7 @@ for(;;)
|
|||
tsec_clen = fstReaderUint64(xc->f);
|
||||
tsec_nitems = fstReaderUint64(xc->f);
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "\ttime section unc: %d, com: %d (%d items)\n",
|
||||
fprintf(stderr, FST_APIMESS"time section unc: %d, com: %d (%d items)\n",
|
||||
(int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems);
|
||||
#endif
|
||||
if(tsec_clen > seclen) break; /* corrupted tsec_clen: by definition it can't be larger than size of section */
|
||||
|
|
@ -4805,7 +4810,7 @@ for(;;)
|
|||
|
||||
if(rc != Z_OK)
|
||||
{
|
||||
printf("tsec uncompress rc = %d\n", rc);
|
||||
fprintf(stderr, FST_APIMESS"fstReaderIterBlocks2(), tsec uncompress rc = %d, exiting.\n", rc);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
|
|
@ -4881,7 +4886,7 @@ for(;;)
|
|||
rc = uncompress(mu, &destlen, mc, sourcelen);
|
||||
if(rc != Z_OK)
|
||||
{
|
||||
printf("rc: %d\n", rc);
|
||||
fprintf(stderr, FST_APIMESS"fstReaderIterBlocks2(), frame uncompress rc: %d, exiting.\n", rc);
|
||||
exit(255);
|
||||
}
|
||||
free(mc);
|
||||
|
|
@ -5044,9 +5049,9 @@ for(;;)
|
|||
packtype = fgetc(xc->f);
|
||||
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "\tframe_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n",
|
||||
fprintf(stderr, FST_APIMESS"frame_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n",
|
||||
(int)frame_uclen, (int)frame_clen, (int)frame_maxhandle);
|
||||
fprintf(stderr, "\tvc_maxhandle: %d, packtype: %c\n", (int)vc_maxhandle, packtype);
|
||||
fprintf(stderr, FST_APIMESS"vc_maxhandle: %d, packtype: %c\n", (int)vc_maxhandle, packtype);
|
||||
#endif
|
||||
|
||||
indx_pntr = blkpos + seclen - 24 -tsec_clen -8;
|
||||
|
|
@ -5054,7 +5059,7 @@ for(;;)
|
|||
chain_clen = fstReaderUint64(xc->f);
|
||||
indx_pos = indx_pntr - chain_clen;
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "\tindx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen);
|
||||
fprintf(stderr, FST_APIMESS"indx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen);
|
||||
#endif
|
||||
chain_cmem = malloc(chain_clen);
|
||||
if(!chain_cmem) goto block_err;
|
||||
|
|
@ -5173,7 +5178,7 @@ for(;;)
|
|||
}
|
||||
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "\tdecompressed chain idx len: %"PRIu32"\n", idx);
|
||||
fprintf(stderr, FST_APIMESS"decompressed chain idx len: %"PRIu32"\n", idx);
|
||||
#endif
|
||||
|
||||
mc_mem_len = 16384;
|
||||
|
|
@ -5241,7 +5246,7 @@ for(;;)
|
|||
|
||||
if(rc != Z_OK)
|
||||
{
|
||||
printf("\tfac: %d clen: %d (rc=%d)\n", (int)i, (int)val, rc);
|
||||
fprintf(stderr, FST_APIMESS"fstReaderIterBlocks2(), fac: %d clen: %d (rc=%d), exiting.\n", (int)i, (int)val, rc);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
|
|
@ -5793,9 +5798,9 @@ mem_required_for_traversal =
|
|||
fstReaderUint64(xc->f);
|
||||
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "rvat sec: %u seclen: %d begtim: %d endtim: %d\n",
|
||||
fprintf(stderr, FST_APIMESS"rvat sec: %u seclen: %d begtim: %d endtim: %d\n",
|
||||
secnum, (int)seclen, (int)beg_tim, (int)end_tim);
|
||||
fprintf(stderr, "\tmem_required_for_traversal: %d\n", (int)mem_required_for_traversal);
|
||||
fprintf(stderr, FST_APIMESS"mem_required_for_traversal: %d\n", (int)mem_required_for_traversal);
|
||||
#endif
|
||||
|
||||
/* process time block */
|
||||
|
|
@ -5814,7 +5819,7 @@ tsec_uclen = fstReaderUint64(xc->f);
|
|||
tsec_clen = fstReaderUint64(xc->f);
|
||||
tsec_nitems = fstReaderUint64(xc->f);
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "\ttime section unc: %d, com: %d (%d items)\n",
|
||||
fprintf(stderr, FST_APIMESS"time section unc: %d, com: %d (%d items)\n",
|
||||
(int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems);
|
||||
#endif
|
||||
ucdata = malloc(tsec_uclen);
|
||||
|
|
@ -5831,7 +5836,7 @@ if(tsec_uclen != tsec_clen)
|
|||
|
||||
if(rc != Z_OK)
|
||||
{
|
||||
printf("tsec uncompress rc = %d\n", rc);
|
||||
fprintf(stderr, FST_APIMESS"fstReaderGetValueFromHandleAtTime(), tsec uncompress rc = %d, exiting.\n", rc);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
|
|
@ -5879,7 +5884,7 @@ if(frame_uclen == frame_clen)
|
|||
rc = uncompress(xc->rvat_frame_data, &destlen, mc, sourcelen);
|
||||
if(rc != Z_OK)
|
||||
{
|
||||
printf("decompress rc: %d\n", rc);
|
||||
fprintf(stderr, FST_APIMESS"fstReaderGetValueFromHandleAtTime(), frame decompress rc: %d, exiting.\n", rc);
|
||||
exit(255);
|
||||
}
|
||||
free(mc);
|
||||
|
|
@ -5890,9 +5895,9 @@ xc->rvat_vc_start = ftello(xc->f); /* points to '!' character */
|
|||
xc->rvat_packtype = fgetc(xc->f);
|
||||
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "\tframe_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n",
|
||||
fprintf(stderr, FST_APIMESS"frame_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n",
|
||||
(int)frame_uclen, (int)frame_clen, (int)xc->rvat_frame_maxhandle);
|
||||
fprintf(stderr, "\tvc_maxhandle: %d\n", (int)xc->rvat_vc_maxhandle);
|
||||
fprintf(stderr, FST_APIMESS"vc_maxhandle: %d\n", (int)xc->rvat_vc_maxhandle);
|
||||
#endif
|
||||
|
||||
indx_pntr = blkpos + seclen - 24 -tsec_clen -8;
|
||||
|
|
@ -5900,7 +5905,7 @@ fstReaderFseeko(xc, xc->f, indx_pntr, SEEK_SET);
|
|||
chain_clen = fstReaderUint64(xc->f);
|
||||
indx_pos = indx_pntr - chain_clen;
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "\tindx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen);
|
||||
fprintf(stderr, FST_APIMESS"indx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen);
|
||||
#endif
|
||||
chain_cmem = malloc(chain_clen);
|
||||
fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET);
|
||||
|
|
@ -6011,7 +6016,7 @@ for(i=0;i<idx;i++)
|
|||
}
|
||||
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, "\tdecompressed chain idx len: %"PRIu32"\n", idx);
|
||||
fprintf(stderr, FST_APIMESS"decompressed chain idx len: %"PRIu32"\n", idx);
|
||||
#endif
|
||||
|
||||
xc->rvat_data_valid = 1;
|
||||
|
|
@ -6071,7 +6076,7 @@ if(!xc->rvat_chain_mem)
|
|||
|
||||
if(rc != Z_OK)
|
||||
{
|
||||
printf("\tclen: %d (rc=%d)\n", (int)xc->rvat_chain_len, rc);
|
||||
fprintf(stderr, FST_APIMESS"fstReaderGetValueFromHandleAtTime(), rvat decompress clen: %d (rc=%d), exiting.\n", (int)xc->rvat_chain_len, rc);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2015 Tony Bybell.
|
||||
* Copyright (c) 2009-2017 Tony Bybell.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -168,7 +168,11 @@ enum fstHierType {
|
|||
FST_HT_ATTRBEGIN = 3,
|
||||
FST_HT_ATTREND = 4,
|
||||
|
||||
FST_HT_MAX = 4
|
||||
/* FST_HT_TREEBEGIN and FST_HT_TREEEND are not yet used by FST but are currently used when fstHier bridges other formats */
|
||||
FST_HT_TREEBEGIN = 5,
|
||||
FST_HT_TREEEND = 6,
|
||||
|
||||
FST_HT_MAX = 6
|
||||
};
|
||||
|
||||
enum fstAttrType {
|
||||
|
|
|
|||
|
|
@ -825,7 +825,7 @@ _next_match:
|
|||
/* Match description too long : reduce it */
|
||||
matchLength = (15-1) + (oMaxMatch-op) * 255;
|
||||
}
|
||||
//printf("offset %5i, matchLength%5i \n", (int)(ip-match), matchLength + MINMATCH);
|
||||
/*printf("offset %5i, matchLength%5i \n", (int)(ip-match), matchLength + MINMATCH);*/
|
||||
ip += MINMATCH + matchLength;
|
||||
|
||||
if (matchLength>=ML_MASK)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2007-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2007-2017 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
|
||||
|
|
@ -217,7 +217,7 @@ static void destroy_sdf_lexor(void)
|
|||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -1887,6 +1887,8 @@ static const char *pts_convert(int value)
|
|||
{
|
||||
const char *string;
|
||||
switch (value) {
|
||||
case 2: string = "100s"; break;
|
||||
case 1: string = "10s"; break;
|
||||
case 0: string = "1s"; break;
|
||||
case -1: string = "100ms"; break;
|
||||
case -2: string = "10ms"; break;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -199,7 +199,7 @@ void destroy_readmem_lexor(void)
|
|||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2007-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2007-2017 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
|
||||
|
|
@ -289,7 +289,10 @@ static PLI_INT32 sys_sdf_annotate_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
|
|||
FILE *sdf_fd;
|
||||
char *fname = get_filename(callh, name, vpi_scan(argv));
|
||||
|
||||
if (fname == 0) return 0;
|
||||
if (fname == 0) {
|
||||
vpi_free_object(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdf_fd = fopen(fname, "r");
|
||||
if (sdf_fd == 0) {
|
||||
|
|
@ -297,6 +300,8 @@ static PLI_INT32 sys_sdf_annotate_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
|
|||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("Unable to open SDF file \"%s\"."
|
||||
" Skipping this annotation.\n", fname);
|
||||
vpi_free_object(argv);
|
||||
free(fname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2011-2017 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -154,7 +154,7 @@ void destroy_tblmod_lexor(void)
|
|||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-2018 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
|
||||
|
|
@ -45,14 +45,14 @@ struct vvp_island_branch_tran : public vvp_island_branch {
|
|||
|
||||
vvp_island_branch_tran(vvp_net_t*en__, bool active_high__,
|
||||
unsigned width__, unsigned part__,
|
||||
unsigned offset__);
|
||||
unsigned offset__, bool resistive__);
|
||||
bool run_test_enabled();
|
||||
void run_resolution();
|
||||
void run_output();
|
||||
|
||||
vvp_net_t*en;
|
||||
unsigned width, part, offset;
|
||||
bool active_high;
|
||||
bool active_high, resistive;
|
||||
tran_state_t state;
|
||||
};
|
||||
|
||||
|
|
@ -60,9 +60,10 @@ vvp_island_branch_tran::vvp_island_branch_tran(vvp_net_t*en__,
|
|||
bool active_high__,
|
||||
unsigned width__,
|
||||
unsigned part__,
|
||||
unsigned offset__)
|
||||
unsigned offset__,
|
||||
bool resistive__)
|
||||
: en(en__), width(width__), part(part__), offset(offset__),
|
||||
active_high(active_high__)
|
||||
active_high(active_high__), resistive(resistive__)
|
||||
{
|
||||
state = en__ ? tran_disabled : tran_enabled;
|
||||
}
|
||||
|
|
@ -235,7 +236,8 @@ bool vvp_island_branch_tran::run_test_enabled()
|
|||
// input is 'x' or 'z'. We use the rules that are given for MOS switches.
|
||||
inline vvp_vector8_t resolve_ambiguous(const vvp_vector8_t&a,
|
||||
const vvp_vector8_t&b,
|
||||
tran_state_t state)
|
||||
tran_state_t state,
|
||||
unsigned str_map[8])
|
||||
{
|
||||
assert(a.size() == b.size());
|
||||
vvp_vector8_t out (a.size());
|
||||
|
|
@ -243,6 +245,9 @@ inline vvp_vector8_t resolve_ambiguous(const vvp_vector8_t&a,
|
|||
for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
|
||||
vvp_scalar_t a_bit = a.value(idx);
|
||||
vvp_scalar_t b_bit = b.value(idx);
|
||||
b_bit = vvp_scalar_t(b_bit.value(),
|
||||
str_map[b_bit.strength0()],
|
||||
str_map[b_bit.strength1()]);
|
||||
if (state == tran_unknown) {
|
||||
switch (b_bit.value()) {
|
||||
case BIT4_0:
|
||||
|
|
@ -293,8 +298,8 @@ static void push_value_through_branch(const vvp_vector8_t&val,
|
|||
// previously collected (and resolved) for the port.
|
||||
if (branch->width == 0) {
|
||||
// There are no part selects.
|
||||
dst_port->value = resolve_ambiguous(dst_port->value, val,
|
||||
branch->state);
|
||||
dst_port->value = resolve_ambiguous(dst_port->value, val, branch->state,
|
||||
vvp_switch_strength_map[branch->resistive]);
|
||||
|
||||
} else if (dst_ab == 1) {
|
||||
// The other side is a strict subset (part select)
|
||||
|
|
@ -413,7 +418,7 @@ void compile_island_tranif(int sense, char*island, char*pa, char*pb, char*pe)
|
|||
vvp_island_branch_tran*br = new vvp_island_branch_tran(en,
|
||||
sense ? true :
|
||||
false,
|
||||
0, 0, 0);
|
||||
0, 0, 0, false);
|
||||
|
||||
use_island->add_branch(br, pa, pb);
|
||||
|
||||
|
|
@ -430,7 +435,7 @@ void compile_island_tranvp(char*island, char*pa, char*pb,
|
|||
free(island);
|
||||
|
||||
vvp_island_branch_tran*br = new vvp_island_branch_tran(NULL, false,
|
||||
wid, par, off);
|
||||
wid, par, off, false);
|
||||
|
||||
use_island->add_branch(br, pa, pb);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2017 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
|
||||
|
|
@ -334,7 +334,7 @@ void destroy_lexor()
|
|||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
32
vvp/npmos.cc
32
vvp/npmos.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2005-2018 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
|
||||
|
|
@ -19,9 +19,10 @@
|
|||
|
||||
# include "npmos.h"
|
||||
|
||||
vvp_fun_pmos_::vvp_fun_pmos_(bool enable_invert)
|
||||
vvp_fun_pmos_::vvp_fun_pmos_(bool enable_invert, bool resistive)
|
||||
{
|
||||
inv_en_ = enable_invert;
|
||||
resistive_ = resistive;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -58,12 +59,18 @@ void vvp_fun_pmos_::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
|
|||
|
||||
void vvp_fun_pmos_::generate_output_(vvp_net_ptr_t ptr)
|
||||
{
|
||||
const unsigned*strength_map = vvp_switch_strength_map[resistive_];
|
||||
|
||||
vvp_vector8_t out (bit_.size());
|
||||
|
||||
for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
|
||||
vvp_bit4_t b_en = en_.value(idx);
|
||||
vvp_scalar_t b_bit = bit_.value(idx);
|
||||
|
||||
b_bit = vvp_scalar_t(b_bit.value(),
|
||||
strength_map[b_bit.strength0()],
|
||||
strength_map[b_bit.strength1()]);
|
||||
|
||||
switch (b_en) {
|
||||
case BIT4_0:
|
||||
out.set_bit(idx, b_bit);
|
||||
|
|
@ -93,7 +100,7 @@ void vvp_fun_pmos_::generate_output_(vvp_net_ptr_t ptr)
|
|||
|
||||
|
||||
vvp_fun_pmos::vvp_fun_pmos(bool enable_invert)
|
||||
: vvp_fun_pmos_(enable_invert)
|
||||
: vvp_fun_pmos_(enable_invert, false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +119,7 @@ void vvp_fun_pmos::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
|||
}
|
||||
|
||||
vvp_fun_rpmos::vvp_fun_rpmos(bool enable_invert)
|
||||
: vvp_fun_pmos_(enable_invert)
|
||||
: vvp_fun_pmos_(enable_invert, true)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +133,7 @@ void vvp_fun_rpmos::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
|||
if (ptr.port() != 0)
|
||||
return;
|
||||
|
||||
bit_ = resistive_reduction(bit);
|
||||
bit_ = bit;
|
||||
generate_output_(ptr);
|
||||
}
|
||||
|
||||
|
|
@ -135,8 +142,9 @@ void vvp_fun_rpmos::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
|||
* CMOS primitive.
|
||||
*/
|
||||
|
||||
vvp_fun_cmos_::vvp_fun_cmos_()
|
||||
vvp_fun_cmos_::vvp_fun_cmos_(bool resistive)
|
||||
{
|
||||
resistive_ = resistive;
|
||||
}
|
||||
|
||||
void vvp_fun_cmos_::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t &bit,
|
||||
|
|
@ -175,6 +183,8 @@ void vvp_fun_cmos_::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
|
|||
|
||||
void vvp_fun_cmos_::generate_output_(vvp_net_ptr_t ptr)
|
||||
{
|
||||
const unsigned*strength_map = vvp_switch_strength_map[resistive_];
|
||||
|
||||
vvp_vector8_t out (bit_.size());
|
||||
|
||||
for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
|
||||
|
|
@ -182,6 +192,10 @@ void vvp_fun_cmos_::generate_output_(vvp_net_ptr_t ptr)
|
|||
vvp_bit4_t b_p_en = p_en_.value(idx);
|
||||
vvp_scalar_t b_bit = bit_.value(idx);
|
||||
|
||||
b_bit = vvp_scalar_t(b_bit.value(),
|
||||
strength_map[b_bit.strength0()],
|
||||
strength_map[b_bit.strength1()]);
|
||||
|
||||
if (b_n_en == BIT4_1 || b_p_en == BIT4_0) {
|
||||
out.set_bit(idx, b_bit);
|
||||
} else if (b_n_en == BIT4_0 && b_p_en == BIT4_1) {
|
||||
|
|
@ -206,7 +220,7 @@ void vvp_fun_cmos_::generate_output_(vvp_net_ptr_t ptr)
|
|||
}
|
||||
|
||||
vvp_fun_cmos::vvp_fun_cmos()
|
||||
: vvp_fun_cmos_()
|
||||
: vvp_fun_cmos_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +239,7 @@ void vvp_fun_cmos::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
|||
}
|
||||
|
||||
vvp_fun_rcmos::vvp_fun_rcmos()
|
||||
: vvp_fun_cmos_()
|
||||
: vvp_fun_cmos_(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -239,6 +253,6 @@ void vvp_fun_rcmos::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
|||
if (ptr.port() != 0)
|
||||
return;
|
||||
|
||||
bit_ = resistive_reduction(bit);
|
||||
bit_ = bit;
|
||||
generate_output_(ptr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_npmos_H
|
||||
#define IVL_npmos_H
|
||||
/*
|
||||
* Copyright (c) 2005-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2005-2018 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
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
class vvp_fun_pmos_ : public vvp_net_fun_t {
|
||||
|
||||
public:
|
||||
explicit vvp_fun_pmos_(bool enable_invert);
|
||||
explicit vvp_fun_pmos_(bool enable_invert, bool resistive);
|
||||
|
||||
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||
vvp_context_t);
|
||||
|
|
@ -62,7 +62,7 @@ class vvp_fun_pmos_ : public vvp_net_fun_t {
|
|||
|
||||
vvp_vector8_t bit_;
|
||||
vvp_vector4_t en_;
|
||||
bool inv_en_;
|
||||
bool inv_en_, resistive_;
|
||||
};
|
||||
|
||||
class vvp_fun_pmos : public vvp_fun_pmos_ {
|
||||
|
|
@ -109,7 +109,7 @@ class vvp_fun_rpmos : public vvp_fun_pmos_ {
|
|||
|
||||
class vvp_fun_cmos_ : public vvp_net_fun_t {
|
||||
public:
|
||||
explicit vvp_fun_cmos_();
|
||||
explicit vvp_fun_cmos_(bool resistive);
|
||||
|
||||
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t &bit,
|
||||
vvp_context_t);
|
||||
|
|
@ -126,6 +126,7 @@ class vvp_fun_cmos_ : public vvp_net_fun_t {
|
|||
vvp_vector8_t bit_;
|
||||
vvp_vector4_t n_en_;
|
||||
vvp_vector4_t p_en_;
|
||||
bool resistive_;
|
||||
};
|
||||
|
||||
class vvp_fun_cmos : public vvp_fun_cmos_ {
|
||||
|
|
|
|||
|
|
@ -648,78 +648,42 @@ static void schedule_event_(struct event_s*cur, vvp_time64_t delay,
|
|||
receive the event at hand. Put the event in to the
|
||||
appropriate list for the kind of assign we have at hand. */
|
||||
|
||||
switch (select_queue) {
|
||||
struct event_s** q = 0;
|
||||
|
||||
switch (select_queue) {
|
||||
case SEQ_START:
|
||||
if (ctim->start == 0) {
|
||||
ctim->start = cur;
|
||||
} else {
|
||||
cur->next = ctim->active->next;
|
||||
ctim->active->next = cur;
|
||||
ctim->active = cur;
|
||||
}
|
||||
q = &ctim->start;
|
||||
break;
|
||||
|
||||
case SEQ_ACTIVE:
|
||||
if (ctim->active == 0) {
|
||||
ctim->active = cur;
|
||||
|
||||
} else {
|
||||
/* Put the cur event on the end of the active list. */
|
||||
cur->next = ctim->active->next;
|
||||
ctim->active->next = cur;
|
||||
ctim->active = cur;
|
||||
}
|
||||
q = &ctim->active;
|
||||
break;
|
||||
|
||||
case SEQ_NBASSIGN:
|
||||
if (ctim->nbassign == 0) {
|
||||
ctim->nbassign = cur;
|
||||
|
||||
} else {
|
||||
/* Put the cur event on the end of the active list. */
|
||||
cur->next = ctim->nbassign->next;
|
||||
ctim->nbassign->next = cur;
|
||||
ctim->nbassign = cur;
|
||||
}
|
||||
q = &ctim->nbassign;
|
||||
break;
|
||||
|
||||
case SEQ_RWSYNC:
|
||||
if (ctim->rwsync == 0) {
|
||||
ctim->rwsync = cur;
|
||||
|
||||
} else {
|
||||
/* Put the cur event on the end of the active list. */
|
||||
cur->next = ctim->rwsync->next;
|
||||
ctim->rwsync->next = cur;
|
||||
ctim->rwsync = cur;
|
||||
}
|
||||
q = &ctim->rwsync;
|
||||
break;
|
||||
|
||||
case SEQ_ROSYNC:
|
||||
if (ctim->rosync == 0) {
|
||||
ctim->rosync = cur;
|
||||
|
||||
} else {
|
||||
/* Put the cur event on the end of the active list. */
|
||||
cur->next = ctim->rosync->next;
|
||||
ctim->rosync->next = cur;
|
||||
ctim->rosync = cur;
|
||||
}
|
||||
q = &ctim->rosync;
|
||||
break;
|
||||
|
||||
case DEL_THREAD:
|
||||
if (ctim->del_thr == 0) {
|
||||
ctim->del_thr = cur;
|
||||
|
||||
} else {
|
||||
/* Put the cur event on the end of the active list. */
|
||||
cur->next = ctim->del_thr->next;
|
||||
ctim->del_thr->next = cur;
|
||||
ctim->del_thr = cur;
|
||||
}
|
||||
q = &ctim->del_thr;
|
||||
break;
|
||||
}
|
||||
|
||||
if (q) {
|
||||
if (*q) {
|
||||
/* Put the cur event on the end of the queue. */
|
||||
cur->next = (*q)->next;
|
||||
(*q)->next = cur;
|
||||
}
|
||||
*q = cur;
|
||||
}
|
||||
}
|
||||
|
||||
static void schedule_event_push_(struct event_s*cur)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2018 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
|
||||
|
|
@ -780,6 +780,15 @@ void vvp_signal_value::get_signal_value(struct t_vpi_value*vp)
|
|||
}
|
||||
}
|
||||
|
||||
static double vlg_round(double rval)
|
||||
{
|
||||
if (rval >= 0.0) {
|
||||
return floor(rval + 0.5);
|
||||
} else {
|
||||
return ceil(rval - 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
static void real_signal_value(struct t_vpi_value*vp, double rval)
|
||||
{
|
||||
char*rbuf = (char *) need_result_buf(64 + 1, RBUF_VAL);
|
||||
|
|
@ -797,31 +806,26 @@ static void real_signal_value(struct t_vpi_value*vp, double rval)
|
|||
if (rval != rval || (rval && (rval == 0.5*rval))) {
|
||||
rval = 0.0;
|
||||
} else {
|
||||
if (rval >= 0.0) rval = floor(rval + 0.5);
|
||||
else rval = ceil(rval - 0.5);
|
||||
rval = vlg_round(rval);
|
||||
}
|
||||
vp->value.integer = (PLI_INT32)rval;
|
||||
break;
|
||||
|
||||
case vpiDecStrVal:
|
||||
#if !defined(__GNUC__)
|
||||
if (isnan(rval))
|
||||
sprintf(rbuf, "%s", "nan");
|
||||
else
|
||||
sprintf(rbuf, "%0.0f", rval);
|
||||
#else
|
||||
sprintf(rbuf, "%0.0f", rval);
|
||||
#endif
|
||||
if (isnan(rval))
|
||||
sprintf(rbuf, "%s", "nan");
|
||||
else
|
||||
sprintf(rbuf, "%0.0f", vlg_round(rval));
|
||||
vp->value.str = rbuf;
|
||||
break;
|
||||
|
||||
case vpiHexStrVal:
|
||||
sprintf(rbuf, "%lx", (long)rval);
|
||||
sprintf(rbuf, "%lx", (long)vlg_round(rval));
|
||||
vp->value.str = rbuf;
|
||||
break;
|
||||
|
||||
case vpiBinStrVal: {
|
||||
unsigned long val = (unsigned long)rval;
|
||||
unsigned long val = (unsigned long)vlg_round(rval);
|
||||
unsigned len = 0;
|
||||
|
||||
while (val > 0) {
|
||||
|
|
@ -829,7 +833,7 @@ static void real_signal_value(struct t_vpi_value*vp, double rval)
|
|||
val /= 2;
|
||||
}
|
||||
|
||||
val = (unsigned long)rval;
|
||||
val = (unsigned long)vlg_round(rval);
|
||||
for (unsigned idx = 0 ; idx < len ; idx += 1) {
|
||||
rbuf[len-idx-1] = (val & 1)? '1' : '0';
|
||||
val /= 2;
|
||||
|
|
|
|||
|
|
@ -339,7 +339,8 @@ extern vpiHandle vpip_make_int4(const char*name, int msb, int lsb,
|
|||
vvp_net_t*vec);
|
||||
extern vpiHandle vpip_make_var4(const char*name, int msb, int lsb,
|
||||
bool signed_flag, vvp_net_t*net);
|
||||
extern vpiHandle vpip_make_net4(const char*name, int msb, int lsb,
|
||||
extern vpiHandle vpip_make_net4(__vpiScope*scope,
|
||||
const char*name, int msb, int lsb,
|
||||
bool signed_flag, vvp_net_t*node);
|
||||
|
||||
/*
|
||||
|
|
@ -506,7 +507,9 @@ struct __vpiRealVar : public __vpiHandle {
|
|||
};
|
||||
|
||||
extern struct __vpiScope* vpip_scope(__vpiRealVar*sig);
|
||||
extern vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net, bool is_wire);
|
||||
extern vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net);
|
||||
extern vpiHandle vpip_make_real_net(__vpiScope*scope,
|
||||
const char*name, vvp_net_t*net);
|
||||
|
||||
class __vpiBaseVar : public __vpiHandle {
|
||||
|
||||
|
|
|
|||
|
|
@ -178,7 +178,8 @@ vpiHandle __vpiRealVar::vpi_handle(int code)
|
|||
vpiHandle __vpiRealVar::vpi_iterate(int code)
|
||||
{ return real_var_iterate(code, this); }
|
||||
|
||||
vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net, bool is_wire)
|
||||
static vpiHandle vpip_make_real_(__vpiScope*scope, const char*name,
|
||||
vvp_net_t*net, bool is_wire)
|
||||
{
|
||||
struct __vpiRealVar*obj = new __vpiRealVar;
|
||||
|
||||
|
|
@ -187,11 +188,22 @@ vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net, bool is_wire)
|
|||
obj->is_wire = is_wire;
|
||||
obj->net = net;
|
||||
|
||||
obj->within.scope = vpip_peek_current_scope();
|
||||
obj->within.scope = scope;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net)
|
||||
{
|
||||
return vpip_make_real_(vpip_peek_current_scope(), name, net, false);
|
||||
}
|
||||
|
||||
vpiHandle vpip_make_real_net(__vpiScope*scope,
|
||||
const char*name, vvp_net_t*net)
|
||||
{
|
||||
return vpip_make_real_(scope, name, net, true);
|
||||
}
|
||||
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
void real_delete(vpiHandle item)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -132,9 +132,19 @@ char *generic_get_str(int code, vpiHandle ref, const char *name, const char *ind
|
|||
return res;
|
||||
}
|
||||
|
||||
static vpiHandle fill_in_net4(struct __vpiSignal*obj,
|
||||
const char*name, int msb, int lsb,
|
||||
bool signed_flag, vvp_net_t*node);
|
||||
static vpiHandle fill_in_net4(struct __vpiSignal*obj, __vpiScope*scope,
|
||||
const char*name, int msb, int lsb,
|
||||
bool signed_flag, vvp_net_t*node);
|
||||
|
||||
static vpiHandle fill_in_var4(struct __vpiSignal*obj,
|
||||
const char*name, int msb, int lsb,
|
||||
bool signed_flag, vvp_net_t*node)
|
||||
{
|
||||
// Variable declarations are always resolved immediately,
|
||||
// so we can assume they belong in the current scope.
|
||||
return fill_in_net4(obj, vpip_peek_current_scope(),
|
||||
name, msb, lsb, signed_flag, node);
|
||||
}
|
||||
|
||||
/*
|
||||
* The standard formatting/conversion routines.
|
||||
|
|
@ -972,7 +982,7 @@ struct signal_longint : public __vpiSignal {
|
|||
vpiHandle vpip_make_int4(const char*name, int msb, int lsb, vvp_net_t*vec)
|
||||
{
|
||||
__vpiSignal*obj = new signal_integer;
|
||||
return fill_in_net4(obj, name, msb, lsb, true, vec);
|
||||
return fill_in_var4(obj, name, msb, lsb, true, vec);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1011,7 +1021,7 @@ vpiHandle vpip_make_int2(const char*name, int msb, int lsb, bool signed_flag,
|
|||
}
|
||||
}
|
||||
|
||||
return fill_in_net4(obj, name, msb, lsb, signed_flag, vec);
|
||||
return fill_in_var4(obj, name, msb, lsb, signed_flag, vec);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1021,7 +1031,7 @@ vpiHandle vpip_make_var4(const char*name, int msb, int lsb,
|
|||
bool signed_flag, vvp_net_t*vec)
|
||||
{
|
||||
__vpiSignal*obj = new signal_reg;
|
||||
return fill_in_net4(obj, name, msb, lsb, signed_flag, vec);
|
||||
return fill_in_var4(obj, name, msb, lsb, signed_flag, vec);
|
||||
}
|
||||
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
|
|
@ -1116,7 +1126,7 @@ void signal_pool_delete()
|
|||
* The name is the PLI name for the object. If it is an array it is
|
||||
* <name>[<index>].
|
||||
*/
|
||||
static vpiHandle fill_in_net4(struct __vpiSignal*obj,
|
||||
static vpiHandle fill_in_net4(struct __vpiSignal*obj, __vpiScope*scope,
|
||||
const char*name, int msb, int lsb,
|
||||
bool signed_flag, vvp_net_t*node)
|
||||
{
|
||||
|
|
@ -1130,18 +1140,19 @@ static vpiHandle fill_in_net4(struct __vpiSignal*obj,
|
|||
// Place this object within a scope. If this object is
|
||||
// attached to an array, then this value will be replaced with
|
||||
// the handle to the parent.
|
||||
obj->within.scope = vpip_peek_current_scope();
|
||||
obj->within.scope = scope;
|
||||
|
||||
count_vpi_nets += 1;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
vpiHandle vpip_make_net4(const char*name, int msb, int lsb,
|
||||
vpiHandle vpip_make_net4(__vpiScope*scope,
|
||||
const char*name, int msb, int lsb,
|
||||
bool signed_flag, vvp_net_t*node)
|
||||
{
|
||||
struct __vpiSignal*obj = new signal_net;
|
||||
return fill_in_net4(obj, name, msb, lsb, signed_flag, node);
|
||||
return fill_in_net4(obj, scope, name, msb, lsb, signed_flag, node);
|
||||
}
|
||||
|
||||
static int PV_get_base(struct __vpiPV*rfp)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -80,6 +80,15 @@ static int vthr_word_get(int code, vpiHandle ref)
|
|||
}
|
||||
}
|
||||
|
||||
static double vlg_round(double rval)
|
||||
{
|
||||
if (rval >= 0.0) {
|
||||
return floor(rval + 0.5);
|
||||
} else {
|
||||
return ceil(rval - 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||
{
|
||||
struct __vpiVThrWord*obj = dynamic_cast<__vpiVThrWord*>(ref);
|
||||
|
|
@ -108,31 +117,31 @@ static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp)
|
|||
if (val != val || (val && (val == 0.5*val))) {
|
||||
val = 0.0;
|
||||
} else {
|
||||
if (val >= 0.0) val = floor(val + 0.5);
|
||||
else val = ceil(val - 0.5);
|
||||
val = vlg_round(val);
|
||||
}
|
||||
vp->value.integer = (PLI_INT32)val;
|
||||
break;
|
||||
|
||||
case vpiDecStrVal:
|
||||
#if !defined(__GNUC__)
|
||||
if (isnan(val))
|
||||
sprintf(rbuf, "%s", "nan");
|
||||
else
|
||||
sprintf(rbuf, "%0.0f", val);
|
||||
#else
|
||||
sprintf(rbuf, "%0.0f", val);
|
||||
#endif
|
||||
if (isnan(val))
|
||||
sprintf(rbuf, "%s", "nan");
|
||||
else
|
||||
sprintf(rbuf, "%0.0f", vlg_round(val));
|
||||
vp->value.str = rbuf;
|
||||
break;
|
||||
|
||||
case vpiOctStrVal:
|
||||
sprintf(rbuf, "%lo", (long)vlg_round(val));
|
||||
vp->value.str = rbuf;
|
||||
break;
|
||||
|
||||
case vpiHexStrVal:
|
||||
sprintf(rbuf, "%lx", (long)val);
|
||||
sprintf(rbuf, "%lx", (long)vlg_round(val));
|
||||
vp->value.str = rbuf;
|
||||
break;
|
||||
|
||||
case vpiBinStrVal: {
|
||||
unsigned long vali = (unsigned long)val;
|
||||
unsigned long vali = (unsigned long)vlg_round(val);
|
||||
unsigned len = 0;
|
||||
|
||||
while (vali > 0) {
|
||||
|
|
@ -140,7 +149,7 @@ static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp)
|
|||
vali /= 2;
|
||||
}
|
||||
|
||||
vali = (unsigned long)val;
|
||||
vali = (unsigned long)vlg_round(val);
|
||||
for (unsigned idx = 0 ; idx < len ; idx += 1) {
|
||||
rbuf[len-idx-1] = (vali & 1)? '1' : '0';
|
||||
vali /= 2;
|
||||
|
|
@ -279,6 +288,7 @@ class __vpiVThrVec4Stack : public __vpiHandle {
|
|||
void vpi_get_value_int_ (p_vpi_value vp, const vvp_vector4_t&val);
|
||||
void vpi_get_value_real_ (p_vpi_value vp, const vvp_vector4_t&val);
|
||||
void vpi_get_value_strength_(p_vpi_value vp, const vvp_vector4_t&val);
|
||||
void vpi_get_value_octstr_(p_vpi_value vp, const vvp_vector4_t&val);
|
||||
void vpi_get_value_hexstr_(p_vpi_value vp, const vvp_vector4_t&val);
|
||||
void vpi_get_value_vector_(p_vpi_value vp, const vvp_vector4_t&val);
|
||||
private:
|
||||
|
|
@ -346,6 +356,9 @@ void __vpiVThrVec4Stack::vpi_get_value(p_vpi_value vp)
|
|||
case vpiDecStrVal:
|
||||
vpi_get_value_decstr_(vp, val);
|
||||
break;
|
||||
case vpiOctStrVal:
|
||||
vpi_get_value_octstr_(vp, val);
|
||||
break;
|
||||
case vpiHexStrVal:
|
||||
vpi_get_value_hexstr_(vp, val);
|
||||
break;
|
||||
|
|
@ -396,6 +409,48 @@ void __vpiVThrVec4Stack::vpi_get_value_decstr_(p_vpi_value vp, const vvp_vector4
|
|||
vp->value.str = rbuf;
|
||||
}
|
||||
|
||||
void __vpiVThrVec4Stack::vpi_get_value_octstr_(p_vpi_value vp, const vvp_vector4_t&val)
|
||||
{
|
||||
unsigned wid = val.size();
|
||||
unsigned owid = (wid + 2) / 3;
|
||||
char*rbuf = (char*) need_result_buf(owid+1, RBUF_VAL);
|
||||
rbuf[owid] = 0;
|
||||
|
||||
unsigned oval = 0;
|
||||
for (unsigned idx = 0; idx < wid ; idx += 1) {
|
||||
unsigned tmp = 0;
|
||||
switch (val.value(idx)) {
|
||||
case BIT4_0:
|
||||
tmp = 0;
|
||||
break;
|
||||
case BIT4_1:
|
||||
tmp = 1;
|
||||
break;
|
||||
case BIT4_X:
|
||||
tmp = 2;
|
||||
break;
|
||||
case BIT4_Z:
|
||||
tmp = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
oval = oval | (tmp << 2*(idx%3));
|
||||
|
||||
if (idx%3 == 2) {
|
||||
owid -= 1;
|
||||
rbuf[owid] = oct_digits[oval];
|
||||
oval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (owid > 0) {
|
||||
owid -= 1;
|
||||
rbuf[owid] = oct_digits[oval];
|
||||
oval = 0;
|
||||
}
|
||||
vp->value.str = rbuf;
|
||||
}
|
||||
|
||||
void __vpiVThrVec4Stack::vpi_get_value_hexstr_(p_vpi_value vp, const vvp_vector4_t&val)
|
||||
{
|
||||
unsigned wid = val.size();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2018 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
|
||||
|
|
@ -2200,7 +2200,7 @@ static bool do_disable(vthread_t thr, vthread_t match)
|
|||
}
|
||||
|
||||
vthread_t parent = thr->parent;
|
||||
if (parent && parent->i_am_joining) {
|
||||
if (parent && parent->i_am_joining && test_joinable(parent, thr)) {
|
||||
// If a parent is waiting in a %join, wake it up. Note
|
||||
// that it is possible to be waiting in a %join yet
|
||||
// already scheduled if multiple child threads are
|
||||
|
|
@ -2210,8 +2210,7 @@ static bool do_disable(vthread_t thr, vthread_t match)
|
|||
if (! parent->i_have_ended)
|
||||
schedule_vthread(parent, 0, true);
|
||||
|
||||
// Let the parent do the reaping.
|
||||
vthread_reap(thr);
|
||||
do_join(parent, thr);
|
||||
|
||||
} else if (parent) {
|
||||
/* If the parent is yet to %join me, let its %join
|
||||
|
|
@ -2518,6 +2517,10 @@ bool of_DIV_S(vthread_t thr, vvp_code_t)
|
|||
if (bp[0] == 0) {
|
||||
vvp_vector4_t tmp(wid, BIT4_X);
|
||||
vala = tmp;
|
||||
} else if (((long)ap[0] == LONG_MIN) && ((long)bp[0] == -1)) {
|
||||
vvp_vector4_t tmp(wid, BIT4_0);
|
||||
tmp.set_bit(wid-1, BIT4_1);
|
||||
vala = tmp;
|
||||
} else {
|
||||
long tmpa = (long) ap[0];
|
||||
long tmpb = (long) bp[0];
|
||||
|
|
@ -2614,7 +2617,7 @@ bool of_END(vthread_t thr, vvp_code_t)
|
|||
/* If I have a parent who is waiting for me, then mark that I
|
||||
have ended, and schedule that parent. Also, finish the
|
||||
%join for the parent. */
|
||||
if (thr->parent && thr->parent->i_am_joining) {
|
||||
if (!thr->i_am_detached && thr->parent && thr->parent->i_am_joining) {
|
||||
vthread_t tmp = thr->parent;
|
||||
assert(! thr->i_am_detached);
|
||||
|
||||
|
|
@ -3768,6 +3771,9 @@ bool of_MOD_S(vthread_t thr, vvp_code_t)
|
|||
if (rv == 0)
|
||||
goto x_out;
|
||||
|
||||
if ((lv == LONG_LONG_MIN) && (rv == -1))
|
||||
goto zero_out;
|
||||
|
||||
/* Sign extend the signed operands when needed. */
|
||||
if (wid < 8*sizeof(long long)) {
|
||||
if (lv & (1LL << (wid-1)))
|
||||
|
|
@ -3799,6 +3805,9 @@ bool of_MOD_S(vthread_t thr, vvp_code_t)
|
|||
x_out:
|
||||
vala = vvp_vector4_t(wid, BIT4_X);
|
||||
return true;
|
||||
zero_out:
|
||||
vala = vvp_vector4_t(wid, BIT4_0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -67,6 +67,11 @@ void vvp_darray::get_word(unsigned, vvp_object_t&)
|
|||
cerr << "XXXX get_word(vvp_object_t) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_darray::shallow_copy(const vvp_object*)
|
||||
{
|
||||
cerr << "XXXX shallow_copy(vvp_object_t) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
template <class TYPE> vvp_darray_atom<TYPE>::~vvp_darray_atom()
|
||||
{
|
||||
}
|
||||
|
|
@ -101,6 +106,16 @@ template <class TYPE> void vvp_darray_atom<TYPE>::get_word(unsigned adr, vvp_vec
|
|||
value = tmp;
|
||||
}
|
||||
|
||||
template <class TYPE> void vvp_darray_atom<TYPE>::shallow_copy(const vvp_object*obj)
|
||||
{
|
||||
const vvp_darray_atom<TYPE>*that = dynamic_cast<const vvp_darray_atom<TYPE>*>(obj);
|
||||
assert(that);
|
||||
|
||||
unsigned num_items = min(array_.size(), that->array_.size());
|
||||
for (unsigned idx = 0 ; idx < num_items ; idx += 1)
|
||||
array_[idx] = that->array_[idx];
|
||||
}
|
||||
|
||||
template class vvp_darray_atom<uint8_t>;
|
||||
template class vvp_darray_atom<uint16_t>;
|
||||
template class vvp_darray_atom<uint32_t>;
|
||||
|
|
@ -140,6 +155,16 @@ void vvp_darray_vec4::get_word(unsigned adr, vvp_vector4_t&value)
|
|||
assert(value.size() == word_wid_);
|
||||
}
|
||||
|
||||
void vvp_darray_vec4::shallow_copy(const vvp_object*obj)
|
||||
{
|
||||
const vvp_darray_vec4*that = dynamic_cast<const vvp_darray_vec4*>(obj);
|
||||
assert(that);
|
||||
|
||||
unsigned num_items = min(array_.size(), that->array_.size());
|
||||
for (unsigned idx = 0 ; idx < num_items ; idx += 1)
|
||||
array_[idx] = that->array_[idx];
|
||||
}
|
||||
|
||||
vvp_darray_vec2::~vvp_darray_vec2()
|
||||
{
|
||||
}
|
||||
|
|
@ -173,6 +198,15 @@ void vvp_darray_vec2::get_word(unsigned adr, vvp_vector4_t&value)
|
|||
}
|
||||
}
|
||||
|
||||
void vvp_darray_vec2::shallow_copy(const vvp_object*obj)
|
||||
{
|
||||
const vvp_darray_vec2*that = dynamic_cast<const vvp_darray_vec2*>(obj);
|
||||
assert(that);
|
||||
|
||||
unsigned num_items = min(array_.size(), that->array_.size());
|
||||
for (unsigned idx = 0 ; idx < num_items ; idx += 1)
|
||||
array_[idx] = that->array_[idx];
|
||||
}
|
||||
|
||||
vvp_darray_object::~vvp_darray_object()
|
||||
{
|
||||
|
|
@ -200,6 +234,16 @@ void vvp_darray_object::get_word(unsigned adr, vvp_object_t&value)
|
|||
value = array_[adr];
|
||||
}
|
||||
|
||||
void vvp_darray_object::shallow_copy(const vvp_object*obj)
|
||||
{
|
||||
const vvp_darray_object*that = dynamic_cast<const vvp_darray_object*>(obj);
|
||||
assert(that);
|
||||
|
||||
unsigned num_items = min(array_.size(), that->array_.size());
|
||||
for (unsigned idx = 0 ; idx < num_items ; idx += 1)
|
||||
array_[idx] = that->array_[idx];
|
||||
}
|
||||
|
||||
vvp_darray_real::~vvp_darray_real()
|
||||
{
|
||||
}
|
||||
|
|
@ -226,6 +270,16 @@ void vvp_darray_real::get_word(unsigned adr, double&value)
|
|||
value = array_[adr];
|
||||
}
|
||||
|
||||
void vvp_darray_real::shallow_copy(const vvp_object*obj)
|
||||
{
|
||||
const vvp_darray_real*that = dynamic_cast<const vvp_darray_real*>(obj);
|
||||
assert(that);
|
||||
|
||||
unsigned num_items = min(array_.size(), that->array_.size());
|
||||
for (unsigned idx = 0 ; idx < num_items ; idx += 1)
|
||||
array_[idx] = that->array_[idx];
|
||||
}
|
||||
|
||||
vvp_darray_string::~vvp_darray_string()
|
||||
{
|
||||
}
|
||||
|
|
@ -252,6 +306,16 @@ void vvp_darray_string::get_word(unsigned adr, string&value)
|
|||
value = array_[adr];
|
||||
}
|
||||
|
||||
void vvp_darray_string::shallow_copy(const vvp_object*obj)
|
||||
{
|
||||
const vvp_darray_string*that = dynamic_cast<const vvp_darray_string*>(obj);
|
||||
assert(that);
|
||||
|
||||
unsigned num_items = min(array_.size(), that->array_.size());
|
||||
for (unsigned idx = 0 ; idx < num_items ; idx += 1)
|
||||
array_[idx] = that->array_[idx];
|
||||
}
|
||||
|
||||
vvp_queue::~vvp_queue()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ class vvp_darray : public vvp_object {
|
|||
|
||||
virtual void set_word(unsigned adr, const vvp_object_t&value);
|
||||
virtual void get_word(unsigned adr, vvp_object_t&value);
|
||||
|
||||
virtual void shallow_copy(const vvp_object*obj);
|
||||
};
|
||||
|
||||
template <class TYPE> class vvp_darray_atom : public vvp_darray {
|
||||
|
|
@ -55,6 +57,7 @@ template <class TYPE> class vvp_darray_atom : public vvp_darray {
|
|||
size_t get_size(void) const;
|
||||
void set_word(unsigned adr, const vvp_vector4_t&value);
|
||||
void get_word(unsigned adr, vvp_vector4_t&value);
|
||||
void shallow_copy(const vvp_object*obj);
|
||||
|
||||
private:
|
||||
std::vector<TYPE> array_;
|
||||
|
|
@ -70,6 +73,7 @@ class vvp_darray_vec4 : public vvp_darray {
|
|||
size_t get_size(void) const;
|
||||
void set_word(unsigned adr, const vvp_vector4_t&value);
|
||||
void get_word(unsigned adr, vvp_vector4_t&value);
|
||||
void shallow_copy(const vvp_object*obj);
|
||||
|
||||
private:
|
||||
std::vector<vvp_vector4_t> array_;
|
||||
|
|
@ -86,6 +90,7 @@ class vvp_darray_vec2 : public vvp_darray {
|
|||
size_t get_size(void) const;
|
||||
void set_word(unsigned adr, const vvp_vector4_t&value);
|
||||
void get_word(unsigned adr, vvp_vector4_t&value);
|
||||
void shallow_copy(const vvp_object*obj);
|
||||
|
||||
private:
|
||||
std::vector<vvp_vector2_t> array_;
|
||||
|
|
@ -101,6 +106,7 @@ class vvp_darray_real : public vvp_darray {
|
|||
size_t get_size(void) const;
|
||||
void set_word(unsigned adr, double value);
|
||||
void get_word(unsigned adr, double&value);
|
||||
void shallow_copy(const vvp_object*obj);
|
||||
|
||||
private:
|
||||
std::vector<double> array_;
|
||||
|
|
@ -115,6 +121,7 @@ class vvp_darray_string : public vvp_darray {
|
|||
size_t get_size(void) const;
|
||||
void set_word(unsigned adr, const std::string&value);
|
||||
void get_word(unsigned adr, std::string&value);
|
||||
void shallow_copy(const vvp_object*obj);
|
||||
|
||||
private:
|
||||
std::vector<std::string> array_;
|
||||
|
|
@ -129,6 +136,7 @@ class vvp_darray_object : public vvp_darray {
|
|||
size_t get_size(void) const;
|
||||
void set_word(unsigned adr, const vvp_object_t&value);
|
||||
void get_word(unsigned adr, vvp_object_t&value);
|
||||
void shallow_copy(const vvp_object*obj);
|
||||
|
||||
private:
|
||||
std::vector<vvp_object_t> array_;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2004-2018 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
|
||||
|
|
@ -3421,7 +3421,8 @@ unsigned vvp_wide_fun_core::port_count() const
|
|||
vvp_vector4_t& vvp_wide_fun_core::value(unsigned idx)
|
||||
{
|
||||
assert(idx < nports_);
|
||||
assert(port_values_);
|
||||
if (port_values_ == 0)
|
||||
port_values_ = new vvp_vector4_t [nports_];
|
||||
return port_values_[idx];
|
||||
}
|
||||
|
||||
|
|
@ -3685,31 +3686,28 @@ vvp_scalar_t fully_featured_resolv_(vvp_scalar_t a, vvp_scalar_t b)
|
|||
return res;
|
||||
}
|
||||
|
||||
vvp_vector8_t resistive_reduction(const vvp_vector8_t&that)
|
||||
{
|
||||
static unsigned rstr[8] = {
|
||||
0, /* Hi-Z --> Hi-Z */
|
||||
1, /* Small capacitance --> Small capacitance */
|
||||
1, /* Medium capacitance --> Small capacitance */
|
||||
2, /* Weak drive --> Medium capacitance */
|
||||
2, /* Large capacitance --> Medium capacitance */
|
||||
3, /* Pull drive --> Weak drive */
|
||||
5, /* Strong drive --> Pull drive */
|
||||
5 /* Supply drive --> Pull drive */
|
||||
};
|
||||
|
||||
vvp_vector8_t res (that.size());
|
||||
|
||||
for (unsigned idx = 0 ; idx < res.size() ; idx += 1) {
|
||||
vvp_scalar_t bit = that.value(idx);
|
||||
bit = vvp_scalar_t(bit.value(),
|
||||
rstr[bit.strength0()],
|
||||
rstr[bit.strength1()]);
|
||||
res.set_bit(idx, bit);
|
||||
unsigned vvp_switch_strength_map[2][8] = {
|
||||
{ // non-resistive
|
||||
0, /* High impedance --> High impedance */
|
||||
1, /* Small capacitor --> Small capacitor */
|
||||
2, /* Medium capacitor --> Medium capacitor */
|
||||
3, /* Weak drive --> Weak drive */
|
||||
4, /* Large capacitor --> Large capacitor */
|
||||
5, /* Pull drive --> Pull drive */
|
||||
6, /* Strong drive --> Strong drive */
|
||||
6 /* Supply drive --> Strong drive */
|
||||
},
|
||||
{ // resistive
|
||||
0, /* High impedance --> High impedance */
|
||||
1, /* Small capacitor --> Small capacitor */
|
||||
1, /* Medium capacitor --> Small capacitor */
|
||||
2, /* Weak drive --> Medium capacitor */
|
||||
2, /* Large capacitor --> Medium capacitor */
|
||||
3, /* Pull drive --> Weak drive */
|
||||
5, /* Strong drive --> Pull drive */
|
||||
5 /* Supply drive --> Pull drive */
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
vvp_vector4_t reduce4(const vvp_vector8_t&that)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_vvp_net_H
|
||||
#define IVL_vvp_net_H
|
||||
/*
|
||||
* Copyright (c) 2004-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2004-2018 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
|
||||
|
|
@ -954,9 +954,11 @@ inline vvp_vector8_t resolve(const vvp_vector8_t&a, const vvp_vector8_t&b)
|
|||
return out;
|
||||
}
|
||||
|
||||
/* This function implements the strength reduction implied by
|
||||
Verilog standard resistive devices. */
|
||||
extern vvp_vector8_t resistive_reduction(const vvp_vector8_t&a);
|
||||
/* This lookup tabke implements the strength reduction implied by
|
||||
Verilog standard switch devices. The major dimension selects
|
||||
between non-resistive and resistive devices. */
|
||||
extern unsigned vvp_switch_strength_map[2][8];
|
||||
|
||||
/* The reduce4 function converts a vector8 to a vector4, losing
|
||||
strength information in the process. */
|
||||
extern vvp_vector4_t reduce4(const vvp_vector8_t&that);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ static void __compile_var_real(char*label, char*name,
|
|||
|
||||
define_functor_symbol(label, net);
|
||||
|
||||
vpiHandle obj = vpip_make_real_var(name, net, false);
|
||||
vpiHandle obj = vpip_make_real_var(name, net);
|
||||
compile_vpi_symbol(label, obj);
|
||||
|
||||
if (name) {
|
||||
|
|
@ -350,7 +350,7 @@ static void do_compile_net(vvp_net_t*node, vvp_array_t array,
|
|||
vpiHandle obj = 0;
|
||||
if (! local_flag) {
|
||||
/* Make the vpiHandle for the reg. */
|
||||
obj = vpip_make_net4(name, msb, lsb, signed_flag, node);
|
||||
obj = vpip_make_net4(scope, name, msb, lsb, signed_flag, node);
|
||||
/* This attaches the label to the vpiHandle */
|
||||
compile_vpi_symbol(my_label, obj);
|
||||
}
|
||||
|
|
@ -481,7 +481,7 @@ static void __compile_real_net2(vvp_net_t*node, vvp_array_t array,
|
|||
|
||||
vpiHandle obj = 0;
|
||||
if (!local_flag) {
|
||||
obj = vpip_make_real_var(name, node, true);
|
||||
obj = vpip_make_real_net(scope, name, node);
|
||||
compile_vpi_symbol(my_label, obj);
|
||||
}
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
|
|
|
|||
Loading…
Reference in New Issue