Skip to content

Commit 8aa5d96

Browse files
committed
Allow more constructs in a generate loop.
Previously the generate loop contained a StatementBlock which limited what could be put inside of loops to statements. However, other constructs can be put in loops like always blocks, etc. This change expands what may be placed in the body of a GenerateLoop.
1 parent 4160592 commit 8aa5d96

File tree

8 files changed

+471
-142
lines changed

8 files changed

+471
-142
lines changed

xls/codegen/module_builder.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,8 @@ absl::Status ModuleBuilder::EmitArrayCopyAndUpdateViaGenerate(
662662
loop = module_->Add<GenerateLoop>(SourceInfo(), genvar_name, init, limit,
663663
std::move(label));
664664
} else {
665-
loop = innermost_loop->body()->Add<GenerateLoop>(
666-
SourceInfo(), genvar_name, init, limit, std::move(label));
665+
loop = innermost_loop->Add<GenerateLoop>(SourceInfo(), genvar_name, init,
666+
limit, std::move(label));
667667
}
668668
innermost_loop = loop;
669669
return loop;
@@ -750,8 +750,8 @@ absl::Status ModuleBuilder::EmitArrayCopyAndUpdateViaGenerate(
750750
assignment_section()->Add<ContinuousAssignment>(SourceInfo(), lhs_indexed,
751751
assignment_rhs);
752752
} else {
753-
innermost_loop->body()->Add<ContinuousAssignment>(SourceInfo(), lhs_indexed,
754-
assignment_rhs);
753+
innermost_loop->Add<ContinuousAssignment>(SourceInfo(), lhs_indexed,
754+
assignment_rhs);
755755
}
756756

757757
return absl::OkStatus();

xls/codegen/vast/vast.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -603,8 +603,7 @@ GenerateLoop::GenerateLoop(std::string_view genvar_name, Expression* init,
603603
loc, file->Make<GenvarDef>(loc, std::string(genvar_name)))),
604604
init_(init),
605605
limit_(limit),
606-
label_(std::move(label)),
607-
body_(file->Make<StatementBlock>(loc)) {}
606+
label_(std::move(label)) {}
608607

