Dizi dedektörü üreteci: SystemVerilog'da Moore ve Mealy FSM'ler
Bir bit deseni yazın; onu yakalayan durum makinesini, Moore ya da Mealy, örtüşen ya da örtüşmeyen, canlı bir diyagram ve SystemVerilog kodu olarak alın.
- Sınır
- 6 bit
- Yayımlandı
- Yazarlık
- Taslağı yapay zekâ desteğiyle hazırlandı, İsmail tarafından gözden geçirildi
1 ile 6 bit; ilk gelen bit başta.
5 state, 10 geçiş. Moore: found, S1011 state'inde 1.
“Çalıştır” bu senaryoyu baştan oynatır; bir girişe basmak buradan devam eder.
Çalışan bir state machine (durum makinesi): state diyagramı ve dalga biçimi aynı zaman ekseninde. Girişler: rst_n, sig_in. Çıkışlar: found. clk periyodu 8 tick. Makinenin 5 state'i var: IDLE, S1, S10, S101 ve S1011; reset ile IDLE state'inde başlar; 10 geçişi var. Dalga biçimi şunları gösteriyor: clk, rst_n, sig_in, state, found.
Şekil 1. “Çalıştır” düğmesine basın: sig_in, 1011 desenini her clock periyodunda bir bit olmak üzere taşır ve yanan state onu S1011 state'ine kadar izler.
// sequence_detector_1011: generated from a state diagram on alwaysff.com.
// Detects 1011 on sig_in, overlapping: 1011011 holds it twice.
// Moore: found is high for the clock period after the last bit.
// Reset style: asynchronous, active low.
module sequence_detector_1011 (
input logic clk,
input logic rst_n,
input logic sig_in,
output logic found
);
typedef enum logic [2:0] {
IDLE = 3'd0,
S1 = 3'd1,
S10 = 3'd2,
S101 = 3'd3,
S1011 = 3'd4
} state_t;
state_t state, next;
// The state register: the only flip-flops in the module.
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= IDLE;
end else begin
state <= next;
end
end
// Next state. The default assignment holds the state when no branch fires,
// so no arm can leave a latch behind.
always_comb begin
next = state;
unique case (state)
IDLE: begin
if (sig_in) next = S1;
else if (!sig_in) next = IDLE;
end
S1: begin
if (!sig_in) next = S10;
else if (sig_in) next = S1;
end
S10: begin
if (sig_in) next = S101;
else if (!sig_in) next = IDLE;
end
S101: begin
if (sig_in) next = S1011;
else if (!sig_in) next = S10;
end
S1011: begin
if (!sig_in) next = S10;
else if (sig_in) next = S1;
end
default: next = IDLE;
endcase
end
// Moore output: a function of the state alone.
always_comb begin
found = 1'b0;
unique case (state)
S1011: found = 1'b1;
default: ;
endcase
end
endmoduleSonucu nasıl okursunuz
Her state (durum), desenin ne kadarının geldiğini gösterir. IDLE desenden henüz hiçbir şey
görmemiştir; S1, S10 ve S101 desenin ilk bir, iki ve üç bitini görmüştür. Moore makinesinin
son state'i, 1011 deseni için S1011, desenin tamamını görmüştür ve found'un 1 olduğu tek
state odur. Her state'ten iki ok çıkar, sig_in'in her değeri için bir tane; oklar, kodun sig_in
ve !sig_in testlerine karşılık 1 ya da 0 ile etiketlenir. Kodda her state'in ilk if'i,
eşleşmeyi bir adım ileri taşıyan bitin okudur; Mealy makinesinde eşleşmeyi tamamlayan okta ayrıca
/ found yazar.
Şekil iki senaryo oynatır. Yakala reset'i bırakır ve deseni bir kez, her clock periyodunda bir
bit olarak verir: makine deseni state state izler ve found'un yükseldiği yerde durur.
Örtüşme, desen kendisiyle örtüşebiliyorsa vardır. Deseni iki kez, iki eşleşme bitleri
paylaşacak biçimde içeren en kısa girişi verir, 1011 için 1011011, ve bu dedektörün deseni bir
kez mi iki kez mi bulduğunu dalga biçimi gösterir.
Kod, referans sayfalarındaki kod gibi sitenin kendi stiliyle yazılır. Her state unique case'in
bir kolu, her ok da o kolun if zincirinde bir daldır. Diyagramda bir state'in ya da okun
üzerine gelin veya klavyeyle ona ulaşın: koddaki satırları yanar. Bir satırın üzerine
geldiğinizde de diyagramdaki karşılığı yanar. Kod bloğunun çubuğundaki “Kopyala” kodu kopyalar,
“İndir” ise onu modülün adını taşıyan bir dosya olarak kaydeder.
Makine nasıl kurulur
Makinenin temeli desenin prefix fonksiyonudur (önek fonksiyonu); Knuth–Morris–Pratt aramasının
kalbindeki tablo. Desenin her öneki için, aynı zamanda desenin de öneki olan en uzun öz soneki
kaydeder ve bir uyuşmazlıkta makinenin nereye gideceğini bu belirler. 1011 dedektöründe 101'den
sonra gelen bir 0, makineyi IDLE'a döndürmez: giriş artık 10 ile biter, bu da desenin ilk iki
bitidir; makine S10'a gider. IDLE'a dönmek, başarısız bir eşleşmenin içinde başlayan her
eşleşmeyi kaçırmak olurdu.
Bir eşleşme makineyi iki yerde bırakabilir. Örtüşen dedektörde bir eşleşmeyi bitiren bitler
bir sonrakini başlatabilir: 1011'den sonra son 1 desenin ilk biti olduğundan makine S1'deymiş
gibi devam eder. Örtüşmeyen dedektörde eşleşme bitlerini harcar ve makine IDLE'dan yeniden
başlar. 1000 gibi, aynı zamanda öneki olan bir öz soneki bulunmayan bir desen kendisiyle
örtüşemez; o zaman iki seçim aynı makineyi kurar ve kontrollerin altındaki satır bunu söyler.
Moore ve Mealy, kodun biçimleri
Moore makinesi eşleşmeyi kendine ait bir state'te bildirir: n bit için n + 1 state vardır
ve found, son biti alan kenardan sonraki clock periyodu boyunca 1'dir. Mealy makinesi
eşleşmeyi onu tamamlayan okta bildirir: n state vardır ve found, son bit sig_in üzerindeyken,
kenardan önce 1 olur; çünkü state'e olduğu kadar girişe de bağlıdır.
Process sayısı kodun nasıl bölündüğünü seçer. Üç process'te state register'ı, sonraki state
mantığı ve çıkış mantığı üç ayrı bloktadır. İki process'te sonraki state ve çıkışlar tek bir
always_comb içindedir. Tek process'te her şey always_ff içindedir ve çıkışlar, state ile aynı
kenarda değişen register'lara dönüşür. Moore çıkışı zaten o kenarda değişir; Mealy çıkışı ise
girişe kenardan önce cevap verir ve register olunca bir clock periyodu geç cevap verirdi. Bu yüzden
tek process yalnızca Moore makineleri için sunulur.
Kodlama, typedef enum'ın tanımladığı kodları ve dalga biçimindeki state satırını belirler:
binary state'leri sırayla sayar, Gray komşu kodlar arasında tek bir bit değiştirir, one-hot ise
her state'e kendine ait bir bit verir.
Sınırlar
Desenler 1 ile 6 bit arasıdır. Makinenin tek bir girişi, sig_in, ve tek bir çıkışı, found,
vardır; adlar referans sayfasındakilerle aynıdır. Reset asenkron ve active-low'dur, rst_n; kod
bunu başlığında söyler. İkisi dışında her diyagram otomatik olarak yerleştirilir ve 4 bite kadar
her biri 360 px'lik bir telefona sığar; daha genişleri kendi çerçevesinin içinde kayar. O iki
makine, örtüşmeyen Mealy 00 ve 11, bir state çifti arasında otomatik yerleşimin çizemediği üç
ok taşır ve elle yerleştirilmiştir. Bir dedektörün ilk reset'inden önce, register bilinen bir değer
tutmazken ne yaptığı, makinesi bu üretecin varsayılanı olan 1011 referans
sayfasının konusudur.