vhdlpp: Added Subprogram::fix_variables() method.
This commit is contained in:
parent
5d26f0e28d
commit
6d75af86e6
|
|
@ -26,6 +26,7 @@
|
||||||
# include "sequential.h"
|
# include "sequential.h"
|
||||||
# include "ivl_assert.h"
|
# include "ivl_assert.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
|
# include <cassert>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -49,6 +50,7 @@ void Subprogram::set_program_body(list<SequentialStmt*>*stmt)
|
||||||
{
|
{
|
||||||
ivl_assert(*this, statements_==0);
|
ivl_assert(*this, statements_==0);
|
||||||
statements_ = stmt;
|
statements_ = stmt;
|
||||||
|
fix_variables();
|
||||||
fix_port_types();
|
fix_port_types();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,6 +99,47 @@ void Subprogram::fix_port_types()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Subprogram::fix_variables() {
|
||||||
|
for(std::map<perm_string, Variable*>::iterator it = new_variables_.begin(); it != new_variables_.end(); ++it) {
|
||||||
|
Variable*var = it->second;
|
||||||
|
const VType*type = var->peek_type();
|
||||||
|
|
||||||
|
// SystemVerilog does not handle variables that have length dependendent
|
||||||
|
// on other variables. We have to convert it to a dynamic array and
|
||||||
|
// construct it.
|
||||||
|
if(type->is_variable_length()) {
|
||||||
|
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
|
||||||
|
|
||||||
|
// Currently we handle only one dimensional variables
|
||||||
|
assert(arr->dimensions() == 1);
|
||||||
|
|
||||||
|
Expression*lsb = arr->dimension(0).lsb();
|
||||||
|
Expression*msb = arr->dimension(0).msb();
|
||||||
|
|
||||||
|
// We cannot have dynamic arrays with custom range,
|
||||||
|
// it has to be [size-1:0]
|
||||||
|
int64_t lsb_val;
|
||||||
|
assert(lsb->evaluate(NULL, lsb_val) && lsb_val == 0);
|
||||||
|
//ExpArithmetic*size = new ExpArithmetic(ExpArithmetic::MINUS, msb, lsb);
|
||||||
|
// Because lsb_val == 0, we may simplify the size expression:
|
||||||
|
Expression*size = msb;
|
||||||
|
|
||||||
|
// Prepare the construction statement
|
||||||
|
assert(statements_);
|
||||||
|
VariableSeqAssignment*init = new VariableSeqAssignment(new ExpName(var->peek_name()),
|
||||||
|
new ExpNew(size));
|
||||||
|
statements_->push_front(init);
|
||||||
|
|
||||||
|
// Now substitute the variable type
|
||||||
|
std::vector<VTypeArray::range_t> new_range;
|
||||||
|
new_range.push_back(VTypeArray::range_t());
|
||||||
|
VTypeArray*new_array = new VTypeArray(arr->element_type(), new_range);
|
||||||
|
it->second = new Variable(var->peek_name(), fix_logic_darray(new_array));
|
||||||
|
delete var;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VTypeArray*Subprogram::fix_logic_darray(const VTypeArray*type)
|
VTypeArray*Subprogram::fix_logic_darray(const VTypeArray*type)
|
||||||
{
|
{
|
||||||
Expression*zero = new ExpInteger(0);
|
Expression*zero = new ExpInteger(0);
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,12 @@ class Subprogram : public LineInfo, public ScopeBase {
|
||||||
// to translation between VHDL and SystemVerilog.
|
// to translation between VHDL and SystemVerilog.
|
||||||
void fix_port_types();
|
void fix_port_types();
|
||||||
|
|
||||||
|
// SystemVerilog does not allow to have signals/variables which size is
|
||||||
|
// evaluated at runtime. This function finds such variables and modifies
|
||||||
|
// their type to dynamic array and adds appropriate 'new' statement in
|
||||||
|
// the program body.
|
||||||
|
void fix_variables();
|
||||||
|
|
||||||
// For the time being, dynamic arrays work exclusively with vectors.
|
// For the time being, dynamic arrays work exclusively with vectors.
|
||||||
// To emulate dynamic array of 'logic'/'bit' type, we need to create a vector
|
// To emulate dynamic array of 'logic'/'bit' type, we need to create a vector
|
||||||
// of width == 1, to be used as the array element type.
|
// of width == 1, to be used as the array element type.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue