vhdlpp: Support for selected assignments.
This commit is contained in:
parent
5a0d967682
commit
c28000c55f
|
|
@ -367,6 +367,38 @@ ExpConditional::case_t::~case_t()
|
|||
}
|
||||
}
|
||||
|
||||
ExpSelected::ExpSelected(Expression*selector, std::list<case_t*>*options)
|
||||
: ExpConditional(NULL, NULL, options), selector_(selector)
|
||||
{
|
||||
// Currently condition field contains only value,
|
||||
// so substitute it with a comparison to create a valid condition
|
||||
for(std::list<case_t*>::iterator it = options_.begin();
|
||||
it != options_.end(); ++it) {
|
||||
Expression*cond = (*it)->condition();
|
||||
|
||||
if(cond)
|
||||
(*it)->set_condition(new ExpRelation(ExpRelation::EQ, selector_->clone(), cond));
|
||||
}
|
||||
}
|
||||
|
||||
ExpSelected::~ExpSelected()
|
||||
{
|
||||
}
|
||||
|
||||
Expression*ExpSelected::clone() const
|
||||
{
|
||||
std::list<case_t*>*new_options = NULL;
|
||||
if(!options_.empty()) {
|
||||
new_options = new std::list<case_t*>();
|
||||
|
||||
for(std::list<case_t*>::const_iterator it = options_.begin();
|
||||
it != options_.end(); ++it) {
|
||||
new_options->push_back(new case_t(**it));
|
||||
}
|
||||
}
|
||||
|
||||
return new ExpSelected(selector_->clone(), new_options);
|
||||
}
|
||||
|
||||
void ExpConditional::case_t::visit(ExprVisitor& func)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -466,6 +466,9 @@ class ExpConditional : public Expression {
|
|||
case_t(const case_t&other);
|
||||
~case_t();
|
||||
|
||||
inline Expression*condition() { return cond_; }
|
||||
inline void set_condition(Expression*cond) { cond_ = cond; }
|
||||
|
||||
int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*lt);
|
||||
int emit_option(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
int emit_default(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
|
|
@ -481,9 +484,9 @@ class ExpConditional : public Expression {
|
|||
public:
|
||||
ExpConditional(Expression*cond, std::list<Expression*>*tru,
|
||||
std::list<case_t*>*options);
|
||||
~ExpConditional();
|
||||
virtual ~ExpConditional();
|
||||
|
||||
Expression*clone() const;
|
||||
virtual Expression*clone() const;
|
||||
|
||||
const VType*probe_type(Entity*ent, ScopeBase*scope) const;
|
||||
int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
|
||||
|
|
@ -492,10 +495,24 @@ class ExpConditional : public Expression {
|
|||
void dump(ostream&out, int indent = 0) const;
|
||||
void visit(ExprVisitor& func);
|
||||
|
||||
private:
|
||||
protected:
|
||||
std::list<case_t*> options_;
|
||||
};
|
||||
|
||||
/*
|
||||
* Expression to handle selected assignments (with .. select target <= value when ..)
|
||||
*/
|
||||
class ExpSelected : public ExpConditional {
|
||||
public:
|
||||
ExpSelected(Expression*selector, std::list<case_t*>*options);
|
||||
~ExpSelected();
|
||||
|
||||
Expression*clone() const;
|
||||
|
||||
private:
|
||||
Expression*selector_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is a special expression type that represents posedge/negedge
|
||||
* expressions in sensitivity lists.
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ static void touchup_interface_for_functions(std::list<InterfacePort*>*ports)
|
|||
%type <arch_statement> concurrent_conditional_signal_assignment
|
||||
%type <arch_statement> concurrent_signal_assignment_statement concurrent_simple_signal_assignment
|
||||
%type <arch_statement> for_generate_statement generate_statement if_generate_statement
|
||||
%type <arch_statement> process_statement
|
||||
%type <arch_statement> process_statement selected_signal_assignment
|
||||
%type <arch_statement_list> architecture_statement_part generate_statement_body
|
||||
|
||||
%type <choice> choice
|
||||
|
|
@ -370,8 +370,8 @@ static void touchup_interface_for_functions(std::list<InterfacePort*>*ports)
|
|||
%type <elsif> if_statement_elsif
|
||||
%type <elsif_list> if_statement_elsif_list if_statement_elsif_list_opt
|
||||
|
||||
%type <exp_options> else_when_waveform
|
||||
%type <exp_options_list> else_when_waveforms
|
||||
%type <exp_options> else_when_waveform selected_waveform
|
||||
%type <exp_options_list> else_when_waveforms selected_waveform_list
|
||||
|
||||
%type <subprogram> function_specification subprogram_specification subprogram_body_start
|
||||
%type <severity> severity severity_opt
|
||||
|
|
@ -833,6 +833,10 @@ concurrent_signal_assignment_statement /* IEEE 1076-2008 P11.6 */
|
|||
|
||||
| IDENTIFIER ':' concurrent_conditional_signal_assignment { $$ = $3; }
|
||||
|
||||
| selected_signal_assignment
|
||||
|
||||
| IDENTIFIER ':' selected_signal_assignment { $$ = $3; }
|
||||
|
||||
| name LEQ error ';'
|
||||
{ errormsg(@2, "Syntax error in signal assignment waveform.\n");
|
||||
delete $1;
|
||||
|
|
@ -2175,6 +2179,47 @@ selected_names_lib
|
|||
| selected_name_lib
|
||||
;
|
||||
|
||||
selected_signal_assignment
|
||||
: K_with expression K_select name LEQ selected_waveform_list ';'
|
||||
{ ExpSelected*tmp = new ExpSelected($2, $6);
|
||||
FILE_NAME(tmp, @3);
|
||||
delete $2;
|
||||
delete $6;
|
||||
|
||||
ExpName*name = dynamic_cast<ExpName*>($4);
|
||||
assert(name);
|
||||
SignalAssignment*tmpa = new SignalAssignment(name, tmp);
|
||||
FILE_NAME(tmpa, @1);
|
||||
|
||||
$$ = tmpa;
|
||||
}
|
||||
;
|
||||
|
||||
selected_waveform
|
||||
: waveform K_when expression
|
||||
{ ExpConditional::case_t*tmp = new ExpConditional::case_t($3, $1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| waveform K_when K_others
|
||||
{ ExpConditional::case_t*tmp = new ExpConditional::case_t(0, $1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
selected_waveform_list
|
||||
: selected_waveform_list ',' selected_waveform
|
||||
{ list<ExpConditional::case_t*>*tmp = $1;
|
||||
tmp->push_back($3);
|
||||
$$ = tmp;
|
||||
}
|
||||
| selected_waveform
|
||||
{ list<ExpConditional::case_t*>*tmp = new list<ExpConditional::case_t*>;
|
||||
tmp->push_back($1);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
sequence_of_statements
|
||||
: sequence_of_statements sequential_statement
|
||||
|
|
|
|||
Loading…
Reference in New Issue