
Aktiva "digitala" högtalare
Re: Aktiva "digitala" högtalare
Kamfilter var ett bra namn
, tänker själv på gitter från interferens av vågor.

Re: Aktiva "digitala" högtalare
http://en.wikipedia.org/wiki/Comb_filter
Man får utsläckning och förstärkning på var N'te frekvens mao?
Man får utsläckning och förstärkning på var N'te frekvens mao?
Re: Aktiva "digitala" högtalare
Det blir varken mer eller mindre kamfilter av en 10µs fördröjning till ena högtalaren än om man hade flyttat den högtalaren 3,4mm längre bak.
Re: Aktiva "digitala" högtalare
Nej, såvida man inte sitter och lyssnar med huvudet fastspännt i clockwork orange-stil exakt mitt mellan högtalarna så spelar nog fördröjningar i den storleksordningen ingen större roll!
Nåja, dags för nästa kapitel.
Har grovt designat blocken som behövs för att implementera A2N-interfacet, toppnivån för en kanal ser ut såhär:

Det här är det mest generella fallet, som är upstream-kanalen i slavenheterna.
Sequencer-blocket skapar nya tomma paket i en viss takt, och med ett visst antal tidsluckor av en viss storlek.
Encoder fyller i data i de tidsluckor som är valda, och beräknar ny CRC.
Decoder läser ut data från de tidsluckor som är valda, och kontrollerar CRC.
TX gör 8b10b-kodning och skickar iväg datan seriellt över ett LVDS-par.
RX tar emot data från ett LVDS-par, deserialiserar och avkodar 8b10b.
RX-blocket är det jobbigaste att få till, för att man måste synka mot den inkommande bitströmmen. För det första måste man hitta vilken bit som är den första i varje kodord (finns tio tänkbara lägen). Det har man som tur är redan tänkt på i den vanliga 8b10b-koden. Det finns ett par kodord (K28.1 och K28.5) som innehåller ett unikt bitmönster som inte uppstår någonstans utom när dessa skickas. Använder dessa två som "idle" (skickas hela tiden när det inte finns någon data att skicka) och "reset" (skickas hela tiden när man vill nollställa hela systemet).
Förutom att hitta rätt bland dessa tio tänkbara startlägen i bitströmmen så måste man också sampla varje bit vid rätt tillfälle. På downstream-kanalen kunde man nog nöja sig med att skicka datan i fas med master-klockan och använda den för att sampla vid rätt tillfälle, men det funkar sämre i upstream-riktningen. Även om datan är i perfekt fas med klockan när den skickas så stämmer det inte alls när den kommer fram, då den skickas i motsatt riktning jämfört med klockan.

Min tänkta lösning (ej testad i praktiken ännu) är att skapa en intern klocka som är 8X snabbare än master-klockan (med hjälp av ett DCM-block), vilket ger totalt fyra flanker per bit-tid (4 bitar skickas per masterklock-cykel). Genom att sampla på alla flanker och titta på mellan vilka samplade värden det förekommer övergångar (1->0, 0->1) bör man kunna hitta den bästa flanken att använda. Sen är det bara att slänga bort tre av fyra bitar och köra vidare med resten. Om datan ligger som den övre raden i bilden ovan så vill man alltså helst sampla på de "blå" flankerna, i mittenfallet antingen röda eller gröna och i undre fallet de svarta...
Nåja, dags för nästa kapitel.
Har grovt designat blocken som behövs för att implementera A2N-interfacet, toppnivån för en kanal ser ut såhär:

Det här är det mest generella fallet, som är upstream-kanalen i slavenheterna.
Sequencer-blocket skapar nya tomma paket i en viss takt, och med ett visst antal tidsluckor av en viss storlek.
Encoder fyller i data i de tidsluckor som är valda, och beräknar ny CRC.
Decoder läser ut data från de tidsluckor som är valda, och kontrollerar CRC.
TX gör 8b10b-kodning och skickar iväg datan seriellt över ett LVDS-par.
RX tar emot data från ett LVDS-par, deserialiserar och avkodar 8b10b.
RX-blocket är det jobbigaste att få till, för att man måste synka mot den inkommande bitströmmen. För det första måste man hitta vilken bit som är den första i varje kodord (finns tio tänkbara lägen). Det har man som tur är redan tänkt på i den vanliga 8b10b-koden. Det finns ett par kodord (K28.1 och K28.5) som innehåller ett unikt bitmönster som inte uppstår någonstans utom när dessa skickas. Använder dessa två som "idle" (skickas hela tiden när det inte finns någon data att skicka) och "reset" (skickas hela tiden när man vill nollställa hela systemet).
Förutom att hitta rätt bland dessa tio tänkbara startlägen i bitströmmen så måste man också sampla varje bit vid rätt tillfälle. På downstream-kanalen kunde man nog nöja sig med att skicka datan i fas med master-klockan och använda den för att sampla vid rätt tillfälle, men det funkar sämre i upstream-riktningen. Även om datan är i perfekt fas med klockan när den skickas så stämmer det inte alls när den kommer fram, då den skickas i motsatt riktning jämfört med klockan.

Min tänkta lösning (ej testad i praktiken ännu) är att skapa en intern klocka som är 8X snabbare än master-klockan (med hjälp av ett DCM-block), vilket ger totalt fyra flanker per bit-tid (4 bitar skickas per masterklock-cykel). Genom att sampla på alla flanker och titta på mellan vilka samplade värden det förekommer övergångar (1->0, 0->1) bör man kunna hitta den bästa flanken att använda. Sen är det bara att slänga bort tre av fyra bitar och köra vidare med resten. Om datan ligger som den övre raden i bilden ovan så vill man alltså helst sampla på de "blå" flankerna, i mittenfallet antingen röda eller gröna och i undre fallet de svarta...
Re: Aktiva "digitala" högtalare
Angående fasförskjutningen i klockan, går det inte att styra fasen i DCM i realtid? Har för mig jag såg någon application note från Xilinx där man kunde autojustera klockförskjutningen för bästa samplingstidpunkt.
Re: Aktiva "digitala" högtalare
Jo, den möjligheten finns också. Går dock åt flera DCM:er (iaf om man ska göra det separat för varje kanal) vilket jag inte har.
Finns även en lösning som låter som ett totalt fulhack men som Xilinx själva använder till DDR-minneskontroller, bygg en lång kedja av LUTs och MUXar för att plocka ut signalen ut kedjan efter lagom fördröjning.
Finns även en lösning som låter som ett totalt fulhack men som Xilinx själva använder till DDR-minneskontroller, bygg en lång kedja av LUTs och MUXar för att plocka ut signalen ut kedjan efter lagom fördröjning.
Re: Aktiva "digitala" högtalare
Kolla in XAPP224 Data Recovery hos Xilinix. Där beskriver de en metod som liknar din Cyr. De skapar fyra klockdomäner med hjälp av en DCM och översamplar data, sen synkronserar de tillbaka de fyra bitarna till samma klockdomän och avgör var flanken inträffade. Finns VHDL kod för det också där.
Hur har du implementerat dina 8b/10b block ? Kör du rena lockup tabeller eller har du implementerat logiken som finns föreslagen i standarden ?
Hur har du implementerat dina 8b/10b block ? Kör du rena lockup tabeller eller har du implementerat logiken som finns föreslagen i standarden ?
Re: Aktiva "digitala" högtalare
XAPP224 verkar intressant, ska läsa igenom den efter lite mer morgonkoffein...
Min 8b10b-kod har jag "snott" från http://asics.chuckbenz.com/
Och appropå det så kan jag också tipsa om den här smidiga generatorn för CRC-kod:
http://www.easics.com/webtools/crctool
Min 8b10b-kod har jag "snott" från http://asics.chuckbenz.com/
Och appropå det så kan jag också tipsa om den här smidiga generatorn för CRC-kod:
http://www.easics.com/webtools/crctool
Re: Aktiva "digitala" högtalare
Upptäckte att XAPP225 var ännu mer passande, använder samma princip men något förenklat då det bara hanterar fallet där frekvensen är exakt känd men fasen är okänd. Tog det mesta av XAPP225-designen och applicerade det på min originalidé, så nu har jag implementerat hela RX-blocket och testat det i simulering. Har ingen hårdvara med mig där jag är nu, så test i verkligheten får vänta lite...
Funderar på att peta in hela koden i SVN eller Mercurial innan den växer för mycket, och undrar om jag skulle se till att lägga upp det (read-only) på webben också? Finns det något intresse?

Funderar på att peta in hela koden i SVN eller Mercurial innan den växer för mycket, och undrar om jag skulle se till att lägga upp det (read-only) på webben också? Finns det något intresse?

Re: Aktiva "digitala" högtalare
OK, beta-version av Mercurial-web:
http://hg.area26.se/
Har bara lagt in delar av FPGA-koden än så länge.
Det ska funka att hämta koden antingen som snapshot (ZIP/TGZ/TBZ) eller med "hg clone".
http://hg.area26.se/
Har bara lagt in delar av FPGA-koden än så länge.
Det ska funka att hämta koden antingen som snapshot (ZIP/TGZ/TBZ) eller med "hg clone".
Re: Aktiva "digitala" högtalare
Har precis kört ett litet loopback-test i hårdvara, ingen överdrivet spännande men hela kedjan med 8b10b-kodningen, data-paket, automatisk fas-justering och detektering av komma-symboler etc fungerar tydligen iaf. Testade även med några olika långa kablar och mycket riktigt ändrades vilken fas som samplingen utfördes på i RX-blocket...
Ska lägga på lite logik som faktiskt kollar datan och verifierar CRC, och sen köra lite långtester med olika kablar... so far so good!
Lägger in mer och mer kod i mercurial efter hand, kika om ni vill...
Ska lägga på lite logik som faktiskt kollar datan och verifierar CRC, och sen köra lite långtester med olika kablar... so far so good!
Lägger in mer och mer kod i mercurial efter hand, kika om ni vill...
Re: Aktiva "digitala" högtalare
Går det bra? Såg att fftw uppgraderats och kom att tänka på ditt projekt. Kanske du kan ha nytta av något därifrån?
Re: Aktiva "digitala" högtalare
Sakta men säkert 
Idag snodde jag ihop en enkel 3D-modell av en komplett förstärkarmodul, så jag kunde rita bakpanelen och få alla hål på rätt ställe...

För övrigt har jag bytt SPI-flash två gånger på det lilla FPGA-kortet. Först hade jag satt dit AT45DB011B som jag hade liggande, men jag hade tydligen lite otur när jag tänkte för dessa stöder inte de läskommandon som jag hade "byglat" FPGA:n för att använda. Beställde ett par M25P10 från Elfa och lödde dit, innan jag märkte att de har en helt annan pinout! Till slut köpte jag AT45DB041D från Futurlec och nu funkar det som det ska.
Ibland borde man tänka lite mer innan man handlar
Möjligt att FFTW kan komma till användning så småningom, en bit kvar innan det blir någon rumskorrektion eller liknande dock...

Idag snodde jag ihop en enkel 3D-modell av en komplett förstärkarmodul, så jag kunde rita bakpanelen och få alla hål på rätt ställe...

För övrigt har jag bytt SPI-flash två gånger på det lilla FPGA-kortet. Först hade jag satt dit AT45DB011B som jag hade liggande, men jag hade tydligen lite otur när jag tänkte för dessa stöder inte de läskommandon som jag hade "byglat" FPGA:n för att använda. Beställde ett par M25P10 från Elfa och lödde dit, innan jag märkte att de har en helt annan pinout! Till slut köpte jag AT45DB041D från Futurlec och nu funkar det som det ska.
Ibland borde man tänka lite mer innan man handlar

Möjligt att FFTW kan komma till användning så småningom, en bit kvar innan det blir någon rumskorrektion eller liknande dock...