Aansturing van een stappenmotor

Vergelijkbare documenten
EE1410: Digitale Systemen BSc. EE, 1e jaar, , 2e werkcollege

Digitale Systeem Engineering 1. Week 4 Toepassing: Pulse Width Modulation Jesse op den Brouw DIGSE1/

Antwoorden zijn afgedrukt!!!!!!!

Digitale Systemen (ET1 410)

Project Digitale Systemen

Studentnummer:... Opleiding:...

Opgave Tussentijdse Oefeningen Jaarproject I Reeks 4: Lcd Interface & Files

Inleiding Digitale Techniek

Digitale Systeem Engineering 1. Week 1 VHDL basics, datatypes, signal assignment Jesse op den Brouw DIGSE1/

b) Geef het schema van een minimale realisatie met uitsluitend NANDs en inverters voor uitgang D.

Eindtentamen Digitale Systemen 07/07/2006, uur

Toets Digitale Systemen 01/06/2006, uur

Scan-pad technieken. Zet elk register om in een scan-pad register (twee opeenvolgende D-latches: master-slave):

Basisconcept VHDL. Digitaal Ontwerpen Tweede studiejaar. Wim Dolman. Engineering, leerroute Elektrotechniek Faculteit Techniek

Combinatorisch tegenover sequentieel

EE1410: Digitale Systemen BSc. EE, 1e jaar, , vragencollege 2

Tentamen Digitale Systemen (EE1410) 6 juli 2012, uur

EE1410: Digitale Systemen BSc. EE, 1e jaar, , vragencollege 1

Faculteit Elektrotechniek - Leerstoel ES Tentamen Schakeltechniek. Vakcode 5A050, 19 januari 2005, 14:00u-17:00u

Jan Genoe KHLim. Reken schakelingen. Jan Genoe KHLim

Faculteit Elektrotechniek - Leerstoel ES Tentamen Schakeltechniek. Vakcode 5A050, 19 januari 2005, 14:00u-17:00u

EE1410: Digitale Systemen BSc. EE, 1e jaar, , 8e hoorcollege

Sequentiële schakelingen

Hfdst. 2: COMBINATORISCH PROGRAMMEREN

Klasse B output buffer voor een Flat Panel Display Kolom aansturing

Faculteit Elektrotechniek - Leerstoel ES Tentamen Schakeltechniek. Vakcode 5A050, 17 november 2004, 9:00u-12:00u

Lab6: Implementatie video timing generator

Dobbelsteen 6 Tabellendemo: alle opgedane ervaringen gebundeld

Combinatorische schakelingen

Digitale technieken Deeltoets II

Microcontrollers Labo

Ontwerp van digitale systemen. in VHDL

VANTEK Discovery set. N. B. De OPITEC bouwpakketten zijn gericht op het onderwijs. N991240#1

INHOUDSTAFEL... 2 VOORWOORD... 3 INLEIDING... 4 GEBRUIK VAN MOTOREN... 8 DE HERHAALFUNCTIE... 9 SAMENVATTENDE OEFENING... 10

Opgaven. en uitwerkingen bij het boek Digitale Techniek. Jesse op den Brouw

Labo digitale technieken

Jan Genoe KHLim. VHDL Inleiding. In dit hoofdstuk situeren we het steeds toenemende belang van VHDL in het elektronisch ontwerp.

Antwoorden vragen en opgaven Basismodule

Studiewijzer Digitale Systeemengineering 1 (E-DIGSE1-13) 3 studiepunten

Hardware-software Co-design

KAEDU : Outputs en inputs

Getalformaten, timers en tellers

De keuzestructuur. Versie DD

Logische algebra. 1. Wat zijn Booleaanse variabelen? 2. Bewerkingen op Booleaanse variabelen. 2.1 Inversie. 2.2 Product

B3C 70cm converter besturing. v PE5PVB bar.net bar.net

OPDRACHTEN PRACTICUM DIGSE1. J.E.J op den Brouw De Haagse Hogeschool Opleiding Elektrotechniek 19 maart 2016

ES1 Project 1: Microcontrollers

Proeftentamen in1211 Computersystemen I (NB de onderstreepte opgaven zijn geschikt voor de tussentoets)

Logische functies. Negatie

Logische Schakelingen

INHOUDSTAFEL... 2 VOORWOORD... 3 INLEIDING... 4 GEBRUIK VAN MOTOREN... 9 DE HERHAALFUNCTIE ZELF EEN BLOK MAKEN... 11

De FOR lus: // terug naar waar je vandaan kwam Serial.begin(115200); // communicatie snelheid met de PC

Sequentiële Logica. Processoren 24 november 2014

In deze mannual zal ik het voorbeeld van de Led cube gebruiken maar de principes zijn op alles toepasbaar.

Programmeren met Arduino-software

Digitaal Ontwerp Mogelijke Examenvragen

GIP. De computer gestuurde trein

Deel 1: Arduino kennismaking. Wat is een microcontroller, structuur van een programma, syntax,

Small Basic Programmeren Text Console 2

Inleiding Digitale Techniek

Proeftentamen Digitale technieken

Opgave Tussentijdse Oefeningen Jaarproject I Reeks 3: Tijd, licht en warmte

Multiplexers en demultiplexers MULTIPLEXERS

Computer architecturen: Muis en toetsenbord

Over Betuwe College. Lego Mindstorm project

Rekenen aan wortels Werkblad =

7,6. Samenvatting door A woorden 12 april keer beoordeeld. Natuurkunde. Natuurkunde Systemen. Systemen

Informatica 2. Met uitwerkingen n.a.v. document van Elvire Theelen in Luc bijgewerkt door Peter van Diepen

RAM geheugens. Jan Genoe KHLim. Situering RAM-geheugens. Geheugens. Halfgeleider Geheugens. Willekeurig toegankelijk geheugen

Een intelligent DMX netwerk

Inhoudsopgave. Optimalisatie van de mmips. Forwarding optie 1. Design flow. implementation

Proeftentamen in1211 Computersystemen I (Opm: de onderstreepte opgaven zijn geschikt voor de tussentoets)

Meetopdrachten Poortschakelingen 1 met Multisim

Mindstorms-Ev3 Robot

Space Invaders op de micro:bit

2 Algemene opbouw van een computersysteem

De Arduino-microcontroller in de motorvoertuigentechniek (2)

Microcontrollers Week 1 Introductie microcontroller Jesse op den Brouw INLMIC/

Ontwerpmethoden. Doelstelling

Deeltoets Digitale technieken

Zelftest Programmeren in PL/I

VAN HET PROGRAMMEREN. Inleiding

EE1410: Digitale Systemen BSc. EE, 1e jaar, , 6e hoorcollege

Het grondtal van het decimaal stelsel is 10. Voorbeeld: het getal Poorten De tellereenheid Mevr. Loncke 1

2 Elementaire bewerkingen

In- en uitgangssignalen van microprocessoren

Transcriptie:

Cursus VHDL deel 2: Aansturing van een stappenmotor Jan Genoe In dit uitgewerkt voorbeeld schetsen we de werkwijze die moet gevolgd worden om uitgaande van een probleemstelling tot een concrete en werkende oplossing te komen Versie: zondag 2 april 2000 1

Basisopgave Programmeer de aandrijving van een stappenmotor die in twee richtingen kan draaien 4 wikkelingen (A, B, C, D) moeten aangestuurd worden (actief hoog) Drie drukknoppen zijn voorzien als input: voorwaarts (draaivolgorde: A, B, C, D, A,.) achterwaarts (draaivolgorde: D, C, B, A, D,.) stop (prioritair ten opzichte van de andere drukknoppen) De sequentie van wikkelingen wordt aangedreven met de snelheid van de klok library ieee; ieee; use use ieee.std_logic_1164.all; entity stappenmotor is is port port ( voorwaarts, achterwaarts, stop: stop: in in std_logic; klok: klok: in in std_logic; A,B,C,D: out out std_logic); end end stappenmotor; Een eerste stap in het analyseren van een opgave is altijd het bepalen van: Wat zijn de ingangssignalen en wat is het type? Wat zijn de uitgangssignalen en wat is het type? Met hoeveel klokken wordt er gewerkt? Op basis hiervan kan dan eigenlijk al de entity van de VHDL code geschreven worden. Versie: zondag 2 april 2000 2

