王金明:《VerilogHDL程序设计教程》
王金明:《Verilog HDL 程序设计教程》 - 1 -
【例3.1】4 位全加器
module adder4cout,sum,ina,inb,cin;
output[3:0] sum;
output cout;
input[3:0] ina,inb;
input cin;
assign cout,sumina+inb+cin; endmodule
【例3.2】4 位计数器
module count4out,reset,clk; output[3:0] out;
input reset,clk;
reg[3:0] out;
always @posedge clk
begin
if reset out0; //同步复位
else outout+1; //计数
end
endmodule
【例3.3】4 位全加器的仿真程序
`timescale 1ns/1ns `include "adder4.v" module adder_tp; //测试模块的名字 reg[3:0] a,b; //测试输入信号定义为reg 型 reg cin;
wire[3:0] sum; //测试输出信号定义为wire 型 wire cout;
integer i,j;
adder4 addersum,cout,a,b,cin; //调用测试对象 always #5 cin~cin; //设定cin 的取值 initial
begin
a0;b0;cin0;
fori1;i16;ii+1
#10 ai; //设定a 的取值
end
程序文本
- 2 -
initial
begin
forj1;j16;jj+1
#10 bj; //设定b 的取值
end
initial //定义结果显示格式
begin
$monitor$time,,,"%d + %d + %b%b,%d",a,b,cin,cout,sum;
#160 $finish;
end
endmodule
【例3.4】4 位计数器的仿真程序
`timescale 1ns/1ns `include "count4.v" module coun4_tp;
reg clk,reset; //测试输入信号定义为reg 型 wire[3:0] out; //测试输出信号定义为wire 型 parameter DELY100; count4 mycountout,reset,clk; //调用测试对象 always #DELY/2 clk ~clk; //产生时钟波形 initial
begin //激励信号定义
clk 0; reset0;
#DELY reset1;
#DELY reset0;
#DELY*20 $finish;
end
//定义结果显示格式
initial $monitor$time,,,"clk%d reset%d out%d", clk, reset,out;
endmodule
【例3.5】“与-或-非”门电路
module AOIA,B,C,D,F; //模块名为AOI端口列
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
A,B,C,D,F input A,B,C,D; //模块的输入端口为A,B,C,D output F; //模块的输出端口为F
王金明:《Verilog HDL 程序设计教程》
- 3 -
wire A,B,C,D,F; //定义信号的数据类型
assign F ~A&B|C&D; //逻辑功能描述
endmodule
【例5.1】用case 语句描述的4 选1 数据选择器 module mux4_1out,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 //敏感信号列表 casesel
2'b00: outin0;
2'b01: outin1;
2'b10: outin2;
2'b11: outin3;
default: out2'bx; endcase
endmodule
【例5.2】同步置数、同步清零的计数器 module countout,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.3】用always 过程语句描述的简单算术逻辑单元 `define add 3'd0
`define minus 3'd1 `define band 3'd2 `define bor 3'd3 `define bnot 3'd4 程序文本
- 4 -
module aluout,opcode,a,b;
output[7:0] out; reg[7:0] out;
input[2:0] opcode; //操作码
input[7:0] a,b; //操作数
always@opcode or a or b //电平敏感的always 块
begin
caseopcode
`add: out a+b; //加操作
`minus: out a-b; //减操作
`band: out a&b; //求与
`bor: out a|b; //求或
`bnot: out~a; //求反
default: out8'hx; //未收到指令时,输出任意态 endcase
end
endmodule
【例5.4】用initial 过程语句对测试变量A、B、C 赋值
`timescale 1ns/1ns module test;
reg A,B,C;
initial
begin
A 0; B 1; C 0; #50 A 1; B 0; #50 A 0; C 1; #50 B 1;
#50 B 0; C 0; #50 $finish ;
end
endmodule
【例5.5】用begin-end 串行块产生信号波形 `timescale 10ns/1ns module wave1;
reg wave;
parameter cycle10; initial
begin
王金明:《Verilog HDL 程序设计教程》 - 5 -
wave0;
#cycle/2 wave1; #cycle/2 wave0; #cycle/2 wave1; #cycle/2 wave0; #cycle/2 wave1; #cycle/2 $finish ; end
initial $monitor$time,,,"wave%b",wave;
endmodule
【例5.6】用fork-join 并行块产生信号波形 `timescale 10ns/1ns module wave2;
reg wave;
parameter cycle5; initial
fork
wave0;
#cycle wave1;
#2*cycle wave0;
#3*cycle wave1;
#4*cycle wave0;
#5*cycle wave1;
#6*cycle $finish;
join
initial $monitor$time,,,"wave%b",wave;
endmodule
【例5.7】持续赋值方式定义的2 选1 多路选择器 module MUX21_1out,a,b,sel; input a,b,sel;
output out;
assign outsel0?a:b; //持续赋值,如果sel 为0,则outa ;否则outb endmodule
【例5.8】阻塞赋值方式定义的2 选1 多路选择器 module MUX21_2out,a,b,sel; input a,b,sel;
程序文本
- 6 -
output out;
reg out;
always@a or b or sel
begin
ifsel0 outa; //阻塞赋值
else outb;
end
endmodule
【例5.9】非阻塞赋值
module non_blockc,b,a,clk;
output c,b;
input clk,a;
reg c,b;
always @posedge clk begin
ba;
cb;
end
endmodule
【例5.10】阻塞赋值
module blockc,b,a,clk; output c,b;
input clk,a;
reg c,b;
always @posedge clk
begin
ba;
cb;
end
endmodule
【例5.11】模为60 的BCD 码加法计数器 module count60qout,cout,data,load,cin,reset,clk;
output[7:0] qout; output cout;
input[7:0] data; input load,cin,clk,reset;
reg[7:0] qout;
always @posedge clk //clk 上升沿时刻计数 王金明:《Verilog HDL 程序设计教程》 - 7 -
begin
if reset qout0; //同步复位
else ifload qoutdata; //同步置数 else ifcin
begin
ifqout[3:0]9 //低位是否为9,是则 begin
qout[3:0]0; //回0,并判断高位是否为5
if qout[7:4]5 qout[7:4]0; else
qout[7:4]qout[7:4]+1; //高位不为5,则加1 end
else //低位不为9,则加1
qout[3:0]qout[3:0]+1; end
end
assign coutqout8'h59&cin?1:0; //产生进位输出信号 endmodule
【例5.12】BCD 码?七段数码管显示译码器
module decode4_7decodeout,indec;
output[6:0] decodeout; input[3:0] indec;
reg[6:0] decodeout;
always @indec
begin
caseindec //用case 语句进行译码
4'd0:decodeout7'b1111110; 4'd1:decodeout7'b0110000; 4'd2:decodeout7'b1101101;
4'd3:decodeout7'b1111001; 4'd4:decodeout7'b0110011; 4'd5:decodeout7'b1011011; 4'd6:decodeout7'b1011111; 4'd7:decodeout7'b1110000; 4'd8:decodeout7'b1111111; 4'd9:decodeout7'b1111011; default: decodeout7'bx; endcase
end
程序文本
- 8 -
endmodule
【例5.13】用casez 描述的数据选择器
module mux_casezout,a,b,c,d,select;
output out;
input a,b,c,d;
input[3:0] select;
reg out;
always @select or a or b or c or d
begin
casezselect
4'b1: out a; 4'b??1?: out b; 4'b?1??: out c; 4'b1: out d; endcase
end
endmodule
【例5.14】隐含锁存器举例
module buried_ffc,b,a;
output c;
input b,a;
reg c;
always @a or b begin
ifb1&&a1 ca&b; end
endmodule
【例5.15】用for 语句描述的七人投票表决器
module voter7pass,vote;
output pass;
input[6:0] vote; reg[2:0] sum;
integer i;
reg pass;
always @vote
begin
sum0;
王金明:《Verilog HDL 程序设计教程》 - 9 -
fori0;i6;ii+1 //for 语句
ifvote[i] sumsum+1; ifsum[2] pass1; //若超过4 人赞成,则pass1 else pass0;
end
endmodule
【例5.16】用for 语句实现2 个8 位数相乘 module mult_foroutcome,a,b;
parameter size8; input[size:1] a,b; //两个操作数
output[2*size:1] outcome; //结果 reg[2*size:1] outcome; integer i;
always @a or b
begin
outcome0;
fori1; isize; ii+1 //for 语句
ifb[i] outcomeoutcome +a i-1; end
endmodule
【例5.17】用repeat 实现8 位二进制数的乘法
module mult_repeatoutcome,a,b; parameter size8;
input[size:1] a,b;
output[2*size:1] outcome; reg[2*size:1] temp_a,outcome; reg[size:1] temp_b;
always @a or b
begin
outcome0;
temp_aa;
temp_bb;
repeatsize //repeat 语句,size 为循环次数
begin
iftemp_b[1] //如果temp_b 的最低位为1,就执行下面的加法 outcomeoutcome+temp_a; temp_atemp_a1; //操作数a 左移一位
程序文本
- 10 -
temp_btemp_b1; //操作数b 右移一位
end
end
endmodule
【例5.18】同一循环的不同实现方式
module loop1; //方式1 integer i;
initial
fori0;i4;ii+1 //for 语句 begin
$display“i%h”,i;
end
endmodule
module loop2; //方式2 integer i;
initial begin i0;
whilei4 //while 语句
begin
$display "i%h",i;
ii+1;
end
end
endmodule
module loop3; //方式3
integer i;
initial begin
i0;
repeat4 //repeat 语句
begin
$display "i%h",i; ii+1;
end
end
endmodule
【例5.19】使用了`include 语句的16 位加法器 王金明:《Verilog HDL 程序设计教程》 - 11 -
`include "adder.v" module adder16cout,sum,a,b,cin;
output cout;
parameter my_size16;
output[my_size-1:0] sum; input[my_size-1:0] a,b; input cin;
adder my_addercout,sum,a,b,cin; //调用adder 模块 endmodule
//下面是adder 模块代码
module addercout,sum,a,b,cin;
parameter size16;
output cout;
output[size-1:0] sum; input cin;
input[size-1:0] a,b; assign cout,suma+b+cin; endmodule
【例5.20】条件编译举例
module compileout,A,B; output out;
input A,B;
`ifdef add //宏名为add
assign outA+B;
`else
assign outA-B;
`endif
endmodule
【例6.1】加法计数器中的进程
module countdata,clk,reset,load,cout,qout;
output cout;
output[3:0] qout; reg[3:0] qout;
input[3:0] data;
input clk,reset,load; 程序文本
- 12 -
always @posedge clk //进程1,always 过程块 begin
if !reset qout 4'h00; //同步清0,低电平有效 else if load qout data; //同步预置 else qoutqout + 1; //加法计数
end
assign coutqout4'hf?1:0; //进程2,用持续赋值产生进位信号
endmodule
【例6.2】任务举例
module alutaskcode,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
fori3;i0;ii-1
out[i]a[i]&b[i]; //按位与
end
endtask
always@code or a or b begin
casecode
2'b00: my_anda,b,c; /* 调用任务my_and,需注意端口列表的顺序应与任务定义中的一致,这里
的a,b,c
分别对应任务定义中的a,b,out */ 2'b01: ca|b; //或
2'b10: ca-b; //相减
2'b11: ca+b; //相加
endcase
end
endmodule
王金明:《Verilog HDL 程序设计教程》
- 13 -
【例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 ADDcode,a,b,c; //调用被测试模块
initial begin
code4'd0; a 4'b0000; b 4'b1111; #DELY code4'd0; a 4'b0111; b 4'b1101; #DELY code4'd1; a 4'b0001; b 4'b0011; #DELY code4'd2; a 4'b1001; b 4'b0011; #DELY code4'd3; a 4'b0011; b 4'b0001; #DELY code4'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
count0;
for i0;i7;ii+1
if x[i]1'b0 countcount+1; get0count;
end
endfunction
【例6.5】用函数和case 语句描述的编码器(不含优先顺序) module code_83din,dout; input[7:0] din;
output[2:0] dout;
程序文本
- 14 -
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 codedin ; //函数调用
endmodule
【例6.6】阶乘运算函数
module functclk,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 result0; //复位
else begin
result 2 * factorialn; //调用factorial 函数 end
end
function[31:0] factorial; //阶乘运算函数定义(注意无端口列表)
input[3:0] opa; //函数只能定义输入端,输出端口为函数名本身
reg[3:0] i;
begin
factorial opa1 : 0; fori 2; i opa; i i+1 //该句若要综合通过,opa 应赋具体的数值
factorial i* factorial; //阶乘运算
end
王金明:《Verilog HDL 程序设计教程》
- 15 -
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
n0; reset1; clk0;
forn0;n15;nn+1
#100 nn;
end
initial $monitor$time,,,"n%d result%d",n,result;
//定义输出显示格式
always # `clk_cycle clk~clk; //产生时钟信号 funct funct_try.clkclk,.nn,.resultresult,.resetreset;
//调用被测试模块
endmodule
【例6.8】顺序执行模块1
module serial1q,a,clk; output q,a;
input clk;
reg q,a;
always @posedge clk begin
q~q;
a~q;
end
endmodule
【例6.9】顺序执行模块2
module serial2q,a,clk; output q,a;
程序文本
- 16 -
input clk;
reg q,a;
always @posedge clk begin
a~q;
q~q;
end
endmodule
【例6.10】并行执行模块1
module paral1q,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 paral2q,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.1】调用门元件实现的4 选1 MUX
王金明:《Verilog HDL 程序设计教程》
- 17 -
module mux4_1aout,in1,in2,in3,in4,cntrl1,cntrl2;
output out;
input in1,in2,in3,in4,cntrl1,cntrl2; wire notcntrl1,notcntrl2,w,x,y,z; not notcntrl1,cntrl2,
notcntrl2,cntrl2;
and w,in1,notcntrl1,notcntrl2, x,in2,notcntrl1,cntrl2,
y,in3,cntrl1,notcntrl2,
z,in4,cntrl1,cntrl2;
or out,w,x,y,z;
endmodule
【例7.2】用case 语句描述的4 选1 MUX
module mux4_1bout,in1,in2,in3,in4,cntrl1,cntrl2;
output out;
input in1,in2,in3,in4,cntrl1,cntrl2; reg out;
always@in1 or in2 or in3 or in4 or cntrl1 or cntrl2
casecntrl1,cntrl2
2'b00:outin1;
2'b01:outin2;
2'b10:outin3;
2'b11:outin4;
default:out2'bx;
endcase
endmodule
【例7.3】行为描述方式实现的4 位计数器 module count4clk,clr,out;
input clk,clr;
output[3:0] out;
reg[3:0] out;
always @posedge clk or posedge clr
begin
if clr out0;
else outout+1;
end
endmodule
程序文本
- 18 -
【例7.4】数据流方式描述的4 选1 MUX module mux4_1cout,in1,in2,in3,in4,cntrl1,cntrl2;
output out;
input in1,in2,in3,in4,cntrl1,cntrl2; assign outin1 & ~cntrl1 & ~cntrl2|in2 & ~cntrl1 & cntrl2|
in3 & cntrl1 & ~cntrl2|in4 & cntrl1 & cntrl2; endmodule
【例7.5】用条件运算符描述的4 选1 MUX
module mux4_1dout,in1,in2,in3,in4,cntrl1,cntrl2; output out;
input in1,in2,in3,in4,cntrl1,cntrl2; assign outcntrl1cntrl2in4:in3:cntrl2in2:in1; endmodule
【例7.6】门级结构描述的2 选1MUX
module mux2_1aout,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_1bout,a,b,sel;
output out;
input a,b,sel;
reg out;
always @a or b or sel begin
ifsel out b;
else out a;
end
endmodule
【例7.8】数据流描述的2 选1MUX module MUX2_1cout,a,b,sel;
output out;
王金明:《Verilog HDL 程序设计教程》 - 19 -
input a,b,sel;
assign out selb : a; endmodule
【例7.9】调用门元件实现的1 位半加器 module half_add1a,b,sum,cout;
input a,b;
output sum,cout;
and cout,a,b;
xor sum,a,b;
endmodule
【例7.10】数据流方式描述的1 位半加器
module half_add2a,b,sum,cout; input a,b;
output sum,cout;
assign suma^b;
assign couta&b;
endmodule
【例7.11】采用行为描述的1 位半加器
module half_add3a,b,sum,cout; input a,b;
output sum,cout;
reg sum,cout;
always @a or b
begin
case a,b //真值表描述
2'b00: begin sum0; cout0; end 2'b01: begin sum1; cout0; end 2'b10: begin sum1; cout0; end 2'b11: begin sum0; cout1; end endcase
end
endmodule
【例7.12】采用行为描述的1 位半加器 module half_add4a,b,sum,cout;
input a,b;
output sum,cout; 程序文本
- 20 -
reg sum,cout;
always @a or b begin
sum a^b;
couta&b;
end
endmodule
【例7.13】调用门元件实现的1 位全加器 module full_add1a,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_add2a,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_add3a,b,cin,sum,cout; input a,b,cin;
output sum,cout;
assign cout,suma+b+cin;
endmodule
【例7.16】行为描述的1 位全加器
module full_add4a,b,cin,sum,cout; input a,b,cin;
output sum,cout;
王金明:《Verilog HDL 程序设计教程》 - 21 -
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_add5a,b,cin,sum,cout;
input a,b,cin;
output sum,cout;
reg cout,m1,m2,m3; //在always 块中被赋值的变量应定义为reg 型
wire s1;
xor x1s1,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_1sum,cout,a,b,cin; output[3:0] sum;
output cout;
input[3:0] a,b;
input cin;
full_add1 f0a[0],b[0],cin,sum[0],cin1; //级连描述 full_add1 f1a[1],b[1],cin1,sum[1],cin2;
full_add1 f2a[2],b[2],cin2,sum[2],cin3;
程序文本
- 22 -
full_add1 f3a[3],b[3],cin3,sum[3],cout;
endmodule
【例7.19】数据流描述的4 位全加器
module add4_2cout,sum,a,b,cin;
output[3:0] sum;
output cout;
input[3:0] a,b;
input cin;
assign cout,suma+b+cin; endmodule
【例7.20】行为描述的4 位全加器
module add4_3cout,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,suma+b+cin;
end
endmodule
【例8.1】$time 与$realtime 的区别 `timescale 10ns/1ns
module time_dif; reg ts;
parameter delay2.6; initial
begin
#delay ts1;
#delay ts0;
#delay ts1;
#delay ts0;
end
initial $monitor$time,,,"ts%b",ts; //使用函数$time
王金明:《Verilog HDL 程序设计教程》 - 23 -
endmodule
【例8.2】$random 函数的使用
`timescale 10ns/1ns module random_tp; integer data;
integer i;
parameter delay10; initial $monitor$time,,,"data%b",data;
initial begin
fori0; i100; ii+1 #delay data$random; //每次产生一个随机数 end
endmodule
【例8.3】1 位全加器进位输出UDP 元件 primitive carry_udpcout,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.4】包含x 态输入的1 位全加器进位输出UDP 元件
primitive carry_udpx1cout,cin,a,b;
input cin,a,b; output cout; table
// cin a b : cout //真值表 0 0 0 : 0;
程序文本
- 24 -
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;
0 0 x : 0; //只要有两个输入为0,则进位输出肯定为0
0 x 0 : 0;
x 0 0 : 0;
1 1 x : 1; //只要有两个输入为1,则进位输出肯定为1
1 x 1 : 1;
x 1 1 : 1;
endtable
endprimitive
【例8.5】用简缩符“?”表述的1 位全加器进位输出UDP 元件 primitive carry_udpx2cout,cin,a,b;
input cin,a,b;
output cout;
table
// cin a b : cout //真值表0 0 : 0; //只要有两个输入为0,则进位输出
肯定为0
00 : 0;
0 0: 0;1 1 : 1; //只要有两个输入为1,则进位输出肯定为1 11 : 1;
1 1: 1;
endtable
endprimitive
【例8.6】3 选1 多路选择器UDP 元件
primitive mux31Y,in0,in1,in2,s2,s1;
input in0,in1,in2,s2,s1; output Y;
table
//in0 in1 in2 s2 s1 : Y 0? 0 0 : 0; //当s2s100 时,Yin0
1? 0 0 : 1;00 1 : 0; //当s2s101 时,Yin1 王金明:《Verilog HDL 程序设计教程》
- 25 -10 1 : 1;? 0 1: 0; //当s2s11?时,Yin2? 1 1: 1;
0 00: 0;
1 10: 1;
000 : 0;
110 : 1;0 01 : 0;1 11 : 1; endtable
endprimitive
【例8.7】电平敏感的1 位数据锁存器UDP 元件 primitive latchQ,clk,reset,D; input clk,reset,D;
output Q;
reg Q;
initial Q 1'b1; //初始化
table
// clk reset D : state : Q1:: 0 ; //reset1,则不管其他端口为什么值,
输出都为0
0 0 0 :: 0 ; //clk0,锁存器把D 端的输入值输出 0 0 1 :: 1 ;
1 0:: - ; //clk1,锁存器的输出保持原值,用符号“-”表示 endtable
endprimitive
【例8.8】上升沿触发的D 触发器UDP 元件
primitive DFFQ,D,clk; output Q;
input D,clk;
reg Q;
table
//clk D : state : Q 01 0 :: 0; //上升沿到来,输出QD
01 1 :: 1;
0x 1 : 1 : 1;
0x 0 : 0 : 0;
?0:: -; //没有上升沿到来,输出Q 保持原值?? :: - ; //时钟不变,输出
也不变
程序文本
- 26 -
endtable
endprimitive
【例8.9】带异步置1 和异步清零的上升沿触发的D 触发器UDP 元件
primitive DFF_UDPQ,D,clk,clr,set;
output Q;
input D,clk,clr,set; reg Q;
table
// clk D clr set : state : Q 01 1 0 0 :: 0;
01 1 0 x :: 0;? 0 x : 0 : 0; 01 0 0 0 :: 1;
01 0 x 0 :: 1;? x 0 : 1 : 1; x1 1 0 0 : 0 : 0;
x1 0 0 0 : 1 : 1;
0x 1 0 0 : 0 : 0;
0x 0 0 0 : 1 : 1;? 1:: 1; //异步复位? 0 1 :: 0; //异步置1 n0 0 :: -;*? :: -;? ?0:: -; ?0:: -;:: x;
endtable
endprimitive
【例8.12】延迟定义块举例
module delayout,a,b,c;
output out;
input a,b,c;
and a1n1,a,b;
or o1out,c,n1;
specify
aout2;
bout3;
cout1;
王金明:《Verilog HDL 程序设计教程》 - 27 -
endspecify
endmodule
【例8.13】激励波形的描述
'timescale 1ns/1ns module test1;
reg A,B,C;
initial
begin //激励波形描述
A 0; B 1; C 0; #100 C 1;
#100 A 1; B 0; #100 A 0;
#100 C 0;
#100 $finish;
end
initial $monitor$time,,,"A%d B%d C%d",A,B,C; //显示
endmodule
【例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
【例8.17】存储器在仿真程序中的应用
module ROMaddr,data,oe; output[7:0] data; //数据信号
input[14:0] addr; //地址信号
input oe; //读使能信号,低电平有效
程序文本
- 28 -
reg[7:0] mem[0:255]; //存储器定义
parameter DELAY 100; assign #DELAY dataoe0mem[addr] : 8'hzz;
initial $readmemh"rom.hex",mem; //从文件中读入数据
endmodule
【例8.18】8 位乘法器的仿真程序
`timescale 10ns/1ns
module mult_tp; //测试模块的名字
reg[7:0] a,b; //测试输入信号定义为reg 型
wire [15:0] out; //测试输出信号定义为wi