ΗΥ220 Εργαστήριο Ψηφιακών Κυκλωμάτων Verilog: Στυλ Κώδικα και Synthesizable Verilog Χειμερινό Εξάμηνο 2009 2010
Τα στυλ του κώδικα Τρεις βασικές κατηγορίες Behavioral (procedural) Dataflow Structural Synthesizable or not Διαφορετικός κώδικας για διαφορετικούς σκοπούς Synthesizable ή όχι; University of Crete ΗΥ220 2
Behavioral (1/3) Ενδιαφερόμαστε για την συμπεριφορά των blocks Αρχικό simulation Επιβεβαίωση αρχιτεκτονικής Test benches Απο απλά μέχρι εκλεπτυσμένα initial begin reset everything always @(posedge clk) begin case (opcode) 8 hab: RegFile[dst] = #2 in; 8 hef: dst = #2 in0 + in1; 8 h02: Memory[addr] = #2 data; case if (branch) dst = #2 br_addr; University of Crete ΗΥ220 3
Περισσότερες εκφράσεις for / while functions tasks fork join Περισσότεροι τύποι Behavioral (2/3) integer sum, i; integer opcodes [31:0]; real average; initial for (i=0; i<32; i=i+1) opcodes[i] = 0; always @(posedge clk) begin sum = sum + 1; average = average + (c / sum); opcodes[d] = sum; integer! real πίνακες $display( sum: %d, avg: %f, sum, average); University of Crete ΗΥ220 4
Behavioral (3/3) module test; define period 20 task ShowValues; input [7:0] data; $display(..., data); task... always @(posedge clk) ShowValues(counter);... module initial begin reset_ = 1 b0; reset_ = #(2*`period + 5) 1 b1; @(branch); reset _ = 1 b0; reset_ = #(2*`period + 5) 1 b1; always @(negedge reset_) begin fork a = #2 8 h44; b = #(4*`period + 2) 1 b0; c = #(16*`period + 2) 8 h44; join University of Crete ΗΥ220 5
Register Transfer Level RTL Το πιο διαδεδομένο δ δ και υποστηριζόμενο μοντελο για synthesizable κώδικα Κάθε block κώδικα αφορά την είσοδο λίγων καταχωρητών Σχεδιάζουμε κύκλο κύκλο με «οδηγό» το ρολόι Εντολές: Λιγότερες όχι τόσο περιοριστικές Think Hardware! Combinatorial Logic University of Crete ΗΥ220 6
Αυστηρότατο μοντέλο Μόνο module instantiations Συνήθως για το top level module Καλύτερη η αυστηρή χρήση Structural module top; wire clk, reset; wire [31:0] d_data, I_data; wire [9:0] d_adr; wire [5:0] i_adr; clock clk0(clk); processor pr0(clk, reset, d_adr, d d_data, d i_adr, i_data,...); memory mem0(d_adr, d_data); memory mem1(i_adr, i_data) ; tester tst0(reset,...); του module University of Crete ΗΥ220 7
μερικές συμβουλές Ονοματολογία wire a, Όχι πολύ μεγάλα / μικρά ονόματα με νόημα Συνδυαστική λογική Όχιόλασεμια γραμμή if (~req && Αναγνωσιμότητα Δομή Πολλες οντότητες Χρησιμοποιήστε indentation Καλύτερη ομαδοποίηση Αναγνωσιμότητα memory_data_write_enable; wire mem_wr_en, ((flag & prv_ack) ~set) && (count-2 == 0))... University of Crete ΗΥ220 8
περισσότερες συμβουλές Διευκολύνουν την ανάγνωση και την χρήση του κώδικα (filters, tools etc) Είσοδοι ξεκινούν με i_* Οι έξοδοι με o_* Οι τρικατάστατες με io_* Εκτός από ρολόι και reset Τα active low σήματα τελειώνουν με *_n Συνδέσεις πορτών συσχετίζοντας ονόματα module adder(o_sum, i_in1, i_in2); adder i0_adder ( instance names i0_adder, i1_adder.i_in2(b),.i_in1(a),.o_sum(c) ) osum= o_sum C, iin1= i_in1 A, iin2= i_in2 B University of Crete ΗΥ220 9
Σχόλια Ακούγεται μονότονο, αλλά Κώδικας hardware πιο δύσκολος στην κατανόηση Ακόμα και ο σχεδιαστής ξεχνάει γρήγορα Αν δε μπουν στην αρχή, δε μπαίνουν ποτέ Σημεία κλειδιά Σε κάθε module Σε κάθε block /*************************** * Comments on module test: * Module test comprises of * the following components **************************/ module test; Line comment University of Crete ΗΥ220 10
Verilog and Synthesis Χρήσεις της Verilog Μοντελοποίηση και event driven προσομοίωση Προδιαγραφές κυκλώματος για σύνθεση ύθ (logic synthesis) Logic Synthesis Snthesis Μετατροπή ενός υποσυνόλου της Verilog σε netlist Register Inference, combinatorial logic Βελτιστοποίηση του netlist (area,speed) Εξαρτάται από την βιβλιοθήκη του synthesizer University of Crete ΗΥ220 11
Synthesizable Verilog Constructs Construct Type Keywords Notes ports parameters module definition signals and variables input, output and inout parameter module, module wire, reg, tri instantiations module instances, e.g. mymux(o,i0,i1,s) i1 primitive gates e.g. nand(out,a,b) procedural always, if, else, case initial not supported procedural blocks begin, data flow assign Delay ignored Operators +,-, &,, ~,!=, ==, etc Caution: *, /, % functions / tasks function, task Limited support(simple CL) Loops for, while, Limited support(assigns) University of Crete ΗΥ220 12
Register D Flip Flop module Reg(Q, D, Clk); parameter N = 16; input Clk; input [N-1:0] D; output [N-1:0] Q; reg [N-1:0] Q; always @(posedged Clk) Q <= D; module University of Crete ΗΥ220 13
Register with Asynchronous Reset module RegRst(Q, D, CLR, Clk); parameter N = 16; input CLR, Clk; input [N-1:0] D; output [N-1:0] Q; reg [N-1:0] Q; always @(posedge Clk or posedge CLR) begin if (CLR) Q <= 0; else module Q <= D; University of Crete ΗΥ220 14
Register with Synchronous Reset module RegRst(Q, D, CLR, Clk); parameter N = 16; input CLR, Clk; input [N-1:0] D; output [N-1:0] Q; reg [N-1:0] Q; always @(posedge Clk) begin if (CLR) Q <= 0; else module Q <= D; University of Crete ΗΥ220 15
Register with Load Enable useful for low power designs module RegLd(Q, D, CE, Clk); parameter N = 16; input CE, Clk; input [N-1:0] D; output [N-1:0] Q; reg [N-1:0] Q; always @(posedge Clk) if (CE) Q <= D; module University of Crete ΗΥ220 16
Register with CLR, SET, CE module RegRst(Q, D, CLR, SET, CE, Clk); parameter N = 16; input input [N-1:0] D; output [N-1:0] Q; CLR, SET, CE, Clk; reg [N-1:0] Q; always @(posedge Clk) begin if (CLR) Q <= 0; else if (SET) Q <= 1; else Q <= D; module University of Crete ΗΥ220 17
Set Clear flip flop flop with Strong Clear module scff(out, Set, Clear, Clk); output Out; input Set, Clear, Clk; reg Out; always @(posedge Clk) module Out <= (Out Set) & ~Clear; University of Crete ΗΥ220 18
Set Clear flip flop flop with Strong Set module Scff(Out, Set, Clear, Clk); output Out; input Set, Clear, Clk; reg Out; always @(posedge Clk) module Out <= Set (Out & ~Clear); University of Crete ΗΥ220 19
T Flip Flop module Tff(Out, Toggle, Clk); output Out; input Toggle, Clk; reg Out; always @(posedge Clk) if (Toggle) module Out <= ~Out; University of Crete ΗΥ220 20
Counter with Async. Reset module v_counters_1 (C, CLR, Q); input C, CLR; output [3:0] Q; reg [3:0] tmp; always @(posedge C or posedge CLR) begin if (CLR) tmp <= 4'b0000; else tmp <= tmp + 1'b1; assign Q = tmp; module University of Crete ΗΥ220 21
Counter with Sync. Load module v_counters_1 (C, D, ALOAD, Q); input C, ALOAD; input [3:0] D; output [3:0] Q; reg [3:0] tmp; always @(posedge C) begin if (ALOAD) tmp <= D; else tmp <= tmp + 1'b1; assign Q = tmp; module University of Crete ΗΥ220 22
Counter with Async. CLR and Sync. Load module v_counters_1 (C, D, CLR, ALOAD, Q); input C, CLR, ALOAD; input [3:0] D; output [3:0] Q; reg [3:0] tmp; always @(posedge C or posedge CLR) begin if (CLR) temp <= 4 b0000; else if (ALOAD) tmp <= D; else tmp <= tmp + 1'b1; assign Q = tmp; module University of Crete ΗΥ220 23
Up/Down Counter with Async. Load module v_counters_1 (C, CLR, Q); input C, Up; output [3:0] Q; reg [3:0] tmp; always @(posedge C or posedge CLR) begin if (CLR) tmp <= 4 b0000; else if (Up) tmp <= tmp + 1'b1; else tmp <= tmp - 1'b1; assign Q = tmp; module University of Crete ΗΥ220 24
Accumulator module accumulator (C, D, CLR, Q); input C, Up; input [3:0] D; output [3:0] Q; reg [3:0] tmp; always @(posedge C or posedge CLR) begin if (CLR) tmp <= 4 b0000; else tmp <= tmp + d; assign Q = tmp; module University of Crete ΗΥ220 25
Shift Registers module shift(clk, SI, SO); input C, SI; output SO; reg [7:0] tmp; always @(posedge CLK) begin tmp = {tmp[6:0], SI}; assign SO = tmp[7]; module University of Crete ΗΥ220 26
Serial In Parallel Out module SIPO(CLK, SI, SO); input C, SI; output [7:0] SO; reg [7:0] tmp; always @(posedge CLK) begin tmp = {tmp[6:0], SI}; assign SO = tmp; module University of Crete ΗΥ220 27
Parallel In Serial Out module PISO(CLK, SI, ALOAD, D, SO); input C, SI; output [7:0] SO; reg [7:0] tmp; always @(posedge CLK) begin if (ALOAD) tmp = D; else tmp = {tmp[6:0], SI}; assign SO = tmp[7]; module University of Crete ΗΥ220 28
Shift register: Division Multipl Multipl. module SHIFT2(CLK, MULT, ALOAD, D, F); input C, MULT, ALOAD; input [7:0] D; output [7:0] F; reg [7:0] tmp; always @(posedge CLK) begin if (ALOAD) tmp = D; else if (MULT) tmp = {tmp[5:0], 2 b00}; else tmp = {2 b00, tmp[7:2]}; assign F = tmp; module University of Crete ΗΥ220 29
Shift register: Division Multipl Multipl. module SHIFT2(CLK, MULT, ALOAD, D, F); input C, MULT, ALOAD; input [7:0] D; output [7:0] F; reg [7:0] tmp; always @(posedge CLK) begin if (ALOAD) tmp = D; else if (MULT) tmp = tmp<<2; else tmp = tmp>>2; assign F = tmp; module University of Crete ΗΥ220 30
Shift register module SHIFT(DI, SEL, SO); input [7:0] D; output [1:0] SEL; reg [7:0] SO; always @(DI or SEL) begin case (SEL) 2 b00 : SO = DI; 2 b01 : SO = DI << 1; 2 b10 : SO = DI << 2; default : SO = DI << 3; case module University of Crete ΗΥ220 31
Barrel Shift Register module BarShiftReg(Out, In, Ld, Shift, Clk, Reset_); parameter N = 32; input Ld, Shift, Clk, Reset_; input [N-1:0] In; output [N-1:0] Out; reg [N-1:0] Out; always @(posedge Clk) begin if (~Reset_) Out <= 0; else begin if (Ld) Out <= In; else if (Shift) begin Out <= {Out[N-2:0],Out[N-1]}; module University of Crete ΗΥ220 32
Tristate Driver module Tris(TrisOut, TrisIn, TrisOen); parameter N = 32; input [N-1:0] TrisIn; input TrisOen; output [N-1:0] TrisOut; wire [N-1:0] TrisOut = TrisOen? TrisIn : bz; module University of Crete ΗΥ220 33
Multiplexor 2 to 1 module mux2(out, In1, In0, Sel); parameter N = 16; output [N-1:0] Out; input [N-1:0] In1, In0; input Sel; wire [N-1:0] Out = Sel? In1 : In0; module University of Crete ΗΥ220 34
Multiplexor 4 to 1 module mux4(out, In3, In2, In1, In0, Sel); parameter N = 32; input [ 1:0] Sel; input [N-1:0] In3, In2, In1, In0; output [N-1:0] Out; reg [N-1:0] Out; always @(In0 or In1 or In2 or In3 or Sel) begin case ( Sel ) 2'b00 : Out <= In0; 2'b01 : Out <= In1; 2'b10 : Out <= In2; 2'b11 : Out <= In3; case module University of Crete ΗΥ220 35
Multiplexor 4 to 1 module mux4(out, In2, In1, In0, Sel); parameter N = 32; input [ 1:0] Sel; input [N-1:0] In2, In1, In0; output [N-1:0] Out; reg [N-1:0] Out; always @(In0 or In1 or In2 or Sel) begin case ( Sel ) 2'b00 : Out <= In0; 2'b01 : Out <= In1; default: Out <= In2; module case University of Crete ΗΥ220 36
Encoders module encoder (sel, res); input [7:0] res; output [2:0] sel; reg [7:0] sel; always @(sel or res) begin case (res) 8'b00000001 : sel = 3'b000; 8'b00000010 : sel = 3'b001; 8'b00000100 : sel = 3'b010; 8'b00001000 : sel = 3'b011; 8'b00010000 : sel = 3'b100; 8'b00100000 : sel = 3'b101; 8'b01000000 : sel = 3'b101; default : sel = 3'b111; case module University of Crete ΗΥ220 37
Decoders module decoders (sel, res); input [2:0] sel; output [7:0] res; reg [7:0] res; always @(sel or res) begin case (sel) 3'b000 : res = 8'b00000001; 3'b001 : res = 8'b00000010; 3'b010 : res = 8'b00000100; 3'b011 : res = 8'b00001000; 3'b100 : res = 8'b00010000; 3'b101 : res = 8'b00100000; 3'b110 : res = 8'b01000000; default : res = 8'b10000000; case module University of Crete ΗΥ220 38
3 to 8 Binary Decoder module Dec(In, Out); input [2:0] In; output [7:0] Out; reg [7:0] Out; integer i; reg [7:0] tmp; always @(In) begin tmp = 0; for (i=0; i<8; i=i+1) if (In==i) tmp[i]=1; Out = tmp; module University of Crete ΗΥ220 39
8 to 3 Binary Encoder module Enc(In, Out); input [7:0] In; output [2:0] Out; reg [2:0] Out; integer i; always @(In) begin Out = 0; for (i=0; i<8; i=i+1) if (In[i]) Out=i; module University of Crete ΗΥ220 40
Λογική με προτεραιότητες (1/3) University of Crete ΗΥ220 41
Λογική με προτεραιότητες (2/3) Μάλλον δεν θέλαμε αυτό : University of Crete ΗΥ220 42
Λογική με προτεραιότητες (3/3) Πολύ Καλύτερο!!! University of Crete ΗΥ220 43
Combinatorial Logic and Latches (1/3) module mux3(out, In2, In1, In0, Sel); parameter N = 32; input [ 1:0] Sel; input [N-1:0] In2, In1, In0; output [N-1:0] Out; reg [N-1:0] Out; always @(In0 or In1 or In2 or Sel) begin case ( Sel ) 2'b00 : Out <= In0; 2'b01 : Out <= In1; 2'b10 : Out <= In2; case module Γιατί είναι λάθος; University of Crete ΗΥ220 44
Combinatorial Logic and Latches (2/3) module mux3(out, In2, In1, In0, Sel); parameter N = 32; input [ 1:0] Sel; input [N-1:0] In2, In1, In0; output [N-1:0] Out; reg [N-1:0] Out; always @(In0 or In1 or In2 or Sel) begin case ( Sel ) 2'b00 : Out <= In0; 2'b01 : Out <= In1; 2'b10 : Out <= In2; default : Out <= 0; case module Το σωστό!!! University of Crete ΗΥ220 45
Combinatorial Logic and Latches (3/3) Όταν φτιάχνουμε συνδυαστική ήλογική με always blocks και regs τότε πρέπει να αναθέτουμε τιμές στις εξόδους της λογικής για όλες τις πιθανές περιπτώσεις εισόδων (κλήσεις του always)!!! Για κάθε if ένα else Για κάθε case ένα default Παραλείψεις δημιουργούν latches κατά τη σύνθεση Οι περιπτώσεις που δεν καλύπτουμε χρησιμοποιούνται για το «σβήσιμο» του load enable του latch. (θυμάται την παλιά τιμή) University of Crete ΗΥ220 46
Priority Enforcer Module Priority is right > left (MS) module PriorEnf(In, Out, OneDetected); parameter N = 8; input [N-1:0] In; output [N-1:0] Out; output OneDetected; reg [N-1:0] Out; reg OneDetected; integer i; Temporary registers reg DetectNot; Temporary registers always @(In) begin DetectNot=1; for (i=0; i<n; i=i+1) if (In[i] & DetectNot) begin Out[i]=1; DetectNot=0; else Out[i]=0; OneDetected =!DetectNot; module University of Crete ΗΥ220 47
Unsigned Adders module adder(a, b, sum); input [7:0] a,b; output [7:0] sum; assign sum = a + b; module University of Crete ΗΥ220 48
Unsigned Adders module adder(a, b, sum); input [7:0] a,b; output [7:0] sum; output co; wire [8:0] temp; assign temp = a + b; assign sum = temp[7:0]; assign co = temp[8]; module University of Crete ΗΥ220 49
Signed Adders module adder(a, b, sum); input signed [7:0] a,b; output signed [7:0] sum; assign sum = a + b; module University of Crete ΗΥ220 50
Comparators module comparator(a, b, cmp); input [7:0] a,b; output cmp; assign cmp = (a>b)? 1 b1 : 1 b0; module University of Crete ΗΥ220 51
Mux4t1 RegLd Tris module MuxRegTris(Out, In0, In1, In2, In3, Select, Ld, TrisEn, Clk); parameter N = 32; input Ld, TrisEn, Clk; input [ 1:0] Select; input [N-1:0] In0, In1, In2, In3; output [N-1:0] Out; reg [N-1:0] MuxReg; always @(posedge Clk) begin if(ld) begin case(select) 0 : MuxReg <= In0; 1 : MuxReg <= In1; 2 : MuxReg <= In2; 3 : MuxReg <= In3; case wire [N-1:0] Out = TrisEn? MuxReg : 'bz; module University of Crete ΗΥ220 52
Up Counter Divider module Cnt(Out, Zero, En, Clear, Clk); parameter N = 32; parameter MaxCnt = 100; input En, Clear, Clk; output Zero; output [N-1:0] Out; reg [N-1:0] Out; reg Zero; always @(posedge Clk) begin if(clear) begin Out <= 0; Zero <= 0; else if (En) begin if (Out==MaxCnt) begin Out <= 0; Zero <= 1; else begin Out <= Out + 1; Zero <= 0; module University of Crete ΗΥ220 53
Positive Edge Detector module PosEdgDet(Out, In, Clk); input In, Clk; output Out; reg Tmp; always @(posedge Clk) Tmp <= In; wire Out = ~Tmp & In; module University of Crete ΗΥ220 54
Latch module Latch(In, Out, Ld); parameter N = 16; input [N-1:0] In; input Ld; output [N-1:0] Out; reg [N-1:0] Out; always @(In or Ld) if (Ld) Out = In; module University of Crete ΗΥ220 55
Sync. RAM module rams (clk,we,addr,,, di, do); input clk, we, en; input [5:0] addr; input [15:0] di; output [15:0] do; reg [15:0] do; reg [15:0] RAM [63:0]; always @(posedge clk) begin if (we) RAM[addr]<=di; do <= RAM[addr]; module University of Crete ΗΥ220 56
Async. RAM module rams (clk,we,addr,,, di, do); input clk, we, en; input [5:0] addr; input [15:0] di; output [15:0] do; reg [15:0] RAM [63:0]; always @(posedge clk) begin if (we) RAM[addr]<=di; assign do <= RAM[addr]; module University of Crete ΗΥ220 57
Ο NumberGenerator (1/2) module NumberGenerator ( o_numberout, Clk, Rst_n ); output [2:0] o_numberout; input Clk; input Rst_n; This is a counter (register + adder ) that counts cycles it wraps-around to zero alone reg [23:0] cycle_counter; always @(posedge Clk) begin if ( ~Rst_n ) begin Reset value 1 cycle_counter <= 1; else begin cycle_counter <= cycle_counter + 1; Generates a pulse every time the cycle counter goes to zero hence every 2^24 cycles in a 18 MHz clock (55,55 ns period) 2^24 * 55,55 ns which is approximatelly 0,93 sec wire NextNumber = ( cycle_counter == 0 ); wire NextNumber = ~ ( cycle_counter );... University of Crete ΗΥ220 58
Ο NumberGenerator (2/2)... Output register reg [2:0] o_numberout; always @(posedge Clk) begin if ( ~Rst_n ) begin o_numberout <= 0; else begin It changes value when the pulse comes if ( NextNumber ) o_numberout <= o_numberout + 1; else The else is not needed since it is a register o_numberout <= o_numberout; module University of Crete ΗΥ220 59
Ο SSDecoder του Lab0 είναι RTL reg [7:0] SegData; always @( i_numberin ) begin case ( i_numberin ) 3'b000: SegData <= 8'h3F; 3'b001: SegData <= 8'h06;... default: begin SegData <= 8'h80; case reg [7:0] o_segdata_n; always @(posedge Clk) begin if ( ~Rst_n ) begin o_segdata_n <= 8'hFF; else begin o_segdata_n <= ~SegData; University of Crete ΗΥ220 60
Synthesizable Verilog Περιγράφει το κύκλωμα που θέλουμε να σχεδιάσουμε. Behavioral high h levell αλλά δεν ξέρουμε ακριβώς πώς θα υλοποιηθεί Gate level low level => καλύτερος έλεγχος του κυκλώματος αλλά δύσκολο στην περιγραφή University of Crete ΗΥ220 61
Synthesizable Verilog Το καλύτερο βιβλίο είναι το manual του synthesizer που θα χρησιμοποιήσετε! University of Crete ΗΥ220 62
Synthesis Tool Manual Διαβάστε τι υποστηρίζει και τι όχι το synthesis tool University of Crete ΗΥ220 63