- BlackBox:
    name: Clash.Sized.Vector.head
    kind: Expression
    type: 'head :: Vec (n
      + 1) a -> a'
    template: ~IF ~VIVADO ~THEN ~TYPMO'(fromSLV(~VAR[vec][0](0))) ~ELSE ~VAR[vec][0](0)
      ~FI
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.tail
    kind: Expression
    type: 'tail :: Vec (n
      + 1) a -> Vec n a'
    template: ~VAR[vec][0](1 to ~VAR[vec][0]'high)
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.last
    kind: Expression
    type: Vec (n + 1) a ->
      a
    template: ~IF ~VIVADO ~THEN ~TYPMO'(fromSLV(~VAR[vec][0](~VAR[vec][0]'high)))
      ~ELSE ~VAR[vec][0](~VAR[vec][0]'high) ~FI
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.init
    kind: Expression
    type: Vec (n + 1) a ->
      Vec n a
    template: ~VAR[vec][0](0 to ~VAR[vec][0]'high - 1)
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.select
    kind: Declaration
    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
    template: |-
      -- select begin
      ~GENSYM[select][0] : for ~GENSYM[i][1] in ~RESULT'range generate
        ~RESULT(~SYM[1]) <= ~VAR[vec][4](~LIT[1]+(~LIT[2]*~SYM[1]));
      end generate;
      -- select end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.++
    kind: Expression
    type: '(++) :: Vec n a
      -> Vec m a -> Vec (n + m) a'
    template: ~TYPMO'(~TYPM[0]'(~ARG[0]) & ~TYPM[1]'(~ARG[1]))
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.concat
    kind: Declaration
    type: 'concat :: Vec n
      (Vec m a) -> Vec (n * m) a'
    template: |-
      -- concat begin
      ~GENSYM[concat][0] : for ~GENSYM[i][1] in 0 to (~LENGTH[~TYP[0]] - 1) generate
      begin~IF ~VIVADO ~THEN
      ~RESULT(~SYM[1] * ~LENGTH[~TYPEL[~TYP[0]]] to ((~SYM[1]+1) * ~LENGTH[~TYPEL[~TYP[0]]]) - 1) <= fromSLV(~VAR[vec][0](~SYM[1]));~ELSE
      ~RESULT(~SYM[1] * ~LENGTH[~TYPEL[~TYP[0]]] to ((~SYM[1]+1) * ~LENGTH[~TYPEL[~TYP[0]]]) - 1) <= ~VAR[vec][0](~SYM[1]);~FI
      end generate;
      -- concat end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.splitAt
    kind: Expression
    type: 'splitAt :: SNat
      m -> Vec (m + n) a -> (Vec m a, Vec n a)'
    template: ~IF~LENGTH[~TYPO]~THEN~ARG[1]~ELSE(~VAR[vec][1](0 to ~LIT[0]-1),~VAR[vec][1](~LIT[0]
      to ~VAR[vec][1]'high))~FI
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.unconcat
    kind: Declaration
    type: |-
      unconcat :: KnownNat n     -- ARG[0]
                => SNat m         -- ARG[1]
                -> Vec (n * m) a  -- ARG[2]
                -> Vec n (Vec m a)
    template: |-
      -- unconcat begin~DEVNULL[~ARG[0]]
      ~GENSYM[unconcat][0] : for ~GENSYM[i][2] in ~RESULT'range generate
      begin~IF ~VIVADO ~THEN
        ~RESULT(~SYM[2]) <= ~TOBV[~VAR[vec][2]((~SYM[2] * ~LIT[1]) to ((~SYM[2] * ~LIT[1]) + ~LIT[1] - 1))][~TYPEL[~TYPO]];~ELSE
        ~RESULT(~SYM[2]) <= ~VAR[vec][2]((~SYM[2] * ~LIT[1]) to ((~SYM[2] * ~LIT[1]) + ~LIT[1] - 1));~FI
      end generate;
      -- unconcat end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.map
    kind: Declaration
    type: 'map :: (a -> b)
      -> Vec n a -> Vec n b'
    template: |-
      -- map begin
      ~GENSYM[map][0] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN~IF~SIZE[~TYP[1]]~THEN
        signal ~GENSYM[map_in][2]  : ~TYPEL[~TYP[1]];~ELSE ~FI
        signal ~GENSYM[map_out][3] : ~TYPEL[~TYPO];
      begin~IF~SIZE[~TYP[1]]~THEN
        ~SYM[2] <= fromSLV(~VAR[vec][1](~SYM[1]));~ELSE ~FI
        ~INST 0
          ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
          ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[1]]~
        ~INST
        ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
      end generate;~ELSE
      begin
        ~INST 0
          ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
          ~INPUT  <= ~VAR[vec][1](~SYM[1])~ ~TYPEL[~TYP[1]]~
        ~INST
      end generate;~FI
      -- map end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.imap
    kind: Declaration
    type: 'imap :: KnownNat
      n => (Index n -> a -> b) -> Vec n a -> Vec n b'
    template: |-
      -- imap begin
      ~GENSYM[imap][0] : block
        function ~GENSYM[max][6] (l,r : in natural) return natural is
        begin
          if l > r then return l;
          else return r;
          end if;
        end function;
      begin
        ~GENSYM[imap][5] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN~IF~SIZE[~TYP[2]]~THEN
          signal ~GENSYM[map_in][2]  : ~TYPEL[~TYP[2]];~ELSE ~FI
          signal ~GENSYM[map_out][3] : ~TYPEL[~TYPO];
        begin~IF~SIZE[~TYP[2]]~THEN
          ~SYM[2] <= fromSLV(~VAR[vec][2](~SYM[1]));~ELSE ~FI
          ~INST 1
            ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
            ~INPUT  <= to_unsigned(~SYM[1],~SYM[6](1,integer(ceil(log2(real(~LIT[0]))))))~ ~INDEXTYPE[~LIT[0]]~
            ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[2]]~
          ~INST
          ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
        end generate;~ELSE
        begin
          ~INST 1
            ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
            ~INPUT  <= to_unsigned(~SYM[1],~SYM[6](1,integer(ceil(log2(real(~LIT[0]))))))~ ~INDEXTYPE[~LIT[0]]~
            ~INPUT  <= ~VAR[vec][2](~SYM[1])~ ~TYPEL[~TYP[2]]~
          ~INST
        end generate;~FI
      end block;
      -- imap end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.imap_go
    kind: Declaration
    type: 'imap_go :: Index
      n -> (Index n -> a -> b) -> Vec m a -> Vec m b'
    template: |-
      -- imap_go begin
      ~GENSYM[imap][5] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN~IF~SIZE[~TYP[2]]~THEN
        signal ~GENSYM[map_in][2]  : ~TYPEL[~TYP[2]];~ELSE ~FI
        signal ~GENSYM[map_out][3] : ~TYPEL[~TYPO];
        signal ~GENSYM[i2][4]      : ~TYP[0];
      begin~IF~SIZE[~TYP[2]]~THEN
        ~SYM[2] <= fromSLV(~VAR[vec][2](~SYM[1]));~ELSE ~FI
        ~SYM[4] <= ~ARG[0] + to_unsigned(~SYM[1],~SIZE[~TYP[0]]);
        ~INST 1
          ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
          ~INPUT  <= ~SYM[4]~ ~TYP[0]~
          ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[2]]~
        ~INST
        ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
      end generate;~ELSE
        signal ~SYM[4] : ~TYP[0];
      begin
        ~SYM[4] <= ~ARG[0] + to_unsigned(~SYM[1],~SIZE[~TYP[0]]);
        ~INST 1
          ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
          ~INPUT  <= ~SYM[4]~ ~TYP[0]~
          ~INPUT  <= ~VAR[vec][2](~SYM[1])~ ~TYPEL[~TYP[2]]~
        ~INST
      end generate;~FI
      -- imap_go end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.zipWith
    kind: Declaration
    type: 'zipWith :: (a ->
      b -> c) -> Vec n a -> Vec n b -> Vec n c'
    template: |-
      -- zipWith begin
      ~GENSYM[zipWith][0] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN~IF~SIZE[~TYP[1]]~THEN
        signal ~GENSYM[zipWith_in1][2] : ~TYPEL[~TYP[1]];~ELSE ~FI~IF~SIZE[~TYP[2]]~THEN
        signal ~GENSYM[zipWith_in2][6] : ~TYPEL[~TYP[2]];~ELSE ~FI
        signal ~GENSYM[zipWith_out][3] : ~TYPEL[~TYPO];
      begin~IF~SIZE[~TYP[1]]~THEN
        ~SYM[2] <= fromSLV(~VAR[vec1][1](~SYM[1]));~ELSE ~FI~IF~SIZE[~TYP[2]]~THEN
        ~SYM[6] <= fromSLV(~VAR[vec2][2](~SYM[1]));~ELSE ~FI
        ~INST 0
          ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
          ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[1]]~
          ~INPUT  <= ~SYM[6]~ ~TYPEL[~TYP[2]]~
        ~INST
        ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
      end generate;~ELSE
      begin
        ~INST 0
          ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
          ~INPUT  <= ~VAR[vec1][1](~SYM[1])~ ~TYPEL[~TYP[1]]~
          ~INPUT  <= ~VAR[vec2][2](~SYM[1])~ ~TYPEL[~TYP[2]]~
        ~INST
      end generate;~FI
      -- zipWith end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.foldr
    kind: Declaration
    type: 'foldr :: (a ->
      b -> b) -> b -> Vec n a -> b'
    template: |-
      -- foldr begin~IF ~LENGTH[~TYP[2]] ~THEN
      ~GENSYM[foldr][0] : block
        type ~GENSYM[foldr_res_type][1] is array (natural range <>) of ~TYP[1];
        signal ~GENSYM[intermediate][2] : ~SYM[1] (0 to ~LENGTH[~TYP[2]]);
      begin
        ~SYM[2](~LENGTH[~TYP[2]]) <= ~ARG[1];

        foldr_loop : for ~GENSYM[i][3] in 0 to (~LENGTH[~TYP[2]] - 1) generate~IF ~VIVADO ~THEN~IF~SIZE[~TYP[2]]~THEN
          signal ~GENSYM[foldr_in][4] : ~TYPEL[~TYP[2]];~ELSE ~FI
        begin~IF~SIZE[~TYP[2]]~THEN
          ~SYM[4] <= fromSLV(~VAR[vec][2](~SYM[3]));~ELSE ~FI
          ~INST 0
            ~OUTPUT <= ~SYM[2](~SYM[3])~ ~TYP[1]~
            ~INPUT  <= ~SYM[4]~ ~TYPEL[~TYP[2]]~
            ~INPUT  <= ~SYM[2](~SYM[3]+1)~ ~TYP[1]~
          ~INST
        end generate;~ELSE
        begin
          ~INST 0
            ~OUTPUT <= ~SYM[2](~SYM[3])~ ~TYP[1]~
            ~INPUT  <= ~VAR[vec][2](~SYM[3])~ ~TYPEL[~TYP[2]]~
            ~INPUT  <= ~SYM[2](~SYM[3]+1)~ ~TYP[1]~
          ~INST
        end generate;~FI

        ~RESULT <= ~SYM[2](0);
      end block;~ELSE
      ~RESULT <= ~ARG[1];~FI
      -- foldr end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.index_int
    kind: Declaration
    type: 'index_int :: KnownNat
      n => Vec n a -> Int -> a'
    template: |-
      -- index begin
      ~IF~SIZE[~TYP[1]]~THEN~GENSYM[indexVec][0] : block
        signal ~GENSYM[vec_index][1] : integer range 0 to ~LIT[0]-1;
      begin
        ~SYM[1] <= to_integer(~ARG[2])
        -- pragma translate_off
                     mod ~LIT[0]
        -- pragma translate_on
                     ;~IF ~VIVADO ~THEN
        ~RESULT <= fromSLV(~VAR[vec][1](~SYM[1]));~ELSE
        ~RESULT <= ~VAR[vec][1](~SYM[1]);~FI
      end block;~ELSE~RESULT <= ~ERRORO;~FI
      -- index end
