clash-systemverilog 0.5.10 → 0.6
raw patch · 11 files changed
+172/−58 lines, 11 filesdep ~clash-libdep ~clash-preludePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: clash-lib, clash-prelude
API changes (from Hackage documentation)
- CLaSH.Backend.SystemVerilog: instance CLaSH.Backend.Backend CLaSH.Backend.SystemVerilog.SystemVerilogState
+ CLaSH.Backend.SystemVerilog: instance Backend SystemVerilogState
Files
- CHANGELOG.md +4/−0
- README.md +3/−3
- clash-systemverilog.cabal +6/−6
- primitives/CLaSH.Prelude.BlockRam.File.json +1/−1
- primitives/CLaSH.Prelude.ROM.File.json +2/−2
- primitives/CLaSH.Sized.Internal.BitVector.json +12/−8
- primitives/CLaSH.Sized.Internal.Index.json +1/−1
- primitives/CLaSH.Sized.Internal.Signed.json +11/−11
- primitives/CLaSH.Sized.Internal.Unsigned.json +4/−4
- primitives/CLaSH.Sized.Vector.json +116/−21
- src/CLaSH/Backend/SystemVerilog.hs +12/−1
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog for the [`clash-systemverilog`](http://hackage.haskell.org/package/clash-systemverilog) package +## 0.6 *October 3rd 2015*+* New features:+ * Support `clash-prelude-0.10`+ ## 0.5.10 *September 21st 2015* * New features: * Report simulation time in assert messages
README.md view
@@ -11,8 +11,8 @@ Features of CλaSH: * Strongly typed (like VHDL), yet with a very high degree of type inference,- which enables both safe and fast prototying using consise descriptions (like- Verilog)+ enabling both safe and fast prototying using consise descriptions (like+ Verilog). * Interactive REPL: load your designs in an interpreter and easily test all your component without needing to setup a test bench.@@ -21,7 +21,7 @@ fully parametric by default. * Synchronous sequential circuit design based on streams of values, called- `Signal`s.+ `Signal`s, lead to natural descriptions of feedback loops. * Support for multiple clock domains, with type safe clock domain crossing.
clash-systemverilog.cabal view
@@ -1,5 +1,5 @@ Name: clash-systemverilog-Version: 0.5.10+Version: 0.6 Synopsis: CAES Language for Synchronous Hardware - SystemVerilog backend Description: CλaSH (pronounced ‘clash’) is a functional hardware description language that@@ -10,8 +10,8 @@ Features of CλaSH: . * Strongly typed (like VHDL), yet with a very high degree of type inference,- which enables both safe and fast prototying using consise descriptions (like- Verilog)+ enabling both safe and fast prototying using consise descriptions (like+ Verilog). . * Interactive REPL: load your designs in an interpreter and easily test all your component without needing to setup a test bench.@@ -20,7 +20,7 @@ fully parametric by default. . * Synchronous sequential circuit design based on streams of values, called- @Signal@s.+ @Signal@s, lead to natural descriptions of feedback loops. . * Support for multiple clock domains, with type safe clock domain crossing. .@@ -93,8 +93,8 @@ ViewPatterns Build-depends: base >= 4.6.0.1 && < 5,- clash-lib >= 0.5.12,- clash-prelude >= 0.9,+ clash-lib >= 0.6,+ clash-prelude >= 0.10, fgl >= 5.4.2.4, lens >= 3.9.2, mtl >= 2.1.2,
primitives/CLaSH.Prelude.BlockRam.File.json view
@@ -12,7 +12,7 @@ -> Signal' clk (BitVector m)" , "templateD" : "// blockRamFile begin-~TYPO RAM_~SYM[0] [0:~LIT[2]-1];+~SIGDO[RAM_~SYM[0]] [0:~LIT[2]-1]; ~SIGD[dout_~SYM[1]][7]; initial begin
primitives/CLaSH.Prelude.ROM.File.json view
@@ -8,7 +8,7 @@ -> BitVector m" , "templateD" : "// asyncRomFile begin-~TYPO ROM_~SYM[0] [0:~LIT[1]-1];+~SIGDO[ROM_~SYM[0]] [0:~LIT[1]-1]; initial begin $readmemb(~FILE[~LIT[2]],ROM_~SYM[0]);@@ -29,7 +29,7 @@ -> Signal' clk (BitVector m)" , "templateD" : "// romFile begin-~TYPO ROM_~SYM[0] [0:~LIT[2]-1];+~SIGDO[ROM_~SYM[0]] [0:~LIT[2]-1]; initial begin $readmemb(~FILE[~LIT[3]],ROM_~SYM[0]);
primitives/CLaSH.Sized.Internal.BitVector.json view
@@ -144,11 +144,13 @@ => BitVector n -- ARG[1] -> Bit" , "templateD" :-"// msb begin+"// msb begin~IF ~LIT[0] ~THEN ~SIGD[~SYM[0]][1]; assign ~SYM[0] = ~ARG[1]; assign ~RESULT = ~SYM[0][~LIT[0]-1];-// msb end"+~ELSE+assign ~RESULT = 1'b0;+~FI// msb end" } } , { "BlackBox" :@@ -157,11 +159,13 @@ "lsb# :: BitVector n -- ARG[0] -> Bit" , "templateD" :-"// lsb begin+"// lsb begin~IF ~SIZE[~TYP[0]] ~THEN ~SIGD[~SYM[0]][0]; assign ~SYM[0] = ~ARG[0]; assign ~RESULT = ~SYM[0][0];-// lsb end"+~ELSE+assign ~RESULT = 1'b0;+~FI// lsb end" } } , { "BlackBox" :@@ -202,8 +206,8 @@ } , { "BlackBox" : { "name" : "CLaSH.Sized.Internal.BitVector.minBound#"- , "type" : "minBound# :: KnownNat n => BitVector n"- , "templateE" : "~LIT[0]'d0"+ , "type" : "minBound# :: BitVector n"+ , "templateE" : "~SIZE[~TYPO]'d0" } } , { "BlackBox" :@@ -275,7 +279,7 @@ , { "BlackBox" : { "name" : "CLaSH.Sized.Internal.BitVector.toInteger#" , "type" : "toInteger# :: BitVector n -> Integer"- , "templateE" : "$unsigned(~ARG[0])"+ , "templateD" : "assign ~RESULT = $unsigned(~ARG[0]);" } } , { "BlackBox" :@@ -339,7 +343,7 @@ , { "BlackBox" : { "name" : "CLaSH.Sized.Internal.BitVector.resize#" , "type" : "resize# :: KnownNat m => BitVector n -> BitVector m"- , "templateE" : "$unsigned(~ARG[1])"+ , "templateD" : "assign ~RESULT = $unsigned(~ARG[1]);" } } ]
primitives/CLaSH.Sized.Internal.Index.json view
@@ -79,7 +79,7 @@ , { "BlackBox" : { "name" : "CLaSH.Sized.Internal.Index.toInteger#" , "type" : "toInteger# :: Index n -> Integer"- , "templateE" : "$unsigned(~ARG[0])"+ , "templateD" : "assign ~RESULT = $unsigned(~ARG[0]);" } } ]
primitives/CLaSH.Sized.Internal.Signed.json view
@@ -153,29 +153,29 @@ } , { "BlackBox" : { "name" : "CLaSH.Sized.Internal.Signed.mod#"- , "type" : "mod# :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "type" : "mod# :: Signed n -> Signed n -> Signed n" , "templateD" : "// modSigned begin-~SIGD[~SYM[0]][1];-~SIGD[~SYM[1]][1];-~SIGD[~SYM[2]][2];+~SIGD[~SYM[0]][0];+~SIGD[~SYM[1]][0];+~SIGD[~SYM[2]][1]; // remainder-assign ~SYM[0] = ~ARG[1] % ~ARG[2];+assign ~SYM[0] = ~ARG[0] % ~ARG[1]; // modulo-assign ~SYM[1] = ~ARG[1];-assign ~SYM[2] = ~ARG[2];-assign ~RESULT = (~SYM[1][~LIT[0]-1] == ~SYM[2][~LIT[0]-1]) ?+assign ~SYM[1] = ~ARG[0];+assign ~SYM[2] = ~ARG[1];+assign ~RESULT = (~SYM[1][~SIZE[~TYPO]-1] == ~SYM[2][~SIZE[~TYPO]-1]) ? ~SYM[0] :- (~ARG[1] == ~LIT[0]'sd0 ? ~LIT[0]'sd0 : ~SYM[0] + ~ARG[1]);+ (~SYM[1] == ~SIZE[~TYPO]'sd0 ? ~SIZE[~TYPO]'sd0 : ~SYM[0] + ~SYM[1]); // modSigned end" } } , { "BlackBox" : { "name" : "CLaSH.Sized.Internal.Signed.toInteger#" , "type" : "toInteger# :: Signed n -> Integer"- , "templateE" : "$signed(~ARG[0])"+ , "templateD" : "assign ~RESULT = $signed(~ARG[0]);" } } , { "BlackBox" :@@ -259,7 +259,7 @@ , { "BlackBox" : { "name" : "CLaSH.Sized.Internal.Signed.truncateB#" , "type" : "truncateB# :: KnownNat m => Signed (n + m) -> Signed m"- , "templateE" : "$signed(~ARG[1])"+ , "templateD" : "assign ~RESULT = $signed(~ARG[1]);" } } ]
primitives/CLaSH.Sized.Internal.Unsigned.json view
@@ -54,8 +54,8 @@ } , { "BlackBox" : { "name" : "CLaSH.Sized.Internal.Unsigned.minBound#"- , "type" : "minBound# :: KnownNat n => Unsigned n"- , "templateE" : "~LIT[0]'d0"+ , "type" : "minBound# :: Unsigned n"+ , "templateE" : "~SIZE[~TYPO]'d0" } } , { "BlackBox" :@@ -127,7 +127,7 @@ , { "BlackBox" : { "name" : "CLaSH.Sized.Internal.Unsigned.toInteger#" , "type" : "toInteger# :: Unsigned n -> Integer"- , "templateE" : "$unsigned(~ARG[0])"+ , "templateD" : "assign ~RESULT = $unsigned(~ARG[0]);" } } , { "BlackBox" :@@ -191,7 +191,7 @@ , { "BlackBox" : { "name" : "CLaSH.Sized.Internal.Unsigned.resize#" , "type" : "resize# :: KnownNat m => Unsigned n -> Unsigned m"- , "templateE" : "$unsigned(~ARG[1])"+ , "templateD" : "assign ~RESULT = $unsigned(~ARG[1]);" } } ]
primitives/CLaSH.Sized.Vector.json view
@@ -116,7 +116,7 @@ genvar ~SYM[1]; ~GENERATE for (~SYM[1]=0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : concat_~SYM[2]- assign ~RESULT[(~SYM[5] * $size(~SYM[0][0])) : ((~SYM[5] * $size(~SYM[0][0])) + $high(~SYM[0][0]))] = ~SYM[0][~SYM[1]];+ assign ~RESULT[(~SYM[1] * $size(~SYM[0][0])) : ((~SYM[1] * $size(~SYM[0][0])) + $high(~SYM[0][0]))] = ~SYM[0][~SYM[1]]; end ~ENDGENERATE // concat end"@@ -158,26 +158,6 @@ } } , { "BlackBox" :- { "name" : "CLaSH.Sized.Vector.merge"- , "type" : "merge :: Vec n a -> Vec n a -> Vec (n + n) a"- , "templateD" :-"// merge begin-~SIGD[~SYM[0]][0];-~SIGD[~SYM[1]][1];-assign ~SYM[0] = ~ARG[0];-assign ~SYM[1] = ~ARG[1];--genvar ~SYM[2];-~GENERATE- for (~SYM[2] = 0; ~SYM[2] < $size(~SYM[0]); ~SYM[2] = ~SYM[2] + 1) begin : merge_~SYM[3]- assign ~RESULT[2*~SYM[2]] = ~SYM[0][~SYM[2]];- assign ~RESULT[2*~SYM[2]+1] = ~SYM[1][~SYM[2]];- end-~ENDGENERATE-// merge end"- }- }-, { "BlackBox" : { "name" : "CLaSH.Sized.Vector.map" , "type" : "map :: (a -> b) -> Vec n a -> Vec n b" , "templateD" :@@ -198,6 +178,29 @@ } } , { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.imap"+ , "type" : "imap :: KnownNat n => (Index n -> a -> b) -> Vec n a -> Vec n b"+ , "templateD" :+"// imap begin+~SIGD[~SYM[0]][2];+assign ~SYM[0] = ~ARG[2];++genvar ~SYM[1];+~GENERATE+ for (~SYM[1]=0; ~SYM[1] < $size(~RESULT); ~SYM[1] = ~SYM[1] + 1) begin : map_~SYM[2]+ logic [~SIZE[~INDEXTYPE[~LIT[0]]]-1:0] ~SYM[3];+ assign ~SYM[3] = ~SYM[1];+ ~INST 1+ ~OUTPUT <= ~RESULT[~SYM[1]]~ ~TYPEL[~TYPO]~+ ~INPUT <= ~SYM[3]~ ~INDEXTYPE[~LIT[0]]~+ ~INPUT <= ~SYM[0][~SYM[1]]~ ~TYPEL[~TYP[2]]~+ ~INST+ end+~ENDGENERATE+// imap end"+ }+ }+, { "BlackBox" : { "name" : "CLaSH.Sized.Vector.zipWith" , "type" : "zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c" , "templateD" :@@ -221,6 +224,78 @@ } } , { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.foldr"+ , "type" : "foldr :: (a -> b -> b) -> b -> Vec n a -> b"+ , "templateD" :+"// foldr start~IF ~LENGTH[~TYP[2]] ~THEN+~SIGDO[intermediate_~SYM[0]] [0:~LENGTH[~TYP[2]]];+assign intermediate_~SYM[0][~LENGTH[~TYP[2]]] = ~ARG[1];++~SIGD[xs_~SYM[2]][2];+assign xs_~SYM[2] = ~ARG[2];++genvar i_~SYM[3];+~GENERATE+for (i_~SYM[3]=0; i_~SYM[3] < ~LENGTH[~TYP[2]]; i_~SYM[3]=i_~SYM[3]+1) begin : foldr_loop+ ~INST 0+ ~OUTPUT <= intermediate_~SYM[0][i_~SYM[3]]~ ~TYP[1]~+ ~INPUT <= xs_~SYM[2][i_~SYM[3]]~ ~TYPEL[~TYP[2]]~+ ~INPUT <= intermediate_~SYM[0][i_~SYM[3]+1]~ ~TYP[1]~+ ~INST+end+~ENDGENERATE++assign ~RESULT = intermediate_~SYM[0][0];+~ELSE+assign ~RESULT = ~ARG[1];+~FI// foldr end"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.fold"+ , "type" : "fold :: (a -> a -> a) -> Vec (n+1) a -> a"+ , "comment" : "THIS ONLY WORKS FOR POWER OF TWO LENGTH VECTORS"+ , "templateD" :+"// fold begin+// put flat input array into the first half of the intermediate array+~SIGDO[intermediate_~SYM[0]][0:(2*~LENGTH[~TYP[1]])-2];+assign intermediate_~SYM[0][0:~LENGTH[~TYP[1]]-1] = ~ARG[1];++// calculate the depth of the tree+localparam levels_~SYM[4] = $clog2(~LENGTH[~TYP[1]]);++// given a level and a depth, calculate the corresponding index into the+// intermediate array+function integer depth2Index_~SYM[8];+ input integer levels;+ input integer depth;++ depth2Index_~SYM[8] = (2 ** levels) - (2 ** depth);+endfunction++// Create the tree of instantiated components+genvar d_~SYM[5];+genvar i_~SYM[6];+~GENERATE+if (levels_~SYM[4] != 0) begin : make_tree_~SYM[7]+ for (d_~SYM[5] = (levels_~SYM[4] - 1); d_~SYM[5] >= 0; d_~SYM[5]=d_~SYM[5]-1) begin : tree_depth+ for (i_~SYM[6] = 0; i_~SYM[6] < (2**d_~SYM[5]); i_~SYM[6] = i_~SYM[6]+1) begin : tree_depth_loop+ ~INST 0+ ~OUTPUT <= intermediate_~SYM[0][depth2Index_~SYM[8](levels_~SYM[4]+1,d_~SYM[5]+1)+i_~SYM[6]]~ ~TYPO~+ ~INPUT <= intermediate_~SYM[0][depth2Index_~SYM[8](levels_~SYM[4]+1,d_~SYM[5]+2)+(2*i_~SYM[6])]~ ~TYPO~+ ~INPUT <= intermediate_~SYM[0][depth2Index_~SYM[8](levels_~SYM[4]+1,d_~SYM[5]+2)+(2*i_~SYM[6])+1]~ ~TYPO~+ ~INST+ end+ end+end+~ENDGENERATE++// The last element of the intermediate array holds the result+assign ~RESULT = intermediate_~SYM[0][(2*~LENGTH[~TYP[1]])-2];+// fold end"+ }+ }+, { "BlackBox" : { "name" : "CLaSH.Sized.Vector.index_int" , "type" : "index_integer :: KnownNat n => Vec n a -> Int -> a" , "templateD" :@@ -266,6 +341,26 @@ { "name" : "CLaSH.Sized.Vector.replicate" , "type" : "replicate :: SNat n -> a -> Vec n a" , "templateE" : "'{~LIT[0] {~ARG[1]}}"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.transpose"+ , "type" : "transpose :: KnownNat n => Vec m (Vec n a) -> Vec n (Vec m a)"+ , "templateD" :+"// transpose begin+~SIGD[~SYM[0]][1];+assign ~SYM[0] = ~ARG[1];++genvar ~SYM[1];+genvar ~SYM[2];+~GENERATE+ for (~SYM[1] = 0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : transpose_outer_~SYM[3]+ for (~SYM[2] = 0; ~SYM[2] < $size(~RESULT); ~SYM[2] = ~SYM[2] + 1) begin : transpose_inner_~SYM[4]+ assign ~RESULT[~SYM[2]][~SYM[1]] = ~SYM[0][~SYM[1]][~SYM[2]];+ end+ end+~ENDGENERATE+// transpose end" } } , { "BlackBox" :
src/CLaSH/Backend/SystemVerilog.hs view
@@ -336,6 +336,9 @@ expr_ _ (Identifier id_ (Just _)) = text id_ +expr_ _ (DataCon (Vector 0 _) _ _) =+ error $ $(curLoc) ++ "SystemVerilog: Trying to create a Nil vector."+ expr_ _ (DataCon (Vector 1 _) _ [e]) = "'" <> braces (expr_ False e) expr_ _ e@(DataCon (Vector n _) _ [e1,e2]) = "'" <> case vectorChain e of Just es -> listBraces (mapM (expr_ False) es)@@ -407,7 +410,15 @@ vectorChain _ = Nothing exprLit :: Maybe (HWType,Size) -> Literal -> SystemVerilogM Doc-exprLit Nothing (NumLit i) = integer i+exprLit Nothing (NumLit i) =+ let integerLow = -2^(31 :: Integer) :: Integer+ integerHigh = 2^(31 :: Integer) - 1 :: Integer+ i' = if i < integerLow+ then integerLow+ else if i > integerHigh+ then integerHigh+ else i+ in parenIf (i' < 0) (integer i') exprLit (Just (hty,sz)) (NumLit i) = case hty of Unsigned _ -> int sz <> "'d" <> integer i Signed _