gpt4 book ai didi

haskell - 在堪萨斯熔岩中用信号索引矩阵矩阵

转载 作者:行者123 更新时间:2023-12-02 06:26:34 25 4
gpt4 key购买 nike

我正在尝试实现时间复用来驱动 4 位数字的 7 段显示器:该设备有 7 个数据腿和 4 个阳极,因此如果要显示四个不同的数字,则必须将阳极设置为 0001首先是您的分割市场的数据腿;然后过了一会儿,将阳极设置为0010并更新数据腿;等等。

我正在尝试在堪萨斯熔岩中实现这一点。然而,Xilinx 编译器拒绝生成的 VHDL,并出现类型错误(查看生成的代码,我认为这是正确的)。

首先,我的 Lava 代码:它基本上实现了序列 [0, 1, 2, 3, 0, ...] 的信号,然后使用 .!. 中的 Language.KansasLava.Signal 运算符来索引到矩阵矩阵参数。阳极值是通过在每个时间步向左旋转 0001 生成的。

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DataKinds #-}
import Language.KansasLava
import Hardware.KansasLava.Boards.Papilio.LogicStart -- from http://github.com/gergoerdi/kansas-lava-papilio
import Data.Sized.Matrix
import Data.Sized.Unsigned as Unsigned
import Data.Bits

driveSS :: forall clk sig n. (Clock clk, sig ~ Signal clk, Size n, Rep n, Num n, Integral n) => Matrix n (Matrix X7 (sig Bool)) -> SevenSeg clk ActiveLow n
driveSS segss = SevenSeg (fmap bitNot anodes) segs high
where
clkAnode :: sig Bool
clkAnode = divideClk (Witness :: Witness X8)

selector :: sig n
selector = counter clkAnode

segss' :: sig (Matrix n (Matrix X7 Bool))
segss' = pack . fmap pack $ segss

segs :: Matrix X7 (sig Bool)
segs = unpack $ segss' .!. selector

anodes :: Matrix n (sig Bool)
anodes = rotatorL clkAnode

test_sseg :: Fabric ()
test_sseg = do
sw <- switches
let sw' = cropAt sw 1
sseg $ driveSS $ matrix [sw', zero, zero, zero]
where
zero = matrix $ replicate 7 low

divideClk :: forall c sig ix. (Clock c, sig ~ Signal c, Size ix) => Witness ix -> sig Bool
divideClk _ = counter high .==. (0 :: sig (Unsigned ix))

counter :: (Rep a, Num a, Clock c, sig ~ Signal c) => sig Bool -> sig a
counter inc = loop
where
reg = register 0 loop
loop = mux inc (reg, reg + 1)

rotatorL :: (Clock c, sig ~ Signal c, Size ix, Integral ix) => sig Bool -> Matrix ix (sig Bool)
rotatorL step = fromUnsigned loop
where
reg = register 1 loop
loop = mux step (reg, rotateL reg 1)

fromUnsigned :: (sig ~ Signal c, Size ix) => sig (Unsigned ix) -> Matrix ix (sig Bool)
fromUnsigned = unpack . coerce Unsigned.toMatrix

main :: IO ()
main = do
writeVhdlPrelude "lava-prelude.vhdl"
kleg <- reifyFabric $ do
board_init
test_sseg
writeVhdlCircuit "hello" "hello.vhdl" kleg
writeUCF "hello.ucf" kleg

因此,当我尝试编译生成的 VHDL 时,我收到以下错误消息:

ERROR:HDLParsers:800 - "/home/cactus/prog/lava/hello/src/hello.vhdl" Line 85. Type of sig_24_o0 is incompatible with type of sig_28_o0.

来自 hello.vhdl 的相关行是:

type sig_24_o0_type is array (7 downto 0) of std_logic_vector(0 downto 0);
signal sig_24_o0 : sig_24_o0_type;

signal sig_25_o0 : std_logic_vector(1 downto 0);

type sig_28_o0_type is array (3 downto 0) of std_logic_vector(6 downto 0);
signal sig_28_o0 : sig_28_o0_type;

sig_24_o0 <= sig_28_o0(to_integer(unsigned(sig_25_o0)));

sig_24_o0的类型好像不对;我认为它应该是 array (6 downto 0) of std_logic_vector(0 downto 0)std_logic_vector(6 downto 0) ,但我不知道 Lava 使用这些 std_logic_vector(0 downto 0)

最佳答案

我最终通过复用每条线路而不是复用整个总线来解决这个问题:

segss' :: Matrix X7 (Matrix n (sig Bool))
segss' = columns . joinRows $ segss

segs :: Matrix X7 (sig Bool)
segs = fmap (nary selector) segss'

使用辅助函数

nary :: forall a clk sig n. (Clock clk, sig ~ Signal clk, Rep a, Size n, Rep n) => sig n -> Matrix n (sig a) -> sig a
nary sel inps = pack inps .!. sel

由此生成的 VHDL 编译得很好;虽然我不知道它是否会使最终的电路变得更加复杂(或者甚至更简单)。

关于haskell - 在堪萨斯熔岩中用信号索引矩阵矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13211984/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com