1. 程式人生 > >Verilog例子整理(轉載)

Verilog例子整理(轉載)

               

【例5.6 】用fork-join 並行塊產生訊號波形

`timescale 10ns/1ns 
module wave2; 
reg wave; 
parameter cycle=5; 
initial

fork

wave=0;
#(cycle) wave=1;
#(2*cycle) wave=0;
#(3*cycle) wave=1;
#(4*cycle) wave=0;
#(5*cycle) wave=1;
#(6*cycle) $finish;


join 
initial $monitor($time,,,"wave=%b",wave); 
endmodule

【例5.7 】持續賦值方式定義的2 選1 多路選擇器

module MUX21_1(out,a,b,sel);
input a,b,sel;
output out;
assign out=(sel==0)?a:b;


//持續賦值,如果sel為0,則out=a ;否則out=b

endmodule

【例5.8 】阻塞賦值方式定義的2 選1 多路選擇器

module MUX21_2(out,a,b,sel); 
input a,b,sel; 
output out;
reg out;

[email protected](a or b or sel)


begin 
if(sel==0) out=a; //阻塞賦值
else out=b;


end
endmodule
【例5.2 】同步置數、同步清零的計數器

module count(out,data,load,reset,clk);
output[7:0] out;
input[7:0] data;
input load,clk,reset;
reg[7:0] out;
always @(posedge clk) //clk 上升沿觸發


begin
if (!reset) out = 8'h00; //同步清0,低電平有效
else if (load) out = data; //同步預置
else out = out + 1; //計數
end

 

endmodule

【例5.9 】非阻塞賦值

module non_block(c,b,a,clk);
output c,b; 
input clk,a;
reg c,b;
always @(posedge clk)


begin

b<=a;
c<=b;


end
endmodule


【例5.10 】阻塞賦值

module block(c,b,a,clk);
output c,b;
input clk,a;
reg c,b;
always @(posedge clk)


begin

b=a;
c=b;


end
endmodule


【例5.15 】用for 語句描述的七人投票表決器

module voter7(pass,vote);
output pass;
input[6:0] vote;
reg[2:0] sum;
integer i;
reg pass;
always @(vote)


begin

sum=0;

for(i=0;i<=6;i=i+1) //for語句
if(vote[i]) sum=sum+1;
if(sum[2]) pass=1; //若超過4人贊成,則pass=1
else pass=0;


 end 
endmodule

【例6.2 】任務舉例

module alutask(code,a,b,c);
input[1:0] code;
input[3:0] a,b;
output[4:0] c;
reg[4:0] c;


task my_and; //任務定義,注意無埠列表
input[3:0] a,b; //a,b,out 名稱的作用域範圍為task任務內部
output[4:0] out;
integer i;


begin 
for(i=3;i>=0;i=i-1) 
out[i]=a[i]&b[i]; //按位與

end 
endtask

[email protected](code or a or b) 
begin 
case(code)

2'b00: my_and(a,b,c); 
/*呼叫任務my_and,需注意埠列表的順序應與任務定義中的一致,這裡的a,b,c

分別對應任務定義中的a,b,out */ 
2'b01: c=a|b; //或
2'b10: c=a-b; //相減
2'b11: c=a+b; //相加

endcase 
end 
endmodule

【例6.3 】測試程式

`include "alutask.v" 
module alu_tp; 
reg[3:0] a,b; 
reg[1:0] code; 
wire[4:0] c; 
parameter DELY = 100;

alutask ADD(code,a,b,c); //呼叫被測試模組

initial begin

code=4'd0; a= 4'b0000; b= 4'b1111; 
#DELY code=4'd0; a= 4'b0111; b= 4'b1101; 
#DELY code=4'd1; a= 4'b0001; b= 4'b0011; 
#DELY code=4'd2; a= 4'b1001; b= 4'b0011; 
#DELY code=4'd3; a= 4'b0011; b= 4'b0001; 
#DELY code=4'd3; a= 4'b0111; b= 4'b1001; 
#DELY $finish; 
end 
initial $monitor($time,,,"code=%b a=%b b=%b c=%b", code,a,b,c); 
endmodule

