Teach Pelajaran dengan makmal jarak jauh

Pelajaran Teach

Logik digital pada DE1-SoC (3/6): ingatan — flip-flop dan daftar

Bina flip-flop D dan daftar dalam Verilog, uji tingkah laku jam dan set semula, serta bezakan logik gabungan daripada keadaan tersimpan.

  • Altera DE1-SoC
  • 55 min
  • Prasiswazah, pengenalan
  • ms-MY
  • Digital systems & FPGA
Altera DE1-SoC
Altera DE1-SoC

Hasil pembelajaran

  • Menerangkan sebab logik jujukan memerlukan ingatan manakala logik gabungan tidak.

  • Menghuraikan flip-flop D sebagai sampel dan tahan pada pinggir jam, dengan set semula segerak.

  • Membina daftar muatan selari 8 bit daripada flip-flop D yang berkongsi jam dan set semula.

  • Menggunakan penetapan tidak menyekat dalam blok berjam dan mengenali input KEY aktif-rendah.

Pratonton aktiviti pelajar

Kandungan aktiviti

Pratonton sahaja. Dalam sesi kelas, pelajar boleh mengisi jawapan dan menyerahkan hasil kerja mereka kepada guru.

1

Mengapa litar memerlukan ingatan

10 min

Setiap reka bentuk setakat ini ialah reka bentuk gabungan: LED merupakan fungsi tulen kedudukan suis *pada masa itu*. Tukar satu suis dan output berubah sebaik sahaja isyarat merambat melalui gerbang. Litar gabungan tidak mempunyai keadaan: litar itu tidak mengetahui nilai input sebentar tadi dan tidak dapat mengingati apa-apa.

Namun kebanyakan sistem berguna memerlukan ingatan. Pembilang mesti mengetahui nilai semasanya untuk menghasilkan nilai berikutnya. CPU perlu menyimpan kendalian dan hasil antara arahan. Lampu isyarat perlu mengetahui warna yang sedang menyala untuk menentukan warna seterusnya. Semua ini tidak boleh dilakukan dengan gerbang sahaja kerana gerbang hanya mencerminkan input semasa.

Logik jujukan ialah logik yang mengingati. Outputnya bergantung bukan sahaja pada input semasa, tetapi juga pada keadaan yang tersimpan, iaitu perkara yang berlaku sebelumnya. Blok asas yang menyimpan satu bit keadaan ialah flip-flop, manakala penjaga masa yang memberitahu semua flip-flop *bila* perlu dikemas kini ialah jam.

DE1-SoC menyediakan jam bergerak bebas 50 MHz bernama CLOCK_50, iaitu gelombang segi empat yang naik dan turun 50,000,000 kali sesaat. Mulai pelajaran ini, reka bentuk jujukan anda mesti menyenaraikannya sebagai input. Templat lalai leds_mirror.v hanya menyenaraikan suis, butang dan LED serta tidak mempunyai jam, jadi anda perlu menambah input CLOCK_50; pada modul. Melupakan input ini ialah ralat paling lazim dalam reka bentuk jujukan.

Litar manakah yang merupakan litar jujukan — outputnya boleh bergantung pada masa lalu — dan bukannya litar gabungan?

Reka bentuk gabungan dalam Pelajaran 1–2 hanya menyenaraikan suis dan LED, tetapi reka bentuk berjam seperti flip-flop juga mesti menyenaraikan input CLOCK_50;. Mengapakah flip-flop atau daftar memerlukan jam sebagai input, dan apakah yang lazimnya berlaku jika anda meninggalkannya? Jawab dalam satu atau dua ayat.

2

Flip-flop D: sampel dan tahan pada pinggir jam

11 min

Flip-flop D ialah unsur ingatan paling ringkas. Ia mempunyai input data D, input jam dan output Q. Seluruh peraturannya ialah:

> Pada setiap pinggir menaik jam, Q menangkap nilai D lalu mengekalkannya sehingga pinggir menaik berikutnya.

Antara pinggir, perubahan input tidak memberi kesan: Q kekal beku. Inilah sampel dan tahan: flip-flop mensampel D ketika jam berubah daripada 0 kepada 1, kemudian mengekalkan sampel itu. Dengan cara inilah litar memperoleh ingatan: Q boleh kekal 1 lama selepas D kembali kepada 0 kerana ia mengingati sampel tersebut.

Rajah pemasaan flip-flop D: gelombang segi empat jam, isyarat data D yang berubah pada masa sembarangan dan output Q yang hanya berubah untuk sepadan dengan D pada setiap pinggir menaik jam lalu mengekalkan nilai itu hingga pinggir berikutnya, menunjukkan sampel dan tahan.

Sampel dan tahan pada pinggir jam: Q hanya dikemas kini pada setiap pinggir menaik CLOCK_50, menyalin nilai D pada ketika itu lalu mengekalkannya sehingga pinggir berikutnya. Perubahan D antara pinggir diabaikan.

Menulis tingkah laku ini dalam Verilog — dua idea baharu.

Pertama, blok berjam. Tingkah laku dipicu pinggir dihuraikan dengan always @(posedge CLOCK_50): pernyataan di dalamnya dilaksanakan sekali pada setiap pinggir menaik, bukan secara berterusan. Isyarat yang ditetapkan di dalam blok ini mesti diisytiharkan sebagai reg kerana ia mengekalkan nilai antara pinggir.

Kedua, penetapan tidak menyekat <=. Dalam blok berjam, sentiasa gunakan <=, bukan =. Operator <= bermaksud “sampel semua sebelah kanan sekarang, kemudian kemas kini semua sebelah kiri bersama-sama pada pinggir”, tepat seperti flip-flop sebenar yang semuanya mensampel serentak. Menggunakan =, iaitu penetapan menyekat, dalam blok berjam ialah ralat Verilog klasik: penetapan berkuat kuasa mengikut turutan pada pinggir yang sama, lalu satu flip-flop boleh melihat nilai *baharu* flip-flop lain dan bukan nilai lamanya. Perkakasan yang terhasil mungkin tidak sepadan dengan niat anda. Petua: gunakan <= dalam blok berjam; gunakan = hanya dalam logik gabungan dengan assign atau always @(*).

Set semula segerak. Kita juga memerlukan cara memaksa Q kembali kepada nilai yang diketahui. Set semula segerak diperiksa *di dalam* blok berjam, jadi ia hanya berkuat kuasa pada pinggir jam:

always @(posedge CLOCK_50) begin
    if (!KEY[0]) Q <= TODO_RESET_VALUE;   // set semula segerak, dinilai pada pinggir
    else         Q <= TODO_CAPTURED_VALUE;
end

Oleh sebab KEY aktif-rendah, butang dibaca sebagai 0 apabila ditekan. Maka !KEY[0] bernilai benar sepanjang butang set semula ditekan.

Katakan anda menulis Q = SW[0]; dengan = menyekat, bukannya <=, di dalam always @(posedge CLOCK_50). Operator manakah yang sepatutnya digunakan, dan apakah yang boleh berlaku apabila beberapa flip-flop dalam satu blok berjam dikemas kini bersama-sama menggunakan =?

Katakan D berdenyut kepada 1 hanya seketika *antara* dua pinggir menaik dan kembali kepada 0 sebelum pinggir seterusnya. Adakah Q pernah menjadi 1? Terangkan jawapan anda menggunakan peraturan sampel dan tahan.

3

Latihan 2-A — flip-flop D (set semula dalam tindakan)

12 min

Bina satu flip-flop D pada papan sebenar. Sambungannya ialah SW[0] = D, KEY[0] = set semula (aktif-rendah), LEDR[0] = Q dan LEDR[1] = ~Q.

Baca ini sebelum menjalankannya — penting. Pada 50 MHz, Q mengikut D 50,000,000 kali sesaat, jauh lebih pantas daripada penglihatan anda atau kamera. Jadi walaupun litar ini benar-benar *menyimpan* D, anda tidak dapat *melihat* proses penyimpanan: ubah SW[0] dan LEDR[0] kelihatan mengikutinya serta-merta. Oleh itu, latihan ini sebenarnya menunjukkan set semula, bukan penyimpanan. Tingkah laku yang akan anda perhatikan ialah:

- Dengan SW[0] dinaikkan (D=1), LEDR[0] menyala manakala LEDR[1], yang menunjukkan ~Q, padam.
- Tekan dan tahan KEY[0] — butang yang ditekan dibaca sebagai 0, jadi set semula aktif. LEDR[0] padam walaupun SW[0] masih dinaikkan. Set semula mengatasi data.
- Lepaskan KEY[0]: LEDR[0] kembali mengikut SW[0].

Anda akan *melihat* ingatan dalam latihan berikutnya, 2-B. Buat masa ini, tumpukan perhatian pada set semula yang mengatasi input data.

// Pelajaran 3 - Latihan 2-A: templat awal flip-flop D
// SW[0]=D, KEY[0]=set semula (aktif-rendah), LEDR[0]=Q, LEDR[1]=~Q.
module leds_mirror(CLOCK_50, SW, KEY, LEDR);
    input        CLOCK_50;
    input  [9:0] SW;
    input  [3:0] KEY;
    output [9:0] LEDR;

    reg Q;
    always @(posedge CLOCK_50) begin
        if (!KEY[0]) Q <= TODO_RESET_VALUE;
        else         Q <= TODO_D_INPUT;
    end

    assign LEDR[0]   = TODO_Q_OUTPUT;
    assign LEDR[1]   = TODO_NOT_Q_OUTPUT;
    assign LEDR[9:2] = 8'b0;
endmodule
  1. Buka makmal Verilog DE1-SoC. Editor memaparkan fail leds_mirror.v.

  2. Pilih seluruh kandungan leds_mirror.v dan gantikannya dengan modul flip-flop D di atas. Kekalkan nama modul leds_mirror. Perhatikan bahawa modul kini mengisytiharkan input CLOCK_50;: baris ini diperlukan untuk setiap reka bentuk berjam.

  3. Pilih Jalankan sintesis (Synthesize). Jika lawatan berpandu menutupi butang, tutup atau langkau lawatan itu terlebih dahulu. Tunggu sehingga selesai, biasanya sekitar 1 hingga 3 minit. Jika ralat dilaporkan, punca paling lazim ialah CLOCK_50 tiada dalam senarai port atau tanda koma bernoktah hilang. Betulkan dan jalankan sintesis sekali lagi. Teruskan hanya apabila status akhir menyatakan binaan berjaya dengan 0 ralat.

  4. Pilih Muat naik ke FPGA (Upload to FPGA) dan tunggu sesi papan serta kamera langsung.

  5. Naikkan SW[0] (D=1). Sahkan bahawa LEDR[0] (Q) menyala dan LEDR[1] (~Q) padam.

  6. Tunjukkan set semula: dengan SW[0] masih dinaikkan, tekan dan tahan KEY[0]. Perhatikan LEDR[0] padam walaupun suis tidak berubah: set semula mengatasi data. Lepaskan KEY[0] dan sahkan LEDR[0] menyala semula.

Tetapkan SW[0] dan KEY[0] seperti dalam setiap baris, kemudian catat perkara yang ditunjukkan oleh LEDR[0] (Q) dan LEDR[1] (~Q) pada kamera (1 = menyala, 0 = padam). Ingat bahawa KEY aktif-rendah: ditekan = 0, dilepaskan = 1.

SW[0] (D) KEY[0] (0=ditekan, 1=dilepaskan) LEDR[0] = Q LEDR[1] = ~Q

Apakah perbezaan antara flip-flop ini dengan wayar biasa dari SW[0] ke LEDR[0]? Jawab dari segi ingatan.

Reka bentuk ini menggunakan set semula segerak. Tunjukkan baris kod yang melakukan set semula dan terangkan maksud “segerak” dari segi *masa* set semula itu berkuat kuasa. Anda akan mempelajari set semula tak segerak dalam Pelajaran 5.

Mengapakah LEDR[1] sentiasa menunjukkan nilai yang bertentangan dengan LEDR[0]?

Latihan 2-A benar-benar menyimpan D, tetapi pada kamera anda hanya dapat melihat set semula berfungsi, bukan penyimpanan. Dengan menggunakan kadar jam 50 MHz, terangkan sebab penyimpanan itu tidak kelihatan tetapi set semula jelas kelihatan.

4

Latihan 2-B — daftar muatan selari 8 bit (ingatan yang dapat dilihat)

12 min

Daftar hanyalah N flip-flop D yang disusun bersebelahan dan semuanya berkongsi jam serta set semula yang sama. Daftar 8 bit menyimpan 8 bit. Muatan selari menyalin semua 8 bit input ke dalam daftar serentak pada satu pinggir jam: setiap flip-flop menangkap bit datanya sendiri pada masa yang sama.

Kawalan muat menjadikan ingatan dapat dilihat. Daripada menangkap data pada *setiap* pinggir seperti flip-flop tunggal, daftar ini hanya menangkap apabila anda mengarahkannya. Anda boleh mengubah suis sesuka hati dan nilai tersimpan kekal sama sehingga dimuatkan semula. Sambungannya ialah SW[7:0] = data, KEY[0] = set semula (aktif-rendah) dan KEY[1] = muat (aktif-rendah).

Oleh sebab KEY aktif-rendah, anda perlu menekan dan melepaskan KEY[1] untuk memuat: apabila ditekan, KEY[1] dibaca sebagai 0, lalu kod menguji !KEY[1] untuk mengesan keadaan itu. Perhatikan bahawa KEY[1] *disampel oleh jam*; ia bukan isyarat jam yang dinyahlantun dalam perkakasan. Reka bentuk hanya memeriksa aras butang pada setiap pinggir menaik, dan itu memadai untuk latihan ini.

// Pelajaran 3 - Latihan 2-B: templat awal daftar muatan selari 8 bit
// SW[7:0]=data, KEY[0]=set semula (aktif-rendah), KEY[1]=muat (aktif-rendah).
module leds_mirror(CLOCK_50, SW, KEY, LEDR);
    input        CLOCK_50;
    input  [9:0] SW;
    input  [3:0] KEY;
    output [9:0] LEDR;

    reg [7:0] Q;
    always @(posedge CLOCK_50) begin
        if (!KEY[0])      Q <= TODO_RESET_VECTOR;
        else if (!KEY[1]) Q <= TODO_LOAD_VALUE;
    end

    assign LEDR[7:0] = TODO_REGISTER_OUTPUT;
    assign LEDR[9:8] = 2'b00;
endmodule
  1. Dalam leds_mirror.v, gantikan seluruh kandungan dengan modul daftar 8 bit di atas. Kekalkan nama modul leds_mirror dan kekalkan input CLOCK_50;.

  2. Pilih Jalankan sintesis (Synthesize), tunggu sehingga berjaya, kemudian pilih Muat naik ke FPGA (Upload to FPGA).

  3. Tetapkan suis kepada SW[7:0] = 10101010, dengan SW[7] sebagai bit paling bererti. LED belum menunjukkan nilai ini kerana tiada data dimuatkan.

  4. Muat: tekan dan lepaskan KEY[1]. LEDR[7:0] kini menunjukkan 10101010. Daftar telah menangkap nilai suis.

  5. Lihat ingatan: sekarang ubah suis kepada SW[7:0] = 01010101 tanpa menyentuh KEY[1]. Perhatikan LED: LED tidak berubah. Daftar mengekalkan nilai tersimpan walaupun input berbeza. Inilah ingatan.

  6. Kemas kini: tekan dan lepaskan KEY[1] sekali lagi. Kini LEDR[7:0] berubah kepada 01010101.

  7. Set semula: tekan dan lepaskan KEY[0]. Semua lapan LED padam — Q = 00000000 — tanpa mengira kedudukan suis.

Jalankan urutan muat dan catat 8 LED (LEDR[7:0]) pada setiap peringkat. Pemerhatian utama ialah baris 'suis berubah, TANPA muat': nilai tersimpan mesti kekal sama seperti baris sebelumnya.

Peringkat SW[7:0] ditetapkan kepada Tindakan pada KEY LEDR[7:0] yang diperhatikan

Hantar bukti anda. Ambil tangkapan kamera yang membuktikan daftar sedang *mengekalkan* nilai: LEDR[7:0] menunjukkan 10101010, iaitu nilai yang dimuatkan sebelumnya, sementara suis pada skrin SW[7:0] ditetapkan kepada corak berbeza seperti 01010101 dan anda tidak menekan KEY[1]. Tunjukkan LED yang kekal dan kedudukan suis yang berbeza dalam tangkapan yang sama, kemudian lampirkannya di bawah.

Dalam langkah 5, anda mengubah suis tetapi LED tidak berubah. Terangkan sebabnya menggunakan perkataan “simpan” dan “muat”.

Jika anda menahan set semula (KEY[0]) dan muat (KEY[1]) serentak pada satu pinggir jam, apakah nilai yang akan diambil oleh daftar, dan mengapa? Tunjukkan baris kod yang menentukannya.

Apakah tujuan praktikal daftar muatan selari di dalam CPU? Berikan satu contoh khusus perkara yang mungkin disimpan oleh daftar tersebut.

5

Perkara yang anda bina dan catatan tentang gaya set semula

8 min

Anda membina dua asas semua ingatan dalam sistem digital: flip-flop D, yang menyimpan satu bit dengan sampel dan tahan pada pinggir jam, serta daftar, iaitu beberapa flip-flop yang dimuatkan selari dan mengekalkan nilainya sehingga diarahkan sebaliknya. Anda menggunakan always @(posedge CLOCK_50) dengan penetapan tidak menyekat <= dan melihat input KEY aktif-rendah bertindak sebagai kawalan.

Catatan untuk pelajaran seterusnya — dua gaya set semula. Kedua-dua reka bentuk dalam pelajaran ini menggunakan set semula segerak: set semula diperiksa *di dalam* blok berjam, maka ia hanya berkuat kuasa pada pinggir menaik. Gaya ini kemas dan mudah diramal serta akan terus digunakan untuk unsur storan dalam pelajaran ini dan pelajaran berikutnya. Namun Pelajaran 5 dan 6 tentang mesin keadaan terhingga akan beralih kepada set semula tak segerak aktif-rendah, yang ditulis sebagai always @(posedge CLOCK_50 or negedge KEY[0]). Gaya itu memaksa litar ke keadaan selamat serta-merta tanpa menunggu pinggir jam, berguna untuk memulihkan mesin keadaan yang tersangkut pada papan. Perbezaan terperinci dan sebab FSM memilih gaya tak segerak akan diterangkan di sana. Buat masa ini, ketahui bahawa kedua-dua gaya wujud dan pelajaran ini sengaja menggunakan gaya segerak.

Urutan manakah yang sepadan dengan perkara yang anda lakukan bagi setiap latihan dalam pelajaran ini?

Dalam tiga atau empat ayat, terangkan bagaimana Latihan 2-B *membuktikan* bahawa daftar mempunyai ingatan — rujuk data anda —, mengapa Latihan 2-A hanya dapat menunjukkan set semula dan bukan penyimpanan, serta nyatakan satu keadaan apabila kekutuban aktif-rendah KEY penting dalam langkah anda.