Projekt UART-krets

Innehållsförteckning

  1. Innehållsförteckning
  2. Bilageförteckning
  3. Bakgrund
  4. Tankegång
  5. VHDL-kod
  6. Kommandofil för simulering
  7. Schema
  8. Test av implementationen

Bilageförteckning

Bilaga 1: Simuleringsresultat

Bilaga 2: Symbolschema

Bakgrund

Jag har som projektuppgift i kursen Digital Konstruktion valt att konstruera en UART-krets, alltså en krets för seriell kommunikation. Den fungerar så att den tar emot seriella indata på en ledning, och sänder vidare denna som en parallell signal till en mottagare.

Det protokoll som används vid den seriella överföringen är tämligen okomplicerat. Då ledningen inte används ligger den som en logisk etta. Före ett utsänt dataord sänds en startbit, vilken består av en logisk nolla. Denna nolla följs sedan av databitarna (i detta fall sju till antalet), en paritetsbit och två stoppbitar (stoppbitarna är logiska ettor). När nästa dataord ska sändas över upprepas proceduren.

Sändningen sker i hastigheten 9.600 bps (bitar per sekund), inklusive start-, stopp- och paritetsbitar. Protokollet använder udda paritet, vilket betyder att det sammanräknade antalet ettor i databitarna och paritetsbiten (start- och stoppbitar räknas ej in) ska vara udda. Kretsen klockas med en klocksignal på 4 MHz.

För att läsa av signalen används några extra signalledningar, en lässignal ("read") som talar om när läsning önskas, en flagga för full buffert ("rdrf" - receive data register full), en flagga för paritetsfel ("parity_error") samt en sjubitars datautgång ("par_data_out"). Full buffert-signalen ettställs då data mottagits (inklusive start- och stoppbitar), och paritetsfel flaggas om den mottagna datan har felaktig paritet. Läsning sker då läs-signalen ges logisk etta, och då nollställs även buffert full- och paritetsfelssignalerna.

Denna UART-krets beskrivs i VHDL-kod, vilken m.h.a lämpliga hjälpmeden kan syntetiseras till ett grindschema, och laddas ner till en programmerbar krets.

Enligt projektbeskrivningen ska utdatat läggas i three-state (hög impedans) då läs-signalen ligger låg, men p.g.a problem vid simuleringen har min konstruktion nollor som utdata i det fallet. Dock borde det inte vara några större problem att ändra i VHDL-koden för att göra detta.

Tankegång

För att realisera UART-kretsen valde jag att göra ett VHDL-"program" som beskriver en sorts tillståndsmaskin. Denna tillståndsmaskin aktiveras då startbiten kommer. Eftersom kretsen klockas med 4 MHz, och kommunikationen ska ske med 9.600 bps måste en räknare (den interna signalen "Count" i VHDL-koden) som inväntar varje bit införas. Denna räknare räknar först in halva startbiten, 208 klockpulser, för att ligga i mitten av signalen (det är osäkert att mäta på "kanten" av signalen), och sedan räknas den i hela pulser (417 klockpulser).

Tillståndsmaskinen har ett tillstånd för varje bit som kan komma in, och det aktuella tillståndet (den interna signalen "State" i VHDL-koden) talar om vilken bit det är som kommer in, och agerar på rätt sätt.

Kretsen har synkron reset, och klockas på positiv klockflank.

VHDL-kod

Här följer den kommenterade VHDL-koden för UART-kretsen:

Källkod ej inkluderad i denna onlineversion

Kommandofil för simulering

Här följer den kommenterade kommandofilen som jag använde vid simuleringen för att få vågformsdiagrammet i bilaga 1.

Till kommandofil

Schema

Se bilaga 2 för symbolschema. Observera att p.g.a ett fel så står det "Clock" i.st.f "Clk" på klockingången. Detta schema beskriver vilka in- och utgångar som finns, samt hur de kopplats till Xilinx-kretsens olika ben.

Test av implementationen

UART-kretsen har testats, BIT-fil för nedladdning till krets finns tillgänglig från författaren, och visat sig fungera. Dock visade det sig att den vid vissa bitmönster ibland kan "komma fel" i inläsningen. Detta beror på att om kretsen uppfattar en bit mitt i som en startbit, så uppfattar den bitmönstret fel.