【例6.4 】函式

function[7:0] get0; 
input[7:0] x; 
reg[7:0] count; 
integer i;

begin

count=0;

for (i=0;i<=7;i=i+1)

if (x[i]=1'b0) count=count+1;

get0=count;

end 
endfunction
【例6.5 】用函式和case 語句描述的編碼器(不含優先順序)

module code_83(din,dout); 
input[7:0] din; 
output[2:0] dout;


function[2:0] code; //函式定義

input[7:0] din; //函式只有輸入,輸出為函式名本身

casex (din)
8'b1xxx_xxxx : code = 3'h7;
8'b01xx_xxxx : code = 3'h6;
8'b001x_xxxx : code = 3'h5;
8'b0001_xxxx : code = 3'h4;
8'b0000_1xxx : code = 3'h3;
8'b0000_01xx : code = 3'h2;
8'b0000_001x : code = 3'h1;
8'b0000_000x : code = 3'h0;
default: code = 3'hx;
endcase


endfunction

assign dout = code(din) ; //函式呼叫

endmodule

【例6.6 】階乘運算函式

module funct(clk,n,result,reset);
output[31:0] result;
input[3:0] n;
input reset,clk;
reg[31:0] result;
always @(posedge clk) //在clk的上升沿時執行運算


begin
if(!reset) result<=0; //復位
else begin


result <= 2 * factorial(n); // 呼叫factorial函式

end
end


function[31:0] factorial; //階乘運算函式定義(注意無埠列表)
input[3:0] opa; //函式只能定義輸入端,輸出埠為函式名本身
reg[3:0] i;

begin

factorial = opa ? 1 : 0; 
for(i= 2; i <= opa; i = i+1) //該句若要綜合通過,opa應賦具體的數值
factorial = i* factorial; //階乘運算

end


endfunction 
endmodule

【例6.7 】測試程式

`define clk_cycle 50 
`include "funct.v" 
module funct_tp; 
reg[3:0] n; 
reg reset,clk; 
wire[31:0] result;

initial //定義激勵向量
begin


n=0; reset=1; clk=0;
for(n=0;n<=15;n=n+1)
#100 n=n;


end

initial $monitor($time,,,"n=%d result=%d",n,result); 
//定義輸出顯示格式
always # `clk_cycle clk=~clk; //產生時鐘訊號

funct funct_try(.clk(clk),.n(n),.result(result),.reset(reset)); 
//呼叫被測試模組

endmodule


【例6.8 】順序執行模組1

module serial1(q,a,clk);
output q,a;
input clk;
reg q,a;
always @(posedge clk)


begin
q=~q;
a=~q;
end


endmodule

【例6.9 】順序執行模組2

module serial2(q,a,clk); 
output q,a;

input clk;
reg q,a;
always @(posedge clk)


begin

a=~q;

q=~q;

end 
endmodule

【例6.10 】並行執行模組1

module paral1(q,a,clk);
output q,a;
input clk;
reg q,a;
always @(posedge clk)


begin

q=~q;

end 
always @(posedge clk)

begin

a=~q;

end 
endmodule

【例6.11 】並行執行模組2

module paral2(q,a,clk);
output q,a;
input clk;
reg q,a;
always @(posedge clk)


begin

a=~q;

end 
always @(posedge clk)

begin

q=~q;

end 
endmodule

【例7.3 】行為描述方式實現的4 位計數器

module count4(clk,clr,out);
input clk,clr;
output[3:0] out;
reg[3:0] out;
always @(posedge clk or posedge clr)


begin
if (clr) out<=0;
else out<=out+1;
end


endmodule

【例7.6 】門級結構描述的2 選1MUX

module mux2_1a(out,a,b,sel);
output out;
input a,b,sel;
not (sel_,sel);
and (a1,a,sel_),


(a2,b,sel); 
or (out,a1,a2); 
endmodule

【例7.7 】行為描述的2 選1MUX

module mux2_1b(out,a,b,sel);
output out;
input a,b,sel;
reg out;
always @(a or b or sel)


begin 
if(sel) out = b; 
else out = a; 
end 
endmodule

【例7.8 】資料流描述的2 選1MUX

module MUX2_1c(out,a,b,sel); 
output out;


input a,b,sel; 
assign out = sel ? b : a; 
endmodule

【例7.9 】呼叫門元件實現的1 位半加器

module half_add1(a,b,sum,cout);
input a,b;
output sum,cout;
and (cout,a,b);
xor (sum,a,b);
endmodule


【例7.10 】資料流方式描述的1 位半加器

module half_add2(a,b,sum,cout);
input a,b;
output sum,cout;
assign sum=a^b;
assign cout=a&b;
endmodule


【例7.11 】採用行為描述的1 位半加器

module half_add3(a,b,sum,cout);
input a,b;
output sum,cout;
reg sum,cout;
always @(a or b)


begin
case ({a,b}) //真值表描述
2'b00: begin sum=0; cout=0; end
2'b01: begin sum=1; cout=0; end
2'b10: begin sum=1; cout=0; end
2'b11: begin sum=0; cout=1; end
endcase


end 
endmodule

【例7.12 】採用行為描述的1 位半加器

module half_add4(a,b,sum,cout);
input a,b;
output sum,cout;


reg sum,cout;
always @(a or b)
begin


sum= a^b;

cout=a&b;

end
endmodule


【例7.13 】呼叫門元件實現的1 位全加器

module full_add1(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
wire s1,m1,m2,m3;
and (m1,a,b),


(m2,b,cin),
(m3,a,cin);
xor (s1,a,b),


(sum,s1,cin);
or (cout,m1,m2,m3);
endmodule


【例7.14 】資料流描述的1 位全加器

module full_add2(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
assign sum = a ^ b ^ cin;
assign cout = (a & b)|(b & cin)|(cin & a);
endmodule


【例7.15 】1 位全加器

module full_add3(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
assign {cout,sum}=a+b+cin;
endmodule


【例7.16 】行為描述的1 位全加器

module full_add4(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;


reg sum,cout; //在always塊中被賦值的變數應定義為reg型
reg m1,m2,m3;
always @(a or b or cin)


begin

sum = (a ^ b) ^ cin;

m1 = a & b;

m2 = b & cin;

m3 = a & cin;

cout = (m1|m2)|m3;

end
endmodule


【例7.17 】混合描述的1 位全加器

module full_add5(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
reg cout,m1,m2,m3; //在always塊中被賦值的變數應定義為reg型
wire s1;
xor x1(s1,a,b); //呼叫門元件
always @(a or b or cin) //always 塊語句


begin

m1 = a & b;

m2 = b & cin;

m3 = a & cin;

cout = (m1| m2) | m3;

end

assign sum = s1 ^ cin; //assign 持續賦值語句

endmodule

【例7.18 】結構描述的4 位級連全加器

`include "full_add1.v"
module add4_1(sum,cout,a,b,cin);
output[3:0] sum;
output cout;
input[3:0] a,b;
input cin;


full_add1 f0(a[0],b[0],cin,sum[0],cin1); //級連描述
full_add1 f1(a[1],b[1],cin1,sum[1],cin2);
full_add1 f2(a[2],b[2],cin2,sum[2],cin3);

 

full_add1 f3(a[3],b[3],cin3,sum[3],cout);

endmodule

【例7.19 】資料流描述的4 位全加器

module add4_2(cout,sum,a,b,cin);
output[3:0] sum;
output cout;
input[3:0] a,b;
input cin;
assign {cout,sum}=a+b+cin;
endmodule


【例7.20 】行為描述的4 位全加器

module add4_3(cout,sum,a,b,cin);
output[3:0] sum;
output cout;
input[3:0] a,b;
input cin;
reg[3:0] sum;
reg cout;
always @(a or b or cin)
begin


{cout,sum}=a+b+cin;

end
endmodule


【例8.2】$random 函式的使用

`timescale 10ns/1ns

module random_tp;

integer data;

integer i;

parameter delay=10;

initial $monitor($time,,,"data=%b",data);

initial begin

for(i=0; i<=100; i=i+1)

#delay data=$random; //每次產生一個隨機數

end
endmodule

primitive carry_udp(cout,cin,a,b);
input cin,a,b;
output cout;


table

//cin a b : cout //真值表

0 0 0 : 0; 
0 1 0 : 0; 
0 0 1 : 0; 
0 1 1 : 1; 
1 0 0 : 0; 
1 0 1 : 1; 
1 1 0 : 1; 
1 1 1 : 1; 
endtable

endprimitive

【例8.15 】用always 過程塊產生兩個時鐘訊號

module test2; 
reg clk1,clk2; 
parameter CYCLE = 100; 
always

begin

{clk1,clk2} = 2'b10;
#(CYCLE/4) {clk1,clk2} = 2'b01;
#(CYCLE/4) {clk1,clk2} = 2'b11;
#(CYCLE/4) {clk1,clk2} = 2'b00;
#(CYCLE/4) {clk1,clk2} = 2'b10;


end 
initial $monitor($time,,,"clk1=%b clk2=%b",clk1,clk2); 
endmodule


【例9.1 】基本閘電路的幾種描述方法

(1)門級結構描述
module gate1(F,A,B,C,D);
input A,B,C,D;
output F;
nand(F1,A,B); //呼叫門元件
and(F2,B,C,D);
or(F,F1,F2);
endmodule


(2)資料流描述
module gate2(F,A,B,C,D);
input A,B,C,D;
output F;
assign F=(A&B)|(B&C&D); //assign 持續賦值
endmodule


(3)行為描述
module gate3(F,A,B,C,D); 
input A,B,C,D; 
output F;

reg F;
always @(A or B or C or D) //過程賦值
begin


F=(A&B)|(B&C&D);

end
endmodule
【例9.2 】用bufif1 關鍵字描述的三態門

module tri_1(in,en,out);
input in,en;
output out;
tri out;
bufif1 b1(out,in,en); //注意三態門埠的排列順序
endmodule


【例9.3 】用assign 語句描述的三態門

module tri_2(out,in,en);
output out;
input in,en;
assign out = en ? in : 'bz;


//若en=1,則out=in;若en=0,則out為高阻態

endmodule

【例9.4 】三態雙向驅動器

module bidir(tri_inout,out,in,en,b);
inout tri_inout;
output out;
input in,en,b;
assign tri_inout = en ? in : 'bz;
assign out = tri_inout ^ b;
endmodule


【例9.5 】三態雙向驅動器

module bidir2(bidir,en,clk);
inout[7:0] bidir;
input en,clk;
reg[7:0] temp;
assign bidir= en ? temp : 8'bz;
always @(posedge clk)


begin

if(en) temp=bidir; 
else temp=temp+1; 
end 
endmodule

【例9.6 】3-8 譯碼器

module decoder_38(out,in);
output[7:0] out;
input[2:0] in;
reg[7:0] out;
always @(in)


begin

case(in)
3'd0: out=8'b11111110;
3'd1: out=8'b11111101;
3'd2: out=8'b11111011;
3'd3: out=8'b11110111;
3'd4: out=8'b11101111;
3'd5: out=8'b11011111;
3'd6: out=8'b10111111;
3'd7: out=8'b01111111;


endcase 
end 
endmodule

【例9.7 】8-3 優先編碼器

module encoder8_3(none_on,outcode,a,b,c,d,e,f,g,h);
output none_on;
output[2:0] outcode;
input a,b,c,d,e,f,g,h;
reg[3:0] outtemp;
assign {none_on,outcode}=outtemp;
always @(a or b or c or d or e or f or g or h)


begin
if(h) outtemp=4'b0111;
else if(g) outtemp=4'b0110;
else if(f) outtemp=4'b0101;
else if(e) outtemp=4'b0100;
else if(d) outtemp=4'b0011;
else if(c) outtemp=4'b0010;
else if(b) outtemp=4'b0001;
else if(a) outtemp=4'b0000; 
else outtemp=4'b1000;


end
endmodule


【例9.8 】用函式定義的8-3 優先編碼器

module code_83(din, dout);
input[7:0] din;
output[2:0] dout;


function[2:0] code; //函式定義
input[7:0] din; //函式只有輸入埠,輸出為函式名本身
if (din[7]) code = 3'd7;
else if (din[6]) code = 3'd6;
else if (din[5]) code = 3'd5;
else if (din[4]) code = 3'd4;
else if (din[3]) code = 3'd3;
else if (din[2]) code = 3'd2;
else if (din[1]) code = 3'd1;
else code = 3'd0;
endfunction


assign dout = code(din); //函式呼叫
endmodule
【例9.10 】奇偶校驗位產生器

module parity(even_bit,odd_bit,input_bus);
output even_bit,odd_bit;
input[7:0] input_bus;
assign odd_bit = ^ input_bus; //產生奇校驗位
assign even_bit = ~odd_bit; //產生偶校驗位
endmodule


【例9.11 】用if-else 語句描述的4 選1 MUX

module mux_if(out,in0,in1,in2,in3,sel);
output out;
input in0,in1,in2,in3;
input[1:0] sel;
reg out;
always @(in0 or in1 or in2 or in3 or sel)


begin
if(sel==2'b00) out=in0;
else if(sel==2'b01) out=in1;
else if(sel==2'b10) out=in2;
else out=in3;


end 
endmodule

【例9.12 】用case 語句描述的4 選1 MUX

module mux_case(out,in0,in1,in2,in3,sel);
output out;
input in0,in1,in2,in3;
input[1:0] sel;
reg 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; 
default: out=in3;

endcase 
end
endmodule

【例9.13 】用組合電路實現的ROM

module rom(addr,data);
input[3:0] addr;
output[7:0] data;


function[7:0] romout;
input[3:0] addr;
case(addr)


0 : romout = 0; 
1 : romout = 1; 
2 : romout = 4; 
3 : romout = 9; 
4 : romout = 16; 
5 : romout = 25; 
6 : romout = 36; 
7 : romout = 49; 
8 : romout = 64; 
9 : romout = 81; 
10 : romout = 100; 
11 : romout = 121; 
12 : romout = 144; 
13 : romout = 169; 
14 : romout = 196; 
15 : romout = 225; 
default : romout = 8'hxx; 
endcase 
endfunction 
assign data = romout(addr); 
endmodule

【例9.14 】基本D 觸發器

module DFF(Q,D,CLK);
output Q;
input D,CLK;
reg Q;
always @(posedge CLK)


begin

Q <= D;

end 
endmodule

【例9.15 】帶非同步清0、非同步置1 的D 觸發器

module DFF1(q,qn,d,clk,set,reset);
input d,clk,set,reset;
output q,qn;
reg q,qn;
always @(posedge clk or negedge set or negedge reset)


begin

if (!reset) begin
q <= 0; //非同步清0,低電平有效
qn <= 1;


end
else if (!set) begin
q <= 1; //非同步置1,低電平有效
qn <= 0;


end
else begin


q <= d;
qn <= ~d;


end 
end 
endmodule

【例9.16 】帶同步清0、同步置1 的D 觸發器

module DFF2(q,qn,d,clk,set,reset);
input d,clk,set,reset;
output q,qn;
reg q,qn;
always @(posedge clk)


begin
if (reset) begin

q <= 0;qn <= 1; //同步清0,高電平有效