2012-11-03 1 views
6

Ich versuche, Zeitmultiplexing zu implementieren, um eine 7-Segment-Anzeige mit 4 Ziffern zu fahren: Das Gerät verfügt über 7 Datenbeine und 4 Anoden, also wenn Sie vier anzeigen möchten verschiedene Ziffern, müssen Sie zuerst die Anoden auf 0001 setzen und die Datenbeine zu Ihren Segmenten; Setzen Sie nach einer Weile die Anoden auf 0010 und aktualisieren Sie die Datenbeine; und so weiter.Indizieren einer Matrix von Matrizen mit einem Signal in Kansas Lava

Ich versuche, dies in Kansas Lava zu implementieren. Der Xilinx-Compiler weist den generierten VHDL jedoch mit einem Typfehler zurück (und ich betrachte den generierten Code, denke ich, dass er richtig ist).

zuerst, meine Lava-Code: Es implementiert im Grunde genommen ein Signal der Sequenz [0, 1, 2, 3, 0, ...], verwendet den Operator von .!.Language.KansasLava.Signal zum Indizieren in die Matrix-of-Matrizen-Parameter. Der Anodenwert wird erzeugt, indem bei jedem Zeitschritt nach links 0001 gedreht wird.

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

Also, wenn ich versuche, das erzeugte VHDL zu kompilieren, erhalte ich diese Fehlermeldung:

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. 

Die entsprechenden Zeilen aus hello.vhdl sind:

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))); 

Die Art der sig_24_o0 scheint falsch ; Ich denke, es sollte entweder array (6 downto 0) of std_logic_vector(0 downto 0) oder std_logic_vector(6 downto 0) sein, aber ich weiß nicht, was Lava diese std_logic_vector(0 downto 0) verwendet.

Antwort

1

landete ich pro-Draht durch Multiplexen, um dieses nach oben arbeiten statt Multiplexen des gesamten Bus:

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

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

mit der Hilfsfunktion

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 

Der VHDL erzeugt durch diese kompiliert ganz gut; obwohl ich keine Ahnung habe, ob es die resultierende Schaltung komplizierter macht (oder vielleicht sogar einfacher).

+0

Andy Gill, Betreuer von Kansas Lava, hat mir per Mail mitgeteilt, dass dies tatsächlich wie ein Insekt in Lava selbst aussieht. Ich akzeptiere diese Antwort als eine effektive Umgehungslösung. – Cactus

Verwandte Themen