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

Verilog/SystemVerilog generation error: "Can't match template for ...Unsigned.rotateR#" #169

Closed
thoughtpolice opened this issue Aug 16, 2016 · 3 comments

Comments

@thoughtpolice
Copy link
Contributor

thoughtpolice commented Aug 16, 2016

With:

$ clash --version
CAES Language for Synchronous Hardware, version 0.6.22 (using clash-lib, version: 0.6.20)

Consider the following circuit, which is the NORX F permutation, with the recommended 4 rounds (it is almost a transliteration of Figure 2.4, pg 9 in the NORX v2.0 specification):

module NORX where
import Data.Bits
import CLaSH.Prelude

type W = Unsigned 32

norx :: Vec 16 W -> Vec 16 W
norx inp = iterate d5 f inp !! 4

f :: Vec 16 W -> Vec 16 W
f inp = result
  where
    (s0:>s1:>s2:>s3:>s4:>s5:>s6:>s7:>s8:>s9:>s10:>s11:>s12:>s13:>s14:>s15:>_) = inp

    -- Column round
    (t0, t4, t8,  t12) = g (s0, s4, s8,  s12)
    (t1, t5, t9,  t13) = g (s1, s5, s9,  s13)
    (t2, t6, t10, t14) = g (s2, s6, s10, s14)
    (t3, t7, t11, t15) = g (s3, s7, s11, s15)
    -- Diagonal round
    (u0, u5, u10, u15) = g (t0, t5, t10, t15)
    (u1, u6, u11, u12) = g (t1, t6, t11, t12)
    (u2, u7, u8,  u13) = g (t2, t7, t8,  t13)
    (u3, u4, u9,  u14) = g (t3, t4, t9,  t14)

    result = (u0:>u1:>u2:>u3:>u4:>u5:>u6:>u7:>u8:>u9:>u10:>u11:>u12:>u13:>u14:>u15:>Nil)

g :: (W, W, W, W) -> (W, W, W, W)
g (a, b, c, d) = (a'', b'', c'', d'')
  where
    a'  = h a b
    d'  = (a' `xor` d)   `rotateR` 8
    c'  = h c d'
    b'  = (b `xor` c')   `rotateR` 11
    a'' = h a' b'
    d'' = (a'' `xor` d') `rotateR` 16
    c'' = h c' d''
    b'' = (b' `xor` c'') `rotateR` 31

h :: W -> W -> W
h x y = (x `xor` y) `xor` ((x .&. y) `shiftL` 1)

--------------------------------------------------------------------------------
-- HDL export interface

topEntity :: Vec 16 W -> Vec 16 W
topEntity = norx

testInput :: Signal (Vec 16 (Unsigned 32))
testInput = stimuliGenerator $(v [ (0 :: Unsigned 32):>1:>2:>3:>4:>5:>6:>7:>8:>9:>10:>11:>12:>13:>14:>15:>Nil ] )

expectedOutput :: Signal (Vec 16 (Unsigned 32)) -> Signal Bool
expectedOutput = outputVerifier $(v [ (0x99a0283a :: Unsigned 32)
                                    :> 0x16c4b42e
                                    :> 0x6e7fa00b
                                    :> 0x7d075c66
                                    :> 0x65c1af81
                                    :> 0xee254c00
                                    :> 0x126631b6
                                    :> 0xf8915260
                                    :> 0x083181d5
                                    :> 0x85dc0152
                                    :> 0x1a44a1f3
                                    :> 0x7ba61b1a
                                    :> 0x37dde5df
                                    :> 0x078203d3
                                    :> 0x9b3c0701
                                    :> 0x9ce6be37
                                    :> Nil ])

This works and passes the test vector:

$ clash --interactive norx.hs
CLaSHi, version 0.6.22 (using clash-lib, version 0.6.20):
http://www.clash-lang.org/  :? for help
[1 of 1] Compiling NORX             ( norx.hs, interpreted ) [GHC.TypeLits.Normalise changed]
Ok, modules loaded: NORX.
*NORX> sampleN 2 $ expectedOutput (fmap topEntity testInput)
[False,True]
*NORX>

I expect that I should be able to compile this (very simple) circuit to Verilog or SystemVerilog, but I can't. VHDL does work:

$ clash --interactive norx.hs
CLaSHi, version 0.6.22 (using clash-lib, version 0.6.20):
http://www.clash-lang.org/  :? for help
[1 of 1] Compiling NORX             ( norx.hs, interpreted )
Ok, modules loaded: NORX.
*NORX> :vhdl
[1 of 1] Compiling NORX             ( norx.hs, norx.o )
Loading dependencies took 1.257921s
Applied 42 transformations
Normalisation took 1.391006s
Netlist generation took 0.348471s
Applied 73 transformations
Applied 132 transformations
Testbench generation took 0.31372s
Total compilation took 3.326497s
*NORX> :verilog
[1 of 1] Compiling NORX             ( norx.hs, norx.o )
Loading dependencies took 1.363019s
Applied 38 transformations
Normalisation took 1.452286s
*** Exception: CLaSH.Netlist.BlackBox(92): Can't match template for "CLaSH.Sized.Internal.Unsigned.rotateR#" :

[C "// rotateR begin\nwire [2*",L 0,C "-1:0] ",GenSym [C "u"] 0,C ";\nassign ",Sym "" 0,C " = {",I 1,C ",",I 1,C "} >> ",I 2,C ";\nassign ",O,C " = ",Sym "" 0,C "[",L 1,C "-1 : 0];\n// rotateR end"]

with context:

Context {bbResult = (Left (Identifier "app_arg_0" Nothing),Unsigned 32), bbInputs = [(Left (Literal (Just (Signed 64,64)) (NumLit 32)),Signed 64,True),(Left (Identifier "app_arg" Nothing),Unsigned 32,False),(Left (BlackBoxE "GHC.Types.I#" [I 0] (Context {bbResult = (Left (Identifier "app_arg_0" Nothing),Signed 64), bbInputs = [(Left (Literal (Just (Signed 64,64)) (NumLit 31)),Signed 64,True)], bbFunctions = fromList []}) True),Signed 64,True)], bbFunctions = fromList []}

*NORX>

SystemVerilog fails in a very similar manner to this, with basically the exact same error message.

@thoughtpolice
Copy link
Contributor Author

I think I see the problem:

assign ~RESULT = ~SYM[0][~LIT[1]-1 : 0];

~LIT[1] should be ~LIT[0], which refers to the KnownNat constraint. Otherwise, verifyBlackBoxContext will check literals against the inputs context, and return the 3rd Tuple component, which I believe specifies whether it's constant or not - which is (Left (Identifier "app_arg" Nothing),Unsigned 32,False) in this case.

@thoughtpolice
Copy link
Contributor Author

Yes, I've confirmed this is the problem, fixing my primitives .json file in place makes this example work.

@christiaanb
Copy link
Member

Thanks for the report, and for finding the source of the bug so quickly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants