Sommario:

Sequencer digitale in 4 fasi: 19 fasi (con immagini)
Sequencer digitale in 4 fasi: 19 fasi (con immagini)

Video: Sequencer digitale in 4 fasi: 19 fasi (con immagini)

Video: Sequencer digitale in 4 fasi: 19 fasi (con immagini)
Video: le istituzioni dormono parte 2 2024, Luglio
Anonim
Sequencer digitale a 4 fasi
Sequencer digitale a 4 fasi
Sequencer digitale a 4 fasi
Sequencer digitale a 4 fasi

CPE 133, Cal Poly San Luis Obispo

Creatori del progetto: Jayson Johnston e Bjorn Nelson

Nell'industria musicale di oggi, uno degli "strumenti" più comunemente usati è il sintetizzatore digitale. Ogni genere di musica, dall'hip-hop al pop e persino al country, utilizza un sintetizzatore digitale in studio per creare i ritmi e i suoni di cui hanno bisogno per dare vita alla loro musica. In questo tutorial, creeremo un sintetizzatore molto semplice con la scheda FPGA Basys 3.

Il sintetizzatore sarà in grado di suonare quattro semiminime selezionati a un numero costante di battiti al minuto. Gli utenti utilizzeranno gli interruttori per assegnare ogni semiminima a un'altezza musicale. Per questo progetto utilizziamo un convertitore digitale-analogico (DAC) a 4 bit per prendere l'uscita dalla scheda e convertirla in un segnale analogico. L'uscita dal DAC verrà quindi inviata a un altoparlante standard del computer, creando la nostra musica. Sono possibili sedici discrete piazzole. Limiteremo il nostro sintetizzatore a una singola ottava di 12 note, che cadono tra il Do centrale (261,6 Hz) e il Si4 (493,9 Hz). L'utente avrà anche la possibilità di assegnare più note contemporaneamente, nonché di assegnare una pausa premendo Assegna senza che nessuno degli interruttori del tono sia spostato verso l'alto. Quando ogni nota viene selezionata e suonata, la nota della lettera viene mostrata sul display a 7 segmenti. Utilizzeremo anche tre dei pulsanti sulla scheda, uno per riprodurre e mettere in pausa la musica, uno per reimpostare il sintetizzatore e metterlo in modalità "selezione", e il terzo per assegnare a ciascuna nota un'altezza mentre è in modalità selezione.

Una volta che l'utente è soddisfatto della scelta delle note e dopo aver premuto il pulsante di riproduzione, il sintetizzatore suonerà ripetutamente ciascuna nota in successione finché l'utente non premerà pausa o selezione.

Ecco un elenco delle attrezzature necessarie:

  • Vivado (o qualsiasi spazio di lavoro VHDL)
  • Basys 3 o scheda FPGA simile
  • Convertitore digitale-analogico (min. 4-bit)
  • Altoparlante con jack per cuffie
  • Cavi di filo

Passaggio 1: operazione da parte dell'utente del sequenziatore digitale

Funzionamento dell'utente del sequenziatore digitale
Funzionamento dell'utente del sequenziatore digitale

I passaggi seguenti servono per azionare il sequenziatore digitale. Il sequencer digitale supporta la riproduzione di 12 tonalità distinte (C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B), che vanno da 261,6 Hz a 493,9 Hz.

1. Premere il pulsante sinistro per mettere la scheda in modalità di selezione. In questa modalità, i 4 interruttori più a sinistra (interruttori da 13 a 16) verranno utilizzati ciascuno per memorizzare un valore di altezza distinto.

2. Per effettuare una selezione, attivare uno degli interruttori di sinistra, quindi utilizzare i 4 interruttori più a destra (interruttori da 1 a 4) per scegliere il tono desiderato. Il tono associato a una specifica combinazione di interruttori di destra verrà mostrato sul display a sette segmenti e il display si aggiornerà al nuovo tono associato ogni volta che gli interruttori di destra vengono spostati su una nuova combinazione. È possibile assegnare una pausa non assegnando mai un'altezza a uno degli interruttori di sinistra o assegnando alla nota un'altezza indicata come 0 sul display. Una volta trovata la tonalità desiderata e visualizzata sul display, premere il pulsante di assegnazione in basso per assegnare quella specifica tonalità alla nota.

3. Ripetere il passaggio 2 per le tre note rimanenti, attivando singolarmente ciascuno degli interruttori di sinistra rimanenti, scegliendo la rispettiva altezza con gli interruttori di destra e premendo il pulsante in basso per assegnare l'altezza alla nota. Più note possono essere assegnate alla stessa altezza spostando più di uno degli interruttori di sinistra verso l'alto contemporaneamente.

4. Ora che tutte le note sono state assegnate, il sequencer digitale è pronto per suonare. Per riprodurre le note sull'altoparlante, premi semplicemente il pulsante di riproduzione/pausa destro per iniziare a riprodurre la musica. L'ordine della sequenza di riproduzione rispecchia le altezze associate agli interruttori di sinistra, da sinistra a destra. Le note verranno suonate a un determinato numero di battiti al minuto, nell'ordine 1, 2, 3, 4, 1, 2…. Il display mostrerà la nota attualmente in riproduzione mentre gli altoparlanti riproducono la musica. Per mettere in pausa la riproduzione della musica, è sufficiente premere il pulsante destro, quindi la riproduzione della musica si interromperà e sul display verrà visualizzato un simbolo di pausa. Premendo nuovamente il pulsante destro si riprenderà la riproduzione.

Passaggio 2: dettagli tecnici

Dettagli tecnici
Dettagli tecnici

Il nostro sintetizzatore fa uso di molti diversi componenti digitali. Sono incluse macchine a stati finiti, registri, multiplexer, divisori di clock e altro ancora. Per costruire il nostro sintetizzatore, abbiamo utilizzato 10 file modulari unici. Piuttosto che rendere ogni modulo un componente, abbiamo suddiviso i file modulari per funzione. La maggior parte dei moduli, di conseguenza, sono più di un componente. Nota che l'immagine sopra mostra ogni blocco legato insieme nel nostro design di punta.

Discuteremo ogni modulo descrivendo gli input e gli output, scomponendo i suoi componenti e spiegando il suo scopo nella progettazione generale. Un file ZIP è incluso nella parte inferiore dell'istruzione, che contiene ogni file di codice VHDL utilizzato nel progetto.

Ingressi

  • Clk (segnale di clock nativo)
  • PP (riproduzione/pausa)
  • Sel (metti il sintetizzatore in modalità di selezione)
  • Assegna (assegna uno step a un pitch)
  • Step (le note posizionali)
  • Freq (gli interruttori che creano il pitch desiderato)

Uscite

  • Anodo (anodi a 7 segmenti)
  • Catodo (catodi a 7 segmenti)
  • DAC (4 bit che pilotano il DAC)

Passaggio 3: dettagli tecnici

Dettagli tecnici
Dettagli tecnici

Passaggio 4: divisore dell'orologio a 7 segmenti

Divisore orologio a 7 segmenti
Divisore orologio a 7 segmenti

Il nostro sintetizzatore fa uso di tre divisori di clock, tutti producono segnali che hanno uno scopo diverso nel nostro progetto. Un divisore di clock prende un segnale di clock nativo e produce un segnale alterato che ha una frequenza inferiore al segnale di clock originale. Il clock nativo del Basys 3 è 100 MHz. Questa è la frequenza utilizzata dai nostri divisori di clock. Se si utilizza una scheda FPGA diversa con una frequenza di clock nativa diversa, potrebbe essere necessario modificare il codice.

Il divisore di clock a 7 segmenti produce un segnale che guida il file seg_display. Spiegheremo come funziona questo file in modo più dettagliato quando arriveremo alla sua sezione. In sostanza, questo divisore di clock produce un segnale a 240 Hz che verrà utilizzato per passare da anodi a catodi sul display. Il segnale è 240 Hz perché la frequenza alla quale l'occhio umano non può riconoscere l'assenza di luce è 60 Hz. Stiamo usando due cifre, quindi raddoppiando questa frequenza, ogni cifra oscillerà a 60 Hz. Quindi lo raddoppiamo per ottenere 240 Hz perché il sistema cambia solo quando il segnale diventa alto, non quando diventa basso.

Per ottenere ciò, il divisore prende il segnale nativo a 100 MHz e conta su ogni fronte di salita. Quando il contatore raggiunge 416667, l'uscita passerà da basso ad alto, o viceversa.

Ingressi

Clk (segnale di clock nativo)

Uscite

Clk_7seg (a seg_display)

Componenti

  • D registro
  • MUX
  • Invertitore
  • sommatore

Passaggio 5: Divisore dell'orologio dei battiti al minuto

Divisore dell'orologio battiti al minuto
Divisore dell'orologio battiti al minuto

Il divisore di clock BPM funziona in modo simile. Questo divisore produce la frequenza di clock che guida la commutazione tra i quattro passaggi durante l'emissione dei toni nello stato di riproduzione. Abbiamo deciso di passare da una nota all'altra a 100 BPM. A 100 BPM, ogni nota verrà suonata per 3/5 di secondo. Il segnale risultante avrebbe una frequenza di 1,67 Hz.

Per produrre un segnale di questa frequenza, abbiamo usato di nuovo un sistema di conteggio, ma questa volta il conteggio è stato di 60 milioni. Ogni volta che il contatore raggiungeva i 60 milioni, il segnale di uscita passava alto o basso.

Ingressi

Clk (frequenza di clock nativa)

Uscite

Clk_BPM (a output_FSM)

Componenti

  • D registro
  • MUX
  • Invertitore
  • sommatore

Passaggio 6: Divisore dell'orologio delle piazzole

Divisore dell'orologio delle piazzole
Divisore dell'orologio delle piazzole

Il Pitch Clock Divider è il più grande dei nostri divisori per orologi. Questo divisore emette 12 diversi segnali corrispondenti alle 12 diverse note che il nostro sintetizzatore può suonare. Usando le conoscenze di base della teoria musicale, abbiamo dedotto che un bit o un bus potrebbe oscillare a una velocità che corrisponde alla frequenza delle note musicali. Per vedere le frequenze che abbiamo usato, guarda qui. Abbiamo usato la quarta ottava di altezze.

Lo stesso sistema di conteggio viene utilizzato qui. Per i valori specifici a cui abbiamo contato, vedere il file etichettato Clk_div_pitches.

Ingressi

Clk (frequenza di clock nativa)

Uscite

C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B (per selezionare output)

Componenti

  • D registro
  • MUX
  • Invertitore
  • sommatore

Passaggio 7: Riproduci/Pausa/Seleziona macchina a stati

Riproduci/Pausa/Seleziona macchina a stati
Riproduci/Pausa/Seleziona macchina a stati

Nel nostro progetto ci sono due macchine a stati finiti (FSM). Un FSM è un dispositivo logico che può esistere in un solo stato su un numero finito di stati. Utilizzando un FSM, un circuito digitale può passare a un nuovo stato basato su una combinazione di ingressi. Utilizzando la logica di ingresso, lo stato di un FSM cambierà quando c'è un fronte di salita del clock. Dallo stato e dagli ingressi nel circuito, è possibile creare una logica di uscita che fornisce uscite che esistono solo se l'FSM si trova in un determinato stato.

La macchina a stati PPS è il primo FSM nel nostro circuito. Ci sono tre stati in questo FSM; Modalità di riproduzione, pausa e selezione. Per spostarci tra i diversi stati, abbiamo utilizzato i pulsanti PP e Selezione. Vedere il diagramma di stato sopra per vedere come si verificano le transizioni tra gli stati. Abbiamo effettuato questa transizione FSM sul fronte di salita del clock nativo a 100 MHz, in modo che fosse impossibile per la macchina non effettuare la transizione quando è stato premuto uno dei pulsanti, anche per un periodo di tempo molto breve. Lo stato attuale (P_state) è l'unico output di questo modulo.

Ingressi

  • Clk (frequenza di clock nativa)
  • Sel (tasto sinistro)
  • PP (tasto destro)

Uscite

P_state (stato attuale, a output_FSM, note_assign, seg_dsiplay, final_select)

Componenti

  • MUX
  • D registro

Passaggio 8: Riproduci/Pausa/Seleziona macchina a stati

Riproduci/Pausa/Seleziona macchina a stati
Riproduci/Pausa/Seleziona macchina a stati

Passaggio 9: uscita FSM

Uscita FSM
Uscita FSM

Questo è il secondo FSM a cui si fa riferimento nella sezione precedente. Questo FSM ha una funzione diversa dall'altro, ma la base per questo è essenzialmente la stessa.

L'uscita FSM funziona solo se lo stato attuale del primo FSM è "01" (lo stato di riproduzione). Essenzialmente, questa è l'abilitazione per il modulo. Se lo stato è "01", l'FSM passerà da uno stato all'altro sul fronte di salita del segnale di clock BPM. Lo facciamo perché output_FSM controlla quale numero binario per il passo selezionato viene inviato ai moduli output_select e seg_display. L'FSM ha un ingresso a 16 bit proveniente dal modulo di assegnazione delle note, che sarà trattato in seguito. Nello stato "00" per output_FSM, il modulo emetterà "xxxx" per la prima nota assegnata. Quindi in "01", emetterà "aaaa" per la seconda nota e così via per ogni nota prima di tornare alla prima nota. Vedere il diagramma di stato sopra.

Questo FSM differisce dal primo perché non esiste una logica di ingresso per controllare la commutazione tra gli stati. Invece, l'FSM funzionerà solo quando lo stato del primo FSM è "01", e quindi questo FSM passerà da uno stato all'altro solo sul fronte di salita del segnale di clock. Un'altra differenza è che questo modulo ha una logica di uscita, il che significa che non emette lo stato attuale, ma emette il numero binario per il passo in quello stato.

Ingressi

  • Clk_BPM (segnale di clock BPM dal divisore di clock)
  • FSM1_state (PS da PPS FSM)
  • Pitch_in (pitch da note_assign)

Uscite

Pitch_out (un passo alla volta, a output_select e seg_display)

Componenti

  • MUX
  • D registro

Passaggio 10: uscita FSM

Uscita FSM
Uscita FSM

Passaggio 11: Assegna nota

Assegna nota
Assegna nota

