www.mikrocontroller.net

Forum: FPGA, VHDL & Co. 64bit Schieberegister


Autor: Marc X. (tuxscreen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich bin ein Neuling in Sachen VHDL und habe mir mal ein kleines Projekt 
parat gelegt, welches ich gerne mit einem CPLD durchführen möchte.

Ich möchte ein simples 64bit Schieberegister mit Enable (Latch) bauen.

Den unten angefügten Code habe ich mir aus verschiedenen Beispielen 
zusammengestellt und wollte mir mal Eure Verbesserungsvorschläge 
anhören.

Im Moment suche ich auch noch eine Möglichkeit das zu simulieren, aber 
ich finde nichts - hab ich eventuell etwas vergessen zu installieren?
(WebISE 9.2 von Xilinx)

Sehr unsicher war ich mir bei dem 'process..' im Hauptstrang.
Den hab ich eigentlich nur eingefügt um keine Fehlermeldung mehr wegen 
dem 'if' zu bekommen???
Und irgendwie hab ich das Gefühl das ich hier einiges an Ressourcen 
verschwende, ich bekomme das nur in einem rel. großem CPLD (95144) 
synthetisiert?

Danke und Gruß
Marc
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.ALL;



entity BIGSHIFTER is 
  port(C, SLI : in  std_logic;
        Q : out std_logic_vector(63 downto 0));
end BIGSHIFTER;

architecture archi of BIGSHIFTER is
  signal tmp: std_logic_vector(63 downto 0);
  begin
    process (C)
      begin 
        if (C'event and C='1') then 
          tmp <= tmp(62 downto 0)& SLI;
        end if;
    end process;
    Q <= tmp;
end archi;


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.ALL;

entity test1 is
   port ( C      : in    std_logic; 
          SerialIn    : in    std_logic; 
          Enable    : in    std_logic; 
          Q : out   std_logic_vector (63 downto 0));
end test1;

architecture BEHAVIORAL of test1 is
  signal tmp: std_logic_vector(63 downto 0);
   component BIGSHIFTER
      port ( C   : in    std_logic;             
             SLI : in    std_logic; 
             Q   : out   std_logic_vector (63 downto 0));
   end component;
   
begin
   my_shift : BIGSHIFTER
      port map (C=>C,
                SLI=>SerialIn,
                Q(63 downto 0)=>tmp(63 downto 0));
  process (Enable, tmp)
  begin
     if (Enable = '1') then
        Q <= tmp;
     end if;
  end process;
end BEHAVIORAL;


Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code schaut mal gar nicht so schlecht aus, sollte im Prinnzip 
eigentlich funtionieren. Du hast die 2 Funktionen schieben und latchen 
getrennt, das ist OK und verschwendet keine Resource. Man kann das 
sicher auch in einem Prozess zusammenfassen.
Anmerkungen :
- Die libraries STD_LOGIC_ARITH, STD_LOGIC_UNSIGNED und numeric_std 
werden nicht benötigt. Numeric_std und std_logic beißen sich sogar, Du 
solltest nur numeric_std verwenden. Aber in diesem Fall, wie gesagt, 
wird sie überhaupt nicht benötigt, da Du keine einfachen Berechnung 
(z.B. Addition) in diesem Beispiel verwendest.
- Du solltest rising_edge(clock) schreiben, nicht
  clock'event and clock = '1'
- Der Eingang enable ist eigentlich kein enable, jedenfall nicht im 
Sinne dass er das Shiften enabled, sondern wirkt als Übernahme-Latch für 
den Ausgang. Ist das so gewollt?
- Latches sind zwar möglich, aber man sollte sie besser vermeiden 
solange man sie nicht unbedingt benötigt. Besser wäre die Übernahme vom 
Shiftregister an die Ausgänge auch taktsynchron zu machen.
- Zum Simulieren gibt es mehrere Möglichkeiten :
Bei der ISE ist ein Simulator normalerweise dabei, man kann soviel ich 
weiss sogar automatisch eine Testbench erstellen. Beide werden von mir 
nie verwendet.
Besser ist es, Du lädst Dir ModelSim Starter Edition von der Xilinx 
Homepage herunter. Dann schreibst Du Dir eine Testbench, das ist ein 
weiteres VHDL Programm, das deine Schieberregister test1 als Komponente 
aufruft. Diese Testbench hat keine Eingangs- und Ausgangsports mehr, 
sonden alle Signale werden in der Testbench nach deinen Wünschen mittels 
Zuweisungen vom Type a <= '1' after 100 ns; erzeugt.

Autor: Thomas Reinemann (Firma: abaxor engineering) (abaxor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

so aufwendig musst du es nicht machen. Im Prinzip musst du nur so etwas 
wie

         sq <= sq (sq'high - 1 downto 0) & SerialIn;

in einen Prozess einbetten.
Denn fogenden Code habe ich nicht getestet.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- wenn schon dann das Package, hier brauchst du es aber auch nicht
use ieee.numeric_std.ALL;
-- die folgenden Packages braucht man nie :-)
--use IEEE.STD_LOGIC_ARITH.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity test1 is
   port ( C      : in    std_logic;
          SerialIn    : in    std_logic;
          Enable    : in    std_logic;
          Q : out   std_logic_vector (63 downto 0));
end test1;

architecture BEHAVIORAL of test1 is
   signal sq : std_logic_vector (q'range);
begin

q <= sq;

  process (c)
  begin
     if rising_edge(c) then
       if enable = '1' then
         sq <= sq (sq'high - 1 downto 0) & SerialIn;
       end if;
     end if;
  end process;
end BEHAVIORAL;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Und irgendwie hab ich das Gefühl das ich hier einiges an Ressourcen
> verschwende, ich bekomme das nur in einem rel. großem CPLD (95144)
> synthetisiert?
Ja, es ist nun mal so, dass du 2 mal 64 Register brauchst:

weil  1) dein Schieberegister
        if (C'event and C='1') then 
          tmp <= tmp(62 downto 0)& SLI;
        end if;
64 Register benötigt (das ist so gewollt)

und  2) dein Ausgangslatch
     if (Enable = '1') then
        Q <= tmp;
     end if;
auch nochmal 64 Register braucht (ist das so gewollt?)

In der Summe 128 Register,
das passt dann in einen 9572 (= 72 FFs) schon nicht mehr rein.

Und wie Thomas schon geschrieben hat, willst du das wahrscheinlich gar 
nicht, was dein Code macht: der shiftet dauernd, und das Ergebnis wird 
am Ausgang sichtbar, solange enable='1' ist.

Autor: Marc X. (tuxscreen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für Eure ausführlichen Antworten.

Das Ganze ist zur Steuerung einer 8x8 LED-Matrix und da hab ich dann 
endlich mal den Sinn und Zweck eines CPLDs zu nutzen versucht.

Ich möchte in das Schieberegister ein neues Datum reinschieben und 
dieses soll erst zu einem bestimmten Zeitpunkt (am Ende) an die Ausgänge 
übernommen werden, da ich ein zwischenzeitliches Flackern vermeiden 
will.

In dem anderen Fall (enable = '0') will ich noch entscheiden ob die 
Ausgänge high, low oder tristate sind. Wie würde eine solche Zuweisung 
aussehen? Also, wie weise ich dem 64bit Register 64bittig tri-state zu?

Ich möchte noch einen 1bit Ausgang hinzufügen, aus welchem die Bits 
seriell hinausgeschoben werden, sodaß ich mehrere dieser Bausteine 
miteinander verbinden kann. Also quasi das Q'S eines 4094 
Schieberegisters.

Folgender Code soll dies bewerkstelligen (Dank an Thomas):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.ALL;

entity test1 is
   port ( C:       in std_logic; -- clock
          SerialIn: in std_logic; -- serial input
          Enable:   in std_logic; -- latch-enable
       Qs: out std_logic;   -- 1bit Ausgang, soll sofort durchgeclocked werden
          Q : out std_logic_vector (63 downto 0)); -- latched Ausgang, nur aktiv bei enable='1'
end test1;

architecture BEHAVIORAL of test1 is
   signal sq : std_logic_vector (q'range);
begin

  process (c)
  begin
     if rising_edge(c) then
         sq <= sq (sq'high - 1 downto 0) & SerialIn;
         Qs <= sq(q'high);
       end if;
  end process;

  process (c, enable)
  begin
    if enable = '1' then -- mit "if rising_edge(c) and enable = '1' then" funktioniert es nicht?
      q <= sq;
    else
       q <= "0000000000000000000000000000000000000000000000000000000000000000"; 
      -- geht das auch 'übersichtlicher' ? eventuell auch in Abhängigkeit von range?
    end if;
  end process;
  
end BEHAVIORAL;


Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Marc Wetzel (tuxscreen)

>Ich möchte in das Schieberegister ein neues Datum reinschieben und
>dieses soll erst zu einem bestimmten Zeitpunkt (am Ende) an die Ausgänge

>Ausgänge high, low oder tristate sind. Wie würde eine solche Zuweisung
>aussehen? Also, wie weise ich dem 64bit Register 64bittig tri-state zu?

Also willst du quasi einen 74HC595 als 64 Bit Version nachbauen? Das 
braucht aber 128 FlipFlops.

Einen Vektor komplett auf einen Wert zuzuweisen geht einfach.

mein_vektor <= (others=>'Z');

>Ich möchte noch einen 1bit Ausgang hinzufügen, aus welchem die Bits
>seriell hinausgeschoben werden, sodaß ich mehrere dieser Bausteine
>miteinander verbinden kann.

Nichts leichter als das.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.ALL;

entity test1 is
   port ( clk       : in std_logic; -- clock
          SerialIn  : in std_logic; -- serial input
          load      : in std_logic; -- Ausgangsregister laden
          Enable    : in std_logic; -- latch-enable
          SerialOut : out std_logic; -- Serieller Ausgang, 
          Q         : out std_logic_vector (63 downto 0)); -- latched Ausgang, nur aktiv bei enable='1'
end test1;

architecture BEHAVIORAL of test1 is
   signal data_shift : std_logic_vector (q'range);
   signal data_out   : std_logic_vector (q'range);
begin

-- direkte Zuweisungen

SerialOut <= data_shift(q'high);

-- Schieberegister, getaktet

  process (clk)
  begin
     if rising_edge(clk) then
       if load ='0' then
         data_shift <= data_shift (sq'high - 1 downto 0) & SerialIn;         
       else
         data_out <= data_shift;
       end if;
     end if;
  end process;

-- Tristate Steuerung, kombinatorisch

  process (enable, sq)
  begin
    if enable = '1' then
      q <= data_out;
    else
      q <= (others => 'Z');
    end if; 
  end process;
  
end BEHAVIORAL;

MfG
Falk

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.