Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support splitting up struct method parameters into multiple input ports #729

Open
wants to merge 46 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
49532f4
Initial, hacky work on computing wrapper interface method types using…
krame505 Aug 1, 2024
363cc7b
Attempt at attachting port names with a primative on every input. Do…
krame505 Aug 8, 2024
b24ca9c
Pass the input port names by tagging methods with a new primative
krame505 Aug 10, 2024
92fa2e8
Refactor WrapMethod type class
krame505 Aug 10, 2024
c6b22fa
Input port splitting works end-to-end, modulo sanity checks and savin…
krame505 Aug 13, 2024
57258ec
Handle prefix for input port names via wrap typeclasses
krame505 Aug 13, 2024
8fdb09d
Saving port types using WrapField type class method
krame505 Aug 13, 2024
5945a7c
Bug fixes
krame505 Aug 13, 2024
25695a4
Use WrapField to determine noinline foreign function types
krame505 Aug 14, 2024
6568cc8
Cleanup, add DeepSplitPorts type class
krame505 Aug 14, 2024
1b1f033
Add primMethod wrapper prim calls in vMkRWire1
krame505 Aug 15, 2024
730f044
Update expected test output
krame505 Aug 15, 2024
7975da7
Re-add module arg port type saving, still need to do port name confli…
krame505 Aug 15, 2024
3ba06d4
Fix saving Inout port types
krame505 Aug 15, 2024
96c35e5
Update test expected output
krame505 Aug 15, 2024
d08c97a
Update expected test output
krame505 Aug 15, 2024
b651d36
Fix prefix computation in genwrap 'to' function and port saving state…
krame505 Aug 16, 2024
4020ade
Fix inadvertantly disabled type check for foreign functions
krame505 Aug 16, 2024
2c9e86e
Update test expected results
krame505 Aug 16, 2024
0c15378
Add interface port name sanity checking after elaboration
krame505 Aug 17, 2024
1ecce93
Fix bug introduced in computing split vector interface prefixes
krame505 Aug 17, 2024
936d140
Add sketch of splitting tuples
krame505 Aug 17, 2024
eccaf03
Check for clash with default clock/reset ports
krame505 Aug 17, 2024
4e48c17
Better error message for synthesizing an interface with a non-Bits me…
krame505 Aug 17, 2024
14fb02c
Cleanup trailing whitespace
krame505 Aug 17, 2024
7aea56f
Update expected results, testsuite passing
krame505 Aug 17, 2024
af1e1eb
Reorganize port splitting utilites into a seperate library, add Shall…
krame505 Aug 17, 2024
a52f2e6
More efficient implementation of splitting vectors
krame505 Aug 19, 2024
36a4dc2
Avoid extra _1 suffix for DeepSplitPorts on Int/UInt
krame505 Aug 19, 2024
8999a65
Add test cases for port splitting
krame505 Aug 19, 2024
be3d910
Add test of DeepSplitPorts with an explicit non-recursive instance
krame505 Aug 20, 2024
150d29c
Fix NoSplit instance
krame505 Aug 20, 2024
c8114b1
Add a comment
krame505 Aug 20, 2024
0ea992e
Stuff the field name in the WrapField type class as a type parameter …
krame505 Aug 20, 2024
9d7921f
Fix trailing whitespace
krame505 Aug 20, 2024
f0d8ac7
Addressing Ravi's comments
krame505 Aug 20, 2024
7067fbe
Fix more comments
krame505 Aug 21, 2024
0e23ad0
Fix testsuite failure after error message tweak
krame505 Aug 22, 2024
1329534
Record the full field name path in WrapField context, for better erro…
krame505 Aug 22, 2024
6f8c504
Don't surface implicit conditions from inside ICMethod
krame505 Aug 22, 2024
b1165c9
FIx trailing whitespace
krame505 Aug 23, 2024
0868d79
Slightly less gross list deconstruction in IExpand
krame505 Aug 23, 2024
df0f863
Add more tests
krame505 Aug 23, 2024
d7b1859
Merge remote-tracking branch 'upstream/main' into genwrap
krame505 Aug 23, 2024
82a1c3f
Merge branch 'main' into genwrap
krame505 Oct 18, 2024
5a34e93
Clean up exports
krame505 Jan 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add test of DeepSplitPorts with an explicit non-recursive instance
  • Loading branch information
krame505 committed Aug 20, 2024
commit be3d910088008f10bfb790c4552010780fb0d7f7
10 changes: 8 additions & 2 deletions src/Libraries/Base1/SplitPorts.bs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ package SplitPorts where
import qualified List
import Vector



-- Newtype tags to indicate that a types should be split (recursively or not) into ports
data ShallowSplit a = ShallowSplit a
data DeepSplit a = DeepSplit a

