Skip to content

Commit ae3dd64

Browse files
author
Alex McKenna
authored
Merge pull request #1059 from clash-lang/nested-product-names
Generate unique names for port wires. Fix #1041
2 parents 5af9572 + 8bdc7fa commit ae3dd64

File tree

4 files changed

+101
-6
lines changed

4 files changed

+101
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
* [#1030](https://github.com/clash-lang/clash-compiler/issues/1030): `bindConstantVar` will bind (workfree) constructs
8686
* [#1034](https://github.com/clash-lang/clash-compiler/issues/1034): Error (10137): object "pllLock" on lhs must have a variable data type
8787
* [#1046](https://github.com/clash-lang/clash-compiler/issues/1046): Don't confuse term/type namespaces in 'lookupIdSubst'
88+
* [#1041](https://github.com/clash-lang/clash-compiler/issues/1041): Nested product types incorrectly decomposed into ports
8889

8990
* Fixes without issue reports:
9091
* Fix bug in `rnfX` defined for `Down` ([baef30e](https://github.com/clash-lang/clash-compiler/commit/baef30eae03dc02ba847ffbb8fae7f365c5287c2))

clash-lib/src/Clash/Netlist/Util.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,8 +1272,8 @@ mkOutput' pM = case pM of
12721272
pN <- uniquePortName p o
12731273
return ([(pN,hwty)],[],pN)
12741274

1275-
go' (PortProduct p ps) (o,hwty) = do
1276-
pN <- uniquePortName p o
1275+
go' (PortProduct p ps) (_,hwty) = do
1276+
pN <- mkUniqueIdentifier Basic (Text.pack p)
12771277
let (attrs, hwty') = stripAttributes hwty
12781278
case hwty' of
12791279
Vector sz hwty'' -> do
@@ -1298,12 +1298,12 @@ mkOutput' pM = case pM of
12981298
results <- zipWithM appendIdentifier (map (pN,) hwtys) [0..]
12991299
let ps' = extendPorts $ map (prefixParent p) ps
13001300
(ports,decls,ids) <- unzip3 <$> uncurry (zipWithM mkOutput') (ps', results)
1301+
let netdecl = NetDecl Nothing pN hwty'
13011302
case ids of
1302-
[i] -> let netdecl = NetDecl Nothing pN hwty'
1303-
assign = Assignment i (Identifier pN Nothing)
1303+
[i] -> let assign = Assignment i (Identifier pN Nothing)
13041304
in return (concat ports,netdecl:assign:concat decls,pN)
1305-
_ -> let netdecl = NetDecl Nothing pN hwty'
1306-
assigns = zipWith (assignId pN hwty' 0) ids [0..]
1305+
1306+
_ -> let assigns = zipWith (assignId pN hwty' 0) ids [0..]
13071307
in if null attrs then
13081308
return (concat ports,netdecl:assigns ++ concat decls,pN)
13091309
else

tests/shouldwork/Naming/T1041.hs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
{-# LANGUAGE RecordWildCards #-}
3+
4+
module T1041 where
5+
6+
import Prelude as P
7+
8+
import Clash.Prelude
9+
import Clash.Netlist.Types
10+
11+
import Test.Tasty.Clash
12+
import Test.Tasty.Clash.NetlistTest
13+
14+
data VGASync dom = VGASync
15+
{ vgaHSync :: Signal dom (Unsigned 8)
16+
, vgaVSync :: Signal dom (Unsigned 8)
17+
, vgaDE :: Signal dom (Unsigned 8)
18+
}
19+
20+
data VGAOut dom = VGAOut
21+
{ vgaSync :: VGASync dom
22+
, vgaR :: Signal dom (Unsigned 8)
23+
, vgaG :: Signal dom (Unsigned 8)
24+
, vgaB :: Signal dom (Unsigned 8)
25+
}
26+
27+
{-# ANN getVgaOut
28+
(Synthesize
29+
{ t_name = "Pattern"
30+
, t_inputs =
31+
[ PortName "CLK_25MHZ"
32+
, PortName "RESET"
33+
]
34+
, t_output =
35+
PortProduct "VGA"
36+
[ PortProduct ""
37+
[ PortName "HSYNC"
38+
, PortName "VSYNC"
39+
, PortName "DE"
40+
]
41+
, PortName "RED"
42+
, PortName "GREEN"
43+
, PortName "BLUE"
44+
]
45+
}) #-}
46+
getVgaOut :: Clock System -> Reset System -> VGAOut System
47+
getVgaOut clk rst = VGAOut{..}
48+
where
49+
vgaSync = VGASync{..}
50+
where
51+
vgaHSync = pure 0
52+
vgaVSync = pure 1
53+
vgaDE = pure 2
54+
55+
vgaR = pure 3
56+
vgaG = pure 4
57+
vgaB = pure 5
58+
59+
testPath :: FilePath
60+
testPath = "tests/shouldwork/Naming/T1041.hs"
61+
62+
assertOneVGA :: Component -> IO ()
63+
assertOneVGA (Component _ _ _ ds)
64+
| vgas == 1 = pure ()
65+
| otherwise = error $ "Expected one declaration of VGA wire: got " <> show vgas
66+
where
67+
vgas = P.length (filter isVGADecl ds)
68+
69+
-- Multiple cases as mkUniqueIdentifier Basic
70+
-- in VHDL changes names to be lowercase.
71+
--
72+
isVGADecl (NetDecl' _ Wire "vga" _ _) = True
73+
isVGADecl (NetDecl' _ Wire "VGA" _ _) = True
74+
isVGADecl _ = False
75+
76+
getComponent :: (a, b, c, d) -> d
77+
getComponent (_, _, _, x) = x
78+
79+
mainVHDL :: IO ()
80+
mainVHDL = do
81+
netlist <- runToNetlistStage SVHDL id testPath
82+
mapM_ (assertOneVGA . getComponent) netlist
83+
84+
mainVerilog :: IO ()
85+
mainVerilog = do
86+
netlist <- runToNetlistStage SVerilog id testPath
87+
mapM_ (assertOneVGA . getComponent) netlist
88+
89+
mainSystemVerilog :: IO ()
90+
mainSystemVerilog = do
91+
netlist <- runToNetlistStage SSystemVerilog id testPath
92+
mapM_ (assertOneVGA . getComponent) netlist
93+

testsuite/Main.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ runClashTest = defaultMain $ clashTestRoot
253253
[ runTest "T967a" def{hdlSim=False}
254254
, runTest "T967b" def{hdlSim=False}
255255
, runTest "T967c" def{hdlSim=False}
256+
, netlistTest ("tests" </> "shouldwork" </> "Naming") allTargets [] "T1041" "main"
256257
]
257258
, clashTestGroup "Numbers"
258259
[ runTest "BitInteger" def

0 commit comments

Comments
 (0)