packages feed

clash-systemverilog (empty) → 0.5

raw patch · 31 files changed

+2573/−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 view
@@ -0,0 +1,4 @@+# Changelog for the [`clash-systemverilog`](http://hackage.haskell.org/package/clash-systemverilog) 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-systemverilog`+  * See the LICENSE file for license and copyright details
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ clash-systemverilog.cabal view
@@ -0,0 +1,79 @@+Name:                 clash-systemverilog+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:+  .+  * SystemVerilog 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.SystemVerilog++  other-modules:      Paths_clash_systemverilog
+ primitives/CLaSH.Driver.TestbenchGen.json view
@@ -0,0 +1,55 @@+[ { "BlackBox" :+    { "name"      : "CLaSH.Driver.TestbenchGen.clockGen"+    , "templateD" :+"// pragma translate_off+always begin+  ~RESULT = 0;+  #~LIT[0] forever begin+    ~RESULT = ~ ~RESULT;+    #~LIT[1];+    ~RESULT = ~ ~RESULT;+    #~LIT[2];+  end+end+// pragma translate_on"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Driver.TestbenchGen.resetGen"+    , "templateD" :+"// pragma translate_off+initial begin+  ~RESULT = 0;+  #~LIT[0] ~RESULT = 1;+end+// pragma translate_on"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Driver.TestbenchGen.doneGen"+    , "templateD" :+"assign ~RESULT = ~ARG[0];++// pragma translate_off+always_comb begin+  if (~ARG[0] == 1'b1) begin+    $finish;+  end+end+// pragma translate_on+"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Driver.TestbenchGen.finishedGen"+    , "templateD" :+"always begin+// pragma translate_off+  ~RESULT <= 1'b0;+  #~LIT[0]+// pragma translate_on+  ~RESULT = 1'b1;+end"+    }+  }+]
+ 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,31 @@+[ { "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+~SIGD[~SYM[0]][3];+~SIGD[~SYM[1]][7];++initial begin+  ~SYM[0] = ~LIT[3];+end++always @(posedge ~CLK[2]) begin+  if (~ARG[6]) begin+    ~SYM[0][~ARG[4]] <= ~ARG[7];+  end+  ~SYM[1] <= ~SYM[0][~ARG[5]];+end++assign ~RESULT = ~SYM[1];"+    }+  }+]
+ primitives/CLaSH.Prelude.Testbench.json view
@@ -0,0 +1,22 @@+[ { "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+// pragma translate_off+always @(posedge ~CLK[2] or negedge ~RST[2]) begin+  if (~ARG[2] != ~ARG[3]) begin+    $display(\"expected: %b, actual: %b\", ~TYPM[3]_to_lv(~ARG[3]), ~TYPM[2]_to_lv(~ARG[2]));+    $stop;+  end+end+// pragma translate_on+assign ~RESULT = ~ARG[4];"+    }+  }+]
+ 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,70 @@+[ { "BlackBox" :+    { "name" : "CLaSH.Signal.Internal.register#"+    , "type" :+"register# :: SClock clk     -- ARG[0]+           -> a              -- ARG[1]+           -> Signal' clk a  -- ARG[2]+           -> Signal' clk a"+    , "templateD" :+"~SIGD[~SYM[0]][2];++always_ff @(posedge ~CLK[0] or negedge ~RST[0])+if (~ ~RST[0]) begin+  ~SYM[0] <= ~ARG[1];+end else begin+  ~SYM[0] <= ~ARG[2];+end++assign ~RESULT = ~SYM[0];"+    }+  }+, { "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" :+"~SIGD[~SYM[0]][3];++always_ff @(posedge ~CLK[0] or negedge ~RST[0])+if (~ ~RST[0]) begin+  ~SYM[1] <= ~ARG[1];+end else begin+  if (~ARG[2]) begin+    ~SYM[1] <= ~ARG[3];+  end+end++assign ~RESULT = ~SYM[1];"+    }+  }++, { "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,365 @@+[ { "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'b1"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.low"+    , "type"      : "low :: Bit"+    , "templateE" : "1'b0"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.++#"+    , "type"      : "(++#) :: KnownNat m => BitVector n -> BitVector m -> BitVector (n + m)"+    , "templateE" : "{~ARG[1],~ARG[2]}"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.reduceAnd#"+    , "type"      : "reduceAnd# :: KnownNat n => BitVector n -> BitVector 1"+    , "templateE" : "& (~ARG[1])"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.reduceOr#"+    , "type"      : "reduceOr# :: BitVector n -> BitVector 1"+    , "templateE" : "| (~ARG[0])"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.reduceXor#"+    , "type"      : "reduceXor# :: BitVector n -> BitVector 1"+    , "templateE" : "^ (~ARG[0])"+    }+  }+, { "BlackBox" :+    { "name" : "CLaSH.Sized.Internal.BitVector.index#"+    , "type" :+"index# :: KnownNat n  -- ARG[0]+        => BitVector n -- ARG[1]+        -> Int         -- ARG[2]+        -> Bit"+    , "templateD" :+"// index+~SIGD[~SYM[0]][1];+~SIGD[~SYM[1]][2];++assign ~SYM[0] = ~ARG[1];+assign ~SYM[1] = ~ARG[2];++// pragma translate_off+always_comb begin+  if (~SYM[1] < $low(~SYM[0]) || ~SYM[1] > $high(~SYM[0])) begin+    $display(\"Index: %d, is out of bounds: %d to %d\", ~SYM[1], $low(~SYM[0]), $high(~SYM[0]));+    ~RESULT = ~ERRORO;+  end else begin+  // pragma translate_on+    ~RESULT = ~SYM[0][~SYM[1]];+  // pragma translate_off+  end+end+// pragma translate_on"+    }+  }+, { "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+~SIGD[~SYM[0]][2];+assign ~SYM[0] = ~ARG[2];++~SIGD[~SYM[1]][1];+always_comb begin+  ~SYM[1] = ~ARG[1];+  // pragma translate_off+  if (~SYM[0] < $low(~SYM[1]) || ~SYM[0] > $high(~SYM[1])) begin+    $display(\"Index: %d, is out of bounds: %d to %d\", ~SYM[0], $low(~SYM[1]), $high(~SYM[1]));+    ~SYM[1] = ~ERROR[1];+  end else begin+    // pragma translate_on+    ~SYM[1][~SYM[0]] = ~ARG[3];+    // pragma translate_off+  end+  // pragma translate_on+end++assign ~RESULT = ~SYM[1];"+    }+  }+, { "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+~SIGD[~SYM[0]][0];++always_comb begin+  ~SYM[0] = ~ARG[0];+  ~SYM[0][~LIT[1] : ~LIT[2]] = ~ARG[3];+end++assign ~RESULT = ~SYM[0];"+    }+  }+, { "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+~SIGD[~SYM[0]][0];+assign ~SYM[0] = ~ARG[0];+assign ~RESULT = ~SYM[1][~LIT[1] : ~LIT[2]];"+    }+  }+, { "BlackBox" :+    { "name" : "CLaSH.Sized.Internal.BitVector.split#"+    , "type" :+"split# :: KnownNat n        -- ARG[0]+        => BitVector (m + n) -- ARG[1]+        -> (BitVector m, BitVector n)"+    , "templateD" :+"// split+~SIGD[~SYM[0]][1];+assign ~SYM[0] = ~ARG[1];+assign ~RESULT = '{ ~SYM[0][$high(~SYM[0]) : ~LIT[0]]+                  , ~SYM[0][(~LIT[0]-1) : 0]+                  };"+    }+  }+, { "BlackBox" :+    { "name" : "CLaSH.Sized.Internal.BitVector.msb#"+    , "type" :+"msb# :: KnownNat n  -- ARG[0]+      => BitVector n -- ARG[1]+      -> Bit"+    , "templateD" :+"// msb+~SIGD[~SYM[0]][1];+assign ~SYM[0] = ~ARG[1];+assign ~RESULT = ~SYM[0][~LIT[0]-1];"+    }+  }+, { "BlackBox" :+    { "name" : "CLaSH.Sized.Internal.BitVector.lsb#"+    , "type" :+"lsb# :: BitVector n -- ARG[0]+      -> Bit"+    , "templateD" :+"// lsb+~SIGD[~SYM[0]][0];+assign ~SYM[0] = ~ARG[0];+assign ~RESULT = ~SYM[0][0];"+    }+  }+, { "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"+    , "templateE" : "~LIT[0]'d0"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.maxBound#"+    , "type"      : "maxBound# :: KnownNat n => BitVector n"+    , "templateE" : "{~LIT[0] {1'b1}}"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.+#"+    , "type"      : "(+#) :: KnownNat n => BitVector n -> BitVector n -> BitVector n"+    , "templateE" : "~ARG[1] + ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.-#"+    , "type"      : "(-#) :: KnownNat n => BitVector n -> BitVector n -> BitVector n"+    , "templateE" : "~ARG[1] - ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.*#"+    , "type"      : "(*#) :: KnownNat n => BitVector n -> BitVector n -> BitVector n"+    , "templateE" : "~ARG[1] * ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.negate#"+    , "type"      : "negate# :: KnownNat n => BitVector n -> BitVector n"+    , "templateE" : "-~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.fromInteger#"+    , "type"      : "fromInteger# :: KnownNat n => Integer -> BitVector n"+    , "templateE" : "$unsigned(~ARG[1])"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.plus#"+    , "type"      : "plus# :: KnownNat (Max m n + 1) => BitVector m -> BitVector n -> BitVector (Max m n + 1)"+    , "templateE" : "~ARG[1] + ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.minus#"+    , "type"      : "minus# :: KnownNat (Max m n + 1) => BitVector m -> BitVector n -> BitVector (Max m n + 1)"+    , "templateE" : "~ARG[1] - ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.times#"+    , "type"      : "times# :: KnownNat (m + n) => BitVector m -> BitVector n -> BitVector (m + n)"+    , "templateE" : "~ARG[1] * ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.quot#"+    , "type"      : "quot# :: BitVector n -> BitVector n -> BitVector n"+    , "templateE" : "~ARG[1]) / ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.rem#"+    , "type"      : "rem# :: BitVector n -> BitVector n -> BitVector n"+    , "templateE" : "~ARG[1] % ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.mod#"+    , "type"      : "mod# :: BitVector n -> BitVector n -> BitVector n"+    , "templateE" : "~ARG[1] % ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.toInteger#"+    , "type"      : "toInteger# :: BitVector n -> Integer"+    , "templateE" : "$unsigned(~ARG[0])"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.and#"+    , "type"      : "and# :: BitVector n -> BitVector n -> BitVector n"+    , "templateE" : "~ARG[0] & ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.or#"+    , "type"      : "or# :: BitVector n -> BitVector n -> BitVector n"+    , "templateE" : "~ARG[0] | ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.xor#"+    , "type"      : "xor# :: BitVector n -> BitVector n -> BitVector n"+    , "templateE" : "~ARG[0] ^ ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.complement#"+    , "type"      : "complement# :: KnownNat n => BitVector n -> BitVector n"+    , "templateE" : "~ ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.shiftL#"+    , "type"      : "shiftL# :: KnownNat n => BitVector n -> Int -> BitVector n"+    , "templateE" : "~ARG[1] << ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.shiftR#"+    , "type"      : "shiftR# :: KnownNat n => BitVector n -> Int -> BitVector n"+    , "templateE" : "~ARG[1] >> ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.rotateL#"+    , "type"      : "rotateL# :: KnownNat n => BitVector n -> Int -> BitVector n"+    , "templateD" :+"// rotateL+logic [2*~LIT[0]-1:0] ~SYM[0];+assign ~SYM[0] = {~ARG[1],~ARG[1]} << ~ARG[2];+assign ~RESULT = ~SYM[0][~LIT[1]-1 : 0];"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.rotateR#"+    , "type"      : "rotateR# :: KnownNat n => BitVector n -> Int -> BitVector n"+    , "templateD" :+"// rotateR+logic [2*~LIT[0]-1:0] ~SYM[0];+assign ~SYM[0] = {~ARG[1],~ARG[1]} >> ~ARG[2];+assign ~RESULT = ~SYM[0][~LIT[1]-1 : 0];"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.BitVector.resize#"+    , "type"      : "resize# :: KnownNat m => BitVector n -> BitVector m"+    , "templateE" : "$unsigned(~ARG[1])"+    }+  }+]
+ 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" : "~LIT[0]-1"+    }+  }+, { "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" : "~ARG[1] * ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Index.fromInteger#"+    , "type"      : "fromInteger# :: KnownNat n => Integer -> Index n"+    , "templateE" : "$unsigned(~ARG[1])"+    }+  }+, { "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] % ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Index.mod#"+    , "type"      : "mod# :: KnownNat n => Index n -> Index n -> Index n"+    , "templateE" : "~ARG[1] % ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Index.toInteger#"+    , "type"      : "toInteger# :: Index n -> Integer"+    , "templateE" : "$unsigned(~ARG[0])"+    }+  }+]
+ primitives/CLaSH.Sized.Internal.Signed.json view
@@ -0,0 +1,260 @@+[ { "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" : "~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.unpack#"+    , "type"      : "unpack# :: KnownNat n => BitVector n -> Signed n"+    , "templateE" : "~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 SV for n=0"+    , "templateE" : "{1'b1, {(~LIT[0]-1) {1'b0}}}"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.maxBound#"+    , "type"      : "maxBound# :: KnownNat n => Signed n"+    , "comment"   : "Generates incorrect SV for n=0"+    , "templateE" : "{1'b0, {(~LIT[0]-1) {1'b1}}}"+    }+  }+, { "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" : "~ARG[1] * ~ARG[2]"+    }+  }+, { "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" : "(~ARG[1] < ~LIT[0]'sd0) ? -~ARG[1] : ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.fromInteger#"+    , "type"      : "fromInteger# :: KnownNat n => Integer -> Signed (n :: Nat)"+    , "templateE" : "$signed(~ARG[1])"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.plus#"+    , "type"      : "plus# :: KnownNat (1 + Max m n) => Signed m -> Signed n -> Signed (1 + Max m n)"+    , "templateE" : "~ARG[1] + ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.minus#"+    , "type"      : "minus# :: KnownNat (1 + Max m n) => Signed m -> Signed n -> Signed (1 + Max m n)"+    , "templateE" : "~ARG[1] - ~ARG[2]"+    }+  }+, { "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] % ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.div#"+    , "type"      : "div# :: KnownNat n => Signed n -> Signed n -> Signed n"+    , "templateD" :+"// divInt+~SIGD[~SYM[0]][1];+~SIGD[~SYM[1]][1];+~SIGD[~SYM[2]][2];++// divide (rounds towards zero)+assign ~SYM[0] = ~ARG[1] / ~ARG[2];++// round toward minus infinity+assign ~SYM[1] = ~ARG[1];+assign ~SYM[2] = ~ARG[2];+assign ~RESULT = (~SYM[1][~LIT[0]-1] == ~SYM[2][~LIT[0]-1]) ? ~SYM[0] : ~SYM[0] - ~LIT[0]'sd1;"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.mod#"+    , "type"      : "mod# :: KnownNat n => Signed n -> Signed n -> Signed n"+    , "templateD" :+"// modSigned+~SIGD[~SYM[0]][1];+~SIGD[~SYM[1]][1];+~SIGD[~SYM[2]][2];++// remainder+assign ~SYM[0] = ~ARG[1] % ~ARG[2];++// modulo+assign ~SYM[1] = ~ARG[1];+assign ~SYM[2] = ~ARG[2];+assign ~RESULT = (~SYM[1][~LIT[0]-1] == ~SYM[2][~LIT[0]-1]) ?+                 ~SYM[0] :+                 (~ARG[1] == ~LIT[0]'sd0 ? ~LIT[0]'sd0 : ~SYM[0] + ~ARG[1]);"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.toInteger#"+    , "type"      : "toInteger# :: Signed n -> Integer"+    , "templateE" : "$signed(~ARG[0])"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.and#"+    , "type"      : "and# :: KnownNat n => Signed n -> Signed n -> Signed n"+    , "templateE" : "~ARG[1] & ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.or#"+    , "type"      : "or# :: KnownNat n => Signed n -> Signed n -> Signed n"+    , "templateE" : "~ARG[1] | ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.xor#"+    , "type"      : "xor# :: KnownNat n => Signed n -> Signed n -> Signed n"+    , "templateE" : "~ARG[1] ^ ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.complement#"+    , "type"      : "complement# :: KnownNat n => Signed n -> Signed n"+    , "templateE" : "~ ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.shiftL#"+    , "type"      : "shiftL# :: KnownNat n => Signed n -> Int -> Signed n"+    , "templateE" : "~ARG[1] <<< ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.shiftR#"+    , "type"      : "shiftR# :: KnownNat n => Signed n -> Int -> Signed n"+    , "templateE" : "~ARG[1] >>> ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.rotateL#"+    , "type"      : "rotateL# :: KnownNat n => Signed n -> Int -> Signed n"+    , "templateD" :+"// rotateL+logic [2*~LIT[0]-1:0] ~SYM[0];+assign ~SYM[0] = {~ARG[1],~ARG[1]} << ~ARG[2];+assign ~RESULT = $signed(~SYM[0][~LIT[1]-1 : 0]);"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.rotateR#"+    , "type"      : "rotateR# :: KnownNat n => Signed n -> Int -> Signed n"+    , "templateD" :+"// rotateR+logic [2*~LIT[0]-1:0] ~SYM[0];+assign ~SYM[0] = {~ARG[1],~ARG[1]} >> ~ARG[2];+assign ~RESULT = $signed(~SYM[0][~LIT[1]-1 : 0]);"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.resize#"+    , "type"      : "resize# :: (KnownNat n, KnownNat m) => Signed n -> Signed m"+    , "comment"   : "Back-end should only use this code when the result is smaller than the argument"+    , "templateD" :+"// resize+generate+  if (~LIT[1] < ~LIT[0]) begin+    // truncate, sign preserving+    ~SIGD[~SYM[0]][2];+    assign ~SYM[0] = ~ARG[2];+    assign ~RESULT = $signed({~SYM[0][~LIT[0]-1],~SYM[0][(~LIT[1]-2):0]});+  end else begin+    // sign-extend+    assign ~RESULT = $signed(~ARG[2]);+  end+endgenerate"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Signed.truncateB#"+    , "type"      : "truncateB# :: KnownNat m => Signed (n + m) -> Signed m"+    , "templateE" : "$signed(~ARG[1])"+    }+  }+]
+ primitives/CLaSH.Sized.Internal.Unsigned.json view
@@ -0,0 +1,201 @@+[ { "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" : "~ARG[0]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.unpack#"+    , "type"      : "unpack# :: BitVector n -> Unsigned n"+    , "templateE" : "~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"+    , "templateE" : "~LIT[0]'d0"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.maxBound#"+    , "type"      : "maxBound# :: KnownNat n => Unsigned n"+    , "templateE" : "{~LIT[0] {1'b1}}"+    }+  }+, { "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" : "~ARG[1] * ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.negate#"+    , "type"      : "negate# :: KnownNat n => Unsigned n -> Unsigned n"+    , "templateE" : "- ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.fromInteger#"+    , "type"      : "fromInteger# :: KnownNat n => Integer -> Unsigned n"+    , "templateE" : "$unsigned(~ARG[1])"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.plus#"+    , "type"      : "plus# :: KnownNat (1 + Max m n) => Unsigned m -> Unsigned n -> Unsigned (1 + Max m n)"+    , "templateE" : "~ARG[1] + ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.minus#"+    , "type"      : "minus# :: KnownNat (1 + Max m n) => Unsigned m -> Unsigned n -> Unsigned (1 + Max m n)"+    , "templateE" : "~ARG[1] - ~ARG[2]"+    }+  }+, { "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] % ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.mod#"+    , "type"      : "mod# :: Unsigned n -> Unsigned n -> Unsigned n"+    , "templateE" : "~ARG[1] % ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.toInteger#"+    , "type"      : "toInteger# :: Unsigned n -> Integer"+    , "templateE" : "$unsigned(~ARG[0])"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.and#"+    , "type"      : "and# :: Unsigned n -> Unsigned n -> Unsigned n"+    , "templateE" : "~ARG[0] & ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.or#"+    , "type"      : "or# :: Unsigned n -> Unsigned n -> Unsigned n"+    , "templateE" : "~ARG[0] | ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.xor#"+    , "type"      : "xor# :: Unsigned n -> Unsigned n -> Unsigned n"+    , "templateE" : "~ARG[0] ^ ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.complement#"+    , "type"      : "complement# :: KnownNat n => Unsigned n -> Unsigned n"+    , "templateE" : "~ ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.shiftL#"+    , "type"      : "shiftL# :: KnownNat n => Unsigned n -> Int -> Unsigned n"+    , "templateE" : "~ARG[1] << ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.shiftR#"+    , "type"      : "shiftR# :: KnownNat n => Unsigned n -> Int -> Unsigned n"+    , "templateE" : "~ARG[1] >> ~ARG[2]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.rotateL#"+    , "type"      : "rotateL# :: KnownNat n => Unsigned n -> Int -> Unsigned n"+    , "templateD" :+"// rotateL+logic [2*~LIT[0]-1:0] ~SYM[0];+assign ~SYM[0] = {~ARG[1],~ARG[1]} << ~ARG[2];+assign ~RESULT = ~SYM[0][~LIT[1]-1 : 0];"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.rotateR#"+    , "type"      : "rotateR# :: KnownNat n => Unsigned n -> Int -> Unsigned n"+    , "templateD" :+"// rotateR+logic [2*~LIT[0]-1:0] ~SYM[0];+assign ~SYM[0] = {~ARG[1],~ARG[1]} >> ~ARG[2];+assign ~RESULT = ~SYM[0][~LIT[1]-1 : 0];"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Internal.Unsigned.resize#"+    , "type"      : "resize# :: KnownNat m => Unsigned n -> Unsigned m"+    , "templateE" : "$unsigned(~ARG[1])"+    }+  }+]
+ primitives/CLaSH.Sized.Vector.json view
@@ -0,0 +1,341 @@+[ { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.eq#"+    , "type"      : "eq# :: Eq a => Vec n a -> Vec n a -> Bool"+    , "templateE" : "~ARG[0] == ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.neq#"+    , "type"      : "neq# :: Eq a => Vec n a -> Vec n a -> Bool"+    , "templateE" : "~ARG[0] != ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.head"+    , "type"      : "head :: Vec (n + 1) a -> a"+    , "templateD" :+"// head+~SIGD[~SYM[0]][0];+assign ~SYM[0] = ~ARG[0];++assign ~RESULT = ~SYM[0][0];"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.tail"+    , "type"      : "tail :: Vec (n + 1) a -> Vec n a"+    , "templateD" :+"// tail+~SIGD[~SYM[0]][0];+assign ~SYM[0] = ~ARG[0];++assign ~RESULT = ~SYM[0][1 : $high(~SYM[0])];"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.last"+    , "type"      : "Vec (n + 1) a -> a"+    , "templateD" :+"// last+~SIGD[~SYM[0]][0];+assign ~SYM[0] = ~ARG[0];++assign ~RESULT = ~SYM[0][$high(~SYM[0])];"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.init"+    , "type"      : "Vec (n + 1) a -> Vec n a"+    , "templateD" :+"// init+~SIGD[~SYM[0]][0];+assign ~SYM[0] = ~ARG[0];++assign ~RESULT = ~SYM[0][0 : $high(~SYM[0]) - 1];"+    }+  }+, { "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+~SIGD[~SYM[0]][4];+assign ~SYM[0] = ~ARG[4];++genvar ~SYM[1];+generate+  for (~SYM[1]=0; ~SYM[1] < ~LIT[3]; ~SYM[1] = ~SYM[1] + 1) begin : select_~SYM[2]+    assign ~RESULT[~SYM[1]] = ~SYM[0][~LIT[1] + (~LIT[2] * ~SYM[1])];+  end+endgenerate"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.++"+    , "type"      : "(++) :: Vec n a -> Vec m a -> Vec (n + m) a"+    , "templateD" :+"// (++)+~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(~RESULT); ~SYM[2] = ~SYM[2] + 1) begin : append_~SYM[3]+    if (~SYM[2] < $size(~SYM[0])) begin+      assign ~RESULT[~SYM[2]] = ~SYM[0][~SYM[2]];+    end else begin+      assign ~RESULT[~SYM[2]] = ~SYM[1][~SYM[2]-$size(~SYM[0])];+    end+  end+endgenerate"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.concat"+    , "type"      : "concat :: Vec n (Vec m a) -> Vec (n * m) a"+    , "templateD" :+"// concat+~SIGD[~SYM[0]][0];+assign ~SYM[0] = ~ARG[0];++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]];+  end+endgenerate"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.splitAt"+    , "type"      : "splitAt :: SNat m -> Vec (m + n) a -> (Vec m a, Vec n a)"+    , "templateD" :+"// splitAt+~SIGD[~SYM[0]][1];+assign ~SYM[0] = ~ARG[1];++assign ~RESULT = '{~SYM[0][$left(~RESULT.~TYPMO_sel0) : $right(~RESULT.~TYPMO_sel0)]+                  ,~SYM[0][($left(~RESULT.~TYPMO_sel1) + $size(~RESULT.~TYPMO_sel0)) : ($right(~RESULT.~TYPMO_sel1) + $size(~RESULT.~TYPMO_sel0))]+                  };"+    }+  }+, { "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+~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 : unconcat_~SYM[2]+    assign ~RESULT[~SYM[1]] = ~SYM[0][(~SYM[1] * ~LIT[1]) : ((~SYM[1] * ~LIT[1]) + ~LIT[1] - 1)];+  end+endgenerate"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.merge"+    , "type"      : "merge :: Vec n a -> Vec n a -> Vec (n + n) a"+    , "templateD" :+"// merge+~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"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.map"+    , "type"      : "map :: (a -> b) -> Vec n a -> Vec n b"+    , "templateD" :+"// map+~SIGD[~SYM[0]][1];+assign ~SYM[0] = ~ARG[1];++genvar ~SYM[1];+generate+  for (~SYM[1]=0; ~SYM[1] < $size(~RESULT); ~SYM[1] = ~SYM[1] + 1) begin : map_~SYM[2]+    ~INST 0+      ~OUTPUT <= ~RESULT[~SYM[1]]~ ~TYPEL[~TYPO]~+      ~INPUT  <= ~SYM[0][~SYM[1]]~ ~TYPEL[~TYP[1]]~+    ~INST+  end+endgenerate"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.zipWith"+    , "type"      : "zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c"+    , "templateD" :+"// zipWith+~SIGD[~SYM[0]][1];+~SIGD[~SYM[1]][2];+assign ~SYM[0] = ~ARG[1];+assign ~SYM[1] = ~ARG[2];++genvar ~SYM[2];+generate+  for (~SYM[2] = 0; ~SYM[2] < $size(~RESULT); ~SYM[2] = ~SYM[2] + 1) begin : zipWith_~SYM[2]+    ~INST 0+      ~OUTPUT <= ~RESULT[~SYM[2]]~ ~TYPEL[~TYPO]~+      ~INPUT  <= ~SYM[0][~SYM[2]]~ ~TYPEL[~TYP[1]]~+      ~INPUT  <= ~SYM[1][~SYM[2]]~ ~TYPEL[~TYP[2]]~+    ~INST+  end+endgenerate"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.index_int"+    , "type"      : "index_integer :: KnownNat n => Vec n a -> Int -> a"+    , "templateD" :+"// index_integer+~SIGD[~SYM[0]][1];+~SIGD[~SYM[1]][2];++assign ~SYM[0] = ~ARG[1];+assign ~SYM[1] = ~ARG[2];+++always_comb begin+// pragma translate_off+  if (~SYM[1] < $low(~SYM[0]) || ~SYM[1] > $high(~SYM[0])) begin+    $display(\"Index: %d, is out of bounds: %d to %d\", ~SYM[1], $low(~SYM[0]), $high(~SYM[0]));+    ~RESULT = ~ERRORO;+  end else begin+  // pragma translate_on+    ~RESULT = ~SYM[0][~SYM[1]];+  // pragma translate_off+  end+// pragma translate_on+end"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.replace_int"+    , "type"      : "replace_int :: KnownNat n => Vec n a -> Int -> a -> Vec n a"+    , "templateD" :+"// replace_integer+~SIGD[~SYM[0]][2];+assign ~SYM[0] = ~ARG[2];++~SIGD[~SYM[1]][1];+always_comb begin+  ~SYM[1] = ~ARG[1];+  // pragma translate_off+  if (~SYM[0] < $low(~SYM[1]) || ~SYM[0] > $high(~SYM[1])) begin+    $display(\"Index: %d, is out of bounds: %d to %d\", ~SYM[0], $low(~SYM[1]), $high(~SYM[1]));+    ~SYM[1] = ~ERROR[1];+  end else begin+    // pragma translate_on+    ~SYM[1][~SYM[0]] = ~ARG[3];+    // pragma translate_off+  end+  // pragma translate_on+end++assign ~RESULT = ~SYM[1];"+    }+  }+, { "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" : "'{~LIT[0] {~ARG[1]}}"+    }+  }+, { "BlackBox" :+    { "name"      : "CLaSH.Sized.Vector.reverse"+    , "type"      : "reverse :: Vec n a -> Vec n a"+    , "templateD" :+"// reverse+~SIGD[~SYM[0]][0];+assign ~SYM[0] = ~ARG[0];++genvar ~SYM[1];+generate+  for (~SYM[1] = 0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : reverse_~SYM[2]+    assign ~RESULT[$high(~SYM[0]) - ~SYM[1]] = ~SYM[0][~SYM[1]];+  end+endgenerate"+    }+  }+, { "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+~SIGD[~SYM[0]][1];+assign ~SYM[0] = ~ARG[1];++genvar ~SYM[1];+generate+  for (~SYM[1] = 0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : concatBitVector_~SYM[2]+    assign ~RESULT[((~SYM[1] * ~LIT[0]) + ~LIT[0] - 1) : (~SYM[1] * ~LIT[0])] = ~SYM[0][~SYM[1]];+  end+endgenerate"+    }+  }+, { "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+~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 : unconcatBitVector_~SYM[2]+    assign ~RESULT[~SYM[1]] = ~SYM[0][((~SYM[1] * ~LIT[1]) + ~LIT[1] - 1) : (~SYM[1] * ~LIT[1])];+  end+endgenerate"+    }+  }+]
+ 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,56 @@+[ { "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] % ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Base.divInt"+    , "type"      : "divInt :: Int -> Int -> Int"+    , "templateD" :+"// divInt+~SIGD[~SYM[0]][0];+~SIGD[~SYM[1]][0];+~SIGD[~SYM[2]][1];++// divide (rounds towards zero)+assign ~SYM[0] = ~ARG[0] / ~ARG[1];++// round toward minus infinity+assign ~SYM[1] = ~ARG[0];+assign ~SYM[2] = ~ARG[1];+assign ~RESULT = (~SYM[1][31] == ~SYM[2][31]) ? ~SYM[0] : ~SYM[0] - 32'sd1;"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Base.modInt"+    , "type"      : "modInt :: Int -> Int -> Int"+    , "templateD" :+"// modInt+~SIGD[~SYM[0]][0];+~SIGD[~SYM[1]][0];+~SIGD[~SYM[2]][1];++// remainder+assign ~SYM[0] = ~ARG[0] % ~ARG[1];++// modulo+assign ~SYM[1] = ~ARG[0];+assign ~SYM[2] = ~ARG[1];+assign ~RESULT = (~SYM[1][31] == ~SYM[2][31]) ?+                 ~SYM[0] :+                 (~ARG[1] == 32'sd0 ? 32'sd0 : ~SYM[0] + ~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,93 @@+[ { "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] & ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Classes.||"+    , "type"      : "(::) :: Bool -> Bool -> Bool"+    , "templateE" : "~ARG[0] | ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Classes.not"+    , "type"      : "not :: Bool -> Bool"+    , "templateE" : "~ ~ARG[0]"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Classes.divInt#"+    , "type"      : "divInt# :: Int# -> Int# -> Int#"+    , "templateD" :+"// divInt+~SIGD[~SYM[0]][0];+~SIGD[~SYM[1]][0];+~SIGD[~SYM[2]][1];++// divide (rounds towards zero)+assign ~SYM[0] = ~ARG[0] / ~ARG[1];++// round toward minus infinity+assign ~SYM[1] = ~ARG[0];+assign ~SYM[2] = ~ARG[1];+assign ~RESULT = (~SYM[1][31] == ~SYM[2][31]) ? ~SYM[0] : ~SYM[0] - 32'sd1;"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Classes.modInt#"+    , "type"      : "modInt# :: Int# -> Int# -> Int#"+    , "templateD" :+"// modInt+~SIGD[~SYM[0]][0];+~SIGD[~SYM[1]][0];+~SIGD[~SYM[2]][1];++// remainder+assign ~SYM[0] = ~ARG[0] % ~ARG[1];++// modulo+assign ~SYM[1] = ~ARG[0];+assign ~SYM[2] = ~ARG[1];+assign ~RESULT = (~SYM[1][31] == ~SYM[2][31]) ?+                 ~SYM[0] :+                 (~ARG[1] == 32'sd0 ? 32'sd0 : ~SYM[0] + ~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,177 @@+[ { "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" : "~ARG[0] < 32'sd0 ? -~ARG[0] : ~ARG[0]"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Integer.Type.divInteger"+    , "type"      : "divInteger :: Integer -> Integer -> Integer"+    , "templateD" :+"// divInteger+~SIGD[~SYM[0]][0];+~SIGD[~SYM[1]][0];+~SIGD[~SYM[2]][1];++// divide (rounds towards zero)+assign ~SYM[0] = ~ARG[0] / ~ARG[1];++// round toward minus infinity+assign ~SYM[1] = ~ARG[0];+assign ~SYM[2] = ~ARG[1];+assign ~RESULT = (~SYM[1][31] == ~SYM[2][31]) ? ~SYM[0] : ~SYM[0] - 32'sd1;"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Integer.Type.modInteger"+    , "type"      : "modInteger :: Integer -> Integer -> Integer"+    , "templateD" :+"// modInteger+~SIGD[~SYM[0]][0];+~SIGD[~SYM[1]][0];+~SIGD[~SYM[2]][1];++// remainder+assign ~SYM[0] = ~ARG[0] % ~ARG[1];++// modulo+assign ~SYM[1] = ~ARG[0];+assign ~SYM[2] = ~ARG[1];+assign ~RESULT = (~SYM[1][31] == ~SYM[2][31]) ?+                 ~SYM[0] :+                 (~ARG[1] == 32'sd0 ? 32'sd0 : ~SYM[0] + ~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] % ~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 -> Bool"+    , "templateE" : "(~ARG[0] == ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Integer.Type.neqInteger#"+    , "type"      : "neqInteger :: Integer -> Integer -> Bool"+    , "templateE" : "(~ARG[0] != ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Integer.Type.leInteger#"+    , "type"      : "leInteger :: Integer -> Integer -> Bool"+    , "templateE" : "(~ARG[0] <= ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Integer.Type.gtInteger#"+    , "type"      : "gtInteger :: Integer -> Integer -> Bool"+    , "templateE" : "(~ARG[0] > ~ARG[1] ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Integer.Type.ltInteger#"+    , "type"      : "ltInteger :: Integer -> Integer -> Bool"+    , "templateE" : "(~ARG[0] < ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Integer.Type.geInteger#"+    , "type"      : "geInteger :: Integer -> Integer -> Bool"+    , "templateE" : "(~ARG[0] >= ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Integer.Type.shiftRInteger"+    , "type"      : "shiftRInteger :: Integer -> Int# -> Integer"+    , "templateE" : "~ARG[0] >>> ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Integer.Type.shiftLInteger"+    , "type"      : "shiftLInteger :: Integer -> Int# -> Integer"+    , "templateE" : "~ARG[0] <<< ~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] % ~ARG[1]"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Prim.negateInt#"+    , "type"      : "negateInt# :: Int# -> Int#"+    , "templateE" : "-~ARG[0]"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Prim.>#"+     , "type"      : "(>#) :: Int# -> Int# -> Bool"+    , "templateE" : "(~ARG[0] > ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Prim.>=#"+    , "type"      : "(>=#) :: Int# -> Int# -> Bool"+    , "templateE" : "(~ARG[0] >= ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Prim.==#"+    , "type"      : "(==) :: Int# -> Int# -> Bool"+    , "templateE" : "(~ARG[0] == ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Prim./=#"+    , "type"      : "(/=#) :: Int# -> Int# -> Bool"+    , "templateE" : "(~ARG[0] != ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Prim.<#"+    , "type"      : "(<#) :: Int# -> Int# -> Bool"+    , "templateE" : "(~ARG[0] < ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "BlackBox" :+    { "name"      : "GHC.Prim.<=#"+    , "type"      : "(<=#) :: Int# -> Int# -> Bool"+    , "templateE" : "(~ARG[0] <= ~ARG[1]) ? 32'sd1 : 32'sd0"+    }+  }+, { "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/SystemVerilog.hs view
@@ -0,0 +1,458 @@+{-# LANGUAGE CPP               #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecursiveDo       #-}+{-# LANGUAGE TemplateHaskell   #-}+{-# LANGUAGE TupleSections     #-}+{-# LANGUAGE ViewPatterns      #-}++-- | Generate SystemVerilog for assorted Netlist datatypes+module CLaSH.Backend.SystemVerilog (SystemVerilogState) where++import qualified Control.Applicative                  as A+import           Control.Lens                         hiding (Indexed)+import           Control.Monad                        (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           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                           (curLoc, makeCached, (<:>))++#ifdef CABAL+import qualified Paths_clash_systemverilog+#else+import qualified System.FilePath+#endif++-- | State for the 'CLaSH.Backend.SystemVerilog.SystemVerilogM' monad:+data SystemVerilogState =+  SystemVerilogState+    { _tyCache   :: HashSet HWType -- ^ Previously encountered  HWTypes+    , _tyCount   :: Int -- ^ Product type counter+    , _nameCache :: HashMap HWType Doc -- ^ Cache for previously generated product type names+    }++makeLenses ''SystemVerilogState++instance Backend SystemVerilogState where+  initBackend     = SystemVerilogState HashSet.empty 0 HashMap.empty+#ifdef CABAL+  primDir         = const (Paths_clash_systemverilog.getDataFileName "primitives")+#else+  primDir _       = return ("clash-systemverilog" System.FilePath.</> "primitives")+#endif+  extractTypes    = _tyCache+  name            = const "systemverilog"+  extension       = const ".sv"++  genHDL          = genVerilog+  mkTyPackage     = mkTyPackage_+  hdlType         = verilogType+  hdlTypeErrValue = verilogTypeErrValue+  hdlTypeMark     = verilogTypeMark+  hdlSig t ty     = sigDecl (text t) ty+  inst            = inst_+  expr            = expr_++type SystemVerilogM a = State SystemVerilogState a++-- | Generate VHDL for a Netlist component+genVerilog :: Component -> SystemVerilogM (String,Doc)+genVerilog c = (unpack cName,) A.<$> verilog+  where+    cName   = componentName c+    verilog = "// Automatically generated SystemVerilog" <$$>+              tyImports <$$>+              module_ c++-- | Generate a SystemVerilog package containing type definitions for the given HWTypes+mkTyPackage_ :: [HWType]+             -> SystemVerilogM Doc+mkTyPackage_ hwtys =+    "package types ;" <$>+      indent 2 packageDec <$>+      indent 2 funDecs <$>+    "endpackage : types"+  where+    usedTys     = concatMap mkUsedTys hwtys+    needsDec    = nubBy eqReprTy $ (hwtys ++ usedTys)+    hwTysSorted = topSortHWTys needsDec+    packageDec  = vcat $ mapM tyDec hwTysSorted+    funDecs     = vcat $ mapM funDec hwTysSorted++    eqReprTy :: HWType -> HWType -> Bool+    eqReprTy (Vector n ty1) (Vector m ty2)+      | m == n    = eqReprTy ty1 ty2+      | otherwise = False+    eqReprTy ty1 ty2+      | isUnsigned ty1 && isUnsigned ty2 = typeSize ty1 == typeSize ty2+      | otherwise                        = ty1 == ty2++    isUnsigned :: HWType -> Bool+    isUnsigned Bool          = True+    isUnsigned (Unsigned _)  = True+    isUnsigned (BitVector _) = True+    isUnsigned (Index _)     = True+    isUnsigned (Sum _ _)     = True+    isUnsigned (SP _ _)      = True+    isUnsigned _             = 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 elTy nodesI)+    edge t@(Product _ tys) = let ti = HashMap.lookupDefault (error $ $(curLoc) ++ "Product") t nodesI+                             in mapMaybe (\ty -> liftM (ti,,()) (HashMap.lookup 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 ty nodesI)) tys) ctys+    edge _                 = []++tyDec :: HWType -> SystemVerilogM Doc+tyDec (Vector n elTy) = "typedef" <+> verilogType elTy <+>  "array_of_" <> int n <> "_" <> tyName elTy <+> brackets (int 0 <> colon <> int (n-1)) <> semi++tyDec ty@(Product _ tys) = prodDec+  where+    prodDec = "typedef struct {" <$>+                indent 2 (vcat $ zipWithM (\x y -> sigDecl x y <> semi) selNames tys) <$>+              "}" <+> tName <> semi++    tName    = tyName ty+    selNames = map (\i -> tName <> "_sel" <> int i) [0..]++tyDec _ = empty++funDec :: HWType -> SystemVerilogM Doc+funDec (Clock _) = empty+funDec (Reset _) = empty+funDec t =+  "function logic" <+> brackets (int (typeSize t - 1) <> colon <> int 0)  <+> verilogTypeMark t <> "_to_lv" <> parens (sigDecl "i" t) <> semi <$>+  indent 2 (verilogTypeMark t <> "_to_lv" <+> "=" <+>+    (case t of+       Vector n elTy -> listBraces (sequence [verilogTypeMark elTy <> "_to_lv" <> parens ("i" <> brackets (int i)) | i <- [0..(n-1)]])+       Product _ tys -> listBraces (zipWithM (\elTy i -> verilogTypeMark elTy <> "_to_lv" <> parens ("i" <> dot <> verilogTypeMark t <> "_sel" <> int i)) tys [0..])+       _             -> "i")+       <> semi) <$>+  "endfunction"++tyImports :: SystemVerilogM Doc+tyImports = "import types:: * ;"++module_ :: Component -> SystemVerilogM Doc+module_ c =+    "module" <+> text (componentName c) <> tupled ports <> semi <$>+    indent 2 (inputPorts <$> outputPort <$$> decls (declarations c)) <$$> insts (declarations c) <$>+    "endmodule"+  where+    ports = sequence+          $ [ text i | (i,_) <- inputs c ] +++            [ text i | (i,_) <- hiddenPorts c] +++            [ text (fst $ output c) ]++    inputPorts = case (inputs c ++ hiddenPorts c) of+                   [] -> empty+                   p  -> vcat (punctuate semi (sequence [ "input" <+> sigDecl (text i) ty | (i,ty) <- p ])) <> semi++    outputPort = "output" <+> sigDecl (text (fst $ output c)) (snd $ output c) <> semi++verilogType :: HWType -> SystemVerilogM Doc+verilogType t = do+  tyCache %= HashSet.insert t+  case t of+    (Vector _ _)  -> tyName t+    (Product _ _) -> tyName t+    Integer       -> verilogType (Signed 32)+    (Signed n)    -> "logic signed" <+> brackets (int (n-1) <> colon <> int 0)+    (Clock _)     -> "logic"+    (Reset _)     -> "logic"+    _             -> "logic" <+> brackets (int (typeSize t -1) <> colon <> int 0)++sigDecl :: SystemVerilogM Doc -> HWType -> SystemVerilogM Doc+sigDecl d t = verilogType t <+> d++-- | Convert a Netlist HWType to the root of a Verilog type+verilogTypeMark :: HWType -> SystemVerilogM Doc+verilogTypeMark t = do+  tyCache %= HashSet.insert t+  tyName t++tyName :: HWType -> SystemVerilogM Doc+tyName Integer           = "integer_32"+tyName Bool              = "logic_vector_1"+tyName (Vector n elTy)   = "array_of_" <> int n <> "_" <> tyName elTy+tyName (BitVector n)     = "logic_vector_" <> int n+tyName t@(Index _)       = "logic_vector_" <> int (typeSize t)+tyName (Signed n)        = "signed_" <> int n+tyName (Unsigned n)      = "logic_vector_" <> int n+tyName t@(Sum _ _)       = "logic_vector_" <> int (typeSize t)+tyName t@(Product _ _)   = makeCached t nameCache prodName+  where+    prodName = do i <- tyCount <<%= (+1)+                  "product" <> int i+tyName t@(SP _ _)        = "logic_vector_" <> int (typeSize t)+tyName (Clock _) = "logic"+tyName (Reset _) = "logic"+tyName t =  error $ $(curLoc) ++ "tyName: " ++ show t++-- | Convert a Netlist HWType to an error VHDL value for that type+verilogTypeErrValue :: HWType -> SystemVerilogM Doc+verilogTypeErrValue Bool                = "1'bx"+verilogTypeErrValue Integer         = "{32 {1'bx}}"+verilogTypeErrValue (Unsigned n)    = braces (int n <+> braces "1'bx")+verilogTypeErrValue (Signed n)      = braces (int n <+> braces "1'bx")+verilogTypeErrValue (Vector n elTy) = "'" <> braces (int n <+> braces (verilogTypeErrValue elTy))+verilogTypeErrValue t@(Sum _ _)     = braces (int (typeSize t) <+> braces "1'bx")+verilogTypeErrValue (Product _ elTys)   = "'" <> listBraces (mapM verilogTypeErrValue elTys)+verilogTypeErrValue (BitVector 1)   = "1'bx"+verilogTypeErrValue (BitVector n)   = braces (int n <+> braces "1'bx")+verilogTypeErrValue t@(SP _ _)      = braces (int (typeSize t) <+> braces "1'bx")+verilogTypeErrValue e = error $ $(curLoc) ++ "no error value defined for: " ++ show e++decls :: [Declaration] -> SystemVerilogM Doc+decls [] = empty+decls ds = do+    dsDoc <- catMaybes A.<$> mapM decl ds+    case dsDoc of+      [] -> empty+      _  -> punctuate' semi (A.pure dsDoc)++decl :: Declaration -> SystemVerilogM (Maybe Doc)+decl (NetDecl id_ ty) = Just A.<$> sigDecl (text id_) ty++decl _ = return Nothing++insts :: [Declaration] -> SystemVerilogM Doc+insts [] = empty+insts is = indent 2 . vcat . punctuate linebreak . fmap catMaybes $ mapM inst_ is++-- | Turn a Netlist Declaration to a SystemVerilog concurrent block+inst_ :: Declaration -> SystemVerilogM (Maybe Doc)+inst_ (Assignment id_ e) = fmap Just $+  "assign" <+> text id_ <+> equals <+> expr_ False e <> semi++inst_ (CondAssignment id_ scrut es) = fmap Just $+    "always_comb begin" <$>+    indent 2 ("case" <> parens (expr_ True scrut) <$>+                (indent 2 $ vcat $ punctuate semi (conds es)) <> semi <$>+              "endcase") <$>+    "end"+  where+    conds :: [(Maybe Expr,Expr)] -> SystemVerilogM [Doc]+    conds []                = return []+    conds [(_,e)]           = ("default" <+> colon <+> text id_ <+> equals <+> expr_ False e) <:> return []+    conds ((Nothing,e):_)   = ("default" <+> colon <+> text id_ <+> equals <+> expr_ False e) <:> return []+    conds ((Just c ,e):es') = (expr_ True c <+> colon <+> text id_ <+> equals <+> expr_ False e) <:> conds es'++inst_ (InstDecl nm lbl pms) = fmap Just $+    text nm <+> text lbl <$$> pms' <> semi+  where+    pms' = tupled $ sequence [dot <> text i <+> parens (expr_ False e) | (i,e) <- pms]++inst_ (BlackBoxD _ bs bbCtx) = do+  t <- renderBlackBox bs bbCtx+  fmap Just (string t)++inst_ (NetDecl _ _) = return Nothing++-- | Turn a Netlist expression into a SystemVerilog expression+expr_ :: Bool -- ^ Enclose in parenthesis?+      -> Expr -- ^ Expr to convert+      -> SystemVerilogM 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 <> verilogTypeMark ty <> "_sel" <> int fI+expr_ _ (Identifier id_ (Just (DC (ty@(SP _ _),_)))) = text id_ <> brackets (int start <> colon <> int end)+  where+    start = typeSize ty - 1+    end   = typeSize ty - conSize ty++expr_ _ (Identifier id_ (Just _))                      = text id_++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)+                                                     Nothing -> let e2' = expr_ False e2+                                                                in  listBraces $ sequence ((expr_ False e1):[e2' <> brackets (int i) | i <- [0..(n-2)] ])++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 = braces (hcat $ punctuate comma $ sequence (dcExpr:argExprs ++ extraArg))++expr_ _ (DataCon ty@(Sum _ _) (DC (_,i)) []) = int (typeSize ty) <> "'d" <> int i+expr_ _ (DataCon ty@(Product _ _) _ es) = "'" <> listBraces (zipWithM (\i e -> verilogTypeMark ty <> "_sel" <> int i <> colon <+> expr_ False e) [0..] es)++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_))          = text id_ <> brackets (int 0)+expr_ _ (DataTag Bool (Right id_))         = "$signed" <> parens (listBraces (sequence [braces (int 31 <+> braces "1'b0"),text id_]))++expr_ _ (DataTag (Sum _ _) (Left id_))     = "$unsigned" <> parens (text id_)+expr_ _ (DataTag (Sum _ _) (Right id_))    = "$signed" <> parens (text id_)++expr_ _ (DataTag (Product _ _) (Right _))  = "32'sd0"++expr_ _ (DataTag hty@(SP _ _) (Right id_)) = "$signed" <> parens+                                               (text id_ <> brackets+                                               (int start <> colon <> int end))+  where+    start = typeSize hty - 1+    end   = typeSize hty - conSize hty++expr_ _ (DataTag (Vector 0 _) (Right _)) = "32'sd0"+expr_ _ (DataTag (Vector _ _) (Right _)) = "32'sd1"++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 -> SystemVerilogM Doc+exprLit Nothing         (NumLit i) = integer i+exprLit (Just (hty,sz)) (NumLit i) = case hty of+                                       Unsigned _   -> int sz <> "'d" <> integer i+                                       Signed _+                                        | i < 0     -> "-" <> int sz <> "'sd" <> integer (abs i)+                                        | otherwise -> int sz <> "'sd" <> integer i+                                       _            -> int sz <> "'b" <> blit++  where+    blit = bits (toBits sz i)+exprLit _             (BoolLit t)  = if t then "1'b1" else "1'b0"+exprLit _             (BitLit b)   = "1'b" <> 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] -> SystemVerilogM Doc+bits = hcat . mapM bit_char++bit_char :: Bit -> SystemVerilogM Doc+bit_char H = char '1'+bit_char L = char '0'+bit_char U = char 'U'+bit_char Z = char 'Z'++toSLV :: HWType -> Expr -> SystemVerilogM Doc+toSLV t@(Product _ tys) (Identifier id_ Nothing) = do+    selIds' <- sequence selIds+    listBraces (zipWithM toSLV tys selIds')+  where+    tName    = verilogTypeMark 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) = listBraces (zipWithM toSLV tys es)++toSLV (Vector n elTy) (Identifier id_ Nothing) = do+    selIds' <- sequence (reverse selIds)+    listBraces (mapM (toSLV elTy) selIds')+  where+    selNames = map (fmap (displayT . renderOneLine) ) $ reverse [text id_ <> brackets (int i) | i <- [0 .. (n-1)]]+    selIds   = map (fmap (`Identifier` Nothing)) selNames+toSLV (Vector n elTy) (DataCon _ _ es) = listBraces (zipWithM toSLV [elTy,Vector (n-1) elTy] es)++toSLV _ e = expr_ False e++fromSLV :: HWType -> Identifier -> Int -> Int -> SystemVerilogM Doc+fromSLV t@(Product _ tys) id_ start _ = "'" <> listBraces (zipWithM (\s e -> s <> colon <+> 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 t@(Vector n elTy) id_ start _ = verilogTypeMark t <> "'" <> parens ("'" <> listBraces (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 Integer    id_ start end = fromSLV (Signed 32) id_ start end+fromSLV (Signed _) id_ start end = "$signed" <> parens (text id_ <> brackets (int start <> colon <> int end))++fromSLV _ id_ start end = text id_ <> brackets (int start <> colon <> int end)++dcToExpr :: HWType -> Int -> Expr+dcToExpr ty i = Literal (Just (ty,conSize ty)) (NumLit (toInteger i))++listBraces :: Monad m => m [Doc] -> m Doc+listBraces = encloseSep lbrace rbrace comma++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