Desain prosesor Verilog


Bagian I
Bagian II
Bagian III
Bagian iv
Bagian v

Kami merancang Little Man Computer di Verilog.

Artikel tentang LMC ada di Habré.

Simulator online komputer ini ada di sini .

Kami menulis modul RAM / RAM yang terdiri dari empat (N = 2) empat-bit (M = 4) kata. Data dimuat ke dalam RAM dari data_in di adr ketika Anda mengklik tombol:
module R0 #(parameter N = 2, M = 4) ( input RAM_button, // input [N-1:0] adr, // input [M-1:0] data_in, //   output [M-1:0] RAM_out //   ); reg [M-1:0] mem [2**N-1:0]; //  mem always @(posedge RAM_button) //    mem [adr] <= data_in; //     data_in assign RAM_out = mem[adr]; // RAM_out    endmodule 

Sebagai generator eksternal, hubungkan timer 555 CMOS (beroperasi dari 3.3V).
Kami menghubungkan penghitung 555 ke penghitung, menghubungkan penghitung ke input alamat RAM :
 module R1 #(parameter N = 2, M = 4) ( input timer555, RAM_button, //input [N-1:0] adr, input [M-1:0] data_in, output [M-1:0] RAM_out ); reg [1:0]counter; //  always @(posedge timer555) //    counter <= counter + 1; //    1 wire [N-1:0] adr; assign adr = counter; //       reg [M-1:0] mem [2**N-1:0]; always @(posedge RAM_button) mem [adr] <= data_in; assign RAM_out = mem[adr]; endmodule 

Di sini, ketika menggambarkan penghitung penghitung dan memori, digunakan penugasan non-pemblokiran <= Operator penugasan dipertimbangkan di situs web marsohod.org di sini
Deskripsi penghitung ada di marsohod.org di sini

Tambahkan fungsi unduhan ke penghitung.
Pengunduhan dilakukan dengan perintah Counter_load :
 //input Counter_load; wire [3:0] branch_adr; //   assign branch_adr = data_in; always @(posedge timer555) begin if(Counter_load) //  "Counter_load"    "branch_adr" counter <= branch_adr; else counter <= counter + 1; end 


Dalam modul terpisah, buat register 4bit (baterai):
 module register4 ( input [3:0] reg_data, input reg_button, output reg [3:0] q ); always @(posedge reg_button) q <= reg_data; endmodule 

Tambahkan akumulator Acc , multiplexer MUX2 dan jumlah penambah ke sirkuit umum.
Penambah menambahkan nomor dalam nomor Acc baterai dari memori.
Input sinyal dari multiplexer diberi angka data_in dan jumlah .
Selanjutnya, nomor dari multiplexer MUX2 dimuat ke baterai Acc :
 module R2 #(parameter ADDR_WIDTH = 2, DATA_WIDTH = 4) ( input timer555, Counter_load, RAM_button, input MUX_switch, input Acc_button, input [3:0] data_in, output [3:0] Acc, output [DATA_WIDTH-1:0] RAM, output reg [1:0] counter ); wire [1:0] branch_adr; assign branch_adr = data_in[1:0]; //Counter always @(posedge timer555) begin if(Counter_load) counter <= branch_adr; else counter <= counter + 1; end wire [ADDR_WIDTH-1:0] adr; assign adr = counter; //RAM reg [DATA_WIDTH-1:0] mem [2**ADDR_WIDTH-1:0]; always @(posedge RAM_button) mem [adr] <= Acc; assign RAM = mem[adr]; //sum wire [3:0] sum; assign sum = Acc + RAM; //MUX reg [3:0] MUX2; always @* // Always @* —  «» MUX2 = MUX_switch ? sum : data_in; //Accumulator register4 Acc_reg( .reg_data(MUX2), .reg_button(Acc_button), .q(Acc) ); endmodule 

Selalu @ * berarti "selalu." Beberapa synthesizer tidak mengerti desain ini. Multiplexer juga dapat ditulis tanpa Selalu @ * (di sini digunakan hanya sebagai contoh).


Pengurangan


Untuk melakukan pengurangan, perlu untuk memberikan angka yang dikurangi dalam kode tambahan . Anda dapat membaca tentang penambahan dan pengurangan angka biner dalam buku teks "Sirkuit digital dan arsitektur komputer" (David M. Harris dan Sarah L. Harris) di bab 1.4.6. Tanda Angka Biner

Tambahkan ke modul utama elemen yang mengurangi dari nomor di baterai nomor yang tersimpan di memori:
 wire [3:0] subtract; assign subract = Acc - RAM ; 

Ganti multiplexer 2-input dengan 4-input:
 always @* MUX4 = MUX_switch[1] ? (MUX_switch[0] ? RAM : subtract) : (MUX_switch[0] ? sum : data_in); 

Kami menghubungkan perangkat output ke baterai (register 4bit'ny), kami juga menghubungkan 2 bendera ke baterai:

1. Bendera "Nol" adalah log. Elemen 4 ATAU TIDAK. Bendera dinaikkan jika konten Ass adalah nol.

2. Bendera "Nol atau Angka Positif" adalah log. elemen TIDAK pada tingkat tinggi baterai 4-bit. Bendera dinaikkan jika konten Ass lebih besar dari atau sama dengan nol.

 // "" output Z_flag; assign Z_flag = ~(|Acc); // 4-  - // "   " output PZ_flag; assign PZ_flag = ~Acc[3]; 


4 ATAU TIDAK
Di sini kami menggambarkan katup multi-input ATAU TIDAK sebagai ~ (| Acc)
Verilog juga mendukung satu set Jenis Gerbang.

Kata kunci berikut ini didefinisikan untuk gerbang logika: dan (DAN), nand (DAN-TIDAK), atau (OR-NOT), xor (Exclusive OR), xnor (Exclusive OR-NOT), buf (elemen Buffer) , bukan (Negasi, BUKAN).

Di Verilog, saat menggunakan gerbang, Anda harus menentukan input dan output elemen, serta (opsional) nama gerbang. Misalnya, katup dan dan atau harus memiliki satu keluaran dan dua atau lebih input. Jadi, untuk katup juga, kita punya
atau beri nama argumen list_of_
atau mynor (out, in0, in1, in2, in3);




Tambahkan tiga tim

1. memuat konten baterai ke perangkat output data_out
2. memuat alamat ke konter jika bendera “nol” dinaikkan ( JMP jika Acc = 0)
3. memuat alamat ke konter jika bendera “nol atau angka positif” dinaikkan ( JMP jika Acc > = 0)

 module R3 #(parameter ADDR_WIDTH = 2, DATA_WIDTH = 4) ( input timer555, RAM_button, input JMP, Z_JMP, PZ_JMP, input [1:0] MUX_switch, input Acc_button, input Output_button, input [3:0] data_in, output [3:0] Acc, output [3:0] data_out, output [DATA_WIDTH-1:0] RAM, output Z_flag, PZ_flag, output reg [1:0] counter ); wire [1:0] branch_adr; assign branch_adr = data_in[1:0]; wire Z,PZ; assign Z = Z_flag & Z_JMP; assign PZ = PZ_flag & PZ_JMP; //Counter always @(posedge timer555) begin if(JMP|Z|PZ) counter <= branch_adr; else counter <= counter + 1; end wire [ADDR_WIDTH-1:0] adr; assign adr = counter; //RAM reg [DATA_WIDTH-1:0] mem [2**ADDR_WIDTH-1:0]; always @(posedge RAM_button) mem [adr] <= Acc; assign RAM = mem[adr]; //sum wire [3:0] sum; assign sum = Acc + RAM; //subtract wire [3:0] subtract; assign subtract = Acc - RAM; //MUX reg [3:0] MUX4; always @* MUX4 = MUX_switch[1] ? (MUX_switch[0] ? RAM : subtract) : (MUX_switch[0] ? sum : data_in); register4 Acc_reg( .reg_data(MUX4), .reg_clk(Acc_button), .q(Acc) ); register4 Output_reg( .reg_data(Acc), .reg_clk(Output_button), .q(data_out) ); assign Z_flag = ~(|Acc); assign PZ_flag = ~Acc[3]; endmodule 



Kami menempatkan perintah dan alamat di satu RAM / RAM, dan data di yang lain.



Skema dapat diunduh dari sini .

Dalam delapan digit pertama, perintah disimpan, dalam empat digit terakhir alamat dimasukkan ke dalam penghitung.

Secara umum, memasukkan nomor ke baterai Ass harus dilakukan setelah mengganti multiplexer MUX (untuk perintah ADD , SUB , LDA ), sesuai dengan pembusukan jam.

T.O. di komputer kita sistem perintah berikut

48x - ADD tambahkan nomor dari RAM ke Ass
50x - SUB kurangi jumlah yang tersimpan dalam RAM dari Ass
80x - STA menyimpan nomor dari baterai ke RAM di alamat x
58x - LDA memuat nomor dari alamat x di Ass
04x - BRA transisi tanpa syarat ke sel dengan alamat x
02x - Transisi BRZ ke sel dengan alamat x, jika Ass = 0 (transisi kondisional)
01x - Transisi BRP ke sel dengan alamat x, jika Ass> = 0 (transisi kondisional)
40x - INP memuat nomor dari data_input dalam Ass
20x - OUT memuat nomor dari Ass ke data_out

Kami tidak akan memiliki tim HLT .

Ambil contoh algoritma untuk menemukan maksimal dua angka dari situs http://peterhigginson.co.uk/LMC/

Algoritma bekerja seperti ini: kami menyimpan dua angka dari data_in dalam memori data. Kurangi yang pertama dari angka kedua:

  • jika hasilnya negatif, tulis angka pertama di Ass, tulis angka dari Ass di data_out;
  • jika hasilnya positif, tulis angka kedua di Ass, tulis angka dari Ass di data_out.

00 INP
01 STA 11
02 INP
03 STA 12
04 SUB 11
05 BRP 08
06 LDA 11
07 BRA 09
08 LDA 12
09 OUT


Dalam sistem perintah kami, algoritma ini akan terlihat seperti ini

400
80b
400
80c
50b
018
58b
049
58c
200



Elemen BUKAN pada input kontrol penghitung yang diperlukan untuk memuat data ke dalam penghitung adalah fitur dari program Logisim, dalam skema nyata, elemen BUKAN pada input kontrol tidak diperlukan (setidaknya saya tidak tahu penghitung seperti itu).

Quartus II dapat diunduh dari situs web resmi.

Ketika mendaftar di bawah Fungsi Pekerjaan Utama Saya adalah *, pilih Siswa.
Selanjutnya, Anda perlu mengunduh driver untuk programmer (driver untuk usb-blaster dapat diinstal dari C: \ altera \ ... \ quartus \ drivers \ usb-blaster).

Logisim dapat diunduh di sini .

Source: https://habr.com/ru/post/id412057/


All Articles