diff --git a/xls/codegen_v_1_5/BUILD b/xls/codegen_v_1_5/BUILD index 7762c31ec1..d345d24034 100644 --- a/xls/codegen_v_1_5/BUILD +++ b/xls/codegen_v_1_5/BUILD @@ -1003,10 +1003,12 @@ cc_library( cc_test( name = "codegen_test", srcs = [ + "codegen_combinational_function_test.cc", "codegen_function_test.cc", "codegen_proc_test.cc", ], data = glob([ + "testdata/codegen_combinational_function_test_*", "testdata/codegen_function_test_*", "testdata/codegen_proc_test_*", ]), @@ -1018,17 +1020,24 @@ cc_test( "//xls/codegen:module_signature", "//xls/codegen:module_signature_cc_proto", "//xls/codegen:test_fifos", + "//xls/codegen/vast", "//xls/common:golden_files", "//xls/common:xls_gunit_main", "//xls/common/status:matchers", "//xls/common/status:status_macros", "//xls/estimators/delay_model:delay_estimator", + "//xls/examples:sample_packages", + "//xls/interpreter:ir_interpreter", + "//xls/interpreter:random_value", "//xls/ir", "//xls/ir:bits", "//xls/ir:channel", + "//xls/ir:clone_package", + "//xls/ir:events", "//xls/ir:function_builder", "//xls/ir:ir_parser", "//xls/ir:op", + "//xls/ir:source_location", "//xls/ir:value", "//xls/scheduling:scheduling_options", "//xls/simulation:module_simulator", @@ -1040,6 +1049,7 @@ cc_test( "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", + "@com_google_absl//absl/types:span", "@googletest//:gtest", ], ) diff --git a/xls/codegen_v_1_5/codegen_combinational_function_test.cc b/xls/codegen_v_1_5/codegen_combinational_function_test.cc new file mode 100644 index 0000000000..d2ecb1c804 --- /dev/null +++ b/xls/codegen_v_1_5/codegen_combinational_function_test.cc @@ -0,0 +1,2242 @@ +// Copyright 2026 The XLS Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/container/flat_hash_map.h" +#include "absl/status/statusor.h" +#include "absl/types/span.h" +#include "xls/codegen/codegen_options.h" +#include "xls/codegen/codegen_result.h" +#include "xls/codegen/module_signature.pb.h" +#include "xls/codegen/vast/vast.h" +#include "xls/codegen_v_1_5/codegen.h" +#include "xls/common/status/matchers.h" +#include "xls/common/status/status_macros.h" +#include "xls/estimators/delay_model/delay_estimator.h" +#include "xls/examples/sample_packages.h" +#include "xls/interpreter/function_interpreter.h" +#include "xls/interpreter/random_value.h" +#include "xls/ir/bits.h" +#include "xls/ir/clone_package.h" +#include "xls/ir/events.h" +#include "xls/ir/function_builder.h" +#include "xls/ir/ir_parser.h" +#include "xls/ir/op.h" +#include "xls/ir/package.h" +#include "xls/ir/source_location.h" +#include "xls/ir/value.h" +#include "xls/scheduling/scheduling_options.h" +#include "xls/simulation/module_simulator.h" +#include "xls/simulation/module_testbench.h" +#include "xls/simulation/module_testbench_thread.h" +#include "xls/simulation/verilog_test_base.h" + +namespace xls::codegen { +namespace { + +using ::absl_testing::IsOkAndHolds; + +constexpr char kTestName[] = "codegen_combinational_function_test"; +constexpr char kTestdataPath[] = "xls/codegen_v_1_5/testdata"; + +class TestDelayEstimator : public DelayEstimator { + public: + TestDelayEstimator() : DelayEstimator("test") {} + + absl::StatusOr GetOperationDelayInPs(Node* node) const override { + switch (node->op()) { + case Op::kParam: + case Op::kStateRead: + case Op::kLiteral: + case Op::kBitSlice: + case Op::kConcat: + return 0; + default: + return 1; + } + } +}; + +class CodegenCombinationalFunctionTest : public verilog::VerilogTestBase { + protected: + absl::StatusOr GenerateCombinationalModule( + FunctionBase* top, const verilog::CodegenOptions& codegen_options) { + Package* package = top->package(); + XLS_RETURN_IF_ERROR(package->SetTop(top)); + return Codegen(package, codegen_options, SchedulingOptions(), + /*delay_estimator=*/nullptr); + } + + verilog::CodegenOptions codegen_options() { + return verilog::VerilogTestBase::codegen_options().generate_combinational( + true); + } +}; + +TEST_P(CodegenCombinationalFunctionTest, RrotToText) { + auto rrot32_data = sample_packages::BuildRrot32(); + Function* f = rrot32_data.second; + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", UBits(0x12345678ULL, 32)}, {"y", UBits(4, 32)}}), + IsOkAndHolds(UBits(0x81234567, 32))); +} + +TEST_P(CodegenCombinationalFunctionTest, RandomExpression) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", u8); + auto b = fb.Param("b", u8); + auto c = fb.Param("c", u8); + auto a_minus_b = fb.Subtract(a, b, SourceInfo(), /*name=*/"diff"); + auto lhs = (a_minus_b * a_minus_b); + auto rhs = (c * a_minus_b); + auto out = fb.Add(lhs, rhs, SourceInfo(), /*name=*/"the_output"); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(out)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + + // Value should be: (7-2)*(7-2) + 3*(7-2) = 40 + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"a", UBits(7, 8)}, {"b", UBits(2, 8)}, {"c", UBits(3, 8)}}), + IsOkAndHolds(UBits(40, 8))); +} + +TEST_P(CodegenCombinationalFunctionTest, ReturnsLiteral) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + fb.Literal(UBits(123, 8)); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunAndReturnSingleOutput(verilog::ModuleSimulator::BitsMap()), + IsOkAndHolds(UBits(123, 8))); +} + +TEST_P(CodegenCombinationalFunctionTest, ReturnsTupleLiteral) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + fb.Literal(Value::Tuple({Value(UBits(123, 8)), Value(UBits(42, 32))})); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction(absl::flat_hash_map()), + IsOkAndHolds(Value::Tuple({Value(UBits(123, 8)), Value(UBits(42, 32))}))); +} + +TEST_P(CodegenCombinationalFunctionTest, ReturnsEmptyTuple) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + fb.Literal(Value::Tuple({})); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction(absl::flat_hash_map()), + IsOkAndHolds(Value::Tuple({}))); +} + +TEST_P(CodegenCombinationalFunctionTest, PassesEmptyTuple) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + fb.Param("x", package.GetTupleType({})); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction({{"x", Value::Tuple({})}}), + IsOkAndHolds(Value::Tuple({}))); +} + +TEST_P(CodegenCombinationalFunctionTest, TakesEmptyTuple) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", u8); + fb.Param("b", package.GetTupleType({})); + auto c = fb.Param("c", u8); + fb.Add(a, c, SourceInfo(), /*name=*/"sum"); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction({{"a", Value(UBits(42, 8))}, + {"b", Value::Tuple({})}, + {"c", Value(UBits(100, 8))}}), + IsOkAndHolds(Value(UBits(142, 8)))); +} + +TEST_P(CodegenCombinationalFunctionTest, ReturnsParam) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + fb.Param("a", u8); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunAndReturnSingleOutput({{"a", UBits(0x42, 8)}}), + IsOkAndHolds(UBits(0x42, 8))); +} + +TEST_P(CodegenCombinationalFunctionTest, + CombinationalExpressionWhichRequiresNamedIntermediate) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", u8); + auto b = fb.Param("b", u8); + auto a_plus_b = a + b; + auto out = fb.BitSlice(a_plus_b, /*start=*/3, /*width=*/4, SourceInfo(), + /*name=*/"slice_n_dice"); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(out)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"a", UBits(0x42, 8)}, {"b", UBits(0x33, 8)}}), + IsOkAndHolds(UBits(14, 4))); +} + +TEST_P(CodegenCombinationalFunctionTest, ExpressionsOfTuples) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + Type* u10 = package.GetBitsType(10); + Type* u16 = package.GetBitsType(16); + Type* tuple_u10_u16 = package.GetTupleType({u10, u16}); + auto a = fb.Param("a", u8); + auto b = fb.Param("b", u10); + auto c = fb.Param("c", tuple_u10_u16); + + // Glom all the inputs together into a big tuple. + auto a_b_c = fb.Tuple({a, b, c}, SourceInfo(), /*name=*/"big_tuple"); + + // Then extract some elements and perform some arithmetic operations on them + // after zero-extending them to the same width (16-bits). + auto a_plus_b = fb.ZeroExtend(fb.TupleIndex(a_b_c, 0), 16) + + fb.ZeroExtend(fb.TupleIndex(a_b_c, 1), 16); + auto c_tmp = fb.TupleIndex(a_b_c, 2); + auto c0_minus_c1 = + fb.ZeroExtend(fb.TupleIndex(c_tmp, 0), 16) - fb.TupleIndex(c_tmp, 1); + + // Result should be a two-tuple containing {a + b, c[0] - c[1]} + auto return_value = fb.Tuple({a_plus_b, c0_minus_c1}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(return_value)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction({{"a", Value(UBits(42, 8))}, + {"b", Value(UBits(123, 10))}, + {"c", Value::Tuple({Value(UBits(333, 10)), + Value(UBits(222, 16))})}}), + IsOkAndHolds( + Value::Tuple({Value(UBits(165, 16)), Value(UBits(111, 16))}))); +} + +TEST_P(CodegenCombinationalFunctionTest, TupleLiterals) { + std::string text = R"( +package TupleLiterals + +top fn main(x: bits[123]) -> bits[123] { + literal.1: (bits[123], bits[123], bits[123]) = literal(value=(0x10000, 0x2000, 0x300)) + tuple_index.2: bits[123] = tuple_index(literal.1, index=0) + tuple_index.3: bits[123] = tuple_index(literal.1, index=1) + tuple_index.4: bits[123] = tuple_index(literal.1, index=2) + sum1: bits[123] = add(tuple_index.2, tuple_index.3) + sum2: bits[123] = add(tuple_index.4, x) + ret total: bits[123] = add(sum1, sum2) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction({{"x", Value(UBits(0x40, 123))}}), + IsOkAndHolds(Value(UBits(0x12340, 123)))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayLiteral) { + std::string text = R"( +package ArrayLiterals + +top fn main(x: bits[32], y: bits[32]) -> bits[44] { + literal.1: bits[44][3][2] = literal(value=[[1, 2, 3], [4, 5, 6]]) + array_index.2: bits[44][3] = array_index(literal.1, indices=[x]) + ret result: bits[44] = array_index(array_index.2, indices=[y]) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction( + {{"x", Value(UBits(0, 32))}, {"y", Value(UBits(1, 32))}}), + IsOkAndHolds(Value(UBits(2, 44)))); + EXPECT_THAT(simulator.RunFunction( + {{"x", Value(UBits(1, 32))}, {"y", Value(UBits(0, 32))}}), + IsOkAndHolds(Value(UBits(4, 44)))); +} + +TEST_P(CodegenCombinationalFunctionTest, OneHot) { + std::string text = R"( +package OneHot + +top fn main(x: bits[3]) -> bits[4] { + ret one_hot.1: bits[4] = one_hot(x, lsb_prio=true) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction({{"x", Value(UBits(0b000, 3))}}), + IsOkAndHolds(Value(UBits(0b1000, 4)))); + EXPECT_THAT(simulator.RunFunction({{"x", Value(UBits(0b001, 3))}}), + IsOkAndHolds(Value(UBits(0b0001, 4)))); + EXPECT_THAT(simulator.RunFunction({{"x", Value(UBits(0b010, 3))}}), + IsOkAndHolds(Value(UBits(0b0010, 4)))); + EXPECT_THAT(simulator.RunFunction({{"x", Value(UBits(0b011, 3))}}), + IsOkAndHolds(Value(UBits(0b0001, 4)))); + EXPECT_THAT(simulator.RunFunction({{"x", Value(UBits(0b100, 3))}}), + IsOkAndHolds(Value(UBits(0b0100, 4)))); + EXPECT_THAT(simulator.RunFunction({{"x", Value(UBits(0b101, 3))}}), + IsOkAndHolds(Value(UBits(0b0001, 4)))); + EXPECT_THAT(simulator.RunFunction({{"x", Value(UBits(0b110, 3))}}), + IsOkAndHolds(Value(UBits(0b0010, 4)))); + EXPECT_THAT(simulator.RunFunction({{"x", Value(UBits(0b111, 3))}}), + IsOkAndHolds(Value(UBits(0b0001, 4)))); +} + +TEST_P(CodegenCombinationalFunctionTest, OneHotSelect) { + std::string text = R"( +package OneHotSelect + +top fn main(p: bits[2], x: bits[16], y: bits[16]) -> bits[16] { + ret one_hot_sel.1: bits[16] = one_hot_sel(p, cases=[x, y]) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + absl::flat_hash_map args = { + {"x", Value(UBits(0x00ff, 16))}, {"y", Value(UBits(0xf0f0, 16))}}; + args["p"] = Value(UBits(0b00, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0x0000, 16)))); + args["p"] = Value(UBits(0b01, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0x00ff, 16)))); + args["p"] = Value(UBits(0b10, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0xf0f0, 16)))); + args["p"] = Value(UBits(0b11, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0xf0ff, 16)))); +} + +TEST_P(CodegenCombinationalFunctionTest, OneHotSelectNonBits) { + std::string text = R"( +package OneHotSelect + +top fn main(p: bits[2], x: (bits[16], bits[16]), y: (bits[16], bits[16])) -> (bits[16], bits[16]) { + ret one_hot_sel.1: (bits[16], bits[16]) = one_hot_sel(p, cases=[x, y]) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + absl::flat_hash_map args = { + {"x", Value::Tuple({Value(UBits(0x00ff, 16)), Value(UBits(0xff00, 16))})}, + {"y", + Value::Tuple({Value(UBits(0xf0f0, 16)), Value(UBits(0x0f0f, 16))})}}; + args["p"] = Value(UBits(0b00, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0x0000, 16)), Value(UBits(0x0000, 16))}))); + args["p"] = Value(UBits(0b01, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0x00ff, 16)), Value(UBits(0xff00, 16))}))); + args["p"] = Value(UBits(0b10, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0xf0f0, 16)), Value(UBits(0x0f0f, 16))}))); + args["p"] = Value(UBits(0b11, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0xf0ff, 16)), Value(UBits(0xff0f, 16))}))); +} + +TEST_P(CodegenCombinationalFunctionTest, PrioritySelect) { + std::string text = R"( +package PrioritySelect + +top fn main(p: bits[2], x: bits[16], y: bits[16], d: bits[16]) -> bits[16] { + ret priority_sel.1: bits[16] = priority_sel(p, cases=[x, y], default=d) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + absl::flat_hash_map args = { + {"x", Value(UBits(0x00ff, 16))}, + {"y", Value(UBits(0xf0f0, 16))}, + {"d", Value(UBits(0xff00, 16))}}; + args["p"] = Value(UBits(0b00, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0xff00, 16)))); + args["p"] = Value(UBits(0b01, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0x00ff, 16)))); + args["p"] = Value(UBits(0b10, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0xf0f0, 16)))); + args["p"] = Value(UBits(0b11, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0x00ff, 16)))); +} + +TEST_P(CodegenCombinationalFunctionTest, PrioritySelectMultipleAreMerged) { + std::string text = R"( +package PrioritySelect + +top fn main(p: bits[2], x: bits[16], y: bits[16], d: bits[16]) -> bits[16] { + priority_sel.1: bits[16] = priority_sel(p, cases=[x, y], default=d) + priority_sel.2: bits[16] = priority_sel(p, cases=[y, x], default=d) + ret add.3: bits[16] = add(priority_sel.1, priority_sel.2) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + absl::flat_hash_map args = { + {"x", Value(UBits(0x00ff, 16))}, + {"y", Value(UBits(0xf0f0, 16))}, + {"d", Value(UBits(0xff00, 16))}}; + args["p"] = Value(UBits(0b00, 2)); + // both priority selects return 0xff00, 0xff00 + 0xff00 = 0xfe00 + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0xfe00, 16)))); + args["p"] = Value(UBits(0b01, 2)); + // sum = 0x00ff + 0xf0f0 = 0xf1ef + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0xf1ef, 16)))); + args["p"] = Value(UBits(0b10, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0xf1ef, 16)))); + args["p"] = Value(UBits(0b11, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0xf1ef, 16)))); +} + +TEST_P(CodegenCombinationalFunctionTest, PrioritySelectWithAndWithoutDefault) { + // Tests that the different specialized ways of codegen'ing priority selects + // are applied in the right context, e.g. we don't make a no-default priority + // select function and call it later for a needs-default priority select. + std::string text = R"( +package PrioritySelect + +top fn main(p: bits[2], x: bits[16], y: bits[16], d: bits[16]) -> (bits[16], bits[16]) { + literal.1: bits[2] = literal(value=1) + or.2: bits[2] = or(p, literal.1) + priority_sel.3: bits[16] = priority_sel(or.2, cases=[x, y], default=d) + priority_sel.4: bits[16] = priority_sel(p, cases=[x, y], default=d) + ret tuple.5: (bits[16], bits[16]) = tuple(priority_sel.3, priority_sel.4) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + absl::flat_hash_map args = { + {"x", Value(UBits(0x00ff, 16))}, + {"y", Value(UBits(0xf0f0, 16))}, + {"d", Value(UBits(0xff00, 16))}}; + args["p"] = Value(UBits(0b00, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0x00ff, 16)), Value(UBits(0xff00, 16))}))); + args["p"] = Value(UBits(0b01, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0x00ff, 16)), Value(UBits(0x00ff, 16))}))); + args["p"] = Value(UBits(0b10, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0x00ff, 16)), Value(UBits(0xf0f0, 16))}))); + args["p"] = Value(UBits(0b11, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0x00ff, 16)), Value(UBits(0x00ff, 16))}))); +} + +TEST_P(CodegenCombinationalFunctionTest, PrioritySelectOneHot) { + std::string text = R"( +package PrioritySelectOneHot + +top fn main(p: bits[1], x: bits[16], y: bits[16], d: bits[16]) -> bits[16] { + one_hot.1: bits[2] = one_hot(p, lsb_prio=true) + ret priority_sel.2: bits[16] = priority_sel(one_hot.1, cases=[x, y], default=d) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + absl::flat_hash_map args = { + {"x", Value(UBits(0x00ff, 16))}, + {"y", Value(UBits(0xf0f0, 16))}, + {"d", Value(UBits(0xff00, 16))}}; + args["p"] = Value(UBits(0b0, 1)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0xf0f0, 16)))); + args["p"] = Value(UBits(0b1, 1)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value(UBits(0x00ff, 16)))); +} + +TEST_P(CodegenCombinationalFunctionTest, PrioritySelectArray) { + std::string text = R"( +package PrioritySelectArray + +top fn main(p: bits[2], x: bits[16][4], y: bits[16][4], d: bits[16][4]) -> bits[16][4] { + ret priority_sel.1: bits[16][4] = priority_sel(p, cases=[x, y], default=d) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + XLS_ASSERT_OK_AND_ASSIGN( + Value x_value, Value::UBitsArray({0x00ff, 0x00ff, 0x00ff, 0x00ff}, 16)); + XLS_ASSERT_OK_AND_ASSIGN( + Value y_value, Value::UBitsArray({0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0}, 16)); + XLS_ASSERT_OK_AND_ASSIGN( + Value d_value, Value::UBitsArray({0xff00, 0xff00, 0xff00, 0xff00}, 16)); + absl::flat_hash_map args = { + {"x", x_value}, {"y", y_value}, {"d", d_value}}; + args["p"] = Value(UBits(0b00, 2)); + EXPECT_THAT(simulator.RunFunction(args), IsOkAndHolds(d_value)); + args["p"] = Value(UBits(0b01, 2)); + EXPECT_THAT(simulator.RunFunction(args), IsOkAndHolds(x_value)); + args["p"] = Value(UBits(0b10, 2)); + EXPECT_THAT(simulator.RunFunction(args), IsOkAndHolds(y_value)); + args["p"] = Value(UBits(0b11, 2)); + EXPECT_THAT(simulator.RunFunction(args), IsOkAndHolds(x_value)); +} + +TEST_P(CodegenCombinationalFunctionTest, + PrioritySelectMultipleArraysWithSameElementType) { + std::string text = R"( +package PrioritySelectArraysWithSameElementType + +top fn main(p: bits[2], x_short: bits[16][2], x_long: bits[16][4], y_short: bits[16][2], y_long: bits[16][4], d_short: bits[16][2], d_long: bits[16][4]) -> (bits[16][2], bits[16][4]) { + priority_sel.1: bits[16][2] = priority_sel(p, cases=[x_short, y_short], default=d_short) + priority_sel.2: bits[16][4] = priority_sel(p, cases=[x_long, y_long], default=d_long) + ret tuple.3: (bits[16][2], bits[16][4]) = tuple(priority_sel.1, priority_sel.2) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + XLS_ASSERT_OK_AND_ASSIGN(Value x_short_value, + Value::UBitsArray({0x00ff, 0x00ff}, 16)); + XLS_ASSERT_OK_AND_ASSIGN(Value y_short_value, + Value::UBitsArray({0xf0f0, 0xf0f0}, 16)); + XLS_ASSERT_OK_AND_ASSIGN(Value d_short_value, + Value::UBitsArray({0xff00, 0xff00}, 16)); + XLS_ASSERT_OK_AND_ASSIGN( + Value x_long_value, + Value::UBitsArray({0x00ff, 0x00ff, 0x00ff, 0x00ff}, 16)); + XLS_ASSERT_OK_AND_ASSIGN( + Value y_long_value, + Value::UBitsArray({0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0}, 16)); + XLS_ASSERT_OK_AND_ASSIGN( + Value d_long_value, + Value::UBitsArray({0xff00, 0xff00, 0xff00, 0xff00}, 16)); + absl::flat_hash_map args = { + {"x_short", x_short_value}, {"y_short", y_short_value}, + {"d_short", d_short_value}, {"x_long", x_long_value}, + {"y_long", y_long_value}, {"d_long", d_long_value}}; + args["p"] = Value(UBits(0b00, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple({d_short_value, d_long_value}))); + args["p"] = Value(UBits(0b01, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple({x_short_value, x_long_value}))); + args["p"] = Value(UBits(0b10, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple({y_short_value, y_long_value}))); + args["p"] = Value(UBits(0b11, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple({x_short_value, x_long_value}))); +} + +TEST_P(CodegenCombinationalFunctionTest, PrioritySelectArrayOneHot) { + std::string text = R"( +package PrioritySelectArrayOneHot + +top fn main(p: bits[1], x: bits[16][4], y: bits[16][4], d: bits[16][4]) -> bits[16][4] { + one_hot.1: bits[2] = one_hot(p, lsb_prio=true) + ret priority_sel.2: bits[16][4] = priority_sel(one_hot.1, cases=[x, y], default=d) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + XLS_ASSERT_OK_AND_ASSIGN( + Value x_value, Value::UBitsArray({0x00ff, 0x00ff, 0x00ff, 0x00ff}, 16)); + XLS_ASSERT_OK_AND_ASSIGN( + Value y_value, Value::UBitsArray({0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0}, 16)); + XLS_ASSERT_OK_AND_ASSIGN( + Value d_value, Value::UBitsArray({0xff00, 0xff00, 0xff00, 0xff00}, 16)); + absl::flat_hash_map args = { + {"x", x_value}, {"y", y_value}, {"d", d_value}}; + args["p"] = Value(UBits(0b0, 1)); + EXPECT_THAT(simulator.RunFunction(args), IsOkAndHolds(y_value)); + args["p"] = Value(UBits(0b1, 1)); + EXPECT_THAT(simulator.RunFunction(args), IsOkAndHolds(x_value)); +} + +TEST_P(CodegenCombinationalFunctionTest, PrioritySelectNonBits) { + constexpr std::string_view text = R"( +package PrioritySelect + +top fn main(p: bits[2], x: (bits[16], bits[16]), y: (bits[16], bits[16]), d: (bits[16], bits[16])) -> (bits[16], bits[16]) { + ret priority_sel.1: (bits[16], bits[16]) = priority_sel(p, cases=[x, y], default=d) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + absl::flat_hash_map args = { + {"x", Value::Tuple({Value(UBits(0x00ff, 16)), Value(UBits(0xff00, 16))})}, + {"y", Value::Tuple({Value(UBits(0xf0f0, 16)), Value(UBits(0x0f0f, 16))})}, + {"d", Value::Tuple({Value(UBits(0xff00, 16)), Value(UBits(0x00ff, 16))})}, + }; + args["p"] = Value(UBits(0b00, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0xff00, 16)), Value(UBits(0x00ff, 16))}))); + args["p"] = Value(UBits(0b01, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0x00ff, 16)), Value(UBits(0xff00, 16))}))); + args["p"] = Value(UBits(0b10, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0xf0f0, 16)), Value(UBits(0x0f0f, 16))}))); + args["p"] = Value(UBits(0b11, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple( + {Value(UBits(0x00ff, 16)), Value(UBits(0xff00, 16))}))); +} + +TEST_P(CodegenCombinationalFunctionTest, PrioritySelectMixedBitsAndNonBits) { + constexpr std::string_view text = R"( +package PrioritySelect + +top fn main(p: bits[2], x: (bits[16], bits[16]), y: (bits[16], bits[16]), d: (bits[16], bits[16])) -> (bits[32], bits[16], bits[16]) { + tuple_index.1: bits[16] = tuple_index(x, index=0) + tuple_index.2: bits[16] = tuple_index(x, index=1) + tuple_index.3: bits[16] = tuple_index(y, index=0) + tuple_index.4: bits[16] = tuple_index(y, index=1) + tuple_index.5: bits[16] = tuple_index(d, index=0) + tuple_index.6: bits[16] = tuple_index(d, index=1) + concat.7: bits[32] = concat(tuple_index.1, tuple_index.2) + concat.8: bits[32] = concat(tuple_index.3, tuple_index.4) + concat.9: bits[32] = concat(tuple_index.5, tuple_index.6) + priority_sel.10: bits[32] = priority_sel(p, cases=[concat.7, concat.8], default=concat.9) + priority_sel.11: (bits[16], bits[16]) = priority_sel(p, cases=[x, y], default=d) + tuple_index.12: bits[16] = tuple_index(priority_sel.11, index=0) + tuple_index.13: bits[16] = tuple_index(priority_sel.11, index=1) + ret tuple.14: (bits[32], bits[16], bits[16]) = tuple(priority_sel.10, tuple_index.12, tuple_index.13) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + absl::flat_hash_map args = { + {"x", Value::Tuple({Value(UBits(0x00ff, 16)), Value(UBits(0xff00, 16))})}, + {"y", Value::Tuple({Value(UBits(0xf0f0, 16)), Value(UBits(0x0f0f, 16))})}, + {"d", Value::Tuple({Value(UBits(0xff00, 16)), Value(UBits(0x00ff, 16))})}, + }; + args["p"] = Value(UBits(0b00, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple({Value(UBits(0xff0000ff, 32)), + Value(UBits(0xff00, 16)), + Value(UBits(0x00ff, 16))}))); + args["p"] = Value(UBits(0b01, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple({Value(UBits(0x00ffff00, 32)), + Value(UBits(0x00ff, 16)), + Value(UBits(0xff00, 16))}))); + args["p"] = Value(UBits(0b10, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple({Value(UBits(0xf0f00f0f, 32)), + Value(UBits(0xf0f0, 16)), + Value(UBits(0x0f0f, 16))}))); + args["p"] = Value(UBits(0b11, 2)); + EXPECT_THAT(simulator.RunFunction(args), + IsOkAndHolds(Value::Tuple({Value(UBits(0x00ffff00, 32)), + Value(UBits(0x00ff, 16)), + Value(UBits(0xff00, 16))}))); +} + +TEST_P(CodegenCombinationalFunctionTest, UncommonParameterTypes) { + std::string text = R"( +package UncommonParameterTypes + +top fn main(a: bits[32], + b: (bits[32], ()), + c: bits[32][3], + d: (bits[32], bits[32])[1], + e: (bits[32][2], (), ()), + f: bits[0], + g: bits[1]) -> bits[32] { + tuple_index.1: bits[32] = tuple_index(b, index=0) + literal.2: bits[32] = literal(value=0) + array_index.3: bits[32] = array_index(c, indices=[g]) + array_index.4: (bits[32], bits[32]) = array_index(d, indices=[literal.2]) + tuple_index.5: bits[32] = tuple_index(array_index.4, index=1) + tuple_index.6: bits[32][2] = tuple_index(e, index=0) + array_index.7: bits[32] = array_index(tuple_index.6, indices=[g]) + ret or.8: bits[32] = or(a, tuple_index.1, array_index.3, tuple_index.5, array_index.7) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr codegen_package, + ClonePackage(package.get())); + ASSERT_TRUE(codegen_package->GetTop().has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(*codegen_package->GetTop(), + codegen_options())); + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + + std::minstd_rand engine; + ASSERT_TRUE(package->GetTop().value()->IsFunction()); + Function* fn = package->GetTop().value()->AsFunctionOrDie(); + std::vector arguments = RandomFunctionArguments(fn, engine); + XLS_ASSERT_OK_AND_ASSIGN( + Value expected, DropInterpreterEvents(InterpretFunction(fn, arguments))); + EXPECT_THAT(simulator.RunFunction(arguments), IsOkAndHolds(expected)); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayIndexWithBoundsCheck) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + Type* array_u8 = package.GetArrayType(3, u8); + auto a = fb.Param("A", array_u8); + auto index = fb.Param("index", u8); + fb.ArrayIndex(a, {index}); + + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule( + f, codegen_options().array_index_bounds_checking(true))); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction({{"A", Value::UBitsArray({30, 40, 50}, 8).value()}, + {"index", Value(UBits(1, 8))}}), + IsOkAndHolds(Value(UBits(40, 8)))); + EXPECT_THAT( + simulator.RunFunction({{"A", Value::UBitsArray({30, 40, 50}, 8).value()}, + {"index", Value(UBits(3, 8))}}), + IsOkAndHolds(Value(UBits(50, 8)))); + EXPECT_THAT( + simulator.RunFunction({{"A", Value::UBitsArray({30, 40, 50}, 8).value()}, + {"index", Value(UBits(42, 8))}}), + IsOkAndHolds(Value(UBits(50, 8)))); + + // The out of bounds value should return the highest index value. + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr tb, + verilog::ModuleTestbench::CreateFromVerilogText( + result.verilog_text, GetFileType(), + result.signature, GetSimulator())); + XLS_ASSERT_OK_AND_ASSIGN(verilog::ModuleTestbenchThread * tbt, + tb->CreateThreadDrivingAllInputs( + "main", /*default_value=*/verilog::ZeroOrX::kX)); + verilog::SequentialBlock& seq = tbt->MainBlock(); + seq.Set("A", UBits(0xabcdef, 24)); + seq.Set("index", UBits(42, 8)); + seq.AtEndOfCycle().ExpectEq("out", 0xab); + XLS_EXPECT_OK(tb->Run()); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayIndexWithoutBoundsCheck) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + Type* array_u8 = package.GetArrayType(3, u8); + auto a = fb.Param("A", array_u8); + auto index = fb.Param("index", u8); + fb.ArrayIndex(a, {index}); + + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, + GenerateCombinationalModule( + f, codegen_options().array_index_bounds_checking(false))); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction({{"A", Value::UBitsArray({30, 40, 50}, 8).value()}, + {"index", Value(UBits(1, 8))}}), + IsOkAndHolds(Value(UBits(40, 8)))); + EXPECT_THAT( + simulator.RunFunction({{"A", Value::UBitsArray({30, 40, 50}, 8).value()}, + {"index", Value(UBits(2, 8))}}), + IsOkAndHolds(Value(UBits(50, 8)))); + + // The out of bounds value should return X. + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr tb, + verilog::ModuleTestbench::CreateFromVerilogText( + result.verilog_text, GetFileType(), + result.signature, GetSimulator())); + XLS_ASSERT_OK_AND_ASSIGN(verilog::ModuleTestbenchThread * tbt, + tb->CreateThreadDrivingAllInputs( + "main", /*default_value=*/verilog::ZeroOrX::kX)); + verilog::SequentialBlock& seq = tbt->MainBlock(); + seq.Set("A", UBits(0xabcdef, 24)); + seq.Set("index", UBits(3, 8)); + seq.AtEndOfCycle().ExpectX("out"); + XLS_EXPECT_OK(tb->Run()); +} + +TEST_P(CodegenCombinationalFunctionTest, TwoDArray) { + // Build up a two dimensional array from scalars, then deconstruct it and do + // something with the elements. + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", u8); + auto b = fb.Param("b", u8); + auto c = fb.Param("c", u8); + auto row_0 = fb.Array({a, b, c}, a.GetType()); + auto row_1 = fb.Array({a, b, c}, a.GetType()); + auto two_d = fb.Array({row_0, row_1}, row_0.GetType()); + fb.Add(fb.ArrayIndex(fb.ArrayIndex(two_d, {fb.Literal(UBits(0, 8))}), + {fb.Literal(UBits(2, 8))}), + fb.ArrayIndex(fb.ArrayIndex(two_d, {fb.Literal(UBits(1, 8))}), + {fb.Literal(UBits(1, 8))})); + + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction({{"a", Value(UBits(123, 8))}, + {"b", Value(UBits(42, 8))}, + {"c", Value(UBits(100, 8))}}), + IsOkAndHolds(Value(UBits(142, 8)))); +} + +TEST_P(CodegenCombinationalFunctionTest, ReturnTwoDArray) { + // Build up a two dimensional array from scalars and return it. + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", u8); + auto b = fb.Param("b", u8); + auto row_0 = fb.Array({a, b}, a.GetType()); + auto row_1 = fb.Array({b, a}, a.GetType()); + fb.Array({row_0, row_1}, row_0.GetType()); + + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value(UBits(123, 8))}, {"b", Value(UBits(42, 8))}}), + IsOkAndHolds(Value::ArrayOrDie({ + Value::ArrayOrDie({Value(UBits(123, 8)), Value(UBits(42, 8))}), + Value::ArrayOrDie({Value(UBits(42, 8)), Value(UBits(123, 8))}), + }))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdateBitElements) { + std::string text = R"( +package ArrayUpdate + +top fn main(idx: bits[2]) -> bits[32][3] { + literal.5: bits[32][3] = literal(value=[1, 2, 3]) + literal.6: bits[32] = literal(value=99) + ret updated_array: bits[32][3] = array_update(literal.5, literal.6, indices=[idx]) +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + + auto make_array = [](absl::Span values) { + std::vector elements; + for (auto v : values) { + elements.push_back(Value(UBits(v, 32))); + } + absl::StatusOr array = Value::Array(elements); + EXPECT_TRUE(array.ok()); + return array.value(); + }; + + EXPECT_THAT(simulator.RunFunction({{"idx", Value(UBits(0b00, 2))}}), + IsOkAndHolds(make_array({99, 2, 3}))); + EXPECT_THAT(simulator.RunFunction({{"idx", Value(UBits(0b01, 2))}}), + IsOkAndHolds(make_array({1, 99, 3}))); + EXPECT_THAT(simulator.RunFunction({{"idx", Value(UBits(0b10, 2))}}), + IsOkAndHolds(make_array({1, 2, 99}))); + EXPECT_THAT(simulator.RunFunction({{"idx", Value(UBits(0b11, 2))}}), + IsOkAndHolds(make_array({1, 2, 3}))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdateArrayElements) { + std::string text = R"( +package ArrayUpdate + +top fn main(idx: bits[2]) -> bits[32][2][3] { + literal.17: bits[32][2][3] = literal(value=[[1, 2], [3, 4], [5, 6]]) + literal.14: bits[32][2] = literal(value=[98, 99]) + ret updated_array: bits[32][2][3] = array_update(literal.17, literal.14, indices=[idx]) +} + +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + + auto make_array = [](absl::Span values) { + std::vector elements; + for (auto v : values) { + elements.push_back(Value(UBits(v, 32))); + } + absl::StatusOr array = Value::Array(elements); + EXPECT_TRUE(array.ok()); + return array.value(); + }; + + auto make_array_of_values = [&](absl::Span values) { + std::vector elements; + for (const auto& array : values) { + elements.push_back(array); + } + absl::StatusOr array_of_values = Value::Array(elements); + EXPECT_TRUE(array_of_values.ok()); + return array_of_values.value(); + }; + + EXPECT_THAT( + simulator.RunFunction({{"idx", Value(UBits(0b00, 2))}}), + IsOkAndHolds(make_array_of_values( + {make_array({98, 99}), make_array({3, 4}), make_array({5, 6})}))); + EXPECT_THAT( + simulator.RunFunction({{"idx", Value(UBits(0b01, 2))}}), + IsOkAndHolds(make_array_of_values( + {make_array({1, 2}), make_array({98, 99}), make_array({5, 6})}))); + EXPECT_THAT( + simulator.RunFunction({{"idx", Value(UBits(0b10, 2))}}), + IsOkAndHolds(make_array_of_values( + {make_array({1, 2}), make_array({3, 4}), make_array({98, 99})}))); + EXPECT_THAT( + simulator.RunFunction({{"idx", Value(UBits(0b11, 2))}}), + IsOkAndHolds(make_array_of_values( + {make_array({1, 2}), make_array({3, 4}), make_array({5, 6})}))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdateTupleElements) { + std::string text = R"( +package ArrayUpdate + +top fn main(idx: bits[2]) -> (bits[32], bits[32])[3] { + literal.17: (bits[32], bits[32])[3] = literal(value=[(1,2),(3,4),(5,6)]) + literal.14: (bits[32], bits[32]) = literal(value=(98, 99)) + ret array_update.15: (bits[32], bits[32])[3] = array_update(literal.17, literal.14, indices=[idx]) +} + +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + + auto make_tuple = [](absl::Span values) { + std::vector elements; + for (auto v : values) { + elements.push_back(Value(UBits(v, 32))); + } + absl::StatusOr tuple = Value::Tuple(elements); + EXPECT_TRUE(tuple.ok()); + return tuple.value(); + }; + + auto make_array_of_values = [&](absl::Span values) { + std::vector elements; + for (const auto& array : values) { + elements.push_back(array); + } + absl::StatusOr array_of_values = Value::Array(elements); + EXPECT_TRUE(array_of_values.ok()); + return array_of_values.value(); + }; + + EXPECT_THAT( + simulator.RunFunction({{"idx", Value(UBits(0b00, 2))}}), + IsOkAndHolds(make_array_of_values( + {make_tuple({98, 99}), make_tuple({3, 4}), make_tuple({5, 6})}))); + EXPECT_THAT( + simulator.RunFunction({{"idx", Value(UBits(0b01, 2))}}), + IsOkAndHolds(make_array_of_values( + {make_tuple({1, 2}), make_tuple({98, 99}), make_tuple({5, 6})}))); + EXPECT_THAT( + simulator.RunFunction({{"idx", Value(UBits(0b10, 2))}}), + IsOkAndHolds(make_array_of_values( + {make_tuple({1, 2}), make_tuple({3, 4}), make_tuple({98, 99})}))); + EXPECT_THAT( + simulator.RunFunction({{"idx", Value(UBits(0b11, 2))}}), + IsOkAndHolds(make_array_of_values( + {make_tuple({1, 2}), make_tuple({3, 4}), make_tuple({5, 6})}))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdateTupleWithArrayElements) { + std::string text = R"( +package ArrayUpdate + +top fn main(idx: bits[2]) -> (bits[32], bits[8][2])[2] { + literal.17: (bits[32], bits[8][2])[2] = literal(value=[(1,[2,3]),(4,[5,6])]) + literal.14: (bits[32], bits[8][2]) = literal(value=(98, [99, 100])) + ret array_update.15: (bits[32], bits[8][2])[2] = array_update(literal.17, literal.14, indices=[idx]) +} + +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr package, + Parser::ParsePackage(text)); + + std::optional top = package->GetTop(); + ASSERT_TRUE(top.has_value()); + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(top.value(), codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + + auto make_array = [](absl::Span values) { + std::vector elements; + for (auto v : values) { + elements.push_back(Value(UBits(v, 8))); + } + absl::StatusOr array = Value::Array(elements); + EXPECT_TRUE(array.ok()); + return array.value(); + }; + + auto make_tuple = [](absl::Span values) { + std::vector elements; + for (const auto& v : values) { + elements.push_back(v); + } + absl::StatusOr tuple = Value::Tuple(elements); + EXPECT_TRUE(tuple.ok()); + return tuple.value(); + }; + + auto make_array_of_values = [&](absl::Span values) { + std::vector elements; + for (const auto& array : values) { + elements.push_back(array); + } + absl::StatusOr array_of_values = Value::Array(elements); + EXPECT_TRUE(array_of_values.ok()); + return array_of_values.value(); + }; + + EXPECT_THAT( + simulator.RunFunction({{"idx", Value(UBits(0b01, 2))}}), + IsOkAndHolds(make_array_of_values( + {make_tuple({Value(UBits(1, 32)), make_array({2, 3})}), + make_tuple({Value(UBits(98, 32)), make_array({99, 100})})}))); +} + +TEST_P(CodegenCombinationalFunctionTest, BuildComplicatedType) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + // Construct some terrible abomination of tuples and arrays. + auto a = fb.Param("a", u8); + auto b = fb.Param("b", u8); + auto c = fb.Param("c", u8); + auto row_0 = fb.Array({a, b}, a.GetType()); + auto row_1 = fb.Array({b, a}, a.GetType()); + auto ar = fb.Array({row_0, row_1}, row_0.GetType()); + auto tuple = fb.Tuple({ar, a}); + // Deconstruct it and return some scalar element. + fb.ArrayIndex(fb.ArrayIndex(fb.TupleIndex(tuple, 0), {a}), {c}); + + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction({{"a", Value(UBits(0, 8))}, + {"b", Value(UBits(42, 8))}, + {"c", Value(UBits(1, 8))}}), + IsOkAndHolds(Value(UBits(42, 8)))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayShapedSel) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + BValue p = fb.Param("p", package.GetBitsType(8)); + BValue x = fb.Param("x", package.GetArrayType(3, package.GetBitsType(8))); + BValue y = fb.Param("y", package.GetArrayType(3, package.GetBitsType(8))); + BValue z = fb.Param("z", package.GetArrayType(3, package.GetBitsType(8))); + BValue d = fb.Param("d", package.GetArrayType(3, package.GetBitsType(8))); + fb.Select(p, {x, y, z}, /*default_value=*/d); + + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + XLS_ASSERT_OK_AND_ASSIGN( + Value x_in, + Parser::ParseTypedValue("[bits[8]:0xa, bits[8]:0xb, bits[8]:0xc]")); + XLS_ASSERT_OK_AND_ASSIGN( + Value y_in, + Parser::ParseTypedValue("[bits[8]:0x1, bits[8]:0x2, bits[8]:0x3]")); + XLS_ASSERT_OK_AND_ASSIGN( + Value z_in, + Parser::ParseTypedValue("[bits[8]:0x4, bits[8]:0x5, bits[8]:0x6]")); + XLS_ASSERT_OK_AND_ASSIGN( + Value d_in, + Parser::ParseTypedValue("[bits[8]:0x7, bits[8]:0x8, bits[8]:0x9]")); + EXPECT_THAT(simulator.RunFunction({{"p", Value(UBits(0, 8))}, + {"x", x_in}, + {"y", y_in}, + {"z", z_in}, + {"d", d_in}}), + IsOkAndHolds(x_in)); + EXPECT_THAT(simulator.RunFunction({{"p", Value(UBits(1, 8))}, + {"x", x_in}, + {"y", y_in}, + {"z", z_in}, + {"d", d_in}}), + IsOkAndHolds(y_in)); + EXPECT_THAT(simulator.RunFunction({{"p", Value(UBits(2, 8))}, + {"x", x_in}, + {"y", y_in}, + {"z", z_in}, + {"d", d_in}}), + IsOkAndHolds(z_in)); + EXPECT_THAT(simulator.RunFunction({{"p", Value(UBits(3, 8))}, + {"x", x_in}, + {"y", y_in}, + {"z", z_in}, + {"d", d_in}}), + IsOkAndHolds(d_in)); + EXPECT_THAT(simulator.RunFunction({{"p", Value(UBits(100, 8))}, + {"x", x_in}, + {"y", y_in}, + {"z", z_in}, + {"d", d_in}}), + IsOkAndHolds(d_in)); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayShapedSelNoDefault) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + BValue p = fb.Param("p", package.GetBitsType(1)); + BValue x = fb.Param("x", package.GetArrayType(3, package.GetBitsType(8))); + BValue y = fb.Param("y", package.GetArrayType(3, package.GetBitsType(8))); + fb.Select(p, {x, y}); + + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + XLS_ASSERT_OK_AND_ASSIGN( + Value x_in, + Parser::ParseTypedValue("[bits[8]:0xa, bits[8]:0xb, bits[8]:0xc]")); + XLS_ASSERT_OK_AND_ASSIGN( + Value y_in, + Parser::ParseTypedValue("[bits[8]:0x1, bits[8]:0x2, bits[8]:0x3]")); + EXPECT_THAT(simulator.RunFunction( + {{"p", Value(UBits(0, 1))}, {"x", x_in}, {"y", y_in}}), + IsOkAndHolds(x_in)); + EXPECT_THAT(simulator.RunFunction( + {{"p", Value(UBits(1, 1))}, {"x", x_in}, {"y", y_in}}), + IsOkAndHolds(y_in)); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayShapedOneHotSelect) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + BValue s = fb.Param("s", package.GetBitsType(2)); + BValue x = fb.Param("x", package.GetArrayType(2, package.GetBitsType(8))); + BValue y = fb.Param("y", package.GetArrayType(2, package.GetBitsType(8))); + fb.OneHotSelect(s, {x, y}); + + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + XLS_ASSERT_OK_AND_ASSIGN( + Value x_in, Parser::ParseTypedValue("[bits[8]:0x0f, bits[8]:0xf0]")); + XLS_ASSERT_OK_AND_ASSIGN( + Value y_in, Parser::ParseTypedValue("[bits[8]:0xab, bits[8]:0xcd]")); + EXPECT_THAT(simulator.RunFunction( + {{"s", Value(UBits(0b00, 2))}, {"x", x_in}, {"y", y_in}}), + IsOkAndHolds(Value::UBitsArray({0x0, 0x0}, 8).value())); + EXPECT_THAT(simulator.RunFunction( + {{"s", Value(UBits(0b01, 2))}, {"x", x_in}, {"y", y_in}}), + IsOkAndHolds(Value::UBitsArray({0x0f, 0xf0}, 8).value())); + EXPECT_THAT(simulator.RunFunction( + {{"s", Value(UBits(0b10, 2))}, {"x", x_in}, {"y", y_in}}), + IsOkAndHolds(Value::UBitsArray({0xab, 0xcd}, 8).value())); + EXPECT_THAT(simulator.RunFunction( + {{"s", Value(UBits(0b11, 2))}, {"x", x_in}, {"y", y_in}}), + IsOkAndHolds(Value::UBitsArray({0xaf, 0xfd}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayConcatArrayOfBits) { + Package package(TestBaseName()); + + std::string ir_text = R"( + fn f(a0: bits[32][2], a1: bits[32][3]) -> bits[32][7] { + array_concat.3: bits[32][5] = array_concat(a0, a1) + ret array_concat.4: bits[32][7] = array_concat(array_concat.3, a0) + } + )"; + XLS_ASSERT_OK_AND_ASSIGN(Function * function, + Parser::ParseFunction(ir_text, &package)); + + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(function, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + + XLS_ASSERT_OK_AND_ASSIGN(Value a0, Value::UBitsArray({1, 2}, 32)); + XLS_ASSERT_OK_AND_ASSIGN(Value a1, Value::UBitsArray({3, 4, 5}, 32)); + XLS_ASSERT_OK_AND_ASSIGN(Value ret, + Value::UBitsArray({1, 2, 3, 4, 5, 1, 2}, 32)); + + EXPECT_THAT(simulator.RunFunction({{"a0", a0}, {"a1", a1}}), + IsOkAndHolds(ret)); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayConcatArrayOfBitsMixedOperands) { + Package package(TestBaseName()); + + std::string ir_text = R"( + fn f(a0: bits[32][2], a1: bits[32][3], a2: bits[32][1]) -> bits[32][7] { + array_concat.4: bits[32][1] = array_concat(a2) + array_concat.5: bits[32][2] = array_concat(array_concat.4, array_concat.4) + array_concat.6: bits[32][7] = array_concat(a0, array_concat.5, a1) + ret array_concat.7: bits[32][7] = array_concat(array_concat.6) + } + )"; + XLS_ASSERT_OK_AND_ASSIGN(Function * function, + Parser::ParseFunction(ir_text, &package)); + + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(function, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + + XLS_ASSERT_OK_AND_ASSIGN(Value a0, Value::UBitsArray({1, 2}, 32)); + XLS_ASSERT_OK_AND_ASSIGN(Value a1, Value::UBitsArray({3, 4, 5}, 32)); + XLS_ASSERT_OK_AND_ASSIGN(Value a2, Value::SBitsArray({-1}, 32)); + XLS_ASSERT_OK_AND_ASSIGN(Value ret, + Value::SBitsArray({1, 2, -1, -1, 3, 4, 5}, 32)); + + EXPECT_THAT(simulator.RunFunction({{"a0", a0}, {"a1", a1}, {"a2", a2}}), + IsOkAndHolds(ret)); +} + +TEST_P(CodegenCombinationalFunctionTest, InterpretArrayConcatArraysOfArrays) { + Package package(TestBaseName()); + + std::string ir_text = R"( + fn f() -> bits[32][2][3] { + literal.1: bits[32][2][2] = literal(value=[[1, 2], [3, 4]]) + literal.2: bits[32][2][1] = literal(value=[[5, 6]]) + + ret array_concat.3: bits[32][2][3] = array_concat(literal.2, literal.1) + } + )"; + XLS_ASSERT_OK_AND_ASSIGN(Function * function, + Parser::ParseFunction(ir_text, &package)); + + XLS_ASSERT_OK_AND_ASSIGN( + auto result, GenerateCombinationalModule(function, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + + XLS_ASSERT_OK_AND_ASSIGN(Value ret, + Value::SBits2DArray({{5, 6}, {1, 2}, {3, 4}}, 32)); + + std::vector args; + EXPECT_THAT(simulator.RunFunction(args), IsOkAndHolds(ret)); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayIndexSimpleArray) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + Type* u16 = package.GetBitsType(16); + auto a = fb.Param("a", package.GetArrayType(3, u8)); + auto idx = fb.Param("idx", u16); + auto ret = fb.ArrayIndex(a, {idx}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction({{"a", Value::UBitsArray({11, 22, 33}, 8).value()}, + {"idx", Value(UBits(2, 16))}}), + IsOkAndHolds(Value(UBits(33, 8)))); + + // OOB access should return the last element. + EXPECT_THAT( + simulator.RunFunction({{"a", Value::UBitsArray({11, 22, 33}, 8).value()}, + {"idx", Value(UBits(42, 16))}}), + IsOkAndHolds(Value(UBits(33, 8)))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayIndexWithNarrowIndex) { + // An array index with a sufficiently narrow index that OOB access is not + // possible. + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + Type* u2 = package.GetBitsType(2); + auto a = fb.Param("a", package.GetArrayType(4, u8)); + auto idx = fb.Param("idx", u2); + auto ret = fb.ArrayIndex(a, {idx}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction( + {{"a", Value::UBitsArray({11, 22, 33, 44}, 8).value()}, + {"idx", Value(UBits(1, 2))}}), + IsOkAndHolds(Value(UBits(22, 8)))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayIndexWithLiteralIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", package.GetArrayType(4, u8)); + auto idx = fb.Literal(UBits(3, 42)); + auto ret = fb.ArrayIndex(a, {idx}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction( + {{"a", Value::UBitsArray({11, 22, 33, 44}, 8).value()}}), + IsOkAndHolds(Value(UBits(44, 8)))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayIndexNilIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", package.GetArrayType(3, u8)); + auto ret = fb.ArrayIndex(a, {}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunFunction( + {{"a", Value::UBitsArray({11, 22, 33}, 8).value()}}), + IsOkAndHolds(Value::UBitsArray({11, 22, 33}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayIndex2DArrayIndexSingleElement) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + Type* u16 = package.GetBitsType(16); + auto a = fb.Param("a", package.GetArrayType(2, package.GetArrayType(3, u8))); + auto idx0 = fb.Param("idx0", u16); + auto idx1 = fb.Param("idx1", u16); + auto ret = fb.ArrayIndex(a, {idx0, idx1}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"idx0", Value(UBits(0, 16))}, + {"idx1", Value(UBits(1, 16))}}), + IsOkAndHolds(Value(UBits(22, 8)))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayIndex2DArrayIndexSubArray) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + Type* u16 = package.GetBitsType(16); + auto a = fb.Param("a", package.GetArrayType(2, package.GetArrayType(3, u8))); + auto idx = fb.Param("idx", u16); + auto ret = fb.ArrayIndex(a, {idx}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"idx", Value(UBits(0, 16))}}), + IsOkAndHolds(Value::UBitsArray({11, 22, 33}, 8).value())); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"idx", Value(UBits(1, 16))}}), + IsOkAndHolds(Value::UBitsArray({44, 55, 66}, 8).value())); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"idx", Value(UBits(42, 16))}}), + IsOkAndHolds(Value::UBitsArray({44, 55, 66}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdateLiteralIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", package.GetArrayType(3, u8)); + auto update_value = fb.Param("value", u8); + auto idx = fb.Literal(UBits(1, 16)); + auto ret = fb.ArrayUpdate(a, update_value, {idx}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction({{"a", Value::UBitsArray({11, 22, 33}, 8).value()}, + {"value", Value(UBits(123, 8))}}), + IsOkAndHolds(Value::UBitsArray({11, 123, 33}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdateVariableIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", package.GetArrayType(3, u8)); + auto update_value = fb.Param("value", u8); + auto idx = fb.Param("idx", package.GetBitsType(32)); + auto ret = fb.ArrayUpdate(a, update_value, {idx}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction({{"a", Value::UBitsArray({11, 22, 33}, 8).value()}, + {"idx", Value(UBits(0, 32))}, + {"value", Value(UBits(123, 8))}}), + IsOkAndHolds(Value::UBitsArray({123, 22, 33}, 8).value())); + // Out-of-bounds should just return the original array. + EXPECT_THAT( + simulator.RunFunction({{"a", Value::UBitsArray({11, 22, 33}, 8).value()}, + {"idx", Value(UBits(3, 32))}, + {"value", Value(UBits(123, 8))}}), + IsOkAndHolds(Value::UBitsArray({11, 22, 33}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdate2DLiteralIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", package.GetArrayType(2, package.GetArrayType(3, u8))); + auto update_value = fb.Param("value", u8); + auto idx0 = fb.Literal(UBits(0, 32)); + auto idx1 = fb.Literal(UBits(2, 14)); + auto ret = fb.ArrayUpdate(a, update_value, {idx0, idx1}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"value", Value(UBits(123, 8))}}), + IsOkAndHolds( + Value::UBits2DArray({{11, 22, 123}, {44, 55, 66}}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdate2DVariableIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", package.GetArrayType(2, package.GetArrayType(3, u8))); + auto update_value = fb.Param("value", u8); + auto idx0 = fb.Param("idx0", package.GetBitsType(32)); + auto idx1 = fb.Param("idx1", package.GetBitsType(32)); + auto ret = fb.ArrayUpdate(a, update_value, {idx0, idx1}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"value", Value(UBits(123, 8))}, + {"idx0", Value(UBits(1, 32))}, + {"idx1", Value(UBits(0, 32))}}), + IsOkAndHolds( + Value::UBits2DArray({{11, 22, 33}, {123, 55, 66}}, 8).value())); + // Out-of-bounds should just return the original array. + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"value", Value(UBits(123, 8))}, + {"idx0", Value(UBits(1, 32))}, + {"idx1", Value(UBits(44, 32))}}), + IsOkAndHolds( + Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value())); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"value", Value(UBits(123, 8))}, + {"idx0", Value(UBits(11, 32))}, + {"idx1", Value(UBits(0, 32))}}), + IsOkAndHolds( + Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdate2DLiteralAndVariableIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", package.GetArrayType(2, package.GetArrayType(3, u8))); + auto update_value = fb.Param("value", u8); + auto idx0 = fb.Param("idx", package.GetBitsType(32)); + auto idx1 = fb.Literal(UBits(2, 14)); + auto ret = fb.ArrayUpdate(a, update_value, {idx0, idx1}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"value", Value(UBits(123, 8))}, + {"idx", Value(UBits(0, 32))}}), + IsOkAndHolds( + Value::UBits2DArray({{11, 22, 123}, {44, 55, 66}}, 8).value())); + // Out-of-bounds should just return the original array. + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"value", Value(UBits(123, 8))}, + {"idx", Value(UBits(10, 32))}}), + IsOkAndHolds( + Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdate2DUpdateArrayLiteralIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", package.GetArrayType(2, package.GetArrayType(3, u8))); + auto update_value = fb.Param("value", package.GetArrayType(3, u8)); + auto idx = fb.Literal(UBits(1, 14)); + auto ret = fb.ArrayUpdate(a, update_value, {idx}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"value", Value::UBitsArray({101, 102, 103}, 8).value()}}), + IsOkAndHolds( + Value::UBits2DArray({{11, 22, 33}, {101, 102, 103}}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, + ArrayUpdate2DUpdateArrayVariableIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", package.GetArrayType(2, package.GetArrayType(3, u8))); + auto update_value = fb.Param("value", package.GetArrayType(3, u8)); + auto idx = fb.Param("idx", package.GetBitsType(37)); + auto ret = fb.ArrayUpdate(a, update_value, {idx}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"value", Value::UBitsArray({101, 102, 103}, 8).value()}, + {"idx", Value(UBits(1, 37))}}), + IsOkAndHolds( + Value::UBits2DArray({{11, 22, 33}, {101, 102, 103}}, 8).value())); + // Out-of-bounds should just return the original array. + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"value", Value::UBitsArray({101, 102, 103}, 8).value()}, + {"idx", Value(UBits(2, 37))}}), + IsOkAndHolds( + Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdate2DUpdateArrayNilIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", package.GetArrayType(2, package.GetArrayType(3, u8))); + auto update_value = + fb.Param("value", package.GetArrayType(2, package.GetArrayType(3, u8))); + auto ret = fb.ArrayUpdate(a, update_value, {}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT( + simulator.RunFunction( + {{"a", Value::UBits2DArray({{11, 22, 33}, {44, 55, 66}}, 8).value()}, + {"value", Value::UBits2DArray({{101, 102, 103}, {104, 105, 106}}, 8) + .value()}}), + IsOkAndHolds( + Value::UBits2DArray({{101, 102, 103}, {104, 105, 106}}, 8).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdateBitsNilIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u8 = package.GetBitsType(8); + auto a = fb.Param("a", u8); + auto update_value = fb.Param("value", u8); + auto ret = fb.ArrayUpdate(a, update_value, {}); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(ret)); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"a", UBits(11, 8)}, {"value", UBits(22, 8)}}), + IsOkAndHolds(UBits(22, 8))); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdateWithDifferentTypesIndices) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u32 = package.GetBitsType(32); + BValue i0 = fb.Param("i0", package.GetBitsType(4)); + BValue i1 = fb.Param("i1", package.GetBitsType(5)); + BValue a = + fb.Param("a", package.GetArrayType(2, package.GetArrayType(3, u32))); + BValue value = fb.Param("value", u32); + fb.ArrayUpdate(a, value, {i0, i1}); + + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayUpdateWithNarrowIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u32 = package.GetBitsType(32); + BValue a = fb.Param("a", package.GetArrayType(10, u32)); + BValue idx = fb.Param("idx", package.GetBitsType(2)); + BValue value = fb.Param("v", u32); + XLS_ASSERT_OK_AND_ASSIGN( + Function * f, fb.BuildWithReturnValue(fb.ArrayUpdate(a, value, {idx}))); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +TEST_P(CodegenCombinationalFunctionTest, ArraySliceWithNarrowStart) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u32 = package.GetBitsType(32); + BValue a = fb.Param("a", package.GetArrayType(5, u32)); + BValue start = fb.Param("start", package.GetBitsType(1)); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(fb.ArraySlice( + a, start, /*width=*/3))); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + XLS_ASSERT_OK_AND_ASSIGN(Value a_value, + Value::UBitsArray({1, 2, 3, 4, 5}, 32)); + EXPECT_THAT( + simulator.RunFunction({{"a", a_value}, {"start", Value(UBits(0, 1))}}), + IsOkAndHolds(Value::UBitsArray({1, 2, 3}, 32).value())); + EXPECT_THAT( + simulator.RunFunction({{"a", a_value}, {"start", Value(UBits(1, 1))}}), + IsOkAndHolds(Value::UBitsArray({2, 3, 4}, 32).value())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +TEST_P(CodegenCombinationalFunctionTest, ArraySliceWithWideStart) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u32 = package.GetBitsType(32); + BValue a = fb.Param("a", package.GetArrayType(5, u32)); + BValue start = fb.Param("start", package.GetBitsType(100)); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(fb.ArraySlice( + a, start, /*width=*/3))); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + XLS_ASSERT_OK_AND_ASSIGN(Value a_value, + Value::UBitsArray({1, 2, 3, 4, 5}, 32)); + EXPECT_THAT( + simulator.RunFunction({{"a", a_value}, {"start", Value(UBits(1, 100))}}), + IsOkAndHolds(Value::UBitsArray({2, 3, 4}, 32).value())); + EXPECT_THAT(simulator.RunFunction( + {{"a", a_value}, {"start", Value(Bits::AllOnes(100))}}), + IsOkAndHolds(Value::UBitsArray({5, 5, 5}, 32).value())); +} + +TEST_P(CodegenCombinationalFunctionTest, ArraySliceWiderThanInputArray) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u32 = package.GetBitsType(32); + BValue a = fb.Param("a", package.GetArrayType(3, u32)); + BValue start = fb.Param("start", package.GetBitsType(32)); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(fb.ArraySlice( + a, start, /*width=*/5))); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + XLS_ASSERT_OK_AND_ASSIGN(Value a_value, Value::UBitsArray({1, 2, 3}, 32)); + EXPECT_THAT( + simulator.RunFunction({{"a", a_value}, {"start", Value(UBits(0, 32))}}), + IsOkAndHolds(Value::UBitsArray({1, 2, 3, 3, 3}, 32).value())); + EXPECT_THAT( + simulator.RunFunction({{"a", a_value}, {"start", Value(UBits(1, 32))}}), + IsOkAndHolds(Value::UBitsArray({2, 3, 3, 3, 3}, 32).value())); + EXPECT_THAT( + simulator.RunFunction({{"a", a_value}, {"start", Value(UBits(2, 32))}}), + IsOkAndHolds(Value::UBitsArray({3, 3, 3, 3, 3}, 32).value())); + EXPECT_THAT(simulator.RunFunction( + {{"a", a_value}, {"start", Value(UBits(123456, 32))}}), + IsOkAndHolds(Value::UBitsArray({3, 3, 3, 3, 3}, 32).value())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +TEST_P(CodegenCombinationalFunctionTest, TwoDArraySlice) { + verilog::VerilogFile file(codegen_options().use_system_verilog() + ? verilog::FileType::kSystemVerilog + : verilog::FileType::kVerilog); + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* u32 = package.GetBitsType(32); + Type* a2_u32 = package.GetArrayType(2, u32); + Type* a2x3_u32 = package.GetArrayType(3, a2_u32); + BValue a = fb.Param("a", a2x3_u32); + BValue start = fb.Param("start", package.GetBitsType(16)); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.BuildWithReturnValue(fb.ArraySlice( + a, start, /*width=*/2))); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + verilog::ModuleSimulator simulator(result.signature, result.verilog_text, + GetFileType(), GetSimulator()); + XLS_ASSERT_OK_AND_ASSIGN(Value a_value, + Value::UBits2DArray({{1, 2}, {3, 4}, {5, 6}}, 32)); + + EXPECT_THAT( + simulator.RunFunction({{"a", a_value}, {"start", Value(UBits(0, 16))}}), + IsOkAndHolds(Value::UBits2DArray({{1, 2}, {3, 4}}, 32).value())); + + EXPECT_THAT( + simulator.RunFunction({{"a", a_value}, {"start", Value(UBits(1, 16))}}), + IsOkAndHolds(Value::UBits2DArray({{3, 4}, {5, 6}}, 32).value())); + + EXPECT_THAT( + simulator.RunFunction({{"a", a_value}, {"start", Value(UBits(2, 16))}}), + IsOkAndHolds(Value::UBits2DArray({{5, 6}, {5, 6}}, 32).value())); + + EXPECT_THAT( + simulator.RunFunction({{"a", a_value}, {"start", Value(UBits(10, 16))}}), + IsOkAndHolds(Value::UBits2DArray({{5, 6}, {5, 6}}, 32).value())); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +TEST_P(CodegenCombinationalFunctionTest, UDiv) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + BValue x = fb.Param("x", package.GetBitsType(32)); + BValue y = fb.Param("y", package.GetBitsType(32)); + fb.UDiv(x, y); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", UBits(42, 32)}, {"y", UBits(7, 32)}}), + IsOkAndHolds(UBits(6, 32))); + // Should round toward zero. + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", UBits(10, 32)}, {"y", UBits(7, 32)}}), + IsOkAndHolds(UBits(1, 32))); + // Div by zero should return max value. + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", UBits(0, 32)}, {"y", UBits(0, 32)}}), + IsOkAndHolds(Bits::AllOnes(32))); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", UBits(12345, 32)}, {"y", UBits(0, 32)}}), + IsOkAndHolds(Bits::AllOnes(32))); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +TEST_P(CodegenCombinationalFunctionTest, SDiv) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + BValue x = fb.Param("x", package.GetBitsType(32)); + BValue y = fb.Param("y", package.GetBitsType(32)); + fb.SDiv(x, y); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", SBits(42, 32)}, {"y", SBits(7, 32)}}), + IsOkAndHolds(SBits(6, 32))); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", SBits(-42, 32)}, {"y", SBits(7, 32)}}), + IsOkAndHolds(SBits(-6, 32))); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", SBits(42, 32)}, {"y", SBits(-7, 32)}}), + IsOkAndHolds(SBits(-6, 32))); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", SBits(-42, 32)}, {"y", SBits(-7, 32)}}), + IsOkAndHolds(SBits(6, 32))); + + // Should round toward zero. + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", SBits(10, 32)}, {"y", SBits(7, 32)}}), + IsOkAndHolds(SBits(1, 32))); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", SBits(-10, 32)}, {"y", SBits(7, 32)}}), + IsOkAndHolds(SBits(-1, 32))); + + // Test overflow condition. + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", Bits::MinSigned(32)}, {"y", SBits(-1, 32)}}), + IsOkAndHolds(Bits::MinSigned(32))); + + // Div by zero should return max/min signed value. + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", SBits(0, 32)}, {"y", SBits(0, 32)}}), + IsOkAndHolds(Bits::MaxSigned(32))); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", SBits(12345, 32)}, {"y", SBits(0, 32)}}), + IsOkAndHolds(Bits::MaxSigned(32))); + EXPECT_THAT(simulator.RunAndReturnSingleOutput( + {{"x", SBits(-12345, 32)}, {"y", SBits(0, 32)}}), + IsOkAndHolds(Bits::MinSigned(32))); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +TEST_P(CodegenCombinationalFunctionTest, OneBitTupleIndex) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + BValue x = fb.Param( + "x", + package.GetArrayType(1, package.GetTupleType({package.GetBitsType(1)}))); + fb.TupleIndex(fb.ArrayIndex(x, {fb.Literal(UBits(0, 32))}), 0); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + XLS_ASSERT_OK_AND_ASSIGN(Value x_value, + Value::Array({Value::Tuple({Value(UBits(1, 1))})})); + EXPECT_THAT(simulator.RunFunction({{"x", x_value}}), + IsOkAndHolds(Value(UBits(1, 1)))); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +TEST_P(CodegenCombinationalFunctionTest, ArrayEq) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* array_type = package.GetArrayType(5, package.GetBitsType(32)); + BValue x = fb.Param("x", array_type); + BValue y = fb.Param("y", array_type); + fb.Eq(x, y); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + Value a = Value::UBitsArray({1, 2, 3, 4, 5}, 32).value(); + Value b = Value::UBitsArray({1, 20, 3, 4, 5}, 32).value(); + EXPECT_THAT(simulator.RunFunction({{"x", a}, {"y", b}}), + IsOkAndHolds(Value(UBits(0, 1)))); + EXPECT_THAT(simulator.RunFunction({{"x", a}, {"y", a}}), + IsOkAndHolds(Value(UBits(1, 1)))); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +TEST_P(CodegenCombinationalFunctionTest, TwoDArrayNe) { + Package package(TestBaseName()); + FunctionBuilder fb(TestBaseName(), &package); + Type* array_type = + package.GetArrayType(2, package.GetArrayType(3, package.GetBitsType(1))); + BValue x = fb.Param("x", array_type); + BValue y = fb.Param("y", array_type); + fb.Ne(x, y); + XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build()); + XLS_ASSERT_OK_AND_ASSIGN(auto result, + GenerateCombinationalModule(f, codegen_options())); + + verilog::ModuleSimulator simulator = + NewModuleSimulator(result.verilog_text, result.signature); + Value a = Value::UBits2DArray({{1, 0, 1}, {1, 1, 0}}, 1).value(); + Value b = Value::UBits2DArray({{1, 1, 1}, {1, 1, 0}}, 1).value(); + EXPECT_THAT(simulator.RunFunction({{"x", a}, {"y", b}}), + IsOkAndHolds(Value(UBits(1, 1)))); + EXPECT_THAT(simulator.RunFunction({{"x", a}, {"y", a}}), + IsOkAndHolds(Value(UBits(0, 1)))); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +INSTANTIATE_TEST_SUITE_P( + CodegenCombinationalFunctionTestInstantiation, + CodegenCombinationalFunctionTest, + testing::ValuesIn(verilog::kDefaultSimulationTargets), + verilog::ParameterizedTestName); + +} // namespace +} // namespace xls::codegen diff --git a/xls/codegen_v_1_5/codegen_function_test.cc b/xls/codegen_v_1_5/codegen_function_test.cc index accf781da2..d94b0e54fd 100644 --- a/xls/codegen_v_1_5/codegen_function_test.cc +++ b/xls/codegen_v_1_5/codegen_function_test.cc @@ -1070,7 +1070,7 @@ TEST_P(CodegenFunctionTest, ValidSignalWithReset) { } } -INSTANTIATE_TEST_SUITE_P(CodegenTestInstantiation, CodegenFunctionTest, +INSTANTIATE_TEST_SUITE_P(CodegenFunctionTestInstantiation, CodegenFunctionTest, testing::ValuesIn(verilog::kDefaultSimulationTargets), verilog::ParameterizedTestName); diff --git a/xls/codegen_v_1_5/codegen_proc_test.cc b/xls/codegen_v_1_5/codegen_proc_test.cc index 3cba889328..a7811676b7 100644 --- a/xls/codegen_v_1_5/codegen_proc_test.cc +++ b/xls/codegen_v_1_5/codegen_proc_test.cc @@ -393,7 +393,30 @@ TEST_P(CodegenProcTest, DeclaredChannelInProc) { IsOkAndHolds(outputs)); } -INSTANTIATE_TEST_SUITE_P(CodegenTestInstantiation, CodegenProcTest, +TEST_P(CodegenProcTest, CombinationalSingleProcWithProcScopedChannels) { + Package package(TestBaseName()); + + TokenlessProcBuilder pb(NewStyleProc(), "myleaf", "tkn", &package); + XLS_ASSERT_OK_AND_ASSIGN(ReceiveChannelInterface * in, + pb.AddInputChannel("in", package.GetBitsType(32))); + XLS_ASSERT_OK_AND_ASSIGN(SendChannelInterface * out, + pb.AddOutputChannel("out", package.GetBitsType(32))); + + pb.Send(out, pb.Add(pb.Receive(in), pb.Literal(UBits(1, 32)))); + XLS_ASSERT_OK_AND_ASSIGN(Proc * proc, pb.Build()); + XLS_ASSERT_OK(package.SetTop(proc)); + + XLS_ASSERT_OK_AND_ASSIGN( + auto result, + Codegen(&package, codegen_options().generate_combinational(true), + SchedulingOptions(), + /*delay_estimator=*/nullptr)); + + ExpectVerilogEqualToGoldenFile(GoldenFilePath(kTestName, kTestdataPath), + result.verilog_text); +} + +INSTANTIATE_TEST_SUITE_P(CodegenProcTestInstantiation, CodegenProcTest, testing::ValuesIn(verilog::kDefaultSimulationTargets), verilog::ParameterizedTestName); diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayEq.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayEq.svtxt new file mode 100644 index 0000000000..34adad6502 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayEq.svtxt @@ -0,0 +1,20 @@ +module ArrayEq( + input wire [159:0] x, + input wire [159:0] y, + output wire out +); + wire [31:0] x_unflattened[5]; + assign x_unflattened[0] = x[31:0]; + assign x_unflattened[1] = x[63:32]; + assign x_unflattened[2] = x[95:64]; + assign x_unflattened[3] = x[127:96]; + assign x_unflattened[4] = x[159:128]; + wire [31:0] y_unflattened[5]; + assign y_unflattened[0] = y[31:0]; + assign y_unflattened[1] = y[63:32]; + assign y_unflattened[2] = y[95:64]; + assign y_unflattened[3] = y[127:96]; + assign y_unflattened[4] = y[159:128]; + + assign out = x_unflattened[0] == y_unflattened[0] && x_unflattened[1] == y_unflattened[1] && x_unflattened[2] == y_unflattened[2] && x_unflattened[3] == y_unflattened[3] && x_unflattened[4] == y_unflattened[4]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayEq.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayEq.vtxt new file mode 100644 index 0000000000..9c430eeebc --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayEq.vtxt @@ -0,0 +1,20 @@ +module ArrayEq( + input wire [159:0] x, + input wire [159:0] y, + output wire out +); + wire [31:0] x_unflattened[0:4]; + assign x_unflattened[0] = x[31:0]; + assign x_unflattened[1] = x[63:32]; + assign x_unflattened[2] = x[95:64]; + assign x_unflattened[3] = x[127:96]; + assign x_unflattened[4] = x[159:128]; + wire [31:0] y_unflattened[0:4]; + assign y_unflattened[0] = y[31:0]; + assign y_unflattened[1] = y[63:32]; + assign y_unflattened[2] = y[95:64]; + assign y_unflattened[3] = y[127:96]; + assign y_unflattened[4] = y[159:128]; + + assign out = x_unflattened[0] == y_unflattened[0] && x_unflattened[1] == y_unflattened[1] && x_unflattened[2] == y_unflattened[2] && x_unflattened[3] == y_unflattened[3] && x_unflattened[4] == y_unflattened[4]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSingleElement.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSingleElement.svtxt new file mode 100644 index 0000000000..680e8e79da --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSingleElement.svtxt @@ -0,0 +1,16 @@ +module ArrayIndex2DArrayIndexSingleElement( + input wire [47:0] a, + input wire [15:0] idx0, + input wire [15:0] idx1, + output wire [7:0] out +); + wire [7:0] a_unflattened[2][3]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + + assign out = a_unflattened[idx0 > 16'h0001 ? 1'h1 : idx0[0:0]][idx1 > 16'h0002 ? 2'h2 : idx1[1:0]]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSingleElement.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSingleElement.vtxt new file mode 100644 index 0000000000..ce4bff0563 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSingleElement.vtxt @@ -0,0 +1,16 @@ +module ArrayIndex2DArrayIndexSingleElement( + input wire [47:0] a, + input wire [15:0] idx0, + input wire [15:0] idx1, + output wire [7:0] out +); + wire [7:0] a_unflattened[0:1][0:2]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + + assign out = a_unflattened[idx0 > 16'h0001 ? 1'h1 : idx0[0:0]][idx1 > 16'h0002 ? 2'h2 : idx1[1:0]]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSubArray.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSubArray.svtxt new file mode 100644 index 0000000000..253397dde7 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSubArray.svtxt @@ -0,0 +1,16 @@ +module ArrayIndex2DArrayIndexSubArray( + input wire [47:0] a, + input wire [15:0] idx, + output wire [23:0] out +); + wire [7:0] a_unflattened[2][3]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] array_index_15[3]; + assign array_index_15 = a_unflattened[idx > 16'h0001 ? 1'h1 : idx[0:0]]; + assign out = {array_index_15[2], array_index_15[1], array_index_15[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSubArray.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSubArray.vtxt new file mode 100644 index 0000000000..bbf816426e --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndex2DArrayIndexSubArray.vtxt @@ -0,0 +1,18 @@ +module ArrayIndex2DArrayIndexSubArray( + input wire [47:0] a, + input wire [15:0] idx, + output wire [23:0] out +); + wire [7:0] a_unflattened[0:1][0:2]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] array_index_15[0:2]; + assign array_index_15[0] = a_unflattened[idx > 16'h0001 ? 1'h1 : idx[0:0]][0]; + assign array_index_15[1] = a_unflattened[idx > 16'h0001 ? 1'h1 : idx[0:0]][1]; + assign array_index_15[2] = a_unflattened[idx > 16'h0001 ? 1'h1 : idx[0:0]][2]; + assign out = {array_index_15[2], array_index_15[1], array_index_15[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexNilIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexNilIndex.svtxt new file mode 100644 index 0000000000..7416057ffa --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexNilIndex.svtxt @@ -0,0 +1,11 @@ +module ArrayIndexNilIndex( + input wire [23:0] a, + output wire [23:0] out +); + wire [7:0] a_unflattened[3]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + + assign out = {a_unflattened[2], a_unflattened[1], a_unflattened[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexNilIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexNilIndex.vtxt new file mode 100644 index 0000000000..f0338dabd5 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexNilIndex.vtxt @@ -0,0 +1,11 @@ +module ArrayIndexNilIndex( + input wire [23:0] a, + output wire [23:0] out +); + wire [7:0] a_unflattened[0:2]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + + assign out = {a_unflattened[2], a_unflattened[1], a_unflattened[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexSimpleArray.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexSimpleArray.svtxt new file mode 100644 index 0000000000..a2fb2a1518 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexSimpleArray.svtxt @@ -0,0 +1,12 @@ +module ArrayIndexSimpleArray( + input wire [23:0] a, + input wire [15:0] idx, + output wire [7:0] out +); + wire [7:0] a_unflattened[3]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + + assign out = a_unflattened[idx > 16'h0002 ? 2'h2 : idx[1:0]]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexSimpleArray.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexSimpleArray.vtxt new file mode 100644 index 0000000000..2c5491f88b --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexSimpleArray.vtxt @@ -0,0 +1,12 @@ +module ArrayIndexSimpleArray( + input wire [23:0] a, + input wire [15:0] idx, + output wire [7:0] out +); + wire [7:0] a_unflattened[0:2]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + + assign out = a_unflattened[idx > 16'h0002 ? 2'h2 : idx[1:0]]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithBoundsCheck.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithBoundsCheck.svtxt new file mode 100644 index 0000000000..b392e0ee0b --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithBoundsCheck.svtxt @@ -0,0 +1,12 @@ +module ArrayIndexWithBoundsCheck( + input wire [23:0] A, + input wire [7:0] index, + output wire [7:0] out +); + wire [7:0] A_unflattened[3]; + assign A_unflattened[0] = A[7:0]; + assign A_unflattened[1] = A[15:8]; + assign A_unflattened[2] = A[23:16]; + + assign out = A_unflattened[index > 8'h02 ? 2'h2 : index[1:0]]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithBoundsCheck.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithBoundsCheck.vtxt new file mode 100644 index 0000000000..2abc08cce6 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithBoundsCheck.vtxt @@ -0,0 +1,12 @@ +module ArrayIndexWithBoundsCheck( + input wire [23:0] A, + input wire [7:0] index, + output wire [7:0] out +); + wire [7:0] A_unflattened[0:2]; + assign A_unflattened[0] = A[7:0]; + assign A_unflattened[1] = A[15:8]; + assign A_unflattened[2] = A[23:16]; + + assign out = A_unflattened[index > 8'h02 ? 2'h2 : index[1:0]]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithLiteralIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithLiteralIndex.svtxt new file mode 100644 index 0000000000..11d98c2291 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithLiteralIndex.svtxt @@ -0,0 +1,12 @@ +module ArrayIndexWithLiteralIndex( + input wire [31:0] a, + output wire [7:0] out +); + wire [7:0] a_unflattened[4]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + assign a_unflattened[3] = a[31:24]; + + assign out = a_unflattened[2'h3]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithLiteralIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithLiteralIndex.vtxt new file mode 100644 index 0000000000..05771469ff --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithLiteralIndex.vtxt @@ -0,0 +1,12 @@ +module ArrayIndexWithLiteralIndex( + input wire [31:0] a, + output wire [7:0] out +); + wire [7:0] a_unflattened[0:3]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + assign a_unflattened[3] = a[31:24]; + + assign out = a_unflattened[2'h3]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithNarrowIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithNarrowIndex.svtxt new file mode 100644 index 0000000000..afcb4a9839 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithNarrowIndex.svtxt @@ -0,0 +1,13 @@ +module ArrayIndexWithNarrowIndex( + input wire [31:0] a, + input wire [1:0] idx, + output wire [7:0] out +); + wire [7:0] a_unflattened[4]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + assign a_unflattened[3] = a[31:24]; + + assign out = a_unflattened[idx]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithNarrowIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithNarrowIndex.vtxt new file mode 100644 index 0000000000..39d987441a --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithNarrowIndex.vtxt @@ -0,0 +1,13 @@ +module ArrayIndexWithNarrowIndex( + input wire [31:0] a, + input wire [1:0] idx, + output wire [7:0] out +); + wire [7:0] a_unflattened[0:3]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + assign a_unflattened[3] = a[31:24]; + + assign out = a_unflattened[idx]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithoutBoundsCheck.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithoutBoundsCheck.svtxt new file mode 100644 index 0000000000..861f5f271b --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithoutBoundsCheck.svtxt @@ -0,0 +1,12 @@ +module ArrayIndexWithoutBoundsCheck( + input wire [23:0] A, + input wire [7:0] index, + output wire [7:0] out +); + wire [7:0] A_unflattened[3]; + assign A_unflattened[0] = A[7:0]; + assign A_unflattened[1] = A[15:8]; + assign A_unflattened[2] = A[23:16]; + + assign out = A_unflattened[index]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithoutBoundsCheck.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithoutBoundsCheck.vtxt new file mode 100644 index 0000000000..11fb9b61b2 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayIndexWithoutBoundsCheck.vtxt @@ -0,0 +1,12 @@ +module ArrayIndexWithoutBoundsCheck( + input wire [23:0] A, + input wire [7:0] index, + output wire [7:0] out +); + wire [7:0] A_unflattened[0:2]; + assign A_unflattened[0] = A[7:0]; + assign A_unflattened[1] = A[15:8]; + assign A_unflattened[2] = A[23:16]; + + assign out = A_unflattened[index]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayLiteral.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayLiteral.svtxt new file mode 100644 index 0000000000..7a7959f4bd --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayLiteral.svtxt @@ -0,0 +1,13 @@ +module main( + input wire [31:0] x, + input wire [31:0] y, + output wire [43:0] out +); + wire [43:0] literal_16[2][3]; + assign literal_16 = '{'{44'h000_0000_0001, 44'h000_0000_0002, 44'h000_0000_0003}, '{44'h000_0000_0004, 44'h000_0000_0005, 44'h000_0000_0006}}; + wire [43:0] array_index_18[3]; + wire [43:0] result; + assign array_index_18 = literal_16[x > 32'h0000_0001 ? 1'h1 : x[0:0]]; + assign result = array_index_18[y > 32'h0000_0002 ? 2'h2 : y[1:0]]; + assign out = result; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayLiteral.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayLiteral.vtxt new file mode 100644 index 0000000000..0507661a7b --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayLiteral.vtxt @@ -0,0 +1,20 @@ +module main( + input wire [31:0] x, + input wire [31:0] y, + output wire [43:0] out +); + wire [43:0] literal_16[0:1][0:2]; + assign literal_16[0][0] = 44'h000_0000_0001; + assign literal_16[0][1] = 44'h000_0000_0002; + assign literal_16[0][2] = 44'h000_0000_0003; + assign literal_16[1][0] = 44'h000_0000_0004; + assign literal_16[1][1] = 44'h000_0000_0005; + assign literal_16[1][2] = 44'h000_0000_0006; + wire [43:0] array_index_18[0:2]; + wire [43:0] result; + assign array_index_18[0] = literal_16[x > 32'h0000_0001 ? 1'h1 : x[0:0]][0]; + assign array_index_18[1] = literal_16[x > 32'h0000_0001 ? 1'h1 : x[0:0]][1]; + assign array_index_18[2] = literal_16[x > 32'h0000_0001 ? 1'h1 : x[0:0]][2]; + assign result = array_index_18[y > 32'h0000_0002 ? 2'h2 : y[1:0]]; + assign out = result; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWiderThanInputArray.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWiderThanInputArray.svtxt new file mode 100644 index 0000000000..7d2a4f8637 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWiderThanInputArray.svtxt @@ -0,0 +1,17 @@ +module ArraySliceWiderThanInputArray( + input wire [95:0] a, + input wire [31:0] start, + output wire [159:0] out +); + wire [31:0] a_unflattened[3]; + assign a_unflattened[0] = a[31:0]; + assign a_unflattened[1] = a[63:32]; + assign a_unflattened[2] = a[95:64]; + wire [31:0] array_slice_15[5]; + assign array_slice_15[0] = a_unflattened[start > 32'h0000_0002 ? 32'h0000_0002 : start + 32'h0000_0000]; + assign array_slice_15[1] = a_unflattened[start > 32'h0000_0001 ? 32'h0000_0002 : start + 32'h0000_0001]; + assign array_slice_15[2] = a_unflattened[start > 32'h0000_0000 ? 32'h0000_0002 : start + 32'h0000_0002]; + assign array_slice_15[3] = a_unflattened[32'h0000_0002]; + assign array_slice_15[4] = a_unflattened[32'h0000_0002]; + assign out = {array_slice_15[4], array_slice_15[3], array_slice_15[2], array_slice_15[1], array_slice_15[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWiderThanInputArray.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWiderThanInputArray.vtxt new file mode 100644 index 0000000000..875bdec73e --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWiderThanInputArray.vtxt @@ -0,0 +1,17 @@ +module ArraySliceWiderThanInputArray( + input wire [95:0] a, + input wire [31:0] start, + output wire [159:0] out +); + wire [31:0] a_unflattened[0:2]; + assign a_unflattened[0] = a[31:0]; + assign a_unflattened[1] = a[63:32]; + assign a_unflattened[2] = a[95:64]; + wire [31:0] array_slice_15[0:4]; + assign array_slice_15[0] = a_unflattened[start > 32'h0000_0002 ? 32'h0000_0002 : start + 32'h0000_0000]; + assign array_slice_15[1] = a_unflattened[start > 32'h0000_0001 ? 32'h0000_0002 : start + 32'h0000_0001]; + assign array_slice_15[2] = a_unflattened[start > 32'h0000_0000 ? 32'h0000_0002 : start + 32'h0000_0002]; + assign array_slice_15[3] = a_unflattened[32'h0000_0002]; + assign array_slice_15[4] = a_unflattened[32'h0000_0002]; + assign out = {array_slice_15[4], array_slice_15[3], array_slice_15[2], array_slice_15[1], array_slice_15[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWithNarrowStart.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWithNarrowStart.svtxt new file mode 100644 index 0000000000..4f21c2ab5a --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWithNarrowStart.svtxt @@ -0,0 +1,17 @@ +module ArraySliceWithNarrowStart( + input wire [159:0] a, + input wire start, + output wire [95:0] out +); + wire [31:0] a_unflattened[5]; + assign a_unflattened[0] = a[31:0]; + assign a_unflattened[1] = a[63:32]; + assign a_unflattened[2] = a[95:64]; + assign a_unflattened[3] = a[127:96]; + assign a_unflattened[4] = a[159:128]; + wire [31:0] array_slice_15[3]; + assign array_slice_15[0] = a_unflattened[{2'h0, start} > 3'h4 ? 3'h4 : {2'h0, start} + 3'h0]; + assign array_slice_15[1] = a_unflattened[{2'h0, start} > 3'h3 ? 3'h4 : {2'h0, start} + 3'h1]; + assign array_slice_15[2] = a_unflattened[{2'h0, start} > 3'h2 ? 3'h4 : {2'h0, start} + 3'h2]; + assign out = {array_slice_15[2], array_slice_15[1], array_slice_15[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWithNarrowStart.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWithNarrowStart.vtxt new file mode 100644 index 0000000000..de81e5454c --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArraySliceWithNarrowStart.vtxt @@ -0,0 +1,17 @@ +module ArraySliceWithNarrowStart( + input wire [159:0] a, + input wire start, + output wire [95:0] out +); + wire [31:0] a_unflattened[0:4]; + assign a_unflattened[0] = a[31:0]; + assign a_unflattened[1] = a[63:32]; + assign a_unflattened[2] = a[95:64]; + assign a_unflattened[3] = a[127:96]; + assign a_unflattened[4] = a[159:128]; + wire [31:0] array_slice_15[0:2]; + assign array_slice_15[0] = a_unflattened[{2'h0, start} > 3'h4 ? 3'h4 : {2'h0, start} + 3'h0]; + assign array_slice_15[1] = a_unflattened[{2'h0, start} > 3'h3 ? 3'h4 : {2'h0, start} + 3'h1]; + assign array_slice_15[2] = a_unflattened[{2'h0, start} > 3'h2 ? 3'h4 : {2'h0, start} + 3'h2]; + assign out = {array_slice_15[2], array_slice_15[1], array_slice_15[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DLiteralIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DLiteralIndex.svtxt new file mode 100644 index 0000000000..06431427e8 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DLiteralIndex.svtxt @@ -0,0 +1,20 @@ +module ArrayUpdate2DLiteralIndex( + input wire [47:0] a, + input wire [7:0] value, + output wire [47:0] out +); + wire [7:0] a_unflattened[2][3]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] array_update_19[2][3]; + assign out = {{array_update_19[1][2], array_update_19[1][1], array_update_19[1][0]}, {array_update_19[0][2], array_update_19[0][1], array_update_19[0][0]}}; + for (genvar __i0 = 0; __i0 < 2; __i0 = __i0 + 1) begin : gen__array_update_19_0 + for (genvar __i1 = 0; __i1 < 3; __i1 = __i1 + 1) begin : gen__array_update_19_1 + assign array_update_19[__i0][__i1] = 32'h0000_0000 == __i0 && 14'h0002 == __i1 ? value : a_unflattened[__i0][__i1]; + end + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DLiteralIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DLiteralIndex.vtxt new file mode 100644 index 0000000000..f28308bb8d --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DLiteralIndex.vtxt @@ -0,0 +1,20 @@ +module ArrayUpdate2DLiteralIndex( + input wire [47:0] a, + input wire [7:0] value, + output wire [47:0] out +); + wire [7:0] a_unflattened[0:1][0:2]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] array_update_19[0:1][0:2]; + assign out = {{array_update_19[1][2], array_update_19[1][1], array_update_19[1][0]}, {array_update_19[0][2], array_update_19[0][1], array_update_19[0][0]}}; + for (genvar __i0 = 0; __i0 < 2; __i0 = __i0 + 1) begin : gen__array_update_19_0 + for (genvar __i1 = 0; __i1 < 3; __i1 = __i1 + 1) begin : gen__array_update_19_1 + assign array_update_19[__i0][__i1] = 32'h0000_0000 == __i0 && 14'h0002 == __i1 ? value : a_unflattened[__i0][__i1]; + end + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayLiteralIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayLiteralIndex.svtxt new file mode 100644 index 0000000000..8687d63d4d --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayLiteralIndex.svtxt @@ -0,0 +1,24 @@ +module ArrayUpdate2DUpdateArrayLiteralIndex( + input wire [47:0] a, + input wire [23:0] value, + output wire [47:0] out +); + wire [7:0] a_unflattened[2][3]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] value_unflattened[3]; + assign value_unflattened[0] = value[7:0]; + assign value_unflattened[1] = value[15:8]; + assign value_unflattened[2] = value[23:16]; + wire [7:0] array_update_17[2][3]; + assign out = {{array_update_17[1][2], array_update_17[1][1], array_update_17[1][0]}, {array_update_17[0][2], array_update_17[0][1], array_update_17[0][0]}}; + for (genvar __i0 = 0; __i0 < 2; __i0 = __i0 + 1) begin : gen__array_update_17_0 + for (genvar __j0 = 0; __j0 < 3; __j0 = __j0 + 1) begin : gen__array_update_17_0__1 + assign array_update_17[__i0][__j0] = 14'h0001 == __i0 ? value_unflattened[__j0] : a_unflattened[__i0][__j0]; + end + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayLiteralIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayLiteralIndex.vtxt new file mode 100644 index 0000000000..d972d52315 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayLiteralIndex.vtxt @@ -0,0 +1,24 @@ +module ArrayUpdate2DUpdateArrayLiteralIndex( + input wire [47:0] a, + input wire [23:0] value, + output wire [47:0] out +); + wire [7:0] a_unflattened[0:1][0:2]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] value_unflattened[0:2]; + assign value_unflattened[0] = value[7:0]; + assign value_unflattened[1] = value[15:8]; + assign value_unflattened[2] = value[23:16]; + wire [7:0] array_update_17[0:1][0:2]; + assign out = {{array_update_17[1][2], array_update_17[1][1], array_update_17[1][0]}, {array_update_17[0][2], array_update_17[0][1], array_update_17[0][0]}}; + for (genvar __i0 = 0; __i0 < 2; __i0 = __i0 + 1) begin : gen__array_update_17_0 + for (genvar __j0 = 0; __j0 < 3; __j0 = __j0 + 1) begin : gen__array_update_17_0__1 + assign array_update_17[__i0][__j0] = 14'h0001 == __i0 ? value_unflattened[__j0] : a_unflattened[__i0][__j0]; + end + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayNilIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayNilIndex.svtxt new file mode 100644 index 0000000000..10e15d7cf3 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayNilIndex.svtxt @@ -0,0 +1,22 @@ +module ArrayUpdate2DUpdateArrayNilIndex( + input wire [47:0] a, + input wire [47:0] value, + output wire [47:0] out +); + wire [7:0] a_unflattened[2][3]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] value_unflattened[2][3]; + assign value_unflattened[0][0] = value[7:0]; + assign value_unflattened[0][1] = value[15:8]; + assign value_unflattened[0][2] = value[23:16]; + assign value_unflattened[1][0] = value[31:24]; + assign value_unflattened[1][1] = value[39:32]; + assign value_unflattened[1][2] = value[47:40]; + + assign out = {{value_unflattened[1][2], value_unflattened[1][1], value_unflattened[1][0]}, {value_unflattened[0][2], value_unflattened[0][1], value_unflattened[0][0]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayNilIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayNilIndex.vtxt new file mode 100644 index 0000000000..54566dd5ef --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayNilIndex.vtxt @@ -0,0 +1,22 @@ +module ArrayUpdate2DUpdateArrayNilIndex( + input wire [47:0] a, + input wire [47:0] value, + output wire [47:0] out +); + wire [7:0] a_unflattened[0:1][0:2]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] value_unflattened[0:1][0:2]; + assign value_unflattened[0][0] = value[7:0]; + assign value_unflattened[0][1] = value[15:8]; + assign value_unflattened[0][2] = value[23:16]; + assign value_unflattened[1][0] = value[31:24]; + assign value_unflattened[1][1] = value[39:32]; + assign value_unflattened[1][2] = value[47:40]; + + assign out = {{value_unflattened[1][2], value_unflattened[1][1], value_unflattened[1][0]}, {value_unflattened[0][2], value_unflattened[0][1], value_unflattened[0][0]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayVariableIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayVariableIndex.svtxt new file mode 100644 index 0000000000..f43ffe86e9 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayVariableIndex.svtxt @@ -0,0 +1,25 @@ +module ArrayUpdate2DUpdateArrayVariableIndex( + input wire [47:0] a, + input wire [23:0] value, + input wire [36:0] idx, + output wire [47:0] out +); + wire [7:0] a_unflattened[2][3]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] value_unflattened[3]; + assign value_unflattened[0] = value[7:0]; + assign value_unflattened[1] = value[15:8]; + assign value_unflattened[2] = value[23:16]; + wire [7:0] array_update_18[2][3]; + assign out = {{array_update_18[1][2], array_update_18[1][1], array_update_18[1][0]}, {array_update_18[0][2], array_update_18[0][1], array_update_18[0][0]}}; + for (genvar __i0 = 0; __i0 < 2; __i0 = __i0 + 1) begin : gen__array_update_18_0 + for (genvar __j0 = 0; __j0 < 3; __j0 = __j0 + 1) begin : gen__array_update_18_0__1 + assign array_update_18[__i0][__j0] = idx == __i0 ? value_unflattened[__j0] : a_unflattened[__i0][__j0]; + end + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayVariableIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayVariableIndex.vtxt new file mode 100644 index 0000000000..2ce61233c9 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DUpdateArrayVariableIndex.vtxt @@ -0,0 +1,25 @@ +module ArrayUpdate2DUpdateArrayVariableIndex( + input wire [47:0] a, + input wire [23:0] value, + input wire [36:0] idx, + output wire [47:0] out +); + wire [7:0] a_unflattened[0:1][0:2]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] value_unflattened[0:2]; + assign value_unflattened[0] = value[7:0]; + assign value_unflattened[1] = value[15:8]; + assign value_unflattened[2] = value[23:16]; + wire [7:0] array_update_18[0:1][0:2]; + assign out = {{array_update_18[1][2], array_update_18[1][1], array_update_18[1][0]}, {array_update_18[0][2], array_update_18[0][1], array_update_18[0][0]}}; + for (genvar __i0 = 0; __i0 < 2; __i0 = __i0 + 1) begin : gen__array_update_18_0 + for (genvar __j0 = 0; __j0 < 3; __j0 = __j0 + 1) begin : gen__array_update_18_0__1 + assign array_update_18[__i0][__j0] = idx == __i0 ? value_unflattened[__j0] : a_unflattened[__i0][__j0]; + end + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DVariableIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DVariableIndex.svtxt new file mode 100644 index 0000000000..9053c4dd31 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DVariableIndex.svtxt @@ -0,0 +1,22 @@ +module ArrayUpdate2DVariableIndex( + input wire [47:0] a, + input wire [7:0] value, + input wire [31:0] idx0, + input wire [31:0] idx1, + output wire [47:0] out +); + wire [7:0] a_unflattened[2][3]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] array_update_21[2][3]; + assign out = {{array_update_21[1][2], array_update_21[1][1], array_update_21[1][0]}, {array_update_21[0][2], array_update_21[0][1], array_update_21[0][0]}}; + for (genvar __i0 = 0; __i0 < 2; __i0 = __i0 + 1) begin : gen__array_update_21_0 + for (genvar __i1 = 0; __i1 < 3; __i1 = __i1 + 1) begin : gen__array_update_21_1 + assign array_update_21[__i0][__i1] = idx0 == __i0 && idx1 == __i1 ? value : a_unflattened[__i0][__i1]; + end + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DVariableIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DVariableIndex.vtxt new file mode 100644 index 0000000000..2b322a07dc --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdate2DVariableIndex.vtxt @@ -0,0 +1,22 @@ +module ArrayUpdate2DVariableIndex( + input wire [47:0] a, + input wire [7:0] value, + input wire [31:0] idx0, + input wire [31:0] idx1, + output wire [47:0] out +); + wire [7:0] a_unflattened[0:1][0:2]; + assign a_unflattened[0][0] = a[7:0]; + assign a_unflattened[0][1] = a[15:8]; + assign a_unflattened[0][2] = a[23:16]; + assign a_unflattened[1][0] = a[31:24]; + assign a_unflattened[1][1] = a[39:32]; + assign a_unflattened[1][2] = a[47:40]; + wire [7:0] array_update_21[0:1][0:2]; + assign out = {{array_update_21[1][2], array_update_21[1][1], array_update_21[1][0]}, {array_update_21[0][2], array_update_21[0][1], array_update_21[0][0]}}; + for (genvar __i0 = 0; __i0 < 2; __i0 = __i0 + 1) begin : gen__array_update_21_0 + for (genvar __i1 = 0; __i1 < 3; __i1 = __i1 + 1) begin : gen__array_update_21_1 + assign array_update_21[__i0][__i1] = idx0 == __i0 && idx1 == __i1 ? value : a_unflattened[__i0][__i1]; + end + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateBitsNilIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateBitsNilIndex.svtxt new file mode 100644 index 0000000000..abbfcb4495 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateBitsNilIndex.svtxt @@ -0,0 +1,7 @@ +module ArrayUpdateBitsNilIndex( + input wire [7:0] a, + input wire [7:0] value, + output wire [7:0] out +); + assign out = value; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateBitsNilIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateBitsNilIndex.vtxt new file mode 100644 index 0000000000..abbfcb4495 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateBitsNilIndex.vtxt @@ -0,0 +1,7 @@ +module ArrayUpdateBitsNilIndex( + input wire [7:0] a, + input wire [7:0] value, + output wire [7:0] out +); + assign out = value; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateLiteralIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateLiteralIndex.svtxt new file mode 100644 index 0000000000..91256c64b4 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateLiteralIndex.svtxt @@ -0,0 +1,15 @@ +module ArrayUpdateLiteralIndex( + input wire [23:0] a, + input wire [7:0] value, + output wire [23:0] out +); + wire [7:0] a_unflattened[3]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + wire [7:0] array_update_17[3]; + assign out = {array_update_17[2], array_update_17[1], array_update_17[0]}; + for (genvar __i0 = 0; __i0 < 3; __i0 = __i0 + 1) begin : gen__array_update_17_0 + assign array_update_17[__i0] = 16'h0001 == __i0 ? value : a_unflattened[__i0]; + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateLiteralIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateLiteralIndex.vtxt new file mode 100644 index 0000000000..65ab69aa7d --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateLiteralIndex.vtxt @@ -0,0 +1,15 @@ +module ArrayUpdateLiteralIndex( + input wire [23:0] a, + input wire [7:0] value, + output wire [23:0] out +); + wire [7:0] a_unflattened[0:2]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + wire [7:0] array_update_17[0:2]; + assign out = {array_update_17[2], array_update_17[1], array_update_17[0]}; + for (genvar __i0 = 0; __i0 < 3; __i0 = __i0 + 1) begin : gen__array_update_17_0 + assign array_update_17[__i0] = 16'h0001 == __i0 ? value : a_unflattened[__i0]; + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateVariableIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateVariableIndex.svtxt new file mode 100644 index 0000000000..bc0027c674 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateVariableIndex.svtxt @@ -0,0 +1,16 @@ +module ArrayUpdateVariableIndex( + input wire [23:0] a, + input wire [7:0] value, + input wire [31:0] idx, + output wire [23:0] out +); + wire [7:0] a_unflattened[3]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + wire [7:0] array_update_18[3]; + assign out = {array_update_18[2], array_update_18[1], array_update_18[0]}; + for (genvar __i0 = 0; __i0 < 3; __i0 = __i0 + 1) begin : gen__array_update_18_0 + assign array_update_18[__i0] = idx == __i0 ? value : a_unflattened[__i0]; + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateVariableIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateVariableIndex.vtxt new file mode 100644 index 0000000000..1270944f7e --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateVariableIndex.vtxt @@ -0,0 +1,16 @@ +module ArrayUpdateVariableIndex( + input wire [23:0] a, + input wire [7:0] value, + input wire [31:0] idx, + output wire [23:0] out +); + wire [7:0] a_unflattened[0:2]; + assign a_unflattened[0] = a[7:0]; + assign a_unflattened[1] = a[15:8]; + assign a_unflattened[2] = a[23:16]; + wire [7:0] array_update_18[0:2]; + assign out = {array_update_18[2], array_update_18[1], array_update_18[0]}; + for (genvar __i0 = 0; __i0 < 3; __i0 = __i0 + 1) begin : gen__array_update_18_0 + assign array_update_18[__i0] = idx == __i0 ? value : a_unflattened[__i0]; + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithDifferentTypesIndices.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithDifferentTypesIndices.svtxt new file mode 100644 index 0000000000..5561971504 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithDifferentTypesIndices.svtxt @@ -0,0 +1,22 @@ +module ArrayUpdateWithDifferentTypesIndices( + input wire [3:0] i0, + input wire [4:0] i1, + input wire [191:0] a, + input wire [31:0] value, + output wire [191:0] out +); + wire [31:0] a_unflattened[2][3]; + assign a_unflattened[0][0] = a[31:0]; + assign a_unflattened[0][1] = a[63:32]; + assign a_unflattened[0][2] = a[95:64]; + assign a_unflattened[1][0] = a[127:96]; + assign a_unflattened[1][1] = a[159:128]; + assign a_unflattened[1][2] = a[191:160]; + wire [31:0] array_update_21[2][3]; + assign out = {{array_update_21[1][2], array_update_21[1][1], array_update_21[1][0]}, {array_update_21[0][2], array_update_21[0][1], array_update_21[0][0]}}; + for (genvar __i0 = 0; __i0 < 2; __i0 = __i0 + 1) begin : gen__array_update_21_0 + for (genvar __i1 = 0; __i1 < 3; __i1 = __i1 + 1) begin : gen__array_update_21_1 + assign array_update_21[__i0][__i1] = i0 == __i0 && i1 == __i1 ? value : a_unflattened[__i0][__i1]; + end + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithDifferentTypesIndices.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithDifferentTypesIndices.vtxt new file mode 100644 index 0000000000..f9e39b36eb --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithDifferentTypesIndices.vtxt @@ -0,0 +1,22 @@ +module ArrayUpdateWithDifferentTypesIndices( + input wire [3:0] i0, + input wire [4:0] i1, + input wire [191:0] a, + input wire [31:0] value, + output wire [191:0] out +); + wire [31:0] a_unflattened[0:1][0:2]; + assign a_unflattened[0][0] = a[31:0]; + assign a_unflattened[0][1] = a[63:32]; + assign a_unflattened[0][2] = a[95:64]; + assign a_unflattened[1][0] = a[127:96]; + assign a_unflattened[1][1] = a[159:128]; + assign a_unflattened[1][2] = a[191:160]; + wire [31:0] array_update_21[0:1][0:2]; + assign out = {{array_update_21[1][2], array_update_21[1][1], array_update_21[1][0]}, {array_update_21[0][2], array_update_21[0][1], array_update_21[0][0]}}; + for (genvar __i0 = 0; __i0 < 2; __i0 = __i0 + 1) begin : gen__array_update_21_0 + for (genvar __i1 = 0; __i1 < 3; __i1 = __i1 + 1) begin : gen__array_update_21_1 + assign array_update_21[__i0][__i1] = i0 == __i0 && i1 == __i1 ? value : a_unflattened[__i0][__i1]; + end + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithNarrowIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithNarrowIndex.svtxt new file mode 100644 index 0000000000..ae42ab7ecb --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithNarrowIndex.svtxt @@ -0,0 +1,23 @@ +module ArrayUpdateWithNarrowIndex( + input wire [319:0] a, + input wire [1:0] idx, + input wire [31:0] v, + output wire [319:0] out +); + wire [31:0] a_unflattened[10]; + assign a_unflattened[0] = a[31:0]; + assign a_unflattened[1] = a[63:32]; + assign a_unflattened[2] = a[95:64]; + assign a_unflattened[3] = a[127:96]; + assign a_unflattened[4] = a[159:128]; + assign a_unflattened[5] = a[191:160]; + assign a_unflattened[6] = a[223:192]; + assign a_unflattened[7] = a[255:224]; + assign a_unflattened[8] = a[287:256]; + assign a_unflattened[9] = a[319:288]; + wire [31:0] array_update_18[10]; + assign out = {array_update_18[9], array_update_18[8], array_update_18[7], array_update_18[6], array_update_18[5], array_update_18[4], array_update_18[3], array_update_18[2], array_update_18[1], array_update_18[0]}; + for (genvar __i0 = 0; __i0 < 10; __i0 = __i0 + 1) begin : gen__array_update_18_0 + assign array_update_18[__i0] = idx == __i0 ? v : a_unflattened[__i0]; + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithNarrowIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithNarrowIndex.vtxt new file mode 100644 index 0000000000..a2320bb4ed --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ArrayUpdateWithNarrowIndex.vtxt @@ -0,0 +1,23 @@ +module ArrayUpdateWithNarrowIndex( + input wire [319:0] a, + input wire [1:0] idx, + input wire [31:0] v, + output wire [319:0] out +); + wire [31:0] a_unflattened[0:9]; + assign a_unflattened[0] = a[31:0]; + assign a_unflattened[1] = a[63:32]; + assign a_unflattened[2] = a[95:64]; + assign a_unflattened[3] = a[127:96]; + assign a_unflattened[4] = a[159:128]; + assign a_unflattened[5] = a[191:160]; + assign a_unflattened[6] = a[223:192]; + assign a_unflattened[7] = a[255:224]; + assign a_unflattened[8] = a[287:256]; + assign a_unflattened[9] = a[319:288]; + wire [31:0] array_update_18[0:9]; + assign out = {array_update_18[9], array_update_18[8], array_update_18[7], array_update_18[6], array_update_18[5], array_update_18[4], array_update_18[3], array_update_18[2], array_update_18[1], array_update_18[0]}; + for (genvar __i0 = 0; __i0 < 10; __i0 = __i0 + 1) begin : gen__array_update_18_0 + assign array_update_18[__i0] = idx == __i0 ? v : a_unflattened[__i0]; + end +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_CombinationalExpressionWhichRequiresNamedIntermediate.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_CombinationalExpressionWhichRequiresNamedIntermediate.svtxt new file mode 100644 index 0000000000..2b92094b6c --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_CombinationalExpressionWhichRequiresNamedIntermediate.svtxt @@ -0,0 +1,11 @@ +module CombinationalExpressionWhichRequiresNamedIntermediate( + input wire [7:0] a, + input wire [7:0] b, + output wire [3:0] out +); + wire [7:0] add_14; + wire [3:0] slice_n_dice; + assign add_14 = a + b; + assign slice_n_dice = add_14[6:3]; + assign out = slice_n_dice; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_CombinationalExpressionWhichRequiresNamedIntermediate.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_CombinationalExpressionWhichRequiresNamedIntermediate.vtxt new file mode 100644 index 0000000000..2b92094b6c --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_CombinationalExpressionWhichRequiresNamedIntermediate.vtxt @@ -0,0 +1,11 @@ +module CombinationalExpressionWhichRequiresNamedIntermediate( + input wire [7:0] a, + input wire [7:0] b, + output wire [3:0] out +); + wire [7:0] add_14; + wire [3:0] slice_n_dice; + assign add_14 = a + b; + assign slice_n_dice = add_14[6:3]; + assign out = slice_n_dice; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ExpressionsOfTuples.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ExpressionsOfTuples.svtxt new file mode 100644 index 0000000000..f4cd67e77d --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ExpressionsOfTuples.svtxt @@ -0,0 +1,12 @@ +module ExpressionsOfTuples( + input wire [7:0] a, + input wire [9:0] b, + input wire [25:0] c, + output wire [31:0] out +); + wire [15:0] add_36; + wire [15:0] sub_37; + assign add_36 = {8'h00, a} + {6'h00, b}; + assign sub_37 = {6'h00, c[25:16]} - c[15:0]; + assign out = {add_36, sub_37}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ExpressionsOfTuples.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ExpressionsOfTuples.vtxt new file mode 100644 index 0000000000..f4cd67e77d --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_ExpressionsOfTuples.vtxt @@ -0,0 +1,12 @@ +module ExpressionsOfTuples( + input wire [7:0] a, + input wire [9:0] b, + input wire [25:0] c, + output wire [31:0] out +); + wire [15:0] add_36; + wire [15:0] sub_37; + assign add_36 = {8'h00, a} + {6'h00, b}; + assign sub_37 = {6'h00, c[25:16]} - c[15:0]; + assign out = {add_36, sub_37}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneBitTupleIndex.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneBitTupleIndex.svtxt new file mode 100644 index 0000000000..6f6435a866 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneBitTupleIndex.svtxt @@ -0,0 +1,9 @@ +module OneBitTupleIndex( + input wire x, + output wire out +); + wire x_unflattened[1]; + assign x_unflattened[0] = x; + + assign out = x_unflattened[1'h0]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneBitTupleIndex.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneBitTupleIndex.vtxt new file mode 100644 index 0000000000..069e39aed0 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneBitTupleIndex.vtxt @@ -0,0 +1,9 @@ +module OneBitTupleIndex( + input wire x, + output wire out +); + wire x_unflattened[0:0]; + assign x_unflattened[0] = x; + + assign out = x_unflattened[1'h0]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHot.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHot.svtxt new file mode 100644 index 0000000000..022530ac54 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHot.svtxt @@ -0,0 +1,6 @@ +module main( + input wire [2:0] x, + output wire [3:0] out +); + assign out = {x[2:0] == 3'h0, x[2] && x[1:0] == 2'h0, x[1] && !x[0], x[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHot.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHot.vtxt new file mode 100644 index 0000000000..022530ac54 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHot.vtxt @@ -0,0 +1,6 @@ +module main( + input wire [2:0] x, + output wire [3:0] out +); + assign out = {x[2:0] == 3'h0, x[2] && x[1:0] == 2'h0, x[1] && !x[0], x[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelect.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelect.svtxt new file mode 100644 index 0000000000..a5b17bd817 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelect.svtxt @@ -0,0 +1,8 @@ +module main( + input wire [1:0] p, + input wire [15:0] x, + input wire [15:0] y, + output wire [15:0] out +); + assign out = x & {16{p[0]}} | y & {16{p[1]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelect.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelect.vtxt new file mode 100644 index 0000000000..a5b17bd817 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelect.vtxt @@ -0,0 +1,8 @@ +module main( + input wire [1:0] p, + input wire [15:0] x, + input wire [15:0] y, + output wire [15:0] out +); + assign out = x & {16{p[0]}} | y & {16{p[1]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelectNonBits.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelectNonBits.svtxt new file mode 100644 index 0000000000..9e5ae0ed7a --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelectNonBits.svtxt @@ -0,0 +1,8 @@ +module main( + input wire [1:0] p, + input wire [31:0] x, + input wire [31:0] y, + output wire [31:0] out +); + assign out = x & {32{p[0]}} | y & {32{p[1]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelectNonBits.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelectNonBits.vtxt new file mode 100644 index 0000000000..9e5ae0ed7a --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_OneHotSelectNonBits.vtxt @@ -0,0 +1,8 @@ +module main( + input wire [1:0] p, + input wire [31:0] x, + input wire [31:0] y, + output wire [31:0] out +); + assign out = x & {32{p[0]}} | y & {32{p[1]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelect.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelect.svtxt new file mode 100644 index 0000000000..e863e62c9b --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelect.svtxt @@ -0,0 +1,29 @@ +module main( + input wire [1:0] p, + input wire [15:0] x, + input wire [15:0] y, + input wire [15:0] d, + output wire [15:0] out +); + function automatic [15:0] priority_sel_16b_2way (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + unique casez (sel) + 2'b?1: begin + priority_sel_16b_2way = case0; + end + 2'b10: begin + priority_sel_16b_2way = case1; + end + 2'b00: begin + priority_sel_16b_2way = default_value; + end + default: begin + // Propagate X + priority_sel_16b_2way = 'X; + end + endcase + end + endfunction + + assign out = priority_sel_16b_2way(p, x, y, d); +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelect.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelect.vtxt new file mode 100644 index 0000000000..dbb65eafa1 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelect.vtxt @@ -0,0 +1,29 @@ +module main( + input wire [1:0] p, + input wire [15:0] x, + input wire [15:0] y, + input wire [15:0] d, + output wire [15:0] out +); + function automatic [15:0] priority_sel_16b_2way (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + casez (sel) + 2'b?1: begin + priority_sel_16b_2way = case0; + end + 2'b10: begin + priority_sel_16b_2way = case1; + end + 2'b00: begin + priority_sel_16b_2way = default_value; + end + default: begin + // Propagate X + priority_sel_16b_2way = 16'dx; + end + endcase + end + endfunction + + assign out = priority_sel_16b_2way(p, x, y, d); +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArray.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArray.svtxt new file mode 100644 index 0000000000..13a7ffeb6d --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArray.svtxt @@ -0,0 +1,48 @@ +module main( + input wire [1:0] p, + input wire [63:0] x, + input wire [63:0] y, + input wire [63:0] d, + output wire [63:0] out +); + function automatic [15:0] priority_sel_64b_2way_element16 (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + unique casez (sel) + 2'b?1: begin + priority_sel_64b_2way_element16 = case0; + end + 2'b10: begin + priority_sel_64b_2way_element16 = case1; + end + 2'b00: begin + priority_sel_64b_2way_element16 = default_value; + end + default: begin + // Propagate X + priority_sel_64b_2way_element16 = 'X; + end + endcase + end + endfunction + wire [15:0] x_unflattened[4]; + assign x_unflattened[0] = x[15:0]; + assign x_unflattened[1] = x[31:16]; + assign x_unflattened[2] = x[47:32]; + assign x_unflattened[3] = x[63:48]; + wire [15:0] y_unflattened[4]; + assign y_unflattened[0] = y[15:0]; + assign y_unflattened[1] = y[31:16]; + assign y_unflattened[2] = y[47:32]; + assign y_unflattened[3] = y[63:48]; + wire [15:0] d_unflattened[4]; + assign d_unflattened[0] = d[15:0]; + assign d_unflattened[1] = d[31:16]; + assign d_unflattened[2] = d[47:32]; + assign d_unflattened[3] = d[63:48]; + wire [15:0] priority_sel_25[4]; + assign priority_sel_25[0] = priority_sel_64b_2way_element16(p, x_unflattened[0], y_unflattened[0], d_unflattened[0]); + assign priority_sel_25[1] = priority_sel_64b_2way_element16(p, x_unflattened[1], y_unflattened[1], d_unflattened[1]); + assign priority_sel_25[2] = priority_sel_64b_2way_element16(p, x_unflattened[2], y_unflattened[2], d_unflattened[2]); + assign priority_sel_25[3] = priority_sel_64b_2way_element16(p, x_unflattened[3], y_unflattened[3], d_unflattened[3]); + assign out = {priority_sel_25[3], priority_sel_25[2], priority_sel_25[1], priority_sel_25[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArray.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArray.vtxt new file mode 100644 index 0000000000..c02e8b08d0 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArray.vtxt @@ -0,0 +1,48 @@ +module main( + input wire [1:0] p, + input wire [63:0] x, + input wire [63:0] y, + input wire [63:0] d, + output wire [63:0] out +); + function automatic [15:0] priority_sel_64b_2way_element16 (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + casez (sel) + 2'b?1: begin + priority_sel_64b_2way_element16 = case0; + end + 2'b10: begin + priority_sel_64b_2way_element16 = case1; + end + 2'b00: begin + priority_sel_64b_2way_element16 = default_value; + end + default: begin + // Propagate X + priority_sel_64b_2way_element16 = 16'dx; + end + endcase + end + endfunction + wire [15:0] x_unflattened[0:3]; + assign x_unflattened[0] = x[15:0]; + assign x_unflattened[1] = x[31:16]; + assign x_unflattened[2] = x[47:32]; + assign x_unflattened[3] = x[63:48]; + wire [15:0] y_unflattened[0:3]; + assign y_unflattened[0] = y[15:0]; + assign y_unflattened[1] = y[31:16]; + assign y_unflattened[2] = y[47:32]; + assign y_unflattened[3] = y[63:48]; + wire [15:0] d_unflattened[0:3]; + assign d_unflattened[0] = d[15:0]; + assign d_unflattened[1] = d[31:16]; + assign d_unflattened[2] = d[47:32]; + assign d_unflattened[3] = d[63:48]; + wire [15:0] priority_sel_25[0:3]; + assign priority_sel_25[0] = priority_sel_64b_2way_element16(p, x_unflattened[0], y_unflattened[0], d_unflattened[0]); + assign priority_sel_25[1] = priority_sel_64b_2way_element16(p, x_unflattened[1], y_unflattened[1], d_unflattened[1]); + assign priority_sel_25[2] = priority_sel_64b_2way_element16(p, x_unflattened[2], y_unflattened[2], d_unflattened[2]); + assign priority_sel_25[3] = priority_sel_64b_2way_element16(p, x_unflattened[3], y_unflattened[3], d_unflattened[3]); + assign out = {priority_sel_25[3], priority_sel_25[2], priority_sel_25[1], priority_sel_25[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArrayOneHot.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArrayOneHot.svtxt new file mode 100644 index 0000000000..f64454a3c6 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArrayOneHot.svtxt @@ -0,0 +1,38 @@ +module main( + input wire p, + input wire [63:0] x, + input wire [63:0] y, + input wire [63:0] d, + output wire [63:0] out +); + wire [15:0] x_unflattened[4]; + assign x_unflattened[0] = x[15:0]; + assign x_unflattened[1] = x[31:16]; + assign x_unflattened[2] = x[47:32]; + assign x_unflattened[3] = x[63:48]; + wire [15:0] y_unflattened[4]; + assign y_unflattened[0] = y[15:0]; + assign y_unflattened[1] = y[31:16]; + assign y_unflattened[2] = y[47:32]; + assign y_unflattened[3] = y[63:48]; + wire [15:0] d_unflattened[4]; + assign d_unflattened[0] = d[15:0]; + assign d_unflattened[1] = d[31:16]; + assign d_unflattened[2] = d[47:32]; + assign d_unflattened[3] = d[63:48]; + wire [1:0] one_hot_21; + wire [2:0] one_hot_31; + wire [15:0] one_hot_sel_36[4]; + wire eq_33; + assign one_hot_21 = {!p, p}; + assign one_hot_31 = {one_hot_21[1:0] == 2'h0, one_hot_21[1] && !one_hot_21[0], one_hot_21[0]}; + assign one_hot_sel_36[0] = x_unflattened[0] & {16{one_hot_21[0]}} | y_unflattened[0] & {16{one_hot_21[1]}}; + assign one_hot_sel_36[1] = x_unflattened[1] & {16{one_hot_21[0]}} | y_unflattened[1] & {16{one_hot_21[1]}}; + assign one_hot_sel_36[2] = x_unflattened[2] & {16{one_hot_21[0]}} | y_unflattened[2] & {16{one_hot_21[1]}}; + assign one_hot_sel_36[3] = x_unflattened[3] & {16{one_hot_21[0]}} | y_unflattened[3] & {16{one_hot_21[1]}}; + assign eq_33 = one_hot_21 == one_hot_31[1:0]; + assign out = {one_hot_sel_36[3], one_hot_sel_36[2], one_hot_sel_36[1], one_hot_sel_36[0]}; + `ifdef ASSERT_ON + __xls_invariant_priority_sel_27_selector_one_hot_A: assert final ($isunknown(eq_33) || eq_33) else $fatal(0, "Selector one_hot.21 was expected to be one-hot, and is not."); + `endif // ASSERT_ON +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArrayOneHot.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArrayOneHot.vtxt new file mode 100644 index 0000000000..cf47f62465 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectArrayOneHot.vtxt @@ -0,0 +1,35 @@ +module main( + input wire p, + input wire [63:0] x, + input wire [63:0] y, + input wire [63:0] d, + output wire [63:0] out +); + wire [15:0] x_unflattened[0:3]; + assign x_unflattened[0] = x[15:0]; + assign x_unflattened[1] = x[31:16]; + assign x_unflattened[2] = x[47:32]; + assign x_unflattened[3] = x[63:48]; + wire [15:0] y_unflattened[0:3]; + assign y_unflattened[0] = y[15:0]; + assign y_unflattened[1] = y[31:16]; + assign y_unflattened[2] = y[47:32]; + assign y_unflattened[3] = y[63:48]; + wire [15:0] d_unflattened[0:3]; + assign d_unflattened[0] = d[15:0]; + assign d_unflattened[1] = d[31:16]; + assign d_unflattened[2] = d[47:32]; + assign d_unflattened[3] = d[63:48]; + wire [1:0] one_hot_21; + wire [2:0] one_hot_31; + wire [15:0] one_hot_sel_36[0:3]; + wire eq_33; + assign one_hot_21 = {!p, p}; + assign one_hot_31 = {one_hot_21[1:0] == 2'h0, one_hot_21[1] && !one_hot_21[0], one_hot_21[0]}; + assign one_hot_sel_36[0] = x_unflattened[0] & {16{one_hot_21[0]}} | y_unflattened[0] & {16{one_hot_21[1]}}; + assign one_hot_sel_36[1] = x_unflattened[1] & {16{one_hot_21[0]}} | y_unflattened[1] & {16{one_hot_21[1]}}; + assign one_hot_sel_36[2] = x_unflattened[2] & {16{one_hot_21[0]}} | y_unflattened[2] & {16{one_hot_21[1]}}; + assign one_hot_sel_36[3] = x_unflattened[3] & {16{one_hot_21[0]}} | y_unflattened[3] & {16{one_hot_21[1]}}; + assign eq_33 = one_hot_21 == one_hot_31[1:0]; + assign out = {one_hot_sel_36[3], one_hot_sel_36[2], one_hot_sel_36[1], one_hot_sel_36[0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMixedBitsAndNonBits.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMixedBitsAndNonBits.svtxt new file mode 100644 index 0000000000..a362491e0b --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMixedBitsAndNonBits.svtxt @@ -0,0 +1,30 @@ +module main( + input wire [1:0] p, + input wire [31:0] x, + input wire [31:0] y, + input wire [31:0] d, + output wire [63:0] out +); + function automatic [31:0] priority_sel_32b_2way (input reg [1:0] sel, input reg [31:0] case0, input reg [31:0] case1, input reg [31:0] default_value); + begin + unique casez (sel) + 2'b?1: begin + priority_sel_32b_2way = case0; + end + 2'b10: begin + priority_sel_32b_2way = case1; + end + 2'b00: begin + priority_sel_32b_2way = default_value; + end + default: begin + // Propagate X + priority_sel_32b_2way = 'X; + end + endcase + end + endfunction + wire [31:0] priority_sel_45; + assign priority_sel_45 = priority_sel_32b_2way(p, x, y, d); + assign out = {priority_sel_32b_2way(p, {x[31:16], x[15:0]}, {y[31:16], y[15:0]}, {d[31:16], d[15:0]}), priority_sel_45[31:16], priority_sel_45[15:0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMixedBitsAndNonBits.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMixedBitsAndNonBits.vtxt new file mode 100644 index 0000000000..16e551e356 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMixedBitsAndNonBits.vtxt @@ -0,0 +1,30 @@ +module main( + input wire [1:0] p, + input wire [31:0] x, + input wire [31:0] y, + input wire [31:0] d, + output wire [63:0] out +); + function automatic [31:0] priority_sel_32b_2way (input reg [1:0] sel, input reg [31:0] case0, input reg [31:0] case1, input reg [31:0] default_value); + begin + casez (sel) + 2'b?1: begin + priority_sel_32b_2way = case0; + end + 2'b10: begin + priority_sel_32b_2way = case1; + end + 2'b00: begin + priority_sel_32b_2way = default_value; + end + default: begin + // Propagate X + priority_sel_32b_2way = 32'dx; + end + endcase + end + endfunction + wire [31:0] priority_sel_45; + assign priority_sel_45 = priority_sel_32b_2way(p, x, y, d); + assign out = {priority_sel_32b_2way(p, {x[31:16], x[15:0]}, {y[31:16], y[15:0]}, {d[31:16], d[15:0]}), priority_sel_45[31:16], priority_sel_45[15:0]}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleAreMerged.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleAreMerged.svtxt new file mode 100644 index 0000000000..509ebd5936 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleAreMerged.svtxt @@ -0,0 +1,30 @@ +module main( + input wire [1:0] p, + input wire [15:0] x, + input wire [15:0] y, + input wire [15:0] d, + output wire [15:0] out +); + function automatic [15:0] priority_sel_16b_2way (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + unique casez (sel) + 2'b?1: begin + priority_sel_16b_2way = case0; + end + 2'b10: begin + priority_sel_16b_2way = case1; + end + 2'b00: begin + priority_sel_16b_2way = default_value; + end + default: begin + // Propagate X + priority_sel_16b_2way = 'X; + end + endcase + end + endfunction + wire [15:0] add_29; + assign add_29 = priority_sel_16b_2way(p, x, y, d) + priority_sel_16b_2way(p, y, x, d); + assign out = add_29; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleAreMerged.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleAreMerged.vtxt new file mode 100644 index 0000000000..dd1a85e1d2 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleAreMerged.vtxt @@ -0,0 +1,30 @@ +module main( + input wire [1:0] p, + input wire [15:0] x, + input wire [15:0] y, + input wire [15:0] d, + output wire [15:0] out +); + function automatic [15:0] priority_sel_16b_2way (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + casez (sel) + 2'b?1: begin + priority_sel_16b_2way = case0; + end + 2'b10: begin + priority_sel_16b_2way = case1; + end + 2'b00: begin + priority_sel_16b_2way = default_value; + end + default: begin + // Propagate X + priority_sel_16b_2way = 16'dx; + end + endcase + end + endfunction + wire [15:0] add_29; + assign add_29 = priority_sel_16b_2way(p, x, y, d) + priority_sel_16b_2way(p, y, x, d); + assign out = add_29; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleArraysWithSameElementType.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleArraysWithSameElementType.svtxt new file mode 100644 index 0000000000..e75f8cf4ca --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleArraysWithSameElementType.svtxt @@ -0,0 +1,82 @@ +module main( + input wire [1:0] p, + input wire [31:0] x_short, + input wire [63:0] x_long, + input wire [31:0] y_short, + input wire [63:0] y_long, + input wire [31:0] d_short, + input wire [63:0] d_long, + output wire [95:0] out +); + function automatic [15:0] priority_sel_32b_2way_element16 (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + unique casez (sel) + 2'b?1: begin + priority_sel_32b_2way_element16 = case0; + end + 2'b10: begin + priority_sel_32b_2way_element16 = case1; + end + 2'b00: begin + priority_sel_32b_2way_element16 = default_value; + end + default: begin + // Propagate X + priority_sel_32b_2way_element16 = 'X; + end + endcase + end + endfunction + function automatic [15:0] priority_sel_64b_2way_element16 (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + unique casez (sel) + 2'b?1: begin + priority_sel_64b_2way_element16 = case0; + end + 2'b10: begin + priority_sel_64b_2way_element16 = case1; + end + 2'b00: begin + priority_sel_64b_2way_element16 = default_value; + end + default: begin + // Propagate X + priority_sel_64b_2way_element16 = 'X; + end + endcase + end + endfunction + wire [15:0] x_short_unflattened[2]; + assign x_short_unflattened[0] = x_short[15:0]; + assign x_short_unflattened[1] = x_short[31:16]; + wire [15:0] x_long_unflattened[4]; + assign x_long_unflattened[0] = x_long[15:0]; + assign x_long_unflattened[1] = x_long[31:16]; + assign x_long_unflattened[2] = x_long[47:32]; + assign x_long_unflattened[3] = x_long[63:48]; + wire [15:0] y_short_unflattened[2]; + assign y_short_unflattened[0] = y_short[15:0]; + assign y_short_unflattened[1] = y_short[31:16]; + wire [15:0] y_long_unflattened[4]; + assign y_long_unflattened[0] = y_long[15:0]; + assign y_long_unflattened[1] = y_long[31:16]; + assign y_long_unflattened[2] = y_long[47:32]; + assign y_long_unflattened[3] = y_long[63:48]; + wire [15:0] d_short_unflattened[2]; + assign d_short_unflattened[0] = d_short[15:0]; + assign d_short_unflattened[1] = d_short[31:16]; + wire [15:0] d_long_unflattened[4]; + assign d_long_unflattened[0] = d_long[15:0]; + assign d_long_unflattened[1] = d_long[31:16]; + assign d_long_unflattened[2] = d_long[47:32]; + assign d_long_unflattened[3] = d_long[63:48]; + wire [15:0] priority_sel_37[2]; + wire [15:0] priority_sel_38[4]; + assign priority_sel_37[0] = priority_sel_32b_2way_element16(p, x_short_unflattened[0], y_short_unflattened[0], d_short_unflattened[0]); + assign priority_sel_37[1] = priority_sel_32b_2way_element16(p, x_short_unflattened[1], y_short_unflattened[1], d_short_unflattened[1]); + assign priority_sel_38[0] = priority_sel_64b_2way_element16(p, x_long_unflattened[0], y_long_unflattened[0], d_long_unflattened[0]); + assign priority_sel_38[1] = priority_sel_64b_2way_element16(p, x_long_unflattened[1], y_long_unflattened[1], d_long_unflattened[1]); + assign priority_sel_38[2] = priority_sel_64b_2way_element16(p, x_long_unflattened[2], y_long_unflattened[2], d_long_unflattened[2]); + assign priority_sel_38[3] = priority_sel_64b_2way_element16(p, x_long_unflattened[3], y_long_unflattened[3], d_long_unflattened[3]); + assign out = {{priority_sel_37[1], priority_sel_37[0]}, {priority_sel_38[3], priority_sel_38[2], priority_sel_38[1], priority_sel_38[0]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleArraysWithSameElementType.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleArraysWithSameElementType.vtxt new file mode 100644 index 0000000000..b08b31f75d --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectMultipleArraysWithSameElementType.vtxt @@ -0,0 +1,82 @@ +module main( + input wire [1:0] p, + input wire [31:0] x_short, + input wire [63:0] x_long, + input wire [31:0] y_short, + input wire [63:0] y_long, + input wire [31:0] d_short, + input wire [63:0] d_long, + output wire [95:0] out +); + function automatic [15:0] priority_sel_32b_2way_element16 (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + casez (sel) + 2'b?1: begin + priority_sel_32b_2way_element16 = case0; + end + 2'b10: begin + priority_sel_32b_2way_element16 = case1; + end + 2'b00: begin + priority_sel_32b_2way_element16 = default_value; + end + default: begin + // Propagate X + priority_sel_32b_2way_element16 = 16'dx; + end + endcase + end + endfunction + function automatic [15:0] priority_sel_64b_2way_element16 (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + casez (sel) + 2'b?1: begin + priority_sel_64b_2way_element16 = case0; + end + 2'b10: begin + priority_sel_64b_2way_element16 = case1; + end + 2'b00: begin + priority_sel_64b_2way_element16 = default_value; + end + default: begin + // Propagate X + priority_sel_64b_2way_element16 = 16'dx; + end + endcase + end + endfunction + wire [15:0] x_short_unflattened[0:1]; + assign x_short_unflattened[0] = x_short[15:0]; + assign x_short_unflattened[1] = x_short[31:16]; + wire [15:0] x_long_unflattened[0:3]; + assign x_long_unflattened[0] = x_long[15:0]; + assign x_long_unflattened[1] = x_long[31:16]; + assign x_long_unflattened[2] = x_long[47:32]; + assign x_long_unflattened[3] = x_long[63:48]; + wire [15:0] y_short_unflattened[0:1]; + assign y_short_unflattened[0] = y_short[15:0]; + assign y_short_unflattened[1] = y_short[31:16]; + wire [15:0] y_long_unflattened[0:3]; + assign y_long_unflattened[0] = y_long[15:0]; + assign y_long_unflattened[1] = y_long[31:16]; + assign y_long_unflattened[2] = y_long[47:32]; + assign y_long_unflattened[3] = y_long[63:48]; + wire [15:0] d_short_unflattened[0:1]; + assign d_short_unflattened[0] = d_short[15:0]; + assign d_short_unflattened[1] = d_short[31:16]; + wire [15:0] d_long_unflattened[0:3]; + assign d_long_unflattened[0] = d_long[15:0]; + assign d_long_unflattened[1] = d_long[31:16]; + assign d_long_unflattened[2] = d_long[47:32]; + assign d_long_unflattened[3] = d_long[63:48]; + wire [15:0] priority_sel_37[0:1]; + wire [15:0] priority_sel_38[0:3]; + assign priority_sel_37[0] = priority_sel_32b_2way_element16(p, x_short_unflattened[0], y_short_unflattened[0], d_short_unflattened[0]); + assign priority_sel_37[1] = priority_sel_32b_2way_element16(p, x_short_unflattened[1], y_short_unflattened[1], d_short_unflattened[1]); + assign priority_sel_38[0] = priority_sel_64b_2way_element16(p, x_long_unflattened[0], y_long_unflattened[0], d_long_unflattened[0]); + assign priority_sel_38[1] = priority_sel_64b_2way_element16(p, x_long_unflattened[1], y_long_unflattened[1], d_long_unflattened[1]); + assign priority_sel_38[2] = priority_sel_64b_2way_element16(p, x_long_unflattened[2], y_long_unflattened[2], d_long_unflattened[2]); + assign priority_sel_38[3] = priority_sel_64b_2way_element16(p, x_long_unflattened[3], y_long_unflattened[3], d_long_unflattened[3]); + assign out = {{priority_sel_37[1], priority_sel_37[0]}, {priority_sel_38[3], priority_sel_38[2], priority_sel_38[1], priority_sel_38[0]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectNonBits.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectNonBits.svtxt new file mode 100644 index 0000000000..0157334065 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectNonBits.svtxt @@ -0,0 +1,29 @@ +module main( + input wire [1:0] p, + input wire [31:0] x, + input wire [31:0] y, + input wire [31:0] d, + output wire [31:0] out +); + function automatic [31:0] priority_sel_32b_2way (input reg [1:0] sel, input reg [31:0] case0, input reg [31:0] case1, input reg [31:0] default_value); + begin + unique casez (sel) + 2'b?1: begin + priority_sel_32b_2way = case0; + end + 2'b10: begin + priority_sel_32b_2way = case1; + end + 2'b00: begin + priority_sel_32b_2way = default_value; + end + default: begin + // Propagate X + priority_sel_32b_2way = 'X; + end + endcase + end + endfunction + + assign out = priority_sel_32b_2way(p, x, y, d); +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectNonBits.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectNonBits.vtxt new file mode 100644 index 0000000000..b9a1b0dec7 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectNonBits.vtxt @@ -0,0 +1,29 @@ +module main( + input wire [1:0] p, + input wire [31:0] x, + input wire [31:0] y, + input wire [31:0] d, + output wire [31:0] out +); + function automatic [31:0] priority_sel_32b_2way (input reg [1:0] sel, input reg [31:0] case0, input reg [31:0] case1, input reg [31:0] default_value); + begin + casez (sel) + 2'b?1: begin + priority_sel_32b_2way = case0; + end + 2'b10: begin + priority_sel_32b_2way = case1; + end + 2'b00: begin + priority_sel_32b_2way = default_value; + end + default: begin + // Propagate X + priority_sel_32b_2way = 32'dx; + end + endcase + end + endfunction + + assign out = priority_sel_32b_2way(p, x, y, d); +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectOneHot.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectOneHot.svtxt new file mode 100644 index 0000000000..6f38fe8345 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectOneHot.svtxt @@ -0,0 +1,18 @@ +module main( + input wire p, + input wire [15:0] x, + input wire [15:0] y, + input wire [15:0] d, + output wire [15:0] out +); + wire [1:0] one_hot_21; + wire [2:0] one_hot_31; + wire eq_33; + assign one_hot_21 = {!p, p}; + assign one_hot_31 = {one_hot_21[1:0] == 2'h0, one_hot_21[1] && !one_hot_21[0], one_hot_21[0]}; + assign eq_33 = one_hot_21 == one_hot_31[1:0]; + assign out = x & {16{one_hot_21[0]}} | y & {16{one_hot_21[1]}}; + `ifdef ASSERT_ON + __xls_invariant_priority_sel_27_selector_one_hot_A: assert final ($isunknown(eq_33) || eq_33) else $fatal(0, "Selector one_hot.21 was expected to be one-hot, and is not."); + `endif // ASSERT_ON +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectOneHot.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectOneHot.vtxt new file mode 100644 index 0000000000..ea27e3b277 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectOneHot.vtxt @@ -0,0 +1,15 @@ +module main( + input wire p, + input wire [15:0] x, + input wire [15:0] y, + input wire [15:0] d, + output wire [15:0] out +); + wire [1:0] one_hot_21; + wire [2:0] one_hot_31; + wire eq_33; + assign one_hot_21 = {!p, p}; + assign one_hot_31 = {one_hot_21[1:0] == 2'h0, one_hot_21[1] && !one_hot_21[0], one_hot_21[0]}; + assign eq_33 = one_hot_21 == one_hot_31[1:0]; + assign out = x & {16{one_hot_21[0]}} | y & {16{one_hot_21[1]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectWithAndWithoutDefault.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectWithAndWithoutDefault.svtxt new file mode 100644 index 0000000000..8a3db1a083 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectWithAndWithoutDefault.svtxt @@ -0,0 +1,29 @@ +module main( + input wire [1:0] p, + input wire [15:0] x, + input wire [15:0] y, + input wire [15:0] d, + output wire [31:0] out +); + function automatic [15:0] priority_sel_16b_2way (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + unique casez (sel) + 2'b?1: begin + priority_sel_16b_2way = case0; + end + 2'b10: begin + priority_sel_16b_2way = case1; + end + 2'b00: begin + priority_sel_16b_2way = default_value; + end + default: begin + // Propagate X + priority_sel_16b_2way = 'X; + end + endcase + end + endfunction + + assign out = {priority_sel_16b_2way(p | 2'h1, x, y, d), priority_sel_16b_2way(p, x, y, d)}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectWithAndWithoutDefault.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectWithAndWithoutDefault.vtxt new file mode 100644 index 0000000000..14f6f9b978 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_PrioritySelectWithAndWithoutDefault.vtxt @@ -0,0 +1,29 @@ +module main( + input wire [1:0] p, + input wire [15:0] x, + input wire [15:0] y, + input wire [15:0] d, + output wire [31:0] out +); + function automatic [15:0] priority_sel_16b_2way (input reg [1:0] sel, input reg [15:0] case0, input reg [15:0] case1, input reg [15:0] default_value); + begin + casez (sel) + 2'b?1: begin + priority_sel_16b_2way = case0; + end + 2'b10: begin + priority_sel_16b_2way = case1; + end + 2'b00: begin + priority_sel_16b_2way = default_value; + end + default: begin + // Propagate X + priority_sel_16b_2way = 16'dx; + end + endcase + end + endfunction + + assign out = {priority_sel_16b_2way(p | 2'h1, x, y, d), priority_sel_16b_2way(p, x, y, d)}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RandomExpression.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RandomExpression.svtxt new file mode 100644 index 0000000000..3a257bedff --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RandomExpression.svtxt @@ -0,0 +1,23 @@ +module RandomExpression( + input wire [7:0] a, + input wire [7:0] b, + input wire [7:0] c, + output wire [7:0] out +); + // lint_off MULTIPLY + function automatic [7:0] umul8b_8b_x_8b (input reg [7:0] lhs, input reg [7:0] rhs); + begin + umul8b_8b_x_8b = lhs * rhs; + end + endfunction + // lint_on MULTIPLY + wire [7:0] diff; + wire [7:0] umul_20; + wire [7:0] umul_21; + wire [7:0] the_output; + assign diff = a - b; + assign umul_20 = umul8b_8b_x_8b(diff, diff); + assign umul_21 = umul8b_8b_x_8b(c, diff); + assign the_output = umul_20 + umul_21; + assign out = the_output; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RandomExpression.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RandomExpression.vtxt new file mode 100644 index 0000000000..3a257bedff --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RandomExpression.vtxt @@ -0,0 +1,23 @@ +module RandomExpression( + input wire [7:0] a, + input wire [7:0] b, + input wire [7:0] c, + output wire [7:0] out +); + // lint_off MULTIPLY + function automatic [7:0] umul8b_8b_x_8b (input reg [7:0] lhs, input reg [7:0] rhs); + begin + umul8b_8b_x_8b = lhs * rhs; + end + endfunction + // lint_on MULTIPLY + wire [7:0] diff; + wire [7:0] umul_20; + wire [7:0] umul_21; + wire [7:0] the_output; + assign diff = a - b; + assign umul_20 = umul8b_8b_x_8b(diff, diff); + assign umul_21 = umul8b_8b_x_8b(c, diff); + assign the_output = umul_20 + umul_21; + assign out = the_output; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RrotToText.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RrotToText.svtxt new file mode 100644 index 0000000000..45cde28f60 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RrotToText.svtxt @@ -0,0 +1,9 @@ +module rrot( + input wire [31:0] x, + input wire [31:0] y, + output wire [31:0] out +); + wire [31:0] sub_18; + assign sub_18 = 32'h0000_0020 - y; + assign out = (y >= 32'h0000_0020 ? 32'h0000_0000 : x >> y) | (sub_18 >= 32'h0000_0020 ? 32'h0000_0000 : x << sub_18); +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RrotToText.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RrotToText.vtxt new file mode 100644 index 0000000000..45cde28f60 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_RrotToText.vtxt @@ -0,0 +1,9 @@ +module rrot( + input wire [31:0] x, + input wire [31:0] y, + output wire [31:0] out +); + wire [31:0] sub_18; + assign sub_18 = 32'h0000_0020 - y; + assign out = (y >= 32'h0000_0020 ? 32'h0000_0000 : x >> y) | (sub_18 >= 32'h0000_0020 ? 32'h0000_0000 : x << sub_18); +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_SDiv.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_SDiv.svtxt new file mode 100644 index 0000000000..2e3ee86cb5 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_SDiv.svtxt @@ -0,0 +1,14 @@ +module SDiv( + input wire [31:0] x, + input wire [31:0] y, + output wire [31:0] out +); + function automatic [31:0] sdiv_32b (input reg [31:0] lhs, input reg [31:0] rhs); + begin + sdiv_32b = rhs == 32'h0000_0000 ? (lhs[31] ? 32'h8000_0000 : 32'h7fff_ffff) : (lhs == 32'h8000_0000 && rhs == 32'hffff_ffff ? 32'h8000_0000 : $unsigned($signed(lhs) / $signed(rhs))); + end + endfunction + wire [31:0] sdiv_15; + assign sdiv_15 = sdiv_32b(x, y); + assign out = sdiv_15; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_SDiv.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_SDiv.vtxt new file mode 100644 index 0000000000..2e3ee86cb5 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_SDiv.vtxt @@ -0,0 +1,14 @@ +module SDiv( + input wire [31:0] x, + input wire [31:0] y, + output wire [31:0] out +); + function automatic [31:0] sdiv_32b (input reg [31:0] lhs, input reg [31:0] rhs); + begin + sdiv_32b = rhs == 32'h0000_0000 ? (lhs[31] ? 32'h8000_0000 : 32'h7fff_ffff) : (lhs == 32'h8000_0000 && rhs == 32'hffff_ffff ? 32'h8000_0000 : $unsigned($signed(lhs) / $signed(rhs))); + end + endfunction + wire [31:0] sdiv_15; + assign sdiv_15 = sdiv_32b(x, y); + assign out = sdiv_15; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TupleLiterals.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TupleLiterals.svtxt new file mode 100644 index 0000000000..b552e48a1d --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TupleLiterals.svtxt @@ -0,0 +1,13 @@ +module main( + input wire [122:0] x, + output wire [122:0] out +); + wire [368:0] literal_19 = {123'h000_0000_0000_0000_0000_0000_0001_0000, 123'h000_0000_0000_0000_0000_0000_0000_2000, 123'h000_0000_0000_0000_0000_0000_0000_0300}; + wire [122:0] sum1; + wire [122:0] sum2; + wire [122:0] total; + assign sum1 = literal_19[368:246] + literal_19[245:123]; + assign sum2 = literal_19[122:0] + x; + assign total = sum1 + sum2; + assign out = total; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TupleLiterals.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TupleLiterals.vtxt new file mode 100644 index 0000000000..b552e48a1d --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TupleLiterals.vtxt @@ -0,0 +1,13 @@ +module main( + input wire [122:0] x, + output wire [122:0] out +); + wire [368:0] literal_19 = {123'h000_0000_0000_0000_0000_0000_0001_0000, 123'h000_0000_0000_0000_0000_0000_0000_2000, 123'h000_0000_0000_0000_0000_0000_0000_0300}; + wire [122:0] sum1; + wire [122:0] sum2; + wire [122:0] total; + assign sum1 = literal_19[368:246] + literal_19[245:123]; + assign sum2 = literal_19[122:0] + x; + assign total = sum1 + sum2; + assign out = total; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArrayNe.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArrayNe.svtxt new file mode 100644 index 0000000000..4acf48d1b4 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArrayNe.svtxt @@ -0,0 +1,22 @@ +module TwoDArrayNe( + input wire [5:0] x, + input wire [5:0] y, + output wire out +); + wire x_unflattened[2][3]; + assign x_unflattened[0][0] = x[0:0]; + assign x_unflattened[0][1] = x[1:1]; + assign x_unflattened[0][2] = x[2:2]; + assign x_unflattened[1][0] = x[3:3]; + assign x_unflattened[1][1] = x[4:4]; + assign x_unflattened[1][2] = x[5:5]; + wire y_unflattened[2][3]; + assign y_unflattened[0][0] = y[0:0]; + assign y_unflattened[0][1] = y[1:1]; + assign y_unflattened[0][2] = y[2:2]; + assign y_unflattened[1][0] = y[3:3]; + assign y_unflattened[1][1] = y[4:4]; + assign y_unflattened[1][2] = y[5:5]; + + assign out = x_unflattened[0][0] != y_unflattened[0][0] || x_unflattened[0][1] != y_unflattened[0][1] || x_unflattened[0][2] != y_unflattened[0][2] || x_unflattened[1][0] != y_unflattened[1][0] || x_unflattened[1][1] != y_unflattened[1][1] || x_unflattened[1][2] != y_unflattened[1][2]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArrayNe.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArrayNe.vtxt new file mode 100644 index 0000000000..50a038be22 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArrayNe.vtxt @@ -0,0 +1,22 @@ +module TwoDArrayNe( + input wire [5:0] x, + input wire [5:0] y, + output wire out +); + wire x_unflattened[0:1][0:2]; + assign x_unflattened[0][0] = x[0:0]; + assign x_unflattened[0][1] = x[1:1]; + assign x_unflattened[0][2] = x[2:2]; + assign x_unflattened[1][0] = x[3:3]; + assign x_unflattened[1][1] = x[4:4]; + assign x_unflattened[1][2] = x[5:5]; + wire y_unflattened[0:1][0:2]; + assign y_unflattened[0][0] = y[0:0]; + assign y_unflattened[0][1] = y[1:1]; + assign y_unflattened[0][2] = y[2:2]; + assign y_unflattened[1][0] = y[3:3]; + assign y_unflattened[1][1] = y[4:4]; + assign y_unflattened[1][2] = y[5:5]; + + assign out = x_unflattened[0][0] != y_unflattened[0][0] || x_unflattened[0][1] != y_unflattened[0][1] || x_unflattened[0][2] != y_unflattened[0][2] || x_unflattened[1][0] != y_unflattened[1][0] || x_unflattened[1][1] != y_unflattened[1][1] || x_unflattened[1][2] != y_unflattened[1][2]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArraySlice.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArraySlice.svtxt new file mode 100644 index 0000000000..f73be17edb --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArraySlice.svtxt @@ -0,0 +1,17 @@ +module TwoDArraySlice( + input wire [191:0] a, + input wire [15:0] start, + output wire [127:0] out +); + wire [31:0] a_unflattened[3][2]; + assign a_unflattened[0][0] = a[31:0]; + assign a_unflattened[0][1] = a[63:32]; + assign a_unflattened[1][0] = a[95:64]; + assign a_unflattened[1][1] = a[127:96]; + assign a_unflattened[2][0] = a[159:128]; + assign a_unflattened[2][1] = a[191:160]; + wire [31:0] array_slice_15[2][2]; + assign array_slice_15[0] = a_unflattened[start > 16'h0002 ? 16'h0002 : start + 16'h0000]; + assign array_slice_15[1] = a_unflattened[start > 16'h0001 ? 16'h0002 : start + 16'h0001]; + assign out = {{array_slice_15[1][1], array_slice_15[1][0]}, {array_slice_15[0][1], array_slice_15[0][0]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArraySlice.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArraySlice.vtxt new file mode 100644 index 0000000000..b5fd6f50b4 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_TwoDArraySlice.vtxt @@ -0,0 +1,19 @@ +module TwoDArraySlice( + input wire [191:0] a, + input wire [15:0] start, + output wire [127:0] out +); + wire [31:0] a_unflattened[0:2][0:1]; + assign a_unflattened[0][0] = a[31:0]; + assign a_unflattened[0][1] = a[63:32]; + assign a_unflattened[1][0] = a[95:64]; + assign a_unflattened[1][1] = a[127:96]; + assign a_unflattened[2][0] = a[159:128]; + assign a_unflattened[2][1] = a[191:160]; + wire [31:0] array_slice_15[0:1][0:1]; + assign array_slice_15[0][0] = a_unflattened[start > 16'h0002 ? 16'h0002 : start + 16'h0000][0]; + assign array_slice_15[0][1] = a_unflattened[start > 16'h0002 ? 16'h0002 : start + 16'h0000][1]; + assign array_slice_15[1][0] = a_unflattened[start > 16'h0001 ? 16'h0002 : start + 16'h0001][0]; + assign array_slice_15[1][1] = a_unflattened[start > 16'h0001 ? 16'h0002 : start + 16'h0001][1]; + assign out = {{array_slice_15[1][1], array_slice_15[1][0]}, {array_slice_15[0][1], array_slice_15[0][0]}}; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UDiv.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UDiv.svtxt new file mode 100644 index 0000000000..57a7079ee0 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UDiv.svtxt @@ -0,0 +1,14 @@ +module UDiv( + input wire [31:0] x, + input wire [31:0] y, + output wire [31:0] out +); + function automatic [31:0] udiv_32b (input reg [31:0] lhs, input reg [31:0] rhs); + begin + udiv_32b = rhs == 32'h0000_0000 ? 32'hffff_ffff : lhs / rhs; + end + endfunction + wire [31:0] udiv_15; + assign udiv_15 = udiv_32b(x, y); + assign out = udiv_15; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UDiv.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UDiv.vtxt new file mode 100644 index 0000000000..57a7079ee0 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UDiv.vtxt @@ -0,0 +1,14 @@ +module UDiv( + input wire [31:0] x, + input wire [31:0] y, + output wire [31:0] out +); + function automatic [31:0] udiv_32b (input reg [31:0] lhs, input reg [31:0] rhs); + begin + udiv_32b = rhs == 32'h0000_0000 ? 32'hffff_ffff : lhs / rhs; + end + endfunction + wire [31:0] udiv_15; + assign udiv_15 = udiv_32b(x, y); + assign out = udiv_15; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UncommonParameterTypes.svtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UncommonParameterTypes.svtxt new file mode 100644 index 0000000000..a562634884 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UncommonParameterTypes.svtxt @@ -0,0 +1,20 @@ +module main( + input wire [31:0] a, + input wire [31:0] b, + input wire [95:0] c, + input wire [63:0] d, + input wire [63:0] e, + input wire g, + output wire [31:0] out +); + wire [31:0] c_unflattened[3]; + assign c_unflattened[0] = c[31:0]; + assign c_unflattened[1] = c[63:32]; + assign c_unflattened[2] = c[95:64]; + wire [63:0] d_unflattened[1]; + assign d_unflattened[0] = d[63:0]; + wire [31:0] tuple_index_35[2]; + assign tuple_index_35[0] = e[31:0]; + assign tuple_index_35[1] = e[63:32]; + assign out = a | b[31:0] | c_unflattened[g] | d_unflattened[1'h0][31:0] | tuple_index_35[g]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UncommonParameterTypes.vtxt b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UncommonParameterTypes.vtxt new file mode 100644 index 0000000000..a597a4b0e1 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_combinational_function_test_UncommonParameterTypes.vtxt @@ -0,0 +1,20 @@ +module main( + input wire [31:0] a, + input wire [31:0] b, + input wire [95:0] c, + input wire [63:0] d, + input wire [63:0] e, + input wire g, + output wire [31:0] out +); + wire [31:0] c_unflattened[0:2]; + assign c_unflattened[0] = c[31:0]; + assign c_unflattened[1] = c[63:32]; + assign c_unflattened[2] = c[95:64]; + wire [63:0] d_unflattened[0:0]; + assign d_unflattened[0] = d[63:0]; + wire [31:0] tuple_index_35[0:1]; + assign tuple_index_35[0] = e[31:0]; + assign tuple_index_35[1] = e[63:32]; + assign out = a | b[31:0] | c_unflattened[g] | d_unflattened[1'h0][31:0] | tuple_index_35[g]; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_proc_test_CombinationalSingleProcWithProcScopedChannels.svtxt b/xls/codegen_v_1_5/testdata/codegen_proc_test_CombinationalSingleProcWithProcScopedChannels.svtxt new file mode 100644 index 0000000000..39382ecbf2 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_proc_test_CombinationalSingleProcWithProcScopedChannels.svtxt @@ -0,0 +1,16 @@ +module myleaf( + input wire [31:0] in, + input wire in_vld, + input wire out_rdy, + output wire in_rdy, + output wire [31:0] out, + output wire out_vld +); + wire stage_outputs_valid_0; + wire [31:0] add_39; + assign stage_outputs_valid_0 = in_vld & out_rdy; + assign add_39 = in + 32'h0000_0001; + assign in_rdy = stage_outputs_valid_0; + assign out = add_39; + assign out_vld = in_vld; +endmodule diff --git a/xls/codegen_v_1_5/testdata/codegen_proc_test_CombinationalSingleProcWithProcScopedChannels.vtxt b/xls/codegen_v_1_5/testdata/codegen_proc_test_CombinationalSingleProcWithProcScopedChannels.vtxt new file mode 100644 index 0000000000..39382ecbf2 --- /dev/null +++ b/xls/codegen_v_1_5/testdata/codegen_proc_test_CombinationalSingleProcWithProcScopedChannels.vtxt @@ -0,0 +1,16 @@ +module myleaf( + input wire [31:0] in, + input wire in_vld, + input wire out_rdy, + output wire in_rdy, + output wire [31:0] out, + output wire out_vld +); + wire stage_outputs_valid_0; + wire [31:0] add_39; + assign stage_outputs_valid_0 = in_vld & out_rdy; + assign add_39 = in + 32'h0000_0001; + assign in_rdy = stage_outputs_valid_0; + assign out = add_39; + assign out_vld = in_vld; +endmodule