- BlackBox:
    name: Clash.Sized.Vector.replace_int
    kind: Declaration
    type: 'replace_int ::
      KnownNat n => Vec n a -> Int -> a -> Vec n a'
    template: |-
      -- replace begin
      ~GENSYM[replaceVec][0] : block
        signal ~GENSYM[vec_index][1] : integer range 0 to ~LIT[0]-1;
      begin
        ~SYM[1] <= to_integer(~ARG[2])
        -- pragma translate_off
                     mod ~LIT[0]
        -- pragma translate_on
                     ;

        process(~SYM[1]~VARS[1]~VARS[3])
          variable ~GENSYM[ivec][2] : ~TYP[1];
        begin
          ~SYM[2] := ~ARG[1];~IF ~VIVADO ~THEN
          ~SYM[2](~SYM[1]) := ~TOBV[~ARG[3]][~TYP[3]];~ELSE
          ~SYM[2](~SYM[1]) := ~ARG[3];~FI
          ~RESULT <= ~SYM[2];
        end process;
      end block;
      -- replace end
- BlackBox:
    name: Clash.Sized.Vector.length
    kind: Expression
    type: 'length :: KnownNat
      n => Vec n a -> Int'
    template: to_signed(~LIT[0],~SIZE[~TYPO])
    workInfo: Constant
