Skip to content

Commit

Permalink
More unit tests and tidying up
Browse files Browse the repository at this point in the history
  • Loading branch information
jameshanlon committed Sep 23, 2023
1 parent e87e249 commit f8446d5
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 19 deletions.
1 change: 1 addition & 0 deletions tools/netlist/TODO.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
To dos
======

- Support descending ranges in split variable type handling, eg [0:3].
- Dumping of a dot file outputs random characters at the end.
- Support for more procedural statements, the full list is:

Expand Down
13 changes: 4 additions & 9 deletions tools/netlist/include/SplitVariables.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ class AnalyseVariableReference {
if (std::next(selectorsIt) != node.selectors.end()) {
selectorsIt++;
const auto& fieldType = getScopeFieldType(packedStruct, memberAccessSelector.name);
return getBitRangeImpl(fieldType, fieldRange);
return getBitRangeImpl(fieldType, newRange);
} else {
return newRange;
}
Expand All @@ -278,7 +278,7 @@ class AnalyseVariableReference {
if (std::next(selectorsIt) != node.selectors.end()) {
selectorsIt++;
const auto& fieldType = getScopeFieldType(packedUnion, memberAccessSelector.name);
return getBitRangeImpl(fieldType, fieldRange);
return getBitRangeImpl(fieldType, newRange);
} else {
return newRange;
}
Expand All @@ -292,13 +292,8 @@ class AnalyseVariableReference {
ConstantRange newRange = {range.lower() + fieldRange.lower(),
range.lower() + fieldRange.upper()};
SLANG_ASSERT(range.contains(newRange));
if (std::next(selectorsIt) != node.selectors.end()) {
selectorsIt++;
const auto& fieldType = getScopeFieldType(enumeration, memberAccessSelector.name);
return getBitRangeImpl(fieldType, fieldRange);
} else {
return newRange;
}
SLANG_ASSERT(std::next(selectorsIt) == node.selectors.end());
return newRange;
}

// Multiple range selectors have only the effect of the last one.
Expand Down
35 changes: 35 additions & 0 deletions tools/netlist/tests/PathTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,3 +490,38 @@ endmodule
CHECK(pathFinder.find(*inPortB, *outPortA).empty());
}

//===---------------------------------------------------------------------===//
// Test case for #792 (bus expression in ports)
//===---------------------------------------------------------------------===//

TEST_CASE("Test case for #792 (bus expression in ports)") {
auto tree = SyntaxTree::fromText(R"(
module test (input [1:0] in_i,
output [1:0] out_o);
wire [1:0] in_s;
assign in_s = in_i;
nop i_nop(.in_i(in_s[1:0]), // ok: in_s, in_i, {in_i[1], in_i[0]}
.out_o(out_o));
endmodule
module nop (input [1:0] in_i,
output [1:0] out_o);
// individual bits access; ok: out_o = in_i;
assign out_o[0] = in_i[0];
assign out_o[1] = in_i[1];
endmodule
)");
Compilation compilation;
compilation.addSyntaxTree(tree);
NO_COMPILATION_ERRORS;
auto netlist = createNetlist(compilation);
auto* inPort = netlist.lookupPort("test.in_i");
auto* outPort = netlist.lookupPort("test.out_o");
PathFinder pathFinder(netlist);
// Valid paths.
CHECK(!pathFinder.find(*inPort, *outPort).empty());
}
117 changes: 107 additions & 10 deletions tools/netlist/tests/VariableSelectorsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,6 @@ module m (input int a);
foo[a][a] = 0;
foo[a+:1] = 0;
foo[a-:1] = 0;
//foo[a+:1][1] = 0;
//foo[a-:1][1] = 0;
foo[1][a] = 0;
foo[1][a+:1] = 0;
foo[1][a-:1] = 0;
Expand Down Expand Up @@ -224,8 +222,6 @@ endmodule
CHECK(getBitRange(netlist, "foo[a][a]") == ConstantRange(0, 7));
CHECK(getBitRange(netlist, "foo[a+:1]") == ConstantRange(0, 7));
CHECK(getBitRange(netlist, "foo[a-:1]") == ConstantRange(0, 7));
//CHECK(getBitRange(netlist, "foo[a+:1][1]") == ConstantRange(0, 7));
//CHECK(getBitRange(netlist, "foo[a-:1][1]") == ConstantRange(0, 7));
CHECK(getBitRange(netlist, "foo[1][a]") == ConstantRange(2, 3));
CHECK(getBitRange(netlist, "foo[1][a+:1]") == ConstantRange(2, 3));
CHECK(getBitRange(netlist, "foo[1][a-:1]") == ConstantRange(2, 3));
Expand Down Expand Up @@ -321,8 +317,6 @@ module m (input int a);
foo[a][a] = 0;
foo[a+:1] = '{'{0, 0}};
foo[a-:2] = '{'{0, 0}, '{0, 0}};
//foo[a+:1][1] = 0;
//foo[a-:1][1] = 0;
foo[1][a] = 0;
foo[1][a+:1] = '{0};
foo[1][a-:2] = '{0, 0};
Expand All @@ -345,8 +339,6 @@ endmodule
CHECK(getBitRange(netlist, "foo[a][a]") == ConstantRange(0, 7));
CHECK(getBitRange(netlist, "foo[a+:1]") == ConstantRange(0, 7));
CHECK(getBitRange(netlist, "foo[a-:2]") == ConstantRange(0, 7));
//CHECK(getBitRange(netlist, "foo[a+:1][1]") == ConstantRange(0, 7));
//CHECK(getBitRange(netlist, "foo[a-:1][1]") == ConstantRange(0, 7));
CHECK(getBitRange(netlist, "foo[1][a]") == ConstantRange(2, 3));
CHECK(getBitRange(netlist, "foo[1][a+:1]") == ConstantRange(2, 3));
CHECK(getBitRange(netlist, "foo[1][a-:2]") == ConstantRange(2, 3));
Expand Down Expand Up @@ -426,6 +418,7 @@ endmodule
//===---------------------------------------------------------------------===//

