Hvordan lese \ skrive data bruker asynkron clk?

X

xtcx

Guest
hei venner!, jeg har et problem der jeg kodeken sender og mottar data ved 2MHZ sclk (kodek intern) clk.It fungerer som master og dermed sclk (at) 2MHz ikke kontrolleres av eksterne midler.Jeg skal forklare i trinn.
1) Jeg leste \ skrive kodek @ 2MHz sclk (kodek clk, master) samtidig på SDI & SDO
2) kodek skriver 32-bits data til Tx_buffer og leser 32-bits data til Rx_buffer (i FPGA)
3) Etter å ha lest 32-bits (1 ramme) i 16us går kodeken til tomgang till 64us.
4) Dette er inaktivt, er å matche prøvetaking tiden som er 16kHz (64us).
5) Kodeken leser \ skriver data @ 2MHz eneste eller den ikke fungerer
6) LES: På 17us, etter kodek stopper skrive \ lese, begynner jeg å lese fra Tx_buffer (parallell til seriell) @ 1Mbps bruke FPGA clk @ 1MHz.Så til slutt jeg fullføre min drift ved 48us.Remaining 16us er gratis
7) SKRIV: At 17us, etter kodek stopper skrive \ lese, begynner jeg å skrive til RX_buffer (seriell til parallell) @ 1Mbps bruke FPGA clk (at) 1MHZ.Igjen jeg er ferdig med det innen 48us.
8) BEGGE 1MHz lese \ skrive til Tx_buffer og Rx_buffer skjer fra 17us til 48us (32-bits @ 1MHz).
9) Denne rutinen er evig.
Problemet her er at siden kodeken klokke 2MHz ikke er nøyaktig i forhold til FPGA clk, den FPGA klokken skifter raskere enn kodek clk.Som et resultat jeg finne mine data mangler et sted ... Hvis jeg bare bytte FPGA 1MHz av codec's (2MHz \ 2 = 1MHz) 1MHz clk, så jeg kan få min rett lydutgang ... Hva couldbe den eksakte årsaken ?.... Er dette problemet med asynkron operasjon ?.... Er ikke klokkene synczing riktig ?.... Hvis alle operasjoner blir gjort ved hjelp av kodek Sclk, så finner jeg ingen problemer.
Does noen har møtt dette problemet?eller har noen ide relatert til dette? ... Har bruker FIFO kunne løse dette ?..... Takk

 
mest sannsynlig skyldtes klokken synkronisering problemet mellom sclk og FPGA klokke.

kan du poste en del av koden din her slik at vi kan analysere abut dataene krysset diff klokke domene.
eller u kanne email meg ycherjier (at) yahoo.com, slik at jeg kan se på detaljer og discuess her.

det er en enkel måte der med 2 FF å gjøre dataene synkroniseres med 2 diff klokke.

 
Her er min komplette koden ... Du kan trygt utelate opplysninger som tilsvarer STATLIGE = s0.Si9nce disse er kun kodek initialization trinn
Bare uttalelser fra STATLIGE <= S1 sekvens trengs ... Min forklaringer på slutten av denne koden ...library IEEE;
bruk IEEE.STD_LOGIC_1164.ALL;
bruk IEEE.STD_LOGIC_ARITH.ALL;
bruk IEEE.STD_LOGIC_UNSIGNED.ALL;-------------------- ENTITY ERKLÆRING -------------------------
enhet SDR_PSK er
PORT (
clk: IN STD_LOGIC;
sclk: in std_logic;
SW2: IN STD_LOGIC;
sdofs: in std_logic;
SDO: in std_logic;
RST: out std_logic;
se: Inout std_logic;
SDI: out std_logic;
sdifs: out std_logic;
---------
LED: OUT STD_LOGIC_VECTOR (15 DOWNTO 0): = x "0000";
- Clk_sdata_op: OUT STD_LOGIC;
- Clk_data_op: OUT STD_LOGIC;
- ----------
Txb: OUT STD_LOGIC;
- Rxb: OUT STD_LOGIC;
INT_OP: OUT STD_LOGIC;
TEST_OP: OUT STD_LOGIC
- Sdofs_op: OUT STD_LOGIC
);
end SDR_PSK;
------------------------ SIGNALER ERKLÆRING ------------------------ --------------
architecture Behavioral of SDR_PSK er
----------- CODEC -------------
TYPE viktigste er (S0, S1);
SIGNAL tilstand: main;

TYPE INTERRUPTS1 IS (INGEN, SYNC_ON, SYNC_OFF);
SIGNAL Interrupt: INTERRUPTS1: = none;
- SIGNAL Interrupt: INTEGER: = 0;
SIGNAL Sig: INTEGER RANGE 0 til 188: = 1;
SIGNAL sig1, t: INTEGER RANGE 0 til 150: = 0; - Må starte med 0
signal Rx_buff1, Rx_buff2: std_logic_vector (15 downto 0): = "0000000000000000";
signal Tx_buff1, Tx_buff2: STD_LOGIC_VECTOR (15 downto 0): = "0000000000000000";
signal TX1, TX2, Tx: STD_LOGIC_VECTOR (31 DOWNTO 0);
signal RX1, RX2, Rx: STD_LOGIC_VECTOR (31 DOWNTO 0): = x "00000000";
signal enab: std_logic: = '0 ';
konstant ca1: std_logic_vector (15 downto 0): = x "8901";
konstant ca2: std_logic_vector (15 downto 0): = x "8101";
konstant CA3: std_logic_vector (15 downto 0): = x "8a7b";
-------- MARKER ----------
---- SIGNAL MARKER1: STD_LOGIC_VECTOR (31 DOWNTO 0): = "01111110011111100111111001111110";
SIGNAL MARKER1: STD_LOGIC_VECTOR (15 DOWNTO 0): = "0111111001111110";
SIGNAL DATA_Tx, DATA_Rx: STD_LOGIC;
SIGNAL TEST_REG: STD_LOGIC_VECTOR (31 DOWNTO 0): = x "aaaaaaaa";
---- SIGNAL BUFFER_Tx: STD_LOGIC_VECTOR (47 DOWNTO 0);
SIGNAL BUFFER_MARKER, Dummy: STD_LOGIC_VECTOR (15 DOWNTO 0);
SIGNAL FLAG_RAMSWAP: STD_LOGIC: = '0 ';
SIGNAL BUFFER_Tx, BUFFER_Rx: STD_LOGIC_VECTOR (31 DOWNTO 0);
--
-------------- Koding -----------
SIGNAL CLK_RECOV_PRE: STD_LOGIC;
SIGNAL Mnchr_Rx, Mnchr_Tx, MONOSHOT_inv: STD_LOGIC;
SIGNAL Mnchr_Rx_inv, Mnchr_Rx_delay: STD_LOGIC;
SIGNAL CLK_RECOV, CLK_RECOV_inv: STD_LOGIC;
SIGNAL A, B, C, D, E, F, G, H, X: STD_LOGIC;
SIGNAL A1, B1, C1, D1, E1, F1: STD_LOGIC;
SIGNAL MONOSHOT: STD_LOGIC;
SIGNAL m, n, o, m1, n1: INTEGER: = 0;
SIGNAL clk_data, clk_sdata: STD_LOGIC;--
----------------------- Forhåndsdefinerte ASSIGNEMENTS ------------------------- ---------------------------
BEGIN
----- Koding og MARKER ---
- Txb <= DATA_Tx;
- Rxb <= DATA_Rx;
- clk_sdata_op <= clk_sdata;
- clk_data_op <= clk_data;
DATA_Rx <= DATA_Tx;
-------------------------------------------------- -------------------------------------------------- --------------------
- 1.CODECINTERFACEMODULE
-------------------------------------------------- -------------------------------------------------- -------------------
process (clk, sclk, stat, SW2, sdofs, SE, enab)
VARIABLE i, i1: INTEGER: = 0;
VARIABLE j: INTEGER: = 0;
VARIABLE temp, temp2: STD_LOGIC: = '0 ';

