Срок доступа к тактовой частоте - PullRequest
0 голосов
/ 08 сентября 2018

Я хотел бы получить доступ к тактовой частоте (в Гц) в качестве значения уровня термина, чтобы я мог использовать ее в счетчиках.

Один из способов, который мне удалось найти, заключается в распаковке уровня типа Dom ain в его тактовый период (в пс), а затем преобразовании его в тактовую частоту. Однако для этого требуется дополнительное ограничение KnownNat ps, которое затем будет заражать все, кто пытается его использовать, вплоть до topLevel:

clkPeriod :: forall dom gated name ps. (dom ~ Dom name ps, KnownNat ps) => Clock dom gated -> Integer
clkPeriod clk = natVal (Proxy :: Proxy ps)

clkRate :: (dom ~ Dom name ps, KnownNat ps) => Clock dom gated -> Integer
clkRate clk = 10^12 `div` clkPeriod clk

Другой способ избежать введения дополнительного ограничения KnownNat состоит в том, чтобы импортировать Clash.Signal.Internal и сопоставление с шаблоном в Clock, поскольку он содержит SNat свидетель периода:

import Clash.Signal.Internal (Clock(..))

clkPeriod :: Clock dom gated -> Integer
clkPeriod (Clock _ period) = snatToInteger period
clkPeriod (GatedClock _ period _) = snatToInteger period

clkRate :: Clock dom gated -> Integer
clkRate clk = 10^12 `div` clkPeriod clk

но это разбивает синтезатор (думаю, мне не следует импортировать Clash.Signal.Internal):

*** Exception: Clash.Rewrite.Util(566): 
Can't create selector ("Clash.Normalize.Transformations(1136):doPatBndr",1,0) for:
($dKnownNat23000 :: GHC.Natural.Natural)

Additional info: TyCon has no DataCons: 
Name {nameSort = User, nameOcc = GHC.Natural.Natural3674937295934324782, nameLoc = UnhelpfulSpan "<no location info>"} GHC.Natural.Natural3674937295934324782

Вот полный модуль, демонстрирующий эту проблему (я попытался синтезировать его с :vhdl, чтобы получить вышеуказанную ошибку):

module Test where

import Clash.Prelude hiding (clkPeriod)
import Data.Word
import Clash.Signal.Internal (Clock(..))

type FromHz rate = 1000000000000 `Div` rate
type Dom25 = Dom "CLK_25MHZ" (FromHz 25175000)

topEntity
    :: Clock Dom25 Source
    -> Reset Dom25 Asynchronous
    -> Signal Dom25 Bit
topEntity = exposeClockReset board
  where
    board = boolToBit <$> r

    r = regEn False (counter .==. 0) (not <$> r)
    counter = register clkrt $ mux (counter .==. 0) (pure clkrt) (pred <$> counter)
    clkrt = fromIntegral $ hideClock clkRate

clkPeriod :: Clock dom gated -> Integer
clkPeriod (Clock _ period) = snatToInteger period
clkPeriod (GatedClock _ period _) = snatToInteger period

clkRate :: Clock dom gated -> Integer
clkRate clk = 10^12 `div` clkPeriod clk

У меня вопрос: есть ли способ повысить clkRate на уровне терминов без введения каких-либо дополнительных ограничений KnownNat или импорта каких-либо модулей Internal?

1 Ответ

0 голосов
/ 23 сентября 2018

Похоже, что это было признано первичным разработчиком Clash Кристианом Баайом как ошибка компилятора Clash в Issue # 348 . Цитирую его комментарий в отчете о проблеме:

Итак, проблема в том, что ядро, которое мы получаем, сопоставляется с шаблоном для чего-то типа Integer и раскрывает внутренности его представления; что-то, что компилятор явно не обрабатывает. Я создам обходной путь / хак, чтобы всегда выбирать ветку, где Integer вписывается в диапазон [-2 ^ 63 .. 2 ^ 63-1], поскольку Clash в настоящее время «ошибочно» переводит Integer в 64 в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...