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


von Björn Specht (Gast)


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

von ope (Gast)


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

von Björn Specht (Gast)


Lesenswert?

Danke Olaf,

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

Ciao und schönes WE

Björn

von Jürgen Schuhmacher (Gast)


Angehängte Dateien:

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;

von Björn Specht (Gast)


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

von ope (Gast)


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

Viele Grüße
Olaf

von Björn Specht (Gast)


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

von Andi (Gast)


Lesenswert?

links!

von ope (Gast)


Lesenswert?

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

von Björn Specht (Gast)


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

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
Noch kein Account? Hier anmelden.