2012-11-03 11 views
6

일시적 멀티플렉싱을 구현하여 7 세그먼트 디스플레이를 4 자리로 구동하려고합니다 : 장치에는 7 개의 데이터 다리와 4 개의 애노드가 있으므로 4 개를 표시하려면 다른 숫자를 사용하려면 먼저 양극을 0001으로 설정하고 데이터 다리를 세그먼트에 설정해야합니다. 그런 다음 잠시 후 양극을 0010으로 설정하고 데이터 다리를 업데이트하십시오. 등등.Kansas Lava에서 신호가있는 행렬의 행렬 인덱싱

캔자스 라바에서 구현하려고합니다. 그러나 Xilinx 컴파일러는 생성 된 VHDL을 유형 오류로 거부합니다. 생성 된 코드를 보면 제 생각에는 맞습니다.

처음으로 나의 용암 코드 : 그것은 기본적으로 [0, 1, 2, 3, 0, ...] 시퀀스의 신호를 구현 한 다음 Language.KansasLava.Signal.!. 연산자를 사용하여 matrix-of-matrices 매개 변수에 색인을 지정합니다. 양극 값은 각 시간 단계에서 왼쪽으로 0001을 돌려서 생성됩니다. hello.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. 

관련 라인은 다음과 같습니다 :

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의 유형이 잘못된 것 같다 내가 생성 된 VHDL을 컴파일 할 때

{-# 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 

그래서,이 오류 메시지가 ; 나는 그것이 array (6 downto 0) of std_logic_vector(0 downto 0) 또는 std_logic_vector(6 downto 0)이어야한다고 생각하지만, 용암이 그걸 std_logic_vector(0 downto 0) 님의 용도로 사용하는지 모르겠습니다.

답변

1

나는 당 와이어 대신 다중의 다중에 의해이 문제를 전체 버스 작동 결국이에 의해 생성 된 VHDL은 잘 컴파일

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 

도우미 기능을 사용하여

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

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

을; 비록 그것이 결과 회로를 더 복잡하게 만들지 모르겠지만 (또는 더 단순한).

+0

캔자스 용암의 관리자 인 앤디 길 (Andy Gill)은 개인 메일로 나에게 이것이 실제로 용암 그 자체의 버그처럼 보일 것이라고 나에게 말했다. 나는이 해답을 효과적인 해결책으로 받아들이고있다. – Cactus