1011 dizi dedektörü

Seri bir bit akışında 1011'i örtüşmeleriyle birlikte bulan bir Moore state machine'i. Beş state, on ok ve eşleşmeyi bildiren tek state.

Seviye
rtl
Kod
sequence-detector-1011
Kontrol edildi
Verilator 5.052, Icarus Verilog 13.0, Yosys 0.66
Yayımlandı
Yazarlık
Taslağı yapay zekâ desteğiyle hazırlandı
Durum
Yapım aşamasında — gözden geçirilsin diye yayında, bitmiş değil.

Bu sayfayı İngilizce oku

Bir dizi dedektörü (sequence detector) sig_in üzerinde her clock'ta bir bit izler ve son birkaç bit bir deseni oluşturduğunda bunu söyler — burada 1011. Her state (durum), makinenin desenden o ana kadar ne kadarını gördüğüdür: hiçbir şey (IDLE), ardından 1, 10, 101 ve 1011. Bu bir Moore state machine'idir (durum makinesi): found yalnızca S1011 state'inin bir özelliğidir, bu yüzden makine orada kaldığı tek clock periyodu boyunca yüksektir.

Oklar, onları seçtiren sig_in değeriyle etiketlenmiştir, 1 ya da 0; kod aynı yerlerde sig_in ve !sig_in koşullarını sınar.

100142. satır1046. satır1001rst_n23–29. satırIDLES1S10S101S1011found=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”a basın. sig_in dört yükselen kenara 1, 0, 1 ve 1 taşır; yanan state deseni S1011'e kadar yürür.

Nasıl çalışır, kenar kenar

Başlangıçta rst_n düşüktür ve reset asenkrondur: register hiçbir clock kenarı beklemeden hemen IDLE olur. Reset, iki kenar arasında, 2. tick'te bırakılır; ilk yükselen kenara kadar hiçbir şey kıpırdamaz.

Kenar 0'da sig_in 1'dir ve makine IDLE'dan S1'e giden oku alır. O ok bir sonraki kenara kadar kalın çizilir: ateşlenen geçiş odur. Dalga biçiminin state satırı state'in adını yazar; karşılık geldiği rakamlar kodlamadır, yani state'leri kodda tanımlandıkları sırayla sayan üç bit.

Kenar 1 ve 2'de bitler 0 ve 1'dir; makine önce S10'a, sonra S101'e ulaşır. Kenar 3'te dördüncü bit, bir 1, onu S1011'e götürür ve found onunla birlikte yükselir. Ne zaman yükseldiğine bakın: dördüncü bit sig_in üzerindeyken değil, onu örnekleyen kenarda. Bir Moore çıkışı state'i bekler.

Örtüşme 1011011'i oynatır. İlk eşleşmeden sonra gelen bit 0'dır ve makine IDLE'a değil S10'a gider: 1011'in sonundaki 1 ile ardından gelen 0, bir sonraki 1011'in başıdır. Üç kenar sonra desen yeniden bulunur; ikincisi birincinin son bitinde başlar.

Reset yok senaryosu rst_n'i hiç etkinleştirmez. Register bilinen bir değer tutmaz, bu yüzden her state kesikli çizilir — register onların kodlarından herhangi birini ya da hiçbir state'i adlandırmayan üç koddan birini tutabilir — ve state satırı taralıdır. found da X'tir, çünkü o state'lerden biri S1011'dir. sig_in 1 kaldıkça hiçbir şey değişmez: bir 1, makinenin nerede olduğuna göre S1, S101 ya da S1011'e götürür ve bunların kodları, 001, 011 ve 100, her bitte farklıdır; bu yüzden register X kalır. sig_in'e bir kez basıp 0 yapın ve iki kenar geçsin: iki 0'da her state IDLE'a gider ve makine reset olmadan X'ten çıkar. 00 bu makine için en kısa synchronizing sequence'tir (senkronlama dizisi) ve iki bitlik tek dizidir: register hangi kodla başlarsa başlasın, S1011 ya da hiçbir state'i adlandırmayan bir kod, bu iki bit onu IDLE'da bırakır. Bu, reset'ler hakkında değil, bu makine hakkında bir şey söyler.

Kod

sequence_detector.sv
// Detects the bit sequence 1011 on sig_in, with overlap: 1011011 is found twice.
//
// Reset style for this module: asynchronous, active low. One style per page,
// stated up front, so nothing on the page has to be read twice.
module sequence_detector (
    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: found = 1'b0;
    endcase
  end

endmodule

Kod ile çizim tek bir şeydir. typedef enum state'leri listeler, always_ff bloğu makinenin tek register'ıdır, ilk case'in her kolu bir state, her if ya da else if satırı bir oktur. Bir state'in üzerine gelin, kolu yanar; bir okun üzerine gelin, satırı yanar; reset işareti register'ı yakar. FSM görüntüleyici, kendi durum makinenizi kodundan aynı biçimde, aynı bağlarla çizer.

Next-state bloğu next = state; ile açılır; böylece koşullarının hepsi yanlış olan bir state, arkasında bir latch bırakmak yerine kendi state'ini korur. Burada her state iki okunu da çizdiği için bu varsayılan atama hiçbir şeye karar vermez; hiçbir kol unutmasın diye oradadır. Çıkış bloğu ayrıdır ve yalnızca state'i okur: found'u bir Moore çıkışı yapan budur.

Sentez sonucu

sequence_detector.sv, Yosys'un genel sentezinde 17 hücre olur; 3 tanesi flip-flop. Hücreler Yosys'un kendi kapı kütüphanesinden; bir FPGA'nın ya da standart hücre kütüphanesinin değil. Sayı herhangi bir çipin alanını değil, mantığı ölçer.

Kod state için 3 bitlik bir kodlama seçer ve bu sayılar onu korur. Yosys kendi fsm pass'ine bırakılırsa onu one-hot olarak yeniden kodlar: 5 flip-flop, toplamda 14 hücre.

synth -nofsm sonrası hücreler, türe göre
HücreNe olduğuAdet
$_DFF_PN0_yükselen kenarda D flip-flop, 0 değerine aktif düşük asenkron reset3
$_AND_2 girişli AND2
$_ANDNOT_ikinci girişi terslenmiş AND, A & ~B4
$_NAND_2 girişli NAND5
$_NOR_2 girişli NOR2
$_OR_2 girişli OR1
Toplam17

Lint Verilator 5.052 ile, testbench Icarus Verilog 13.0 ile, sentez Yosys 0.66 ile yapıldı.

Icarus bu sayfanın üç senaryosundan iki tanesini bu kod üzerinde yeniden oynattı ve dalga biçiminin bunlar için çizdiği 470 değerin hepsi tutuyor. Reset yok dışarıda kaldı: bilinmeyen bir register'dan başlıyor ve bir RTL simülasyonu bunu bu motordan daha iyimser okur.

Sentezden önceki netlist

sequence_detector.sv dosyasının netlistsvg 1.0.2 ile çizilen netlist'i 760 × 765 px boyutunda, sayfanın içinde okunamayacak kadar büyük: tek başına açın, tarayıcı orada yakınlaştırabilir.

Tuzaklar

Örtüşmeyi unutmak. S1011'den 0 ile IDLE'a dönen bir ok daha derli toplu görünür ve 1011011'i yalnızca bir kez bulur. Kısmi bir eşleşmeden çıkan her ok, o ana kadar görülenin hâlâ desenin bir öneki (prefix) olan en uzun sonekine (suffix) gitmelidir. Başka bir desen için dizi dedektörü üreteci makineyi bu kuralla kurar: örtüşen ya da örtüşmeyen, Moore ya da Mealy, koduyla birlikte.

found'u bir çevrim erken beklemek. found'u S101'den 1 ile çıkan okun üzerine koyan bir Mealy sürümü, onu dördüncü bit hâlâ gelirken, bir clock periyodu önce yükseltirdi — üstelik sig_in'den kombinasyonel olarak, bu yüzden girişteki her glitch çıkışa ulaşır.

Reset yok. Bu figürün cevabı X'tir; bir RTL simülasyonu başka bir cevap verir. Aynı kodu rst_n hiç etkinleştirilmeden çalıştırın: X olan state hiçbir case maddesine uymaz, bu yüzden default: kolu seçilir. next zaman 0'dan itibaren IDLE ve found 0'dır; register ilk kenara kadar X, ondan sonra IDLE'dır. Simülasyon sağlıklı görünür. Bir ASIC'te register güç verildiğinde herhangi bir kodla başlar, kullanılmayan üç kod dahil; S1011'de başlarsa daha tek bir bit görmeden bir periyot boyunca found bildirir. Çoğu FPGA'da ise konfigürasyon her flip-flop'un başlangıç değerini yükler, kod başka bir değer vermedikçe 0; bu yüzden bu makine IDLE'da başlar. Ama bu değer bir kez, konfigürasyon sırasında yüklenir ve tasarımın uygulayabileceği bir reset değildir. Eksik bir reset'in RTL simülasyonundan sağ çıkmasının nedeni bu X-optimism'dir (X-iyimserliği).

Kendinizi sınayın

Makine S1011'de ve sıradaki bit 0. Neden IDLE'a değil de S10'a gider?
Çünkü gördüğü son iki bit, önce 1 sonra 0, yeniden 1011'in ilk iki bitidir. IDLE'a gitmek onları atar ve 1011011 iki kez değil bir kez bulunur. Örtüşme (overlap) budur.
Desenin dördüncü biti bütün bir clock periyodu boyunca sig_in üzerinde. found neden o periyodun sonundaki kenara kadar yükselmez?
Çünkü found bir Moore çıkışıdır, yalnızca state'in bir fonksiyonudur. Makine S1011'e dördüncü biti örnekleyen kenarda girer ve found state'i izler; bu yüzden bit gelirken değil, o kenarda yükselir.
“Reset yok” senaryosunda found 0 değil X. Neden?
Register'ı hiçbir şey bilinen bir state'e koymamıştır, bu yüzden makine beş state'inin herhangi birinde ya da hiçbirini adlandırmayan üç koddan birinde olabilir; aralarında found'un 1 olduğu S1011 de vardır. Bunların bazılarında 0, birinde 1 olan bir çıkış bilinmezdir.

Görev: İki kez S101

Yalnızca sig_in girişini siz sürersiniz. Makine 3 ve 5 numaralı kenarlarda S101 state'inde, found da 6 numaralı kenarda 1 olmalı.

Sizin girişiniz
  • sig_in, başlangıçta 0
Betik
  • rst_n başlangıçta 0.
  • rst_n, 0 numaralı kenardan önce 1 olur.
Hedef
  • 3 numaralı kenarda state değeri S101.
  • 5 numaralı kenarda state değeri S101.
  • 6 numaralı kenarda found değeri 1.

JavaScript açıkken “Başla” bu görevi şekilde oynatır.

Tüm görevler

Etiketler rtl state-machine moore sequence-detector

Bir hata mı buldunuz? Düzeltme gönderin