[ { "BlackBox" :
    { "name" : "Clash.Explicit.Testbench.assert"
    , "kind" : "Declaration"
    , "type" :
"assert
  :: (KnownDomain dom, Eq a, ShowX a)      -- (ARG[0],ARG[1],ARG[2])
  => Clock dom                             -- ARG[3]
  -> Reset dom                             -- ARG[4]
  -> String                                -- ARG[5]
  -> Signal dom a                          -- Checked value  (ARG[6])
  -> Signal dom a                          -- Expected value (ARG[7])
  -> Signal dom b                          -- Return valued  (ARG[8])
  -> Signal dom b"
    , "imports": ["~INCLUDENAME[0].all"]
    , "includes" :
      [ { "name" : "slv2string"
        , "extension" : "vhdl"
        , "template" :
"-- helper function of Clash.Explicit.Testbench.assert
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

package ~INCLUDENAME[0] is
  function slv2string (slv : std_logic_vector) return STRING;
end;

package body ~INCLUDENAME[0] is
  function slv2string (slv : std_logic_vector) return STRING is
     variable result : string (1 to slv'length);
     variable res_l : string (1 to 3);
     variable r : integer;
   begin
     r := 1;
     for i in slv'range loop
        res_l := std_logic'image(slv(i));
        result(r) := res_l(2);
        r := r + 1;
     end loop;
     return result;
  end slv2string;
end;"
        }
      ]
    , "template" :
"-- assert begin
~GENSYM[assert][0] : block
  -- pragma translate_off
  signal ~GENSYM[actual][2] : ~TYP[6];
  signal ~GENSYM[expected][3] : ~TYP[7];
  -- pragma translate_on
begin
  -- pragma translate_off
  ~SYM[2] <= ~ARG[6];
  ~SYM[3] <= ~ARG[7];
  process(~ARG[3]) is
  begin
    if (~IF~ACTIVEEDGE[Rising][0]~THENrising_edge~ELSEfalling_edge~FI(~ARG[3])) then
      assert (toSLV(~SYM[2]) = toSLV(~SYM[3])) report (~LIT[5] & \", expected: \" & ~INCLUDENAME[0].slv2string(toSLV(~SYM[3])) & \", actual: \" & ~INCLUDENAME[0].slv2string(toSLV(~SYM[2]))) severity error;
    end if;
  end process;
  -- pragma translate_on
  ~RESULT <= ~ARG[8];
end block;
-- assert end"
    }
  }
,{ "BlackBox" :
    { "name" : "Clash.Explicit.Testbench.assertBitVector"
    , "kind" : "Declaration"
    , "type" :
"assertBitVector
  :: ( KnownDomain dom        --                 ARG[0]
     , KnownNat n )           --                 ARG[1]
  => Clock dom                --                 ARG[2]
  -> Reset dom                --                 ARG[3]
  -> String                   --                 ARG[4]
  -> Signal dom (BitVector n) -- Checked value  (ARG[5])
  -> Signal dom (BitVector n) -- Expected value (ARG[6])
  -> Signal dom b             -- Return valued  (ARG[7])
  -> Signal dom b"
    , "imports" : ["~INCLUDENAME[0].all"]
    , "includes" :
      [{ "name" : "assertBitVector"
      , "extension" : "vhdl"
      , "template" :
"-- helper functions of Clash.Explicit.Testbench.assertBitVector
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

package ~INCLUDENAME[0] is
  function non_std_match (l, r : std_logic_vector) return boolean;
  function slv2string (slv : std_logic_vector) return STRING;
end;

package body ~INCLUDENAME[0] is
  type match_table_type is array (std_ulogic, std_ulogic) of boolean;
  constant match_table: match_table_type :=
    ('0' | 'L' => ('0' | 'L' | '-' => true, others => false),
     '1' | 'H' => ('1' | 'H' | '-' => true, others => false),
     '-' => ('-' => true, others => false),
     others    =>             ('-' => true, others => false)
    );
  -- non_std_match is like std_match
  -- But only accepts '-' as don't care in its the second argument r.
  function non_std_match (l, r : std_logic_vector) return boolean is
    alias la : std_logic_vector (l'length downto 1) is l;
    alias ra : std_logic_vector (r'length downto 1) is r;
  begin
    for i in l'range loop
       if not match_table (l (i), r (i)) then
         return false;
       end if;
    end loop;
    return true;
  end non_std_match;

  function slv2string (slv : std_logic_vector) return STRING is
     variable result : string (1 to slv'length);
     variable res_l : string (1 to 3);
     variable r : integer;
   begin
     r := 1;
     for i in slv'range loop
        res_l := std_logic'image(slv(i));
        result(r) := res_l(2);
        r := r + 1;
     end loop;
     return result;
  end slv2string;

end;
"
      }]
    , "template" :
"-- assertBitVector begin
~GENSYM[assert][0] : block
  -- pragma translate_off
  signal ~GENSYM[actual][2] : ~TYP[5];
  signal ~GENSYM[expected][3] : ~TYP[6];
  -- pragma translate_on
begin
  -- pragma translate_off
  ~SYM[2] <= ~ARG[5];
  ~SYM[3] <= ~ARG[6];
  process(~ARG[2]) is
  begin
    if (~IF~ACTIVEEDGE[Rising][0]~THENrising_edge~ELSEfalling_edge~FI(~ARG[2])) then
      assert (~INCLUDENAME[0].non_std_match(toSLV(~SYM[2]),toSLV(~SYM[3]))) report (~LIT[4] & \", expected: \" & ~INCLUDENAME[0].slv2string(toSLV(~SYM[3])) & \", actual: \" & ~INCLUDENAME[0].slv2string(toSLV(~SYM[2]))) severity error;
    end if;
  end process;
  -- pragma translate_on
  ~RESULT <= ~ARG[7];
end block;
-- assertBitVector end"
    }
  }
, { "BlackBox" :
    { "name" : "Clash.Explicit.Testbench.tbClockGen"
    , "workInfo"  : "Always"
    , "kind" : "Declaration"
    , "warning" : "Clash.Signal.Internal.tbClockGen is not synthesizable!"
    , "type" :
"tbClockGen
  :: KnownDomain dom     -- ARG[0]
  => Signal dom Bool     -- ARG[1]
  -> Clock dom"
    , "comment" :
        "ModelSim and Vivado seem to round time values to an integer number of picoseconds.
        Use two half periods to prevent rounding errors from affecting the full period."
    , "template" :
"-- tbClockGen begin
-- pragma translate_off
~GENSYM[clkGen][0] : process is
  constant ~GENSYM[half_periodH][1] : time := ~PERIOD[0]000 fs / 2;
  constant ~GENSYM[half_periodL][2] : time := ~PERIOD[0]000 fs - ~SYM[1];
begin
  ~RESULT <= ~IF~ACTIVEEDGE[Rising][0]~THEN'0'~ELSE'1'~FI;
  wait for 3000 ps;
  while ~ARG[1] loop
    ~RESULT <= not ~RESULT;
    wait for ~SYM[1];
    ~RESULT <= not ~RESULT;
    wait for ~SYM[2];
  end loop;
  wait;
end process;
-- pragma translate_on
-- tbClockGen end"
    }
  }
, { "BlackBox" :
    { "name" : "Clash.Explicit.Testbench.tbEnableGen"
    , "workInfo" : "Always"
    , "kind" : "Declaration"
    , "type" : "tbEnableGen :: Enable dom"
    , "template" : "~RESULT <= true;"
    }
  }
]