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
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.
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;
> 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
1
if(C'eventandC='1')then
2
tmp<=tmp(62downto0)&SLI;
3
endif;
64 Register benötigt (das ist so gewollt)
und 2) dein Ausgangslatch
1
if(Enable='1')then
2
Q<=tmp;
3
endif;
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.
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):
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useieee.numeric_std.ALL;
4
5
entitytest1is
6
port(C:instd_logic;-- clock
7
SerialIn:instd_logic;-- serial input
8
Enable:instd_logic;-- latch-enable
9
Qs:outstd_logic;-- 1bit Ausgang, soll sofort durchgeclocked werden
10
Q:outstd_logic_vector(63downto0));-- latched Ausgang, nur aktiv bei enable='1'
11
endtest1;
12
13
architectureBEHAVIORALoftest1is
14
signalsq:std_logic_vector(q'range);
15
begin
16
17
process(c)
18
begin
19
ifrising_edge(c)then
20
sq<=sq(sq'high-1downto0)&SerialIn;
21
Qs<=sq(q'high);
22
endif;
23
endprocess;
24
25
process(c,enable)
26
begin
27
ifenable='1'then-- mit "if rising_edge(c) and enable = '1' then" funktioniert es nicht?
@ 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.
1
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.
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useieee.numeric_std.ALL;
4
5
entitytest1is
6
port(clk:instd_logic;-- clock
7
SerialIn:instd_logic;-- serial input
8
load:instd_logic;-- Ausgangsregister laden
9
Enable:instd_logic;-- latch-enable
10
SerialOut:outstd_logic;-- Serieller Ausgang,
11
Q:outstd_logic_vector(63downto0));-- latched Ausgang, nur aktiv bei enable='1'