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
|
* 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
|
||||||
|
|
@ -26,11 +26,6 @@
|
||||||
# include "verinum.h"
|
# include "verinum.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
|
|
||||||
bool dly_used_no_timescale = false;
|
|
||||||
bool dly_used_timescale = false;
|
|
||||||
bool display_ts_dly_warning = true;
|
|
||||||
|
|
||||||
|
|
||||||
PDelays::PDelays()
|
PDelays::PDelays()
|
||||||
{
|
{
|
||||||
delete_flag_ = true;
|
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);
|
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||||
|
|
||||||
/* Print a warning if we find default and `timescale based
|
check_for_inconsistent_delays(scope);
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the delay expression is a real constant or vector
|
/* If the delay expression is a real constant or vector
|
||||||
constant, then evaluate it, scale it to the local time
|
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
|
* 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
|
||||||
|
|
@ -252,7 +252,7 @@ void destroy_lexor(void)
|
||||||
{
|
{
|
||||||
# ifdef FLEX_SCANNER
|
# ifdef FLEX_SCANNER
|
||||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
# 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();
|
yylex_destroy();
|
||||||
# endif
|
# endif
|
||||||
# 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)
|
* Copyright CERN 2013 / 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
|
||||||
|
|
@ -1446,6 +1446,13 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
|
||||||
return 0;
|
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) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: "
|
cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: "
|
||||||
<< name << " expression is the argument cast to expr_wid=" << expr_wid << endl;
|
<< 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) {
|
if (net == 0) {
|
||||||
cerr << get_fileline() << ": internal error: "
|
cerr << get_fileline() << ": error: Unable to bind variable `"
|
||||||
<< "Expecting idents with ntype to be signals." << endl;
|
<< path_ << "' in `" << scope_path(use_scope) << "'" << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! ntype->type_compatible(net->net_type())) {
|
if (const netdarray_t*array_type = dynamic_cast<const netdarray_t*> (ntype)) {
|
||||||
cerr << get_fileline() << ": internal_error: "
|
if (array_type->type_compatible(net->net_type())) {
|
||||||
<< "net type doesn't match context type." << endl;
|
NetESignal*tmp = new NetESignal(net);
|
||||||
|
tmp->set_line(*this);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
cerr << get_fileline() << ": : "
|
// Icarus allows a dynamic array to be initialised with a
|
||||||
<< "net type=";
|
// 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())
|
if (net->net_type())
|
||||||
net->net_type()->debug_dump(cerr);
|
net->net_type()->debug_dump(cerr);
|
||||||
else
|
else
|
||||||
cerr << "<nil>";
|
cerr << "<nil>";
|
||||||
cerr << endl;
|
cerr << endl;
|
||||||
|
|
||||||
cerr << get_fileline() << ": : "
|
cerr << get_fileline() << ": : " << "context type=";
|
||||||
<< "context type=";
|
|
||||||
ivl_assert(*this, ntype);
|
ivl_assert(*this, ntype);
|
||||||
ntype->debug_dump(cerr);
|
ntype->debug_dump(cerr);
|
||||||
cerr << endl;
|
cerr << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
ivl_assert(*this, ntype->type_compatible(net->net_type()));
|
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
|
// expression. Elaborate the expression as an element
|
||||||
// type. The run-time will assign this value to each element.
|
// type. The run-time will assign this value to each element.
|
||||||
const netarray_t*array_type = dynamic_cast<const netarray_t*> (ntype);
|
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);
|
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
|
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);
|
const netvector_t*use_type = dynamic_cast<const netvector_t*> (ntype);
|
||||||
if (use_type == 0) {
|
if (use_type == 0) {
|
||||||
cerr << get_fileline() << ": internal error: "
|
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)
|
* Copyright CERN 2013 / 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
|
||||||
|
|
@ -509,8 +509,10 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||||
|
|
||||||
netclass_t*use_base_class = 0;
|
netclass_t*use_base_class = 0;
|
||||||
if (base_class) {
|
if (base_class) {
|
||||||
ivl_assert(*pclass, scope);
|
if (scope)
|
||||||
use_base_class = scope->find_class(base_class->name);
|
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) {
|
if (use_base_class == 0) {
|
||||||
cerr << pclass->get_fileline() << ": error: "
|
cerr << pclass->get_fileline() << ": error: "
|
||||||
<< "Base class " << base_class->name
|
<< "Base class " << base_class->name
|
||||||
|
|
@ -605,13 +607,9 @@ static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||||
|
|
||||||
void elaborate_rootscope_classes(Design*des)
|
void elaborate_rootscope_classes(Design*des)
|
||||||
{
|
{
|
||||||
if (pform_classes.empty())
|
for (size_t idx = 0 ; idx < pform_classes.size() ; idx += 1) {
|
||||||
return;
|
blend_class_constructors(pform_classes[idx]);
|
||||||
|
elaborate_scope_class(des, 0, pform_classes[idx]);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
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);
|
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||||
|
|
||||||
/* Print a warning if we find default and `timescale based
|
check_for_inconsistent_delays(scope);
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the delay expression is a real constant or vector
|
/* If the delay expression is a real constant or vector
|
||||||
constant, then evaluate it, scale it to the local time
|
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();
|
ndelays = delays.size();
|
||||||
if (ndelays > 12) ndelays = 12;
|
if (ndelays > 12) ndelays = 12;
|
||||||
|
|
||||||
/* Print a warning if we find default and `timescale based
|
check_for_inconsistent_delays(scope);
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Elaborate the delay values themselves. Remember to scale
|
/* Elaborate the delay values themselves. Remember to scale
|
||||||
them for the timescale/precision of the scope. */
|
them for the timescale/precision of the scope. */
|
||||||
|
|
|
||||||
|
|
@ -2100,7 +2100,7 @@ void destroy_lexor(void)
|
||||||
{
|
{
|
||||||
# ifdef FLEX_SCANNER
|
# ifdef FLEX_SCANNER
|
||||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
# 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();
|
yylex_destroy();
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
|
||||||
|
|
@ -1606,7 +1606,7 @@ void destroy_lexor()
|
||||||
{
|
{
|
||||||
# ifdef FLEX_SCANNER
|
# ifdef FLEX_SCANNER
|
||||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
# 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();
|
yylex_destroy();
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ static unsigned string_pool_count = 0;
|
||||||
StringHeap::StringHeap()
|
StringHeap::StringHeap()
|
||||||
{
|
{
|
||||||
cell_base_ = 0;
|
cell_base_ = 0;
|
||||||
cell_ptr_ = HEAPCELL;
|
cell_size_ = 0;
|
||||||
cell_count_ = 0;
|
cell_ptr_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringHeap::~StringHeap()
|
StringHeap::~StringHeap()
|
||||||
|
|
@ -45,20 +45,24 @@ StringHeap::~StringHeap()
|
||||||
const char* StringHeap::add(const char*text)
|
const char* StringHeap::add(const char*text)
|
||||||
{
|
{
|
||||||
unsigned len = strlen(text);
|
unsigned len = strlen(text);
|
||||||
assert((len+1) <= HEAPCELL);
|
unsigned rem = cell_size_ - cell_ptr_;
|
||||||
|
|
||||||
unsigned rem = HEAPCELL - cell_ptr_;
|
|
||||||
if (rem < (len+1)) {
|
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
|
#ifdef CHECK_WITH_VALGRIND
|
||||||
string_pool_count += 1;
|
string_pool_count += 1;
|
||||||
string_pool = (char **) realloc(string_pool,
|
string_pool = (char **) realloc(string_pool,
|
||||||
string_pool_count*sizeof(char **));
|
string_pool_count*sizeof(char **));
|
||||||
string_pool[string_pool_count-1] = cell_base_;
|
string_pool[string_pool_count-1] = cell_base_;
|
||||||
#endif
|
#endif
|
||||||
cell_ptr_ = 0;
|
|
||||||
cell_count_ += 1;
|
|
||||||
assert(cell_base_ != 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char*res = cell_base_ + cell_ptr_;
|
char*res = cell_base_ + cell_ptr_;
|
||||||
|
|
@ -66,7 +70,7 @@ const char* StringHeap::add(const char*text)
|
||||||
cell_ptr_ += len;
|
cell_ptr_ += len;
|
||||||
cell_base_[cell_ptr_++] = 0;
|
cell_base_[cell_ptr_++] = 0;
|
||||||
|
|
||||||
assert(cell_ptr_ <= HEAPCELL);
|
assert(cell_ptr_ <= cell_size_);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,11 +78,11 @@ class StringHeap {
|
||||||
perm_string make(const char*);
|
perm_string make(const char*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum { HEAPCELL = 0x10000 };
|
static const unsigned DEFAULT_CELL_SIZE = 0x10000;
|
||||||
|
|
||||||
char*cell_base_;
|
char*cell_base_;
|
||||||
|
unsigned cell_size_;
|
||||||
unsigned cell_ptr_;
|
unsigned cell_ptr_;
|
||||||
unsigned cell_count_;
|
|
||||||
|
|
||||||
private: // not implemented
|
private: // not implemented
|
||||||
StringHeap(const StringHeap&);
|
StringHeap(const StringHeap&);
|
||||||
|
|
|
||||||
7
main.cc
7
main.cc
|
|
@ -1,5 +1,5 @@
|
||||||
const char COPYRIGHT[] =
|
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
|
* 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);
|
pform_dump(out, cur->second);
|
||||||
}
|
}
|
||||||
out << "PFORM DUMP $ROOT CLASSES:" << endl;
|
out << "PFORM DUMP $ROOT CLASSES:" << endl;
|
||||||
for (map<perm_string,PClass*>::iterator cur = pform_classes.begin()
|
for (size_t idx = 0 ; idx < pform_classes.size() ; idx += 1) {
|
||||||
; cur != pform_classes.end() ; ++ cur) {
|
pform_dump(out, pform_classes[idx]);
|
||||||
pform_dump(out, cur->second);
|
|
||||||
}
|
}
|
||||||
out << "PFORM DUMP PACKAGES:" << endl;
|
out << "PFORM DUMP PACKAGES:" << endl;
|
||||||
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
|
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
|
* 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
|
||||||
|
|
@ -165,7 +165,8 @@ bool netclass_t::test_for_missing_initializers() const
|
||||||
NetScope*netclass_t::method_from_name(perm_string name) const
|
NetScope*netclass_t::method_from_name(perm_string name) const
|
||||||
{
|
{
|
||||||
NetScope*task = class_scope_->child( hname_t(name) );
|
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;
|
return task;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
24
netlist.cc
24
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
|
* 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
|
||||||
|
|
@ -2724,13 +2724,28 @@ DelayType NetProc::delay_type() const
|
||||||
|
|
||||||
DelayType NetBlock::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;
|
||||||
|
|
||||||
|
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)) {
|
for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) {
|
||||||
DelayType dt = cur->delay_type();
|
DelayType dt = cur->delay_type();
|
||||||
if (dt > result) result = dt;
|
if (dt > result) result = dt;
|
||||||
if (dt == DEFINITE_DELAY) break;
|
if (dt == DEFINITE_DELAY) break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -2800,9 +2815,10 @@ DelayType NetPDelay::delay_type() const
|
||||||
return DEFINITE_DELAY;
|
return DEFINITE_DELAY;
|
||||||
} else {
|
} else {
|
||||||
if (statement_) {
|
if (statement_) {
|
||||||
return statement_->delay_type();
|
return combine_delays(ZERO_DELAY,
|
||||||
|
statement_->delay_type());
|
||||||
} else {
|
} 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
|
* 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
|
||||||
|
|
@ -1665,3 +1665,38 @@ NetScope* find_method_containing_scope(const LineInfo&, NetScope*scope)
|
||||||
|
|
||||||
return 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
|
#ifndef IVL_netmisc_H
|
||||||
#define 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
|
* 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
|
||||||
|
|
@ -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 };
|
enum const_bool { C_NON, C_0, C_1, C_X };
|
||||||
const_bool const_logical(const NetExpr*expr);
|
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
|
* When scaling a real value to a time we need to do some standard
|
||||||
* processing.
|
* processing.
|
||||||
|
|
@ -409,4 +405,10 @@ extern void assign_unpacked_with_bufz(Design*des, NetScope*scope,
|
||||||
|
|
||||||
extern NetPartSelect* detect_partselect_lval(Link&pin);
|
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 */
|
#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> function_item function_item_list function_item_list_opt
|
||||||
%type <tf_ports> task_item task_item_list task_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_pexpr> modport_simple_port port_name parameter_value_byname
|
||||||
%type <named_pexprs> port_name_list parameter_value_byname_list
|
%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
|
| K_task lifetime_opt IDENTIFIER error K_endtask
|
||||||
{
|
{
|
||||||
assert(current_task == 0);
|
if (current_task) {
|
||||||
|
pform_pop_scope();
|
||||||
|
current_task = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
endlabel_opt
|
endlabel_opt
|
||||||
{ // Last step: check any closing name. This is done late so
|
{ // 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
|
: port_direction_opt data_type_or_implicit IDENTIFIER dimensions_opt tf_port_item_expr_opt
|
||||||
{ vector<pform_tf_port_t>*tmp;
|
{ 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);
|
perm_string name = lex_strings.make($3);
|
||||||
list<perm_string>* ilist = list_from_identifier($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)) {
|
if (($2 == 0) && ($1==NetNet::PIMPLICIT)) {
|
||||||
// Detect special case this is an undecorated
|
// Detect special case this is an undecorated
|
||||||
// identifier and we need to get the declaration from
|
// 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,
|
port_declaration_context.data_type,
|
||||||
ilist);
|
ilist);
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, the decorations for this identifier
|
// Otherwise, the decorations for this identifier
|
||||||
// indicate the type. Save the type for any right
|
// 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 */
|
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;
|
{ vector<pform_tf_port_t>*tmp;
|
||||||
if ($1 && $3) {
|
if ($1 && $3) {
|
||||||
size_t s1 = $1->size();
|
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.");
|
{ yyerror(@2, "error: Syntax error in task/function port declaration.");
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
}
|
}
|
||||||
| tf_port_list ','
|
| tf_port_item_list ','
|
||||||
{ yyerror(@2, "error: NULL port declarations are not allowed.");
|
{ yyerror(@2, "error: NULL port declarations are not allowed.");
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| tf_port_list ';'
|
| tf_port_item_list ';'
|
||||||
{ yyerror(@2, "error: ';' is an invalid port declaration separator.");
|
{ yyerror(@2, "error: ';' is an invalid port declaration separator.");
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_parse_api_H
|
#ifndef IVL_parse_api_H
|
||||||
#define 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
|
* 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
|
||||||
|
|
@ -45,7 +45,7 @@ extern std::map<perm_string,PUdp*> pform_primitives;
|
||||||
extern std::map<perm_string,data_type_t*> pform_typedefs;
|
extern std::map<perm_string,data_type_t*> pform_typedefs;
|
||||||
extern std::set<enum_type_t*> pform_enum_sets;
|
extern std::set<enum_type_t*> pform_enum_sets;
|
||||||
extern std::map<perm_string,PTaskFunc*> pform_tasks;
|
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 std::map<perm_string,PPackage*> pform_packages;
|
||||||
|
|
||||||
extern void pform_dump(std::ostream&out, const PClass*pac);
|
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)
|
* Copyright CERN 2013 / 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
|
||||||
|
|
@ -71,7 +71,7 @@ set<enum_type_t*>pform_enum_sets;
|
||||||
/*
|
/*
|
||||||
* Class definitions in the $root scope go here.
|
* 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.
|
* 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
|
/* If no scope was found then this is being defined in the
|
||||||
* compilation unit scope. */
|
* compilation unit scope. */
|
||||||
if (scopex == 0) {
|
if (scopex == 0) {
|
||||||
pform_classes[name] = class_scope;
|
pform_classes.push_back(class_scope);
|
||||||
lexical_scope = class_scope;
|
lexical_scope = class_scope;
|
||||||
return 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;
|
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;
|
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
|
* 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
|
* 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);
|
yyrestart(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
||||||
|
*/
|
||||||
void destroy_fp_lexor()
|
void destroy_fp_lexor()
|
||||||
{
|
{
|
||||||
# ifdef FLEX_SCANNER
|
# ifdef FLEX_SCANNER
|
||||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
# 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();
|
yylex_destroy();
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ static int eval_darray_new(ivl_expr_t ex)
|
||||||
unsigned idx;
|
unsigned idx;
|
||||||
switch (ivl_type_base(element_type)) {
|
switch (ivl_type_base(element_type)) {
|
||||||
case IVL_VT_BOOL:
|
case IVL_VT_BOOL:
|
||||||
|
case IVL_VT_LOGIC:
|
||||||
for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) {
|
for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) {
|
||||||
draw_eval_vec4(ivl_expr_parm(init_expr,idx));
|
draw_eval_vec4(ivl_expr_parm(init_expr,idx));
|
||||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", 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;
|
errors += 1;
|
||||||
break;
|
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)) {
|
} else if (init_expr && number_is_immediate(size_expr,32,0)) {
|
||||||
/* In this case, there is an init expression, the
|
/* In this case, there is an init expression, the
|
||||||
expression is NOT an array_pattern, and the size
|
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
|
* 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
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
# include "verinum.h"
|
# include "verinum.h"
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
# include <climits>
|
||||||
# include <cmath> // Needed to get pow for as_double().
|
# include <cmath> // Needed to get pow for as_double().
|
||||||
# include <cstdio> // Needed to get snprintf for as_string().
|
# include <cstdio> // Needed to get snprintf for as_string().
|
||||||
# include <algorithm>
|
# include <algorithm>
|
||||||
|
|
@ -1444,7 +1445,8 @@ verinum operator / (const verinum&left, const verinum&right)
|
||||||
if (use_len <= (8*sizeof(long) - 1)) {
|
if (use_len <= (8*sizeof(long) - 1)) {
|
||||||
long l = left.as_long();
|
long l = left.as_long();
|
||||||
long r = right.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) {
|
for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
|
||||||
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
|
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
|
||||||
v >>= 1;
|
v >>= 1;
|
||||||
|
|
@ -1518,7 +1520,8 @@ verinum operator % (const verinum&left, const verinum&right)
|
||||||
/* Use native signed modulus to do the work. */
|
/* Use native signed modulus to do the work. */
|
||||||
long l = left.as_long();
|
long l = left.as_long();
|
||||||
long r = right.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) {
|
for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
|
||||||
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
|
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
|
||||||
v >>= 1;
|
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
|
* 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
|
||||||
|
|
@ -751,7 +751,16 @@ yyscan_t prepare_lexor(FILE*fd)
|
||||||
return scanner;
|
return scanner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
||||||
|
*/
|
||||||
void destroy_lexor(yyscan_t scanner)
|
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);
|
yylex_destroy(scanner);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright CERN 2015
|
* Copyright CERN 2016-2018
|
||||||
* @author Maciej Suminski (maciej.suminski@cern.ch)
|
* @author Maciej Suminski (maciej.suminski@cern.ch)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* 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*>();
|
std::list<InterfacePort*>*fn_integer_args = new std::list<InterfacePort*>();
|
||||||
fn_integer_args->push_back(new InterfacePort(&primitive_INTEGER));
|
fn_integer_args->push_back(new InterfacePort(&primitive_INTEGER));
|
||||||
fn_integer = new SubprogramBuiltin(perm_string::literal("integer"),
|
fn_integer = new SubprogramBuiltin(perm_string::literal("integer"),
|
||||||
perm_string::literal("$signed"),
|
perm_string::literal("int'"),
|
||||||
fn_integer_args, &primitive_INTEGER);
|
fn_integer_args, &primitive_INTEGER);
|
||||||
std_subprograms[fn_integer->name()] = fn_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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* 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>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#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);
|
dwRetVal = GetTempPath(MAX_PATH, lpTempPathBuffer);
|
||||||
if((dwRetVal > MAX_PATH) || (dwRetVal == 0))
|
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);
|
exit(255);
|
||||||
}
|
}
|
||||||
else
|
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);
|
uRetVal = GetTempFileName(lpTempPathBuffer, TEXT("FSTW"), 0, szTempFileName);
|
||||||
if (uRetVal == 0)
|
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);
|
exit(255);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -803,7 +804,7 @@ if(rc<0)
|
||||||
{
|
{
|
||||||
xc->fseek_failed = 1;
|
xc->fseek_failed = 1;
|
||||||
#ifdef FST_DEBUG
|
#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");
|
perror("Why");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -1663,7 +1664,7 @@ if(zerocnt)
|
||||||
/* fpos += */ fstWriterVarint(f, (zerocnt << 1)); /* scan-build */
|
/* fpos += */ fstWriterVarint(f, (zerocnt << 1)); /* scan-build */
|
||||||
}
|
}
|
||||||
#ifdef FST_DEBUG
|
#ifdef FST_DEBUG
|
||||||
fprintf(stderr, "value chains: %d\n", cnt);
|
fprintf(stderr, FST_APIMESS"value chains: %d\n", cnt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xc->vchg_mem[0] = '!';
|
xc->vchg_mem[0] = '!';
|
||||||
|
|
@ -1738,7 +1739,7 @@ if(xc->dump_size_limit)
|
||||||
xc2->size_limit_locked = 1;
|
xc2->size_limit_locked = 1;
|
||||||
xc2->is_initial_time = 1; /* to trick emit value and emit time change */
|
xc2->is_initial_time = 1; /* to trick emit value and emit time change */
|
||||||
#ifdef FST_DEBUG
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2478,7 +2479,7 @@ if(xc)
|
||||||
#ifndef FST_WRITER_PARALLEL
|
#ifndef FST_WRITER_PARALLEL
|
||||||
if(xc->parallel_enabled)
|
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);
|
exit(255);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -2760,7 +2761,7 @@ if((xc) && (handle <= xc->maxhandle))
|
||||||
xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz);
|
xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz);
|
||||||
if(!xc->vchg_mem)
|
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);
|
exit(255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2874,7 +2875,7 @@ if((xc) && (handle <= xc->maxhandle))
|
||||||
xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz);
|
xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz);
|
||||||
if(!xc->vchg_mem)
|
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);
|
exit(255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3119,7 +3120,7 @@ if(rc<0)
|
||||||
{
|
{
|
||||||
xc->fseek_failed = 1;
|
xc->fseek_failed = 1;
|
||||||
#ifdef FST_DEBUG
|
#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");
|
perror("Why");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -3748,6 +3749,10 @@ if(!xc->fh)
|
||||||
else /* FST_BL_SKIP */
|
else /* FST_BL_SKIP */
|
||||||
{
|
{
|
||||||
pass_status = 0;
|
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);
|
free(mem);
|
||||||
|
|
@ -4435,7 +4440,7 @@ if(gzread_pass_status)
|
||||||
|
|
||||||
if(rc != Z_OK)
|
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);
|
exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4726,7 +4731,7 @@ for(;;)
|
||||||
if((sectype == EOF) || (sectype == FST_BL_SKIP))
|
if((sectype == EOF) || (sectype == FST_BL_SKIP))
|
||||||
{
|
{
|
||||||
#ifdef FST_DEBUG
|
#ifdef FST_DEBUG
|
||||||
fprintf(stderr, "<< EOF >>\n");
|
fprintf(stderr, FST_APIMESS"<< EOF >>\n");
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -4765,9 +4770,9 @@ for(;;)
|
||||||
mem_required_for_traversal = fstReaderUint64(xc->f);
|
mem_required_for_traversal = fstReaderUint64(xc->f);
|
||||||
mem_for_traversal = malloc(mem_required_for_traversal + 66); /* add in potential fastlz overhead */
|
mem_for_traversal = malloc(mem_required_for_traversal + 66); /* add in potential fastlz overhead */
|
||||||
#ifdef FST_DEBUG
|
#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);
|
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
|
#endif
|
||||||
/* process time block */
|
/* process time block */
|
||||||
{
|
{
|
||||||
|
|
@ -4785,7 +4790,7 @@ for(;;)
|
||||||
tsec_clen = fstReaderUint64(xc->f);
|
tsec_clen = fstReaderUint64(xc->f);
|
||||||
tsec_nitems = fstReaderUint64(xc->f);
|
tsec_nitems = fstReaderUint64(xc->f);
|
||||||
#ifdef FST_DEBUG
|
#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);
|
(int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems);
|
||||||
#endif
|
#endif
|
||||||
if(tsec_clen > seclen) break; /* corrupted tsec_clen: by definition it can't be larger than size of section */
|
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)
|
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);
|
exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4881,7 +4886,7 @@ for(;;)
|
||||||
rc = uncompress(mu, &destlen, mc, sourcelen);
|
rc = uncompress(mu, &destlen, mc, sourcelen);
|
||||||
if(rc != Z_OK)
|
if(rc != Z_OK)
|
||||||
{
|
{
|
||||||
printf("rc: %d\n", rc);
|
fprintf(stderr, FST_APIMESS"fstReaderIterBlocks2(), frame uncompress rc: %d, exiting.\n", rc);
|
||||||
exit(255);
|
exit(255);
|
||||||
}
|
}
|
||||||
free(mc);
|
free(mc);
|
||||||
|
|
@ -5044,9 +5049,9 @@ for(;;)
|
||||||
packtype = fgetc(xc->f);
|
packtype = fgetc(xc->f);
|
||||||
|
|
||||||
#ifdef FST_DEBUG
|
#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);
|
(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
|
#endif
|
||||||
|
|
||||||
indx_pntr = blkpos + seclen - 24 -tsec_clen -8;
|
indx_pntr = blkpos + seclen - 24 -tsec_clen -8;
|
||||||
|
|
@ -5054,7 +5059,7 @@ for(;;)
|
||||||
chain_clen = fstReaderUint64(xc->f);
|
chain_clen = fstReaderUint64(xc->f);
|
||||||
indx_pos = indx_pntr - chain_clen;
|
indx_pos = indx_pntr - chain_clen;
|
||||||
#ifdef FST_DEBUG
|
#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
|
#endif
|
||||||
chain_cmem = malloc(chain_clen);
|
chain_cmem = malloc(chain_clen);
|
||||||
if(!chain_cmem) goto block_err;
|
if(!chain_cmem) goto block_err;
|
||||||
|
|
@ -5173,7 +5178,7 @@ for(;;)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FST_DEBUG
|
#ifdef FST_DEBUG
|
||||||
fprintf(stderr, "\tdecompressed chain idx len: %"PRIu32"\n", idx);
|
fprintf(stderr, FST_APIMESS"decompressed chain idx len: %"PRIu32"\n", idx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mc_mem_len = 16384;
|
mc_mem_len = 16384;
|
||||||
|
|
@ -5241,7 +5246,7 @@ for(;;)
|
||||||
|
|
||||||
if(rc != Z_OK)
|
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);
|
exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5793,9 +5798,9 @@ mem_required_for_traversal =
|
||||||
fstReaderUint64(xc->f);
|
fstReaderUint64(xc->f);
|
||||||
|
|
||||||
#ifdef FST_DEBUG
|
#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);
|
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
|
#endif
|
||||||
|
|
||||||
/* process time block */
|
/* process time block */
|
||||||
|
|
@ -5814,7 +5819,7 @@ tsec_uclen = fstReaderUint64(xc->f);
|
||||||
tsec_clen = fstReaderUint64(xc->f);
|
tsec_clen = fstReaderUint64(xc->f);
|
||||||
tsec_nitems = fstReaderUint64(xc->f);
|
tsec_nitems = fstReaderUint64(xc->f);
|
||||||
#ifdef FST_DEBUG
|
#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);
|
(int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems);
|
||||||
#endif
|
#endif
|
||||||
ucdata = malloc(tsec_uclen);
|
ucdata = malloc(tsec_uclen);
|
||||||
|
|
@ -5831,7 +5836,7 @@ if(tsec_uclen != tsec_clen)
|
||||||
|
|
||||||
if(rc != Z_OK)
|
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);
|
exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5879,7 +5884,7 @@ if(frame_uclen == frame_clen)
|
||||||
rc = uncompress(xc->rvat_frame_data, &destlen, mc, sourcelen);
|
rc = uncompress(xc->rvat_frame_data, &destlen, mc, sourcelen);
|
||||||
if(rc != Z_OK)
|
if(rc != Z_OK)
|
||||||
{
|
{
|
||||||
printf("decompress rc: %d\n", rc);
|
fprintf(stderr, FST_APIMESS"fstReaderGetValueFromHandleAtTime(), frame decompress rc: %d, exiting.\n", rc);
|
||||||
exit(255);
|
exit(255);
|
||||||
}
|
}
|
||||||
free(mc);
|
free(mc);
|
||||||
|
|
@ -5890,9 +5895,9 @@ xc->rvat_vc_start = ftello(xc->f); /* points to '!' character */
|
||||||
xc->rvat_packtype = fgetc(xc->f);
|
xc->rvat_packtype = fgetc(xc->f);
|
||||||
|
|
||||||
#ifdef FST_DEBUG
|
#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);
|
(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
|
#endif
|
||||||
|
|
||||||
indx_pntr = blkpos + seclen - 24 -tsec_clen -8;
|
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);
|
chain_clen = fstReaderUint64(xc->f);
|
||||||
indx_pos = indx_pntr - chain_clen;
|
indx_pos = indx_pntr - chain_clen;
|
||||||
#ifdef FST_DEBUG
|
#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
|
#endif
|
||||||
chain_cmem = malloc(chain_clen);
|
chain_cmem = malloc(chain_clen);
|
||||||
fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET);
|
fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET);
|
||||||
|
|
@ -6011,7 +6016,7 @@ for(i=0;i<idx;i++)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FST_DEBUG
|
#ifdef FST_DEBUG
|
||||||
fprintf(stderr, "\tdecompressed chain idx len: %"PRIu32"\n", idx);
|
fprintf(stderr, FST_APIMESS"decompressed chain idx len: %"PRIu32"\n", idx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xc->rvat_data_valid = 1;
|
xc->rvat_data_valid = 1;
|
||||||
|
|
@ -6071,7 +6076,7 @@ if(!xc->rvat_chain_mem)
|
||||||
|
|
||||||
if(rc != Z_OK)
|
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);
|
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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
@ -168,7 +168,11 @@ enum fstHierType {
|
||||||
FST_HT_ATTRBEGIN = 3,
|
FST_HT_ATTRBEGIN = 3,
|
||||||
FST_HT_ATTREND = 4,
|
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 {
|
enum fstAttrType {
|
||||||
|
|
|
||||||
|
|
@ -825,7 +825,7 @@ _next_match:
|
||||||
/* Match description too long : reduce it */
|
/* Match description too long : reduce it */
|
||||||
matchLength = (15-1) + (oMaxMatch-op) * 255;
|
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;
|
ip += MINMATCH + matchLength;
|
||||||
|
|
||||||
if (matchLength>=ML_MASK)
|
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
|
* 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
|
||||||
|
|
@ -217,7 +217,7 @@ static void destroy_sdf_lexor(void)
|
||||||
{
|
{
|
||||||
# ifdef FLEX_SCANNER
|
# ifdef FLEX_SCANNER
|
||||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
# 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();
|
yylex_destroy();
|
||||||
# endif
|
# endif
|
||||||
# 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
|
* 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
|
||||||
|
|
@ -1887,6 +1887,8 @@ static const char *pts_convert(int value)
|
||||||
{
|
{
|
||||||
const char *string;
|
const char *string;
|
||||||
switch (value) {
|
switch (value) {
|
||||||
|
case 2: string = "100s"; break;
|
||||||
|
case 1: string = "10s"; break;
|
||||||
case 0: string = "1s"; break;
|
case 0: string = "1s"; break;
|
||||||
case -1: string = "100ms"; break;
|
case -1: string = "100ms"; break;
|
||||||
case -2: string = "10ms"; 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
|
* 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
|
||||||
|
|
@ -199,7 +199,7 @@ void destroy_readmem_lexor(void)
|
||||||
{
|
{
|
||||||
# ifdef FLEX_SCANNER
|
# ifdef FLEX_SCANNER
|
||||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
# 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();
|
yylex_destroy();
|
||||||
# endif
|
# endif
|
||||||
# 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
|
* 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
|
||||||
|
|
@ -289,7 +289,10 @@ static PLI_INT32 sys_sdf_annotate_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
|
||||||
FILE *sdf_fd;
|
FILE *sdf_fd;
|
||||||
char *fname = get_filename(callh, name, vpi_scan(argv));
|
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");
|
sdf_fd = fopen(fname, "r");
|
||||||
if (sdf_fd == 0) {
|
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));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("Unable to open SDF file \"%s\"."
|
vpi_printf("Unable to open SDF file \"%s\"."
|
||||||
" Skipping this annotation.\n", fname);
|
" Skipping this annotation.\n", fname);
|
||||||
|
vpi_free_object(argv);
|
||||||
|
free(fname);
|
||||||
return 0;
|
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
|
* 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
|
* 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
|
# ifdef FLEX_SCANNER
|
||||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
# 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();
|
yylex_destroy();
|
||||||
# endif
|
# endif
|
||||||
# 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
|
* 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
|
||||||
|
|
@ -45,14 +45,14 @@ struct vvp_island_branch_tran : public vvp_island_branch {
|
||||||
|
|
||||||
vvp_island_branch_tran(vvp_net_t*en__, bool active_high__,
|
vvp_island_branch_tran(vvp_net_t*en__, bool active_high__,
|
||||||
unsigned width__, unsigned part__,
|
unsigned width__, unsigned part__,
|
||||||
unsigned offset__);
|
unsigned offset__, bool resistive__);
|
||||||
bool run_test_enabled();
|
bool run_test_enabled();
|
||||||
void run_resolution();
|
void run_resolution();
|
||||||
void run_output();
|
void run_output();
|
||||||
|
|
||||||
vvp_net_t*en;
|
vvp_net_t*en;
|
||||||
unsigned width, part, offset;
|
unsigned width, part, offset;
|
||||||
bool active_high;
|
bool active_high, resistive;
|
||||||
tran_state_t state;
|
tran_state_t state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -60,9 +60,10 @@ vvp_island_branch_tran::vvp_island_branch_tran(vvp_net_t*en__,
|
||||||
bool active_high__,
|
bool active_high__,
|
||||||
unsigned width__,
|
unsigned width__,
|
||||||
unsigned part__,
|
unsigned part__,
|
||||||
unsigned offset__)
|
unsigned offset__,
|
||||||
|
bool resistive__)
|
||||||
: en(en__), width(width__), part(part__), offset(offset__),
|
: en(en__), width(width__), part(part__), offset(offset__),
|
||||||
active_high(active_high__)
|
active_high(active_high__), resistive(resistive__)
|
||||||
{
|
{
|
||||||
state = en__ ? tran_disabled : tran_enabled;
|
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.
|
// 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,
|
inline vvp_vector8_t resolve_ambiguous(const vvp_vector8_t&a,
|
||||||
const vvp_vector8_t&b,
|
const vvp_vector8_t&b,
|
||||||
tran_state_t state)
|
tran_state_t state,
|
||||||
|
unsigned str_map[8])
|
||||||
{
|
{
|
||||||
assert(a.size() == b.size());
|
assert(a.size() == b.size());
|
||||||
vvp_vector8_t out (a.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) {
|
for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
|
||||||
vvp_scalar_t a_bit = a.value(idx);
|
vvp_scalar_t a_bit = a.value(idx);
|
||||||
vvp_scalar_t b_bit = b.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) {
|
if (state == tran_unknown) {
|
||||||
switch (b_bit.value()) {
|
switch (b_bit.value()) {
|
||||||
case BIT4_0:
|
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.
|
// previously collected (and resolved) for the port.
|
||||||
if (branch->width == 0) {
|
if (branch->width == 0) {
|
||||||
// There are no part selects.
|
// There are no part selects.
|
||||||
dst_port->value = resolve_ambiguous(dst_port->value, val,
|
dst_port->value = resolve_ambiguous(dst_port->value, val, branch->state,
|
||||||
branch->state);
|
vvp_switch_strength_map[branch->resistive]);
|
||||||
|
|
||||||
} else if (dst_ab == 1) {
|
} else if (dst_ab == 1) {
|
||||||
// The other side is a strict subset (part select)
|
// 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,
|
vvp_island_branch_tran*br = new vvp_island_branch_tran(en,
|
||||||
sense ? true :
|
sense ? true :
|
||||||
false,
|
false,
|
||||||
0, 0, 0);
|
0, 0, 0, false);
|
||||||
|
|
||||||
use_island->add_branch(br, pa, pb);
|
use_island->add_branch(br, pa, pb);
|
||||||
|
|
||||||
|
|
@ -430,7 +435,7 @@ void compile_island_tranvp(char*island, char*pa, char*pb,
|
||||||
free(island);
|
free(island);
|
||||||
|
|
||||||
vvp_island_branch_tran*br = new vvp_island_branch_tran(NULL, false,
|
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);
|
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
|
* 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
|
||||||
|
|
@ -334,7 +334,7 @@ void destroy_lexor()
|
||||||
{
|
{
|
||||||
# ifdef FLEX_SCANNER
|
# ifdef FLEX_SCANNER
|
||||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
# 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();
|
yylex_destroy();
|
||||||
# endif
|
# endif
|
||||||
# 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
|
* 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
|
||||||
|
|
@ -19,9 +19,10 @@
|
||||||
|
|
||||||
# include "npmos.h"
|
# 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;
|
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)
|
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());
|
vvp_vector8_t out (bit_.size());
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
|
||||||
vvp_bit4_t b_en = en_.value(idx);
|
vvp_bit4_t b_en = en_.value(idx);
|
||||||
vvp_scalar_t b_bit = bit_.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) {
|
switch (b_en) {
|
||||||
case BIT4_0:
|
case BIT4_0:
|
||||||
out.set_bit(idx, b_bit);
|
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::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_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)
|
if (ptr.port() != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bit_ = resistive_reduction(bit);
|
bit_ = bit;
|
||||||
generate_output_(ptr);
|
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.
|
* 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,
|
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)
|
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());
|
vvp_vector8_t out (bit_.size());
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
|
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_bit4_t b_p_en = p_en_.value(idx);
|
||||||
vvp_scalar_t b_bit = bit_.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) {
|
if (b_n_en == BIT4_1 || b_p_en == BIT4_0) {
|
||||||
out.set_bit(idx, b_bit);
|
out.set_bit(idx, b_bit);
|
||||||
} else if (b_n_en == BIT4_0 && b_p_en == BIT4_1) {
|
} 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()
|
||||||
: 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_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)
|
if (ptr.port() != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bit_ = resistive_reduction(bit);
|
bit_ = bit;
|
||||||
generate_output_(ptr);
|
generate_output_(ptr);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_npmos_H
|
#ifndef IVL_npmos_H
|
||||||
#define 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
|
* 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
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
class vvp_fun_pmos_ : public vvp_net_fun_t {
|
class vvp_fun_pmos_ : public vvp_net_fun_t {
|
||||||
|
|
||||||
public:
|
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,
|
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||||
vvp_context_t);
|
vvp_context_t);
|
||||||
|
|
@ -62,7 +62,7 @@ class vvp_fun_pmos_ : public vvp_net_fun_t {
|
||||||
|
|
||||||
vvp_vector8_t bit_;
|
vvp_vector8_t bit_;
|
||||||
vvp_vector4_t en_;
|
vvp_vector4_t en_;
|
||||||
bool inv_en_;
|
bool inv_en_, resistive_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class vvp_fun_pmos : public vvp_fun_pmos_ {
|
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 {
|
class vvp_fun_cmos_ : public vvp_net_fun_t {
|
||||||
public:
|
public:
|
||||||
explicit vvp_fun_cmos_();
|
explicit vvp_fun_cmos_(bool resistive);
|
||||||
|
|
||||||
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t &bit,
|
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t &bit,
|
||||||
vvp_context_t);
|
vvp_context_t);
|
||||||
|
|
@ -126,6 +126,7 @@ class vvp_fun_cmos_ : public vvp_net_fun_t {
|
||||||
vvp_vector8_t bit_;
|
vvp_vector8_t bit_;
|
||||||
vvp_vector4_t n_en_;
|
vvp_vector4_t n_en_;
|
||||||
vvp_vector4_t p_en_;
|
vvp_vector4_t p_en_;
|
||||||
|
bool resistive_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class vvp_fun_cmos : public vvp_fun_cmos_ {
|
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
|
receive the event at hand. Put the event in to the
|
||||||
appropriate list for the kind of assign we have at hand. */
|
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:
|
case SEQ_START:
|
||||||
if (ctim->start == 0) {
|
q = &ctim->start;
|
||||||
ctim->start = cur;
|
|
||||||
} else {
|
|
||||||
cur->next = ctim->active->next;
|
|
||||||
ctim->active->next = cur;
|
|
||||||
ctim->active = cur;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQ_ACTIVE:
|
case SEQ_ACTIVE:
|
||||||
if (ctim->active == 0) {
|
q = &ctim->active;
|
||||||
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;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQ_NBASSIGN:
|
case SEQ_NBASSIGN:
|
||||||
if (ctim->nbassign == 0) {
|
q = &ctim->nbassign;
|
||||||
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;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQ_RWSYNC:
|
case SEQ_RWSYNC:
|
||||||
if (ctim->rwsync == 0) {
|
q = &ctim->rwsync;
|
||||||
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;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQ_ROSYNC:
|
case SEQ_ROSYNC:
|
||||||
if (ctim->rosync == 0) {
|
q = &ctim->rosync;
|
||||||
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;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEL_THREAD:
|
case DEL_THREAD:
|
||||||
if (ctim->del_thr == 0) {
|
q = &ctim->del_thr;
|
||||||
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;
|
|
||||||
}
|
|
||||||
break;
|
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)
|
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
|
* 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
|
||||||
|
|
@ -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)
|
static void real_signal_value(struct t_vpi_value*vp, double rval)
|
||||||
{
|
{
|
||||||
char*rbuf = (char *) need_result_buf(64 + 1, RBUF_VAL);
|
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))) {
|
if (rval != rval || (rval && (rval == 0.5*rval))) {
|
||||||
rval = 0.0;
|
rval = 0.0;
|
||||||
} else {
|
} else {
|
||||||
if (rval >= 0.0) rval = floor(rval + 0.5);
|
rval = vlg_round(rval);
|
||||||
else rval = ceil(rval - 0.5);
|
|
||||||
}
|
}
|
||||||
vp->value.integer = (PLI_INT32)rval;
|
vp->value.integer = (PLI_INT32)rval;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vpiDecStrVal:
|
case vpiDecStrVal:
|
||||||
#if !defined(__GNUC__)
|
|
||||||
if (isnan(rval))
|
if (isnan(rval))
|
||||||
sprintf(rbuf, "%s", "nan");
|
sprintf(rbuf, "%s", "nan");
|
||||||
else
|
else
|
||||||
sprintf(rbuf, "%0.0f", rval);
|
sprintf(rbuf, "%0.0f", vlg_round(rval));
|
||||||
#else
|
|
||||||
sprintf(rbuf, "%0.0f", rval);
|
|
||||||
#endif
|
|
||||||
vp->value.str = rbuf;
|
vp->value.str = rbuf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vpiHexStrVal:
|
case vpiHexStrVal:
|
||||||
sprintf(rbuf, "%lx", (long)rval);
|
sprintf(rbuf, "%lx", (long)vlg_round(rval));
|
||||||
vp->value.str = rbuf;
|
vp->value.str = rbuf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vpiBinStrVal: {
|
case vpiBinStrVal: {
|
||||||
unsigned long val = (unsigned long)rval;
|
unsigned long val = (unsigned long)vlg_round(rval);
|
||||||
unsigned len = 0;
|
unsigned len = 0;
|
||||||
|
|
||||||
while (val > 0) {
|
while (val > 0) {
|
||||||
|
|
@ -829,7 +833,7 @@ static void real_signal_value(struct t_vpi_value*vp, double rval)
|
||||||
val /= 2;
|
val /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = (unsigned long)rval;
|
val = (unsigned long)vlg_round(rval);
|
||||||
for (unsigned idx = 0 ; idx < len ; idx += 1) {
|
for (unsigned idx = 0 ; idx < len ; idx += 1) {
|
||||||
rbuf[len-idx-1] = (val & 1)? '1' : '0';
|
rbuf[len-idx-1] = (val & 1)? '1' : '0';
|
||||||
val /= 2;
|
val /= 2;
|
||||||
|
|
|
||||||
|
|
@ -339,7 +339,8 @@ extern vpiHandle vpip_make_int4(const char*name, int msb, int lsb,
|
||||||
vvp_net_t*vec);
|
vvp_net_t*vec);
|
||||||
extern vpiHandle vpip_make_var4(const char*name, int msb, int lsb,
|
extern vpiHandle vpip_make_var4(const char*name, int msb, int lsb,
|
||||||
bool signed_flag, vvp_net_t*net);
|
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);
|
bool signed_flag, vvp_net_t*node);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -506,7 +507,9 @@ struct __vpiRealVar : public __vpiHandle {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct __vpiScope* vpip_scope(__vpiRealVar*sig);
|
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 {
|
class __vpiBaseVar : public __vpiHandle {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,8 @@ vpiHandle __vpiRealVar::vpi_handle(int code)
|
||||||
vpiHandle __vpiRealVar::vpi_iterate(int code)
|
vpiHandle __vpiRealVar::vpi_iterate(int code)
|
||||||
{ return real_var_iterate(code, this); }
|
{ 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;
|
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->is_wire = is_wire;
|
||||||
obj->net = net;
|
obj->net = net;
|
||||||
|
|
||||||
obj->within.scope = vpip_peek_current_scope();
|
obj->within.scope = scope;
|
||||||
|
|
||||||
return obj;
|
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
|
#ifdef CHECK_WITH_VALGRIND
|
||||||
void real_delete(vpiHandle item)
|
void real_delete(vpiHandle item)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -132,10 +132,20 @@ char *generic_get_str(int code, vpiHandle ref, const char *name, const char *ind
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
const char*name, int msb, int lsb,
|
||||||
bool signed_flag, vvp_net_t*node);
|
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.
|
* The standard formatting/conversion routines.
|
||||||
* They work with full or partial signals.
|
* They work with full or partial signals.
|
||||||
|
|
@ -972,7 +982,7 @@ struct signal_longint : public __vpiSignal {
|
||||||
vpiHandle vpip_make_int4(const char*name, int msb, int lsb, vvp_net_t*vec)
|
vpiHandle vpip_make_int4(const char*name, int msb, int lsb, vvp_net_t*vec)
|
||||||
{
|
{
|
||||||
__vpiSignal*obj = new signal_integer;
|
__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)
|
bool signed_flag, vvp_net_t*vec)
|
||||||
{
|
{
|
||||||
__vpiSignal*obj = new signal_reg;
|
__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
|
#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
|
* The name is the PLI name for the object. If it is an array it is
|
||||||
* <name>[<index>].
|
* <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,
|
const char*name, int msb, int lsb,
|
||||||
bool signed_flag, vvp_net_t*node)
|
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
|
// Place this object within a scope. If this object is
|
||||||
// attached to an array, then this value will be replaced with
|
// attached to an array, then this value will be replaced with
|
||||||
// the handle to the parent.
|
// the handle to the parent.
|
||||||
obj->within.scope = vpip_peek_current_scope();
|
obj->within.scope = scope;
|
||||||
|
|
||||||
count_vpi_nets += 1;
|
count_vpi_nets += 1;
|
||||||
|
|
||||||
return obj;
|
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)
|
bool signed_flag, vvp_net_t*node)
|
||||||
{
|
{
|
||||||
struct __vpiSignal*obj = new signal_net;
|
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)
|
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>
|
* Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* 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)
|
static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||||
{
|
{
|
||||||
struct __vpiVThrWord*obj = dynamic_cast<__vpiVThrWord*>(ref);
|
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))) {
|
if (val != val || (val && (val == 0.5*val))) {
|
||||||
val = 0.0;
|
val = 0.0;
|
||||||
} else {
|
} else {
|
||||||
if (val >= 0.0) val = floor(val + 0.5);
|
val = vlg_round(val);
|
||||||
else val = ceil(val - 0.5);
|
|
||||||
}
|
}
|
||||||
vp->value.integer = (PLI_INT32)val;
|
vp->value.integer = (PLI_INT32)val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vpiDecStrVal:
|
case vpiDecStrVal:
|
||||||
#if !defined(__GNUC__)
|
|
||||||
if (isnan(val))
|
if (isnan(val))
|
||||||
sprintf(rbuf, "%s", "nan");
|
sprintf(rbuf, "%s", "nan");
|
||||||
else
|
else
|
||||||
sprintf(rbuf, "%0.0f", val);
|
sprintf(rbuf, "%0.0f", vlg_round(val));
|
||||||
#else
|
vp->value.str = rbuf;
|
||||||
sprintf(rbuf, "%0.0f", val);
|
break;
|
||||||
#endif
|
|
||||||
|
case vpiOctStrVal:
|
||||||
|
sprintf(rbuf, "%lo", (long)vlg_round(val));
|
||||||
vp->value.str = rbuf;
|
vp->value.str = rbuf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vpiHexStrVal:
|
case vpiHexStrVal:
|
||||||
sprintf(rbuf, "%lx", (long)val);
|
sprintf(rbuf, "%lx", (long)vlg_round(val));
|
||||||
vp->value.str = rbuf;
|
vp->value.str = rbuf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vpiBinStrVal: {
|
case vpiBinStrVal: {
|
||||||
unsigned long vali = (unsigned long)val;
|
unsigned long vali = (unsigned long)vlg_round(val);
|
||||||
unsigned len = 0;
|
unsigned len = 0;
|
||||||
|
|
||||||
while (vali > 0) {
|
while (vali > 0) {
|
||||||
|
|
@ -140,7 +149,7 @@ static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||||
vali /= 2;
|
vali /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
vali = (unsigned long)val;
|
vali = (unsigned long)vlg_round(val);
|
||||||
for (unsigned idx = 0 ; idx < len ; idx += 1) {
|
for (unsigned idx = 0 ; idx < len ; idx += 1) {
|
||||||
rbuf[len-idx-1] = (vali & 1)? '1' : '0';
|
rbuf[len-idx-1] = (vali & 1)? '1' : '0';
|
||||||
vali /= 2;
|
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_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_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_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_hexstr_(p_vpi_value vp, const vvp_vector4_t&val);
|
||||||
void vpi_get_value_vector_(p_vpi_value vp, const vvp_vector4_t&val);
|
void vpi_get_value_vector_(p_vpi_value vp, const vvp_vector4_t&val);
|
||||||
private:
|
private:
|
||||||
|
|
@ -346,6 +356,9 @@ void __vpiVThrVec4Stack::vpi_get_value(p_vpi_value vp)
|
||||||
case vpiDecStrVal:
|
case vpiDecStrVal:
|
||||||
vpi_get_value_decstr_(vp, val);
|
vpi_get_value_decstr_(vp, val);
|
||||||
break;
|
break;
|
||||||
|
case vpiOctStrVal:
|
||||||
|
vpi_get_value_octstr_(vp, val);
|
||||||
|
break;
|
||||||
case vpiHexStrVal:
|
case vpiHexStrVal:
|
||||||
vpi_get_value_hexstr_(vp, val);
|
vpi_get_value_hexstr_(vp, val);
|
||||||
break;
|
break;
|
||||||
|
|
@ -396,6 +409,48 @@ void __vpiVThrVec4Stack::vpi_get_value_decstr_(p_vpi_value vp, const vvp_vector4
|
||||||
vp->value.str = rbuf;
|
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)
|
void __vpiVThrVec4Stack::vpi_get_value_hexstr_(p_vpi_value vp, const vvp_vector4_t&val)
|
||||||
{
|
{
|
||||||
unsigned wid = val.size();
|
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
|
* 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
|
||||||
|
|
@ -2200,7 +2200,7 @@ static bool do_disable(vthread_t thr, vthread_t match)
|
||||||
}
|
}
|
||||||
|
|
||||||
vthread_t parent = thr->parent;
|
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
|
// If a parent is waiting in a %join, wake it up. Note
|
||||||
// that it is possible to be waiting in a %join yet
|
// that it is possible to be waiting in a %join yet
|
||||||
// already scheduled if multiple child threads are
|
// 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)
|
if (! parent->i_have_ended)
|
||||||
schedule_vthread(parent, 0, true);
|
schedule_vthread(parent, 0, true);
|
||||||
|
|
||||||
// Let the parent do the reaping.
|
do_join(parent, thr);
|
||||||
vthread_reap(thr);
|
|
||||||
|
|
||||||
} else if (parent) {
|
} else if (parent) {
|
||||||
/* If the parent is yet to %join me, let its %join
|
/* 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) {
|
if (bp[0] == 0) {
|
||||||
vvp_vector4_t tmp(wid, BIT4_X);
|
vvp_vector4_t tmp(wid, BIT4_X);
|
||||||
vala = tmp;
|
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 {
|
} else {
|
||||||
long tmpa = (long) ap[0];
|
long tmpa = (long) ap[0];
|
||||||
long tmpb = (long) bp[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
|
/* If I have a parent who is waiting for me, then mark that I
|
||||||
have ended, and schedule that parent. Also, finish the
|
have ended, and schedule that parent. Also, finish the
|
||||||
%join for the parent. */
|
%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;
|
vthread_t tmp = thr->parent;
|
||||||
assert(! thr->i_am_detached);
|
assert(! thr->i_am_detached);
|
||||||
|
|
||||||
|
|
@ -3768,6 +3771,9 @@ bool of_MOD_S(vthread_t thr, vvp_code_t)
|
||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
goto x_out;
|
goto x_out;
|
||||||
|
|
||||||
|
if ((lv == LONG_LONG_MIN) && (rv == -1))
|
||||||
|
goto zero_out;
|
||||||
|
|
||||||
/* Sign extend the signed operands when needed. */
|
/* Sign extend the signed operands when needed. */
|
||||||
if (wid < 8*sizeof(long long)) {
|
if (wid < 8*sizeof(long long)) {
|
||||||
if (lv & (1LL << (wid-1)))
|
if (lv & (1LL << (wid-1)))
|
||||||
|
|
@ -3799,6 +3805,9 @@ bool of_MOD_S(vthread_t thr, vvp_code_t)
|
||||||
x_out:
|
x_out:
|
||||||
vala = vvp_vector4_t(wid, BIT4_X);
|
vala = vvp_vector4_t(wid, BIT4_X);
|
||||||
return true;
|
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;
|
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()
|
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;
|
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<uint8_t>;
|
||||||
template class vvp_darray_atom<uint16_t>;
|
template class vvp_darray_atom<uint16_t>;
|
||||||
template class vvp_darray_atom<uint32_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_);
|
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()
|
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()
|
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];
|
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()
|
vvp_darray_real::~vvp_darray_real()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -226,6 +270,16 @@ void vvp_darray_real::get_word(unsigned adr, double&value)
|
||||||
value = array_[adr];
|
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()
|
vvp_darray_string::~vvp_darray_string()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -252,6 +306,16 @@ void vvp_darray_string::get_word(unsigned adr, string&value)
|
||||||
value = array_[adr];
|
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()
|
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 set_word(unsigned adr, const vvp_object_t&value);
|
||||||
virtual void get_word(unsigned adr, 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 {
|
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;
|
size_t get_size(void) const;
|
||||||
void set_word(unsigned adr, const vvp_vector4_t&value);
|
void set_word(unsigned adr, const vvp_vector4_t&value);
|
||||||
void get_word(unsigned adr, vvp_vector4_t&value);
|
void get_word(unsigned adr, vvp_vector4_t&value);
|
||||||
|
void shallow_copy(const vvp_object*obj);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<TYPE> array_;
|
std::vector<TYPE> array_;
|
||||||
|
|
@ -70,6 +73,7 @@ class vvp_darray_vec4 : public vvp_darray {
|
||||||
size_t get_size(void) const;
|
size_t get_size(void) const;
|
||||||
void set_word(unsigned adr, const vvp_vector4_t&value);
|
void set_word(unsigned adr, const vvp_vector4_t&value);
|
||||||
void get_word(unsigned adr, vvp_vector4_t&value);
|
void get_word(unsigned adr, vvp_vector4_t&value);
|
||||||
|
void shallow_copy(const vvp_object*obj);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<vvp_vector4_t> array_;
|
std::vector<vvp_vector4_t> array_;
|
||||||
|
|
@ -86,6 +90,7 @@ class vvp_darray_vec2 : public vvp_darray {
|
||||||
size_t get_size(void) const;
|
size_t get_size(void) const;
|
||||||
void set_word(unsigned adr, const vvp_vector4_t&value);
|
void set_word(unsigned adr, const vvp_vector4_t&value);
|
||||||
void get_word(unsigned adr, vvp_vector4_t&value);
|
void get_word(unsigned adr, vvp_vector4_t&value);
|
||||||
|
void shallow_copy(const vvp_object*obj);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<vvp_vector2_t> array_;
|
std::vector<vvp_vector2_t> array_;
|
||||||
|
|
@ -101,6 +106,7 @@ class vvp_darray_real : public vvp_darray {
|
||||||
size_t get_size(void) const;
|
size_t get_size(void) const;
|
||||||
void set_word(unsigned adr, double value);
|
void set_word(unsigned adr, double value);
|
||||||
void get_word(unsigned adr, double&value);
|
void get_word(unsigned adr, double&value);
|
||||||
|
void shallow_copy(const vvp_object*obj);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<double> array_;
|
std::vector<double> array_;
|
||||||
|
|
@ -115,6 +121,7 @@ class vvp_darray_string : public vvp_darray {
|
||||||
size_t get_size(void) const;
|
size_t get_size(void) const;
|
||||||
void set_word(unsigned adr, const std::string&value);
|
void set_word(unsigned adr, const std::string&value);
|
||||||
void get_word(unsigned adr, std::string&value);
|
void get_word(unsigned adr, std::string&value);
|
||||||
|
void shallow_copy(const vvp_object*obj);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> array_;
|
std::vector<std::string> array_;
|
||||||
|
|
@ -129,6 +136,7 @@ class vvp_darray_object : public vvp_darray {
|
||||||
size_t get_size(void) const;
|
size_t get_size(void) const;
|
||||||
void set_word(unsigned adr, const vvp_object_t&value);
|
void set_word(unsigned adr, const vvp_object_t&value);
|
||||||
void get_word(unsigned adr, vvp_object_t&value);
|
void get_word(unsigned adr, vvp_object_t&value);
|
||||||
|
void shallow_copy(const vvp_object*obj);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<vvp_object_t> array_;
|
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
|
* 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
|
||||||
|
|
@ -3421,7 +3421,8 @@ unsigned vvp_wide_fun_core::port_count() const
|
||||||
vvp_vector4_t& vvp_wide_fun_core::value(unsigned idx)
|
vvp_vector4_t& vvp_wide_fun_core::value(unsigned idx)
|
||||||
{
|
{
|
||||||
assert(idx < nports_);
|
assert(idx < nports_);
|
||||||
assert(port_values_);
|
if (port_values_ == 0)
|
||||||
|
port_values_ = new vvp_vector4_t [nports_];
|
||||||
return port_values_[idx];
|
return port_values_[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3685,31 +3686,28 @@ vvp_scalar_t fully_featured_resolv_(vvp_scalar_t a, vvp_scalar_t b)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_vector8_t resistive_reduction(const vvp_vector8_t&that)
|
unsigned vvp_switch_strength_map[2][8] = {
|
||||||
{
|
{ // non-resistive
|
||||||
static unsigned rstr[8] = {
|
0, /* High impedance --> High impedance */
|
||||||
0, /* Hi-Z --> Hi-Z */
|
1, /* Small capacitor --> Small capacitor */
|
||||||
1, /* Small capacitance --> Small capacitance */
|
2, /* Medium capacitor --> Medium capacitor */
|
||||||
1, /* Medium capacitance --> Small capacitance */
|
3, /* Weak drive --> Weak drive */
|
||||||
2, /* Weak drive --> Medium capacitance */
|
4, /* Large capacitor --> Large capacitor */
|
||||||
2, /* Large capacitance --> Medium capacitance */
|
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 */
|
3, /* Pull drive --> Weak drive */
|
||||||
5, /* Strong drive --> Pull drive */
|
5, /* Strong drive --> Pull drive */
|
||||||
5 /* Supply 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);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
vvp_vector4_t reduce4(const vvp_vector8_t&that)
|
vvp_vector4_t reduce4(const vvp_vector8_t&that)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_vvp_net_H
|
#ifndef IVL_vvp_net_H
|
||||||
#define 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
|
* 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
|
||||||
|
|
@ -954,9 +954,11 @@ inline vvp_vector8_t resolve(const vvp_vector8_t&a, const vvp_vector8_t&b)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function implements the strength reduction implied by
|
/* This lookup tabke implements the strength reduction implied by
|
||||||
Verilog standard resistive devices. */
|
Verilog standard switch devices. The major dimension selects
|
||||||
extern vvp_vector8_t resistive_reduction(const vvp_vector8_t&a);
|
between non-resistive and resistive devices. */
|
||||||
|
extern unsigned vvp_switch_strength_map[2][8];
|
||||||
|
|
||||||
/* The reduce4 function converts a vector8 to a vector4, losing
|
/* The reduce4 function converts a vector8 to a vector4, losing
|
||||||
strength information in the process. */
|
strength information in the process. */
|
||||||
extern vvp_vector4_t reduce4(const vvp_vector8_t&that);
|
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);
|
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);
|
compile_vpi_symbol(label, obj);
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
|
|
@ -350,7 +350,7 @@ static void do_compile_net(vvp_net_t*node, vvp_array_t array,
|
||||||
vpiHandle obj = 0;
|
vpiHandle obj = 0;
|
||||||
if (! local_flag) {
|
if (! local_flag) {
|
||||||
/* Make the vpiHandle for the reg. */
|
/* 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 */
|
/* This attaches the label to the vpiHandle */
|
||||||
compile_vpi_symbol(my_label, obj);
|
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;
|
vpiHandle obj = 0;
|
||||||
if (!local_flag) {
|
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);
|
compile_vpi_symbol(my_label, obj);
|
||||||
}
|
}
|
||||||
#ifdef CHECK_WITH_VALGRIND
|
#ifdef CHECK_WITH_VALGRIND
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue