Hallo,
als anfänger versuche ich ein Signal zu verschieben. Dazu habe ich als
eingagangsclock 27 Mhz, diese habe ich mittels counter dann
runtergeteilt habe.
Folgender code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SCHIEBEREGISTER is
Port (
EINGANG : in std_logic_vector (3 downto 0);
RESET : in std_logic;
LED : out std_logic;
AUSGANG : out std_logic_vector (3 downto 0);
SAVE0 : buffer std_logic_vector (3 downto 0);
SAVE1 : buffer std_logic_vector (3 downto 0);
SAVE2 : buffer std_logic_vector (3 downto 0);
SAVE3 : buffer std_logic_vector (3 downto 0);
SAVE4 : buffer std_logic_vector (3 downto 0);
SAVE5 : buffer std_logic_vector (3 downto 0);
clk : in std_logic);
end SCHIEBEREGISTER;
architecture Behavioral of SCHIEBEREGISTER is
--signal SAVE0,SAVE1,SAVE2,SAVE3,SAVE4 : std_logic_vector (3 downto 0);
signal clk_2 : std_logic;
COMPONENT TAKT
PORT ( clk_in : in std_logic;
reset : in std_logic;
clk_out: out std_logic);
end COMPONENT;
begin
taktausgabe: TAKT
PORT MAP (clk_in=> clk, reset => RESET, clk_out=>clk_2 );
SCHIEBEREGISTER: process (clk_2,reset)
begin
if reset = '1' then
SAVE0 <="0000";
SAVE1 <="0000";
SAVE2 <="0000";
SAVE3 <="0000";
SAVE4 <="0000";
SAVE5 <="0000";
else
if (clk_2 = '1' and clk_2'event ) then
SAVE0<= EINGANG;
SAVE1<= SAVE0;
SAVE2<= SAVE1;
SAVE3<= SAVE2;
SAVE4<= SAVE3;
SAVE5<= SAVE4;
else
SAVE0 <=SAVE0;
SAVE1 <=SAVE1;
SAVE3 <=SAVE3;
SAVE4 <=SAVE4;
SAVE5 <=SAVE5;
end if;
end if;
end process SCHIEBEREGISTER;
AUSGANG<=SAVE5;
Das funktioniert aber so nicht, komisch ist das wenn ich das so
definiere dann kommt am ausgang nach ca. 2 sek. das signal, tue ich aber
den SAVE5 weg dann kommt das signal nach 6 sek...
Kann mir jemand helfen? ich wollt nur das signal um 4 takte verzögert
ausgeben?
Eingang ist hier ein switch
Ausgang sind hier 4 LEDLED ist einfach kontrolle für takt.
Zudem wird das hier ausreichen und genau das selbe machen:
1
if(clk_2='1'andclk_2'event)then
2
SAVE0<=EINGANG;
3
SAVE1<=SAVE0;
4
SAVE2<=SAVE1;
5
SAVE3<=SAVE2;
6
SAVE4<=SAVE3;
7
SAVE5<=SAVE4;
8
endif;
> Dazu habe ich als eingagangsclock 27 Mhz, diese habe ich> mittels counter dann runtergeteilt habe.
Das ist ein sehr schlechter Designstil.
Ein ideales FPGA-Design hat genau 1 Takt (das gilt besonders für
Anfänger). Und der Rest wird mit Clock-Enables gemacht.
Siehe Taktung FPGA/CPLD
Was ist dein clk_2? Welche Frequenz hat der?
Mein clk_2 kommt von clk_out welches ich hier definiert habe und dann
als component definiert habe.
Ja ich bin auch anfänger deswegen meine frage, wie sollte ich es denn
machen?
Gruss
Mario
entity TAKT is
Generic (MAXCOUNT,N :integer:= 53999998); -- EINSTELLBARE VARIABLE
FÜR ZÄHLER!!
Port ( clk_in : in STD_LOGIC; -- RICHTIGER CLOCKEINGAGN MIT 27
MHZ
reset : in STD_LOGIC; -- RESET UM ZÄHLER AUF NULL ZU
SETZEN
clk_out : out STD_LOGIC); -- INTERN VERWENDETER
RUNTERGEDROSSELTER CLOCK -> HIER 1 HZ
end TAKT;
architecture Behavioral of TAKT is
signal cnt: integer range 0 to N ;
begin
TAKTGEBER: process (reset,clk_in)
begin
if (reset = '1') then
cnt<=0;
else
if (clk_in='1' and clk_in'event) then
cnt<=cnt+1;
elsif (cnt = MAXCOUNT) then
cnt<=0;
end if;
end if;
end process TAKTGEBER;
TAKTOUT: process (cnt)
begin
if ((cnt) < (MAXCOUNT/2)) then
clk_out<= '0';
else
clk_out<= '1';
end if;
end process TAKTOUT;
end Behavioral;
Das hast du selber erfunden?
Damit beschreibst du Flipflops (cnt), bei denen der Takteingang Vorrang
vor dem Reseteingang hat. Sowas kannst du nicht kaufen.
Probiers mal so:
1
entityTAKTis
2
Generic(MAXCOUNT,N:integer:=27000000);-- EINSTELLBARE VARIABLE FÜR ZÄHLER!!
3
Port(clk_in:inSTD_LOGIC;-- RICHTIGER CLOCKEINGAGN MIT 27 MHZ
4
-- reset : in STD_LOGIC; -- RESET nicht nötig.
5
clk_out:outSTD_LOGIC);-- Clock-Enable -> HIER 1 HZ
6
endTAKT;
7
8
architectureBehavioralofTAKTis
9
signalcnt:integerrange0toN-1;
10
begin
11
12
TAKTGEBER:process(reset,clk_in)
13
begin
14
if(clk_in='1'andclk_in'event)then
15
if(cnt=MAXCOUNT)then
16
cnt<=0;
17
clk_out<='1';-- nur 1 Takt aktiv
18
else
19
cnt<=cnt+1;
20
clk_out<='0';
21
endif;
22
endif;
23
endprocessTAKTGEBER;
24
25
endBehavioral;
Und dann im Top-Level:
1
2
:
3
SCHIEBEREGISTER:process(clk,reset)
4
begin
5
ifreset='1'then
6
SAVE0<="0000";
7
SAVE1<="0000";
8
SAVE2<="0000";
9
SAVE3<="0000";
10
SAVE4<="0000";
11
SAVE5<="0000";
12
elsifrising_edge(clk)then
13
if(clk_2='1')then
14
SAVE0<=EINGANG;
15
SAVE1<=SAVE0;
16
SAVE2<=SAVE1;
17
SAVE3<=SAVE2;
18
SAVE4<=SAVE3;
19
SAVE5<=SAVE4;
20
endif;
21
endif;
22
endprocess;
23
:
Und sowas ist Käse:
SAVE0 : buffer std_logic_vector...
Gewöhne dir besser an, mit lokalen Signalen zu arbeiten und diese dann
auf einen OUT Port zuzuweisen.
Hi,
danke für die Antwort!!
fürs verständniss: Was passiert jetzt genau bei der änderung von clk
='1' and clk'event zu rising_edge(clk) then
if (clk_2 = '1') then
>> Und sowas ist Käse:>> SAVE0 : buffer std_logic_vector...
soll ich dann die zwischenspeicherungen SAVE signale nicht in der entity
sonern als hilfssignal in der architectur definieren?
Gruss
> Was passiert jetzt genau bei der änderung von> clk ='1' and clk'event zu rising_edge(clk) then
Nichts, es schreibt sich kürzer.
Der Trick mit dem Clock-Enable liegt darin, dass du vorher clk_2
verwendet hast:
1
if(clk_2='1'andclk_2'event)then
2
SAVE0<=EINGANG;
Und ich verwende clk. Und als Clock-Enable den clk_2, der selber aber
nur 1 clk-Zyklus lang aktiv ist:
1
elsifrising_edge(clk)then-- kompakter
2
elsifclk='1'andclk'eventthen-- alternativ, aber nicht so schön zu lesen
3
if(clk_2='1')then-- ist je Sekunde für 1 clk-Zyklus lang '1'
4
SAVE0<=EINGANG;
> SAVE signale nicht in der entity> sonern als hilfssignal in der architectur definieren?
Ja.
Hi, also so funktioniert das auch irgendwie nicht.
Ich verstehe nicht was am Takt falsch sein soll.
ZUM TAKT:
ich habe 27 Mil. takte in einer sekunde. Ich lasse mit steigender Flanke
den counter hoch zahlen bis 54 Milund sag das mein neues clocksignal dan
den wert '1' hat wenn der bei kleiner der hälfte der 54Mil. und 0 wenn
er mehr als der hälfte der 54 Mil. ist. Also habe ich eine sekunde lang
eine 1 und eine sekunde lang eine 0 am clk_out. ODER TÄUSCHE ICH MICH
DA?
und dann schiebe ich das signal mit steigneder flanke dieses clk_out
signals oder nicht?
Ich verzweifele echt langsam am dem zeug...arrrr
Gruss
> Also habe ich eine sekunde lang eine 1 und eine sekunde lang eine 0 am> clk_out. ODER TÄUSCHE ICH MICH DA?
Was sagt die Simulation?
Was, du simulierst nicht :-o
Naja, wie auch immer:
1) Es ist schlecht, einen Takt aus Kombinatorik zu erzeugen.
1
if((cnt)<(MAXCOUNT/2))then
Das Stichwort dazu heißt: Glitches
2) Es ist schlecht, unnötig viele Takte im Design zu haben.
In deinem Design clk und clk_2
Stichworte hierzu: Taktdomänen und Synchronisation
Ok
aber ich verstehe nicht wie du dann mit deinem code dann auf (eine
sekunde 1 eine sekunde 0) kommen willst?
Und wie gesagt meine clk_in weiße ich der clk von 27 Mhz zu die auch
wirklich anliegt zu, und mit clk_out erzeuge ich dann meinen neuen takt
und dann als componente weisse ich clk_out dem hilfssignal clk_2 zu,
welches ich dann in der architecture verwende verwende....
Gruss
> aber ich verstehe nicht wie du dann mit deinem code dann auf (eine> sekunde 1 eine sekunde 0) kommen willst?
Ich will doch gar keinen Takt mit 1:1 Pulspausenverhältnis.
Ich will jede Sekunde 1 Takt lang ein Enable-Signal.
Ich will jede Sekunde um eins weiterschieben. Wenn das nicht passt, dann
darfst du auch schreiben:
Warum ich frag ist , weil mit meiner Methode auch eine zustätzliche LED
zum blinken gebracht hab und somit den Takt kontrolliert hab. Nur wenn
ich das dann so mache:
LEDBLINKEN : process (clk_2) -- KONTROLLE -> TAKTAUSGABE AN LED
begin
if rising_edge(clk) then
if (clk_2='1' ) then
LED<='1';
else
LED<='0';
end if;
end if;
end process LEDBLINKEN;
Gruss und danke noch mal