文档库 最新最全的文档下载
当前位置:文档库 › Verilog的135个经典设计实例

Verilog的135个经典设计实例

Verilog的135个经典设计实例
Verilog的135个经典设计实例

【例3.1】4位全加器

module adder4(cout,sum,ina,inb,cin);

output[3:0] sum;

output cout;

input[3:0] ina,inb;

input cin;

assign {cout,sum}=ina+inb+cin;

endmodule

【例3.2】4位计数器

module count4(out,reset,clk);

output[3:0] out;

input reset,clk;

reg[3:0] out;

always @(posedge clk)

begin

if (reset) out<=0; //同步复位

else out<=out+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 adder(sum,cout,a,b,cin); //调用测试对象

always #5 cin=~cin; //设定cin的取值

initial

begin

a=0;b=0;cin=0;

for(i=1;i<16;i=i+1)

#10 a=i; //设定a的取值

end

- 1 -

initial

begin

for(j=1;j<16;j=j+1)

#10 b=j; //设定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 DELY=100;

count4 mycount(out,reset,clk); //调用测试对象

always #(DELY/2) clk = ~clk; //产生时钟波形

initial

begin//激励信号定义

clk =0; reset=0;

#DELY reset=1;

#DELY reset=0;

#(DELY*20) $finish;

end

//定义结果显示格式

initial $monitor($time,,,"clk=%d reset=%d out=%d", clk, reset,out);

endmodule

【例3.5】“与-或-非”门电路

module AOI(A,B,C,D,F); //模块名为AOI(端口列表A,B,C,D,F) input A,B,C,D; //模块的输入端口为A,B,C,D

output F; //模块的输出端口为F

- 2 -

wire A,B,C,D,F; //定义信号的数据类型

assign F= ~((A&B)|(C&D)); //逻辑功能描述

endmodule

【例5.1】用case语句描述的4选1数据选择器

module mux4_1(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) //敏感信号列表

case(sel)

2'b00: out=in0;

2'b01: out=in1;

2'b10: out=in2;

2'b11: out=in3;

default: out=2'bx;

endcase

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.3】用always过程语句描述的简单算术逻辑单元

`define add 3'd0

`define minus 3'd1

`define band 3'd2

`define bor 3'd3

`define bnot 3'd4

- 3 -

module alu(out,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

case(opcode)

`add: out = a+b; //加操作

`minus: out = a-b; //减操作

`band: out = a&b; //求与

`bor: out = a|b; //求或

`bnot: out=~a; //求反

default: out=8'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 cycle=10;

initial

begin

- 4 -

- 5 -

wave=0;

#(cycle/2) wave=1;

#(cycle/2) wave=0; #(cycle/2) wave=1; #(cycle/2) wave=0; #(cycle/2) wave=1; #(cycle/2) $finish ; end

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

【例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.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.11】模为60的BCD码加法计数器

module count60(qout,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上升沿时刻计数- 6 -

if (reset) qout<=0; //同步复位

else if(load) qout<=data; //同步置数

else if(cin)

begin

if(qout[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 cout=((qout==8'h59)&cin)?1:0; //产生进位输出信号

endmodule

【例5.12】BCD码—七段数码管显示译码器

module decode4_7(decodeout,indec);

output[6:0] decodeout;

input[3:0] indec;

reg[6:0] decodeout;

always @(indec)

begin

case(indec) //用case语句进行译码

4'd0:decodeout=7'b1111110;

4'd1:decodeout=7'b0110000;

4'd2:decodeout=7'b1101101;

4'd3:decodeout=7'b1111001;

4'd4:decodeout=7'b0110011;

4'd5:decodeout=7'b1011011;

4'd6:decodeout=7'b1011111;

4'd7:decodeout=7'b1110000;

4'd8:decodeout=7'b1111111;

4'd9:decodeout=7'b1111011;

default: decodeout=7'bx;

endcase

end

- 7 -

【例5.13】用casez描述的数据选择器

module mux_casez(out,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

casez(select)

4'b???1: out = a;

4'b??1?: out = b;

4'b?1??: out = c;

4'b1???: out = d;

endcase

end

endmodule

【例5.14】隐含锁存器举例

module buried_ff(c,b,a);

output c;

input b,a;

reg c;

always @(a or b)

begin

if((b==1)&&(a==1)) c=a&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;

- 8 -

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

【例5.16】用for语句实现2个8位数相乘

module mult_for(outcome,a,b);

parameter size=8;

input[size:1] a,b; //两个操作数

output[2*size:1] outcome; //结果

reg[2*size:1] outcome;

integer i;

always @(a or b)

begin

outcome=0;

for(i=1; i<=size; i=i+1) //for语句

if(b[i]) outcome=outcome +(a << (i-1));

end

endmodule

【例5.17】用repeat实现8位二进制数的乘法

module mult_repeat(outcome,a,b);

parameter size=8;

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

outcome=0;

temp_a=a;

temp_b=b;

repeat(size) //repeat语句,size为循环次数

begin

if(temp_b[1]) //如果temp_b的最低位为1,就执行下面的加法

outcome=outcome+temp_a;

temp_a=temp_a<<1; //操作数a左移一位

- 9 -

temp_b=temp_b>>1; //操作数b右移一位

end

end

endmodule

【例5.18】同一循环的不同实现方式

module loop1; //方式1

integer i;

initial

for(i=0;i<4;i=i+1) //for语句

begin

$display(“i=%h”,i);

end

endmodule

module loop2; //方式2

integer i;

initial begin

i=0;

while(i<4) //while语句

begin

$display ("i=%h",i);

i=i+1;

end

end

endmodule

module loop3; //方式3

integer i;

initial begin

i=0;

repeat(4) //repeat语句

begin

$display ("i=%h",i);

i=i+1;

end

end

endmodule

【例5.19】使用了`include语句的16位加法器

- 10 -

`include "adder.v"

module adder16(cout,sum,a,b,cin);

output cout;

parameter my_size=16;

output[my_size-1:0] sum;

input[my_size-1:0] a,b;

input cin;

adder my_adder(cout,sum,a,b,cin); //调用adder模块

endmodule

//下面是adder模块代码

module adder(cout,sum,a,b,cin);

parameter size=16;

output cout;

output[size-1:0] sum;

input cin;

input[size-1:0] a,b;

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

endmodule

【例5.20】条件编译举例

module compile(out,A,B);

output out;

input A,B;

`ifdef add //宏名为add

assign out=A+B;

`else

assign out=A-B;

`endif

endmodule

【例6.1】加法计数器中的进程

module count(data,clk,reset,load,cout,qout);

output cout;

output[3:0] qout;

reg[3:0] qout;

input[3:0] data;

input clk,reset,load;

- 11 -

always @(posedge clk) //进程1,always过程块

begin

if (!reset) qout= 4'h00; //同步清0,低电平有效

else if (load) qout= data; //同步预置

else qout=qout + 1; //加法计数

end

assign cout=(qout==4'hf)?1:0; //进程2,用持续赋值产生进位信号

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

- 12 -

【例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;

- 13 -

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

- 14 -

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;

- 15 -

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.1】调用门元件实现的4选1 MUX - 16 -

module mux4_1a(out,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_1b(out,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)

case({cntrl1,cntrl2})

2'b00:out=in1;

2'b01:out=in2;

2'b10:out=in3;

2'b11:out=in4;

default:out=2'bx;

endcase

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

- 17 -

【例7.4】数据流方式描述的4选1 MUX

module mux4_1c(out,in1,in2,in3,in4,cntrl1,cntrl2);

output out;

input in1,in2,in3,in4,cntrl1,cntrl2;

assign out=(in1 & ~cntrl1 & ~cntrl2)|(in2 & ~cntrl1 & cntrl2)| (in3 & cntrl1 & ~cntrl2)|(in4 & cntrl1 & cntrl2);

endmodule

【例7.5】用条件运算符描述的4选1 MUX

module mux4_1d(out,in1,in2,in3,in4,cntrl1,cntrl2);

output out;

input in1,in2,in3,in4,cntrl1,cntrl2;

assign out=cntrl1 ? (cntrl2 ? in4:in3):(cntrl2 ? in2:in1);

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;

- 18 -

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;

- 19 -

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;

- 20 -

Verilog编码风格

Verilog编码风格 嵌入式开发2010-05-03 15:28:13 阅读14 评论0 字号:大中小订阅 这是以前公司的对fpga代码编写的要求 良好代码编写风格的通则概括如下: (1)对所有的信号名、变量名和端口名都用小写,这样做是为了和业界的习惯保持一致;对常量名和用户定义的类型用大写; (2)使用有意义的信号名、端口名、函数名和参数名; (3)信号名长度不要太长; (4)对于时钟信号使用clk 作为信号名,如果设计中存在多个时钟,使用clk 作为时钟信号的前缀; (5)对来自同一驱动源的信号在不同的子模块中采用相同的名字,这要求在芯片总体设计时就定义好顶层子模块间连线的名字,端口和连接端口的信号尽可能采用相同的名字; (6)对于低电平有效的信号,应该以一个下划线跟一个小写字母b 或n 表示。注意在同一个设计中要使用同一个小写字母表示低电平有效; (7)对于复位信号使用rst 作为信号名,如果复位信号是低电平有效,建议使用rst_n; (8)当描述多比特总线时,使用一致的定义顺序,对于verilog 建议采用bus_signal[x:0]的表示; (9)尽量遵循业界已经习惯的一些约定。如*_r 表示寄存器输出,*_a 表示异步信号,*_pn 表示多周期路径第n 个周期使用的信号,*_nxt 表示锁存前的信号,*_z 表示三态信号等; (10)在源文件、批处理文件的开始应该包含一个文件头、文件头一般包含的内容如下例所示:文件名,作者,模块的实现功能概述和关键特性描述,文件创建和修改的记录,包括修改时间,修改的内容等; (11)使用适当的注释来解释所有的always 进程、函数、端口定义、信号含义、变量含义或信号组、变量组的意义等。注释应该放在它所注释的代码附近,要求简明扼要,只要足够说明设计意图即可,避免过于复杂; (12)每一行语句独立成行。尽管VHDL 和Verilog 都允许一行可以写多个语句,当时每个语句独立成行可以增加可读性和可维护性。同时保持每行小于或等于72 个字符,这样做都是为了提高代码得可读性; (13)建议采用缩进提高续行和嵌套语句得可读性。缩进一般采用两个空格,如西安交通大学SOC 设计中心 2 如果空格太多则在深层嵌套时限制行长。同时缩进避免使用TAB 键,这样可以避免不同机器TAB 键得设置不同限制代码得可移植能力; (14)在RTL 源码的设计中任何元素包括端口、信号、变量、函数、任务、模块等的命名都不能取Verilog 和VHDL 语言的关键字; (15)在进行模块的端口申明时,每行只申明一个端口,并建议采用以下顺序:

原创:VHDL verilog 互相调用的例子

给两个例子, 一个是VHDL做顶层调用verilog 一个是verilog 做顶层调用VHDL VHDL调用verilog: module sync_block #( parameter INITIALISE = 2'b00 ) ( input clk, // clock to be sync'ed to input data_in, // Data to be 'synced' output data_out // synced data ); //VHD entity dcm_reset is port( ref_reset : in std_logic; -- Synchronous reset in ref_clk domain ref_clk : in std_logic; -- Reliable reference clock of known frequency (125MHz) dcm_locked : in std_logic; -- The DCM locked signal dcm_reset : out std_logic -- The reset signal which should be connected to the DCM ); end dcm_reset; component sync_block port ( clk : in std_logic; -- clock to be sync'ed to data_in : in std_logic; -- Data to be 'synced' data_out : out std_logic -- synced data ); end component; dcm_locked_sync_tx : sync_block port map( clk => ref_clk, data_in => dcm_locked, data_out => dcm_locked_sync ); verilog调用VHDL:(目标还是上述VHDL模块) module gmii_if ( …… ); dcm_reset rx_dcm_reset ( .ref_reset (tx_reset), .ref_clk (tx_clk),

VerilogHDL实例

本文档含有很多Verilog HDL例子://与门 module zxhand2(c,a,b); input a,b; output c; assign c= a & b; endmodule //或门 module zxhor2(c,a,b); input a,b; output c; assign c= a | b; endmodule //非门 module zxhnot2(c,b); input b; output c; assign c=~ b; endmodule ////异或门 module zxhxro2(c,a,b); input b; output c; assign c=a ^ b; endmodule 两选一电路 module data_scan(d0,d1,sel,q); output q; input d0,d1,sel; wire t1,t2,t3; n1 zxhand2(t1,d0,sel); n2 zxhnot2 (t4,sel); n3 zxhand2(t2,d1,t4); n4 zxhor2(t3,t1,t2);

assign q=t1; endmodule verilog HDL实例(一) 练习一.简单的组合逻辑设计 目的: 掌握基本组合逻辑电路的实现方法。 这是一个可综合的数据比较器,很容易看出它的功能是比较数据a与数据b,如果两个数据相同,则给出结果1,否则给出结果0。在Verilog HDL中,描述组合逻辑时常使用assign结构。注意 equal=(a==b)?1:0,这是一种在组合逻辑实现分支判断时常使用的格式。 模块源代码: //--------------- compare.v ----------------- module compare(equal,a,b); input a,b; output equal; assign equal=(a==b)?1:0; //a等于b时,equal输出为1;a不等于b时, //equal输出为0。 endmodule 测试模块用于检测模块设计得正确与否,它给出模块的输入信号,观察模块的内部信号和输出信号,如果发现结果与预期的有所偏差,则要对设计模块进行修改。 测试模块源代码: `timescale 1ns/1ns //定义时间单位。 module comparetest; reg a,b; wire equal; initial //initial常用于仿真时信号的给出。 begin a=0; b=0; #100 a=0; b=1; #100 a=1; b=1; #100 a=1; b=0; #100 $stop; //系统任务,暂停仿真以便观察仿真波形。 end compare compare1(.equal(equal),.a(a),.b(b)); //调用模块。 Endmodule

Verilog的135个经典设计实例

【例3.1】4位全加器 module adder4(cout,sum,ina,inb,cin); output[3:0] sum; output cout; input[3:0] ina,inb; input cin; assign {cout,sum}=ina+inb+cin; endmodule 【例3.2】4位计数器 module count4(out,reset,clk); output[3:0] out; input reset,clk; reg[3:0] out; always @(posedge clk) begin if (reset) out<=0; //同步复位 else out<=out+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 adder(sum,cout,a,b,cin); //调用测试对象 always #5 cin=~cin; //设定cin的取值 initial begin a=0;b=0;cin=0; for(i=1;i<16;i=i+1) #10 a=i; //设定a的取值 end - 1 -

initial begin for(j=1;j<16;j=j+1) #10 b=j; //设定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 DELY=100; count4 mycount(out,reset,clk); //调用测试对象 always #(DELY/2) clk = ~clk; //产生时钟波形 initial begin//激励信号定义 clk =0; reset=0; #DELY reset=1; #DELY reset=0; #(DELY*20) $finish; end //定义结果显示格式 initial $monitor($time,,,"clk=%d reset=%d out=%d", clk, reset,out); endmodule 【例3.5】“与-或-非”门电路 module AOI(A,B,C,D,F); //模块名为AOI(端口列表A,B,C,D,F) input A,B,C,D; //模块的输入端口为A,B,C,D output F; //模块的输出端口为F - 2 -

verilog_FPGA实例

一、组合逻辑实验 (2) 实验13X8译码器程序 (2) 实验2二-十进制译码器 (2) 实验3BCD码—七段数码管显示译码器 (3) 实验48-3编码器 (4) 实验58-3优先编码器 (4) 实验6十—二进制编码器 (5) 实验7三选一数据选择器 (5) 实验8半加器 (6) 实验9全加器 (7) 实验10半减器 (8) 实验11全减器 (8) 实验12多位数值比较器 (9) 实验13奇偶校验 (9) 实验14补码生成 (10) 实验158位硬件加法器的设计 (10) 实验164位并行乘法器 (10) 实验17七人表决器 (10) 实验18格雷码变换 (11) 二、时序逻辑实验 (11) 实验1D触发器 (11) 实验2JK触发器 (12) 实验3四位移位寄存器 (12) 实验4异步计数器 (13) 实验5同步计数器 (14) 实验6可逆计数器 (15) 实验7步长可变的加减计数器 (16) 实验8含异步清0和同步时钟使能的4位加法计数器 (17) 实验9顺序脉冲发生器 (18) 实验10序列信号发生器 (18) 实验11用状态机实现串行数据检测器 (19) 实验12分频器 (20) 实验13Moore状态机 (21) 实验14Mealy状态机 (23) 实验15三层电梯 (24) 实验16性线反馈移位寄存器(LFSR)设计 (32) 实验17正负脉宽数控调制信号发生器 (32) 三、存储器设计 (34) 实验1只读存储器(ROM) (34) 实验2SRAM (34) 实验3FIFO (35) 四、扩展接口实验 (39) 实验1流水灯 (39) 实验2VGA彩色信号显示控制器设计 (40)

Verilog程序例子

modul e and1(a, b, c); input a; input b; output c; assign c = a & b; endmodul e `timescale 1ns/1ns modul e t; reg a; reg b; wire c; and1 t(a,b,c); initial begin a=0; b=0; #100 a = 1; b = 0; #100 a = 0; b = 1; #100 a = 0; b = 0; #100 a = 1; b = 1; #100 $stop;

end initial $monitor("a = %d, ", a, " b = %d, ", b, "c = %d\n", c); endmodul e modul e add(a, b, in, c, out); input a; input b; input in; output c; output out; assign {out, c} = a + b + in; endmodul e `timescal e 1ns/1ns modul e count_t; reg clk; reg a; reg b; reg in; wire c; wire out; ad d process(a, b, in, c, out);

initial clk = 0; always forever #5 clk = ~clk; initial begin a = 0; b = 0; in = 0; #10 a = 0; b = 0; in = 1; #10 a = 0; b = 1; in = 0; #10 a = 0; b = 1; in = 1; #10 a = 1; b = 0; in = 0; #10 a = 1; b = 0; in = 1; #10 a = 1; b = 1; in = 0; #10 a = 1; b = 1; in = 1; end initial begin #200 $finish; end initial $monitor(" out = %d, c = %d\n", out, c); endmodul e modul e compare (equal, a, b); input a,b; output equal; assign equal= (a==b)?1:0; endmodul e `timescal e 1ns/1ns modul e t; reg a, b; wire equal; initial begin a=0; b=0; #100 a = 1; b = 0;

Verilog语言基础教程

Verilog HDL Verilog HDL是一种硬件描述语言,用于从算法级、门级到开关级的多种抽象 设计层次的数字系统建模。被建模的数字系统对象的复杂性可以介于简单的门和完整的电子数字系统之间。数字系统能够按层次描述,并可在相同描述中显式地进行时序建模。 Verilog HDL 语言具有下述描述能力:设计的行为特性、设计的数据流特性、设计的结构组成以及包含响应监控和设计验证方面的时延和波形产生机制。所有这些都使用同一种建模语言。此外,Verilog HDL语言提供了编程语言接口,通过该接口可以在模拟、验证期间从设计外部访问设计,包括模拟的具体控制和运行。 Verilog HDL语言不仅定义了语法,而且对每个语法结构都定义了清晰的模拟、仿真语义。因此,用这种语言编写的模型能够使用Verilog仿真器进行验证。语言从C编程语言中继承了多种操作符和结构。Verilog HDL提供了扩展的建模能力,其中许多扩展最初很难理解。但是,Verilog HDL语言的核心子集非常易于学习和使用,这对大多数建模应用来说已经足够。当然,完整的硬件描述语言足以对从最复杂的芯片到完整的电子系统进行描述。 =============================== 中文版Verilog HDL简明教程:第1章简介 Verilog HDL是一种硬件描述语言,用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模。被建模的数字系统对象的复杂性可以介于简单的门和完整的电子数字系统之间。数字系统能够按层次描述,并可在相同描述中显式地进行时序建模。 Verilog HDL 语言具有下述描述能力:设计的行为特性、设计的数据流特性、设计的结构组成以及包含响应监控和设计验证方面的时延和波形产生机制。所有这些都使用同一种建模语言。此外,Verilog HDL语言提供了编程语言接口,通过该接口可以在模拟、验证期间从设计外部访问设计,包括模拟的具体控制和运行。 Verilog HDL语言不仅定义了语法,而且对每个语法结构都定义了清晰的模拟、仿真语义。因此,用这种语言编写的模型能够使用Verilog仿真器进行验证。语言从C编程语言中继承了多种操作符和结构。Verilog HDL提供了扩展的建模能力,其中许多扩展最初很难理解。但是,Verilog HDL语言的核心子集非常易于学习和使用,这对大多数建模应用来说已经足够。当然,完整的硬件描述语言足以对从最复杂的芯片到完整的电子系统进行描述。 历史 Verilog HDL语言最初是于1983年由Gateway Design Automation公司为其模

jtag的经典例子,verilog

jtag的经典例子 module jtag(TCK,TMS, TDI, PROGRAM_COUNT, SFR_DATA, SOURCE_DI, XRAMDI, PROGDI, TRESET, SCLK, //Output TDO, //SOURCE_AJ, DESTIN_AJ, XRAMAJ, PROGAJ, DESTIN_DOJ, XRAMDOJ, PROGRAM_COUNTJ, PROGDOJ, NXRAMRJ, nXRAMWJ, NPSENJ ,PROGWE, SFR_WRITEJ, Write_SFR, Read_SFR , Read_RAM, NDESTIN_WEJ, nDESTIN_WEJ, Write_PC, ICReset,ICDisable,ICClock_Disable,ICClock_Enable ); //Input input TCK; input TMS; input TDI; input TRESET; input SCLK; //IC stop feedback signal at step_into state

input [15:0] PROGRAM_COUNT; //present PC value input [7:0] SFR_DATA; input [7:0] SOURCE_DI; input [7:0] XRAMDI; input [7:0] PROGDI; //Output output ICReset; output ICDisable; output ICClock_Disable; output TDO; //output [7:0] SOURCE_AJ; //output [15:0] XRAMAJ; //output [15:0] PROGAJ; //output [7:0] DESTIN_DOJ; //output [7:0] XRAMDOJ; //output [7:0] PROGDOJ; //output [15:0] PROGRAM_COUNTJ; output Write_PC; output NXRAMRJ; output nXRAMWJ;//NXRAMWJ, output NPSENJ;

Verilog的150个经典设计实例

module adder4(cout,sum,ina,inb,cin); output[3:0] sum; output cout; input[3:0] ina,inb; input cin; assign {cout,sum}=ina+inb+cin; endmodule 【例3.2】4位计数器 module count4(out,reset,clk); output[3:0] out; input reset,clk; reg[3:0] out; always @(posedge clk) begin if (reset) out<=0; //同步复位 else out<=out+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 adder(sum,cout,a,b,cin); //调用测试对象 always #5 cin=~cin; //设定cin的取值 initial begin a=0;b=0;cin=0; for(i=1;i<16;i=i+1) #10 a=i; //设定a的取值 end - 1 -

initial begin for(j=1;j<16;j=j+1) #10 b=j; //设定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 DELY=100; count4 mycount(out,reset,clk); //调用测试对象 always #(DELY/2) clk = ~clk; //产生时钟波形 initial begin//激励信号定义 clk =0; reset=0; #DELY reset=1; #DELY reset=0; #(DELY*20) $finish; end //定义结果显示格式 initial $monitor($time,,,"clk=%d reset=%d out=%d", clk, reset,out); endmodule 【例3.5】“与-或-非”门电路 module AOI(A,B,C,D,F); //模块名为AOI(端口列表A,B,C,D,F) input A,B,C,D; //模块的输入端口为A,B,C,D output F; //模块的输出端口为F - 2 -

verilog实例代码2word版本

v e r i l o g实例代码2

//与门 module zxhand2(c,a,b); input a,b; output c; assign c= a & b; endmodule //或门 module zxhor2(c,a,b); input a,b; output c; assign c= a | b; endmodule //非门 module zxhnot2(c,b); input b; output c; assign c=~ b; endmodule ////异或门 module zxhxro2(c,a,b); input b; output c; assign c=a ^ b; endmodule 两选一电路 module data_scan(d0,d1,sel,q); output q; input d0,d1,sel; wire t1,t2,t3; n1 zxhand2(t1,d0,sel); n2 zxhnot2 (t4,sel); n3 zxhand2(t2,d1,t4); n4 zxhor2(t3,t1,t2); assign q=t1;

endmodule verilog HDL实例(一) 练习一.简单的组合逻辑设计 目的: 掌握基本组合逻辑电路的实现方法。 这是一个可综合的数据比较器,很容易看出它的功能是比较数据a与数据b,如果两个数据相同,则给出结果1,否则给出结果0。在Verilog HDL中,描述组合逻辑时常使用assign结构。注意equal=(a==b)?1:0,这是一种在组合逻辑实现分支判断时常使用的格式。 模块源代码: //--------------- compare.v ----------------- module compare(equal,a,b); input a,b; output equal; assign equal=(a==b)?1:0; //a等于b时,equal输出为1;a不等于b时, //equal输出为0。 endmodule 测试模块用于检测模块设计得正确与否,它给出模块的输入信号,观察模块的内部信号和输出信号,如果发现结果与预期的有所偏差,则要对设计模块进行修改。 测试模块源代码: `timescale 1ns/1ns //定义时间单位。 module comparetest; reg a,b; wire equal; initial //initial常用于仿真时信号的给出。 begin a=0; b=0; #100 a=0; b=1; #100 a=1; b=1; #100 a=1; b=0; #100 $stop; //系统任务,暂停仿真以便观察仿真波形。 end compare compare1(.equal(equal),.a(a),.b(b)); //调用模块。 Endmodule

verilog常用例子

2.6.1 Verilog基本模块 1.触发器的Verilog实现 时序电路是高速电路的主要应用类型,其特点是任意时刻电路产生的稳定输出不仅与当前的输入有关,而且还与电路过去时刻的输入有关。时序电路的基本单元就是触发器。下面介绍几种常见同步触发器的Verilog 实现。 同步RS触发器 RS触发器分为同步触发器和异步触发器,二者的区别在于同步触发器有一个时钟端clk,只有在时钟端的信号上升(正触发)或下降(负触发)时,触发器的输出才会发生变化。下面以正触发为例,给出其Verilog 代码实现。 例2-15 正触发型同步RS触发器的Verilog实现。 module sy_rs_ff (clk, r, s, q, qb); input clk, r, s; output q, qb; reg q; assign qb = ~ q; always @(posedge clk) begin case({r, s}) 2'b00: q <= 0; 2'b01: q <= 1; 2'b10: q <= 0; 2'b11: q <= 1'bx; endcase end endmodule 上述程序经过综合Synplify Pro后,其RTL级结构如图2-2所示。 图2-2 同步RS触发器的RTL结构图 在ModelSim 6.2b中完成仿真,其结果如图2-3所示

图2-3 同步RS触发器的仿真结果示意图 同步T触发器 T触发器也分为同步触发器和异步触发器,二者的区别在于同步T触发器多了一个时钟端。同步T触发器的逻辑功能为:当时钟clk沿到来时,如果T=0,则触发器状态保持不变;否则,触发器输出端反转。R 为复位端,当其为高电平时,输出Q与时钟无关,Q=0。 例2-16 同步T触发器的Verilog实现。 module sy_t_ff(clk, r, t, q, qb); input clk, r, t; output q, qb; reg q; assign qb = ~q; always @(posedge clk) begin if(r) q <= 0; else q <= ~q; end endmodule 上述程序经过综合Synplify Pro后,其RTL级结构如图2-4所示。 图2-4 同步T触发器电路的RTL结构图 在ModelSim 6.2b中完成仿真,其结果如图2-5所示

Verilog语言良好的代码编写格式

Verilog 及VHDL良好的代码编写风格 良好代码编写风格可以满足信、达、雅的要求。在满足功能和性能目标的前提下,增强代码的可读性、可移植性,首要的工作是在项目开发之前为整个设计团队建立一个命名约定和缩略语清单,以文档的形式记录下来,并要求每位设计人员在代码编写过程中都要严格遵守。良好代码编写风格的通则概括如下:(1)对所有的信号名、变量名和端口名都用小写,这样做是为了和业界的习惯保持一致;对常量名和用户定义的类型用大写; (2)使用有意义的信号名、端口名、函数名和参数名; (3)信号名长度不要太长; (4)对于时钟信号使用clk 作为信号名,如果设计中存在多个时钟,使用clk 作为时钟信号的前缀; (5)对来自同一驱动源的信号在不同的子模块中采用相同的名字,这要求在芯片总体设计时就定义好顶层子模块间连线的名字,端口和连接端口的信号尽可能采用相同的名字; (6)对于低电平有效的信号,应该以一个下划线跟一个小写字母b 或n 表示。注意在同一个设计中要使用同一个小写字母表示低电平有效; (7)对于复位信号使用rst 作为信号名,如果复位信号是低电平有效,建议使用rst_n; (8)当描述多比特总线时,使用一致的定义顺序,对于verilog 建议采用 bus_signal[x:0]的表示; (9)尽量遵循业界已经习惯的一些约定。如*_r 表示寄存器输出,*_a 表示异步信号,*_pn 表示多周期路径第n 个周期使用的信号,*_nxt 表示锁存前的信号,*_z 表示三态信号等; (10)在源文件、批处理文件的开始应该包含一个文件头、文件头一般包含的内容如下例所示:文件名,作者,模块的实现功能概述和关键特性描述,文件创建和修改的记录,包括修改时间,修改的内容等; (11)使用适当的注释来解释所有的always 进程、函数、端口定义、信号含义、变量含义或信号组、变量组的意义等。注释应该放在它所注释的代码附近,要求简明扼要,只要足够说明设计意图即可,避免过于复杂; (12)每一行语句独立成行。尽管VHDL 和Verilog 都允许一行可以写多个语句,当时每个语句独立成行可以增加可读性和可维护性。同时保持每行小于或等于72 个字符,这样做都是为了提高代码得可读性; (13)建议采用缩进提高续行和嵌套语句得可读性。缩进一般采用两个空格,如西安交通大学SOC 设计中心2 如果空格太多则在深层嵌套时限制行长。同时缩进避免使用TAB 键,这样可以避免不同机器TAB 键得设置不同限制代码得可移植能力; (14)在RTL 源码的设计中任何元素包括端口、信号、变量、函数、任务、模块等的命名都不能取Verilog 和VHDL 语言的关键字; (15)在进行模块的端口申明时,每行只申明一个端口,并建议采用以下顺序:输入信号的clk、rst、enables other control signals、data and address signals。然后再申明输出信号的clk、rst、enalbes other control signals、data signals;

Verilog实例代码

- 1 - 【例3.1】4位全加器 module adder4(cout,sum,ina,inb,cin); output [3:0] sum; output cout; input [3:0] ina,inb; input cin; assign {cout,sum}=ina+inb+cin; endmodule 【例3.2】4位计数器 module count4(out,reset,clk); output [3:0] out; input reset,clk; reg [3:0] out; always @(posedge clk) begin if (reset) out<=0; //同步复位 else out<=out+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 adder(sum,cout,a,b,cin); //调用测试对象 always #5 cin=~cin; //设定cin 的取值 initial begin a=0;b=0;cin=0; for (i=1;i<16;i=i+1) #10 a=i; //设定a 的取值 end

initial begin for(j=1;j<16;j=j+1) #10 b=j; //设定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 DELY=100; always #(DELY/2) clk = ~clk; //产生时钟波形 initial begin//激励信号定义 clk =0; reset=0; #DELY reset=1; #DELY reset=0; #(DELY*20) $finish; end //定义结果显示格式 initial $monitor($time,,,"clk=%d reset=%d out=%d", clk, reset,out); endmodule 【例3.5】“与-或-非”门电路 module AOI(A,B,C,D,F); //模块名为AOI(端口列表A,B,C,D,F) input A,B,C,D; //模块的输入端口为A,B,C,D output F; //模块的输出端口为F - 2 -

verilog数字系统设计教程第6章例题

第六章例题 [例1]:用initial 块对存储器变量赋初始值 initial begin areg=0; //初始化寄存器areg for(index=0;index