430 likes | 636 Views
CID 2 curs 4. 2 noiembrie 2006. Verilog Prezentarea programului Xilinx ISE (1). Verilog. operatori definirea porturilor instruc ţiuni ciclice taskuri si funcţii. Verilog. operatori. Tipuri de operatori în Verilog. aritmetici bit cu bit (bitwise) reducere logici relaţionali
E N D
CID 2 curs 4 2 noiembrie 2006
Verilog • Prezentarea programului Xilinx ISE (1)
Verilog • operatori • definirea porturilor • instrucţiuni ciclice • taskuri si funcţii
Verilog operatori
Tipuri de operatori în Verilog • aritmetici • bit cu bit (bitwise) • reducere • logici • relaţionali • deplasare • condiţionali
Operatori aritmetici • adunare + • scădere – • înmulţire * • împărţire / • modulo %
C2 – complement faţă de 2 • variabilele de tip reg, numere negative, sunt reprezentate automat în C2, dar sunt interpretate ca întregi fără semn • ex: A=5, B=2 (pe 4 biti, rezultatul pe 5 biti) A-B=3 B-A=29 - A=27
Exemple y1 = 8’b1011_1001 y2 = 8’b1101_0100 ~y1 = 0100_0110 y1 & y2 = 1001_0000 y1 | y2 = 1111_1101 y1 ^ y2 = 0110_1101
Exemple • rezultatul este pe un singur bit!!! • x = 4’b 1101 & x = 0 ~& x = 1 | x = 1 ^ x = 1 ~^ x = 0
== si === • == egalitate logică strictă, x pt ambiguităţi • === egalitate în logică cu 4 stări (egalitate după caz) • ex: 110xz 110xz (===) 110xz == 110xz are rezultatul x
Exemple • rezultatul este o valoare logică • Atenţie!!! operatorii logici pot fi folosiţi inadecvat deoarece tipurile de variabile nu sunt foarte restrictive • A && B, pentru variabile scalare, este identic cu A&B • pentru vectori: adevărat (1 logic) întreg pozitiv • ex A = 3’b110, B = 3’b11x A&&B = 0 (fals) A & B = 110 (logic adevarat) (intreg fără semn)
Precizări • rezultatul este o valoare logică (adevărat sau fals) • pentru net-uri sau reg-uri, se compară ca numere fără semn • orice bit z sau x => rezultat x
Exemple A = 1101_1001 A << 1 1011_0010 A << 3 1100_1000 A >> 2 0011_0110 A >>> 2 1001_0110
Operator condiţional y = (a==b) ? c:d ex. driver bus date wire [15:0] bus_a = enable_a ? data : 16’bz obs. definire compactata wire si assign enable_a = x => bus_a = 16’bx
Operator concatenare • utili pentru definirea bus-urilor • reunesc (concateneaza mai multi biti intr-un bus) • includ duplicarea (replicarea multipla) {a, b, c} //.... Concatenate a, b and c into a bus {3{a}} // ....... Replicate a, 3 times {{5{a}}, b} //.. Replicate a, 5 times and concatenate to b
Verilog definirea porturilor
1. listă ordonată DEFINIRE module circuit(out, in1, in2, in3); …. endmodule INSTANTIERE circuit circuit1(A, B, C, D); // A= out, B = in1, C=in2, D=in3 … circuit circuit2(B, D, A, C); // B= out, D=in1, A=in2, C=in3
2. referinţă după nume DEFINIRE module circuit(out, in1, in2, in3); …. endmodule INSTANTIERE circuit circuit1(.out(A), .in1(B), .in2(C), .in3(D); circuit circuit2(.in1(B), .in3(D), .in2(C), .out(A);
Verilog taskuri si funcţii
task un “task” este o subrutină care are orice număr de intrări sau ieşiri şi poate conţine controale de timp (instructiuni timing) task <task_name>; input <input_name>; <more_inputs> output <output_name>; <more_outputs> begin <statements>; end endtask
reguli • există task-uri de sistem şi task-uri definite de utilizator • taskuri de sistem: $stop, $display, $time • taskurile definite de utilizator pot avea porturi in, out, inout (oricât de multe) şi secvente procedurale care includ controale de timp • sunt apelate prin numele lor şi lista de valori de intrare în ordinea în care sunt declarate
exemplu task error_action; input read_write; input correct_value; input actual_value; input [8:0] output_string; begin if (ERROR_CHECK) begin if (read_write) $display("Error: %s value incorrect during write %d at time %t\nExpecting %b, got %b", output_string, write_attempt, $realtime, correct_value, actual_value);
continuare else $display("Error: %s value incorrect during read %d at time %t\nExpecting %b, got %b", output_string, read_attempt, $realtime, correct_value, actual_value); if (ON_ERROR=="FINISH") $finish; else if (ON_ERROR=="STOP") $stop; end end endtask
exemplu de apelare error_action(1'b1, wr_ready_value, WR_READY, "WR_READY");
funcţie function [<lower>:<upper>] <output_name> ; input <name>; begin <statements> end endfunction
reguli • o funcţie definită de utilizator care poate fi apelată din orice porţiune a codului, dar numai în instrucţiuni de atribuire • se poate defini în interiorul unui modul • poate avea mai multe intrări, dar o singură ieşire • nu poate conţine referinţe de timing
exemplu function [9:0] gray_encode; input [9:0] binary_input; begin gray_encode[9] = binary_input[9]; for (k=8; k>=0; k=k-1) begin gray_encode[k] = binary_input[k+1] ^ binary_input[k]; end end endfunction
exemplu de apelare write_count este intrarea binară transmisă funcţiei gray_encode ieşirea funcţiei gray_encode este atribuită semnalului FIFO_ADDR FIFO_ADDR = gray_encode(write_count);
comparaţie function- primitive • ambele au o singură ieşire • la funcţii, ieşirea şi intrările pot fi vectori (la primitive sunt obligatoriu scalare) • primitivele se definesc obligatoriu în afara modulelor • primitivele sunt folosite în descrieri structurale, funcţiile în atribuiri
Verilog instrucţiuni ciclice
always @ • sensibil la palier (valori logice): circuite combinaţionale şi latchuri transparente always @ (a or b or c) SE RECOMANDĂ FOLOSIREA = • sensibil la front (modificarea valorilor semnalelor): bistabile, circuite secvenţiale sincrone always @ (posedge ck or negedge enable) SE RECOMANDĂ FOLOSIREA <=
always - if Specificati intotdeauna optiunea else in instructiunile if combinationalepentru a evita sintetizarea eronată a unui latch!!! always @* // simbolizează orice conditie if (<condition>) begin <signal> = <value>; else <signal> = <value>; end
always - case // 7-segment encoding // 0 // --- // 5 | | 1 // --- <--6 // 4 | | 2 // --- // 3
always @(<4-bit_hex_input>) case (<4-bit_hex_input>) 4'b0001 : <7-seg_output> = 7'b1111001; // 1 4'b0010 : <7-seg_output> = 7'b0100100; // 2 4'b0011 : <7-seg_output> = 7'b0110000; // 3 4'b0100 : <7-seg_output> = 7'b0011001; // 4 4'b0101 : <7-seg_output> = 7'b0010010; // 5 4'b0110 : <7-seg_output> = 7'b0000010; // 6 4'b0111 : <7-seg_output> = 7'b1111000; // 7 4'b1000 : <7-seg_output> = 7'b0000000; // 8
4'b1001 : <7-seg_output> = 7'b0010000; // 9 4'b1010 : <7-seg_output> = 7'b0001000; // A 4'b1011 : <7-seg_output> = 7'b0000011; // b 4'b1100 : <7-seg_output> = 7'b1000110; // C 4'b1101 : <7-seg_output> = 7'b0100001; // d 4'b1110 : <7-seg_output> = 7'b0000110; // E 4'b1111 : <7-seg_output> = 7'b0001110; // F default : <7-seg_output> = 7'b1000000; // 0 endcase
care este rezultatul unor operaţii sau expresii logice • cum se conectează porturile într-o instanţiere • scrieţi un bloc de program ciclic sau sa îl comentaţi