Eerste stap: implementatie FSM Er zijn drie toestanden extern waarneembare aanwezig: T_stop (ook de opstart toestand) T_voorwaarts T_achterwaarts opstart T_Stop T_Voorwaarts T_Achterwaarts Vervolgens moet het functioneren van het te ontwerpen bouwblok bekeken worden: Is het een zuiver combinatorisch blok? Heeft het blok een geheugenwerking voor de toestand waarin het zich bevindt? - In dit geval is het belangrijk de verschillende toestanden waarin het systeem zich kan bevinden te herkennen en te benoemen. - Vervolgens tekenen we een diagram dat ons toelaat de overgangen tussen de verschillende toestanden te bepalen. Versie: zondag 2 april 2000 3

Code voor state variabelen De mogelijke toestanden definiëren we steeds als een nieuw type voor de toestandsvariabelen. Het synthese tool kan dan de meest aangewezen state encodering kiezen. architecture architecture motor_arch motor_arch of of stappenmotor is is type type Extern_T Extern_T is is (T_stop,T_voorwaarts,T_achterwaarts); signal signal T_oud,T_nieuw T_oud,T_nieuw : Extern_T; Extern_T; begin begin -- -- nu nu verder verder in in te te vullen vullen end end motor_arch; motor_arch; De verschillende toestanden waarin het systeem zich kan bevinden slagen we op als een signaal in een toestandsvariabele. We definiëren dit signaal als een opsommingstype. Meestal is de state, die het eerste voorkomt in de lijst, de state waar het systeem in terechtkomt bij het opstarten Opmerking: Men kan natuurlijk ook ervoor kiezen de state encodering manueel uit te voeren. Hiertoe dienen echter een aantal regels gevolgd te worden en is vaak ook een hele optimalisatie nodig. Versie: zondag 2 april 2000 4

Transitie diagram Onder welke voorwaarde van stop, voorwaarts en achterwaarts gaan we over? 000,1XX 011 stop, voorwaarts, achterwaarts opstart T_Stop 0X0 010 001 1XX, 1XX, 011 011 00X T_Voorwaarts 001 010 T_Achterwaarts Vervolgens maken we een lijstje op van de inputsignalen die gaan bepalen wanneer we overgaan van de ene toestand naar de andere toestand (dit lijstje is hier omkaderd) Voor elk van de mogelijke transities gaan we bepalen welke inputsignalen nodig zijn om die transitie te kunnen maken. (De signalen die hierbij niet van belang zijn kunnen we weergeven met een X) Opmerking: Het is hierbij belangrijk na te kijken of alle mogelijkheden van de inputsignalen ook op het schema weergegeven worden. Versie: zondag 2 april 2000 5

Combinatorisch process voor volgende toestand Enkel stop, voorwaarts, achterwaarts (kader op het transitie diagram) bepalen de evolutie, dus deze komen samen met de huidige toestand in de sensitivity list. comb_t comb_t : process(t_oud,stop,voorwaarts,achterwaarts) begin begin if if (stop (stop = '1')or '1')or ((achterwaarts='1') and and (voorwaarts='1')) then then T_nieuw T_nieuw <= <= T_stop; T_stop; elsif elsif voorwaarts='1' voorwaarts='1' then then T_nieuw T_nieuw <= <= T_voorwaarts; T_voorwaarts; elsif elsif achterwaarts='1' then then T_nieuw T_nieuw <= <= T_achterwaarts; T_achterwaarts; else else T_nieuw T_nieuw <= <= T_oud; T_oud; end end if; if; end end process process comb_t; comb_t; Het state diagram kunnen we nu gaan vertalen naar een combinatorisch process dat de volgende toestand bepaalt op basis van: De huidige toestand De input signalen Deze komen dan ook beiden voor in de sensitivity list van het process. Kijk goed na of het process volledig overeenkomt met het state diagram. Versie: zondag 2 april 2000 6

geklokt process voor volgende toestand Bij een geklokt process staat enkel de klok in de sensitivity list (er zijn geen asynchrone resets) Seq_T: Seq_T: Process Process (klok) (klok) begin begin if if (klok'event and and (klok='1')) then then T_oud T_oud <= <= T_nieuw; end end if; if; end end process process Seq_T; Seq_T; Het tweede deel van de Moore FSM slaagt de toestand op in een register. Hiervoor gebruiken we een eenvoudig geklokt process. Versie: zondag 2 april 2000 7

Alternatieve implementatie Tussen voorwaarts en achterwaarts stoppen we eventjes opstart 000,1XX 011 T_Stop stop, voorwaarts, achterwaarts 0X0 010 001 1XX, 1XX, 0X1 01X 00X T_Voorwaarts T_Achterwaarts Een alternatieve implementatie zou kunnen zijn dat we, elke keer we veranderen van draairichting, dat we dan over de stoptoestand passeren. Het toestandsdiagram ziet er dan als het volgt uit. Opmerking: Dit vereist dat de druktoets minstens 2 klokperiodes ingeduwd wordt om van de voorwaartse draairichting naar de achterwaartse draairichting over te gaan, of omgekeerd. Voor normale kloksnelheden is dit geen probleem. Dit kan bovendien een methode zijn om een stoorpuls op de lijn uit te schakelen (zie later). Versie: zondag 2 april 2000 8

Interne FSM Welke wikkeling (A,B,C,D) momenteel aangedreven wordt, bepaalt de interne FSM T_A T_D T_B T_C Er is echter nog een tweede FSM aanwezig in dit systeem. Om met een vaste sequentie de verschillende stuurklemmen van de stappenmotor te kunnen aansturen moet de vorige stuurklem sowieso onthouden worden. Een geheugenwerking impliceert zo goed als altijd een FSM. Versie: zondag 2 april 2000 9

Toevoegen state variabelen in de architectuur architecture architecture motor_arch motor_arch of of stappenmotor is is type type Extern_T Extern_T is is (T_stop,T_voorwaarts,T_achterwaarts); type type Intern_T Intern_T is is (T_A,T_B,T_C,T_D); signal signal T_oud,T_nieuw T_oud,T_nieuw : Extern_T; Extern_T; signal signal Ti_oud,Ti_nieuw Ti_oud,Ti_nieuw : Intern_T; Intern_T; begin begin -- -- nu nu verder verder in in te te vullen vullen end end motor_arch; motor_arch; We definiëren opnieuw een opsommingstype (hier Intern_T) waarin de 4 mogelijke toestanden (T_A, T_B, T_C, en T_D) zijn opgenomen. We definiëren ook 2 nieuwe signalen, een voor de nieuwe interne toestand (Ti_nieuw) en een voor de opgeslagen interne toestand, of de oude interne toestand (Ti_oud). Deze declaraties komen bij de aanvang van de architectuur. Versie: zondag 2 april 2000 10

Transitie diagram De combinaties die niet kunnen voorkomen moeten niet weergegeven worden 100 T_stop, T_voorwaarts, T_achterwaarts 100 T_A 100 010 010 T_D 001 001 001 001 T_B 010 T_C 010 100 Opnieuw maken we een transitie diagram voor deze FSM, waarbij we gaan bepalen hoe het systeem evolueert onder invloed van de ingangssignalen. Het enige ingangssignaal dat hier gebruikt wordt is de externe toestand. Versie: zondag 2 april 2000 11

Combinatorisch process voor volgende toestand comb_ti comb_ti : process(ti_oud,t_oud) begin begin if if T_oud T_oud = T_voorwaarts T_voorwaarts then then case case Ti_oud Ti_oud is is when when T_A=>Ti_nieuw T_A=>Ti_nieuw <= <= T_B; T_B; when when T_B=>Ti_nieuw T_B=>Ti_nieuw <= <= T_C; T_C; when when T_C=>Ti_nieuw T_C=>Ti_nieuw <= <= T_D; T_D; when when others=>ti_nieuw <= <= T_A; T_A; end end case; case; elsif elsif T_oud T_oud = T_achterwaarts T_achterwaarts then then case case Ti_oud Ti_oud is is when when T_A=>Ti_nieuw T_A=>Ti_nieuw <= <= T_D; T_D; when when T_B=>Ti_nieuw T_B=>Ti_nieuw <= <= T_A; T_A; when when T_C=>Ti_nieuw T_C=>Ti_nieuw <= <= T_B; T_B; when when others=>ti_nieuw <= <= T_C; T_C; end end case; case; else else Ti_nieuw Ti_nieuw <=Ti_oud; <=Ti_oud; end end if; if; end end process process comb_ti; comb_ti; We kunnen nu het combinatorisch process opbouwen dat de nieuwe toestand afleidt op basis van de oude toestand en het ingangssignaal. We testen hier de 2 gevallen van het ingangssignaal, namelijk T_voorwaards en T_achterwaards. In het geval van T_stop dient de toestand niet te veranderen. Dit wordt in de else toegevoegd. Versie: zondag 2 april 2000 12

Geklokt process voor volgende toestand Seq_Ti: Seq_Ti: Process Process (klok) (klok) begin begin if if (klok'event and and (klok='1')) then then Ti_oud Ti_oud <= <= Ti_nieuw; end end if; if; end end process process Seq_Ti; Seq_Ti; Bij het toekomen van de klok dient de nieuw berekende toestand in het geheugen opgeslagen te worden. Dit doen we aan de hand van een geklokt process. Versie: zondag 2 april 2000 13

Combinatorisch Output process Het output process wordt enkel bepaald door de state variable (Ti_oud) comb_out: Process (Ti_oud) begin begin case case Ti_oud is is when when T_A=>A<='1';B<='0';C<='0';D<='0'; when when T_B=>A<='0';B<='1';C<='0';D<='0'; when when T_C=>A<='0';B<='0';C<='1';D<='0'; when when T_D=>A<='0';B<='0';C<='0';D<='1'; end end case; case; end end process comb_out; Als laatste dienen we de uitgangen van deze Moore FSM te bepalen. Bij een Moore FSM worden de uitgangen enkel maar bepaald door de huidige toestand en niet door de ingangssignalen. De uitgangen worden dus bepaald aan de hand van een combinatorisch process met Ti_oud als enige ingang. Nu hebben we alle VHDL code om deze aansturing te implementeren. Wanneer we de entity (pg 2) laten volgen door de architectuur (pg 10) en we vullen hier de processen gegeven op paginas 6, 7, 12,13, en 14 krijgen we een werkend sturing voor een stappenmotor. Doe dit, dit is een goede oefening. Versie: zondag 2 april 2000 14

Resultaat van simulatie 4 onderste signalen zijn input, de 4 bovenste signalen zijn de output. Het nummer van de pin staat erbij Voor de eerste klok is de toestand onduidelijk. Deze sturing hebben we eerst gesynthetiseerd naar een CPLD (de C331 van Cypress) en na synthese de werking gesimuleerd aan de hand van de NOVA simulator. We zien dat het signaal achterwaarts, dat het eerst toekomt de aanstuursequentie in gang zet volgens A, D, C, B, A, D, C Dan komt er een stop puls en blijft het systeem een aantal periodes stroom voren naar wikkeling C. Vervolgens komt er een voorwaarts puls en loop de sequentie verder als C, D, A, B, C, D, A, B, C, D, A,. Indien nodig voor debug toepassingen kan je ook de interne signalen (zoals voor de toestand) toevoegen op het display. Versie: zondag 2 april 2000 15

Report file: gebruikte state encodering State variable 't_nieuw' is represented by a Bit_vector (0 to 1). State encoding (sequential) for 't_nieuw' is: t_stop := b"00"; t_voorwaarts := b"01"; t_achterwaarts := b"10"; State variable 't_oud' is represented by a Bit_vector (0 to 1). State encoding (sequential) for 't_oud' is: t_stop := b"00"; t_voorwaarts := b"01"; t_achterwaarts := b"10"; State variable 'ti_nieuw' is represented by a Bit_vector (0 to 1). State encoding (sequential) for 'ti_nieuw' is: t_a := b"00"; t_b := b"01"; t_c := b"10"; t_d := b"11"; State variable 'ti_oud' is represented by a Bit_vector (0 to 1). State encoding (sequential) for 'ti_oud' is: t_a := b"00"; t_b := b"01"; t_c := b"10"; t_d := b"11"; Wanneer er nu iets niet functioneert zoals we wensen, gaan we in de eerste plaats nakijken of het systeem wel in de toestand is waarin het zich zou moeten bevinden. Dit kunnen we doen door ook de signalen die de toestand voorstellen op het display te brengen. Hiervoor moeten we natuurlijk weten welke code welke toestand voorstelt. Dit kunnen we terugvinden in de report file. Hierin geeft het synthese tool weer welke encodering hij voor de verschillende toestanden gekozen heeft. Versie: zondag 2 april 2000 16

Report file: design equations voor de output DESIGN EQUATIONS (21:36:31) a a = /ti_oudsbv_0.q * /ti_oudsbv_1.q b = /ti_oudsbv_0.q * ti_oudsbv_1.q c c = ti_oudsbv_0.q * /ti_oudsbv_1.q d = ti_oudsbv_0.q * ti_oudsbv_1.q t_a := t_b := t_c := t_d := b"00"; b"01"; b"10"; b"11"; In de report file vinden we ook alle booleaanse vergelijkingen terug van de combinatorisch blokjes. Het synthese tool herleidt deze tot zijn sum of products vorm (SOP). Omdat deze report file een ascii file is en er dus geen streep boven een variabele kan gezet worden om de negatie aan te duiden, is elke variabele die genegeerd moet worden voorafgegaan door een /. Ook deze vergelijkingen laten toe na te kijken wat er gebeurt als het systeem niet doet wat het zou moeten doen. Versie: zondag 2 april 2000 17

design equations voor de output t_oudsbv_0.d = t_nieuwsbv_0 t_oudsbv_0.c = klok klok Data ingang FF bit 0 klok ingang FF bit 0 t_oudsbv_1.d = t_nieuwsbv_1 t_oudsbv_1.c = klok klok En hoe zijn dan de geheugen elementen of state registers terug te vinden in deze report file. De state registers worden weggeschreven naar Flip-Flops, meestal D-Flip- Flops, maar het kunnen ook andere Flip-Flops zijn. Elk van deze Flip-Flops heeft de nodige signalen liggen aan zijn ingangen, zoals D-ingang (Data ingang), C-ingang (klok ingang). Deze ingangen worden gekenmerkt door de naar van het blok met een.d of een.c erachter. De report file geeft ook hier weer aan wat er aan deze ingangen ligt. Versie: zondag 2 april 2000 18

Besluit synthese CPLD CY7C331-20PC Kleinste uit de reeks 20 % van de producttermen gebruikt 56 % van de macrocellen gebruikt c331 c331 achterwaarts achterwaarts = = 1 1 28 = 28 = t_nieuwsbv_0 t_nieuwsbv_0 voorwaarts voorwaarts = = 2 2 27 = 27 = a a not not used used * * 3 3 26 = 26 = t_nieuwsbv_1 t_nieuwsbv_1 not not used used * * 4 4 25 = 25 = c c not not used used * * 5 5 24 = 24 = t_oudsbv_0 t_oudsbv_0 not not used used * * 6 6 23 = 23 = stop stop not not used used * * 7 7 22 * 22 * not not used used not not used used * * 8 8 21 * 21 * not not used used not not used used * * 9 9 20 = 20 = ti_oudsbv_0 ti_oudsbv_0 not not used used * 10 * 10 19 = 19 = klok klok not not used used * 11 * 11 18 = 18 = d d not not used used * 12 * 12 17 = 17 = ti_nieuwsbv_0 ti_nieuwsbv_0 not not used used * 13 * 13 16 = 16 = b b not not used used * 14 * 14 15 = 15 = ti_nieuwsbv_1 ti_nieuwsbv_1 De report file geeft hier ook aan welk percentage van de producttermen er werkelijk gebruikt worden. Welk percentage van de macrocellen er gebruikt wordt. Voor dit eenvoudig ontwerp stelt er zich geen probleem. Ook kan er een overzicht bekomen worden dat aangeeft welke signalen op welke pinnen van de IC toekomen. Versie: zondag 2 april 2000 19

Synthese naar de kleinste FPGA: overzicht Slechts een klein deel van de logica is gebruikt: 7.3 % van de cellen 20 % van de bonding padden 2 % van de verbindingslijnen 0.1 % van de via s Grootste vertraging: 12.1 ns Het systeem kan ook gesynthetiseerd worden naar een FPGA. We kozen ook hier weer de kleinste uit de reeks. Na de synthese moeten we overgaan naar de routing. Slechts na de routing kunnen we de interne vertragingen kennen omdat bij een FPGA het de lengte van de verbinding is die de vertraging zal bepalen. Als we het bekomen schema op zijn geheel bekijken ziet het eruit als hierboven. We zien dat er ook hier weer slechts een beperkt deel van de IC gebruikt wordt. Het bovenstaande schema gaan we in meer detail bekijken: Versie: zondag 2 april 2000 20

Synthese naar de kleinste FPGA: eerste FSM Eerst bekijken we de linkerbovenhoek. We zien hier de bonding paden waaraan de 4 inputsignalen worden verbonden en vandaar gaat het naar de FSM die de externe toestand gaat bijhouden (bouwblokken C1 en C2). Versie: zondag 2 april 2000 21

Synthese naar de kleinste FPGA: beide FSM De uitgang van deze externe FSM stuurt de ingang van de interne FSM aan. Deze is geïmplementeerd in bouwblokken D1 en D2. (De weergave is het middelste deel van bovenaan pagina 20) Versie: zondag 2 april 2000 22

Synthese naar de kleinste FPGA: output De resultaten van deze interne FSM worden dan weer gebruikt om de 4 uitgangen aan te drijven. (De weergave is het rechter deel van bovenaan pagina 20) Versie: zondag 2 april 2000 23

Delay histogram Aantal verbindingen Vertragingstijd (ns) Elke knoop die weergegeven is op de voorgaande schema heeft een zekere vertraging ten opzichte van de knopen die deze knopen bepalen. Het routing-analyse tool geeft hiervan een volledige lijst. Wanneer we al deze vertragingen op een histogram uitzetten bekomen we het bovenstaande overzicht. Het belangrijkste hierbij is dat de grootste vertraging 12.1 ns is. Versie: zondag 2 april 2000 24

Vertraging per pad nummer Vertragingstijd (ns) Nummer van de verbinding De vertraging kan ook worden uitgezet in functie van het nummer van het verbindingspad. Dat wordt weergegeven in de bovenstaande figuur. Versie: zondag 2 april 2000 25

Aanpassing van de opgave (1) Een stappenmotor kan ook aan halve snelheid worden gebruikt. Hiertoe wordt de tussenpositie gebruikt. Dit wordt bekomen door beide klemmen gelijktijdig aan te sturen. De voorwaartse sequentie die dan wordt bekomen is A, AB, B, BC, C, CD, D, DA, en een gelijkaardige sequentie voor achterwaarts Een schakelaar (geen drukknop) laat toe te selecteren tussen volle ( 1 ) en halve ( 0 ) snelheid. Zorg ervoor dat, als hij overgaat van volle snelheid voorwaarts naar volle snelheid achterwaarts, er langs halve snelheid voorwaarts, stop en halve snelheid achterwaarts gepasseerd wordt (maar gedurende 1 klokperiode). Equivalente overgangen passeren op een equivalente wijze langs de stop. entity stappenmotor is is port port ( voorwaarts, achterwaarts, stop: stop: in in std_logic; klok: klok: in in std_logic; snelheid: in in std_logic); A,B,C,D: out out std_logic); end end stappenmotor; Voer deze aanpassing in het Labo uit aan de hand van Xilinx hardware. Indien je hiermee klaar bent, kan je ook aan de hand van LEDs de draairichting aangeven. Versie: zondag 2 april 2000 26

Implementatie van de stappenmotor Hierboven wordt een mogelijke implementatie aangegeven van een stappenmotor met 3 spoelen, namelijk A, B, en C. Voor verdere details verwijs ik naar de cursus motoren. Versie: zondag 2 april 2000 27

Positie van de stappenmotor Een stappenmotor kan veel stappen per omwenteling hebben Tot 1000 stappen per omwenteling is niet ongewoon Het is vaak belangrijk de positie, of de hoek bij te houden We veronderstellen in dit uitgewerkt voorbeeld dat we 200 posities moeten kunnen bijhouden (van 0 tot 199) Dit is dus een FSM met 200 toestanden We gaan dit implementeren als een teller (dit is ook een FSM) een stap vooruit is +1 een stap achteruit is -1 85 86 87 88 89 90 91 92 Versie: zondag 2 april 2000 28

Implementatie van de teller (voorbeeld 2) We moeten een bibliotheek (package) gebruiken waarin staat hoe een optelling moet geïmplementeerd worden Een optelling in hardware kan gebeuren op veel verschillende manieren (ripple carry, carry select, ) Wij moeten kiezen hoe In elke bibliotheek (package) wordt een keuze gemaakt Je kan overwegen een andere implementatie te gebruiken omwille van verschillende redenen: snelheid, hoeveelheid logica,... Vooraan in de VHDL code (voor de declaratie van de entity) komt dus: library ieee; use ieee.std_logic_1164.all; use work.std_arith.all; Versie: zondag 2 april 2000 29

Vergelijking van de teller met de interne FSM Wanneer we de teller vergelijken met de interne FSM zien we dat deze erg parallel lopen. Bovendien zien we dat de 2 laatste bits overeenkomen met de wikkeling die moet aangestuurd worden. We kunnen dus de interne FSM vervangen door de implementatie van de teller. Maar indien we we een stappenmotor met 3 fasen genomen hadden (zie implementatievoorbeeld) konden we we de de beide FSM niet samennemen Dan behouden we ze allebei Versie: zondag 2 april 2000 30

Signaal declaraties: voorbeeld 2 We declareren de teller als een vector van 8 bits architecture motor_arch of of stappenmotor is is type type Extern_T is is (T_stop,T_voorwaarts,T_achterwaarts); signal T_oud,T_nieuw : Extern_T; signal teller, teller_nieuw:std_logic_vector(7 downto 0); 0); begin begin...... Versie: zondag 2 april 2000 31

Combinatorisch process voor volgende toestand Het combinatorisch process voor de volgende toestand van de teller wordt: comb_ti : process(t_oud,teller) begin begin if if T_oud T_oud = T_voorwaarts then then teller_nieuw<=teller+1; elsif elsif T_oud T_oud = T_achterwaarts then then teller_nieuw<=teller-1; else else teller_nieuw <= <= teller; end end if; if; end end process comb_ti; Dit is eenvoudiger dan de vorige implementatie Deze VHDL code is inderdaad eenvoudiger dan de vorige implementatie. De nodige hardware zal daarentegen veel complexer zijn. Voor de optelling wordt gebruik gemaakt van de bibliotheek. Versie: zondag 2 april 2000 32

Geklokt process voor volgende toestand Het nieuwe geklokte process wordt: Seq_Ti: Process (klok) begin begin if if (klok'event and and (klok='1')) then then teller <= <= teller_nieuw; end end if; if; end end process Seq_Ti; Versie: zondag 2 april 2000 33

Combinatorisch Output process Het output process wordt enkel bepaald door de waarde van de teller comb_out: Process (teller) begin begin case case teller(1 downto 0) 0) is is when when "00"=>A<='1';B<='0';C<='0';D<='0'; when when "01"=>A<='0';B<='1';C<='0';D<='0'; when when "10"=>A<='0';B<='0';C<='1';D<='0'; when when others =>A<='0';B<='0';C<='0';D<='1'; end end case; case; end end process comb_out; Wanneer we alle nieuwe code in de file van de vorige code inbrengen krijgen we een nieuwe file die we kunnen simuleren. Oefening: werk dit voorbeeld ook uit voor halve stappen. Gebruik hiervoor een 9 bit getal. Een hele stap vooruit is +2 Een halve stap vooruit is +1 Een halve stap achteruit is -1 Een hele stap achteruit is -2 Versie: zondag 2 april 2000 34

Bespreking van de synthese Na synthese blijkt alles normaal te werken In de report file vinden we echter: ---------------------------------------------------------- ---------------------------------------------------------- Detecting Detecting unused unused logic. logic. ---------------------------------------------------------- ---------------------------------------------------------- User User names names teller_nieuw_7 teller_nieuw_7 teller_nieuw_6 teller_nieuw_6 teller_nieuw_5 teller_nieuw_5 teller_nieuw_4 teller_nieuw_4 teller_nieuw_3 teller_nieuw_3 teller_nieuw_2 teller_nieuw_2 teller_7 teller_7 teller_6 teller_6 teller_5 teller_5 teller_4 teller_4 teller_3 teller_3 teller_2 teller_2 Deleted Deleted 12 12 User User equations/components. equations/components. Deleted Deleted 12 12 Synthesized Synthesized equations/components. equations/components. Versie: zondag 2 april 2000 35

Bespreking van de synthese (2) Dit is logisch: intern gebruiken we deze hogere orde bits niet we exporteren deze bits ook niet (ze staan niet in de port van de entity) Dus zal hij deze extra logica niet maken als hij ze toch niet gebruikt. Het nodige aantal producttermen macrocellen blijft dus ook exact hetzelfde dan bij de vorige synthese Waarom dan de teller bijvoegen? Versie: zondag 2 april 2000 36

Meerwaarde van de teller (1) De meerwaarde van het toevoegen van een teller is dat we er voor kunnen zorgen dat de motor steeds binnen zijn grenzen (0 tot 199) blijft. We moeten deze eis dan ook toevoegen aan het combinatorisch blok voor de volgende tellerwaarde. comb_ti : process(t_oud,teller) begin begin if if (T_oud = T_voorwaarts) and and (teller/="11000111") then then teller_nieuw<=teller+1; elsif elsif (T_oud = T_achterwaarts) and and (teller/= 00000000") then then teller_nieuw<=teller-1; else else teller_nieuw <= <= teller; end end if; if; end end process comb_ti; Versie: zondag 2 april 2000 37

Bespreking van de synthese Dit krijgen we niet meer in een CY7C331-20PC omdat dit ontwerp te complex geworden is, vooral door de vergelijking en de optelling. Een CPLD expandeert deze volledig Een CY7C341B-15HC is bijvoorbeeld wel een goede CPLD om de synthese naar uit te voeren. Versie: zondag 2 april 2000 38

Invoering van de reset Om een systeem bij het opstarten of bij een probleem in de goede startsituatie te krijgen is het meestal goed een globale reset te voorzien. Elk geklokt process passen we aan als hiernaast aangegeven De reset moet ook aan de port toegevoegd worden Bij het begin van een simulatie brengen we de reset gedurende enkele ticks 1 Seq_T: Seq_T: Process Process (reset,klok) (reset,klok) begin begin if if reset='1' reset='1' then then T_oud T_oud <=T_stop; <=T_stop; elsif elsif (klok'event (klok'event and and (klok='1')) (klok='1')) then then T_oud T_oud <= <= T_nieuw; T_nieuw; end end if; if; end end process process Seq_T; Seq_T; Seq_Ti: Seq_Ti: Process Process (reset,klok) (reset,klok) begin begin if if reset='1' reset='1' then then teller teller <="00000000"; <="00000000"; elsif elsif (klok'event (klok'event and and (klok='1')) (klok='1')) then then teller teller <= <= teller_nieuw; teller_nieuw; end end if; if; end end process process Seq_Ti; Seq_Ti; Versie: zondag 2 april 2000 39

Uitbreiding voor de liefhebbers Toon de huidige positie van de stappenmotor op een 3-digit seven segment display, waarvan de cijfers gemultiplexed zijn Omrekenen van de digitale waarde van de positie naar een BCD waarde vraagt veel te veel logica. Houdt de positie ook decimaal bij, in parallel Implementeer 3 FSM, elk als een BCD teller. Implementeer een combinatorische BCD naar seven-segement decoder Implementeer een multiplexer tussen deze BCD tellers en de decoder Implementeer een FSM die afwisselend elk van de 3 cijfers naar de decoder stuurt. Versie: zondag 2 april 2000 40

Stappenmotor met externe positiesturing In de port voegen de 3 signalen toe: de gewenste positie (8bit: in) het go signaal (in) waarna de gewenste positie gestockeerd wordt en de motor naar deze positie gaat het ok signaal (out) als deze positie bereikt is. Verwijder 2 signalen uit de port: voorwaarts en achterwaarts Herbruik de stop ingang als een noodstop: zet dan de gestockeerde gewenste positie gelijk aan de huidige positie Versie: zondag 2 april 2000 41

Aanpassing van de enitity en signaaldeclaratie entity stappenmotor is is port port ( go,stop,klok,reset: in in std_logic; positie: in in std_logic_vector(7 downto 0); 0); A,B,C,D,ok: out out std_logic); end end stappenmotor; architecture motor_arch of of stappenmotor is is signal T_positie,T_positie_nieuw : std_logic_vector(7 downto 0); 0); signal teller,teller_nieuw :std_logic_vector(7 downto 0); 0); begin begin T_positie_nieuw T_positie teller_nieuw teller A,B,C,D Versie: zondag 2 april 2000 42

Nieuwe combinatorisch process van de externe FSM Stop go positie Comb_T: Process (teller,t_positie,positie,stop,go) begin begin if if stop stop ='1' ='1' then then T_positie_nieuw <= <= teller; elsif elsif go='1' then then T_positie_nieuw <= <= positie; else else T_positie_nieuw <= <= T_positie; end end if; if; end end process Comb_T; T_positie_nieuw T_positie teller Let op, het is erg belangrijk om alle gevallen te voorzien in een combinatorisch blok. Indien je dit niet doet, dit is indien je de lijnen else T_positie_nieuw <= T_positie; zou weglaten, heb je geen combinatorisch blok meer maar een blok met een geheugenwerking. Als je vanuit het software standpunt redeneert, denk je: de werking is toch dezelfde... Probeer dit dan maar eens uit en je zal zien dat je een heel andere simulatie resultaat bekomt dan een aantal pagina's verder. Versie: zondag 2 april 2000 43

Nieuwe geklokt process van de externe FSM Seq_T: Process (reset,klok) begin begin if if reset='1' then then T_positie <="00000000"; elsif elsif (klok'event and and (klok='1')) then then T_positie <= <= T_positie_nieuw; end end if; if; end end process Seq_T; T_positie_nieuw T_positie Versie: zondag 2 april 2000 44

Nieuwe combinatorisch blok van de interne FSM comb_ti : process(t_positie,teller) begin begin if if (teller<t_positie) and and (teller/="11000111") then then teller_nieuw<=teller+1; elsif elsif (teller>t_positie) and and (teller/="00000000") then then teller_nieuw<=teller-1; else else teller_nieuw<=teller; end end if; if; end end process comb_ti; T_positie teller_nieuw teller Ook hier geldt hetzelfde als enkele pagina s terug. Als je de laatste else niet voorziet krijg je een totaal andere werking. Indien je deze lijn weglaat, weet je niet wat hij zal doen in de andere gevallen (else). De kans is heel groot dat hij de hele tijd de laatste bit van tellernieuw zal veranderen. Versie: zondag 2 april 2000 45

Extra output process Interne geklokt process en output functie blijven Bijkomende output functie voor OK ok_p: ok_p: Process (teller, T_positie) begin begin if if teller=t_positie then then ok ok <='1'; else else ok ok <='0'; end end if; if; end end process ok_p; ok_p; ok T_positie_nieuw T_positie teller_nieuw teller A,B,C,D Versie: zondag 2 april 2000 46

Resultaat van de simulatie Versie: zondag 2 april 2000 47

Uitlezing van een lijn CCD array met 2/3 klokken Dit is een heel gelijkaardige opgave Eerst moet er een opneem signaal komen Vervolgens komen de klokken» De 2 klokken komen volgens de sequentie A,B,A,» 3 klokken moeten volgens de sequentie A, AB,B, BC, C, Kan echter aan veel hogere frequenties werken Versie: zondag 2 april 2000 48

Combinatie beide systemen: uitlezing flatbed scanner Een stappenmotor gaat langs de verticale as snel als er geen informatie dient doorgestuurd te worden stap voor stap als er een gescande lijn dient doorgestuurd te worden P.S. Dit was een examenopgave van het academiejaar 1997-1998 Versie: zondag 2 april 2000 49

SCSI standaard voor flatbed scanners De SCSI standaard definieert ook voor scanners welk de volgorde is voor de door te geven bytes. Op basis hiervan kan een IC de scanner aansturen. Versie: zondag 2 april 2000 50

Hoofd FSM Inlezen SCSI gegevens Inleesteller=40 Motor naar startpositie OK=1 Inlezen en doorsturen CCD Motor één stap verder CCDOK=1 Gevraagd # stappen? neen ja OK=1 Motor naar beginpositie Versie: zondag 2 april 2000 51

Typedeclaratie voor de HoofdFSM architecture architecture scan_arch scan_arch of of scanner scanner is is type type hoofdfsm_t hoofdfsm_t is is (T_inleesSCSI,T_naarstart,T_doCCD,T_stapverder,T_naarbegin); signal signal T_hoofdFSM_oud,T_hoofdFSM_nieuw : hoofdfsm_t; hoofdfsm_t; -- -- nu nu verder verder in in te te vullen vullen end end scan_arch; scan_arch; Versie: zondag 2 april 2000 52

Combinatorisch process voor de volgende toestand comb_hoofdfsm comb_hoofdfsm : process(t_hoofdfsm_oud,inleesteller,ok,ccdok, verticaalstappen, verticaalteller) verticaalteller) begin begin case case T_hoofdFSM_oud T_hoofdFSM_oud is is when when T_inleesSCSI=>if T_inleesSCSI=>if inleesteller="101000" then then T_hoofdFSM_nieuw T_hoofdFSM_nieuw <=T_naarstart; <=T_naarstart; else else T_hoofdFSM_nieuw T_hoofdFSM_nieuw <=T_inleesSCSI; <=T_inleesSCSI; end end if; if; when when T_naarstart=> T_naarstart=> if if OK='1' OK='1' then then T_hoofdFSM_nieuw T_hoofdFSM_nieuw <=T_doCCD; <=T_doCCD; else else T_hoofdFSM_nieuw T_hoofdFSM_nieuw <=T_naarstart; <=T_naarstart; end end if; if; Versie: zondag 2 april 2000 53

Combinatorisch process voor de volgende toestand when when T_doCCD=> T_doCCD=> if if CCDOK='1' CCDOK='1' then then if if (verticaalstappen=verticaalteller) then then T_hoofdFSM_nieuw T_hoofdFSM_nieuw <=T_naarbegin; <=T_naarbegin; else else T_hoofdFSM_nieuw T_hoofdFSM_nieuw <=T_stapverder; <=T_stapverder; end end if; if; else else T_hoofdFSM_nieuw T_hoofdFSM_nieuw <=T_doCCD; <=T_doCCD; end end if; if; when when T_stapverder=>T_hoofdFSM_nieuw <=T_doCCD; <=T_doCCD; when when others=> others=> if if OK='1' OK='1' then then T_hoofdFSM_nieuw T_hoofdFSM_nieuw <=T_inleesSCSI; <=T_inleesSCSI; else else T_hoofdFSM_nieuw T_hoofdFSM_nieuw <=T_naarbegin; <=T_naarbegin; end end if; if; end end case; case; end end process process comb_hoofdfsm; comb_hoofdfsm; Versie: zondag 2 april 2000 54

Combinatorisch process voor de output comb_hoofdfsm_out : process(t_hoofdfsm_oud,startpositie,teller) begin begin CCDgo<='0'; CCDgo<='0'; go<='0'; go<='0'; case case T_hoofdFSM_oud T_hoofdFSM_oud is is when when T_inleesSCSI=>null; when when T_naarstart=>positie<=startpositie;go<='1'; when when T_doCCD=>CCDgo<='1'; when when T_stapverder=>positie<=teller+1;go<='1'; when when others=>positie<=(others=>'0');go<='1'; end end case; case; end end process process comb_hoofdfsm_out; Ik wil hierbij nog eens opmerken dat het belangrijk is dat multiple drivers voor signalen voorkomen worden. Deze FSM gaat bepalen welke het 'positie' signaal is dat wordt doorgegeven aan de FSM van de stappenmotor (vroeger reeds uitgewerkt) en gaat daarna ook een 'go' signaal geven. Verschillende posities worden doorgegeven op verschillende momenten, en als het niet in eenzelfde process geschreven wordt hebben we snel multiple drivers. Versie: zondag 2 april 2000 55

Inlezen (en tellen) van de SCSI-data Hiervoor gaan we de SCSI_data_ready als klok gebruiken Met deze klok verhogen we de inleesteller met 1 vergeet niet deze teller terug op nul te zetten als we in een ander hoofdblok bezig zijn. Als we aan de juiste tellerwaarde gekomen zijn slagen we de nuttige gegeven op startpositie (byte 12 en byte 13) verticaalstappen (byte 20 en byte 21) CCDstartpositie (byte 8 en byte 9) CCDstappen (byte 17 en byte 18) We kiezen voor een A4 blad en 300 dpi Dit geeft 2475 * 3510 punten 12 bit getallen zijn voldoende om posities voor te stellen Versie: zondag 2 april 2000 56

Tellen van de SCSI data bytes tellerreset<='1' when when T_hoofdFSM_oud=T_naarbegin else else '0'; '0'; SCSI_bytes_teller : process(scsi_data_ready,tellerreset) begin begin if if (tellerreset='1') then then inleesteller<=(others=>'0'); elsif elsif (SCSI_data_ready'event and and (SCSI_data_ready='1')) then then inleesteller <= <= inleesteller+1; end end if; if; end end process SCSI_bytes_teller; Versie: zondag 2 april 2000 57

Geklokt process voor de opslag van de ingelezen data opslag_scsi_bytes : process(scsi_data_ready) begin begin if if (SCSI_data_ready'event and and (SCSI_data_ready='1')) then then case case inleesteller inleesteller is is when when "001100" "001100" =>startpositie(11 downto downto 8)<=scsi_data(3 8)<=scsi_data(3 downto downto 0); 0); when when "001101" "001101" =>startpositie(7 =>startpositie(7 downto downto 0)<=scsi_data(7 0)<=scsi_data(7 downto downto 0); 0); when when "010100" "010100" =>verticaalstappen(11 downto downto 8)<=scsi_data(3 8)<=scsi_data(3 downto downto 0); 0); when when "010101" "010101" =>verticaalstappen(7 downto downto 0)<=scsi_data(7 0)<=scsi_data(7 downto downto 0); 0); when when "001000" "001000" =>CCDstartpositie(11 downto downto 8)<=scsi_data(3 8)<=scsi_data(3 downto downto 0); 0); when when "001001" "001001" =>CCDstartpositie(7 downto downto 0)<=scsi_data(7 0)<=scsi_data(7 downto downto 0); 0); when when "010001" "010001" =>CCDstappen(11 =>CCDstappen(11 downto downto 8)<=scsi_data(3 8)<=scsi_data(3 downto downto 0); 0); when when "010010" "010010" =>CCDstappen(7 =>CCDstappen(7 downto downto 0)<=scsi_data(7 0)<=scsi_data(7 downto downto 0); 0); when when others others =>null; =>null; end end case; case; end end if; if; end end process process opslag_scsi_bytes; Versie: zondag 2 april 2000 58

Uitlezen van de CCD array Hiervoor gaan we een aparte bouwblok (component) maken. Deze bouwblok kunnen we dan afzonderlijk testen Hierna gaan we deze component instantiëren in de architectuur van de scanner ARCHITECTURE ARCHITECTURE scan_arch scan_arch OF OF scanner scanner IS IS -- -- COMPONENT COMPONENT CCD CCD PORT PORT (-- (-- in in te te vullen vullen ); ); END END COMPONENT; COMPONENT; BEGIN BEGIN u1: u1: CCD CCD PORT PORT MAP MAP (-- (-- in in te te vullen vullen ); ); END END scan_arch; scan_arch; In de component declaratie moeten we de port instructie overnemen, exact zoals deze voorkomt in de entity van de vhdl file van de CCDuitlezing zoals we die gaan maken. In de component instantiering vullen we de locale signalen is, alsof we deze zouden aansluiten op de verschillende pinnen. Een component kan verschillende keren geïnstantiëerd worden, telkens met verschillende ingangssignalen. Het gebruikte oppervlak neemt dan lineair toe met het aantal geïnstantiëerde componenten. Versie: zondag 2 april 2000 59

Specificaties van de CCD aansturing Als het "CCDgo" signaal '1' wordt, wordt de gehele lijn ingeladen in de CCDs. (CCD_load wordt eventjes '1') Er zijn dan telkens 3 klokpulsen nodig om de hele lijn één pixel naar links te schuiven (het meest linkse punt wordt telkens uitgelezen) We tellen hoeveel pixels we verschuiven tot we aan de "CCDstartpositie" komen We herstarten de teller en verschuiven terug tot we "CCDstappen" aantal pixels naar buiten geschoven hebben. Hierbij zullen we dan steeds de pixels doorgeven aan de SCSI bus. Hierna geven we een CCDOK signaal Versie: zondag 2 april 2000 60

Entity van de CCD aansturing library library ieee; ieee; use use ieee.std_logic_1164.all; use use work.std_arith.all; entity entity CCD CCD is is port port ( CCDgo,CCD_klok: CCDgo,CCD_klok: in in std_logic; std_logic; CCDstartpositie,CCDstappen: in in std_logic_vector(11 downto downto 0); 0); CCD_DATA: CCD_DATA: in in std_logic_vector(7 downto downto 0); 0); CCD_A,CCD_load: CCD_A,CCD_load: out out std_logic; std_logic; CCD_B,CCD_C: CCD_B,CCD_C: buffer buffer std_logic; std_logic; CCDOK,SCSI_DATA_Available: out out std_logic; std_logic; SCSI_DATA: SCSI_DATA: inout inout std_logic_vector(7 downto downto 0)); 0)); end end CCD; CCD; We merken hierbij op dat de output signalen CCD_B en CCD_C van het type buffer zijn. Dit is omdat we ze intern zullen herbruiken. Versie: zondag 2 april 2000 61

Externe FSM CCDgo=1 Wachten op stappenmotor CCDstartpositie=teller schuiven naar startpositie Einddetectie1 Schuiven naar eindpositie CCDstappen=teller Einddetectie2 Versie: zondag 2 april 2000 62

Interne FSM De telrichting is hier steeds dezelfde, en elke klokpuls bewegen we verder tenzij we in toestand A zitten en schuiven='0' Toestand A is ook de reset-toestand. toestand B gebruiken we om de teller 1 te verhogen. 0 schuiven T_A 1 T_C T_B We hebben maar één signaal dat deze FSM controleert, namelijk het "schuiven" signaal. Er zijn drie output signalen van deze FSM, namelijk CCD_A, CCD_B en CCD_C, die elk overeenkomen met een toestand. We kiezen ervoor om in toestand B de teller de opdracht te geven te verhogen. Dan bekomen we het resultaat van deze verhoging in de tellerregisters op het moment dat we in toestand C zijn. In deze toestand kunnen we van dit tellerregister gebruik maken om, op basis van een vergelijking met een te bekomen waarde, te bepalen wat het signaal schuiven moet zijn. Dit zal dan weer op zijn beurt gaan bepalen wat we in toestand A moeten doen. Om dit te kunnen doen moeten we terug gebruik maken van het signaal CCD_B, dat normaal van het type out zou zijn. Daardoor verandert dit type in buffer. Het signaal CCD_C gaan we ook intern hergebruiken om het moment te bepalen waarop de SCSI_data signalen op de SCSI bus worden gezet. Ook dit port signaal moet dus van het type buffer worden. Oefening: voor het aansturen van een CCD camera is het meestal zo dat de klokken (A,B,C) een zekere overlap hebben. Pas het toestandsdiagram aan zodat er een overlap van de klokken voorzien is. Versie: zondag 2 april 2000 63

Declaratie interne signalen/toekenning hulpsignalen architecture architecture CCD_arch CCD_arch of of CCD CCD is is type type Extern_T Extern_T is is (T_wacht,T_naarstart,T_naareinde); type type Intern_T Intern_T is is (T_A,T_B,T_C); (T_A,T_B,T_C); signal signal T_oud,T_nieuw T_oud,T_nieuw : Extern_T; Extern_T; signal signal Ti_oud,Ti_nieuw Ti_oud,Ti_nieuw : Intern_T; Intern_T; signal signal teller,teller_nieuw:std_logic_vector(11 downto downto 0); 0); signal signal schuiven, schuiven, einddetectie1,einddetectie2:std_logic; begin begin einddetectie1<='1' when when (teller==ccdstartpositie) else else '0'; '0'; einddetectie2<='1' when when (teller==ccdstappen) else else '0'; '0'; Concurrent alternatief voor if then else in process Versie: zondag 2 april 2000 64

Combinatorisch process van de externe FSM comb_t comb_t : process(t_oud,ccdgo,einddetectie1,einddetectie2) begin begin case case T_oud T_oud is is when when T_wacht=> T_wacht=> if if (CCDgo (CCDgo ='1') ='1') then then T_nieuw T_nieuw <= <= T_naarstart; T_naarstart; else else T_nieuw T_nieuw <= <= T_wacht; T_wacht; end end if; if; when when T_naarstart=> T_naarstart=> if if (einddetectie1 (einddetectie1 ='1') ='1') then then T_nieuw T_nieuw <= <= T_naareinde; T_naareinde; else else T_nieuw T_nieuw <= <= T_naarstart; T_naarstart; end end if; if; when when others=> others=> if if (einddetectie2 (einddetectie2 ='1') ='1') then then T_nieuw T_nieuw <= <= T_wacht; T_wacht; else else T_nieuw T_nieuw <= <= T_naareinde; T_naareinde; end end if; if; end end case; case; end end process process comb_t; comb_t; Versie: zondag 2 april 2000 65

