Skip to content

Commit 93244c0

Browse files
grebecopybara-github
authored andcommitted
Support instantiations in block interpreter.
Now that we have block elaboration and visitors on those elaborations, we implement support for instantiations in the block interpreter. The idea is that there's a top-level elaborated block visitor that iterates through the elaborated nodes, implements inter-block ops, and then delegates the other ops to a per-block IR interpreter. These changes also extend to the block evaluator, which needs to elaborate in some places, update how registers are initialized, etc. PiperOrigin-RevId: 625088110
1 parent 5e6bad1 commit 93244c0

16 files changed

+806
-92
lines changed

Diff for: xls/interpreter/BUILD

+10
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ cc_library(
3838
"@com_google_absl//absl/log:check",
3939
"@com_google_absl//absl/status",
4040
"@com_google_absl//absl/status:statusor",
41+
"@com_google_absl//absl/strings",
4142
"@com_google_absl//absl/strings:str_format",
4243
"@com_google_absl//absl/types:span",
4344
"//xls/codegen:module_signature_cc_proto",
@@ -47,6 +48,7 @@ cc_library(
4748
"//xls/ir",
4849
"//xls/ir:bits",
4950
"//xls/ir:bits_ops",
51+
"//xls/ir:block_elaboration",
5052
"//xls/ir:events",
5153
"//xls/ir:keyword_args",
5254
"//xls/ir:register",
@@ -67,13 +69,16 @@ cc_library(
6769
"@com_google_absl//absl/random:distributions",
6870
"@com_google_absl//absl/status",
6971
"@com_google_absl//absl/status:statusor",
72+
"@com_google_absl//absl/strings",
7073
"@com_google_absl//absl/strings:str_format",
7174
"@com_google_absl//absl/types:span",
7275
"//xls/codegen:module_signature_cc_proto",
7376
"//xls/common/status:ret_check",
7477
"//xls/common/status:status_macros",
7578
"//xls/ir",
7679
"//xls/ir:bits",
80+
"//xls/ir:block_elaboration",
81+
"//xls/ir:elaboration",
7782
"//xls/ir:events",
7883
"//xls/ir:register",
7984
"//xls/ir:value",
@@ -169,12 +174,17 @@ cc_library(
169174
":block_evaluator",
170175
"@com_google_absl//absl/container:flat_hash_map",
171176
"@com_google_absl//absl/status",
177+
"@com_google_absl//absl/status:statusor",
178+
"@com_google_absl//absl/strings",
179+
"@com_google_absl//absl/strings:str_format",
172180
"@com_google_absl//absl/types:span",
173181
"//xls/codegen:module_signature_cc_proto",
174182
"//xls/common:xls_gunit_main",
175183
"//xls/common/status:matchers",
184+
"//xls/common/status:status_macros",
176185
"//xls/ir",
177186
"//xls/ir:bits",
187+
"//xls/ir:elaboration",
178188
"//xls/ir:format_preference",
179189
"//xls/ir:function_builder",
180190
"//xls/ir:ir_test_base",

Diff for: xls/interpreter/block_evaluator.cc

+56-15
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@
2929
#include "absl/random/distributions.h"
3030
#include "absl/status/status.h"
3131
#include "absl/status/statusor.h"
32+
#include "absl/strings/str_cat.h"
3233
#include "absl/strings/str_format.h"
3334
#include "absl/types/span.h"
3435
#include "xls/common/status/ret_check.h"
3536
#include "xls/common/status/status_macros.h"
3637
#include "xls/ir/bits.h"
3738
#include "xls/ir/block.h"
39+
#include "xls/ir/block_elaboration.h"
40+
#include "xls/ir/elaboration.h"
3841
#include "xls/ir/events.h"
3942
#include "xls/ir/node.h"
4043
#include "xls/ir/nodes.h"
@@ -179,16 +182,24 @@ absl::StatusOr<std::vector<absl::flat_hash_map<std::string, Value>>>
179182
BlockEvaluator::EvaluateSequentialBlock(
180183
Block* block,
181184
absl::Span<const absl::flat_hash_map<std::string, Value>> inputs) const {
185+
XLS_ASSIGN_OR_RETURN(BlockElaboration elaboration,
186+
BlockElaboration::Elaborate(block));
182187
// Initial register state is zero for all registers.
183188
absl::flat_hash_map<std::string, Value> reg_state;
184-
for (Register* reg : block->GetRegisters()) {
185-
reg_state[reg->name()] = ZeroOfType(reg->type());
189+
for (BlockInstance* inst : elaboration.instances()) {
190+
if (!inst->block().has_value()) {
191+
continue;
192+
}
193+
for (Register* reg : inst->block().value()->GetRegisters()) {
194+
reg_state[absl::StrCat(inst->RegisterPrefix(), reg->name())] =
195+
ZeroOfType(reg->type());
196+
}
186197
}
187198

188199
std::vector<absl::flat_hash_map<std::string, Value>> outputs;
189200
for (const absl::flat_hash_map<std::string, Value>& input_set : inputs) {
190201
XLS_ASSIGN_OR_RETURN(BlockRunResult result,
191-
EvaluateBlock(input_set, reg_state, block));
202+
EvaluateBlock(input_set, reg_state, elaboration));
192203
outputs.push_back(std::move(result.outputs));
193204
reg_state = std::move(result.reg_state);
194205
}
@@ -394,10 +405,21 @@ BlockEvaluator::EvaluateChannelizedSequentialBlock(
394405
std::minstd_rand random_engine;
395406
random_engine.seed(seed);
396407

408+
XLS_ASSIGN_OR_RETURN(BlockElaboration elaboration,
409+
BlockElaboration::Elaborate(block));
410+
397411
// Initial register state is zero for all registers.
398412
absl::flat_hash_map<std::string, Value> reg_state;
399-
for (Register* reg : block->GetRegisters()) {
400-
reg_state[reg->name()] = ZeroOfType(reg->type());
413+
for (BlockInstance* inst : elaboration.instances()) {
414+
// Instance isn't a BlockInstantiation, must be e.g. a FIFO or FFI
415+
// instantiation. No registers to initialize.
416+
if (!inst->block().has_value()) {
417+
continue;
418+
}
419+
for (Register* reg : inst->block().value()->GetRegisters()) {
420+
reg_state[absl::StrCat(inst->RegisterPrefix(), reg->name())] =
421+
ZeroOfType(reg->type());
422+
}
401423
}
402424

403425
int64_t max_cycle_count = inputs.size();
@@ -427,7 +449,7 @@ BlockEvaluator::EvaluateChannelizedSequentialBlock(
427449

428450
// Block results
429451
XLS_ASSIGN_OR_RETURN(BlockRunResult result,
430-
EvaluateBlock(input_set, reg_state, block));
452+
EvaluateBlock(input_set, reg_state, elaboration));
431453

432454
// Sources get ready
433455
for (ChannelSource& src : channel_sources) {
@@ -503,9 +525,10 @@ BlockEvaluator::EvaluateChannelizedSequentialBlockWithUint64(
503525
namespace {
504526
class BaseBlockContinuation final : public BlockContinuation {
505527
public:
506-
BaseBlockContinuation(Block* block, BlockRunResult&& initial_result,
528+
BaseBlockContinuation(BlockElaboration&& block,
529+
BlockRunResult&& initial_result,
507530
const BlockEvaluator& evaluator)
508-
: block_(block),
531+
: elaboration_(std::move(block)),
509532
last_result_(std::move(initial_result)),
510533
evaluator_(evaluator) {}
511534

@@ -525,7 +548,7 @@ class BaseBlockContinuation final : public BlockContinuation {
525548
const absl::flat_hash_map<std::string, Value>& inputs) final {
526549
XLS_ASSIGN_OR_RETURN(
527550
last_result_,
528-
evaluator_.EvaluateBlock(inputs, last_result_.reg_state, block_));
551+
evaluator_.EvaluateBlock(inputs, last_result_.reg_state, elaboration_));
529552
return absl::OkStatus();
530553
}
531554

@@ -540,7 +563,7 @@ class BaseBlockContinuation final : public BlockContinuation {
540563
}
541564

542565
private:
543-
Block* block_;
566+
BlockElaboration elaboration_;
544567
BlockRunResult last_result_;
545568
const BlockEvaluator& evaluator_;
546569
};
@@ -550,18 +573,36 @@ absl::StatusOr<std::unique_ptr<BlockContinuation>>
550573
BlockEvaluator::NewContinuation(
551574
Block* block,
552575
const absl::flat_hash_map<std::string, Value>& initial_registers) const {
553-
return std::make_unique<BaseBlockContinuation>(
554-
block, BlockRunResult{.reg_state = initial_registers}, *this);
576+
XLS_ASSIGN_OR_RETURN(BlockElaboration elaboration,
577+
BlockElaboration::Elaborate(block));
578+
return NewContinuation(std::move(elaboration), initial_registers);
555579
}
556580

557581
absl::StatusOr<std::unique_ptr<BlockContinuation>>
558582
BlockEvaluator::NewContinuation(Block* block) const {
583+
XLS_ASSIGN_OR_RETURN(BlockElaboration elaboration,
584+
BlockElaboration::Elaborate(block));
559585
absl::flat_hash_map<std::string, Value> regs;
560586
regs.reserve(block->GetRegisters().size());
561-
for (const auto reg : block->GetRegisters()) {
562-
regs[reg->name()] = ZeroOfType(reg->type());
587+
for (BlockInstance* inst : elaboration.instances()) {
588+
if (!inst->block().has_value()) {
589+
continue;
590+
}
591+
for (const auto reg : inst->block().value()->GetRegisters()) {
592+
regs[absl::StrCat(inst->RegisterPrefix(), reg->name())] =
593+
ZeroOfType(reg->type());
594+
}
563595
}
564-
return NewContinuation(block, regs);
596+
return NewContinuation(std::move(elaboration), regs);
597+
}
598+
599+
absl::StatusOr<std::unique_ptr<BlockContinuation>>
600+
BlockEvaluator::NewContinuation(
601+
BlockElaboration&& elaboration,
602+
const absl::flat_hash_map<std::string, Value>& initial_registers) const {
603+
return std::make_unique<BaseBlockContinuation>(
604+
std::move(elaboration), BlockRunResult{.reg_state = initial_registers},
605+
*this);
565606
}
566607

567608
} // namespace xls

Diff for: xls/interpreter/block_evaluator.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "absl/types/span.h"
3030
#include "xls/codegen/module_signature.pb.h"
3131
#include "xls/ir/block.h"
32+
#include "xls/ir/block_elaboration.h"
3233
#include "xls/ir/events.h"
3334
#include "xls/ir/value.h"
3435

@@ -211,10 +212,9 @@ class BlockEvaluator {
211212
// Create a new block continuation with all registers initialized to the given
212213
// values. This continuation can be used to feed input values in
213214
// cycle-by-cycle.
214-
virtual absl::StatusOr<std::unique_ptr<BlockContinuation>> NewContinuation(
215+
absl::StatusOr<std::unique_ptr<BlockContinuation>> NewContinuation(
215216
Block* block,
216-
const absl::flat_hash_map<std::string, Value>& initial_registers)
217-
const;
217+
const absl::flat_hash_map<std::string, Value>& initial_registers) const;
218218

219219
// Create a new block continuation with all registers initialized to zero
220220
// values. This continuation can be used to feed input values in
@@ -228,7 +228,7 @@ class BlockEvaluator {
228228
virtual absl::StatusOr<BlockRunResult> EvaluateBlock(
229229
const absl::flat_hash_map<std::string, Value>& inputs,
230230
const absl::flat_hash_map<std::string, Value>& registers,
231-
Block* block) const = 0;
231+
const BlockElaboration& elaboration) const = 0;
232232

233233
// The name of this evaluator for debug purposes.
234234
std::string_view name() const { return name_; }
@@ -362,6 +362,10 @@ class BlockEvaluator {
362362
}
363363

364364
protected:
365+
virtual absl::StatusOr<std::unique_ptr<BlockContinuation>> NewContinuation(
366+
BlockElaboration&& elaboration,
367+
const absl::flat_hash_map<std::string, Value>& initial_registers) const;
368+
365369
std::string_view name_;
366370
};
367371

0 commit comments

Comments
 (0)