Ich versuche, die strukturelle Implementierung des Ringzählers zu implementieren. Ich bekomme diesen Fehler:
ERROR:Xst:528 - Multisource in Unit <ringcounter> bei Signal <count<3>>; Dieses Signal ist mit mehreren Treibern verbunden.
Ich konnte es erfolgreich simulieren. Dieses Modul ist Teil des Projekts, das ich umsetze!..
Hier ist mein VHDL-Code:
entity DFF is
Port (
reset : in STD_LOGIC;
clk : in STD_LOGIC;
D : in STD_LOGIC;
Q : out STD_LOGIC);
end DFF;
architecture Behavioral of DFF is
begin
process(clk,reset)
begin
if reset = '1' then
Q <= '0'; -- clear register
elsif (clk'event and clk = '1') then
Q<=D; --positive edge of clock is used
end if;
end process;
end Behavioral;
--Code for ring counter
entity ringcounter is
Port ( reset : in STD_LOGIC;
clk : in STD_LOGIC;
count : out STD_LOGIC_VECTOR (3 downto 0));
end ringcounter;
architecture Behavioral of ringcounter is
signal q0,q1,q2,q3 : STD_LOGIC : = '0'; ---initialising the signals
--signal temp :STD_LOGIC : = '1'; --not using it as of now.
component DFF is
Port ( reset : in STD_LOGIC;
clk : in STD_LOGIC;
D : in STD_LOGIC;
Q : out STD_LOGIC);
end component;
begin
q3<= '1';
DFF1: DFF port map(reset,clk,q3,q0);
DFF2: DFF port map(reset,clk,q0,q1);
DFF3: DFF port map(reset,clk,q1,q2);
DFF4: DFF port map(reset,clk,q2,q3);
count <= q3&q2&q1&q0;
end Behavioral;
Was läuft schief?
bearbeiten
Ich habe die Änderungen wie vorgeschlagen vorgenommen, aber während der Simulation wird die Ausgabe nicht für die Ringzählerausgabe aktualisiert, obwohl ich die Uhr angegeben habe! Die Ausgabe ist noch undefiniert!
Unten ist der geänderte Code
entity DFF is
Port ( reset : in STD_LOGIC;
clk : in STD_LOGIC;
D : in STD_LOGIC;
Q : out STD_LOGIC);
end DFF;
architecture Behavioral of DFF is
begin
process(clk,reset)
begin
if reset='1' then
Q <= '0'; -- clear register
elsif (clk'event and clk='1') then
Q<=D; --positive edge of clock is used
end if;
end process;
end Behavioral;
------------CODE OF RING COUNTER-----------------------
entity ringcounter is
Port ( reset : in STD_LOGIC;
clk : in STD_LOGIC;
count : out STD_LOGIC_VECTOR (3 downto 0));
end ringcounter;
architecture Behavioral of ringcounter is
signal q0,q1,q2 : STD_LOGIC := '0'; ---initialising the signals
signal q3 :STD_LOGIC := '1';
component DFF is
Port ( reset : in STD_LOGIC;
clk : in STD_LOGIC;
D : in STD_LOGIC;
Q : out STD_LOGIC);
end component;
begin
DFF1: DFF port map(reset,clk,q3,q0);
DFF2: DFF port map(reset,clk,q0,q1);
DFF3: DFF port map(reset,clk,q1,q2);
DFF4: DFF port map(reset,clk,q2,q3);
count <= q3&q2&q1&q0;
end Behavioral;
Ja, ich habe Reset angegeben. Dieses Mal wird der Wert nur auf Null gesetzt und es findet kein Übergang statt, was sehr offensichtlich ist, als ich versuchte, ein Flipflop mit voreingestelltem Eingang einzufügen, das einen 1-Wert in den Flipflop-Ring pumpt! ... Ich simuliere es nur. Wie stelle ich den Wert so ein, dass er nach dem Zurücksetzen/Voreinstellen verschoben wird? Übersehe ich eine Prozedur? ...
Das Problem ist jetzt also: Wie initialisiere ich alle Flipflops und beginne danach mit dem Schalten nacheinander mit dem Simulator? ...
Ich habe versucht, das Verhaltensmodell zu verwenden, ohne DFF zu verwenden. Unten ist der Code für dasselbe.
Entität ringCounter_BehaviorModel ist
Port ( CLK : in STD_LOGIC;
CLR : in STD_LOGIC;
Q : inout STD_LOGIC_VECTOR (3 downto 0);
NQ : inout STD_LOGIC_VECTOR (3 downto 0));
EndringCounter_BehaviorModel;
Architektur Verhalten von ringCounter_BehaviorModel ist
Start
verarbeiten (CLK, CLR)
beginnen wenn (CLR ='0') dann
Q<= "1000";
elsif (CLR ='1') then
if CLK'event and CLK='1' then
Q(0) <= Q(3);
for i in 0 to 2 loop
Q(i+1) <= Q(i);
end loop;
end if;
end if;
Prozess beenden;
Ende Verhalten;
Meine Frage ist, wenn ich es simuliere, erzwinge ich den Wert von clr auf 0, um den Zähler auf 1000 zu initialisieren, und gebe dem Takteingang ein Taktsignal. Nachdem ich auf Ausführen geklickt habe, konnte ich die Werte von Q als 1000 sehen, aber die Werte bleiben gleich, selbst wenn ich beobachte, dass der Takt zwischen 0 und 1 variiert.
Wenn ich es erneut ausführe, gehen alle Werte verloren und ich muss die Werte erneut erzwingen.
Bei clr = '1' erfolgt keine Initialisierung und keine Hoffnung auf Verschiebung der gewünschten Werte. Übersehe ich einen Punkt im Verfahren oder sollte ich den Code ändern oder ist die gemachte Beobachtung im Falle einer Simulation in Ordnung?
Die Zusammenfassung des Problems bleibt also immer noch dieselbe und besteht nur darin, den Ringzähler zu initialisieren und zu beginnen, sich im System zu drehen.
Innerhalb des Ringzählers wird q3 sowohl durch die gleichzeitige Zuweisung q3<='1' als auch durch DFF4 zugewiesen. Beides gleichzeitig kann man nicht haben.
ringcounter
Die DFFs sind alle in einem Ring miteinander verkettet - wie kann man beim Zurücksetzen
initialisiert werden, ohne einen zweiten Treiber hinzuzufügen?Du machst unnötige Arbeit. Sie sollten kein DFF-Primitive erstellen müssen. Der Synther ist schlau genug, um einen std_logic_vector, der sozusagen „getaktet“ ist (dh von einem Prozessblock mit clk in der Sensitivitätsliste umgeben ist), in eine Sammlung von DFFs umzuwandeln.
Beseitigen Sie das DFF-Primitive, erstellen Sie stattdessen einen std_logic_vector und erstellen Sie dann in Ringcounter einen Prozess, der beim Zurücksetzen (Ihr Reset ist asynchron, übrigens, falls das für Sie einen Unterschied macht) Ihren std_logic_vector mit dem Standardwert lädt Sie wollen (zB "1000"). Und dann dreht es bei einer steigenden Taktflanke jedes Element des Ringzählers nach links.
Wenn Sie dabei Probleme haben, kann ich später noch einmal vorbeischauen und Ihnen zeigen, wie es geht. Aber ich lasse Sie lieber zuerst versuchen, es selbst herauszufinden.
Wie die Antwort von Apalopohapa zeigt, besteht Ihr Problem darin, dass mehrere Treiber dasselbe Signal verwenden. Die Anweisung q3 <= '1'
ist immer aktiv - es ist nicht nur eine Initialisierung. Da Sie std_logic
and not std_ulogic
verwenden, ist dies technisch gesehen kein Fehler, und der Simulator wird es problemlos ausführen (möglicherweise mit unbeabsichtigten Ergebnissen, obwohl das Problem manchmal maskiert wird, weil es sich zufällig in etwas löst, das funktioniert).
Wenn Sie möchten, dass Ihr Zähler nach dem Zurücksetzen um startet "1000"
und jede Uhr rotiert (was so aussieht, als würden Sie es tun), wäre eine Möglichkeit, ihn DFF
so zu ändern, dass er optional Q
auf voreingestellt werden kann '1'
, anstatt ihn immer auf zurückzusetzen '0'
. Sie könnten dies tun, indem Sie entweder eine preset
Eingabe oder ein generisches oder etwas hinzufügen, das seinen Initialisierungswert festlegt. Es gibt auch andere Ansätze, die funktionieren würden.
Dean
fru1tbat
q3
Signals bei der Deklaration wird nichts für die Simulation tun, da es von einerDFF
Instanz gesteuert wird.ajs410