- BlackBox:
    name: Clash.Sized.Vector.replicate
    kind: Expression
    type: 'replicate :: SNat
      n -> a -> Vec n a'
    template: ~TYPMO'(0 to ~LIT[0]-1 => ~IF ~VIVADO ~THEN ~TOBV[~ARG[1]][~TYP[1]]
      ~ELSE ~ARG[1] ~FI)
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.transpose
    kind: Declaration
    type: 'transpose :: KnownNat
      n => Vec m (Vec n a) -> Vec n (Vec m a)'
    template: |-
      -- transpose begin
      ~GENSYM[transpose_outer][2] : for ~GENSYM[row_index][3] in 0 to (~LENGTH[~TYP[1]] - 1) generate
        ~GENSYM[transpose_inner][4] : for ~GENSYM[col_index][5] in ~RESULT'range generate~IF ~VIVADO ~THEN
          ~RESULT(~SYM[5])((~LENGTH[~TYP[1]]-~SYM[3])*~SIZE[~TYPEL[~TYPEL[~TYPO]]]-1 downto (~LENGTH[~TYP[1]]-~SYM[3]-1)*~SIZE[~TYPEL[~TYPEL[~TYPO]]]) <= ~VAR[vec][1](~SYM[3])((~RESULT'length-~SYM[5])*~SIZE[~TYPEL[~TYPEL[~TYPO]]]-1 downto (~RESULT'length-~SYM[5]-1)*~SIZE[~TYPEL[~TYPEL[~TYPO]]]);~ELSE
          ~RESULT(~SYM[5])(~SYM[3]) <= ~VAR[matrix][1](~SYM[3])(~SYM[5]);~FI
        end generate;
      end generate;
      -- transpose end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.reverse
    kind: Declaration
    type: 'reverse :: Vec
      n a -> Vec n a'
    template: |-
      -- reverse begin
      ~GENSYM[reverse_loop][2] : for ~GENSYM[i][3] in 0 to (~LENGTH[~TYP[0]] - 1) generate
        ~RESULT(~VAR[vec][0]'high - ~SYM[3]) <= ~VAR[vec][0](~SYM[3]);
      end generate;
      -- reverse end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.concatBitVector#
    kind: Declaration
    type: |-
      concatBitVector# :: (KnownNat n,KnownNat m) -- (ARG[0],ARG[1])
                        => Vec n (BitVector m)     -- ARG[2]
                        -> BitVector (n * m)
    template: |-
      -- concatBitVector begin
      ~GENSYM[concatBitVectorIter_loop][2] : for ~GENSYM[i][3] in 0 to (~LENGTH[~TYP[2]] - 1) generate
        ~RESULT(((~SYM[3] * ~LIT[1]) + ~LIT[1] - 1) downto (~SYM[3] * ~LIT[1])) <= ~TYPMO'(~VAR[vec][2](~VAR[vec][2]'high - ~SYM[3]));
      end generate;
      -- concatBitVector end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.unconcatBitVector#
    kind: Declaration
    type: |-
      unconcatBitVector# :: (KnownNat n, KnownNat m) -- (ARG[0],ARG[1])
                          => BitVector (n * m)        -- ARG[2]
                          -> Vec n (BitVector m)
    template: |-
      -- unconcatBitVector begin
      ~GENSYM[unconcatBitVectorIter_loop][2] : for ~GENSYM[i][3] in ~RESULT'range generate
        ~RESULT(~RESULT'high - ~SYM[3]) <= ~VAR[vec][2](((~SYM[3] * ~LIT[1]) + ~LIT[1] - 1) downto (~SYM[3] * ~LIT[1]));
      end generate;
      -- unconcatBitVector end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.rotateLeftS
    kind: Declaration
    type: 'rotateLeftS ::
      KnownNat n => Vec n a -> SNat d -> Vec n a'
    template: |-
      -- rotateLeftS begin
      ~GENSYM[rotateLeftS][0] : block
        constant ~GENSYM[shift_amount][2] : natural := ~LIT[2] mod ~LIT[0];
      begin
        ~GENSYM[no_shift][3] : if ~SYM[2] = 0 generate
          ~RESULT <= ~VAR[vec][1];
        end generate;

        ~GENSYM[do_shift][4] : if ~SYM[2] /= 0 generate
          ~RESULT <= ~VAR[vec][1](~SYM[2] to ~LIT[0]-1) &
                     ~VAR[vec][1](0 to ~SYM[2]-1);
        end generate;
      end block;
      -- rotateLeftS end
    workInfo: Never
- BlackBox:
    name: Clash.Sized.Vector.rotateRightS
    kind: Declaration
    type: 'rotateRightS ::
      KnownNat n => Vec n a -> SNat d -> Vec n a'
    template: |-
      -- rotateRightS begin
      ~GENSYM[rotateLeftS][0] : block
        constant ~GENSYM[shift_amount][2] : natural := ~LIT[2] mod ~LIT[0];
      begin
        ~GENSYM[no_shift][3] : if ~SYM[2] = 0 generate
          ~RESULT <= ~VAR[vec][1];
        end generate;

        ~GENSYM[do_shift][4] : if ~SYM[2] /= 0 generate
          ~RESULT <= ~VAR[vec][1](~LIT[0]-~SYM[2] to ~LIT[0]-1) &
                     ~VAR[vec][1](0 to ~LIT[0]-~SYM[2]-1);
        end generate;
      end block;
      -- rotateRightS end
    workInfo: Never
