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.
Kali pertama menggunakan LabsLand? Cipta akaun guru anda
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.
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.
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.
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.
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;
endmoduleBuka makmal Verilog DE1-SoC. Editor memaparkan fail
leds_mirror.v.Pilih seluruh kandungan
leds_mirror.vdan gantikannya dengan modul flip-flop D di atas. Kekalkan nama modulleds_mirror. Perhatikan bahawa modul kini mengisytiharkaninput CLOCK_50;: baris ini diperlukan untuk setiap reka bentuk berjam.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 ialahCLOCK_50tiada 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.Pilih Muat naik ke FPGA (
Upload to FPGA) dan tunggu sesi papan serta kamera langsung.Naikkan
SW[0](D=1). Sahkan bahawaLEDR[0](Q) menyala danLEDR[1](~Q) padam.Tunjukkan set semula: dengan
SW[0]masih dinaikkan, tekan dan tahanKEY[0]. PerhatikanLEDR[0]padam walaupun suis tidak berubah: set semula mengatasi data. LepaskanKEY[0]dan sahkanLEDR[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.
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;
endmoduleDalam
leds_mirror.v, gantikan seluruh kandungan dengan modul daftar 8 bit di atas. Kekalkan nama modulleds_mirrordan kekalkaninput CLOCK_50;.Pilih Jalankan sintesis (
Synthesize), tunggu sehingga berjaya, kemudian pilih Muat naik ke FPGA (Upload to FPGA).Tetapkan suis kepada
SW[7:0] = 10101010, denganSW[7]sebagai bit paling bererti. LED belum menunjukkan nilai ini kerana tiada data dimuatkan.Muat: tekan dan lepaskan
KEY[1].LEDR[7:0]kini menunjukkan10101010. Daftar telah menangkap nilai suis.Lihat ingatan: sekarang ubah suis kepada
SW[7:0] = 01010101tanpa menyentuhKEY[1]. Perhatikan LED: LED tidak berubah. Daftar mengekalkan nilai tersimpan walaupun input berbeza. Inilah ingatan.Kemas kini: tekan dan lepaskan
KEY[1]sekali lagi. KiniLEDR[7:0]berubah kepada01010101.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.
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.