609608
std::string GenerateLoop::Emit(LineInfo* line_info) const {
610609
LineInfoStart(line_info, this);
@@ -618,13 +617,15 @@ std::string GenerateLoop::Emit(LineInfo* line_info) const {
618617
"for (genvar %s = %s; %s < %s; %s = %s + 1) begin%s", genvar_str,
619618
init_str, genvar_str, limit_str, genvar_str, genvar_str, label_suffix));
620619
LineInfoIncrease(line_info, 1);
621-
for (Statement* statement : body_->statements()) {
622-
std::string pre_emit = statement->PreEmit(line_info);
620+
for (const ModuleMember& member : members_) {
621+
std::string pre_emit =
622+
absl::visit([=](auto* m) { return m->PreEmit(line_info); }, member);
623623
if (!pre_emit.empty()) {
624624
lines.push_back(Indent(pre_emit, kDefaultIndentSpaces));
625625
LineInfoIncrease(line_info, 1);
626626
}
627-
lines.push_back(Indent(statement->Emit(line_info), kDefaultIndentSpaces));
627+
lines.push_back(Indent(
628+
absl::visit([=](auto* m) { return m->Emit(line_info); }, member)));
628629
LineInfoIncrease(line_info, 1);
629630
}
630631
lines.push_back("end");

xls/codegen/vast/vast.h

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -731,38 +731,6 @@ class StatementBlock final : public VastNode {
731731
std::vector<Statement*> statements_;
732732
};
733733

734-
// Represents a generate loop construct. Example:
735-
// ```verilog
736-
// for (genvar i = 0; i < 32; i = i + 1) begin : gen_loop
737-
// assign output[i] = input[i];
738-
// end
739-
// ```
740-
//
741-
class GenerateLoop final : public Statement {
742-
public:
743-
GenerateLoop(std::string_view genvar_name, Expression* init,
744-
Expression* limit, std::optional<std::string> label,
745-
VerilogFile* file, const SourceInfo& loc);
746-
747-
LogicRef* genvar() const { return genvar_; }
748-
Expression* init() const { return init_; }
749-
Expression* limit() const { return limit_; }
750-
const std::optional<std::string>& label() const { return label_; }
751-
StatementBlock* body() const { return body_; }
752-
absl::Span<Statement* const> statements() const {
753-
return body_->statements();
754-
}
755-
756-
std::string Emit(LineInfo* line_info) const final;
757-
758-
private:
759-
LogicRef* genvar_;
760-
Expression* init_;
761-
Expression* limit_;
762-
std::optional<std::string> label_;
763-
StatementBlock* body_;
764-
};
765-
766734
// Similar to statement block, but for use if `ifdef `else `endif blocks (no
767735
// "begin" or "end").
768736
class MacroStatementBlock final : public VastNode {
@@ -2268,6 +2236,7 @@ class VerilogFunctionCall final : public Expression {
22682236

22692237
class ModuleSection;
22702238
class ModuleConditionalDirective;
2239+
class GenerateLoop;
22712240

22722241
// Represents a member of a module.
22732242
using ModuleMember =
@@ -2291,6 +2260,38 @@ using ModuleMember =
22912260
// at elaboration time
22922261
GenerateLoop*>;
22932262

2263+
// Represents a generate loop construct. Example:
2264+
// ```verilog
2265+
// for (genvar i = 0; i < 32; i = i + 1) begin : gen_loop
2266+
// assign output[i] = input[i];
2267+
// end
2268+
// ```
2269+
//
2270+
class GenerateLoop final : public Statement {
2271+
public:
2272+
GenerateLoop(std::string_view genvar_name, Expression* init,
2273+
Expression* limit, std::optional<std::string> label,
2274+
VerilogFile* file, const SourceInfo& loc);
2275+
2276+
LogicRef* genvar() const { return genvar_; }
2277+
Expression* init() const { return init_; }
2278+
Expression* limit() const { return limit_; }
2279+
const std::optional<std::string>& label() const { return label_; }
2280+
2281+
template <typename T, typename... Args>
2282+
T* Add(const SourceInfo& loc, Args&&... args);
2283+
void AddMember(ModuleMember member) { members_.push_back(member); }
2284+
2285+
std::string Emit(LineInfo* line_info) const final;
2286+
2287+
private:
2288+
LogicRef* genvar_;
2289+
Expression* init_;
2290+
Expression* limit_;
2291+
std::optional<std::string> label_;
2292+
std::vector<ModuleMember> members_;
2293+
};
2294+
22942295
// A ModuleSection is a container of ModuleMembers used to organize the contents
22952296
// of a module. A Module contains a single top-level ModuleSection which may
22962297
// contain other ModuleSections. ModuleSections enables modules to be
@@ -2993,6 +2994,12 @@ inline T* VerilogPackageSection::Add(const SourceInfo& loc, Args&&... args) {
29932994
return ptr;
29942995
}
29952996

2997+
template <typename T, typename... Args>
2998+
inline T* GenerateLoop::Add(const SourceInfo& loc, Args&&... args) {
2999+
T* ptr = file()->Make<T>(loc, std::forward<Args>(args)...);
3000+
AddMember(ptr);
3001+
return ptr;
3002+
}
29963003
} // namespace verilog
29973004
} // namespace xls
29983005

xls/codegen/vast/vast_test.cc

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
#include <utility>
2222
#include <vector>
2323

24-
#include "gmock/gmock.h"
25-
#include "gtest/gtest.h"
2624
#include "absl/container/flat_hash_map.h"
2725
#include "absl/status/status.h"
2826
#include "absl/status/status_matchers.h"
2927
#include "absl/strings/str_cat.h"
3028
#include "absl/strings/str_format.h"
3129
#include "absl/types/span.h"
30+
#include "gmock/gmock.h"
31+
#include "gtest/gtest.h"
3232
#include "xls/common/status/matchers.h"
3333
#include "xls/ir/bits.h"
3434
#include "xls/ir/fileno.h"
@@ -2834,8 +2834,11 @@ TEST_P(VastTest, SimpleGenerateLoop) {
28342834
m->Add<GenerateLoop>(si, std::string("i"), f.PlainLiteral(0, si),
28352835
f.PlainLiteral(32, si), "gen_loop");
28362836
LogicRef* i = generate_loop->genvar();
2837-
generate_loop->body()->Add<ContinuousAssignment>(
2838-
si, f.Make<Index>(si, output, i), f.Make<Index>(si, input, i));
2837+
generate_loop->Add<ContinuousAssignment>(si, f.Make<Index>(si, output, i),
2838+
f.Make<Index>(si, input, i));
2839+
generate_loop->Add<BlankLine>(si);
2840+
generate_loop->Add<Comment>(si, "This is a comment.");
2841+
generate_loop->Add<InlineVerilogStatement>(si, "inline_verilog_statement;");
28392842

28402843
LineInfo line_info;
28412844
EXPECT_EQ(m->Emit(&line_info),
@@ -2845,6 +2848,9 @@ TEST_P(VastTest, SimpleGenerateLoop) {
28452848
);
28462849
for (genvar i = 0; i < 32; i = i + 1) begin : gen_loop
28472850
assign my_output[i] = my_input[i];
2851+
2852+
// This is a comment.
2853+
inline_verilog_statement;
28482854
end
28492855
endmodule)");
28502856
}
@@ -2864,11 +2870,11 @@ TEST_P(VastTest, NestedGenerateLoop) {
28642870
m->Add<GenerateLoop>(si, std::string("i"), f.PlainLiteral(0, si),
28652871
f.PlainLiteral(4, si), "outer");
28662872
LogicRef* i = outer_loop->genvar();
2867-
auto* inner_loop = outer_loop->body()->Add<GenerateLoop>(
2868-
si, std::string("j"), f.PlainLiteral(0, si), f.PlainLiteral(3, si),
2869-
"inner");
2873+
auto* inner_loop =
2874+
outer_loop->Add<GenerateLoop>(si, std::string("j"), f.PlainLiteral(0, si),
2875+
f.PlainLiteral(3, si), "inner");
28702876
LogicRef* j = inner_loop->genvar();
2871-
inner_loop->body()->Add<ContinuousAssignment>(
2877+
inner_loop->Add<ContinuousAssignment>(
28722878
si, f.Make<Index>(si, f.Make<Index>(si, dst, i), j),
28732879
f.Make<Index>(si, f.Make<Index>(si, src, i), j));
28742880

xls/public/c_api_symbols.txt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,16 @@ xls_vast_data_type_width
312312
xls_vast_data_type_width_as_int64
313313
xls_vast_def_get_data_type
314314
xls_vast_def_get_name
315-
xls_vast_generate_loop_get_body
315+
xls_vast_generate_loop_add_always_comb
316+
xls_vast_generate_loop_add_always_ff
317+
xls_vast_generate_loop_add_blank_line
318+
xls_vast_generate_loop_add_comment
319+
xls_vast_generate_loop_add_continuous_assignment
320+
xls_vast_generate_loop_add_generate_loop
321+
xls_vast_generate_loop_add_inline_verilog_statement
322+
xls_vast_generate_loop_add_instantiation
323+
xls_vast_generate_loop_add_localparam
324+
xls_vast_generate_loop_add_localparam_with_def
316325
xls_vast_generate_loop_get_genvar
317326
xls_vast_index_as_expression
318327
xls_vast_index_as_indexable_expression
@@ -328,8 +337,6 @@ xls_vast_slice_as_expression
328337
xls_vast_statement_block_add_blocking_assignment
329338
xls_vast_statement_block_add_case
330339
xls_vast_statement_block_add_conditional
331-
xls_vast_statement_block_add_continuous_assignment
332-
xls_vast_statement_block_add_generate_loop
333340
xls_vast_statement_block_add_nonblocking_assignment
334341
xls_vast_verilog_file_add_include
335342
xls_vast_verilog_file_add_module
@@ -346,6 +353,7 @@ xls_vast_verilog_file_make_def
346353
xls_vast_verilog_file_make_extern_package_type
347354
xls_vast_verilog_file_make_index
348355
xls_vast_verilog_file_make_index_i64
356+
xls_vast_verilog_file_make_inline_verilog_statement
349357
xls_vast_verilog_file_make_instantiation
350358
xls_vast_verilog_file_make_int_def
351359
xls_vast_verilog_file_make_int_type

0 commit comments

Comments
 (0)