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;
always@(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

always@(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,高电平有效

猜你喜欢

转载自blog.csdn.net/qq_43747091/article/details/86305662