-- Tag to indicate that the DeepSplitPorts recursion should terminate
data NoSplit a = NoSplit a

instance (ShallowSplitPorts a p) => SplitPorts (ShallowSplit a) p where
splitPorts (ShallowSplit x) = shallowSplitPorts x
unsplitPorts = ShallowSplit ∘ shallowUnsplitPorts
Expand All @@ -21,6 +22,11 @@ instance (DeepSplitPorts a p) => SplitPorts (DeepSplit a) p where
unsplitPorts = DeepSplit ∘ deepUnsplitPorts
portNames _ = deepSplitPortNames (_ :: a)

instance DeepSplitPorts (NoSplit a) (Port a) where
splitPorts (NoSplit x) = Port x
unsplitPorts (Port x) = NoSplit x
portNames _ base = List.Cons base List.Nil


-- Helper class using generics, to split a struct or vector into a tuple of ports.
class ShallowSplitPorts a p | a -> p where
Expand Down
20 changes: 19 additions & 1 deletion testsuite/bsc.verilog/splitports/DeepSplit.bs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,28 @@ struct Baz =
e :: Vector 0 Foo
-- No Bits instance needed

struct Quix =
q :: Int 3
v :: Bool
deriving (Bits)

-- Don't recurse into Quix with DeepSplitPorts
instance DeepSplitPorts Quix (Port Quix) where
deepSplitPorts x = Port x
deepUnsplitPorts (Port x) = x
deepSplitPortNames _ base = Cons (base) Nil

struct Zug =
qs :: Vector 2 Quix
blob :: Bool

