Skip to content

Instantly share code, notes, and snippets.

@martijnbastiaan
Last active June 12, 2019 13:18
Show Gist options
  • Save martijnbastiaan/84bf196ae180b39b9968145d625ac649 to your computer and use it in GitHub Desktop.
Save martijnbastiaan/84bf196ae180b39b9968145d625ac649 to your computer and use it in GitHub Desktop.
[ { "BlackBox" :
{ "name" : "BlockRamHack.blockRam1#"
, "type" :
"blockRam#
:: HasCallStack -- ARG[0]
=> Clock dom gated -- clk, ARG[1]
-> Vec n a -- init hack ARG[2]
-> a -- init, ARG[3]
-> Signal dom Int -- rd, ARG[4]
-> Signal dom Bool -- wren, ARG[5]
-> Signal dom Int -- wr, ARG[6]
-> Signal dom a -- din, ARG[7]
-> Signal dom a"
, "templateD" :
"-- blockRam begin
~GENSYM[~COMPNAME_blockRam][0] : block
signal ~GENSYM[RAM][1] : ~TYP[2] := ~TYPM[2]'(0 to ~LENGTH[~TYP[2]]-1 => ~IF ~VIVADO ~THEN ~TOBV[~TYPM[3]'(~LIT[3])][~TYP[3]] ~ELSE ~LIT[3] ~FI);
signal ~GENSYM[rd][3] : integer range 0 to ~LENGTH[~TYP[2]] - 1;
signal ~GENSYM[wr][4] : integer range 0 to ~LENGTH[~TYP[2]] - 1;~IF ~ISGATED[1] ~THEN
signal ~GENSYM[clk][5] : std_logic;
signal ~GENSYM[ce][6] : boolean;~ELSE ~FI
begin
~SYM[3] <= to_integer(~ARG[4])
-- pragma translate_off
mod ~LENGTH[~TYP[2]]
-- pragma translate_on
;
~SYM[4] <= to_integer(~ARG[6])
-- pragma translate_off
mod ~LENGTH[~TYP[2]]
-- pragma translate_on
;
~IF ~VIVADO ~THEN ~IF ~ISGATED[1] ~THEN
(~SYM[5],~SYM[6]) <= ~ARG[1];
~GENSYM[blockRam_sync][7] : process(~SYM[5])
begin
if rising_edge(~SYM[5]) then
if ~SYM[6] then
if ~ARG[5] then
~SYM[1](~SYM[4]) <= ~TOBV[~ARG[7]][~TYP[7]];
end if;
~RESULT <= fromSLV(~SYM[1](~SYM[3]))
-- pragma translate_off
after 1 ps
-- pragma translate_on
;
end if;
end if;
end process;~ELSE
~SYM[7] : process(~ARG[1])
begin
if rising_edge(~ARG[1]) then
if ~ARG[5] then
~SYM[1](~SYM[4]) <= ~TOBV[~ARG[7]][~TYP[7]];
end if;
~RESULT <= fromSLV(~SYM[1](~SYM[3]))
-- pragma translate_off
after 1 ps
-- pragma translate_on
;
end if;
end process;~FI ~ELSE ~IF ~ISGATED[1] ~THEN
(~SYM[5],~SYM[6]) <= ~ARG[1];
~SYM[7] : process(~SYM[5])
begin
if rising_edge(~SYM[5]) then
if ~ARG[5] and ~SYM[6] then
~SYM[1](~SYM[4]) <= ~ARG[7];
end if;
if ~SYM[6] then
~RESULT <= ~SYM[1](~SYM[3])
-- pragma translate_off
after 1 ps
-- pragma translate_on
;
end if;
end if;
end process;~ELSE
~SYM[7] : process(~ARG[1])
begin
if rising_edge(~ARG[1]) then
if ~ARG[5] then
~SYM[1](~SYM[4]) <= ~ARG[7];
end if;
~RESULT <= ~SYM[1](~SYM[3])
-- pragma translate_off
after 1 ps
-- pragma translate_on
;
end if;
end process;~FI ~FI
end block;
--end blockRam"
}
}
]
{-# LANGUAGE MagicHash #-}
module BlockRamHack where
import Data.Maybe (fromJust, isJust)
import Clash.Prelude
import qualified Clash.Explicit.Prelude as E
import Clash.Explicit.BlockRam (blockRam#)
import GHC.Stack (HasCallStack, withFrozenCallStack)
blockRam1#
:: HasCallStack
=> Clock dom gated
-> Vec n a
-> a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRam1# clk vec a rd wren wr din =
blockRam# clk (map (const a) vec) rd wren wr din
{-# NOINLINE blockRam1# #-}
blockRam1E
:: HasCallStack
=> Enum addr
=> Clock dom gated
-> SNat n
-> a
-> Signal dom addr
-> Signal dom (Maybe (addr, a))
-> Signal dom a
blockRam1E = \clk n a rd wrM ->
let en = isJust <$> wrM
(wr,din) = unbundle (fromJust <$> wrM)
in withFrozenCallStack
(blockRam1# clk (replicate n a) (fromEnum <$> rd) en (fromEnum <$> wr) din)
{-# INLINE blockRam1E #-}
blockRam1
:: (Enum addr, HiddenClock domain gated, HasCallStack)
=> SNat n
-> a
-> Signal domain addr
-> Signal domain (Maybe (addr, a))
-> Signal domain a
blockRam1 = \n a rd wrM -> withFrozenCallStack
(hideClock E.blockRam1E n a rd wrM)
{-# INLINE blockRam1 #-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment