FSM Nedir
Bir finite state machine şunları yapan bir kontrolördür:
- Herhangi bir anda sabit bir adlandırılmış durum setinden birini tutar.
- Girişlere (ve muhtemelen mevcut duruma) göre durumlar arasında geçiş yapar.
- Mevcut duruma (ve belki mevcut girişlere) bağlı çıktılar üretir.
Bu dijital tasarımın şaşırtıcı bir kısmını kapsar: traffic-light kontrolörleri, UART verici, memory kontrolörleri, ağ protokolü işleyicileri, instruction decoder'lar, ayrık çalışma modları olan her şey.
FSM'leri datapath mantığından farklı hissettiren şey, değerler değil durumlar olmalarıdır. Bir counter 1, 2, 3, 4 arasında geçer. Bir FSM IDLE, FETCHING, BUSY, DONE arasında geçer - aynı şekil, ama durumların adları var ve geçişlerin anlamı var.
İki Süreçli Kalıp
Standart Verilog FSM iki always bloğu kullanır:
- Bir saatli blok, her saat kenarında state register'ını yakalar. Non-blocking atama kullanır. Küçük - genellikle üç satır.
- Bir kombinasyonel blok, sonraki durumu ve çıktıları hesaplamak için mevcut duruma
casekullanır. Blocking atama kullanır. "İlginç" kod burada yaşar.
Bu ayrımın üç faydası vardır: durumu açıkça düşünmeni zorlar, "bir register artı bir kombinasyonel blok"a temiz eşlenen donanım üretir ve standarttır - Verilog'unu okuyan herkes onu anında tanır.
Çalışılmış Bir Örnek: Sequence Detector
Klasik bir öğretim FSM'i: bir seri girişte 1011 bit dizisini algıla. Dizi tamamlandığında tek döngülük bir pulse çıkar.
İki bloklu yapı yukarıdaki madde işaretidir. Temizleme detayları belirtmeye değer:
- Kombinasyonel bloğun başında varsayılanlar.
next_state = state(olduğun yerde kal) vedetected = 1'b0(pulse yok) "hiçbir şey yapma" atamalarıdır. Hercasedalı sonra yalnızca farklı olan şeyleri ayarlar. Bu, bir latch çıkarmayı imkansız hale getirir. - State adları için
localparam. Modülü okuyan herkes3'd0,3'd1değil,S0,S1,S2,S3şeklinde düşünür. Sentezleyici ikameyi yapar. - Saatli blokta çıktı yok. Tüm "bu state ne yapar" mantığı kombinasyonel blokta yaşar. Saatli blok yalnızca mevcut durumu tutmaktan başka hiçbir şeyden sorumlu değildir.
Moore vs Mealy
Moore: çıktı yalnızca mevcut duruma bağlıdır. Mealy: çıktı mevcut duruma ve mevcut girişlere bağlıdır.
Yukarıdaki örnekte, detected yalnızca in beklenen dizi tamamlama kalıplarından biriyle eşleştiğinde S3 dalı içinde ayarlanır. Bu bir Mealy çıkışıdır - state'e ek olarak in'e bağlıdır. Bir Moore sürümü "yeni algılandı" için ayrı bir state'e sahip olur ve o state mevcut olduğunda detected = 1 ayarlar; çıktı bir döngü sonra pulse verir ama asla in'deki bir glitch'e duyarlı olmaz.
İki stil de geçerlidir. Moore ders kitaplarında varsayılandır çünkü çıktılar girişler döngü ortasında değiştiğinde glitch yapmama garantilidir. Mealy daha hızlıdır (giriş güdümlü çıktılar için register gecikmesi yok) ve birçok durumda daha küçük donanım üretir. Uyguladığın protokole göre seç.
State Encoding: Binary, One-Hot, Gray
Her state'e atadığın bit kalıbı alan ve hız için önemlidir:
- Binary (
S0 = 3'd0,S1 = 3'd1, ...): en küçük state register - state için bit. Maksimum decode mantığı. - One-hot (
S0 = 4'b0001,S1 = 4'b0010, ...): N state için N bit. Decode mantığı önemsizdir (her state bir wire'dır); geçişler hızlıdır. FPGA'lar genellikle bunu varsayılan olarak kullanır. - Gray code: ardışık state'ler tek bir bit farkla. State bitleri saat domain'lerini geçtiğinde kullanışlıdır.
Çoğu modern sentez aracı encoding'i senin için seçer (Vivado, Quartus, Design Compiler'ın hepsinde her birini deneyen ve en iyisini seçen otomatik bir mod vardır). Nadiren belirtmen gerekir. Belirtmen gerektiğinde: çoğu araç bir attribute ek açıklamasını veya (* fsm_encoding = "one_hot" *) pragma'sını kabul eder.
Üç Bloklu Bir Varyant
Bazen FSM'in üç şekilde bölündüğünü göreceksin: state için bir saatli blok, next-state için bir kombinasyonel blok, çıktılar için bir kombinasyonel blok. Bu sadece çıktı hesaplamasının kendi bloğuna kaldırıldığı iki bloklu kalıptır:
// State register
always @(posedge clk) ...
// Next-state mantığı
always @(*) ...
// Çıktı mantığı
always @(*) begin
case (state)
...
endcase
end
Bölünmüş çıktı stili, çıktılar büyük olduğunda ve next-state mantığı aynı blokta olsalardı dağınık olurdu durumlarda yararlıdır. Küçük FSM'ler için fazladan iş.
Bir FSM'de default Ne Yapar
Her FSM'in case ifadesinin bir default dalı olmalıdır. İki neden:
- Güvenlik: state register bir şekilde geçersiz bir değer alırsa (bozulma, hata, kısmi reset),
defaultonu bilinen bir duruma geri getirir. - Sentez ipucu: açık case'ler kapsamlı olduğunda (örneğin 4 değeri de işlenen 2 bitlik bir state),
default: next_state = 'x;sentezleyiciye "varsayılanın ulaşılmaz olduğuna söz veriyorum, serbest optimize et" der. Ulaşılamaz path gerçekten simülasyonda vurulursa, ortaya çıkanxyayılır ve hatayı anında ortaya çıkarır.
default: begin
next_state = S0; // güvenli kurtarma
// veya
next_state = 'x; // ulaşılmaz, serbest optimize et
end
Varsayılanın gerçekten ulaşılmaz olduğunu kanıtlayıp kanıtlamadığına göre seç.
Dikkat Edilmesi Gerekenler
Kombinasyonel bloğun başında varsayılanları unutmak. next_state = state ve çıktı varsayılanları olmadan, her şeyi atamayan bir dal bir latch sızdırır.
Çıktıları saatli bloğa koymak. detected <= 1 always @(posedge clk) bloğunda yaşıyorsa, çıktı register'lanır - bir döngü geç görünür. Bu kasıtlı olabilir ("registered Mealy" çıkışı) ama spec anında bir pulse istediğinde yaygın bir kazara tasarım hatasıdır.
Blocking ve non-blocking karıştırmak. Saatli blok: <=. Kombinasyonel blok: =. İkisini bir blokta karıştırmak bir race condition'dır.
next_state'e referans veren ve state atayan bir kombinasyonel always bloğu. Bu, simülatörün çözemediği bir geri besleme döngüsü kurar. Saatli blok state'e sahiptir; kombinasyonel blok next_state'e sahiptir; asla birinin diğerinin değişkenine dokunmasına izin verme.
Sırada Ne Var
Artık tanımlayabileceğin herhangi bir kontrolörü kurabilirsin. Bir sonraki bölüm sentezlenebilir tasarımdan bir adım geri çıkar ve onu çalıştıran testbench'leri kapsar - stimulus nasıl sürülür, çıktılar nasıl gözlemlenir, waveform'lar nasıl dump edilir ve modüllerinin gerçekten düşündüğün şeyi yaptığını nasıl doğrularsın.
Sıkça Sorulan Sorular
Verilog'da finite state machine nedir?
FSM, küçük bir adlandırılmış durum setinden birini tutan ve girişlere göre aralarında geçiş yapan bir kontrolördür. Verilog'da, standart uygulama iki bloğa sahiptir: her saat kenarında state register'ını güncelleyen saatli bir always ve mevcut durum ile girişlere göre sonraki durumu ve çıktıları hesaplayan kombinasyonel bir always.
Verilog'da standart FSM kalıbı nedir?
İki süreçli FSM: bir saatli always @(posedge clk) bloğu state register'ını tutar ve non-blocking atama kullanır, bir kombinasyonel always @(*) bloğu sonraki durumu ve çıktıları hesaplamak için mevcut duruma case kullanır. Bu ayrım kodu okumayı, lint'lemeyi ve temiz sentezlemeyi kolaylaştırır.
Bir Mealy ile Moore FSM arasındaki fark nedir?
Bir Moore FSM'de, çıktılar yalnızca mevcut duruma bağlıdır. Bir Mealy FSM'de, çıktılar hem mevcut duruma hem de mevcut girişlere bağlıdır. Mealy makineleri bir döngü daha hızlı tepki verir (giriş bağımlı çıktılar için register gecikmesi yok) ama girişler döngü ortasında değişirse glitch üretebilir. Moore makineleri bir döngü daha yavaştır ama daha öngörülebilir - hız gerekmedikçe varsayılan seçimdir.
Verilog'da state'ler nasıl encode edilir?
Modülün içinde localparam sabitleri kullan: localparam IDLE = 3'd0; vb. Üç yaygın encoding: binary (state'ler 0, 1, 2, ... - en küçük state register), one-hot (state başına bir bit, geçiş başına daha az mantık seviyesi) ve gray code (ardışık state'ler tek bir bit farkla - glitch'leri en aza indirir). Sentez araçları genellikle encoding'i senin için seçer; sabitlemek nadiren gereklidir.