Il modulo di assegnazione delle note è responsabile dell'effettiva assegnazione di un'altezza alla nota posizionale, o passo. Questo modulo è in realtà abbastanza semplice. Prima controlla se il circuito è nello stato di "selezione" e se un interruttore a gradino (all'estrema sinistra) è alto. Se questo è vero e viene premuto il pulsante di assegnazione, l'uscita del modulo sarà uguale al numero binario rappresentato dagli interruttori di frequenza (estrema destra).

In origine, avevamo tentato di creare un modulo che salvasse effettivamente uno dei segnali di clock del pitch sull'uscita, ma abbiamo riscontrato problemi con l'uscita che cambiava per seguire i segnali di clock in ingresso. Questo è l'unico modulo utilizzato più di una volta nel progetto finale. Ad ogni passo è associato un modulo note_assign e, per questo motivo, ogni istanza del modulo ottiene un bit del bus Step.

Ingressi

  • P_state (stato attuale da PPS FSM)
  • Sel (tasto sinistro)
  • Interruttore (interruttore a un passo)
  • Freq (interruttori all'estrema destra per il pitch)
  • Assegna (pulsante in basso, assegna una nota)

Uscite

Passo (numero binario, a output_FSM)

Componenti

  • MUX
  • D registrarsi

Passaggio 12: selezione dell'uscita

Selezione uscita
Selezione uscita

La selezione dell'uscita è responsabile di prendere il numero binario per un passo e collegarlo al rispettivo segnale di clock. Nonostante le sue dimensioni, questo è anche un modulo relativamente semplice. Output_select è essenzialmente un decodificatore binario, che decodifica il numero binario per un passo in un segnale di clock specifico. In realtà l'assegnazione dell'uscita a una frequenza di clock ha funzionato meglio qui rispetto al modulo note_assign, perché tutto ciò che questo modulo doveva fare era MUX i segnali di clock con il numero binario che rappresenta l'ingresso di controllo.

Ci scusiamo per lo strano instradamento, Vivado ha organizzato i segnali di altezza in ordine alfabetico per il file clk_div_pitches, ma per questo file li ha organizzati per numero binario crescente, facendo sì che le altezze siano in un ordine diverso. Si noti inoltre che se il numero binario dell'output_FSM era "0000" o qualcosa di maggiore di "1100", il MUX ha inviato un segnale '0' piatto.

Ingresso

  • Passo (da output_FSM);
  • C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B (segnali di clock)

Produzione

Tono (un singolo bit che corrisponde al segnale di clock selezionato, a square_wave)

Componenti

MUX

Passaggio 13: generazione dell'onda quadra

Onda Quadra Gen
Onda Quadra Gen

Il modulo square_wave è il generatore dell'onda quadra emessa dalla scheda al DAC. Usando il segnale di tono del file precedente, questa square_wave inverte il numero di 4 bit tra "0000" e "1111" sul fronte di salita di Tone. Il tono è una frequenza di intonazione specifica, quindi square_wave produce un'onda con una frequenza diversa quando output_FSM passa a un altro stato. L'uscita a 4 bit di questo modulo va al modulo fin_sel, dove la logica determina se questo bus verrà emesso in base allo stato da PPS FSM.

Un'alternativa a questo generatore di onde quadre è la produzione di un'onda sinusoidale. Sebbene questo produrrebbe molto probabilmente un tono finale migliore, è considerevolmente più difficile da implementare, quindi abbiamo optato per generare solo un'onda quadra.

Ingressi

Tono (bit oscillante da output_select)

Uscite

DAC_input (bus oscillante a 4 bit che cambia alla stessa frequenza del tono)

Componenti

  • Invertitore
  • D registro

Passaggio 14: display a 7 segmenti

Display a 7 segmenti
Display a 7 segmenti

Il modulo seg_display controlla il display a 7 segmenti sulla nostra basys board. All'interno del modulo si verificano due processi. Il primo processo decodifica Freq quando è nello stato di "selezione" o Pitch quando è in modalità "play". In modalità "pausa", il modulo decodifica per mostrare il simbolo di pausa. Guardando il codice VHDL, puoi vedere che il decodificatore binario decodifica effettivamente l'ingresso in due diversi segnali, catodo1 e catodo2. Catodo1 rappresenta la lettera corrispondente al passo da visualizzare, catodo2 rappresenta il simbolo piatto (b) se presente. La ragione di ciò si riferisce al secondo processo svolto dal modulo seg_display.

Su una scheda basys3, il display a segmenti ha catodi comuni. Mentre gli anodi controllano quale cifra è accesa, i catodi controllano quali segmenti sono accesi. Poiché il display ha catodi comuni, ciò significa che puoi visualizzare solo un set di segmenti alla volta. Ciò pone un problema per questo progetto perché vogliamo visualizzare una lettera alla prima cifra e il simbolo piatto, se necessario, allo stesso tempo. Ora ricordi il segnale dell'orologio a 7seg? Per aggirare questo problema, cambiamo gli anodi e i catodi avanti e indietro sul segnale di clock a 7seg. Poiché il segnale di clock è 240 Hz e stiamo usando due cifre, ogni cifra oscillerà a 60 Hz. All'occhio umano, sembrerà che le cifre non oscillino affatto.

Si noti inoltre che il display della scheda basys3 utilizza la logica negativa. Ciò significa che se un anodo o un catodo è impostato su '0', quella cifra o segmento sarà attivo e viceversa.

Ingressi

  • Pitch (numero binario per una nota, utilizzato in stato di riproduzione)
  • Freq (interruttori di frequenza, utilizzati quando in stato di selezione)
  • P_state (stato attuale da PPS FSM)
  • Clk_240Hz (segnale di clock da Clk_div_7seg, doppio 120 perché stiamo usando solo il fronte di salita)

Uscite

  • Catodo (bus che controlla i segmenti sul display, uscita finale)
  • Anodo (bus che comanda cifre sul display, uscita finale)

Componenti

  • fermo
  • MUX
  • D registro

Passaggio 15: selezione finale

Selezione finale
Selezione finale

La selezione finale è l'ultimo modulo utilizzato in questo progetto. Un altro modulo semplice, questo modulo controlla l'uscita finale che andrà al DAC. Quando si trova nello stato di "selezione" o "pausa", il modulo emetterà un "0000" statico in modo che non venga riprodotta musica dagli altoparlanti. Nello stato "play", il modulo emetterà i 4-bit oscillanti come determinato da square_wave.

Ingressi

  • P_state (stato attuale da PPS FSM)
  • DAC_input (i 4-bit oscillanti da square_wave)

Uscite

DAC (uguale a DAC_input in stato di riproduzione, output finale)

Componenti

MUX

Passaggio 16: dispositivi esterni: DAC

Dispositivi esterni: DAC
Dispositivi esterni: DAC

Un convertitore digitale-analogico (DAC) prende un segnale discreto e lo converte in un segnale continuo. Il nostro DAC ha quattro bit ed è costituito da un amplificatore sommatore. Utilizzando un rapporto di resistori nel circuito di alimentazione e feedback, siamo stati in grado di creare un sistema che emette a 16 livelli diversi creando la "somma" di ciascun ramo. Bit0, il ramo superiore, porta il minor peso e contribuisce con il minimo potenziale quando è alto a causa della maggiore resistenza dei rami. Il peso aumenta man mano che scendi dai rami. Se dovessi contare in binario verso l'alto e poi verso il basso usando gli ingressi bit, le tensioni di uscita sembrerebbero un'onda sinusoidale graduale. L'ingresso al DAC è stato collegato a quello dei PMOD sulla scheda per trasferire il segnale a 4 bit.

Il DAC è stato originariamente assemblato per un corso di ingegneria elettrica ed è stato progettato e saldato da noi, non acquistato da un negozio. Sopra c'è un'immagine del file di progettazione per la creazione del circuito stampato.

Passaggio 17: Dispositivi esterni: Altoparlante

Dispositivi esterni: Altoparlante
Dispositivi esterni: Altoparlante

Per questo progetto, non vorrai acquistare un paio di altoparlanti super carini. Come puoi vedere, il suono è piuttosto semplice. Siamo andati a comprare un set di altoparlanti per computer da $ 8 da Best Buy. Qualsiasi cosa con un jack per le cuffie funziona bene. Anche il monotono funziona bene. Puoi anche usare le cuffie, ma potresti farle esplodere!

Per collegare l'uscita del DAC agli altoparlanti, abbiamo usato cavi jumper e poi abbiamo tenuto il cavo di uscita sulla punta del jack delle cuffie e il cavo per la messa a terra alla base. Abbiamo provato a usare del nastro isolante per tenere i cavi in posizione, ma ha causato molte interferenze. Provare uno stile diverso di nastro potrebbe risolvere questo problema.

Per i nostri altoparlanti, li abbiamo impostati al massimo e abbiamo ottenuto un rumore decentemente alto.

E questo è l'ultimo passo per creare un sequencer digitale da una scheda FPGA! Vai alle due sezioni successive per scaricare tutto il nostro codice VHDL e vedere il sequencer in azione.

Passaggio 18: dimostrazione video

Questo video mostra la versione finale del progetto di lavoro, incluso il processo di assegnazione degli interruttori a 4 altezze distinte e gli altoparlanti che suonano le rispettive note.

Passaggio 19: codice VHDL

Ecco il codice per l'intero progetto, inclusi i file di vincolo e sim utilizzati durante la creazione del sequencer. Nota che i file di progettazione non utilizzati lo dicono nell'architettura.

Consigliato: