www.mikrocontroller.net

Forum: FPGA, VHDL & Co. CPLD Seriell zu Parallel


Autor: Björn Specht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: ope (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Björn Specht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Olaf,

ich probiere dann mal mein Glück und melde mich später :-)

Ciao und schönes WE

Björn

Autor: Jürgen Schuhmacher (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: Björn Specht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: ope (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.
reg := reg(BITS-2 downto 0) & ADU_DOUT;

Viele Grüße
Olaf

Autor: Björn Specht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
links!

Autor: ope (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jo, links. Man muss dabei beachten, dass es zwei Zählweisen gibt:
std_logic_vector(7 downto 0)
und
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:
std_logic_vector(BIT_WIDTH-1 downto 0)
um zur obigen Dekl. zu kommen. Konsequenter Weise musst Du dann
std_logic_vector(BIT_WIDTH-2 downto 0)
bzw. bei Dir
reg(BITS-2 downto 0) & ADU_DOUT; 
schreiben, um das obere Bit "rauszuschubsen" und das untere
"anzuheften".

Viele Grüße
Olaf

Autor: Björn Specht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.