Output process (1) van de externe FSM outp_t outp_t : process(t_oud,einddetectie1,einddetectie2) begin begin case case T_oud T_oud is is when when T_wacht=> T_wacht=> schuiven<='0'; schuiven<='0'; when when T_naarstart=> T_naarstart=> if if (einddetectie1 (einddetectie1 ='1') ='1') then then schuiven schuiven <= <= '0'; '0'; else else schuiven schuiven <= <= '1'; '1'; end end if; if; when when others=> others=> if if (einddetectie2 (einddetectie2 ='1') ='1') then then schuiven schuiven <= <= '0'; '0'; else else schuiven schuiven <= <= '1'; '1'; end end if; if; end end case; case; end end process process outp_t; outp_t; We splitsen het output process van de externe FSM op in enkele delen. Het splitsen van een process mag altijd, zolang dat we eenzelfde signaal niet toekennen in meer dan één process. (Anders zouden we multipledrivers krijgen). Een opsplitsing naar uitgangssignalen ligt dan vaak voor de hand. In dit process vormen we het signaal schuiven. Schuiven heeft een dubbele functie. De teller op nul zetten als we een eindwaarde bekomen en ook op nul houden zolang we in de wachtpositie zijn. We merken op dat we niet enkel de state gebruiken om de outputfunctie te vormen, maar ook de einddetectiesignalen. Dit houdt in dat de externe FSM een Maely-FSM is. Dit heeft voordelen: anders zou schuiven een klokpuls later gevormd zijn anders zouden we een register meer moeten gebruiken. Maar dit heeft ook gevaren. We mogen Maely FSM niet rondkoppelen in een lus. De andere FSM moeten dus van het Moore type zijn. Versie: zondag 2 april 2000 66

Output process (2) van de externe FSM outp_t2 outp_t2 : process(t_oud,ccdgo) begin begin case case T_oud T_oud is is when when T_wacht=> T_wacht=> if if (CCDgo (CCDgo ='1') ='1') then then CCD_load CCD_load <= <= '1'; '1'; else else CCD_load CCD_load <= <= '0'; '0'; end end if; if; when when others=> others=> CCD_load CCD_load <= <= '0'; '0'; end end case; case; end end process process outp_t2; outp_t2; P.S. ook dit deel heeft meer inputs dan de state en maakt dus deze FSM van het Maely type. Versie: zondag 2 april 2000 67

Output process (3) van de externe FSM outp_t3 outp_t3 : process(t_oud,einddetectie2) begin begin case case T_oud T_oud is is when when T_naareinde=> T_naareinde=> if if (einddetectie2 (einddetectie2 ='1') ='1') then then CCDOK CCDOK <= <= '1'; '1'; else else CCDOK CCDOK <= <= '0'; '0'; end end if; if; when when others=> others=> CCDOK CCDOK <= <= '0'; '0'; end end case; case; end end process process outp_t3; outp_t3; P.S. ook dit deel heeft meer inputs dan de state en maakt dus deze FSM van het Maely type. Versie: zondag 2 april 2000 68

Output process (4) van de externe FSM outp_t4 outp_t4 : process(t_oud,ccd_c,ccd_data) begin begin case case T_oud T_oud is is when when T_naareinde=> T_naareinde=> if if ( CCD_C='1') CCD_C='1') then then SCSI_data SCSI_data <= <= CCD_data; CCD_data; SCSI_DATA_Available<='1'; else else SCSI_data SCSI_data <= <= (others=>'z'); (others=>'z'); SCSI_DATA_Available<='0'; end end if; if; when when others=> others=> SCSI_data SCSI_data <= <= (others=>'z'); (others=>'z'); SCSI_DATA_Available<='0'; end end case; case; end end process process outp_t4; outp_t4; We schrijven naar de SCSI_data bus op het moment dat we in toestand C zijn. Diezelfde bus wordt echter ook op andere momenten gebruikt om data van te lezen. Het is dus zeer belangrijk deze bus hoog impedant ('Z') te maken op de momenten dat er niet op geschreven wordt. P.S. ook dit deel heeft meer inputs dan de state en maakt dus deze FSM van het Maely type. Versie: zondag 2 april 2000 69

Combinatorisch process voor volgende Ti comb_ti comb_ti : process(ti_oud,schuiven) begin begin case case Ti_oud Ti_oud is is when when T_A=> T_A=> if if (schuiven (schuiven ='1') ='1') then then Ti_nieuw Ti_nieuw <= <= T_B; T_B; else else Ti_nieuw Ti_nieuw <= <= T_A; T_A; end end if; if; when when T_B=> T_B=> Ti_nieuw Ti_nieuw <= <= T_C; T_C; when when others=> others=> Ti_nieuw Ti_nieuw <= <= T_A; T_A; end end case; case; end end process process comb_ti; comb_ti; We kunnen nu het combinatorisch process opbouwen dat de nieuwe toestand afleidt op basis van de oude toestand en het signaal schuiven. Versie: zondag 2 april 2000 70

Combinatorisch process voor de volgende tellerwaarde comb_tel : process(teller,ccd_b,schuiven) begin begin if if schuiven = '0' '0' then then teller_nieuw<=(others=>'0'); elsif elsif CCD_B CCD_B = '1' '1' then then teller_nieuw<=teller+1; else else teller_nieuw<=teller; end end if; if; end end process comb_tel; Er is geen output process van de teller omdat de output van de teller de tellerwaarde zelf is. Deze FSM is dus van het Moore type. Versie: zondag 2 april 2000 71

Geklokt process voor volgende toestand We plaatsen de teller, de externe en de interne toestand in eenzelfde geklokt process Seq: Seq: Process Process (CCD_klok) begin begin if if (CCD_klok'event and and (CCD_klok='1')) then then Ti_oud Ti_oud <= <= Ti_nieuw; T_oud T_oud <= <= T_nieuw; teller teller <= <= teller_nieuw; end end if; if; end end process process Seq; Seq; Wanneer een aantal FSM op dezelfde klokflank en op dezelfde klok werken kunnen we de sequentiële processen hiervan tezamen plaatsen in hetzelfde process. Dit vermindert wel de duidelijkheid van de geschreven code, maar levert minder codelijnen. Versie: zondag 2 april 2000 72

Combinatorisch Output process Het output process wordt enkel bepaald door de state variable (Ti_oud) comb_out: Process (Ti_oud) begin begin case case Ti_oud is is when when T_A=>CCD_A<='1';CCD_B<='0';CCD_C<='0'; when when T_B=>CCD_A<='0';CCD_B<='1';CCD_C<='0'; when when T_C=>CCD_A<='0';CCD_B<='0';CCD_C<='1'; end end case; case; end end process comb_out; We zien dat dit output process enkel maar bepaald wordt door de huidige toestand. Deze FSM is dus van het Moore type. Daar er in dit ontwerp maar één FSM van het Maely type is is er geen gevaar voor het rondkoppelen van twee Maely machines. Dit is het laatste blokje dat je nodig hebt om de CCD-uitleescomponent te ontwerpen. De synthese is mogelijk naar een CPLD of een FPGA. Wanneer je deze code simuleert aan de hand van de NOVA simulator en je zou ook de interne signalen wensen te bekijken, vergeet dan niet in de report file na te kijken wat de polariteit van deze signalen is. Als een signaal toch extern niet nodig is, kies het synthese tool de meest eenvoudige oplossing, wat vaak kan bekomen worden door een aantal signalen van polariteit om te wisselen. Versie: zondag 2 april 2000 73