DSO - fortfarande vid liv.
DSO - fortfarande vid liv.
OK, dags för en tråd till om mitt evighetsprojekt numero uno - PC-DSO.
Varning: Om du inte läst om projektet innan så fattar du nog inte mycket av all text. Tråden innehåller inte heller några bilder eller filmer på coola saker som blinkar, snurrar eller ryker
Det gick några månader utan några nämnvärda framsteg, men den senaste veckan (inspirerad av vädret) så har jag satt igång igen.
Har inga stora foton att fylla ut med den här gången, har inte gjort något intressant på själva hårdvarusidan (förutom nätdelen och lite filande på lådan).
Istället har det blivit kodande på diverse nivåer, mest på själva logiken som ska klämmas in i FPGA:n. Den skrivs i Verilog med hjälp av gratisversionen av Altera Quartus. Klämmas är kanske inte rätt ord förresten, allt ser ut att få plats med god marginal i min Cyclone EP1C12.
Har ritat ett något förenklat blockschema:
Beskrivning av de olika blocken:
CPU
En ganska liten (~400 LE + 9 M4K blockram) och snabb (~100MHz) 16bits RISC-processor. Har samma instruktionsuppsättning som XR16 av Jan Gray (länk) men är skriven av mig baserat på dokumentationen från originalet. Anledningen att jag skrev om den från grunden istället för att modifiera XR16 (verilog-kod finns att ladda ner) var främst att jag inte gillade licensen på original-koden, men också att det var "kul" att skriva sin egen processor. Man är allt lite självplågare...
Processorn har 1kB instruktionscache och 2kB internt data-RAM. De flesta instruktioner körs på en klockcykel så länge de finns i cache, utom hopp som tar tre och load som tar två. Vid cache-miss måste däremot instruktionen hämtas från det externa flash-minnet vilket i nuläget tar nästan 20 cykler! Jag räknar dock med att all riktigt kritisk kod finns i små loopar, och såna går ju med full hastighet utom första iterationen...
UARTs
Totalt ska det finnas 5st UARTs, en används för kommunikation med PC under utvecklingen (debug) och ska senare snacka med en mikrokontroller som har hand om frontpanelen (LCD,LEDs,knappar...). De andra fyra kommunicerar med de fyra samplingsmodulerna, för att t.ex. ställa in förstärkning, offset, AC/DC-kopping osv. Just nu finns det bara en UART i systemet och den är tagen från Opencores (länk). Det roliga är att den tar upp mer logik i FPGA:n än processorn. Ska ersättas av en förenklad variant...
EBIU
External Bus Interface Unit
En brygga mellan den interna Wishbone-bussen (länk) och den externa bussen där Flash och ethernet-kontroller (AX88796) sitter. På grund av brist på IO-pinnar så har den här bussen endast fem adress-pinnar. Det räcker för att adressera registren i ethernet-kontrollern men för att kunna komma åt tillräckligt mycket av flash-minnet används en CPLD som "adress-latch". CPLDn har även till uppgift att ladda FPGA:n vid uppstart från config-data som lagras i samma flash, så den hade suttit där i vilket fall som helst.
DSO control
Styrenhet för själva samplingslogiken. Ansluten till Wishbone-bussen och gör det möjligt för processorn att ställa in alla möjliga parametrar, övervaka triggning m.m och läsa ut den insamplade datan. Beskrivningen lite flummig för att jag inte har börjat implementera denna än.
Downsampler (ett block per kanal)
Samplar ner den inkommande datan från 100Ms/s (eventuellt 200Ms/s) med valfri faktor N upp till 1024. Detta görs genom att beräkna dels medelvärdet av N samples och dels min och max-värdet. Man kan sedan välja att spara endast medelvärdet eller alla tre värdena. På så sätt kan man sampla med en effektiv hastighet på t.ex. 100ks/s och ändå se en liten puls på 10ns (man ser inte hur lång pulsen var, men man ser att något hände).
Memory controller
Lagrar samples i ett externt synkront SRAM, och gör det möjligt att läsa ut dom igen. SRAMet är 36 bitar brett och klarar en hastighet på 166MHz. Kommer förmodligen att köras i 150MHz. Samples lagras med en upplösning på 12 bitar, så på en minnesplats får det plats antingen tre medelvärden eller en uppsättning medel/min/max. Varje kanal (4st) har ett visst minnesområde tilldelat (dynamiskt, genom topp och botten-pekare). Området mellan dessa pekare används som en ringbuffert.
MUX
Väljer kanal till triggern. Kommer eventuellt att byggas ut så det finns möjlighet att trigga på inte bara en kanal utan också på summan av två kanaler eller differensen mellan två.
FIR-filter
Bara planerat än så länge, men tanken är att man ska kunna filtrera bort sånt man inte vill trigga på. Filtret kan implementeras med multiplikatorer byggda av M4K-blocken i FPGA:n. Tyvärr har ju Cyclone inte några hårdvarumultiplikatorer, men multiplikation med konstanter kan göras med ramblocken som lookup-tabeller.
Trigger
Namnet säger väl allt. Har bara en simpel flanktrigger nu, men ska försöka fundera ut något smidigt flexibelt sätt att blanda in tid i triggningen också, så man kan trigga på t.ex. pulslängd. Ett visst antal sample (inställbart) efter trigpunkten stannar inskrivningen av data i minnet och man kan läsa ut datan.
Av blocken på bilden är nog c:a 50% klart nu. Lite fler saker ska tillkomma så småningom, bland annat så ska ju scopet även kunna användas som logikanalysator och det kräver att datan behandlas lite annorlunda. Speciellt behövs en annan trigger-modul och downsampler. Eventuellt ska det även gå att köra data "baklänges" och mata ut data från minnet till moduler med D/A-omvandlare.
En väldig massa mjukvara återstår också, både på DSO-sidan och på PC-sidan.... Men förr eller senare blir det nog klart ändå!
Varning: Om du inte läst om projektet innan så fattar du nog inte mycket av all text. Tråden innehåller inte heller några bilder eller filmer på coola saker som blinkar, snurrar eller ryker
Det gick några månader utan några nämnvärda framsteg, men den senaste veckan (inspirerad av vädret) så har jag satt igång igen.
Har inga stora foton att fylla ut med den här gången, har inte gjort något intressant på själva hårdvarusidan (förutom nätdelen och lite filande på lådan).
Istället har det blivit kodande på diverse nivåer, mest på själva logiken som ska klämmas in i FPGA:n. Den skrivs i Verilog med hjälp av gratisversionen av Altera Quartus. Klämmas är kanske inte rätt ord förresten, allt ser ut att få plats med god marginal i min Cyclone EP1C12.
Har ritat ett något förenklat blockschema:
Beskrivning av de olika blocken:
CPU
En ganska liten (~400 LE + 9 M4K blockram) och snabb (~100MHz) 16bits RISC-processor. Har samma instruktionsuppsättning som XR16 av Jan Gray (länk) men är skriven av mig baserat på dokumentationen från originalet. Anledningen att jag skrev om den från grunden istället för att modifiera XR16 (verilog-kod finns att ladda ner) var främst att jag inte gillade licensen på original-koden, men också att det var "kul" att skriva sin egen processor. Man är allt lite självplågare...
Processorn har 1kB instruktionscache och 2kB internt data-RAM. De flesta instruktioner körs på en klockcykel så länge de finns i cache, utom hopp som tar tre och load som tar två. Vid cache-miss måste däremot instruktionen hämtas från det externa flash-minnet vilket i nuläget tar nästan 20 cykler! Jag räknar dock med att all riktigt kritisk kod finns i små loopar, och såna går ju med full hastighet utom första iterationen...
UARTs
Totalt ska det finnas 5st UARTs, en används för kommunikation med PC under utvecklingen (debug) och ska senare snacka med en mikrokontroller som har hand om frontpanelen (LCD,LEDs,knappar...). De andra fyra kommunicerar med de fyra samplingsmodulerna, för att t.ex. ställa in förstärkning, offset, AC/DC-kopping osv. Just nu finns det bara en UART i systemet och den är tagen från Opencores (länk). Det roliga är att den tar upp mer logik i FPGA:n än processorn. Ska ersättas av en förenklad variant...
EBIU
External Bus Interface Unit
En brygga mellan den interna Wishbone-bussen (länk) och den externa bussen där Flash och ethernet-kontroller (AX88796) sitter. På grund av brist på IO-pinnar så har den här bussen endast fem adress-pinnar. Det räcker för att adressera registren i ethernet-kontrollern men för att kunna komma åt tillräckligt mycket av flash-minnet används en CPLD som "adress-latch". CPLDn har även till uppgift att ladda FPGA:n vid uppstart från config-data som lagras i samma flash, så den hade suttit där i vilket fall som helst.
DSO control
Styrenhet för själva samplingslogiken. Ansluten till Wishbone-bussen och gör det möjligt för processorn att ställa in alla möjliga parametrar, övervaka triggning m.m och läsa ut den insamplade datan. Beskrivningen lite flummig för att jag inte har börjat implementera denna än.
Downsampler (ett block per kanal)
Samplar ner den inkommande datan från 100Ms/s (eventuellt 200Ms/s) med valfri faktor N upp till 1024. Detta görs genom att beräkna dels medelvärdet av N samples och dels min och max-värdet. Man kan sedan välja att spara endast medelvärdet eller alla tre värdena. På så sätt kan man sampla med en effektiv hastighet på t.ex. 100ks/s och ändå se en liten puls på 10ns (man ser inte hur lång pulsen var, men man ser att något hände).
Memory controller
Lagrar samples i ett externt synkront SRAM, och gör det möjligt att läsa ut dom igen. SRAMet är 36 bitar brett och klarar en hastighet på 166MHz. Kommer förmodligen att köras i 150MHz. Samples lagras med en upplösning på 12 bitar, så på en minnesplats får det plats antingen tre medelvärden eller en uppsättning medel/min/max. Varje kanal (4st) har ett visst minnesområde tilldelat (dynamiskt, genom topp och botten-pekare). Området mellan dessa pekare används som en ringbuffert.
MUX
Väljer kanal till triggern. Kommer eventuellt att byggas ut så det finns möjlighet att trigga på inte bara en kanal utan också på summan av två kanaler eller differensen mellan två.
FIR-filter
Bara planerat än så länge, men tanken är att man ska kunna filtrera bort sånt man inte vill trigga på. Filtret kan implementeras med multiplikatorer byggda av M4K-blocken i FPGA:n. Tyvärr har ju Cyclone inte några hårdvarumultiplikatorer, men multiplikation med konstanter kan göras med ramblocken som lookup-tabeller.
Trigger
Namnet säger väl allt. Har bara en simpel flanktrigger nu, men ska försöka fundera ut något smidigt flexibelt sätt att blanda in tid i triggningen också, så man kan trigga på t.ex. pulslängd. Ett visst antal sample (inställbart) efter trigpunkten stannar inskrivningen av data i minnet och man kan läsa ut datan.
Av blocken på bilden är nog c:a 50% klart nu. Lite fler saker ska tillkomma så småningom, bland annat så ska ju scopet även kunna användas som logikanalysator och det kräver att datan behandlas lite annorlunda. Speciellt behövs en annan trigger-modul och downsampler. Eventuellt ska det även gå att köra data "baklänges" och mata ut data från minnet till moduler med D/A-omvandlare.
En väldig massa mjukvara återstår också, både på DSO-sidan och på PC-sidan.... Men förr eller senare blir det nog klart ändå!
Kul att det fortfarande är vid liv. Det ska bli intressant att följa fortsättningen. Jag hade själv planer på att konstruera ett oscilloskop, men nu har jag köpt ett hp-skop.
Intressant det är med att köra data baklänges. Finns det på kommerciella skop? I vilken situation kan man ha praktisk nytta av det?
Intressant det är med att köra data baklänges. Finns det på kommerciella skop? I vilken situation kan man ha praktisk nytta av det?
Roligt se att projectet fort farande är vid liv...
Dock vid ner sampler skulle det kanse vara bra om man kunde leta efter min och max, del viss när man ett strek på skärmen i stället för en pixel (hoppas att du fattar) då man i bland letar efter spikar... och man skulle kunna exempel kunna se modulation på am singal utan problem. jag tror att de kan vara en funktion som kan vara ett bra kompliment till medelvärdet....
Dock vid ner sampler skulle det kanse vara bra om man kunde leta efter min och max, del viss när man ett strek på skärmen i stället för en pixel (hoppas att du fattar) då man i bland letar efter spikar... och man skulle kunna exempel kunna se modulation på am singal utan problem. jag tror att de kan vara en funktion som kan vara ett bra kompliment till medelvärdet....
Pytteliten uppdatering:
Pysslade lite med själva lådan idag:
http://area26.no-ip.org/images/dso/pics/IMG_2031.JPG
Pysslade lite med själva lådan idag:
http://area26.no-ip.org/images/dso/pics/IMG_2031.JPG