TEST_CASE("Struct with packed array members") {
// Test recursion from packed struct.
auto tree = SyntaxTree::fromText(R"(
module m;
struct packed {
Expand All @@ -451,30 +444,134 @@ endmodule
CHECK(getBitRange(netlist, "foo.b[2:1]") == ConstantRange(5, 6));
}

TEST_CASE("Struct with packed union members") {
TEST_CASE("Packed struct with packed union and enum members") {
// Test recursion from packed struct.
auto tree = SyntaxTree::fromText(R"(
module m;
typedef enum int { A, B, C } enum_t;
struct packed {
union packed {
logic [3:0] a, b;
} u;
enum_t c;
} foo;
always_comb begin
foo = 0;
foo[1] = 0;
foo.u = 0;
foo.u[2:1] = 0;
foo.u.a[2:1] = 0;
foo.u.b[2:1] = 0;
foo.c = A;
end
endmodule
)");
Compilation compilation;
compilation.addSyntaxTree(tree);
NO_COMPILATION_ERRORS;
auto netlist = createNetlist(compilation);
CHECK(getBitRange(netlist, "foo") == ConstantRange(0, 3));
CHECK(getBitRange(netlist, "foo") == ConstantRange(0, 35));
CHECK(getBitRange(netlist, "foo[1]") == ConstantRange(1, 1));
CHECK(getBitRange(netlist, "foo.u") == ConstantRange(0, 3));
CHECK(getBitRange(netlist, "foo.u[2:1]") == ConstantRange(1, 2));
CHECK(getBitRange(netlist, "foo.u.a[2:1]") == ConstantRange(1, 2));
CHECK(getBitRange(netlist, "foo.u.b[2:1]") == ConstantRange(1, 2));
CHECK(getBitRange(netlist, "foo.c") == ConstantRange(4, 35));
}

TEST_CASE("Packed arrays of structs etc") {
// Test recursion from packed packed array, packed struct, packed union.
auto tree = SyntaxTree::fromText(R"(
module m;
typedef enum int { A, B, C } enum_t;
typedef struct packed {
union packed {
logic [3:0] a, b;
} u;
logic [1:0] c;
enum_t d;
} foo_t;
foo_t [3:0] [1:0] foo;
always_comb begin
foo = 0;
foo[0] = 0;
foo[1] = 0;
foo[0][0] = 0;
foo[0][1] = 0;
foo[0][0].u.a = 0;
foo[0][1].u.a = 0;
foo[0][0].u.b = 0;
foo[0][1].u.b = 0;
foo[0][0].c = 0;
foo[0][1].c = 0;
foo[0][0].d = A;
foo[0][1].d = A;
foo[3][1] = 0;
foo[3][1].u.a = 0;
foo[3][1].u.b = 0;
foo[3][1].c = 0;
foo[3][1].d = A;
end
endmodule
)");
Compilation compilation;
compilation.addSyntaxTree(tree);
NO_COMPILATION_ERRORS;
auto netlist = createNetlist(compilation);
CHECK(getBitRange(netlist, "foo") == ConstantRange(0, 303));
CHECK(getBitRange(netlist, "foo[0]") == ConstantRange(0, 75));
CHECK(getBitRange(netlist, "foo[1]") == ConstantRange(76, 151));
CHECK(getBitRange(netlist, "foo[0][0]") == ConstantRange(0, 37));
CHECK(getBitRange(netlist, "foo[0][1]") == ConstantRange(38, 75));
CHECK(getBitRange(netlist, "foo[0][0].u.a") == ConstantRange(0, 3));
CHECK(getBitRange(netlist, "foo[0][1].u.a") == ConstantRange(38, 41));
CHECK(getBitRange(netlist, "foo[0][0].u.b") == ConstantRange(0, 3));
CHECK(getBitRange(netlist, "foo[0][1].u.b") == ConstantRange(38, 41));
CHECK(getBitRange(netlist, "foo[0][0].c") == ConstantRange(4, 5));
CHECK(getBitRange(netlist, "foo[0][1].c") == ConstantRange(42, 43));
CHECK(getBitRange(netlist, "foo[0][0].d") == ConstantRange(6, 37));
CHECK(getBitRange(netlist, "foo[0][1].d") == ConstantRange(44, 75));
CHECK(getBitRange(netlist, "foo[3][1]") == ConstantRange(266, 303));
CHECK(getBitRange(netlist, "foo[3][1].u.a") == ConstantRange(266, 269));
CHECK(getBitRange(netlist, "foo[3][1].u.b") == ConstantRange(266, 269));
CHECK(getBitRange(netlist, "foo[3][1].c") == ConstantRange(270, 271));
CHECK(getBitRange(netlist, "foo[3][1].d") == ConstantRange(272, 303));
}

TEST_CASE("Union with packed struct members") {
// Test recursion from packed union, packed struct.
auto tree = SyntaxTree::fromText(R"(
module m;
typedef enum int { A, B, C } enum_t;
union packed {
struct packed {
logic [3:0] a, b;
} x, y;
} [3:0] foo;
always_comb begin
foo = 0;
foo[0].x.a = 0;
foo[0].x.b = 0;
foo[0].y.a = 0;
foo[0].y.b = 0;
foo[3].x.a = 0;
foo[3].x.b = 0;
foo[3].y.a = 0;
foo[3].y.b = 0;
end
endmodule
)");
Compilation compilation;
compilation.addSyntaxTree(tree);
NO_COMPILATION_ERRORS;
auto netlist = createNetlist(compilation);
CHECK(getBitRange(netlist, "foo") == ConstantRange(0, 31));
CHECK(getBitRange(netlist, "foo[0].x.a") == ConstantRange(0, 3));
CHECK(getBitRange(netlist, "foo[0].x.b") == ConstantRange(4, 7));
CHECK(getBitRange(netlist, "foo[0].y.a") == ConstantRange(0, 3));
CHECK(getBitRange(netlist, "foo[0].y.b") == ConstantRange(4, 7));
CHECK(getBitRange(netlist, "foo[3].x.a") == ConstantRange(24, 27));
CHECK(getBitRange(netlist, "foo[3].x.b") == ConstantRange(28, 31));
CHECK(getBitRange(netlist, "foo[3].y.a") == ConstantRange(24, 27));
CHECK(getBitRange(netlist, "foo[3].y.b") == ConstantRange(28, 31));
}

0 comments on commit f8446d5

Please sign in to comment.