begynne
-------------------------------------------------- -------------------------------------------------- ------------
IF (SW2 = '0 ') then
Sig <= 0;
state <= S0;
sig1 <= 0;
IF (enab = '0 ') then
se <= '0 ';
RST <= '0 ';
enab <= '1 ';
ELSIF (enab = '1 ') then
se <= '1 ';
RST <= '1 ';
enab <= '1 ';
end if;
ELSIF rising_edge (sclk) then
enab <= '0 '; - Tillate at loopen skal gå neste gang
-----------------------------------------------
- CONTROL WORD KONFIGURASJON
-----------------------------------------------
-----------------------------------------------
- Kontroll Word 1
-----------------------------------------------
case state is
når S0 =>
Sig <= sig 1;
case Sig er

når 1 => sdifs <= '1 ';
når 2 => sdifs <= '0 ';
SDI <= ca1 (15),
når 3 => SDI <= ca1 (14);
når 4 => SDI <= ca1 (13);
når 5 => SDI <= ca1 (12);
når 6 => SDI <= ca1 (11);
når 7 => SDI <= ca1 (10);
når 8 => SDI <= ca1 (9);
når 9 => SDI <= ca1 (

<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Kjølig" border="0" />

;
når 10 => SDI <= ca1 (7);
når 11 => SDI <= ca1 (6);
når 12 => SDI <= ca1 (5);
når 13 => SDI <= ca1 (4);
når 14 => SDI <= ca1 (3);
når 15 => SDI <= ca1 (2);
når 16 => SDI <= ca1 (1);
da 17 => SDI <= ca1 (0);

--------------------------------------------
- Control Word 2.
--------------------------------------------
når 18 => sdifs <= '1 ';
når 19 => sdifs <= '0 ';
SDI <= ca2 (15);
når 20 => SDI <= ca2 (14);
når 21 => SDI <= ca2 (13);
når 22 => SDI <= ca2 (12);
når 23 => SDI <= ca2 (11);
når 24 => SDI <= ca2 (10);
når 25 => SDI <= ca2 (9);
når 26 => SDI <= ca2 (

<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Kjølig" border="0" />

;
når 27 => SDI <= ca2 (7);
når 28 => SDI <= ca2 (6);
når 29 => SDI <= ca2 (5);
når 30 => SDI <= ca2 (4);
når 31 => SDI <= ca2 (3);
når 32 => SDI <= ca2 (2);
når 33 => SDI <= ca2 (1);
når 34 => SDI <= ca2 (0);

----------------------------------------------
- Control Word 3
-----------------------------------------------
da 35 => sdifs <= '1 '; - kontrollregister C
når 36 => sdifs <= '0 ';
SDI <= CA3 (15);
når 37 => SDI <= CA3 (14);
når 38 => SDI <= CA3 (13);
når 39 => SDI <= CA3 (12);
når 40 => SDI <= CA3 (11);
når 41 => SDI <= CA3 (10);
når 42 => SDI <= CA3 (9);
når 43 => SDI <= CA3 (

<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Kjølig" border="0" />

;
når 44 => SDI <= CA3 (7);
når 45 => SDI <= CA3 (6);
når 46 => SDI <= CA3 (5);
når 47 => SDI <= CA3 (4);
når 48 => SDI <= CA3 (3);
når 49 => SDI <= CA3 (2);
når 50 => SDI <= CA3 (1);
når 51 => SDI <= CA3 (0);
state <= s1;
sig1 <= 0;
når andre =>
end case;
------- CODEC initialiseringsprosessen FERDIGSTILLER --------------------------------------- -----
-------------------------------------------------
- Databuffer In & Out (Dette er en evig loop)
-------------------------------------------------
NÅR s1 =>
sdifs <= sdofs;
sig1 <= sig1 1;
case sig1 er
NÅR 0 =>

IF (sdofs = '1 ') then
sig1 <= 1;
ELSIF (sdofs = '0 ') then
sig1 <= 0;
END IF;

Når 1 => SDI <= Tx_buff1 (15);
Rx_buff1 (15) <= SDO;
Interrupt <= SYNC_ON;
NÅR 2 => SDI <= Tx_buff1 (14);
Rx_buff1 (14) <= SDO;
NÅR 3 => SDI <= Tx_buff1 (13);
Rx_buff1 (13) <= SDO;
NÅR 4 => SDI <= Tx_buff1 (12);
Rx_buff1 (12) <= SDO;
NÅR 5 => SDI <= Tx_buff1 (11);
Rx_buff1 (11) <= SDO;
NÅR 6 => SDI <= Tx_buff1 (10);
Rx_buff1 (10) <= SDO;
NÅR 7 => SDI <= Tx_buff1 (9);
Rx_buff1 (9) <= SDO;
NÅR 8 => SDI <= Tx_buff1 (

<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Kjølig" border="0" />

;
Rx_buff1 (

<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Kjølig" border="0" />

<= SDO;
NÅR 9 => SDI <= Tx_buff1 (7);
Rx_buff1 (7) <= SDO;
NÅR 10 => SDI <= Tx_buff1 (6);
Rx_buff1 (6) <= SDO;
NÅR 11 => SDI <= Tx_buff1 (5);
Rx_buff1 (5) <= SDO;
NÅR 12 => SDI <= Tx_buff1 (4);
Rx_buff1 (4) <= SDO;
NÅR 13 => SDI <= Tx_buff1 (3);
Rx_buff1 (3) <= SDO;
NÅR 14 => SDI <= Tx_buff1 (2);
Rx_buff1 (2) <= SDO;
NÅR 15 => SDI <= Tx_buff1 (1);
Rx_buff1 (1) <= SDO;
NÅR 16 => SDI <= Tx_buff1 (0);
Rx_buff1 (0) <= SDO;

NÅR 17 => SDI <= Tx_buff2 (15);
Rx_buff2 (15) <= SDO;
NÅR 18 => SDI <= Tx_buff2 (14);
Rx_buff2 (14) <= SDO;
NÅR 19 => SDI <= Tx_buff2 (13);
Rx_buff2 (13) <= SDO;
NÅR 20 => SDI <= Tx_buff2 (12);
Rx_buff2 (12) <= SDO;
NÅR 21 => SDI <= Tx_buff2 (11);
Rx_buff2 (11) <= SDO;
NÅR 22 => SDI <= Tx_buff2 (10);
Rx_buff2 (10) <= SDO;
NÅR 23 => SDI <= Tx_buff2 (9);
Rx_buff2 (9) <= SDO;
NÅR 24 => SDI <= Tx_buff2 (

<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Kjølig" border="0" />

;
Rx_buff2 (

<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Kjølig" border="0" />

<= SDO;
NÅR 25 => SDI <= Tx_buff2 (7);
Rx_buff2 (7) <= SDO;
NÅR 26 => SDI <= Tx_buff2 (6);
Rx_buff2 (6) <= SDO;
Når 27 => SDI <= Tx_buff2 (5);
Rx_buff2 (5) <= SDO;
NÅR 28 => SDI <= Tx_buff2 (4);
Rx_buff2 (4) <= SDO;
NÅR 29 => SDI <= Tx_buff2 (3);
Rx_buff2 (3) <= SDO;
NÅR 30 => SDI <= Tx_buff2 (2);
Rx_buff2 (2) <= SDO;
NÅR 31 => SDI <= Tx_buff2 (1);
Rx_buff2 (1) <= SDO;
NÅR 32 => SDI <= Tx_buff2 (0);
Rx_buff2 (0) <= SDO;

NÅR 33 =>
Tx_buff1 <= Rx (31 DOWNTO 16);
Tx_buff2 <= Rx (15 DOWNTO 0);
Tx (31 DOWNTO 16) <= Rx_buff1;
Tx (15 DOWNTO 0) <= Rx_buff2;
ledet <= Tx_buff1;
NÅR 100 => Interrupt <= SYNC_OFF;
NÅR 126 => sig1 <= 0;
Når andre => NULL;
END CASE;
når andre =>
end case;
end if;
END PROCESS;

-------------------------------------------------- -------------------------------------------------- -------------------------
-------- 2.MARKERANDBITSTUFFING
-------------------------------------------------- -------------------------------------------------- -------------------------
PROCESS (clk_sdata, clk_data, CLK, sclk) IS
VARIABLE i, i1: INTEGER: = 0;
VARIABLE temp, temp2: STD_LOGIC: = '0 ';
VARIABLE FLAG_LOOP: STD_LOGIC: = '1 ';
BEGIN
---------------------------------
---- CODEC CLOCK GENERATOR @ 1MHz
---------------------------------

IF RISING_EDGE (clk) THEN
I1: = I1 1;
IF i1 (= 40) then
temp2: = NOT (temp2);
clk_data <= temp2;
I1: = 0;
END IF;
END IF;
---------------------------------
CASE Interrupt IS
NÅR SYNC_ON =>
C: IF RISING_EDGE (clk_data) then

- IF (interrupt = SYNC_ON) then
INT_OP <= '1 ';
m1 <= m1 1;
n1 <= n1 1;
IF (M1> = 0 AND m1 <= 30) then
Data_Tx <= Tx (M1); - convertuing Buffer data til seriell
Rx <= Data_Rx (M1);
ELSIF (M1 = 31) then
Data_Tx <= Tx (M1); - convertuing Buffer data til seriell
Rx <= Data_Rx (M1);
END IF;
- ELSIF (interrupt = SYNC_OFF) then
NÅR SYNC_OFF =>
m1 <= 0;
INT_OP <= '0 ';
Når andre => NULL;
END CASE;
END IF;
- END IF;
END PROCESS;
End Behavioral;
-------------------------------------------------- -------------------------------------------------- -----
Mens Codec loop of State = S1 er en evig loop, som samler inn data fra SDO (i tillegg skriver data til SDI) og lagrer det midlertidig i Rx_buff1 & Rx_buffer2 (LCH & Rxh), Tx_buff1 & Tx_buff2 resp.Totally 32 biter.At greven av 33 (sig1) vil jeg passerer denne temp buffer Rx_buff1 & 2 til Tx og Tx_buff1 & 2 til Rx.Så Rx og Tx er 32-bits buffer hvert som holder kodeken data. (Tx leses data fra kodeken mens Rx er data som skal skrives til kodek). Alle operasjoner som har blitt gjort så langt er bare gjort under CODEC's SCLK.ALLE CODEC lese \ skrive operasjoner har blitt kodet under "rising_edge (sclk)", hvor SCLK er generert av kodeken selv asynchronouly på 2MHz.Så alle operasjoner utføres på 2MHz.Nå Jeg trenger å lese \ skrive data fra Tx og Rx hhv bruker en 1MHz clk å få 1mbps data rate.That er jeg trenger å konvertere 2Mbps data til en konstant 1mbps rate .... For 1MHz jeg genereres det fra min 80MHz FPGA master CLK-inngang som er under "Marker og Bit stuffing". Nå her kommer problemet ... Dataene som vi leser fra FPGA's 1MHz clk ikke er i fase eller nøyaktig det samme med sclk.Jeg sjekket det ved å dele 1MHz fra SCLK (kodek clk) og kryss-sjekket og sammenlignet med mine FPGA generert 1MHz clk.Begge er ikke likt i det hele tatt .. Det ser ut som den kodeken CLK er ikke 1MHz men noen 999.1MHz .. Som et resultat kan jeg se FPGA 1MHz CLK skifter raskere enn Sclk (at) 1MHz i CRO klart ... Her Begrepet "avbryt" er å generere et flagg exaclty på den tiden da kodeken lese \ skrive starter ... Så jeg legger mine data samtidig inorder å unngå data-fraværende .. De overvåket visningen her er at jeg må raskt min plass data innen Avbrudd = SYNC_ON ..... Vel, hvis du er i tvil relaterte, bare spør .... Takk for dine interesser !.....

 
Hei, sorry .. jeg er ikke kjenner til VHDL men jeg tror jeg kan grovt gjette hva koden gjør.

jeg har tegne et blokkdiagram som discrib systemet.håper jeg ikke får det galt.

vil, jeg har en tvil, nevner du dette "Etter å ha lest 32-bits (1 ramme) i 16us går kodeken til inaktiv til 64us."

det betyr først, vil den første 32 sclk klokke overføring gyldige data fra kodeken til FPGA så etter de 32 første klokken kodeken vil gå i inaktiv tilstand for 64us der
FPGA vil samle inn data etter de 32 første sclk klokke og bytte det ut på 1MHz.

så spørsmålet mitt er hva som er tilstanden når kodeken komme på tomgang?så du sclk fremdeles trasmiting?
Min gjetning er det ikke trasmiting noen signaler og alltid høyt eller lavt i rundt 64us.

på den andre siden, hva med 1MHz side, wan du signalet kontinuerlig trasmiting eller den kan stanse for noen periode og videresende når data er ferdig?

fra mitt synspunkt, den sclk fra kodeken vil stoppe for 64us som er lang nok for deg å overføre dataene ut på 1MHz.

jeg har feste et dokument, og du kan se på figur 3 og figur 4.
http://www.edaboard.com/viewtopic.php?p=429921 # 429921

håper det hjelper ....
Beklager, men du må logge inn for å vise dette vedlegget

 
Beklager for meg sent svar ... Først vil jeg takke deg for dine interesser!
cherjier skrev:

så spørsmålet mitt er hva som er tilstanden når kodeken komme på tomgang?
så du sclk fremdeles trasmiting ?....
 
Quote:

Vel, problemet mitt her om kodeken som er master, som i den forstand, er dataene og clk timming ikke kontrollerbar i FPGA ... Hvordan kunne du lese data fra et annet clk domene hvis du synkroniserer? ...
 
Takk for din kode cherjier!, Er koden ikke viktig, men konseptet er .... Så ikke noe problem hvis den ikke er i VHDL, alt det betyr er at du hjelper mind! ... Men, jeg kunne bare delvis forstår at koden, Siden vi designere, trenger vi ikke mye av code.What vi vil trenge er konseptet ... Jeg har liten tvil om CDC (klokke domene krysset) ... I dette diagrammet er sclk er matet inn i den 1. D-FF, så FPGA clk to 2nd D-FF.What er fordelen med dette? .. kan du vennligst forklare meg denne CDC med at diagrammet litt?. I mellomtiden er jeg også sjekke dine tidligere koblinger. . Hvis jeg finner noe jeg vil matet her snart .. Takk for dine interesser ....

 
egentlig hva Zerox100 sa var sant også, kanne u implementere en 2 klokke ASYNC FIFO for datasynkronisering, men for ditt tilfelle tror det en liten foss av 2 FF skal være ok.

jeg har tegner du en bølgeform om fordelen med å bruke CDC krets.<img src="http://images.elektroda.net/5_1207032669_thumb.jpg" border="0" alt="How to read\write data using asynchronous clk?" title="Hvordan lese \ skrive data bruker asynkron clk?"/> de viktigste punktene er på den andre FF, hvor andre FF vil registrere Q fra første FF, når Q fra første FF er i endring, mens den andre FF er prøvetaking Q, vil det føre metastability som vist på kurveform ovenfor .denne tilstanden vil skje whrn stigende kanten av sclk og FPGA klokke er for nær.

bruker den tredje FF vil la signalet vellykket krysset klokken domenet.

dessuten i noen tilfeller, designer med sync krets for kontroll signal eller handshaking signal bare.

for eksempel hvis kontrollen signalet er en puls tog i en konstant periode og dette signalet må krysset til andre klokke domene, hvis det ikke krysse vellykket, vil du se at noen av puls mangler og pulsen toget ikke er i en konstant periode.

 

Welcome to EDABoard.com

Sponsor

Back
Top