diff --git a/jlm/hls/backend/rhls2firrtl/RhlsToFirrtlConverterTests.cpp b/jlm/hls/backend/rhls2firrtl/RhlsToFirrtlConverterTests.cpp index d2aeb52ee..478c0c22c 100644 --- a/jlm/hls/backend/rhls2firrtl/RhlsToFirrtlConverterTests.cpp +++ b/jlm/hls/backend/rhls2firrtl/RhlsToFirrtlConverterTests.cpp @@ -45,9 +45,9 @@ class TestableRhlsToFirrtlConverter : public RhlsToFirrtlConverter }; } -/* ================================================================== */ -/* Base fixture: module + assert helpers */ -/* ================================================================== */ +// ================================================================== +// Base fixture: module + assert helpers +// ================================================================== class FirrtlTestBase : public ::testing::Test { @@ -84,9 +84,9 @@ class FirrtlTestBase : public ::testing::Test } }; -/* ================================================================== */ -/* Fixture: default lambda with 2x32-bit inputs, 32-bit output */ -/* ================================================================== */ +// ================================================================== +// Fixture: default lambda with 2x32-bit inputs, 32-bit output +// ================================================================== class FirrtlConversionTest : public FirrtlTestBase { @@ -120,9 +120,9 @@ class FirrtlConversionTest : public FirrtlTestBase } }; -/* ================================================================== */ -/* IsIdentityMapping tests */ -/* ================================================================== */ +// ================================================================== +// IsIdentityMapping tests +// ================================================================== class IdentityMappingTest : public ::testing::Test { @@ -170,9 +170,9 @@ TEST_F(IdentityMappingTest, MixedMappingOneViolates) EXPECT_FALSE(Converter_.TestIsIdentityMapping(*matchOp)); } -/* ================================================================== */ -/* MatchOperation semantic tests */ -/* ================================================================== */ +// ================================================================== +// MatchOperation semantic tests +// ================================================================== TEST_F(IdentityMappingTest, MappedAlternative) { @@ -239,9 +239,9 @@ TEST_F(IdentityMappingTest, Inequality) EXPECT_NE(*matchOp1, *matchOp2); } -/* ================================================================== */ -/* Binary operation FIRRTL conversion tests */ -/* ================================================================== */ +// ================================================================== +// Binary operation FIRRTL conversion tests +// ================================================================== TEST_F(FirrtlConversionTest, AddOperation) { @@ -303,9 +303,9 @@ TEST_F(FirrtlConversionTest, XorOperation) ExpectFirrtlOp(); } -/* ================================================================== */ -/* Shift operation FIRRTL conversion tests */ -/* ================================================================== */ +// ================================================================== +// Shift operation FIRRTL conversion tests +// ================================================================== TEST_F(FirrtlConversionTest, ShlOperation) { @@ -327,9 +327,9 @@ TEST_F(FirrtlConversionTest, LShrOperation) ExpectFirrtlOp(); } -/* ================================================================== */ -/* Signed arithmetic operation FIRRTL conversion tests */ -/* ================================================================== */ +// ================================================================== +// Signed arithmetic operation FIRRTL conversion tests +// ================================================================== TEST_F(FirrtlConversionTest, SDivOperation) { @@ -373,9 +373,9 @@ TEST_F(FirrtlConversionTest, SRemOperation) EXPECT_TRUE(AssertFirrtlOpExists(circuit)); } -/* ================================================================== */ -/* Comparison operation FIRRTL conversion tests */ -/* ================================================================== */ +// ================================================================== +// Comparison operation FIRRTL conversion tests +// ================================================================== TEST_F(FirrtlConversionTest, ComparisonEqualOperation) { @@ -509,9 +509,9 @@ TEST_F(FirrtlConversionTest, ComparisonUgeOperation) ExpectFirrtlOp(); } -/* ================================================================== */ -/* Unary operation FIRRTL conversion tests */ -/* ================================================================== */ +// ================================================================== +// Unary operation FIRRTL conversion tests +// ================================================================== TEST_F(FirrtlConversionTest, UnaryTruncOperation) { @@ -539,9 +539,9 @@ TEST_F(FirrtlConversionTest, UnarySExtOperation) EXPECT_TRUE(AssertFirrtlOpExists(circuit)); } -/* ================================================================== */ -/* Constant operation FIRRTL conversion tests */ -/* ================================================================== */ +// ================================================================== +// Constant operation FIRRTL conversion tests +// ================================================================== TEST_F(FirrtlConversionTest, ConstantIntegerOperation) { @@ -565,9 +565,9 @@ TEST_F(FirrtlConversionTest, ConstantUndefValueOperation) EXPECT_TRUE(AssertFirrtlOpExists(circuit)); } -/* ================================================================== */ -/* Pass-through operation FIRRTL conversion tests */ -/* ================================================================== */ +// ================================================================== +// Pass-through operation FIRRTL conversion tests +// ================================================================== TEST_F(FirrtlConversionTest, PassThroughBitCastOperation) { @@ -595,9 +595,9 @@ TEST_F(FirrtlConversionTest, PassThroughZExtOperation) EXPECT_TRUE(circuit); } -/* ================================================================== */ -/* IntegerToPointerOperation FIRRTL conversion test */ -/* ================================================================== */ +// ================================================================== +// IntegerToPointerOperation FIRRTL conversion test +// ================================================================== TEST_F(FirrtlConversionTest, IntegerToPointerOperation) { @@ -613,9 +613,9 @@ TEST_F(FirrtlConversionTest, IntegerToPointerOperation) EXPECT_TRUE(circuit); } -/* ================================================================== */ -/* MatchOperation non-identity FIRRTL conversion tests */ -/* ================================================================== */ +// ================================================================== +// MatchOperation non-identity FIRRTL conversion tests +// ================================================================== class FirrtlMatchConversionTest : public FirrtlTestBase { @@ -703,9 +703,9 @@ TEST_F(FirrtlMatchConversionTest, MatchOperationIdentityEqualSizes) EXPECT_FALSE(AssertFirrtlOpExists(circuit)); } -/* ================================================================== */ -/* ControlConstantOperation FIRRTL conversion test */ -/* ================================================================== */ +// ================================================================== +// ControlConstantOperation FIRRTL conversion test +// ================================================================== class FirrtlControlConstantTest : public FirrtlTestBase { @@ -731,9 +731,9 @@ TEST_F(FirrtlControlConstantTest, ControlConstantOperation) EXPECT_TRUE(AssertFirrtlOpExists(circuit)); } -/* ================================================================== */ -/* Memory state pass-through FIRRTL conversion tests */ -/* ================================================================== */ +// ================================================================== +// Memory state pass-through FIRRTL conversion tests +// ================================================================== TEST_F(FirrtlTestBase, MemoryStateMergeOperation) { @@ -777,9 +777,9 @@ TEST_F(FirrtlTestBase, LambdaExitMemoryStateMergeOperation) EXPECT_TRUE(circuit); } -/* ================================================================== */ -/* Error handling tests */ -/* ================================================================== */ +// ================================================================== +// Error handling tests +// ================================================================== TEST_F(FirrtlTestBase, UnimplementedSimpleNodeThrows) { @@ -807,9 +807,9 @@ TEST_F(FirrtlTestBase, UnimplementedSimpleNodeThrows) EXPECT_TRUE(exceptionThrown); } -/* ================================================================== */ -/* MuxOperation FIRRTL conversion tests */ -/* ================================================================== */ +// ================================================================== +// MuxOperation FIRRTL conversion tests +// ================================================================== TEST_F(FirrtlTestBase, MuxOperationTwoAlternatives) { @@ -854,9 +854,9 @@ TEST_F(FirrtlTestBase, MuxOperationThreeAlternatives) EXPECT_TRUE(AssertFirrtlOpExists(circuit)); } -/* ================================================================== */ -/* GetElementPtrOperation FIRRTL conversion test */ -/* ================================================================== */ +// ================================================================== +// GetElementPtrOperation FIRRTL conversion test +// ================================================================== TEST_F(FirrtlTestBase, GetElementPtrOperationArrayType) { @@ -880,3 +880,319 @@ TEST_F(FirrtlTestBase, GetElementPtrOperationArrayType) EXPECT_TRUE(AssertFirrtlOpExists(circuit)); EXPECT_TRUE(AssertFirrtlOpExists(circuit)); } + +// ================================================================== +// HLS SinkOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, SinkOperation) +{ + auto bitType = BitType::Create(32); + auto functionType = FunctionType::Create({ bitType }, {}); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & arg0 = *Lambda_->GetFunctionArguments()[0]; + auto sinkOutputs = SinkOperation::create(arg0); + Lambda_->finalize({}); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS TriggerOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, TriggerOperation) +{ + auto triggerType = TriggerType::Create(); + auto bitType = BitType::Create(32); + auto functionType = FunctionType::Create({ triggerType, bitType }, { bitType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & tg = *Lambda_->GetFunctionArguments()[0]; + auto & value = *Lambda_->GetFunctionArguments()[1]; + auto triggerOutputs = TriggerOperation::create(tg, value); + Lambda_->finalize({ triggerOutputs[0] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS BranchOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, BranchOperation) +{ + auto bitType = BitType::Create(32); + auto controlType = ControlType::Create(2); + auto functionType = FunctionType::Create({ controlType, bitType }, { bitType, bitType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & predicate = *Lambda_->GetFunctionArguments()[0]; + auto & value = *Lambda_->GetFunctionArguments()[1]; + auto branchOutputs = ::jlm::hls::BranchOperation::create(predicate, value); + Lambda_->finalize({ branchOutputs[0], branchOutputs[1] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS MuxOperation (NDMux) FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, NDMuxOperation) +{ + auto controlType = ControlType::Create(3); + auto bitType = BitType::Create(32); + auto functionType = FunctionType::Create({ controlType, bitType, bitType, bitType }, { bitType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & tag = *Lambda_->GetFunctionArguments()[0]; + auto & val0 = *Lambda_->GetFunctionArguments()[1]; + auto & val1 = *Lambda_->GetFunctionArguments()[2]; + auto & val2 = *Lambda_->GetFunctionArguments()[3]; + auto muxOutputs = MuxOperation::create(tag, { &val0, &val1, &val2 }, false, false); + Lambda_->finalize({ muxOutputs[0] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS ForkOperation FIRRTL conversion tests +// ================================================================== + +TEST_F(FirrtlTestBase, ForkOperation) +{ + auto bitType = BitType::Create(32); + auto functionType = FunctionType::Create({ bitType }, { bitType, bitType, bitType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & arg0 = *Lambda_->GetFunctionArguments()[0]; + auto forkOutputs = ForkOperation::create(3, arg0, false); + Lambda_->finalize({ forkOutputs[0], forkOutputs[1], forkOutputs[2] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS StateGateOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, StateGateOperation) +{ + auto bitType = BitType::Create(32); + auto memStateType = MemoryStateType::Create(); + auto functionType = FunctionType::Create({ bitType, memStateType }, { bitType, memStateType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & arg0 = *Lambda_->GetFunctionArguments()[0]; + auto & state = *Lambda_->GetFunctionArguments()[1]; + auto stateGateOutputs = StateGateOperation::create(arg0, { &state }); + Lambda_->finalize({ stateGateOutputs[0], stateGateOutputs[1] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS PredicateBufferOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, PredicateBufferOperation) +{ + auto controlType = ControlType::Create(2); + auto functionType = FunctionType::Create({ controlType }, { controlType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & arg0 = *Lambda_->GetFunctionArguments()[0]; + auto predBufOutputs = PredicateBufferOperation::create(arg0); + Lambda_->finalize({ predBufOutputs[0] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS AddressQueueOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, AddressQueueOperation) +{ + auto ptrType = PointerType::Create(); + auto memStateType = MemoryStateType::Create(); + auto functionType = FunctionType::Create({ ptrType, ptrType, memStateType }, { ptrType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & check = *Lambda_->GetFunctionArguments()[0]; + auto & enq = *Lambda_->GetFunctionArguments()[1]; + auto & deq = *Lambda_->GetFunctionArguments()[2]; + auto addrQueueOutput = AddressQueueOperation::create(check, enq, deq, false, 4); + Lambda_->finalize({ addrQueueOutput }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS LoadOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, JlmHlsLoadOperation) +{ + auto ptrType = PointerType::Create(); + auto bitType = BitType::Create(32); + auto memStateType = MemoryStateType::Create(); + auto functionType = + FunctionType::Create({ ptrType, memStateType, bitType }, { bitType, memStateType, ptrType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & addr = *Lambda_->GetFunctionArguments()[0]; + auto & state = *Lambda_->GetFunctionArguments()[1]; + auto & loadResult = *Lambda_->GetFunctionArguments()[2]; + auto loadOutputs = ::jlm::hls::LoadOperation::create(addr, { &state }, loadResult); + Lambda_->finalize({ loadOutputs[0], loadOutputs[1], loadOutputs[2] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS StoreOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, HlsStoreOperation) +{ + auto ptrType = PointerType::Create(); + auto bitType = BitType::Create(32); + auto memStateType = MemoryStateType::Create(); + auto functionType = + FunctionType::Create({ ptrType, bitType, memStateType }, { memStateType, ptrType, bitType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & addr = *Lambda_->GetFunctionArguments()[0]; + auto & value = *Lambda_->GetFunctionArguments()[1]; + auto & state = *Lambda_->GetFunctionArguments()[2]; + auto storeOutputs = ::jlm::hls::StoreOperation::create(addr, value, { &state }, state); + Lambda_->finalize({ storeOutputs[0], storeOutputs[1], storeOutputs[2] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS DecoupledLoadOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, DecoupledLoadOperation) +{ + auto ptrType = PointerType::Create(); + auto bitType = BitType::Create(32); + auto functionType = FunctionType::Create({ ptrType, bitType }, { bitType, ptrType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & addr = *Lambda_->GetFunctionArguments()[0]; + auto & loadResult = *Lambda_->GetFunctionArguments()[1]; + auto dloadOutputs = DecoupledLoadOperation::create(addr, loadResult, 4); + Lambda_->finalize({ dloadOutputs[0], dloadOutputs[1] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS LocalLoadOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, LocalLoadOperation) +{ + auto bitType = BitType::Create(32); + auto memStateType = MemoryStateType::Create(); + auto functionType = FunctionType::Create( + { BitType::Create(64), memStateType, bitType }, + { bitType, memStateType, BitType::Create(64) }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & index = *Lambda_->GetFunctionArguments()[0]; + auto & state = *Lambda_->GetFunctionArguments()[1]; + auto & loadResult = *Lambda_->GetFunctionArguments()[2]; + auto loadOutputs = ::jlm::hls::LocalLoadOperation::create(index, { &state }, loadResult); + Lambda_->finalize({ loadOutputs[0], loadOutputs[1], loadOutputs[2] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); + EXPECT_TRUE(AssertFirrtlOpExists(circuit)); +} + +// ================================================================== +// HLS LocalStoreOperation FIRRTL conversion test +// ================================================================== + +TEST_F(FirrtlTestBase, LocalStoreOperation) +{ + auto bitType = BitType::Create(32); + auto memStateType = MemoryStateType::Create(); + auto functionType = + FunctionType::Create({ BitType::Create(64), bitType, memStateType }, { memStateType }); + Lambda_ = LambdaNode::Create( + Module_->Rvsdg().GetRootRegion(), + LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage)); + + auto & index = *Lambda_->GetFunctionArguments()[0]; + auto & value = *Lambda_->GetFunctionArguments()[1]; + auto & state = *Lambda_->GetFunctionArguments()[2]; + auto storeOutputs = ::jlm::hls::LocalStoreOperation::create(index, value, { &state }); + Lambda_->finalize({ storeOutputs[0] }); + + TestableRhlsToFirrtlConverter converter; + mlir::OwningOpRef circuit(converter.TestMlirGen(Lambda_)); + EXPECT_TRUE(circuit); +}