@@ -4575,6 +4575,65 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
4575
4575
return dev;
4576
4576
}
4577
4577
4578
+ /*
4579
+ * The foreach statement can be written as a for statement like so:
4580
+ *
4581
+ * for (<idx> = $low(<array>) ; <idx> <= $high(<array>) ; <idx> += 1)
4582
+ * <statement_>
4583
+ *
4584
+ * The <idx> variable is already known to be in the containing named
4585
+ * block scope, which was created by the parser.
4586
+ */
4587
+ NetProc* PForeach::elaborate (Design*des, NetScope*scope) const
4588
+ {
4589
+ // Get the signal for the index variable.
4590
+ pform_name_t index_name;
4591
+ index_name.push_back (name_component_t (index_var_));
4592
+ NetNet*idx_sig = des->find_signal (scope, index_name);
4593
+ ivl_assert (*this , idx_sig);
4594
+
4595
+ NetESignal*idx_exp = new NetESignal (idx_sig);
4596
+ idx_exp->set_line (*this );
4597
+
4598
+ // Get the signal for the array variable
4599
+ pform_name_t array_name;
4600
+ array_name.push_back (name_component_t (array_var_));
4601
+ NetNet*array_sig = des->find_signal (scope, array_name);
4602
+ ivl_assert (*this , array_sig);
4603
+
4604
+ NetESignal*array_exp = new NetESignal (array_sig);
4605
+ array_exp->set_line (*this );
4606
+
4607
+ // Make an initialization expression for the index.
4608
+ NetESFunc*init_expr = new NetESFunc (" $low" , IVL_VT_BOOL, 32 , 1 );
4609
+ init_expr->set_line (*this );
4610
+ init_expr->parm (0 , array_exp);
4611
+
4612
+ // Make a condition expression: idx <= $high(array)
4613
+ NetESFunc*high_exp = new NetESFunc (" $high" , IVL_VT_BOOL, 32 , 1 );
4614
+ high_exp->set_line (*this );
4615
+ high_exp->parm (0 , array_exp);
4616
+
4617
+ NetEBComp*cond_expr = new NetEBComp (' L' , idx_exp, high_exp);
4618
+ cond_expr->set_line (*this );
4619
+
4620
+ /* Elaborate the statement that is contained in the foreach
4621
+ loop. */
4622
+ NetProc*sub = statement_->elaborate (des, scope);
4623
+
4624
+ /* Make a step statement: idx += 1 */
4625
+ NetAssign_*idx_lv = new NetAssign_ (idx_sig);
4626
+ NetEConst*step_val = make_const_val (1 );
4627
+ NetAssign*step = new NetAssign (idx_lv, ' +' , step_val);
4628
+ step->set_line (*this );
4629
+
4630
+ NetForLoop*stmt = new NetForLoop (idx_sig, init_expr, cond_expr, sub, step);
4631
+ stmt->set_line (*this );
4632
+ stmt->wrap_up ();
4633
+
4634
+ return stmt;
4635
+ }
4636
+
4578
4637
/*
4579
4638
* elaborate the for loop as the equivalent while loop. This eases the
4580
4639
* task for the target code generator. The structure is:
0 commit comments