interface SplitTest =
putFoo :: DeepSplit Foo -> Action
putBar :: DeepSplit Bar -> Action {-# prefix = "PUT_BAR" #-}
putFooBar :: DeepSplit Foo -> DeepSplit Bar -> Action {-# arg_names = ["fooIn", "barIn"] #-}
putFoos :: DeepSplit (Vector 50 Foo) -> Action
putBaz :: DeepSplit Baz -> Action
putZug :: DeepSplit Zug -> Action


{-# synthesize mkDeepSplitTest #-}
Expand All @@ -42,6 +58,7 @@ mkDeepSplitTest =
putFooBar (DeepSplit x) (DeepSplit y) = $display "putFooBar: " (cshow x) " " (cshow y)
putFoos (DeepSplit x) = $display "putFoos: " (cshow x)
putBaz (DeepSplit x) = $display "putBaz: " (cshow x)
putZug (DeepSplit x) = $display "putZug: " (cshow x)

{-# synthesize sysDeepSplit #-}
sysDeepSplit :: Module Empty
Expand All @@ -56,4 +73,5 @@ sysDeepSplit =
when i == 2 ==> s.putFooBar (DeepSplit $ Foo { x = 5; y = 6; }) (DeepSplit $ Bar { v = vec False True False; w = (False, 0x5678); z = Foo { x = 7; y = 8; } })
when i == 3 ==> s.putFoos $ DeepSplit $ genWith $ \ j -> Foo { x = fromInteger $ 9 + j / 2; y = fromInteger $ 10 - 2*j / 3; }
when i == 4 ==> s.putBaz $ DeepSplit $ Baz { a = Just $ Foo { x = 9; y = 10; }; b = Bar { v = vec True False False; w = (True, 0x1234); z = Foo { x = 3; y = 4; }; }; c = vec (vec (Foo { x = 11; y = 12; }) (Foo { x = 13; y = 14; }) (Foo { x = 15; y = 16; }) (Foo { x = 17; y = 18; }) (Foo { x = 19; y = 20; }) (Foo { x = 21; y = 22; }) (Foo { x = 23; y = 24; }) (Foo { x = 25; y = 26; }), Bar { v = vec True False True; w = (True, 0xBEEF); z = Foo { x = 3; y = 4; } }) (vec (Foo { x = 27; y = 28; }) (Foo { x = 29; y = 30; }) (Foo { x = 31; y = 32; }) (Foo { x = 33; y = 34; }) (Foo { x = 35; y = 36; }) (Foo { x = 37; y = 38; }) (Foo { x = 39; y = 40; }) (Foo { x = 41; y = 42; }), Bar { v = vec True False True; w = (True, 0x4321); z = Foo { x = 123; y = 42; } }) (vec (Foo { x = 43; y = 44; }) (Foo { x = 45; y = 46; }) (Foo { x = 47; y = 48; }) (Foo { x = 49; y = 50; }) (Foo { x = 51; y = 52; }) (Foo { x = 53; y = 54; }) (Foo { x = 55; y = 56; }) (Foo { x = 57; y = 58; }), Bar { v = vec True True True; w = (True, 0xAABB); z = Foo { x = 3; y = 4; } }); d = (); e = nil; }
when i == 5 ==> $finish
when i == 5 ==> s.putZug $ DeepSplit $ Zug { qs = vec (Quix { q = 1; v = True }) (Quix { q = 2; v = False }); blob = False; }
when i == 6 ==> $finish
1 change: 1 addition & 0 deletions testsuite/bsc.verilog/splitports/splitports.exp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ if { $vtest == 1 } {
find_regexp mkDeepSplitTest.v {input \[16 : 0\] putBaz_1_a;}
find_regexp mkDeepSplitTest.v {input \[7 : 0\] putBaz_1_c_2_1_7_y;}
find_regexp mkDeepSplitTest.v {input \[15 : 0\] putBaz_1_c_2_2_w_2;}
find_regexp mkDeepSplitTest.v {input \[3 : 0\] putZug_1_qs_1;}
}

test_c_veri InstanceSplit
Expand Down
1 change: 1 addition & 0 deletions testsuite/bsc.verilog/splitports/sysDeepSplit.out.expected
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ putBar: Bar {v=[True, False, True]; w=(True, 4660); z=Foo {x= 3; y= 4}}
putFooBar: Foo {x= 5; y= 6} Bar {v=[False, True, False]; w=(False, 22136); z=Foo {x= 7; y= 8}}
putFoos: [Foo {x= 9; y= 10}, Foo {x= 9; y= 10}, Foo {x= 10; y= 9}, Foo {x= 10; y= 8}, Foo {x= 11; y= 8}, Foo {x= 11; y= 7}, Foo {x= 12; y= 6}, Foo {x= 12; y= 6}, Foo {x= 13; y= 5}, Foo {x= 13; y= 4}, Foo {x= 14; y= 4}, Foo {x= 14; y= 3}, Foo {x= 15; y= 2}, Foo {x= 15; y= 2}, Foo {x= 16; y= 1}, Foo {x= 16; y= 0}, Foo {x= 17; y= 0}, Foo {x= 17; y= -1}, Foo {x= 18; y= -2}, Foo {x= 18; y= -2}, Foo {x= 19; y= -3}, Foo {x= 19; y= -4}, Foo {x= 20; y= -4}, Foo {x= 20; y= -5}, Foo {x= 21; y= -6}, Foo {x= 21; y= -6}, Foo {x= 22; y= -7}, Foo {x= 22; y= -8}, Foo {x= 23; y= -8}, Foo {x= 23; y= -9}, Foo {x= 24; y= -10}, Foo {x= 24; y= -10}, Foo {x= 25; y= -11}, Foo {x= 25; y= -12}, Foo {x= 26; y= -12}, Foo {x= 26; y= -13}, Foo {x= 27; y= -14}, Foo {x= 27; y= -14}, Foo {x= 28; y= -15}, Foo {x= 28; y= -16}, Foo {x= 29; y= -16}, Foo {x= 29; y= -17}, Foo {x= 30; y= -18}, Foo {x= 30; y= -18}, Foo {x= 31; y= -19}, Foo {x= 31; y= -20}, Foo {x= 32; y= -20}, Foo {x= 32; y= -21}, Foo {x= 33; y= -22}, Foo {x= 33; y= -22}]
putBaz: Baz {a=Valid (Foo {x= 9; y= 10}); b=Bar {v=[True, False, False]; w=(True, 4660); z=Foo {x= 3; y= 4}}; c=[([Foo {x= 11; y= 12}, Foo {x= 13; y= 14}, Foo {x= 15; y= 16}, Foo {x= 17; y= 18}, Foo {x= 19; y= 20}, Foo {x= 21; y= 22}, Foo {x= 23; y= 24}, Foo {x= 25; y= 26}], Bar {v=[True, False, True]; w=(True, 48879); z=Foo {x= 3; y= 4}}), ([Foo {x= 27; y= 28}, Foo {x= 29; y= 30}, Foo {x= 31; y= 32}, Foo {x= 33; y= 34}, Foo {x= 35; y= 36}, Foo {x= 37; y= 38}, Foo {x= 39; y= 40}, Foo {x= 41; y= 42}], Bar {v=[True, False, True]; w=(True, 17185); z=Foo {x= 123; y= 42}}), ([Foo {x= 43; y= 44}, Foo {x= 45; y= 46}, Foo {x= 47; y= 48}, Foo {x= 49; y= 50}, Foo {x= 51; y= 52}, Foo {x= 53; y= 54}, Foo {x= 55; y= 56}, Foo {x= 57; y= 58}], Bar {v=[True, True, True]; w=(True, 43707); z=Foo {x= 3; y= 4}})]; d=(); e=[]}
putZug: Zug {qs=[Quix {q= 1; v=True}, Quix {q= 2; v=False}]; blob=False}