Skip to content

Commit 9c1dd68

Browse files
NL02copybara-github
authored andcommitted
[Explicit State Access] Guard state_read references in schedule_graph and clone_nodes_into_block
PiperOrigin-RevId: 951672414
1 parent 89209a0 commit 9c1dd68

4 files changed

Lines changed: 69 additions & 7 deletions

File tree

xls/codegen/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,7 @@ cc_test(
20662066
"//xls/ir:function_builder",
20672067
"//xls/ir:op",
20682068
"//xls/ir:proc_elaboration",
2069+
"//xls/ir:value",
20692070
"//xls/scheduling:pipeline_schedule",
20702071
"//xls/scheduling:run_pipeline_schedule",
20712072
"//xls/scheduling:scheduling_options",

xls/codegen/clone_nodes_into_block_handler.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -760,15 +760,18 @@ absl::Status CloneNodesIntoBlockHandler::HandleNextValue(Node* node,
760760
Stage stage) {
761761
Proc* proc = function_base_->AsProcOrDie();
762762
Next* next = node->As<Next>();
763-
StateElement* state_element =
764-
next->state_read()->As<StateRead>()->state_element();
763+
StateElement* state_element = next->state_element();
765764
XLS_ASSIGN_OR_RETURN(int64_t index,
766765
proc->GetStateElementIndex(state_element));
767766

768767
StateRegister& state_register = *result_.state_registers.at(index);
768+
bool equivalent_value =
769+
next->has_state_read()
770+
? next->value() == next->state_read()
771+
: next->value() == proc->GetStateReadByStateElement(state_element);
769772
state_register.next_values.push_back(
770773
{.stage = stage,
771-
.value = next->value() == next->state_read()
774+
.value = equivalent_value
772775
? std::nullopt
773776
: std::make_optional(node_map_.at(next->value())),
774777
.predicate =

xls/codegen/synchronous_procs_test.cc

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "xls/ir/op.h"
3939
#include "xls/ir/package.h"
4040
#include "xls/ir/proc_elaboration.h"
41+
#include "xls/ir/value.h"
4142
#include "xls/scheduling/pipeline_schedule.h"
4243
#include "xls/scheduling/run_pipeline_schedule.h"
4344
#include "xls/scheduling/scheduling_options.h"
@@ -244,6 +245,60 @@ TEST_P(SynchronousProcsTest, ChainedProc) {
244245
absl_testing::IsOkAndHolds(outputs));
245246
}
246247

248+
TEST_P(SynchronousProcsTest, DecoupledNextProc) {
249+
Package package(TestBaseName());
250+
251+
TokenlessProcBuilder pb(NewStyleProc(), "my_proc", "tkn", &package);
252+
Type* u32 = package.GetBitsType(32);
253+
BReceiveChannel in = pb.AddInputChannel("top_in", u32);
254+
BSendChannel out = pb.AddOutputChannel("top_out", u32);
255+
BStateElement st_elem = pb.UnreadStateElement("accum", Value(UBits(0, 32)),
256+
/*non_synthesizable=*/false);
257+
BValue st = pb.StateRead(st_elem);
258+
BValue received = pb.Receive(in);
259+
BValue next_st = pb.Add(st, received);
260+
261+
pb.Next(st_elem, next_st);
262+
pb.Send(out, next_st);
263+
264+
XLS_ASSERT_OK_AND_ASSIGN(Proc * top, pb.Build({}));
265+
XLS_ASSERT_OK(package.SetTop(top));
266+
267+
ASSERT_TRUE(top->uses_decoupled_next());
268+
269+
XLS_ASSERT_OK_AND_ASSIGN(ProcElaboration elab,
270+
ProcElaboration::Elaborate(top));
271+
272+
XLS_ASSERT_OK_AND_ASSIGN(PackageSchedule package_schedule,
273+
RunSynchronousPipelineSchedule(
274+
&package, TestDelayEstimator(),
275+
SchedulingOptions().clock_period_ps(1), elab));
276+
277+
ResetProto reset_proto;
278+
reset_proto.set_name("rst");
279+
reset_proto.set_asynchronous(false);
280+
reset_proto.set_active_low(false);
281+
282+
XLS_ASSERT_OK_AND_ASSIGN(
283+
CodegenResult result,
284+
ToPipelineModuleText(
285+
package_schedule, &package,
286+
BuildPipelineOptions()
287+
.reset(reset_proto.name(), reset_proto.asynchronous(),
288+
reset_proto.active_low(), reset_proto.reset_data_path())
289+
.use_system_verilog(UseSystemVerilog())
290+
.emit_as_pipeline(false)));
291+
292+
ModuleSimulator simulator =
293+
NewModuleSimulator(result.verilog_text, result.signature, {});
294+
absl::flat_hash_map<std::string, std::vector<Bits>> inputs = {
295+
{"top_in", {UBits(3, 32), UBits(10, 32), UBits(42, 32)}}};
296+
absl::flat_hash_map<std::string, std::vector<Bits>> outputs = {
297+
{"top_out", {UBits(3, 32), UBits(13, 32), UBits(55, 32)}}};
298+
EXPECT_THAT(simulator.RunInputSeriesProc(inputs, {{"top_out", 3}}),
299+
absl_testing::IsOkAndHolds(outputs));
300+
}
301+
247302
INSTANTIATE_TEST_SUITE_P(PipelineGeneratorTestInstantiation,
248303
SynchronousProcsTest,
249304
testing::ValuesIn(kDefaultSimulationTargets),

xls/scheduling/schedule_graph.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,13 @@ absl::StatusOr<ScheduleGraph> ScheduleGraph::CreateSynchronousGraph(
308308
}
309309

310310
for (Next* next : proc->next_values()) {
311-
backedges.push_back(
312-
ScheduleBackedge{.source = next,
313-
.destination = next->state_read(),
314-
.distance = LessThanInitiationInterval()});
311+
backedges.push_back(ScheduleBackedge{
312+
.source = next,
313+
.destination =
314+
next->has_state_read()
315+
? next->state_read()
316+
: proc->GetStateReadByStateElement(next->state_element()),
317+
.distance = LessThanInitiationInterval()});
315318
}
316319
}
317320

0 commit comments

Comments
 (0)