ich hab ein spartan 3 board und möchte mit diesem vier signale zur
steuerung von einem ADC und einem DAC erzeugen. dazu teile ich den takt
des boards. wenn ich den reset(low-aktiv) auslöse möchte ich, dass die
signale und die zählerstände einen bestimmten zustand annehmen.
jedoch tritt folgender fehler auf:
Signal $n0003 cannot be synthesized, bad synchronous description.
ich hab mich schon auf der xilinx-homepage informiert und weiß nicht
was ich falsch gemacht hab, da die problemlösung genau so beschrieben
wie ich es habe.
Hallo Emir,
ich weiß nicht, ob du einfach so vier Zähler in eine If - Schleife
einbauen kannst, weil bedenke, jede if-then-else Schleife stellt ein
Flip-flop dar.
Am besten du trennst jeden Zähler und machst vier einezelne Prozesse.
Hallo Emir,
das Problem dürfte die Reset-Beschreibung sein.
Du hast Programmiert:
if(clk = '1' and clk'event)then
if(reset = '1') then
var_conv_wert := var_conv_wert + '1';
else
conv <= '1';
var_conv := '1';
var_conv_wert := "00000000000";
end if;
end if;
Damit wird der Reset synchron synthetisiert, auch wenn es
eigentlich nur asynchron sein sollte.
Besser sollte sein:
blabla: process(clk, reset)
if (reset = '1') then
do resetkrams;
elsif (clk = '1' and clk'event) then
do richtiges zeugs;
else
do nix besonderes;
end if;
tschuessle
Bernhard
hmm danke für die anregung, aber wenn ich den code wie folgt schreibe
dann macht er nicht mehr das selbe:
PRO_CONV: process(clk, reset)
begin
if(reset = '0') then
conv <= '1';
var_conv := '1';
var_conv_wert := "00000000000";
elsif(clk = '1' and clk'event)then
var_conv_wert := var_conv_wert + '1';
else
if (var_conv_wert = "101000000000" and var_conv = '1') then
var_conv := '0';
conv <= var_conv;
var_conv_wert := "00000000000";
end if;
if (var_conv_wert = "001100100000" and var_conv = '0') then
var_conv := '1';
conv <= var_conv;
var_conv_wert := "00000000000";
end if;
end if;
end process PRO_CONV;
Also man darf soviele Zähler wie man will in ein If-Statement packen.
Man kann also 4 Zähler auch so programmieren:
if RESET = '0' then
z1 <= (others => '0');
z2 <= (others => '0');
z3 <= (others => '0');
z4 <= (others => '0');
elsif CLK = '1' and CLK'event then
z1 <= z1 + 1;
z2 <= z2 + 10;
z3 <= z3 - 1;
z4 <= z4 - 5;
end if;
Wo das Problem bei dem vhdl.txt Code steckt, kann ich auch nicht sagen.
Wenn ich den Code richtig gelesen habe, dann soll ein Signal mit einer
bestimmten Impulsbreite erzeugt werden. Das würde ich dann so
implementieren:
process(CLK, RESET) is
variable ZAEHLER_VAR: integer range 0 to 1280;
begin
-- Aufwärts-Zähler von 0 bis 1280
if RESET = '0' then
ZAEHLER_VAR := 0;
elsif CLK = '1' and CLK'event then
if ZAEHLER_VAR = 1280 then
ZAEHLER_VAR := 0;
else
ZAEHLER_VAR := ZAEHLER_VAR + 1;
end if;
end if;
-- Ausgangsnetz
if ZAEHLER_VAR > 800 then
CONV <= '1';
else
CONV <= '0';
end if;
end process;
Du willst einen AD-Wandler mit seriellem Protokoll ansteuern? Das würde
ich aber total anders machen. Das Signal SCK ist der Grundtakt des
AD-Wandlers. Den würde ich aus dem globalen Takt durch herunterteilen
erzeugen. Den Rest würde ich mit einer State-Machine machen, die dann
auch die restlichen Signale erzeugt.
Ansonsten müsstest Du Dein Problem nocheinmal näher beschreiben. Dein
Code ist übrigens sehr schlecht lesbar. Es hat bei mir ein wenig
gedauert, bis ich da durchgestiegen bin. Das lag vor allem an den
komischen Einrückungen. Hast Du Tabs benutzt und die Breite verstellt?
ciao, Stefan.
habs eigentlich schon gelöst, indem ich ein "Überprogramm" gemacht
habt indem die Signale in component(s) unterteilt sind.
jetzt gibts keine fehler mehr.
aber um vielleicht eine sauberere lösung zu erhalten, erkläre ich was
ich machen möchte:
Ich hab das Spartan 3 Board das ein ADC und ein DAC besitzt. Beide sind
seriell anzusteuern.
Die Signale SCK und CONV steuern den ADC. Bei jeder negativen Flanke
von SCK wenn CONV=0 ist wird ein Bit ausgegeben.
Diese Bits werden in ein SIPO(seriell in parallel out)-Register
geladen. Das Signal ld_piso ist
ein Signal, dass dem PISO-Register(parallel in seriell out) sagt wann
es die Bit reinladen soll(kommt immer dann wenn die 16 Bit des ADC im
SIPO drin sind).
Beide Register werden arbeiten mit SCK und dazwischen soll noch ein
einfaches digitales Filter kommen, welches ich zunächst weglassen
möchte und nur ein Durchverbindung machen will.
ld_cs diehnt zur Steuerung des ADCs.
Ich habe mir die Datenblätter von ADC und DAC angeschaut und ein
Impulsdiagramm gemacht und hab muss nun diese vier Steuersignale
erzeugen.
Alle vier Signale teile von einem Oszillator am Board runter.
Ok, das macht man dann aber wirklich mit einer State-Machine. Wichtig
ist nicht, das Timing aus dem Datenblatt so genau wie möglich
nachzubauen, sondern die zeitliche Abfolge zu gewährleisten. Das
natürlich innerhalb der Schranken, die das Timing vorgibt.
Deine Lösung erfordert auf jeden Fall wesentlich mehr Hardware als die
Lösung mit einer Statemachine. Du kannst ja mal drüber nachdenken und
die zeitliche Abfolge in einen Automaten pressen. Das gibt wesentlich
weniger Hardware-Verbrauch.
ciao, Stefan.
Mensch, dazu fehlt doch fast ein Wiki-Eintrag. :-)
Wie Du eine aufmalst, solltest Du wissen. Das setze ich mal voraus.
Ansonsten schau Dich mal nach Moore-Automaten oder Mealy-Automaten um.
Hier das Stück Code:
entity AUTOMAT is
port(
RESET: in std_logic;
CLK: in std_logic;
EINGANG: in std_logic_vector(1 downto 0);
AUSGANG: out std_logic_vector(1 downto 0);
);
end entity;
architecture BEHAVIOUR of AUTOMAT is
type STATE_TYPE is (Z1, Z2, Z3);
signal STATE, NEXT_STATE: STATE_TYPE;
begin
-- State Register
State_Reg: process(CLK, RESET) is
begin
if RESET = '0' then
STATE <= Z1;
elsif CLK = '1' and CLK'event then
STATE <= NEXT_STATE;
end if;
end process;
-- State Next Decoder
State_Next: process(STATE, INPUT) is
begin
case STATE is
when Z1 =>
if INPUT = "01" then
NEXT_STATE <= Z2;
else
NEXT_STATE <= Z3;
end if;
when STATE2 =>
NEXT_STATE <= STATE;
if INPUT = "10" then
NEXT_STATE <= Z1;
end if;
when Z3 =>
NEXT_STATE <= STATE;
if INPUT = "00" or INPUT = "11" then
NEXT_STATE <= Z1;
end if;
when others => -- Fehler!
NEXT_STATE <= Z1;
end case;
end process;
-- Output Decoder
State_Output: process(STATE, INPUT) is
begin
case STATE is
when Z1 => OUTPUT <= "00";
when Z2 => OUTPUT <= "10";
when Z3 => OUTPUT <= INPUT; -- Beispiel für Mealy,
-- bei Moore verboten
when others => OUTPUT <= (others => 'X');
end case;
end process;
end architecture;
Ich empfehle Dir folgendes Buch:
J. Reichardt / B. Schwarz: VHDL-Synthese
ISBN: 3-486-25809-5 Oldenbourg-Verlag
kostet 34,80 Euro
http://users.etech.fh-hamburg.de/users/reichardt/buch_rt.html
Da sind solche grundlegenden Sachen beschrieben. Deine Frage macht
wieder deutlich, wie wichtig Grundlagenwissen ist. Lies das Buch, es
wird Dir wirklich helfen.
Was ganz ganz wichtig ist. Bevor Du die State-Machine in VHDL codierst,
mach Dir bitte einen Plan.
ciao, Stefan.
Das Buch gibt es auch zum Download. Was ich an dem Buch nicht so toll
finde: Es geht zwar ausführlich auf alle Sprachkonstrukte von VHDL ein,
erklärt aber nur sehr kurz Standard-Schaltungen, die man täglich so
braucht. State-Machines sind zum Beispiel auf 2 knappen Seiten
abgehandelt. Deshalb habe ich das obige Buch empfohlen, weil es zu
jedem Kapitel auch Übungen enthält. Und es erklärt VHDL eher anhand von
Beispielen.
ciao, Stefan.