Hallöchen, hat jemand einen Tip, wie ich serielle Daten in VHDL in parallele Daten umwandeln kann? Link oder Quelle reicht mir auch! Danke schonmal Björn
an sich ein simples Schieberegister, seriell rein, die einzelnen Taps geben am Ende des Einschiebens (zB nach 8 Takten) die Daten parallel wieder. Bsp. gibt's zu Hauf beim googeln; ich mogel mich aber selber an einer Musterimpl. hier vorbei ;-) BTW, der "concat" Operator ist in VHDL das "&". Wenn Du soetwas findest, bist Du bereits recht nahe 'dran. Viele Grüße Olaf
Danke Olaf, ich probiere dann mal mein Glück und melde mich später :-) Ciao und schönes WE Björn
Hier ist was aus einem alten Design: 16Bit zu parallel mit Latch. -- VHDL Entity adc_aquisor_lib.serial2parallel.symbol -- -- Created: by - jschuhm.ti.com (ASICundFPGA-Rechner4) -- at - 14:25:58 28.11.2004 -- LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; ENTITY serial2parallel IS PORT( clk_en : IN std_logic; clock : IN std_logic; inputserial : IN std_logic; readenable : IN std_logic; reset : IN std_logic; output : OUT std_logic_vector (15 DOWNTO 0) ); END serial2parallel ; -- VHDL Architecture adc_aquisor_lib.serial2parallel.symbol LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; ARCHITECTURE struct OF serial2parallel IS -- Internal signal declarations SIGNAL parallel : std_logic_vector(15 DOWNTO 0); SIGNAL updown : std_logic; -- signal declarations for instance 'localshifter' of 'shiftsp' SIGNAL mw_localshifterreg_cval : std_logic_vector(15 DOWNTO 0); SIGNAL mw_localshifterreg_nval : std_logic_vector(15 DOWNTO 0); BEGIN updown <= '1'; <- vorwaerts zaehlen -- instance 'locallatch' locallatchcombo_proc: PROCESS (readenable, reset, parallel) BEGIN IF (reset = '1' OR reset = 'H') THEN output <= "0000000000000000"; ELSIF (reset = '0' OR reset = 'L') THEN IF (readenable = '1' OR readenable = 'H') THEN output <= parallel; END IF; END IF; END PROCESS locallatchcombo_proc; -- 'localshifter' parallel <= mw_localshifterreg_cval; localshifterseq_proc: PROCESS (clock, reset) BEGIN IF (reset = '1' OR reset = 'H') THEN mw_localshifterreg_cval <= "0000000000000000"; ELSIF (clock'EVENT AND clock='1') THEN IF (clk_en = '1' OR clk_en = 'H') THEN mw_localshifterreg_cval <= mw_localshifterreg_nval; END IF; END IF; END PROCESS localshifterseq_proc; localshiftercombo_proc: PROCESS (updown, inputserial, mw_localshifterreg_cval) VARIABLE temp_dout : std_logic_vector(17 DOWNTO 0); BEGIN IF (updown = '1' OR updown = 'H') THEN temp_dout := inputserial & inputserial & mw_localshifterreg_cval; ELSIF (updown = '0' OR updown = 'L') THEN temp_dout := mw_localshifterreg_cval & inputserial & inputserial; ELSE temp_dout := (OTHERS => 'X'); END IF; mw_localshifterreg_nval <= temp_dout(16 DOWNTO 1); END PROCESS localshiftercombo_proc; -- Instance port mappings. END struct;
Bonjour, danke Jürgen für den ausführlichen Quelltext. Hatte es mit Olafs Variante mal probiert. Sieht jetzt so aus als würde es funzen. Kann die Daten aber nochnicht verifizieren. Ist das denn richtig, das der & Operator gleichzeitig das neue Bit von rechts reinschiebt und somit eine Shiftfunktion erübrigt? also würde '10' & '1' zu '101' ? jetzt mal abgesehen davon, ob ich die syntac richtig habe. also meine Version: sipo:process variable reg : std_logic_vector(BITS-1 downto 0); variable n : natural; begin wait until rising_edge(ADU_SCLK); if ADU_DRDY = '0' then n := 15; end if; if n > 0 then reg := reg(BITS-2 downto 0) & ADU_DOUT; -- n := n-1; else n := n; end if; if n = 0 then FD <= reg; end if; end process sipo; Er setzt hier einen 16Bit seriellen Wert um und weisst ihnam Ende FD zu. ADU_DOUT liefert immer ein Bit. Richtig so oder irgendwelche Ergänzungen? Danke Björn
>Ist das denn richtig, das der & Operator gleichzeitig das neue Bit von >rechts reinschiebt und somit eine Shiftfunktion erübrigt? nein, der & Op "klebt" im Grunde nur zusammen. In der Zeile siehst Du auch, dass das linke Arg von & um 1 verkürzt wurde. Anonsten gäb's Mecker vom compiler.
1 | reg := reg(BITS-2 downto 0) & ADU_DOUT; |
Viele Grüße Olaf
Hi Olaf, danke für die Antwort. Dabei klebt der & Operator ein Bit (ADU_DOUT) von rechts dran. Das linke Argument wird um eins verkürzt, aber wo? wird dies links oder rechts abgeschnitten? Für meine Anwendung muss es links rausfallen und ich hänge rechts das neue Bit dran. Ich hoffe das klappt so... :-) Was meinst Du ? Danke Björn
jo, links. Man muss dabei beachten, dass es zwei Zählweisen gibt:
1 | std_logic_vector(7 downto 0) |
und
1 | std_logic_vector(0 to 7) |
Beide sind 8 bit lang, aber das Indexierungsergebnis ist jeweils ein Anderes (das gleiche gilt, wenn Du mal irgendwann die attribute einsetzt). Generell ist es klug, nur eine zu verwenden. Meist gibts Du zB. die BIT_WIDTH mit 8 an, d.h. bei der Deklaration schreibst Du dann:
1 | std_logic_vector(BIT_WIDTH-1 downto 0) |
um zur obigen Dekl. zu kommen. Konsequenter Weise musst Du dann
1 | std_logic_vector(BIT_WIDTH-2 downto 0) |
bzw. bei Dir
1 | reg(BITS-2 downto 0) & ADU_DOUT; |
schreiben, um das obere Bit "rauszuschubsen" und das untere "anzuheften". Viele Grüße Olaf
Hallo Leute, vielen Dank für Eure Antworten! Das hat mir sehr geholfen. Somit weiss ich das der Teil funktionieren müsste. Leider ist an meiner Schaltung noch irgendwas im Argen. Werde mich mal wider melden, wenn ich das geregelt habe! Ciao Björn
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.