clash-vhdl (empty) → 0.5
raw patch · 31 files changed
+2849/−0 lines, 31 filesdep +basedep +clash-libdep +clash-preludesetup-changed
Dependencies added: base, clash-lib, clash-prelude, fgl, lens, mtl, text, unordered-containers, wl-pprint-text
Files
- CHANGELOG.md +4/−0
- LICENSE +22/−0
- README.md +5/−0
- Setup.hs +2/−0
- clash-vhdl.cabal +79/−0
- primitives/CLaSH.Driver.TestbenchGen.json +48/−0
- primitives/CLaSH.GHC.GHC2Core.json +16/−0
- primitives/CLaSH.Prelude.BlockRam.json +34/−0
- primitives/CLaSH.Prelude.Testbench.json +37/−0
- primitives/CLaSH.Promoted.Nat.json +13/−0
- primitives/CLaSH.Promoted.Symbol.json +13/−0
- primitives/CLaSH.Signal.Bundle.json +6/−0
- primitives/CLaSH.Signal.Explicit.json +11/−0
- primitives/CLaSH.Signal.Internal.json +86/−0
- primitives/CLaSH.Sized.Internal.BitVector.json +469/−0
- primitives/CLaSH.Sized.Internal.Index.json +91/−0
- primitives/CLaSH.Sized.Internal.Signed.json +232/−0
- primitives/CLaSH.Sized.Internal.Unsigned.json +195/−0
- primitives/CLaSH.Sized.Vector.json +384/−0
- primitives/Control.Exception.Base.json +25/−0
- primitives/GHC.Base.json +37/−0
- primitives/GHC.CString.json +11/−0
- primitives/GHC.Classes.json +74/−0
- primitives/GHC.Err.json +13/−0
- primitives/GHC.Integer.Type.json +158/−0
- primitives/GHC.Prim.json +89/−0
- primitives/GHC.Real.json +19/−0
- primitives/GHC.Typelits.json +7/−0
- primitives/GHC.Types.json +11/−0
- primitives/Unsafe.Coerce.json +7/−0
- src/CLaSH/Backend/VHDL.hs +651/−0
+ CHANGELOG.md view
@@ -0,0 +1,4 @@+# Changelog for the [`clash-vhdl`](http://hackage.haskell.org/package/clash-vhdl) package++## 0.5 *March 11th 2015*+* Initial release
+ LICENSE view
@@ -0,0 +1,22 @@+Copyright (c) 2015, University of Twente+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,5 @@+# Support+For updates and questions join the mailing list clash-language+subscribe@googlegroups.com or read the [forum](https://groups.google.com/d/forum/clash-language)++# `clash-vhdl`+ * See the LICENSE file for license and copyright details
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ clash-vhdl.cabal view
@@ -0,0 +1,79 @@+Name: clash-vhdl+Version: 0.5+Synopsis: CAES Language for Synchronous Hardware - As a Library+Description:+ CλaSH (pronounced ‘clash’) is a functional hardware description language that+ borrows both its syntax and semantics from the functional programming language+ Haskell. The merits of using a functional language to describe hardware comes+ from the fact that combinational circuits can be directly modelled as+ mathematical functions and that functional languages lend themselves very well+ at describing and (de-)composing mathematical functions.+ .+ This package provides:+ .+ * VHDL Backend+Homepage: http://www.clash-lang.org/+bug-reports: http://github.com/clash-lang/clash-compiler/issues+License: BSD2+License-file: LICENSE+Author: Christiaan Baaij+Maintainer: Christiaan Baaij <christiaan.baaij@gmail.com>+Copyright: Copyright © 2015 University of Twente+Category: Hardware+Build-type: Simple++Extra-source-files: README.md,+ CHANGELOG.md++Data-files: primitives/CLaSH.Driver.TestbenchGen.json+ primitives/CLaSH.GHC.GHC2Core.json+ primitives/CLaSH.Prelude.BlockRam.json+ primitives/CLaSH.Prelude.Testbench.json+ primitives/CLaSH.Promoted.Nat.json+ primitives/CLaSH.Promoted.Symbol.json+ primitives/CLaSH.Signal.Bundle.json+ primitives/CLaSH.Signal.Explicit.json+ primitives/CLaSH.Signal.Internal.json+ primitives/CLaSH.Sized.Internal.BitVector.json+ primitives/CLaSH.Sized.Internal.Index.json+ primitives/CLaSH.Sized.Internal.Signed.json+ primitives/CLaSH.Sized.Internal.Unsigned.json+ primitives/CLaSH.Sized.Vector.json+ primitives/Control.Exception.Base.json+ primitives/GHC.Base.json+ primitives/GHC.Classes.json+ primitives/GHC.CString.json+ primitives/GHC.Err.json+ primitives/GHC.Integer.Type.json+ primitives/GHC.Prim.json+ primitives/GHC.Real.json+ primitives/GHC.Typelits.json+ primitives/GHC.Types.json+ primitives/Unsafe.Coerce.json++Cabal-version: >=1.10++source-repository head+ type: git+ location: https://github.com/clash-lang/clash-compiler.git++Library+ HS-Source-Dirs: src++ default-language: Haskell2010+ ghc-options: -Wall -fwarn-tabs+ CPP-Options: -DCABAL++ Build-depends: base >= 4.6.0.1 && < 5,+ clash-lib >= 0.5,+ clash-prelude >= 0.7,+ fgl >= 5.4.2.4,+ lens >= 3.9.2,+ mtl >= 2.1.2,+ text >= 0.11.3.1,+ unordered-containers >= 0.2.3.3,+ wl-pprint-text >= 1.1.0.0++ Exposed-modules: CLaSH.Backend.VHDL++ Other-modules: Paths_clash_vhdl
+ primitives/CLaSH.Driver.TestbenchGen.json view
@@ -0,0 +1,48 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Driver.TestbenchGen.clockGen"+ , "templateD" :+"-- pragma translate_off+process is+begin+ ~RESULT <= '0';+ wait for ~LIT[0] ns;+ while (not finished) loop+ ~RESULT <= not ~RESULT;+ wait for ~LIT[1] ns;+ ~RESULT <= not ~RESULT;+ wait for ~LIT[2] ns;+ end loop;+ wait;+end process;+-- pragma translate_on"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Driver.TestbenchGen.resetGen"+ , "templateD" :+"-- pragma translate_off+~RESULT <= '0',+ '1' after ~LIT[0] ns;+-- pragma translate_on"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Driver.TestbenchGen.doneGen"+ , "templateD" : "~RESULT <= ~ARG[0];"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Driver.TestbenchGen.finishedGen"+ , "templateD" :+"~RESULT <=+-- pragma translate_off+ false,+-- pragma translate_on+ true+-- pragma translate_off+ after ~LIT[0] ns+-- pragma translate_on+ ;"+ }+ }+]
+ primitives/CLaSH.GHC.GHC2Core.json view
@@ -0,0 +1,16 @@+[ { "BlackBox" :+ { "name" : "EmptyCase"+ , "templateE" : "~ERRORO"+ }+ }+, { "Primitive" :+ { "name" : "_CO_"+ , "primType" : "Constructor"+ }+ }+, { "Primitive" :+ { "name" : "_TY_"+ , "primType" : "Constructor"+ }+ }+]
+ primitives/CLaSH.Prelude.BlockRam.json view
@@ -0,0 +1,34 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Prelude.BlockRam.blockRam'"+ , "type" :+"blockRam' :: (KnownNat n, KnownNat m) -- (ARG[0],ARG[1])+ => SClock clk -- clk, ARG[2]+ -> Vec n a -- init, ARG[3]+ -> Signal' clk (Unsigned m) -- wr, ARG[4]+ -> Signal' clk (Unsigned m) -- rd, ARG[5]+ -> Signal' clk Bool -- wren, ARG[6]+ -> Signal' clk a -- din, ARG[7]+ -> Signal' clk a"+ , "templateD" :+"blockram_~SYM[0] : block+ signal ~SYM[1] : ~TYP[3] := ~LIT[3]; -- ram+ signal ~SYM[2] : ~TYP[7]; -- inp+ signal ~SYM[3] : ~TYP[7]; -- outp+begin+ ~SYM[2] <= ~ARG[7];++ process(~CLK[2])+ begin+ if rising_edge(~CLK[2]) then+ if ~ARG[6] then+ ~SYM[1](to_integer(~ARG[4])) <= ~SYM[2];+ end if;+ ~SYM[3] <= ~SYM[1](to_integer(~ARG[5]));+ end if;+ end process;++ ~RESULT <= ~SYM[3];+end block;"+ }+ }+]
+ primitives/CLaSH.Prelude.Testbench.json view
@@ -0,0 +1,37 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Prelude.Testbench.assert"+ , "type" :+"assert :: (Eq a,Show a) -- (ARG[0],ARG[1])+ => Signal' t a -- ^ Checked value (ARG[2])+ -> Signal' t a -- ^ Expected value (ARG[3])+ -> Signal' t b -- ^ Return valued (ARG[4])+ -> Signal' t b"+ , "templateD" :+"assert_~SYM[0] : block+ -- pragma translate_off+ function slv2string (slv : std_logic_vector) return STRING is+ variable result : string (1 to slv'length);+ variable r : integer;+ begin+ r := 1;+ for i in slv'range loop+ result(r) := std_logic'image(slv(i))(2);+ r := r + 1;+ end loop;+ return result;+ end;+ -- pragma translate_on+begin+ -- pragma translate_off+ process(~CLK[2],~RST[2],~ARG[2],~ARG[3]) is+ begin+ if (rising_edge(~CLK[2]) or rising_edge(~RST[2])) then+ assert (~ARG[2] = ~ARG[3]) report (\"expected: \" & slv2string(toSLV(~ARG[3])) & \", actual: \" & slv2string(toSLV(~ARG[2]))) severity error;+ end if;+ end process;+ -- pragma translate_on+ ~RESULT <= ~ARG[4];+end block;"+ }+ }+]
+ primitives/CLaSH.Promoted.Nat.json view
@@ -0,0 +1,13 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Promoted.Nat.SNat"+ , "type" : "SNat :: KnownNat n => Proxy n -> SNat n"+ , "templateE" : "~LIT[0]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Promoted.Nat.snatToInteger"+ , "type" : "snatToInteger :: SNat n -> Integer"+ , "templateE" : "~LIT[0]"+ }+ }+]
+ primitives/CLaSH.Promoted.Symbol.json view
@@ -0,0 +1,13 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Promoted.Symbol.SSymbol"+ , "type" : "SSymbol :: KnownNat n => Proxy n -> SSymbol n"+ , "templateE" : "~LIT[0]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Promoted.Symbol.symbolToString"+ , "type" : "symbolToString :: SSymbol n -> String"+ , "templateE" : "~LIT[0]"+ }+ }+]
+ primitives/CLaSH.Signal.Bundle.json view
@@ -0,0 +1,6 @@+[ { "Primitive" :+ { "name" : "CLaSH.Signal.Bundle.vecBundle#"+ , "primType" : "Function"+ }+ }+]
+ primitives/CLaSH.Signal.Explicit.json view
@@ -0,0 +1,11 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Signal.Explicit.unsafeSynchronizer"+ , "type" :+"unsafeSynchronizer :: SClock clk1+ -> SClock clk2+ -> Signal' clk1 a -- ARG[2]+ -> Signal' clk2 a"+ , "templateE" : "~ARG[2]"+ }+ }+]
+ primitives/CLaSH.Signal.Internal.json view
@@ -0,0 +1,86 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Signal.Internal.register#"+ , "type" :+"register# :: SClock clk -- ARG[0]+ -> a -- ARG[1]+ -> Signal' clk a -- ARG[2]+ -> Signal' clk a"+ , "templateD" :+"register_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+ signal ~SYM[2] : ~TYP[2];+begin+ ~SYM[1] <= ~ARG[1];++ process(~CLK[0],~RST[0],~SYM[1])+ begin+ if ~RST[0] = '0' then+ ~SYM[2] <= ~SYM[1];+ elsif rising_edge(~CLK[0]) then+ ~SYM[2] <= ~ARG[2];+ end if;+ end process;++ ~RESULT <= ~SYM[2];+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Signal.Internal.regEn#"+ , "type" :+"regEn# :: SClock clk -- ARG[0]+ -> a -- ARG[1]+ -> Signal' clk Bool -- ARG[2]+ -> Signal' clk a -- ARG[3]+ -> Signal' clk a"+ , "templateD" :+"regEn_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+ signal ~SYM[2] : ~TYP[2];+ signal ~SYM[3] : ~TYP[3];+begin+ ~SYM[1] <= ~ARG[1];+ ~SYM[2] <= ~ARG[2];++ process(~CLK[0],~RST[0],~SYM[1],~SYM[2])+ begin+ if ~RST[0] = '0' then+ ~SYM[3] <= ~SYM[1];+ elsif rising_edge(~CLK[0]) then+ if ~SYM[2] then+ ~SYM[3] <= ~ARG[3];+ end if;+ end if;+ end process;++ ~RESULT <= ~SYM[3];+end block;"+ }+ }++, { "Primitive" :+ { "name" : "CLaSH.Signal.Internal.signal#"+ , "primType" : "Function"+ }+ }+, { "Primitive" :+ { "name" : "CLaSH.Signal.Internal.mapSignal#"+ , "primType" : "Function"+ }+ }+, { "Primitive" :+ { "name" : "CLaSH.Signal.Internal.appSignal#"+ , "primType" : "Function"+ }+ }+, { "Primitive" :+ { "name" : "CLaSH.Signal.Internal.foldr#"+ , "primType" : "Function"+ }+ }+, { "Primitive" :+ { "name" : "CLaSH.Signal.Internal.traverse#"+ , "primType" : "Function"+ }+ }+]
+ primitives/CLaSH.Sized.Internal.BitVector.json view
@@ -0,0 +1,469 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.size#"+ , "type" : "size# :: KnownNat n => BitVector n -> Int"+ , "templateE" : "~LIT[0]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.maxIndex#"+ , "type" : "maxIndex# :: KnownNat n => BitVector n -> Int"+ , "templateE" : "~LIT[0] - 1"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.high"+ , "type" : "high :: Bit"+ , "templateE" : "\"1\""+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.low"+ , "type" : "low :: Bit"+ , "templateE" : "\"0\""+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.++#"+ , "type" : "(++#) :: KnownNat m => BitVector n -> BitVector m -> BitVector (n + m)"+ , "templateE" : "std_logic_vector'(~ARG[1]) & std_logic_vector'(~ARG[2])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.reduceAnd#"+ , "type" : "reduceAnd# :: KnownNat n => BitVector n -> BitVector 1"+ , "templateD" :+"reduceAnd_~SYM[0] : block+ function and_reduce (arg : std_logic_vector) return std_logic is+ variable upper, lower : std_logic;+ variable half : integer;+ variable argi : std_logic_vector (arg'length - 1 downto 0);+ variable result : std_logic;+ begin+ if (arg'length < 1) then+ result := '1';+ else+ argi := arg;+ if (argi'length = 1) then+ result := argi(argi'left);+ else+ half := (argi'length + 1) / 2; -- lsb-biased tree+ upper := and_reduce (argi (argi'left downto half));+ lower := and_reduce (argi (half - 1 downto argi'right));+ result := upper and lower;+ end if;+ end if;+ return result;+ end;+begin+ ~RESULT <= (0 => and_reduce(~ARG[1]));+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.reduceOr#"+ , "type" : "reduceOr# :: BitVector n -> BitVector 1"+ , "templateD" :+"reduceOr_~SYM[0] : block+ function or_reduce (arg : std_logic_vector) return std_logic is+ variable upper, lower : std_logic;+ variable half : integer;+ variable argi : std_logic_vector (arg'length - 1 downto 0);+ variable result : std_logic;+ begin+ if (arg'length < 1) then+ result := '0';+ else+ argi := arg;+ if (argi'length = 1) then+ result := argi(argi'left);+ else+ half := (argi'length + 1) / 2; -- lsb-biased tree+ upper := or_reduce (argi (argi'left downto half));+ lower := or_reduce (argi (half - 1 downto argi'right));+ result := upper or lower;+ end if;+ end if;+ return result;+ end;+begin+ ~RESULT <= (0 => or_reduce(~ARG[0]));+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.reduceXor#"+ , "type" : "reduceXor# :: BitVector n -> BitVector 1"+ , "templateD" :+"reduceXor_~SYM[0] : block+ function xor_reduce (arg : std_logic_vector) return std_logic is+ variable upper, lower : std_logic;+ variable half : integer;+ variable argi : std_logic_vector (arg'length - 1 downto 0);+ variable result : std_logic;+ begin+ if (arg'length < 1) then+ result := '0';+ else+ argi := arg;+ if (argi'length = 1) then+ result := argi(argi'left);+ else+ half := (argi'length + 1) / 2; -- lsb-biased tree+ upper := xor_reduce (argi (argi'left downto half));+ lower := xor_reduce (argi (half - 1 downto argi'right));+ result := upper xor lower;+ end if;+ end if;+ return result;+ end;+begin+ ~RESULT <= (0 => xor_reduce(~ARG[0]));+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.index#"+ , "type" :+"index# :: KnownNat n -- ARG[0]+ => BitVector n -- ARG[1]+ -> Int -- ARG[2]+ -> Bit"+ , "templateD" :+"indexBit_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+ signal ~SYM[2] : ~TYP[2];+begin+ ~SYM[1] <= ~ARG[1];+ ~SYM[2] <= ~ARG[2];+ -- pragma translate_off+ process (~SYM[1],~SYM[2])+ begin+ if ~SYM[2] < ~SYM[1]'low or ~SYM[2] > ~SYM[1]'high then+ assert false report (\"Index: \" & integer'image(~SYM[2]) & \", is out of bounds: \" & integer'image(~SYM[1]'low) & \" downto \" & integer'image(~SYM[1]'high)) severity warning;+ ~RESULT <= ~ERRORO;+ else+ -- pragma translate_on+ ~RESULT <= ~SYM[1](~SYM[2] downto ~SYM[2]);+ -- pragma translate_off+ end if;+ end process;+ -- pragma translate_on+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.replaceBit#"+ , "type" :+"replaceBit# :: KnownNat n -- ARG[0]+ => BitVector n -- ARG[1]+ -> Int -- ARG[2]+ -> Bit -- ARG[3]+ -> BitVector n"+ , "templateD" :+"replaceBit_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+ signal ~SYM[2] : ~TYP[2];+ signal ~SYM[3] : ~TYP[3];+begin+ ~SYM[1] <= ~ARG[1];+ ~SYM[2] <= ~ARG[2];+ ~SYM[3] <= ~ARG[3];+ process(~SYM[1],~SYM[2],~SYM[3])+ variable ~SYM[4] : ~TYP[1];+ begin+ ~SYM[4] := ~SYM[1];+ -- pragma translate_off+ if ~SYM[2] < ~SYM[4]'low or ~SYM[2] > ~SYM[4]'high then+ assert false report (\"Index: \" & integer'image(~SYM[2]) & \", is out of bounds: \" & integer'image(~SYM[1]'low) & \" downto \" & integer'image(~SYM[1]'high)) severity warning;+ ~SYM[4] := ~ERROR[1];+ else+ -- pragma translate_on+ ~SYM[4](~SYM[2] downto ~SYM[2]) := ~SYM[3];+ -- pragma translate_off+ end if;+ -- pragma translate_on+ ~RESULT <= ~SYM[4];+ end process;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.setSlice#"+ , "type" :+"setSlice# :: BitVector (m + 1 + i) -- ARG[0]+ -> SNat m -- ARG[1]+ -> SNat n -- ARG[2]+ -> BitVector (m + 1 - n) -- ARG[3]+ -> BitVector (m + 1 + i)"+ , "templateD" :+"setSlice_~SYM[0] : block+ signal ~SYM[1] : ~TYP[0];+ signal ~SYM[2] : ~TYP[3];+begin+ ~SYM[1] <= ~ARG[0];+ ~SYM[2] <= ~ARG[3];+ process(~SYM[1],~SYM[2])+ variable ~SYM[3] : ~TYP[0];+ begin+ ~SYM[3] := ~SYM[1];+ ~SYM[3](~LIT[1] downto ~LIT[2]) := ~SYM[2];+ ~RESULT <= ~SYM[3];+ end process;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.slice#"+ , "type" :+"slice# :: BitVector (m + 1 + i) -- ARG[0]+ -> SNat m -- ARG[1]+ -> SNat n -- ARG[2]+ -> BitVector (m + 1 - n)"+ , "templateD" :+"slice_~SYM[0] : block+ signal ~SYM[1] : ~TYP[0];+begin+ ~SYM[1] <= ~ARG[0];+ ~RESULT <= ~SYM[1](~LIT[1] downto ~LIT[2]);+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.split#"+ , "type" :+"split# :: KnownNat n -- ARG[0]+ => BitVector (m + n) -- ARG[1]+ -> (BitVector m, BitVector n)"+ , "templateD" :+"split_~SYM[0]: block+ signal ~SYM[1] : ~TYP[1];+begin+ ~SYM[1] <= ~ARG[1];+ ~RESULT <= ( ~SYM[1](~RESULT.~TYPMO_sel0'left + ~RESULT.~TYPMO_sel1'length downto+ ~RESULT.~TYPMO_sel0'right + ~RESULT.~TYPMO_sel1'length)+ , ~SYM[1](~RESULT.~TYPMO_sel1'left downto ~RESULT.~TYPMO_sel1'right)+ );+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.msb#"+ , "type" :+"msb# :: KnownNat n -- ARG[0]+ => BitVector n -- ARG[1]+ -> Bit"+ , "templateD" :+"msb_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+begin+ ~SYM[2]_generate : if ~SYM[1]'length = 0 generate+ begin+ ~RESULT <= \"0\";+ end generate;++ ~SYM[3]_generate : if ~SYM[1]'length /= 0 generate+ ~SYM[1] <= ~ARG[1];+ ~RESULT <= ~SYM[1](~SYM[1]'high downto ~SYM[1]'high);+ end generate;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.lsb#"+ , "type" :+"lsb# :: BitVector n -- ARG[0]+ -> Bit"+ , "templateD" :+"lsb_~SYM[0] : block+ signal ~SYM[1] : ~TYP[0];+begin+ ~SYM[2]_generate : if ~SYM[1]'length = 0 generate+ begin+ ~RESULT <= \"0\";+ end generate;++ ~SYM[3]_generate : if ~SYM[1]'length /= 0 generate+ begin+ ~SYM[1] <= ~ARG[0];+ ~RESULT <= ~SYM[1](0 downto 0);+ end generate;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.eq#"+ , "type" : "eq# :: BitVector n -> BitVector n -> Bool"+ , "templateE" : "~ARG[0] = ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.neq#"+ , "type" : "neq# :: BitVector n -> BitVector n -> Bool"+ , "templateE" : "~ARG[0] /= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.lt#"+ , "type" : "lt# :: BitVector n -> BitVector n -> Bool"+ , "templateE" : "~ARG[0] < ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.ge#"+ , "type" : "ge# :: BitVector n -> BitVector n -> Bool"+ , "templateE" : "~ARG[0] >= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.gt#"+ , "type" : "gt# :: BitVector n -> BitVector n -> Bool"+ , "templateE" : "~ARG[0] > ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.le#"+ , "type" : "le# :: BitVector n -> BitVector n -> Bool"+ , "templateE" : "~ARG[0] <= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.minBound#"+ , "type" : "minBound# :: KnownNat n => BitVector n"+ , "comment" : "Generates incorrect VDHL for n=0"+ , "templateE" : "std_logic_vector'(~LIT[0]-1 downto 0 => '0');"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.maxBound#"+ , "type" : "maxBound# :: KnownNat n => BitVector n"+ , "comment" : "Generates incorrect VDHL for n=0"+ , "templateE" : "std_logic_vector'(~LIT[0]-1 downto 0 => '1');"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.+#"+ , "type" : "(+#) :: KnownNat n => BitVector n -> BitVector n -> BitVector n"+ , "templateE" : "std_logic_vector(unsigned(~ARG[1]) + unsigned(~ARG[2]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.-#"+ , "type" : "(-#) :: KnownNat n => BitVector n -> BitVector n -> BitVector n"+ , "templateE" : "std_logic_vector(unsigned(~ARG[1]) - unsigned(~ARG[2]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.*#"+ , "type" : "(*#) :: KnownNat n => BitVector n -> BitVector n -> BitVector n"+ , "templateE" : "std_logic_vector(resize(unsigned(~ARG[1]) * unsigned(~ARG[2]), ~LIT[0]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.negate#"+ , "type" : "negate# :: KnownNat n => BitVector n -> BitVector n"+ , "templateE" : "std_logic_vector(-(signed(~ARG[1])))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.fromInteger#"+ , "type" : "fromInteger# :: KnownNat n => Integer -> BitVector n"+ , "templateE" : "std_logic_vector(to_unsigned(~ARG[1],~LIT[0]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.plus#"+ , "type" : "plus# :: KnownNat (Max m n + 1) => BitVector m -> BitVector n -> BitVector (Max m n + 1)"+ , "templateE" : "std_logic_vector(resize(unsigned(~ARG[1]),~LIT[0]) + resize(unsigned(~ARG[2]),~LIT[0]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.minus#"+ , "type" : "minus# :: KnownNat (Max m n + 1) => BitVector m -> BitVector n -> BitVector (Max m n + 1)"+ , "templateE" : "std_logic_vector(resize(unsigned(~ARG[1]),~LIT[0]) - resize(unsigned(~ARG[2]),~LIT[0]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.times#"+ , "type" : "times# :: KnownNat (m + n) => BitVector m -> BitVector n -> BitVector (m + n)"+ , "templateE" : "std_logic_vector(unsigned(~ARG[1]) * unsigned(~ARG[2]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.quot#"+ , "type" : "quot# :: BitVector n -> BitVector n -> BitVector n"+ , "templateE" : "std_logic_vector(unsigned(~ARG[1]) / unsigned(~ARG[2]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.rem#"+ , "type" : "rem# :: BitVector n -> BitVector n -> BitVector n"+ , "templateE" : "~ARG[1] rem ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.mod#"+ , "type" : "mod# :: BitVector n -> BitVector n -> BitVector n"+ , "templateE" : "~ARG[1] mod ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.toInteger#"+ , "type" : "toInteger# :: BitVector n -> Integer"+ , "templateE" : "to_integer(unsigned(~ARG[0]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.and#"+ , "type" : "and# :: BitVector n -> BitVector n -> BitVector n"+ , "templateE" : "~ARG[0] and ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.or#"+ , "type" : "or# :: BitVector n -> BitVector n -> BitVector n"+ , "templateE" : "~ARG[0] or ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.xor#"+ , "type" : "xor# :: BitVector n -> BitVector n -> BitVector n"+ , "templateE" : "~ARG[0] xor ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.complement#"+ , "type" : "complement# :: KnownNat n => BitVector n -> BitVector n"+ , "templateE" : "not ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.shiftL#"+ , "type" : "shiftL# :: KnownNat n => BitVector n -> Int -> BitVector n"+ , "templateE" : "std_logic_vector(shift_left(unsigned(~ARG[1]),~ARG[2]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.shiftR#"+ , "type" : "shiftR# :: KnownNat n => BitVector n -> Int -> BitVector n"+ , "templateE" : "std_logic_vector(shift_right(unsigned(~ARG[1]),~ARG[2]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.rotateL#"+ , "type" : "rotateL# :: KnownNat n => BitVector n -> Int -> BitVector n"+ , "templateE" : "std_logic_vector(rotate_left(unsigned(~ARG[1]),~ARG[2]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.rotateR#"+ , "type" : "rotateR# :: KnownNat n => BitVector n -> Int -> BitVector n"+ , "templateE" : "std_logic_vector(rotate_right(unsigned(~ARG[1]),~ARG[2]))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.BitVector.resize#"+ , "type" : "resize# :: KnownNat m => BitVector n -> BitVector m"+ , "templateE" : "std_logic_vector(resize(unsigned(~ARG[1]),~LIT[0]))"+ }+ }+]
+ primitives/CLaSH.Sized.Internal.Index.json view
@@ -0,0 +1,91 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.eq#"+ , "type" : "eq# :: Index n -> Index n -> Bool"+ , "templateE" : "~ARG[0] = ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.neq#"+ , "type" : "neq# :: Index n -> Index n -> Bool"+ , "templateE" : "~ARG[0] /= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.lt#"+ , "type" : "lt# :: Index n -> Index n -> Bool"+ , "templateE" : "~ARG[0] < ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.ge#"+ , "type" : "ge# :: Index n -> Index n -> Bool"+ , "templateE" : "~ARG[0] >= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.gt#"+ , "type" : "gt# :: Index n -> Index n -> Bool"+ , "templateE" : "~ARG[0] > ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.le#"+ , "type" : "le# :: Index n -> Index n -> Bool"+ , "templateE" : "~ARG[0] <= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.maxBound#"+ , "type" : "maxBound# :: KnownNat n => Index n"+ , "templateE" : "to_unsigned(max(0,~LIT[0]-1),~RESULT'length);"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.+#"+ , "type" : "(+#) :: KnownNat n => Index n -> Index n -> Index n"+ , "templateE" : "~ARG[1] + ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.-#"+ , "type" : "(-#) :: KnownNat n => Index n -> Index n -> Index n"+ , "templateE" : "~ARG[1] - ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.*#"+ , "type" : "(*#) :: KnownNat n => Index n -> Index n -> Index n"+ , "templateE" : "resize(~ARG[1] * ~ARG[2], ~LIT[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.fromInteger#"+ , "type" : "fromInteger# :: KnownNat n => Integer -> Index n"+ , "templateE" : "to_unsigned(~ARG[1],integer(ceil(log2(real(max(2,~LIT[0]))))))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.quot#"+ , "type" : "quot# :: KnownNat n => Index n -> Index n -> Index n"+ , "templateE" : "~ARG[1] / ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.rem#"+ , "type" : "rem# :: KnownNat n => Index n -> Index n -> Index n"+ , "templateE" : "~ARG[1] rem ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.mod#"+ , "type" : "mod# :: KnownNat n => Index n -> Index n -> Index n"+ , "templateE" : "~ARG[1] mod ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Index.toInteger#"+ , "type" : "toInteger# :: Index n -> Integer"+ , "templateE" : "to_integer(~ARG[0])"+ }+ }+]
+ primitives/CLaSH.Sized.Internal.Signed.json view
@@ -0,0 +1,232 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Internal.Signed.size#"+ , "type" : "size# :: KnownNat n => Signed n -> Int"+ , "templateE" : "~LIT[0]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.pack#"+ , "type" : "pack# :: KnownNat n => Signed n -> BitVector n"+ , "templateE" : "std_logic_vector(~ARG[1])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.unpack#"+ , "type" : "unpack# :: KnownNat n => BitVector n -> Signed n"+ , "templateE" : "signed(~ARG[1])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.eq#"+ , "type" : "eq# :: Signed n -> Signed n -> Bool"+ , "templateE" : "~ARG[0] = ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.neq#"+ , "type" : "neq# :: Signed n -> Signed n -> Bool"+ , "templateE" : "~ARG[0] /= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.lt#"+ , "type" : "lt# :: Signed n -> Signed n -> Bool"+ , "templateE" : "~ARG[0] < ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.ge#"+ , "type" : "ge# :: Signed n -> Signed n -> Bool"+ , "templateE" : "~ARG[0] >= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.gt#"+ , "type" : "gt# :: Signed n -> Signed n -> Bool"+ , "templateE" : "~ARG[0] > ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.le#"+ , "type" : "le# :: Signed n -> Signed n -> Bool"+ , "templateE" : "~ARG[0] <= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.minBound#"+ , "type" : "minBound# :: KnownNat n => Signed n"+ , "comment" : "Generates incorrect VDHL for n=0"+ , "comment2" : "the quantification with signed gives the array an ascending index"+ , "templateE" : "signed'(0 => '1', 1 to ~LIT[0]-1 => '0')"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.maxBound#"+ , "type" : "maxBound# :: KnownNat n => Signed n"+ , "comment" : "Generates incorrect VDHL for n=0"+ , "comment2" : "the quantification with signed gives the array an ascending index"+ , "templateE" : "signed'(0 => '0', 1 to ~LIT[0]-1 => '1')"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.+#"+ , "type" : "(+#) :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "templateE" : "~ARG[1] + ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.-#"+ , "type" : "(-#) :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "templateE" : "~ARG[1] - ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.*#"+ , "type" : "(*#) :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "templateE" : "resize(~ARG[1] * ~ARG[2], ~LIT[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.negate#"+ , "type" : "negate# :: KnownNat n => Signed n -> Signed n"+ , "templateE" : "-~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.abs#"+ , "type" : "abs# :: KnownNat n => Signed n -> Signed n"+ , "templateE" : "abs ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.fromInteger#"+ , "type" : "fromInteger# :: KnownNat n => Integer -> Signed (n :: Nat)"+ , "templateE" : "to_signed(~ARG[1],~LIT[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.plus#"+ , "type" : "plus# :: KnownNat (1 + Max m n) => Signed m -> Signed n -> Signed (1 + Max m n)"+ , "templateE" : "resize(~ARG[1],~LIT[0]) + resize(~ARG[2],~LIT[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.minus#"+ , "type" : "minus# :: KnownNat (1 + Max m n) => Signed m -> Signed n -> Signed (1 + Max m n)"+ , "templateE" : "resize(~ARG[1],~LIT[0]) - resize(~ARG[2],~LIT[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.times#"+ , "type" : "times# :: KnownNat (m + n) => Signed m -> Signed n -> Signed (m + n)"+ , "templateE" : "~ARG[1] * ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.quot#"+ , "type" : "quot# :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "templateE" : "~ARG[1] / ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.rem#"+ , "type" : "rem# :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "templateE" : "~ARG[1] rem ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.div#"+ , "type" : "div# :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "templateD" :+"divSigned_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+ signal ~SYM[2] : ~TYP[2];+ signal ~SYM[3] : ~TYP[1];+begin+ ~SYM[1] <= ~ARG[1];+ ~SYM[2] <= ~ARG[2];+ ~SYM[3] <= ~SYM[1] / ~SYM[2];+ ~RESULT <= ~SYM[3] - to_signed(1,~LIT[0]) when ~SYM[1](~SYM[1]'high) = not (~SYM[2](~SYM[2]'high)) else+ ~SYM[3];+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.mod#"+ , "type" : "mod# :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "templateE" : "~ARG[1] mod ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.toInteger#"+ , "type" : "toInteger# :: Signed n -> Integer"+ , "templateE" : "to_integer(~ARG[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.and#"+ , "type" : "and# :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "templateE" : "~ARG[1] and ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.or#"+ , "type" : "or# :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "templateE" : "~ARG[1] or ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.xor#"+ , "type" : "xor# :: KnownNat n => Signed n -> Signed n -> Signed n"+ , "templateE" : "~ARG[1] xor ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.complement#"+ , "type" : "complement# :: KnownNat n => Signed n -> Signed n"+ , "templateE" : "not ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.shiftL#"+ , "type" : "shiftL# :: KnownNat n => Signed n -> Int -> Signed n"+ , "templateE" : "shift_left(~ARG[1],~ARG[2])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.shiftR#"+ , "type" : "shiftR# :: KnownNat n => Signed n -> Int -> Signed n"+ , "templateE" : "shift_right(~ARG[1],~ARG[2])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.rotateL#"+ , "type" : "rotateL# :: KnownNat n => Signed n -> Int -> Signed n"+ , "templateE" : "rotate_left(~ARG[1],~ARG[2])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.rotateR#"+ , "type" : "rotateR# :: KnownNat n => Signed n -> Int -> Signed n"+ , "templateE" : "rotate_right(~ARG[1],~ARG[2])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.resize#"+ , "type" : "resize# :: (KnownNat n, KnownNat m) => Signed n -> Signed m"+ , "templateE" : "resize(~ARG[2],~LIT[1])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Signed.truncateB#"+ , "type" : "truncateB# :: KnownNat m => Signed (n + m) -> Signed m"+ , "templateD" :+"truncateB_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+begin+ ~SYM[1] <= ~ARG[1];+ ~RESULT <= ~SYM[1](~LIT[0]-1 downto 0);+end block;"+ }+ }+]
+ primitives/CLaSH.Sized.Internal.Unsigned.json view
@@ -0,0 +1,195 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.size#"+ , "type" : "size# :: KnownNat n => Unsigned n -> Int"+ , "templateE" : "~LIT[0]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.pack#"+ , "type" : "pack# :: Unsigned n -> BitVector n"+ , "templateE" : "std_logic_vector(~ARG[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.unpack#"+ , "type" : "unpack# :: BitVector n -> Unsigned n"+ , "templateE" : "unsigned(~ARG[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.eq#"+ , "type" : "eq# :: Unsigned n -> Unsigned n -> Bool"+ , "templateE" : "~ARG[0] = ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.neq#"+ , "type" : "neq# :: Unsigned n -> Unsigned n -> Bool"+ , "templateE" : "~ARG[0] /= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.lt#"+ , "type" : "lt# :: Unsigned n -> Unsigned n -> Bool"+ , "templateE" : "~ARG[0] < ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.ge#"+ , "type" : "ge# :: Unsigned n -> Unsigned n -> Bool"+ , "templateE" : "~ARG[0] >= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.gt#"+ , "type" : "gt# :: Unsigned n -> Unsigned n -> Bool"+ , "templateE" : "~ARG[0] > ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.le#"+ , "type" : "le# :: Unsigned n -> Unsigned n -> Bool"+ , "templateE" : "~ARG[0] <= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.minBound#"+ , "type" : "minBound# :: KnownNat n => Unsigned n"+ , "comment" : "Generates incorrect VDHL for n=0"+ , "templateE" : "unsigned'(~LIT[0]-1 downto 0 => '0');"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.maxBound#"+ , "type" : "maxBound# :: KnownNat n => Unsigned n"+ , "comment" : "Generates incorrect VDHL for n=0"+ , "templateE" : "unsigned'(~LIT[0]-1 downto 0 => '1');"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.+#"+ , "type" : "(+#) :: KnownNat n => Unsigned n -> Unsigned n -> Unsigned n"+ , "templateE" : "~ARG[1] + ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.-#"+ , "type" : "(-#) :: KnownNat n => Unsigned n -> Unsigned n -> Unsigned n"+ , "templateE" : "~ARG[1] - ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.*#"+ , "type" : "(*#) :: KnownNat n => Unsigned n -> Unsigned n -> Unsigned n"+ , "templateE" : "resize(~ARG[1] * ~ARG[2], ~LIT[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.negate#"+ , "type" : "negate# :: KnownNat n => Unsigned n -> Unsigned n"+ , "templateE" : "unsigned(std_logic_vector(-(signed(std_logic_vector(~ARG[1])))))"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.fromInteger#"+ , "type" : "fromInteger# :: KnownNat n => Integer -> Unsigned n"+ , "templateE" : "to_unsigned(~ARG[1],~LIT[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.plus#"+ , "type" : "plus# :: KnownNat (1 + Max m n) => Unsigned m -> Unsigned n -> Unsigned (1 + Max m n)"+ , "templateE" : "resize(~ARG[1],~LIT[0]) + resize(~ARG[2],~LIT[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.minus#"+ , "type" : "minus# :: KnownNat (1 + Max m n) => Unsigned m -> Unsigned n -> Unsigned (1 + Max m n)"+ , "templateE" : "resize(~ARG[1],~LIT[0]) - resize(~ARG[2],~LIT[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.times#"+ , "type" : "times# :: KnownNat (m + n) => Unsigned m -> Unsigned n -> Unsigned (m + n)"+ , "templateE" : "~ARG[1] * ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.quot#"+ , "type" : "quot# :: Unsigned n -> Unsigned n -> Unsigned n"+ , "templateE" : "~ARG[1] / ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.rem#"+ , "type" : "rem# :: Unsigned n -> Unsigned n -> Unsigned n"+ , "templateE" : "~ARG[1] rem ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.mod#"+ , "type" : "mod# :: Unsigned n -> Unsigned n -> Unsigned n"+ , "templateE" : "~ARG[1] mod ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.toInteger#"+ , "type" : "toInteger# :: Unsigned n -> Integer"+ , "templateE" : "to_integer(~ARG[0])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.and#"+ , "type" : "and# :: Unsigned n -> Unsigned n -> Unsigned n"+ , "templateE" : "~ARG[0] and ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.or#"+ , "type" : "or# :: Unsigned n -> Unsigned n -> Unsigned n"+ , "templateE" : "~ARG[0] or ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.xor#"+ , "type" : "xor# :: Unsigned n -> Unsigned n -> Unsigned n"+ , "templateE" : "~ARG[0] xor ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.complement#"+ , "type" : "complement# :: KnownNat n => Unsigned n -> Unsigned n"+ , "templateE" : "not ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.shiftL#"+ , "type" : "shiftL# :: KnownNat n => Unsigned n -> Int -> Unsigned n"+ , "templateE" : "shift_left(~ARG[1],~ARG[2])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.shiftR#"+ , "type" : "shiftR# :: KnownNat n => Unsigned n -> Int -> Unsigned n"+ , "templateE" : "shift_right(~ARG[1],~ARG[2])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.rotateL#"+ , "type" : "rotateL# :: KnownNat n => Unsigned n -> Int -> Unsigned n"+ , "templateE" : "rotate_left(~ARG[1],~ARG[2])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.rotateR#"+ , "type" : "rotateR# :: KnownNat n => Unsigned n -> Int -> Unsigned n"+ , "templateE" : "rotate_right(~ARG[1],~ARG[2])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Internal.Unsigned.resize#"+ , "type" : "resize# :: KnownNat m => Unsigned n -> Unsigned m"+ , "templateE" : "resize(~ARG[1],~LIT[0])"+ }+ }+]
+ primitives/CLaSH.Sized.Vector.json view
@@ -0,0 +1,384 @@+[ { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.eq#"+ , "type" : "eq# :: Eq a => Vec n a -> Vec n a -> Bool"+ , "templateE" : "~ARG[1] = ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.neq#"+ , "type" : "neq# :: Eq a => Vec n a -> Vec n a -> Bool"+ , "templateE" : "~ARG[1] /= ~ARG[2]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.head"+ , "type" : "head :: Vec (n + 1) a -> a"+ , "templateD" :+"head_~SYM[0] : block+ signal ~SYM[1] : ~TYP[0];+begin+ ~SYM[1] <= ~ARG[0];+ ~RESULT <= ~SYM[1](0);+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.tail"+ , "type" : "tail :: Vec (n + 1) a -> Vec n a"+ , "templateD" :+"tail_~SYM[0] : block+ signal ~SYM[1] : ~TYP[0];+begin+ ~SYM[1] <= ~ARG[0];+ ~RESULT <= ~SYM[1](1 to ~SYM[1]'high);+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.last"+ , "type" : "Vec (n + 1) a -> a"+ , "templateD" :+"last_~SYM[0] : block+ signal ~SYM[1] : ~TYP[0];+begin+ ~SYM[1] <= ~ARG[0];+ ~RESULT <= ~SYM[1](~SYM[1]'high);+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.init"+ , "type" : "Vec (n + 1) a -> Vec n a"+ , "templateD" :+"init_~SYM[0] : block+ signal ~SYM[1] : ~TYP[0];+begin+ ~SYM[1] <= ~ARG[0];+ ~RESULT <= ~SYM[1](0 to ~SYM[1]'high - 1);+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.select"+ , "type" :+"select :: (CmpNat (i + s) (s * n) ~ GT) -- ARG[0]+ => SNat f -- ARG[1]+ -> SNat s -- ARG[2]+ -> SNat n -- ARG[3]+ -> Vec i a -- ARG[4]+ -> Vec n a"+ , "templateD" :+"select_~SYM[0] : block+ signal ~SYM[1] : ~TYP[4];+begin+ ~SYM[1] <= ~ARG[4];++ selectZ_~SYM[2] : if ~RESULT'length = 0 generate+ ~RESULT <= ~ERRORO;+ end generate;++ selectSN_~SYM[3] : if ~RESULT'length /= 0 generate+ selectIter_~SYM[4] : for ~SYM[5] in ~RESULT'range generate+ begin+ ~RESULT(~SYM[5]) <= ~SYM[1](~LIT[1]+(~LIT[2]*~SYM[5]));+ end generate;+ end generate;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.++"+ , "type" : "(++) :: Vec n a -> Vec m a -> Vec (n + m) a"+ , "templateE" : "~TYPM[0]'(~ARG[0]) & ~TYPM[1]'(~ARG[1])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.concat"+ , "type" : "concat :: Vec n (Vec m a) -> Vec (n * m) a"+ , "templateD" :+"concat_~SYM[0] : block+ signal ~SYM[1] : ~TYP[0];+begin+ ~SYM[1] <= ~ARG[0];++ concatZ_~SYM[2] : if ~RESULT'length = 0 generate+ ~RESULT <= ~ERRORO;+ end generate;++ concatSN_~SYM[3] : if ~RESULT'length /= 0 generate+ concatIter_~SYM[4] : for ~SYM[5] in ~SYM[1]'range generate+ begin+ ~RESULT((~SYM[5] * ~SYM[1](0)'length) to ((~SYM[5] * ~SYM[1](0)'length) + ~SYM[1](0)'high)) <= ~SYM[1](~SYM[5]);+ end generate;+ end generate;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.splitAt"+ , "type" : "splitAt :: SNat m -> Vec (m + n) a -> (Vec m a, Vec n a)"+ , "templateD" :+"splitAt_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+begin+ ~SYM[1] <= ~ARG[1];+ ~RESULT <= (~SYM[1](~RESULT.~TYPMO_sel0'left to ~RESULT.~TYPMO_sel0'right)+ ,~SYM[1](~RESULT.~TYPMO_sel1'left + ~RESULT.~TYPMO_sel0'length to ~RESULT.~TYPMO_sel1'right + ~RESULT.~TYPMO_sel0'length));+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.unconcat"+ , "type" :+"unconcat :: KnownNat n -- ARG[0]+ => SNat m -- ARG[1]+ -> Vec (n * m) a -- ARG[2]+ -> Vec n (Vec m a)"+ , "templateD" :+"unconcat_~SYM[0] : block+ signal ~SYM[1] : ~TYP[2];+begin+ ~SYM[1] <= ~ARG[2];++ unconcatZ_~SYM[2] : if ~SYM[1]'length = 0 generate+ ~RESULT <= ~ERRORO;+ end generate;++ unconcatSN_~SYM[3] : if ~SYM[1]'length /= 0 generate+ unconcatIter_~SYM[4] : for ~SYM[5] in ~RESULT'range generate+ begin+ ~RESULT(~SYM[5]) <= ~SYM[1]((~SYM[5] * ~LIT[1]) to ((~SYM[5] * ~LIT[1]) + ~LIT[1] - 1));+ end generate;+ end generate;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.merge"+ , "type" : "merge :: Vec n a -> Vec n a -> Vec (n + n) a"+ , "templateD" :+"merge_~SYM[0] : block+ signal ~SYM[1] : ~TYP[0];+ signal ~SYM[2] : ~TYP[1];+begin+ ~SYM[1] <= ~ARG[0];+ ~SYM[2] <= ~ARG[1];++ mergeZ_~SYM[3] : if ~RESULT'length = 0 generate+ ~RESULT <= ~ERRORO;+ end generate;++ mergeSN_~SYM[4] : if ~RESULT'length /= 0 generate+ mergeIter_~SYM[5] : for ~SYM[6] in ~SYM[1]'range generate+ begin+ ~RESULT(2*~SYM[6]) <= ~SYM[1](~SYM[6]);+ ~RESULT(2*~SYM[6]+1) <= ~SYM[2](~SYM[6]);+ end generate;+ end generate;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.map"+ , "type" : "map :: (a -> b) -> Vec n a -> Vec n b"+ , "templateD" :+"map_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+begin+ ~SYM[1] <= ~ARG[1];++ mapZ_~SYM[2] : if ~RESULT'length = 0 generate+ ~RESULT <= ~ERRORO;+ end generate;++ mapSN_~SYM[3] : if ~RESULT'length /= 0 generate+ mapIter_~SYM[4] : for ~SYM[5] in ~RESULT'range generate+ begin+ ~INST 0+ ~OUTPUT <= ~RESULT(~SYM[5])~ ~TYPEL[~TYPO]~+ ~INPUT <= ~SYM[1](~SYM[5])~ ~TYPEL[~TYP[1]]~+ ~INST+ end generate;+ end generate;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.zipWith"+ , "type" : "zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c"+ , "templateD" :+"zipWith_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+ signal ~SYM[2] : ~TYP[2];+begin+ ~SYM[1] <= ~ARG[1];+ ~SYM[2] <= ~ARG[2];++ zipWithZ_~SYM[3] : if ~RESULT'length = 0 generate+ ~RESULT <= ~ERRORO;+ end generate;++ zipWithSN_~SYM[4] : if ~RESULT'length /= 0 generate+ zipWithIter_~SYM[5] : for ~SYM[6] in ~RESULT'range generate+ begin+ ~INST 0+ ~OUTPUT <= ~RESULT(~SYM[6])~ ~TYPEL[~TYPO]~+ ~INPUT <= ~SYM[1](~SYM[6])~ ~TYPEL[~TYP[1]]~+ ~INPUT <= ~SYM[2](~SYM[6])~ ~TYPEL[~TYP[2]]~+ ~INST+ end generate;+ end generate;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.index_int"+ , "type" : "index_int :: KnownNat n => Vec n a -> Int -> a"+ , "templateD" :+"indexVec_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+ signal ~SYM[2] : ~TYP[2];+begin+ ~SYM[1] <= ~ARG[1];+ ~SYM[2] <= ~ARG[2];+ -- pragma translate_off+ process (~SYM[1],~SYM[2])+ begin+ if ~SYM[2] < ~SYM[1]'low or ~SYM[2] > ~SYM[1]'high then+ assert false report (\"Index: \" & integer'image(~SYM[2]) & \", is out of bounds: \" & integer'image(~SYM[1]'low) & \" to \" & integer'image(~SYM[1]'high)) severity warning;+ ~RESULT <= ~ERRORO;+ else+ -- pragma translate_on+ ~RESULT <= ~SYM[1](~SYM[2]);+ -- pragma translate_off+ end if;+ end process;+ -- pragma translate_on+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.replace_int"+ , "type" : "replace_int :: KnownNat n => Vec n a -> Int -> a -> Vec n a"+ , "templateD" :+"replaceVec_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+ signal ~SYM[2] : ~TYP[2];+ signal ~SYM[3] : ~TYP[3];+begin+ ~SYM[1] <= ~ARG[1];+ ~SYM[2] <= ~ARG[2];+ ~SYM[3] <= ~ARG[3];+ process(~SYM[1],~SYM[2],~SYM[3])+ variable ~SYM[4] : ~TYP[1];+ begin+ ~SYM[4] := ~SYM[1];+ -- pragma translate_off+ if ~SYM[2] < ~SYM[4]'low or ~SYM[2] > ~SYM[4]'high then+ assert false report (\"Index: \" & integer'image(~SYM[2]) & \", is out of bounds: \" & integer'image(~SYM[1]'low) & \" to \" & integer'image(~SYM[1]'high)) severity warning;+ ~SYM[4] := ~ERROR[1];+ else+ -- pragma translate_on+ ~SYM[4](~SYM[2]) := ~SYM[3];+ -- pragma translate_off+ end if;+ -- pragma translate_on+ ~RESULT <= ~SYM[4];+ end process;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.maxIndex"+ , "type" : "maxIndex :: KnownNat n => Vec n a -> Integer"+ , "templateE" : "~LIT[0] - 1"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.length"+ , "type" : "length :: KnownNat n => Vec n a -> Integer"+ , "templateE" : "~LIT[0]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.replicate"+ , "type" : "replicate :: SNat n -> a -> Vec n a"+ , "templateE" : "~TYPMO'(0 to ~LIT[0]-1 => ~ARG[1])"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.reverse"+ , "type" : "reverse :: Vec n a -> Vec n a"+ , "templateD" :+"reverse_~SYM[0] : block+ signal ~SYM[1] : ~TYP[0];+begin+ ~SYM[1] <= ~ARG[0];++ reverseZ_~SYM[2] : if ~RESULT'length = 0 generate+ ~RESULT <= ~SYM[1];+ end generate;++ reverseSN_~SYM[3] : if ~RESULT'length /= 0 generate+ reverseIter_~SYM[4] : for ~SYM[5] in ~SYM[1]'range generate+ ~RESULT(~SYM[1]'high - ~SYM[5]) <= ~SYM[1](~SYM[5]);+ end generate;+ end generate;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.lazyV"+ , "type" : "lazyV :: KnownNat n => Vec n a -> Vec n a"+ , "templateE" : "~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.concatBitVector#"+ , "type" :+"concatBitVector# :: KnownNat m -- ARG[0]+ => Vec n (BitVector m) -- ARG[1]+ -> BitVector (n * m)"+ , "templateD" :+"concatBitVector_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+begin+ ~SYM[1] <= ~ARG[1];++ concatBitVectorZ_~SYM[2] : if ~RESULT'length = 0 generate+ ~RESULT <= ~ERRORO;+ end generate;++ concatBitVectorSN_~SYM[3] : if ~RESULT'length /= 0 generate+ concatBitVectorIter_~SYM[4] : for ~SYM[5] in ~SYM[1]'range generate+ ~RESULT(((~SYM[5] * ~LIT[0]) + ~LIT[0] - 1) downto (~SYM[5] * ~LIT[0])) <= ~TYPMO(~SYM[1](~SYM[5]));+ end generate;+ end generate;+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "CLaSH.Sized.Vector.unconcatBitVector#"+ , "type" :+"unconcatBitVector# :: (KnownNat n, KnownNat m) -- (ARG[0],ARG[1])+ => BitVector (n * m) -- ARG[2]+ -> Vec n (BitVector m)"+ , "templateD" :+"unconcatBitVector_~SYM[0] : block+ signal ~SYM[1] : ~TYP[2];+begin+ ~SYM[1] <= ~ARG[2];++ unconcatBitVectorZ_~SYM[2] : if ~SYM[1]'length = 0 generate+ ~RESULT <= ~ERRORO;+ end generate;++ unconcatBitVectorSN_~SYM[3] : if ~SYM[1]'length /= 0 generate+ unconcatBitVectorIter_~SYM[4] : for ~SYM[5] in ~RESULT'range generate+ ~RESULT(~SYM[5]) <= ~SYM[1](((~SYM[5] * ~LIT[1]) + ~LIT[1] - 1) downto (~SYM[5] * ~LIT[1]));+ end generate;+ end generate;+end block;"+ }+ }+]
+ primitives/Control.Exception.Base.json view
@@ -0,0 +1,25 @@+[ { "BlackBox" :+ { "name" : "Control.Exception.Base.patError"+ , "type" : "patError :: Addr# -> a"+ , "templateE" : "~ERRORO"+ }+ }+, { "BlackBox" :+ { "name" : "Control.Exception.Base.irrefutPatError"+ , "type" : "irrefutPatError :: Addr# -> a"+ , "templateE" : "~ERRORO"+ }+ }+, { "BlackBox" :+ { "name" : "Control.Exception.Base.recSelError"+ , "type" : "recSelError :: Addr# -> a"+ , "templateE" : "~ERRORO"+ }+ }+, { "BlackBox" :+ { "name" : "Control.Exception.Base.absentError"+ , "type" : "absentError :: Addr# -> a"+ , "templateE" : "~ERRORO"+ }+ }+]
+ primitives/GHC.Base.json view
@@ -0,0 +1,37 @@+[ { "Primitive" :+ { "name" : "GHC.Base.$"+ , "primType" : "Function"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Base.quotInt"+ , "type" : "quotInt :: Int -> Int -> Int"+ , "templateE" : "~ARG[0] / ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Base.remInt"+ , "type" : "remInt :: Int -> Int -> Int"+ , "templateE" : "~ARG[0] rem ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Base.divInt"+ , "type" : "divInt :: Int -> Int -> Int"+ , "templateD" :+"divInt_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+begin+ ~SYM[1] <= ~ARG[0] / ~ARG[1];+ ~RESULT <= ~SYM[1] - 1 when ((~ARG[0] = abs ~ARG[0]) /= (~ARG[1] = abs ~ARG[1])) else+ ~SYM[1];+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Base.modInt"+ , "type" : "modInt :: Int -> Int -> Int"+ , "templateE" : "~ARG[0] mod ~ARG[1]"+ }+ }+]
+ primitives/GHC.CString.json view
@@ -0,0 +1,11 @@+[ { "Primitive" :+ { "name" : "GHC.CString.unpackCString#"+ , "primType" : "Function"+ }+ }+, { "Primitive" :+ { "name" : "GHC.CString.unpackCStringUtf8#"+ , "primType" : "Function"+ }+ }+]
+ primitives/GHC.Classes.json view
@@ -0,0 +1,74 @@+[ { "BlackBox" :+ { "name" : "GHC.Classes.eqInt"+ , "type" : "eqInt :: Int -> Int -> Bool"+ , "templateE" : "~ARG[0] = ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Classes.neInt"+ , "type" : "neInt :: Int -> Int -> Bool"+ , "templateE" : "~ARG[0] /= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Classes.gtInt"+ , "type" : "gtInt :: Int -> Int -> Bool"+ , "templateE" : "~ARG[0] > ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Classes.geInt"+ , "type" : "geInt :: Int -> Int -> Bool"+ , "templateE" : "~ARG[0] >= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Classes.ltInt"+ , "type" : "ltInt :: Int -> Int -> Bool"+ , "templateE" : "~ARG[0] < ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Classes.leInt"+ , "type" : "leInt :: Int -> Int -> Bool"+ , "templateE" : "~ARG[0] <= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Classes.&&"+ , "type" : "(&&) :: Bool -> Bool -> Bool"+ , "templateE" : "~ARG[0] and ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Classes.||"+ , "type" : "(::) :: Bool -> Bool -> Bool"+ , "templateE" : "~ARG[0] or ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Classes.not"+ , "type" : "not :: Bool -> Bool"+ , "templateE" : "not ~ARG[0]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Classes.divInt#"+ , "type" : "divInt# :: Int# -> Int# -> Int#"+ , "templateD" :+"divInt_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+begin+ ~SYM[1] <= ~ARG[0] / ~ARG[1];+ ~RESULT <= ~SYM[1] - 1 when ((~ARG[0] = abs ~ARG[0]) /= (~ARG[1] = abs ~ARG[1])) else+ ~SYM[1];+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Classes.modInt#"+ , "type" : "modInt# :: Int# -> Int# -> Int#"+ , "templateE" : "~ARG[0] mod ~ARG[1]"+ }+ }+]
+ primitives/GHC.Err.json view
@@ -0,0 +1,13 @@+[ { "BlackBox" :+ { "name" : "GHC.Err.error"+ , "type" : "error :: [Char] -> a"+ , "templateE" : "~ERRORO"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Err.undefined"+ , "type" : "undefined :: a"+ , "templateE" : "~ERRORO"+ }+ }+]
+ primitives/GHC.Integer.Type.json view
@@ -0,0 +1,158 @@+[ { "BlackBox" :+ { "name" : "GHC.Integer.Type.smallInteger"+ , "type" : "smallInteger :: Int# -> Integer"+ , "templateE" : "~ARG[0]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.integerToInt"+ , "type" : "integerToInt :: Integer -> Int#"+ , "templateE" : "~ARG[0]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.plusInteger"+ , "type" : "plusInteger :: Integer -> Integer -> Integer"+ , "templateE" : "~ARG[0] + ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.minusInteger"+ , "type" : "minusInteger :: Integer -> Integer -> Integer"+ , "templateE" : "~ARG[0] - ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.timesInteger"+ , "type" : "timesInteger :: Integer -> Integer -> Integer"+ , "templateE" : "~ARG[0] * ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.negateInteger"+ , "type" : "negateInteger :: Integer -> Integer"+ , "templateE" : "-~ARG[0]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.absInteger"+ , "type" : "absInteger :: Integer -> Integer"+ , "templateE" : "abs ~ARG[0]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.divInteger"+ , "type" : "divInteger :: Integer -> Integer -> Integer"+ , "templateD" :+"divInteger_~SYM[0] : block+ signal ~SYM[1] : ~TYP[1];+begin+ ~SYM[1] <= ~ARG[0] / ~ARG[1];+ ~RESULT <= ~SYM[1] - 1 when ((~ARG[0] = abs ~ARG[0]) /= (~ARG[1] = abs ~ARG[1])) else+ ~SYM[1];+end block;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.modInteger"+ , "type" : "modInteger :: Integer -> Integer -> Integer"+ , "templateE" : "~ARG[0] mod ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.quotInteger"+ , "type" : "quotInteger :: Integer -> Integer -> Integer"+ , "templateE" : "~ARG[0] / ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.remInteger"+ , "type" : "remInteger :: Integer -> Integer -> Integer"+ , "templateE" : "~ARG[0] rem ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.eqInteger"+ , "type" : "eqInteger :: Integer -> Integer -> Bool"+ , "templateE" : "~ARG[0] = ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.neqInteger"+ , "type" : "neqInteger :: Integer -> Integer -> Bool"+ , "templateE" : "~ARG[0] /= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.leInteger"+ , "type" : "leInteger :: Integer -> Integer -> Bool"+ , "templateE" : "~ARG[0] <= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.gtInteger"+ , "type" : "gtInteger :: Integer -> Integer -> Bool"+ , "templateE" : "~ARG[0] > ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.ltInteger"+ , "type" : "ltInteger :: Integer -> Integer -> Bool"+ , "templateE" : "~ARG[0] < ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.geInteger"+ , "type" : "geInteger :: Integer -> Integer -> Bool"+ , "templateE" : "~ARG[0] >= ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.eqInteger#"+ , "type" : "eqInteger# :: Integer -> Integer -> Int#"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] = ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.neqInteger#"+ , "type" : "neqInteger# :: Integer -> Integer -> Int#"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] /= ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.leInteger#"+ , "type" : "leInteger# :: Integer -> Integer -> Int#"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] <= ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.gtInteger#"+ , "type" : "gtInteger# :: Integer -> Integer -> Int#"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] > ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.ltInteger#"+ , "type" : "ltInteger# :: Integer -> Integer -> Int#"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] < ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.geInteger#"+ , "type" : "geInteger# :: Integer -> Integer -> Int#"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] >= ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.shiftRInteger"+ , "type" : "shiftRInteger :: Integer -> Int# -> Integer"+ , "templateE" : "~ARG[0] / (2**~ARG[1])"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Integer.Type.shiftLInteger"+ , "type" : "shiftLInteger :: Integer -> Int# -> Integer"+ , "templateE" : "~ARG[0] * (2**~ARG[1])"+ }+ }+]
+ primitives/GHC.Prim.json view
@@ -0,0 +1,89 @@+[ { "BlackBox" :+ { "name" : "GHC.Prim.+#"+ , "type" : "(+#) :: Int# -> Int# -> Int#"+ , "templateE" : "~ARG[0] + ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.-#"+ , "type" : "(-#) :: Int# -> Int# -> Int#"+ , "templateE" : "~ARG[0] - ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.*#"+ , "type" : "(*#) :: Int# -> Int# -> Int#"+ , "templateE" : "~ARG[0] * ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.quotInt#"+ , "type" : "quotInt# :: Int# -> Int# -> Int#"+ , "templateE" : "~ARG[0] / ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.remInt#"+ , "type" : "remInt# :: Int# -> Int# -> Int#"+ , "templateE" : "~ARG[0] rem ~ARG[1]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.negateInt#"+ , "type" : "negateInt# :: Int# -> Int#"+ , "templateE" : "-~ARG[0]"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.>#"+ , "type" : "(>#) :: Int# -> Int# -> Bool"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] > ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.>=#"+ , "type" : "(>=#) :: Int# -> Int# -> Bool"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] >= ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.==#"+ , "type" : "(==) :: Int# -> Int# -> Bool"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] = ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim./=#"+ , "type" : "(/=#) :: Int# -> Int# -> Bool"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] /= ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.<#"+ , "type" : "(<#) :: Int# -> Int# -> Bool"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] < ~ARG[1] else 0;"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.<=#"+ , "type" : "(<=#) :: Int# -> Int# -> Bool"+ , "templateD" : "~RESULT <= 1 when ~ARG[0] <= ~ARG[1] else 0;"+ }+ }+, { "Primitive" :+ { "name" : "GHC.Prim.dataToTag#"+ , "primType" : "Function"+ }+ }+, { "Primitive" :+ { "name" : "GHC.Prim.tagToEnum#"+ , "primType" : "Function"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Prim.unsafeCoerce#"+ , "type" : "unsafeCoerce# :: a -> b"+ , "templateE" : "~ARG[0]"+ }+ }+]
+ primitives/GHC.Real.json view
@@ -0,0 +1,19 @@+[ { "BlackBox" :+ { "name" : "GHC.Real.divZeroError"+ , "type" : "divZeroError :: a"+ , "templateE" : "~ERRORO"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Real.ratioZeroDenominatorError"+ , "type" : "ratioZeroDenominatorError :: a"+ , "templateE" : "~ERRORO"+ }+ }+, { "BlackBox" :+ { "name" : "GHC.Real.overflowError"+ , "type" : "overflowError :: a"+ , "templateE" : "~ERRORO"+ }+ }+]
+ primitives/GHC.Typelits.json view
@@ -0,0 +1,7 @@+[ { "BlackBox" :+ { "name" : "GHC.TypeLits.natVal"+ , "type" : "natVal :: forall n proxy. KnownNat n => proxy n -> Integer"+ , "templateE" : "~LIT[0]"+ }+ }+]
+ primitives/GHC.Types.json view
@@ -0,0 +1,11 @@+[ { "Primitive" :+ { "name" : "GHC.Types.Eq#"+ , "primType" : "Constructor"+ }+ }+, { "Primitive" :+ { "name" : "GHC.Types.MkCoercible"+ , "primType" : "Constructor"+ }+ }+]
+ primitives/Unsafe.Coerce.json view
@@ -0,0 +1,7 @@+[ { "BlackBox" :+ { "name" : "Unsafe.Coerce.unsafeCoerce"+ , "type" : "unsafeCoerce :: a -> b"+ , "templateE" : "~ARG[0]"+ }+ }+]
+ src/CLaSH/Backend/VHDL.hs view
@@ -0,0 +1,651 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecursiveDo #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE ViewPatterns #-}++-- | Generate VHDL for assorted Netlist datatypes+module CLaSH.Backend.VHDL (VHDLState) where++import qualified Control.Applicative as A+import Control.Lens hiding (Indexed)+import Control.Monad (forM,join,liftM,zipWithM)+import Control.Monad.State (State)+import Data.Graph.Inductive (Gr, mkGraph, topsort')+import Data.HashMap.Lazy (HashMap)+import qualified Data.HashMap.Lazy as HashMap+import Data.HashSet (HashSet)+import qualified Data.HashSet as HashSet+import Data.List (mapAccumL,nubBy)+import Data.Maybe (catMaybes,mapMaybe)+import Data.Text.Lazy (unpack)+import qualified Data.Text.Lazy as T+import Text.PrettyPrint.Leijen.Text.Monadic++import CLaSH.Backend+import CLaSH.Netlist.BlackBox.Util (extractLiterals, renderBlackBox)+import CLaSH.Netlist.Types+import CLaSH.Netlist.Util+import CLaSH.Util (clog2, curLoc, makeCached, (<:>))++#ifdef CABAL+import qualified Paths_clash_vhdl+#else+import qualified System.FilePath+#endif++-- | State for the 'CLaSH.Netlist.VHDL.VHDLM' monad:+data VHDLState =+ VHDLState+ { _tyCache :: (HashSet HWType) -- ^ Previously encountered HWTypes+ , _tyCount :: Int -- ^ Product type counter+ , _nameCache :: (HashMap HWType Doc) -- ^ Cache for previously generated product type names+ }++makeLenses ''VHDLState++instance Backend VHDLState where+ initBackend = VHDLState HashSet.empty 0 HashMap.empty+#ifdef CABAL+ primDir = const (Paths_clash_vhdl.getDataFileName "primitives")+#else+ primDir _ = return ("clash-vhdl" System.FilePath.</> "primitives")+#endif+ extractTypes = _tyCache+ name = const "vhdl"+ extension = const ".vhdl"++ genHDL = genVHDL+ mkTyPackage = mkTyPackage_+ hdlType = vhdlType+ hdlTypeErrValue = vhdlTypeErrValue+ hdlTypeMark = vhdlTypeMark+ hdlSig t ty = sigDecl (text t) ty+ inst = inst_+ expr = expr_++type VHDLM a = State VHDLState a++-- | Generate VHDL for a Netlist component+genVHDL :: Component -> VHDLM (String,Doc)+genVHDL c = (unpack cName,) A.<$> vhdl+ where+ cName = componentName c+ vhdl = "-- Automatically generated VHDL" <$$>+ tyImports <$$> linebreak <>+ entity c <$$> linebreak <>+ architecture c++-- | Generate a VHDL package containing type definitions for the given HWTypes+mkTyPackage_ :: [HWType]+ -> VHDLM Doc+mkTyPackage_ hwtys =+ "library IEEE;" <$>+ "use IEEE.STD_LOGIC_1164.ALL;" <$>+ "use IEEE.NUMERIC_STD.ALL;" <$$> linebreak <>+ "package" <+> "types" <+> "is" <$>+ indent 2 ( packageDec <$>+ vcat (sequence funDecs)+ ) <$>+ "end" <> semi <> packageBodyDec+ where+ usedTys = concatMap mkUsedTys hwtys+ needsDec = nubBy eqReprTy $ (hwtys ++ usedTys)+ hwTysSorted = topSortHWTys needsDec+ packageDec = vcat $ mapM tyDec hwTysSorted+ (funDecs,funBodies) = unzip $ maxDec : (catMaybes $ map funDec (nubBy eqTypM needsDec))++ packageBodyDec :: VHDLM Doc+ packageBodyDec = case funBodies of+ [] -> empty+ _ -> linebreak <$>+ "package" <+> "body" <+> "types" <+> "is" <$>+ indent 2 (vcat (sequence funBodies)) <$>+ "end" <> semi++ eqReprTy :: HWType -> HWType -> Bool+ eqReprTy (Vector _ ty1) (Vector _ ty2) = eqReprTy ty1 ty2+ eqReprTy ty1 ty2+ | isUnsigned ty1 && isUnsigned ty2 ||+ isSLV ty1 && isSLV ty2 = typeSize ty1 == typeSize ty2+ | otherwise = ty1 == ty2++ eqTypM (Vector _ ty1) (Vector _ ty2) = eqReprTy ty1 ty2+ eqTypM (Signed _) (Signed _) = True+ eqTypM ty1 ty2 = isUnsigned ty1 && isUnsigned ty2 ||+ isSLV ty1 && isSLV ty2 ||+ ty1 == ty2++ isUnsigned :: HWType -> Bool+ isUnsigned (Unsigned _) = True+ isUnsigned (Index _) = True+ isUnsigned (Sum _ _) = True+ isUnsigned _ = False++ isSLV :: HWType -> Bool+ isSLV (BitVector _) = True+ isSLV (SP _ _) = True+ isSLV _ = False++mkUsedTys :: HWType+ -> [HWType]+mkUsedTys v@(Vector _ elTy) = v : mkUsedTys elTy+mkUsedTys p@(Product _ elTys) = p : concatMap mkUsedTys elTys+mkUsedTys sp@(SP _ elTys) = sp : concatMap mkUsedTys (concatMap snd elTys)+mkUsedTys t = [t]++topSortHWTys :: [HWType]+ -> [HWType]+topSortHWTys hwtys = sorted+ where+ nodes = zip [0..] hwtys+ nodesI = HashMap.fromList (zip hwtys [0..])+ edges = concatMap edge hwtys+ graph = mkGraph nodes edges :: Gr HWType ()+ sorted = reverse $ topsort' graph++ edge t@(Vector _ elTy) = maybe [] ((:[]) . (HashMap.lookupDefault (error $ $(curLoc) ++ "Vector") t nodesI,,()))+ (HashMap.lookup (mkVecZ elTy) nodesI)+ edge t@(Product _ tys) = let ti = HashMap.lookupDefault (error $ $(curLoc) ++ "Product") t nodesI+ in mapMaybe (\ty -> liftM (ti,,()) (HashMap.lookup (mkVecZ ty) nodesI)) tys+ edge t@(SP _ ctys) = let ti = HashMap.lookupDefault (error $ $(curLoc) ++ "SP") t nodesI+ in concatMap (\(_,tys) -> mapMaybe (\ty -> liftM (ti,,()) (HashMap.lookup (mkVecZ ty) nodesI)) tys) ctys+ edge _ = []++mkVecZ :: HWType -> HWType+mkVecZ (Vector _ elTy) = Vector 0 elTy+mkVecZ t = t++tyDec :: HWType -> VHDLM Doc+tyDec (Vector _ elTy) = "type" <+> "array_of_" <> tyName elTy <+> "is array (integer range <>) of" <+> vhdlType elTy <> semi++tyDec ty@(Product _ tys) = prodDec+ where+ prodDec = "type" <+> tName <+> "is record" <$>+ indent 2 (vcat $ zipWithM (\x y -> x <+> colon <+> y <> semi) selNames selTys) <$>+ "end record" <> semi++ tName = tyName ty+ selNames = map (\i -> tName <> "_sel" <> int i) [0..]+ selTys = map vhdlType tys++tyDec _ = empty+++maxDec :: (VHDLM Doc, VHDLM Doc)+maxDec =+ ( "function" <+> "max" <+> parens ("left, right: in integer") <+> "return integer" <> semi+ , "function" <+> "max" <+> parens ("left, right: in integer") <+> "return integer" <+> "is" <$>+ "begin" <$>+ indent 2 (vcat $ sequence [ "if" <+> "left > right" <+> "then return left" <> semi+ , "else return right" <> semi+ , "end if" <> semi+ ]) <$>+ "end" <> semi+ )++funDec :: HWType -> Maybe (VHDLM Doc,VHDLM Doc)+funDec Bool = Just+ ( "function" <+> "toSLV" <+> parens ("b" <+> colon <+> "in" <+> "boolean") <+> "return" <+> "std_logic_vector" <> semi <$>+ "function" <+> "fromSLV" <+> parens ("sl" <+> colon <+> "in" <+> "std_logic_vector") <+> "return" <+> "boolean" <> semi+ , "function" <+> "toSLV" <+> parens ("b" <+> colon <+> "in" <+> "boolean") <+> "return" <+> "std_logic_vector" <+> "is" <$>+ "begin" <$>+ indent 2 (vcat $ sequence ["if" <+> "b" <+> "then"+ , indent 2 ("return" <+> dquotes (int 1) <> semi)+ ,"else"+ , indent 2 ("return" <+> dquotes (int 0) <> semi)+ ,"end" <+> "if" <> semi+ ]) <$>+ "end" <> semi <$>+ "function" <+> "fromSLV" <+> parens ("sl" <+> colon <+> "in" <+> "std_logic_vector") <+> "return" <+> "boolean" <+> "is" <$>+ "begin" <$>+ indent 2 (vcat $ sequence ["if" <+> "sl" <+> "=" <+> dquotes (int 1) <+> "then"+ , indent 2 ("return" <+> "true" <> semi)+ ,"else"+ , indent 2 ("return" <+> "false" <> semi)+ ,"end" <+> "if" <> semi+ ]) <$>+ "end" <> semi+ )++funDec Integer = Just+ ( "function" <+> "to_integer" <+> parens ("i" <+> colon <+> "in" <+> "integer") <+> "return" <+> "integer" <> semi <$>+ "function" <+> "toSLV" <+> parens ("i" <+> colon <+> "in" <+> "integer") <+> "return" <+> "std_logic_vector" <> semi+ , "function" <+> "to_integer" <+> parens ("i" <+> colon <+> "in" <+> "integer") <+> "return" <+> "integer" <+> "is" <$>+ "begin" <$>+ indent 2 ("return" <+> "i" <> semi) <$>+ "end" <> semi <$>+ "function" <+> "toSLV" <+> parens ("i" <+> colon <+> "in" <+> "integer") <+> "return" <+> "std_logic_vector" <+> "is" <$>+ "begin" <$>+ indent 2 ("return" <+> "std_logic_vector" <> parens ("to_signed" <> parens ("i" <> comma <> int 32)) <> semi) <$>+ "end" <> semi+ )++funDec (Index _) = Just unsignedToSlvDec++funDec (Signed _) = Just+ ( "function" <+> "toSLV" <+> parens ("s" <+> colon <+> "in" <+> "signed") <+> "return" <+> "std_logic_vector" <> semi+ , "function" <+> "toSLV" <+> parens ("s" <+> colon <+> "in" <+> "signed") <+> "return" <+> "std_logic_vector" <+> "is" <$>+ "begin" <$>+ indent 2 ("return" <+> "std_logic_vector" <> parens ("s") <> semi) <$>+ "end" <> semi+ )++funDec (Unsigned _) = Just unsignedToSlvDec++funDec (Sum _ _) = Just unsignedToSlvDec++funDec t@(Product _ elTys) = Just+ ( "function" <+> "toSLV" <+> parens ("p :" <+> vhdlType t) <+> "return std_logic_vector" <> semi+ , "function" <+> "toSLV" <+> parens ("p :" <+> vhdlType t) <+> "return std_logic_vector" <+> "is" <$>+ "begin" <$>+ indent 2 ("return" <+> parens (hcat (punctuate " & " elTyPrint)) <> semi) <$>+ "end" <> semi+ )+ where+ elTyPrint = forM [0..(length elTys - 1)]+ (\i -> "toSLV" <>+ parens ("p." <> vhdlType t <> "_sel" <> int i))++funDec t@(Vector _ elTy) = Just+ ( "function" <+> "toSLV" <+> parens ("value : " <+> vhdlTypeMark t) <+> "return std_logic_vector" <> semi+ , "function" <+> "toSLV" <+> parens ("value : " <+> vhdlTypeMark t) <+> "return std_logic_vector" <+> "is" <$>+ indent 2+ ( "alias ivalue :" <+> vhdlTypeMark t <> "(1 to value'length) is value;" <$>+ "variable result :" <+> "std_logic_vector" <> parens ("1 to value'length * " <> int (typeSize elTy)) <> semi+ ) <$>+ "begin" <$>+ indent 2+ ("for i in ivalue'range loop" <$>+ indent 2+ ( "result" <> parens (parens ("(i - 1) * " <> int (typeSize elTy)) <+> "+ 1" <+>+ "to i*" <> int (typeSize elTy)) <+>+ ":=" <+> "toSLV" <> parens ("ivalue" <> parens ("i")) <> semi+ ) <$>+ "end" <+> "loop" <> semi <$>+ "return" <+> "result" <> semi+ ) <$>+ "end" <> semi+ )++funDec (BitVector _) = Just slvToSlvDec+funDec (SP _ _) = Just slvToSlvDec++funDec _ = Nothing++unsignedToSlvDec :: (VHDLM Doc, VHDLM Doc)+unsignedToSlvDec =+ ( "function" <+> "toSLV" <+> parens ("u" <+> colon <+> "in" <+> "unsigned") <+> "return" <+> "std_logic_vector" <> semi+ , "function" <+> "toSLV" <+> parens ("u" <+> colon <+> "in" <+> "unsigned") <+> "return" <+> "std_logic_vector" <+> "is" <$>+ "begin" <$>+ indent 2 ("return" <+> "std_logic_vector" <> parens ("u") <> semi) <$>+ "end" <> semi+ )++slvToSlvDec :: (VHDLM Doc, VHDLM Doc)+slvToSlvDec =+ ( "function" <+> "toSLV" <+> parens ("slv" <+> colon <+> "in" <+> "std_logic_vector") <+> "return" <+> "std_logic_vector" <> semi+ , "function" <+> "toSLV" <+> parens ("slv" <+> colon <+> "in" <+> "std_logic_vector") <+> "return" <+> "std_logic_vector" <+> "is" <$>+ "begin" <$>+ indent 2 ("return" <+> "slv" <> semi) <$>+ "end" <> semi+ )++tyImports :: VHDLM Doc+tyImports =+ punctuate' semi $ sequence+ [ "library IEEE"+ , "use IEEE.STD_LOGIC_1164.ALL"+ , "use IEEE.NUMERIC_STD.ALL"+ , "use IEEE.MATH_REAL.ALL"+ , "use work.all"+ , "use work.types.all"+ ]+++entity :: Component -> VHDLM Doc+entity c = do+ rec (p,ls) <- fmap unzip (ports (maximum ls))+ "entity" <+> text (componentName c) <+> "is" <$>+ (case p of+ [] -> empty+ _ -> indent 2 ("port" <>+ parens (align $ vcat $ punctuate semi (A.pure p)) <>+ semi)+ ) <$>+ "end" <> semi+ where+ ports l = sequence+ $ [ (,fromIntegral $ T.length i) A.<$> (fill l (text i) <+> colon <+> "in" <+> vhdlType ty)+ | (i,ty) <- inputs c ] +++ [ (,fromIntegral $ T.length i) A.<$> (fill l (text i) <+> colon <+> "in" <+> vhdlType ty)+ | (i,ty) <- hiddenPorts c ] +++ [ (,fromIntegral $ T.length (fst $ output c)) A.<$> (fill l (text (fst $ output c)) <+> colon <+> "out" <+> vhdlType (snd $ output c))+ ]++architecture :: Component -> VHDLM Doc+architecture c =+ nest 2+ ("architecture structural of" <+> text (componentName c) <+> "is" <$$>+ decls (declarations c)) <$$>+ nest 2+ ("begin" <$$>+ insts (declarations c)) <$$>+ "end" <> semi++-- | Convert a Netlist HWType to a VHDL type+vhdlType :: HWType -> VHDLM Doc+vhdlType hwty = do+ tyCache %= HashSet.insert (mkVecZ hwty)+ vhdlType' hwty++vhdlType' :: HWType -> VHDLM Doc+vhdlType' Bool = "boolean"+vhdlType' (Clock _) = "std_logic"+vhdlType' (Reset _) = "std_logic"+vhdlType' Integer = "integer"+vhdlType' (BitVector n) = case n of+ 0 -> "std_logic_vector (0 downto 1)"+ _ -> "std_logic_vector" <> parens (int (n-1) <+> "downto 0")+vhdlType' (Index u) = "unsigned" <> parens (int (clog2 (max 2 u) - 1) <+> "downto 0")+vhdlType' (Signed n) = if n == 0 then "signed (0 downto 1)"+ else "signed" <> parens (int (n-1) <+> "downto 0")+vhdlType' (Unsigned n) = if n == 0 then "unsigned (0 downto 1)"+ else "unsigned" <> parens ( int (n-1) <+> "downto 0")+vhdlType' (Vector n elTy) = "array_of_" <> tyName elTy <> parens ("0 to " <> int (n-1))+vhdlType' t@(SP _ _) = "std_logic_vector" <> parens (int (typeSize t - 1) <+> "downto 0")+vhdlType' t@(Sum _ _) = case typeSize t of+ 0 -> "unsigned (0 downto 1)"+ n -> "unsigned" <> parens (int (n -1) <+> "downto 0")+vhdlType' t@(Product _ _) = tyName t+vhdlType' Void = "std_logic_vector" <> parens (int (-1) <+> "downto 0")++sigDecl :: VHDLM Doc -> HWType -> VHDLM Doc+sigDecl d t = d <+> colon <+> vhdlType t++-- | Convert a Netlist HWType to the root of a VHDL type+vhdlTypeMark :: HWType -> VHDLM Doc+vhdlTypeMark hwty = do+ tyCache %= HashSet.insert (mkVecZ hwty)+ vhdlTypeMark' hwty+ where+ vhdlTypeMark' Bool = "boolean"+ vhdlTypeMark' (Clock _) = "std_logic"+ vhdlTypeMark' (Reset _) = "std_logic"+ vhdlTypeMark' Integer = "integer"+ vhdlTypeMark' (BitVector _) = "std_logic_vector"+ vhdlTypeMark' (Index _) = "unsigned"+ vhdlTypeMark' (Signed _) = "signed"+ vhdlTypeMark' (Unsigned _) = "unsigned"+ vhdlTypeMark' (Vector _ elTy) = "array_of_" <> tyName elTy+ vhdlTypeMark' (SP _ _) = "std_logic_vector"+ vhdlTypeMark' (Sum _ _) = "unsigned"+ vhdlTypeMark' t@(Product _ _) = tyName t+ vhdlTypeMark' t = error $ $(curLoc) ++ "vhdlTypeMark: " ++ show t++tyName :: HWType -> VHDLM Doc+tyName Integer = "integer"+tyName Bool = "boolean"+tyName (Vector n elTy) = "array_of_" <> int n <> "_" <> tyName elTy+tyName (BitVector n) = "std_logic_vector_" <> int n+tyName t@(Index _) = "unsigned_" <> int (typeSize t)+tyName (Signed n) = "signed_" <> int n+tyName (Unsigned n) = "unsigned_" <> int n+tyName t@(Sum _ _) = "unsigned_" <> int (typeSize t)+tyName t@(Product _ _) = makeCached t nameCache prodName+ where+ prodName = do i <- tyCount <<%= (+1)+ "product" <> int i+tyName t@(SP _ _) = "std_logic_vector_" <> int (typeSize t)+tyName _ = empty++-- | Convert a Netlist HWType to an error VHDL value for that type+vhdlTypeErrValue :: HWType -> VHDLM Doc+vhdlTypeErrValue Bool = "true"+vhdlTypeErrValue Integer = "integer'high"+vhdlTypeErrValue (BitVector _) = "(others => 'X')"+vhdlTypeErrValue (Index _) = "(others => 'X')"+vhdlTypeErrValue (Signed _) = "(others => 'X')"+vhdlTypeErrValue (Unsigned _) = "(others => 'X')"+vhdlTypeErrValue (Vector _ elTy) = parens ("others" <+> rarrow <+> vhdlTypeErrValue elTy)+vhdlTypeErrValue (SP _ _) = "(others => 'X')"+vhdlTypeErrValue (Sum _ _) = "(others => 'X')"+vhdlTypeErrValue (Product _ elTys) = tupled $ mapM vhdlTypeErrValue elTys+vhdlTypeErrValue (Reset _) = "'X'"+vhdlTypeErrValue (Clock _) = "'X'"+vhdlTypeErrValue Void = "(0 downto 1 => 'X')"++decls :: [Declaration] -> VHDLM Doc+decls [] = empty+decls ds = do+ rec (dsDoc,ls) <- fmap (unzip . catMaybes) $ mapM (decl (maximum ls)) ds+ case dsDoc of+ [] -> empty+ _ -> punctuate' semi (A.pure dsDoc)++decl :: Int -> Declaration -> VHDLM (Maybe (Doc,Int))+decl l (NetDecl id_ ty) = Just A.<$> (,fromIntegral (T.length id_)) A.<$>+ "signal" <+> fill l (text id_) <+> colon <+> vhdlType ty++decl _ _ = return Nothing++insts :: [Declaration] -> VHDLM Doc+insts [] = empty+insts is = vcat . punctuate linebreak . fmap catMaybes $ mapM inst_ is++-- | Turn a Netlist Declaration to a VHDL concurrent block+inst_ :: Declaration -> VHDLM (Maybe Doc)+inst_ (Assignment id_ e) = fmap Just $+ text id_ <+> larrow <+> expr_ False e <> semi++inst_ (CondAssignment id_ scrut es) = fmap Just $+ "with" <+> parens (expr_ True scrut) <+> "select" <$>+ indent 2 (text id_ <+> larrow <+> align (vcat (punctuate comma (conds es)) <> semi))+ where+ conds :: [(Maybe Expr,Expr)] -> VHDLM [Doc]+ conds [] = return []+ conds [(_,e)] = expr_ False e <+> "when" <+> "others" <:> return []+ conds ((Nothing,e):_) = expr_ False e <+> "when" <+> "others" <:> return []+ conds ((Just c ,e):es') = expr_ False e <+> "when" <+> parens (expr_ True c) <:> conds es'++inst_ (InstDecl nm lbl pms) = fmap Just $+ nest 2 $ text lbl <+> colon <+> "entity"+ <+> text nm <$$> pms' <> semi+ where+ pms' = do+ rec (p,ls) <- fmap unzip $ sequence [ (,fromIntegral (T.length i)) A.<$> fill (maximum ls) (text i) <+> "=>" <+> expr_ False e | (i,e) <- pms]+ nest 2 $ "port map" <$$> tupled (A.pure p)++inst_ (BlackBoxD _ bs bbCtx) = do t <- renderBlackBox bs bbCtx+ fmap Just (string t)++inst_ _ = return Nothing++-- | Turn a Netlist expression into a VHDL expression+expr_ :: Bool -- ^ Enclose in parenthesis?+ -> Expr -- ^ Expr to convert+ -> VHDLM Doc+expr_ _ (Literal sizeM lit) = exprLit sizeM lit+expr_ _ (Identifier id_ Nothing) = text id_+expr_ _ (Identifier id_ (Just (Indexed (ty@(SP _ args),dcI,fI)))) = fromSLV argTy id_ start end+ where+ argTys = snd $ args !! dcI+ argTy = argTys !! fI+ argSize = typeSize argTy+ other = otherSize argTys (fI-1)+ start = typeSize ty - 1 - conSize ty - other+ end = start - argSize + 1++expr_ _ (Identifier id_ (Just (Indexed (ty@(Product _ _),_,fI)))) = text id_ <> dot <> tyName ty <> "_sel" <> int fI+expr_ _ (Identifier id_ (Just (DC (ty@(SP _ _),_)))) = text id_ <> parens (int start <+> "downto" <+> int end)+ where+ start = typeSize ty - 1+ end = typeSize ty - conSize ty++expr_ _ (Identifier id_ (Just _)) = text id_+expr_ _ (DataCon ty@(Vector 1 _) _ [e]) = vhdlTypeMark ty <> "'" <> parens (int 0 <+> rarrow <+> expr_ False e)+expr_ _ e@(DataCon ty@(Vector _ elTy) _ [e1,e2]) = vhdlTypeMark ty <> "'" <> case vectorChain e of+ Just es -> tupled (mapM (expr_ False) es)+ Nothing -> parens (vhdlTypeMark elTy <> "'" <> parens (expr_ False e1) <+> "&" <+> expr_ False e2)+expr_ _ (DataCon ty@(SP _ args) (DC (_,i)) es) = assignExpr+ where+ argTys = snd $ args !! i+ dcSize = conSize ty + sum (map typeSize argTys)+ dcExpr = expr_ False (dcToExpr ty i)+ argExprs = zipWith toSLV argTys es+ extraArg = case typeSize ty - dcSize of+ 0 -> []+ n -> [exprLit (Just (ty,n)) (NumLit 0)]+ assignExpr = "std_logic_vector'" <> parens (hcat $ punctuate " & " $ sequence (dcExpr:argExprs ++ extraArg))++expr_ _ (DataCon ty@(Sum _ _) (DC (_,i)) []) = "to_unsigned" <> tupled (sequence [int i,int (typeSize ty)])+expr_ _ (DataCon ty@(Product _ _) _ es) = tupled $ zipWithM (\i e -> tName <> "_sel" <> int i <+> rarrow <+> expr_ False e) [0..] es+ where+ tName = tyName ty++expr_ _ (BlackBoxE pNm _ bbCtx _)+ | pNm == "CLaSH.Sized.Internal.Signed.fromInteger#"+ , [Literal _ (NumLit n), Literal _ i] <- extractLiterals bbCtx+ = exprLit (Just (Signed (fromInteger n),fromInteger n)) i++expr_ _ (BlackBoxE pNm _ bbCtx _)+ | pNm == "CLaSH.Sized.Internal.Unsigned.fromInteger#"+ , [Literal _ (NumLit n), Literal _ i] <- extractLiterals bbCtx+ = exprLit (Just (Unsigned (fromInteger n),fromInteger n)) i++expr_ _ (BlackBoxE pNm _ bbCtx _)+ | pNm == "CLaSH.Sized.Internal.BitVector.fromInteger#"+ , [Literal _ (NumLit n), Literal _ i] <- extractLiterals bbCtx+ = exprLit (Just (BitVector (fromInteger n),fromInteger n)) i++expr_ b (BlackBoxE _ bs bbCtx b') = do+ t <- renderBlackBox bs bbCtx+ parenIf (b || b') $ string t++expr_ _ (DataTag Bool (Left id_)) = "false when" <+> text id_ <+> "= 0 else true"+expr_ _ (DataTag Bool (Right id_)) = "1 when" <+> text id_ <+> "else 0"+expr_ _ (DataTag hty@(Sum _ _) (Left id_)) = "to_unsigned" <> tupled (sequence [text id_,int (typeSize hty)])+expr_ _ (DataTag (Sum _ _) (Right id_)) = "to_integer" <> parens (text id_)++expr_ _ (DataTag (Product _ _) (Right _)) = int 0+expr_ _ (DataTag hty@(SP _ _) (Right id_)) = "to_integer" <> parens+ ("unsigned" <> parens+ (text id_ <> parens+ (int start <+> "downto" <+> int end)))+ where+ start = typeSize hty - 1+ end = typeSize hty - conSize hty++expr_ _ (DataTag (Vector 0 _) (Right _)) = int 0+expr_ _ (DataTag (Vector _ _) (Right _)) = int 1++expr_ _ e = error $ $(curLoc) ++ (show e) -- empty++otherSize :: [HWType] -> Int -> Int+otherSize _ n | n < 0 = 0+otherSize [] _ = 0+otherSize (a:as) n = typeSize a + otherSize as (n-1)++vectorChain :: Expr -> Maybe [Expr]+vectorChain (DataCon (Vector 0 _) _ _) = Just []+vectorChain (DataCon (Vector 1 _) _ [e]) = Just [e]+vectorChain (DataCon (Vector _ _) _ [e1,e2]) = Just e1 <:> vectorChain e2+vectorChain _ = Nothing++exprLit :: Maybe (HWType,Size) -> Literal -> VHDLM Doc+exprLit Nothing (NumLit i) = integer i+exprLit (Just (hty,sz)) (NumLit i) = case hty of+ Unsigned _ -> "unsigned'" <> parens blit+ Signed _ -> "signed'" <> parens blit+ BitVector _ -> "std_logic_vector'" <> parens blit+ _ -> blit++ where+ blit = bits (toBits sz i)+exprLit _ (BoolLit t) = if t then "true" else "false"+exprLit _ (BitLit b) = squotes $ bit_char b+exprLit _ l = error $ $(curLoc) ++ "exprLit: " ++ show l++toBits :: Integral a => Int -> a -> [Bit]+toBits size val = map (\x -> if odd x then H else L)+ $ reverse+ $ take size+ $ map (`mod` 2)+ $ iterate (`div` 2) val++bits :: [Bit] -> VHDLM Doc+bits = dquotes . hcat . mapM bit_char++bit_char :: Bit -> VHDLM Doc+bit_char H = char '1'+bit_char L = char '0'+bit_char U = char 'U'+bit_char Z = char 'Z'++toSLV :: HWType -> Expr -> VHDLM Doc+toSLV Bool e = "toSLV" <> parens (expr_ False e)+toSLV Integer e = "std_logic_vector" <> parens ("to_signed" <> tupled (sequence [expr_ False e,int 32]))+toSLV (BitVector _) e = expr_ False e+toSLV (Signed _) e = "std_logic_vector" <> parens (expr_ False e)+toSLV (Unsigned _) e = "std_logic_vector" <> parens (expr_ False e)+toSLV (Sum _ _) e = "std_logic_vector" <> parens (expr_ False e)+toSLV t@(Product _ tys) (Identifier id_ Nothing) = do+ selIds' <- sequence selIds+ encloseSep lparen rparen " & " (zipWithM toSLV tys selIds')+ where+ tName = tyName t+ selNames = map (fmap (displayT . renderOneLine) ) [text id_ <> dot <> tName <> "_sel" <> int i | i <- [0..(length tys)-1]]+ selIds = map (fmap (\n -> Identifier n Nothing)) selNames+toSLV (Product _ tys) (DataCon _ _ es) = encloseSep lparen rparen " & " (zipWithM toSLV tys es)+toSLV (SP _ _) e = expr_ False e+toSLV (Vector n elTy) (Identifier id_ Nothing) = do+ selIds' <- sequence (reverse selIds)+ parens (encloseSep lparen rparen " & " (mapM (toSLV elTy) selIds'))+ where+ selNames = map (fmap (displayT . renderOneLine) ) $ reverse [text id_ <> parens (int i) | i <- [0 .. (n-1)]]+ selIds = map (fmap (`Identifier` Nothing)) selNames+toSLV (Vector n elTy) (DataCon _ _ es) = encloseSep lparen rparen " & " (zipWithM toSLV [elTy,Vector (n-1) elTy] es)+toSLV hty e = error $ $(curLoc) ++ "toSLV: ty:" ++ show hty ++ "\n expr: " ++ show e++fromSLV :: HWType -> Identifier -> Int -> Int -> VHDLM Doc+fromSLV Bool id_ start _ = "fromSLV" <> parens (text id_ <> parens (int start))+fromSLV Integer id_ start end = "to_integer" <> parens (fromSLV (Signed 32) id_ start end)+fromSLV (BitVector _) id_ start end = text id_ <> parens (int start <+> "downto" <+> int end)+fromSLV (Index _) id_ start end = "unsigned" <> parens (text id_ <> parens (int start <+> "downto" <+> int end))+fromSLV (Signed _) id_ start end = "signed" <> parens (text id_ <> parens (int start <+> "downto" <+> int end))+fromSLV (Unsigned _) id_ start end = "unsigned" <> parens (text id_ <> parens (int start <+> "downto" <+> int end))+fromSLV (Sum _ _) id_ start end = "unsigned" <> parens (text id_ <> parens (int start <+> "downto" <+> int end))+fromSLV t@(Product _ tys) id_ start _ = tupled $ zipWithM (\s e -> s <+> rarrow <+> e) selNames args+ where+ tName = tyName t+ selNames = [tName <> "_sel" <> int i | i <- [0..]]+ argLengths = map typeSize tys+ starts = start : snd (mapAccumL ((join (,) .) . (-)) start argLengths)+ ends = map (+1) (tail starts)+ args = zipWith3 (`fromSLV` id_) tys starts ends++fromSLV (SP _ _) id_ start end = text id_ <> parens (int start <+> "downto" <+> int end)+fromSLV (Vector n elTy) id_ start _ = tupled (fmap reverse args)+ where+ argLength = typeSize elTy+ starts = take (n + 1) $ iterate (subtract argLength) start+ ends = map (+1) (tail starts)+ args = zipWithM (fromSLV elTy id_) starts ends+fromSLV hty _ _ _ = error $ $(curLoc) ++ "fromSLV: " ++ show hty++dcToExpr :: HWType -> Int -> Expr+dcToExpr ty i = Literal (Just (ty,conSize ty)) (NumLit (toInteger i))++larrow :: VHDLM Doc+larrow = "<="++rarrow :: VHDLM Doc+rarrow = "=>"++parenIf :: Monad m => Bool -> m Doc -> m Doc+parenIf True = parens+parenIf False = id++punctuate' :: Monad m => m Doc -> m [Doc] -> m Doc+punctuate' s d = vcat (punctuate s d) <> s