• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Verilog 語法教學
 

Verilog 語法教學

on

  • 38,150 views

艾鍗學院-FPGA 實戰教學

艾鍗學院-FPGA 實戰教學
Verilog 語法教學

Statistics

Views

Total Views
38,150
Views on SlideShare
35,367
Embed Views
2,783

Actions

Likes
14
Downloads
0
Comments
0

5 Embeds 2,783

http://www.ittraining.com.tw 2772
https://www.facebook.com 6
http://www.facebook.com 2
http://ittraining.com.tw 2
http://www.plurk.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Verilog 語法教學 Verilog 語法教學 Presentation Transcript

    • FPGA 實戰教學 Part2 Verilog 語法教學 Lilian Chen 1
    • History of Verilog 始於約 1984 年 1) Gateway Design Automation Inc. 原始命名為 HiLo. 在當時並非為標準語言 1985~1987 年 1) 首度出現 Verilog simulator 1990 年 1) Cadence Designed System 收購 Gatway Design Automatic Inc. 並與 Synopsys 合作營銷 Verilog 1990 年 1) Cadence 組織了 Open Verilog International(OVI), 並開 放 Verilog 語言 2
    • History of Verilog 1991 年 1) 訂定 Verilog 語法文件 1994 年 1) IEEE1364 工作小組成立 , 並將 Verilog 建立標準 1995 年 12 月 1) Verilog 成為 IEEE 標準 多年後 , 不斷更新的版本 , 修改了 , Verilog 的許多問題 , 目前較新的版本被稱為 Verilog 2001. 3
    • Introduction Hardware Description Language (HDL). 是一種用來描述數位設計的語言 1) Microprocessor, memory, flip-flop…etc. 語法類似於 C 1) 易於學習 4
    • Design Flow Specification High Level Design Low Level Design RTL Coding Functional Verification Logic Synthesis Gate Level Simulation Place and Route Fabrication Post Si Validation 5
    • 註解單行註解 module add(a,b,ci,sum,co); input a,b,ci; output sum,co; // 註解在這裡 endmodule多行註解 module add(a,b,ci,sum,co); input a,b,ci; output sum,co; /* 註解在這裡 */ endmodule 6
    • White Space 什麼是 White Space? 1) 不被當做語法的字元 2) 目的用於便利閱讀 有哪些字元是 White Space 1) 空白 2) Tab 3) 換行 7
    • Case Sensitivity 命名大小寫不同 1) Add add aDD adD  皆代表不同 item 所有 Verilog keywords 都是小寫 , 若任一 為大寫字母 , 則皆被視為非 keywords 1) keyword case, endcase, module, endmodule, always, … etc 1) Not keyword Case, Endcase, Module, endModule, Always … etc. 8
    • Identifiers 舉凡 module, function, reg, wire 命名可用的字元有 1) a, b, c, …, z 2) A, B, C, …, Z 3) 0, 1, 2, … 9 4) _, $ 命名最長可接受最多 1024 個字 不可以數字為命名的起始 1) 386i  NG 2) i386  OK Escaped Identifiers 1) 386i  OK 2) 386i  NG 9
    • Integer Number 語法 1) <size>’<radix><value> 2) <radix> 跟 <value> 不用管是大小寫 example 1) 4 位元 10, 以 decimal 表示  4’d10 or 4’D10 2) 10 位元 128, 以 hexadecimal 表示  10’h080 or 10’H080 3) 10 位元 10, 以 hexadecimal 表示  10’h00a or 10’h00A 當 <size> 比 <value> 大時 1) 當 <value> 的最高位元為’ 1’ 或’ 0’ 時 , 左邊會填滿 ’ 0’ 2) 當 <value> 的最高位元為’ z’ 時 , 左邊會填滿’ z’ ‘z’ or ‘Z’ 皆可 1) 當 <value> 的最高位元為’ x’ 時 , 左邊會填滿’ x’ ‘x’ or ‘X’ 皆可 當 <value> 出現 ‘ ?’ 時 , 則視為 ‘ z’ ‘X’ Stands for unknown ‘Z’ stands for high impedance ‘1’ for logic high or ‘1’ ‘0’ for logic low or ‘0’ 10
    • Integer Number 基數表示方式Verilog 可接受的表示方式有 ( 以 4 位元 10 為範例 ) 1) Decimal 十進制 4’d10 1) hexadecimal 十六進制 4’ha 1) octal 八進制 4’o12 1) binary 二進制 4’b1010 11
    • Integer Number 基數表示方式 當位元數過多時 , _ 可以用來輔助 , 讓 code 易於閱讀 ( 以 32 位元 10 為範例 ) 1) Decimal  十進制 32’d10 1) hexadecimal 十六進制 32’h0000_000a 1) octal 八進制 32’o000_0000_0012 1) Binary  二進制 32’b0000_0000_0000_0000_0000_0000_0000_1010 12
    • Real Numbers Verilog supports real constants and variables Verilog converts real numbers to integers by rounding Real Numbers can not contain Z and X Real numbers may be specified in either decimal or scientific notation < value >.< value > 1) 1.2  1.2 2) 0.6  0.6 < mantissa >E< exponent > 1) 3.5E6  3500000 Real numbers are rounded off to the nearest integer when assigning to an integer. 13
    • Signed and Unsigned Numbers Verilog 支援 signed 以及 unsigned 兩種類 型的 numbers, 但有一定的限制 類似於 C, 但沒有特定的資料型態 1) ‘int’ or ‘unsigned int’ 在數字前沒有加 ‘ -’ 則代表正數 1) unsigned: 32’hedad_beef 2) signed: -14’h1234 若將負數 assigned 至一個 integer numbers 時 , 則會以 2 的補數格式填入 14
    • Signed and Unsigned Numbersreg [31:0]a,b,c,d;a[31:0] = 14’h1234; a[31:0] = 32’h00001234b[31:0] = -14’h1234; b[31:0] = 32’hffffedccc[31:0] = 32’hdead_beef; c[31:0] = 32’hdeadbeefd[31:0] = -32h’dead_beef; d[31:0] = 32’h21524111 15
    • Module Verilog 語法皆以 module 為主體 module 名稱 module 輸出 / 輸入埠名稱 module add (a,b,ci,sum,co); input a,b,ci; module 輸入宣告 output sum,co; module 輸出宣告 endmodule 註 : 雙向埠則為 inout 16
    • Module – Port Declaration 語法 1) input [range_val:range_var] list of identifiers; 2) output [range_val:range_var] list of identifiers; 3) inout [range_val:range_var] list of identifiers; Example 1) input clk;  一般不會寫成 input [0:0] clk; 2) input clk,reset; 3) input [15:0] data_in; 4) output [7:0]data_out; 5) inout [31:0]data_bidirection; 17
    • Module 不易讀的 Coding Style module add (a,b,ci,sum,co); input a,b,ci; output sum,co; wire sum,co; endmodule 分號 “ ;” 代表一行程式的結束 18
    • Module 易於讀 Coding Style module add (a,b,ci,sum,co); input a,b,ci; output sum,co; wire sum,co; module add( endmodule input a, input b, module add (a,b,ci,sum,co); input ci, input a; output sum, input b; output co); input ci; output sum; wire sum; output co; wire co; wire sum; endmodule wire co; endmodule 19
    • Module Port Connected 語法 1) by Port Order ( C/C++ like) <module name> <module inst_name> (<port1>,<port2>,….,<portn>); 1) by Name Order <module name> <module inst_name> (.<port1_name>(<port1>), .<port2_name>(<port2>), …., .<portn_name>(<portn>)); 20
    • Module Port Connected by Port Ordermodule add(a,b,sum,co); moduel top(a_in,b_in,sum_out,carry_out); input a,b; input a_in,b_in; output sum,co; output sum_out,carry_out; wire sum,co; wire sum_out,carry_out; assign sum = a^b; add adder(a_in,b_in,sum_out,carry_out); assign co = a&b; endmoduleendmodule module inst_name adder a_in a sum sum_out b_in b add co carry_outmodule name top 21
    • Module Port Connected by Name Order moduel top(a_in,b_in,sum_out,carry_out);module add(a,b,sum,co); input a_in,b_in; input a,b; output sum_out,carry_out; output sum,co; wire sum_out,carry_out wire sum,co; add adder(.a(a_in), assign sum = a^b; .b(b_in), assign co = a&b; .sum(sum_out),endmodule .co(carry_out)); endmodule adder a_in a sum sum_out b_in b add co carry_out top 22
    • Module Port Connected by multi-module moduel top(a1_in,b1_in, sum1_out,carry1_out, a2_in,b2_in, adder1 sum2_out,carry2_out); input a1_in,b1_in;a1_in a sum sum1_out output sum1_out,carry1_out; input a2_in,b2_in;b1_in b add co carry1_out output sum2_out,carry2_out; wire sum1_out,carry1_out; wire sum2_out,carry2_out; adder2 add adder1(.a(a1_in),a2_in a sum sum2_out .b(b1_in), .sum(sum1_out),b2_in b co carry2_out .co(carry1_out)); add add adder2(.a(a2_in), .b(b2_in), top .sum(sum2_out), .co(carry2_out)); endmodule 23
    • Module Port Connected by un-connectedmoduel top(a1_in,b1_in,sum1_out,carry1_out, a2_in,b2_in,sum2_out,carry2_out); input a1_in,b1_in; output sum1_out,carry1_out; input a2_in,b2_in; output sum2_out,carry2_out; wire sum1_out,carry1_out; wire sum2_out,carry2_out; add adder1(.a(a1_in),.b(b1_in),.sum(sum1_out),.co(carry1_out)); add adder2(.a2_in,b2_in,sum2_out,carry2_out);endmodule 24
    • Module Port Connected by valuemoduel top(a1_in,b1_in,sum1_out,carry1_out, a2_in,b2_in,sum2_out,carry2_out); input a1_in,b1_in; output sum1_out,carry1_out; input a2_in,b2_in; output sum2_out,carry2_out; wire sum1_out,carry1_out; wire sum2_out,carry2_out; add adder1(.a(a1_in),.b(b1_in),.sum(sum1_out),.co(carry1_out)); 1’b1 add adder2(.a2_in,b2_in,sum2_out,carry2_out); 1’b1endmodule 25
    • Data type Verilog has two data types 1) Nets Represent structural connections between components 1) Registers Represent variables used to store data Explicitly declared 1) With a declaration in your Verilog code. Implicitly declared 1) with no declaration when used to connect structural building blocks in your code. Implicit declaration is always a net type "wire" and is one bit wide. 26
    • Data type module nets/registers nets/registers nets nets nets nets 27
    • Data Types of NetsNet Data Type Functionwire, tri Interconnecting wirewor, trior Wired output ‘OR’ togetherwand, triand Wired output ‘AND’ togethertri0, tri1 Net pull-down or pull-up when no drivingsupply0, supply1 Net constant logic 0 or 1 (supply strength)trireg Retains last value, when drive by z(tristate)註 : 在這麼多的 Net Types 裡 , ‘wire’ 是常用到的 Data type 28
    • Data Types of Register Net Data Function Type reg Unsigned variable integer Signed variable – 32 bits time Unsigned integer – 64 bits real Double precision floating point variable註 : 在這麼多的 Register Types 裡 , ‘reg’ 是常用到的 Data type 29
    • Verilog Operators – arithmeticOperators 功能 Notes+ 加法- 減法* 乘法/ 除法 無法合成% 取餘數 無法合成註 : 若 reg 的值有任一為 ‘ x’ 的話 , 則結果會是 ‘ x’ Example: 4’b00x1 + 4’b001x = 4’b00xx 30
    • Verilog Operators - RelationalOperators 功能 Notesa<b a 是否小於 b 判斷不包 括’ z’ 或’ x’a>b a 是否大於 b 判斷不包 括’ z’ 或’ x’a <= b a 是否小於等於 b 判斷不包 條件成立 , 回覆 ‘ 1’ 括’ z’ 或’ x’a >= b ,‘ x’ 時 ,‘ 0’ ‘ x’ 條件失敗 回覆 如果含有 a 是否大於等於 b 判斷不包 回覆 括’ z’ 或’ x’ 31
    • Verilog Operators - EqualityOperators 功能 Notesa === b a 是否等於 b 判斷包括’ z’ 或’ x’a !== b a 是否不等於 b 判斷包括’ z’ 或’ x’a == b a 是否等於 b 判斷不包括’ z’ 或’ x’a != b a 是否不等於 b 判斷不包括’ z’ 或’ x’ 條件成立 , 回覆 ‘ 1’ 條件失敗 , 回覆 ‘ 0’ 32
    • Verilog Operators – LogicalOperators 功能 Notes! Logical 反相&& Logical and|| Logical or 33
    • Verilog Operators – Bit-wiseOperators 功能 Notes~ 反相 ~x = x& and 0 & x = 0 1&x=x&x=x| or 1|x=1 0|x=x|x=x^ xor 0^x=1^x=x^x=x^~ or ~^ xnor 0 ~^ x = 1 ^~ x = x ~^ x = x 34
    • Verilog Operators – ShiftOperations 功能 Notes<< 左旋>> 右旋 35
    • Verilog Operators – Concatenation 語法 1) {port1,port2,….,port3} 用於將不同的信號組合在一起 reg [3:0]a; reg b; wire [10:0]c; c[10:0] = {a[3:0],4’b1101,b,2’b00}; c[10:0] = {a[2:0],4’b1101,a[3],1’b1,b,1’b0}; 36
    • Verilog Operators – Replication 語法 1) {n{m}}  replicate value m, n times Example 1) {3{a}}  {a,a,a} 2) {b,{3{c,d}}}  {b,c,d,c,d,c,d} 註 : 藍色的 ‘ {}’ 是 Concatenation 37
    • Verilog Operators – Conditional 語法 1) <cond_expr> ? <true_expr> : <false_expr>; Example 1) a = (c==b) ? d : 1’b1; 當 c 等於 b 時 , a 等於 d, 否則 a 等於 ‘ 1’ 1) out = enable ? Data_out : 1’bz; 當 enable 為 ‘ 1’ 時 , out 等於 Data_out, 否則 out 等於 ‘ z’ 1) y = en1 ? dout1 : en2 ? dout2 : 1’bz; 當 en1 為 ‘ 1’ 時 , y 等於 dout1, 當 en1 為 ‘ 0’ 且 en2 為 ‘ 1’ 時 , y 等於 dout2, 否則 y 為 ‘ z’註 : <enable ?> 這樣的寫法等同於 <(enable==1’b1)?> 38
    • Verilog Abstraction Levels Behavioral 1) Higher level of modeling where behavior of logic is modeled. RTL 1) Logic is modeled at register level Structural 1) Logic is modeled at both register level and gate level 39
    • Procedural Blocks initial 1) 只在一時間為零時執行 , 且只執行一次 2) 通常應用在 simulation model always 1) 始終循環執行注意 , 在 initial 以及 always 內被指定的 Data type 都會是 reg 的型態 40
    • Procedural Blocksmodule initial_bad_style(clk,rst,en,dout); module initial_good_style(clk,rst,en,dout); output clk,rst,en,dout; output clk,rst,en,dout; reg clk,rst; reg clk,rst; wire en,dout; reg en,dout; initial initial begin begin clk = 1’b0; clk = 1’b0; rst = 1’b0; rst = 1’b0; en = 1’b0; en = 1’b0; dout = 1’b1; dout = 1’b1; end endendmodule endmodule 41
    • Procedural Blocksmodule proc_good_style(clk,en,dout); module proc_good_style(clk,en,dout); input clk, en input clk, en output dout; output dout; wire dout; reg dout; always @(posedge clk) always @(posedge clk) begin begin if(en==1’b1) if(en==1’b1) dout = 1’b1; dout = 1’b1; else else dout = 1’b0; dout = 1’b0; end endendmodule endmodule 42
    • Procedural assignment 當程序的程式多於一個指令時 , 必須用下 列兩種將多個指令給包起來 1) Sequential  begin – end 2) Parallel  fork – join 43
    • Procedural assignmentmodule initial_fork(clk,rst,en,dout); module initial_begin(clk,rst,en,dout); output clk,rst,en,dout; output clk,rst,en,dout; reg clk,rst, en,dout; reg clk,rst, en,dout; initial initial begin begin #0 clk = 1’bz; #0 clk = 1’bz; rst = 1’bz; rst = 1’bz; en = 1’bz; f1 b1 en = 1’bz; dout = 1’bz; dout = 1’bz; fork #1 clk = 1’b0; b2 #1 clk = 1’b0; f2 #10 rst = 1’b0; b3 #10 rst = 1’b0; f3 #5 en = 1’b0; b4 #5 en = 1’b0; f4 #3 dout = 1’b1; b5 #3 dout = 1’b1; f5 end join end endmoduleendmodule b1 b2 b3 b4 b5 f1 f2 f5 f4 f3 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 44
    • Blocking and Non-blocking Blocking  ‘=‘ 1) 在同一個程序裡 , 執行順序按照 code 的順序 Non-blocking  ‘<=‘ 1) 在同一個程序裡 , 所有的 code 同時執行 45
    • Blocking and Non-blocking Blocking Non-Blocking reg a = 1’b1; reg a = 1’b1; reg b = 1’b0; reg b = 1’b0; always @(posedge clk) always @(posedge clk) begin begin a = b; a <= b; b = a; b <= a; end end a a b b 46
    • if- else 語法 1) <if>(< 判斷式 1>) inital begin begin < 執行式 1> #0 < 判斷式 1> = false end <else> <if>>(< 判斷式 2>) < 判斷式 2> = false begin #1 < 判斷式 1> = true < 執行式 2> < 判斷式 2> = false end #1 < 判斷式 1> = false <else> < 判斷式 2> = true begin #1 < 判斷式 1> = true < 執行式 3> < 判斷式 2> = true end end 執行時 , 一律由第一個判斷式開始< 執行式 3> < 執行式 1> < 執行式 2> < 執行式 1> < 執行式 1> 0 1 2 3 4 47
    • case 語法 1) <case>(< 判斷子 >) < 條件 1> : begin < 執行式 1> end < 條件 2> : begin < 執行式 2> end ….. <default> : begin < 執行式 n> end <endcase> 48
    • case initial begin #0 b[3:0] = 4’b0000; #1 b[3:0] = 4’b0001; #1 b[3:0] = 4’b0010; case(b[3:0]) #1 b[3:0] = 4’b0011; 4’b0000: begin <s1> end #1 b[3:0] = 4’b0100; 4’b0001: begin <s2> end #1 b[3:0] = 4’b0101; 4’b0010: begin <s3> end #1 b[3:0] = 4’b0110; 4’b0100: begin <s4> end #1 b[3:0] = 4’b0111; 4’b1000: begin <s5> end #1 b[3:0] = 4’b1000; 4’b1110: begin <s6> end #1 b[3:0] = 4’b1001; default: begin <sn> end #1 b[3:0] = 4’b1010; endcase #1 b[3:0] = 4’b1011; #1 b[3:0] = 4’b1100; #1 b[3:0] = 4’b1101; #1 b[3:0] = 4’b1110; #1 b[3:0] = 4’b1111; ends1 s2 s3 sn s4 sn sn sn s5 sn sn sn sn sn s6 sn sn sn sn sn0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 49
    • casez casex 語法 1) <casez/casex>(< 判斷子 >) < 條件 1> : begin < 執行式 1> end < 條件 2> : begin < 執行式 2> end ….. <default> : begin < 執行式 n> end <endcase> casez : ‘z’ as don’t care casex : ‘z’ and ‘x’ as don’t care 50
    • Dealy controls 語法 1) #<time>< 執行式 >; Example 1) #0 reset = 1’b0; 2) #15 reset = 1’b1; 51
    • Edge sensitive event control 語法 1) @(<posedge/negedge> <signal>) begin < 執行式 > end 2) @(<posedge/negedge> <signal> or <posedge/negedge><signal>) begin < 執行式 > end 52
    • Edge sensitive event control initial begin #0 clk <= 1’b0;module add(clk,rst,a,b,sum,co); forever #1 clk <= ~ clk; input clk,rst,a,b; initial begin end output sum,co; reg sum,co; #0 {rst,a,b} <= {1’b0,1’b1,1’b1}; #2 {rst,a,b} <= {1’b1,1’b0,1’b0}; always @(posedge clk or negedge rst) #2 {rst,a,b} <= {1’b1,1’b1,1’b0}; begin #2 {rst,a,b} <= {1’b1,1’b0,1’b1}; if(rst==1’b0) #2 {rst,a,b} <= {1’b1,1’b1,1’b1}; begin sum <= 1’b0; end co <= 1’b0; sum end else co begin a sum <= a ^ b; b co <= a & b; rst end end clkendmodule 0 1 2 3 4 5 6 7 8 9 53
    • Level sensitive event control 語法 1) @(<signal>) begin < 執行式 > end 2) @(<signal> or <signal>) begin < 執行式 > end 54
    • Level sensitive event control module add(clk,rst,a,b,sum,co); initial input clk,rst,a,b; begin output sum,co; reg sum,co; #0 {rst,a,b} <= {1’b0,1’b1,1’b1}; #2 {rst,a,b} <= {1’b1,1’b0,1’b0}; always @(a or b or rst) #2 {rst,a,b} <= {1’b1,1’b1,1’b0}; begin #2 {rst,a,b} <= {1’b1,1’b0,1’b1}; if(rst==1’b0) #2 {rst,a,b} <= {1’b1,1’b1,1’b1}; begin end sum <= 1’b0; co <= 1’b0; end sum else begin co sum <= a ^ b; a co <= a & b; end b end rst endmodule 0 1 2 3 4 5 6 7 8 9 55
    • Tri-State buffermodule tri_buff(in,out,en); initial input in,en; begin output out; #0 {in,en} <= {1’b0,1’b0}; wire out; #1 {in,en} <= {1’b0,1’b1}; #1 {in,en} <= {1’b1,1’b0}; assign out = (en==1’b1) ? in : 1’bz; #1 {in,en} <= {1’b1,1’b1}; endendmodule in en out 0 1 2 3 4 5 56
    • Task task 是用在所有的編程語言,一般被稱為程序或子程序。 Include 在 module 內, task 可以被調用多次,減少了代碼重複。 可以有任意數量的輸入 / 輸出。 可使用 posedge, negedge, # delay 呼叫 task 時的變數傳輸順序即是 , 在 task 中宣告輸出入的順序。 在 task 中可再次呼叫其它的 task, function 語法 task <task_name>; input <input_port>; output <output_port>; begin < 執行式 >; end endtask 57
    • Taskmodule task_calling (temp_a, temp_b, temp_c, temp_d); initial input [7:0] temp_a, temp_c; begin output [7:0] temp_b, temp_d; #0 temp_a[7:0] <= 8d0; reg [7:0] temp_b, temp_d; temp_c[7:0] <= 8d0; forever always @ (temp_a) begin begin #1 temp_a[7:0] <= temp_a[7:0] + 8d1; convert (temp_a, temp_b); temp_c[7:0] <= temp_c[7:0]; end #1 temp_a[7:0] <= temp_a[7:0]; temp_c[7:0] <= temp_c[7:0] + 8d1; always @ (temp_c) end begin end convert (temp_c, temp_d); end temp_a 8’d0 8’d1 8’d2 8’d3 task convert; temp_b 8’d32 8’d33 8’d34 8’d35 input [7:0] temp_in; output [7:0] temp_out; begin temp_c 8’d0 8’d1 8’d2 temp_out = (9/5) *( temp_in + 32); end temp_d 8’d32 8’d33 8’d34 endtask 0 1 2 3 4 5endmodule 58
    • Function 一個 Verilog HDL 語言的功能是一樣的 task ,只有非常小的差異。 1) 可以有任意數量的輸入,但只有一個輸出。 2) 不能使用 posedge, negedge, # delay 。 3) 在 function 內只能再次呼叫 function, 但不 能呼叫 task 。 59
    • Function module pattern(a,b,c,d); output a,b,c,d; wire a,b,c,d; reg [3:0]cnt; assign a = cnt[0]; assign b = cnt[1]; assign c = cnt[2];module function_calling(a,b,c,d,e,out1,out2); assign d = cnt[3]; input a, b, c, d, e; assign e = cnt[0]; output out1,out2; wire out1,out2; initial begin #0 cnt[3:0] <= 4d0; assign out1 = (myfunction (a,b)) ? e : 1bz; forever #1 cnt[3:0] <= cnt[3:0] + 4d1; assign out2 = (myfunction (c,d)) ? e : 1bz; end endmodule function myfunction; a input a, b, c, d; begin b myfunction = a^b; out1 end endfunction e cendmodule d out2 60 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    • Simulation - $dispaly, $strobe, $monitor 這三個 command 語法相同 , 用於 simulation 時顯示文字訊息 $display 以及 $strobe 每次執行時顯示一次 $monitor 則是用於參數有改變就顯示一次 語法很像 C/C++. 1) %d (decimal), %h (hexadecimal), %b (binary), %c (character), %s (string), %t (time), %m (hierarchy level). %5d, %5b etc. 語法 1) $display ("format_string", par_1, par_2, ... ); 2) $strobe ("format_string", par_1, par_2, ... ); 3) $monitor ("format_string", par_1, par_2, ... ); 4) $displayb (as above but defaults to binary..); 5) $strobeh (as above but defaults to hex..); 6) $monitoro (as above but defaults to octal..); 61
    • Simulation - $time, $stime, $realtime These return the current simulation time as a 64-bit integer, a 32-bit integer, and a real number, respectively 62
    • Simulation - $reset, $stop, $finish $reset resets the simulation back to time 0; $stop halts the simulator and puts it in interactive mode where the user can enter commands; $finish exits the simulator back to the operating system. 63
    • Simulation - $scope, $showscope $scope(hierarchy_name) sets the current hierarchical scope to hierarchy_name. $showscopes(n) lists all modules, tasks and block names in (and below, if n is set to 1) the current scope. 64
    • Simulation - $random $random generates a random integer every time it is called. If the sequence is to be repeatable, the first time one invokes random giving it a numerical argument (a seed). Otherwise the seed is derived from the computer clock. 65
    • Simulation - $dumpfile, $dumpvar, $dumpon,$dumpoff, $dumpall These can dump variable changes to a simulation viewer like Debussy. The dump files are capable of dumping all the variables in a simulation. This is convenient for debugging, but can be very slow 語法 1) $dumpfile("filename.vcd") 2) $dumpvar dumps all variables in the design. 3) $dumpvar(1, top) dumps all the variables in module top and below, but not modules instantiated in top. 4) $dumpvar(2, top) dumps all the variables in module top and 1 level below. 5) $dumpvar(n, top) dumps all the variables in module top and n-1 levels below. 6) $dumpvar(0, top) dumps all the variables in module top and all level below. 7) $dumpon initiates the dump. 8) $dumpoff stop dumping. 66
    • Simulation - $fopen, $fdisplay, $fstrobe $fmonitor and$fwrite These commands write more selectively to files. $fopen opens an output file and gives the open file a handle for use by the other commands. $fclose closes the file and lets other programs access it. $fdisplay and $fwrite write formatted data to a file whenever they are executed. They are the same except $fdisplay inserts a new line after every execution and $write does not. $strobe also writes to a file when executed, but it waits until all other operations in the time step are complete before writing. Thus initial #1 a=1; b=0; $fstrobe(hand1, a,b); b=1; will write write 1 1 for a and b. $monitor writes to a file whenever any of its arguments changes. 語法 1) handle1=$fopen("filenam1.suffix") 2) handle2=$fopen("filenam2.suffix") 3) $fstrobe(handle1, format, variable list) //strobe data into filenam1.suffix 4) $fdisplay(handle2, format, variable list) //write data into filenam2.suffix 5) $fwrite(handle2, format, variable list) //write data into filenam2.suffix all on one line. Put in the format string where a new line is desired 67
    • Parameterized Modules Parameter 是 verilog 提供給 module 修改 design 的參數設定 必須提供 default value, 透過 defparam 來 重新設定 default value. 重新設定 default value 的動作稱作 parameter overriding. 68
    • Parameterized Modulesmodule defparam_example(a,b,ci,sum1,sum2,co1,co2); module my_adder(a,b,ci,sum,co); input a,b,ci; parameter citakeCare = 1; output sum1,sum2,co1,co2; input a,b,ci; output sum,co; defparam half_adder.citakeCare = 0; wire sum,co,ci_t; defparam full_adder.citakeCare = 1; assign ci_t = (citakeCare==0) ? 1b0 : ci; assign sum = a ^ b ^ ci_t; my_adder half_adder(.a(a),.b(b),.ci(ci),.sum(sum1),.co(co1)); assign co = ({a,b,ci_t}==3b000) ? 1b0 : my_adder full_adder(.a(a),.b(b),.ci(ci),.sum(sum2),.co(co2)); ({a,b,ci_t}==3b001) ? 1b0 : ({a,b,ci_t}==3b010) ? 1b0 :endmodule ({a,b,ci_t}==3b100) ? 1b0 : 1b1; endmodule sum1 co1 a b ci sum2 co2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 69
    • Parameterized Modulesmodule defparam_example(a,b,ci,sum1,sum2,co1,co2); input a,b,ci; output sum1,sum2,co1,co2; my_adder #(. citakeCare (0)) half_adder(.a(a),.b(b),.ci(ci),.sum(sum1),.co(co1)); my_adder #(. citakeCare (1)) full_adder (.a(a),.b(b),.ci(ci),.sum(sum2),.co(co2));endmodule 70
    • Finite State Machine (FSM) One-Hot FSM Binary (Highly Encoded) FSM
    • FSM Block Diagram
    • Binary FSM
    • One-Hot FSM
    • Two Always Black FSM Style(Good Style) 1/2module fsm(state,delay,done,req,clk,rstn); !rstn !req output state; __idle input delay,done,req,clk,rstn; state = 0 reg state; !req req !done parameter [1:0] __idle = 2b00, req __busy = 2b01, __wait = 2b10, __free __busy __free = 2b11; state = 0 state = 1 done&&!delay reg [1:0]fsmC,fsmN; !delay done&&delayalways @(posedge clk or negedge rstn) begin __wait if(!rstn) fsmC[1:0] <= __idle; state = 1 else fsmC[1:0] <= fsmN[1:0]; end sequential state register delay
    • Two Always Black FSM Style(Good Style) 2/2always @(fsmC or delay or done or req) begin !rstn !req fsmN[1:0] = 2’bxx; state = 1’b0; case(fsmC[1:0]) __idle __idle: begin if(req) fsmN[1:0] = __busy; state = 0 else fsmN[1:0] = __idle; end !req req !done __busy: begin if(!done) fsmN[1:0] = __busy; req else if(delay) fsmN[1:0] = __wait; else fsmN[1:0] = __free; state = 1b1; __free __busy end state = 0 state = 1 __wait: begin done&&!delay if(delay) fsmN[1:0] = __wait; else fsmN[1:0] = __free; state = 1b1; end !delay done&&delay __free: begin if(req) fsmN[1:0] = __busy; __wait else fsmN[1:0] = __idle; end state = 1 endcase end combinational next-stateendmodule combinational output logic delay
    • Important Coding Style Notes 通常 Verilog 是用“ parameters” 來定義 state encodings. 宣告一個 current state 以及一個 next state 在 sequential always block 的通常使用 nonblocking 的 coding 法 在 combinational always block 裡則是用 blocking 的 coding 法 next state 是在 combinational always block 裡做處理 , 在最開始時會給一個 default-X Default output 是在 “ case” 之前給定值 , 然後才在要改 變輸出的那個 case 時改變 output 在 combinational always block 判斷時是使用 “ if”, “else- if” 或者 “ else” 來判斷輸換狀態 .
    • One Always Block FSM Style (avoid!!) module fsm_1(state,delay,done,req,clk,rstn); output state; input delay,done,req,clk,rstn; parameter [1:0] __idle = 2d0, __busy = 2d1, __wait = 2d2, __free = 2d3; !rstn !req reg state; reg [1:0]fsm; always @(posedge clk or negedge rstn) if(!rstn) begin fsm[1:0] <= __idle; __idle end state <= 1b0; state = 0 else begin fsm[1:0] <= 2bx; state <= 1b0; !req req !done case(fsm[1:0]) __idle : if(req) begin fsm[1:0] <= __busy; state <= 1b1; req end else fsm[1:0] <= __idle; __busy: if(!done) begin __free __busy fsm[1:0] <= __busy; state <= 1b1; state = 0 state = 1 end else if(delay) begin done&&!delay fsm[1:0] <= __wait; state <= 1b1; end else fsm[1:0] <= __free; __wait: if(delay) begin fsm[1:0] <= __wait; !delay done&&delay state <= 1b1; __wait end else fsm[1:0] <= __free; __free: if(req) begin fsm[1:0] <= __busy; state <= 1b1; state = 1 end else fsm[1:0] <= __idle; endcase end end endmodule delay
    • One-hot FSM (Good Style) 1/2module fsm_onehot(state,delay,done,req,clk,rstn); !rstn !req output state; input delay,done,req,clk,rstn; __idle parameter [3:0] __idle = 0, Index not State Encoding state = 0 __busy = 1, __wait = 2, !req req !done __free = 3; req reg [3:0]fsmC,fsmN; reg state; __free __busy state = 0 state = 1 always @(posedge clk or negedge rstn) done&&!delay begin if(!rstn) begin fsmC[3:0] <= 4d0; !delay done&&delay fsmC[__idle] <= 1b1; end __wait else fsmC[3:0] <= fsmN[3:0]; state = 1 end delay
    • One-hot FSM (Good Style) 2/2always @(fsmC or delay or done or req) begin fsmN[3:0] = 4d0; state = 1b0; !rstn !req case(1b1) fsmC[__idle]: begin __idle if(req) fsmN[__busy] = 1b1; else fsmN[__idle] = 1b1; state = 0 end fsmC[__busy]: begin !req req !done if(!done) fsmN[__busy] = 1b1; else if(delay) fsmN[__wait] = 1b1; req else fsmN[__free] = 1b1; state = 1b1; end __free __busy fsmC[__wait]: begin state = 0 state = 1 if(delay) fsmN[__wait] = 1b1; done&&!delay else fsmN[__free] = 1b1; state = 1b1; end fsmC[__free]: begin !delay done&&delay if(req) fsmN[__busy] = 1b1; else fsmN[__idle] = 1b1; __wait end end state = 1 endendmodule delay
    • 練習 !rstn !go go & !jmp S0 S9 !jmp S1 !jmp !jmp y=0 y=1 y=0 go & jmpS8 jmp S2 jmp jmpy=0 y=0 !jmp jmpS7 S3 jmpy=0 jmp y=1 jmp jmp !jmp S6 S4 !jmp S5 y=0 !jmp y=0 !jmp y=0
    • Compiler Directives `include `define `undef `ifdef `timescale `resetall `defaultnettype `nounconnected_drive / `unconnected_drive 82
    • `include