verilog实例代码2.doc_第1页
verilog实例代码2.doc_第2页
verilog实例代码2.doc_第3页
verilog实例代码2.doc_第4页
verilog实例代码2.doc_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

/与门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 【例3.1】4 位全加器module adder4(cout,sum,ina,inb,cin);output3:0 sum;output cout;input3:0 ina,inb;input cin;assign cout,sum=ina+inb+cin;endmodule【例3.2】4 位计数器module count4(out,reset,clk);output3:0 out;input reset,clk;reg3:0 out;always (posedge clk)beginif (reset) out=0; /同步复位else out=out+1; /计数endendmodule09.04.07【例5.11】模为60 的BCD 码加法计数器module count60(qout,cout,data,load,cin,reset,clk);output7:0 qout;output cout;input7:0 data;input load,cin,clk,reset;reg7:0 qout;always (posedge clk) /clk 上升沿时刻计数beginif (reset) qout=0; /同步复位else if(load) qout=data; /同步置数else if(cin)beginif(qout3:0=9) /低位是否为9,是则beginqout3:0=0; /回0,并判断高位是否为5if (qout7:4=5) qout7:4=0;elseqout7:4=qout7:4+1; /高位不为5,则加1endelse /低位不为9,则加1qout3:0=qout3:0+1;endendassign cout=(qout=8h59)&cin)?1:0; /产生进位输出信号endmodule【例9.10】奇偶校验位产生器module parity(even_bit,odd_bit,input_bus);output even_bit,odd_bit;input7:0 input_bus;assign odd_bit = input_bus; /产生奇校验位assign even_bit = odd_bit; /产生偶校验位endmodule Verilog HDL实例(二) 练习二. 简单时序逻辑电路的设计 目的:掌握基本时序逻辑电路的实现。 在Verilog HDL中,相对于组合逻辑电路,时序逻辑电路也有规定的表述方式。在可综合的Verilog HDL模型,我们通常使用always块和 (posedge clk)(上升沿)或 (negedge clk)(下降沿)的结构来表述时序逻辑。下面是一个1/2分频器的可综合模型。/ half_clk.v:module half_clk(reset,clk_in,clk_out);input clk_in,reset;output clk_out;reg clk_out;always (posedge clk_in) begin if(!reset) clk_out=0; else clk_out=clk_out; endendmodule在always块中,被赋值的信号都必须定义为reg型,这是由时序逻辑电路的特点所决定的。对于reg型数据,如果未对它进行赋值,仿真工具会认为它是不定态。为了能正确地观察到仿真结果,在可综合风格的模块中我们通常定义一个复位信号reset,当reset为低电平时,对电路中的寄存器进行复位。测试模块的源代码:/- clk_Top.v -timescale 1ns/100psdefine clk_cycle 50module clk_Top.v;reg clk,reset;wire clk_out;always #clk_cycle clk = clk;initial begin clk = 0; reset = 1; #100 reset = 0; #100 reset = 1; #10000 $stop; endhalf_clk half_clk(.reset(reset),.clk_in(clk),.clk_out(clk_out);endmodule Verilog HDL实例(三) 练习三. 利用条件语句实现较复杂的时序逻辑电路 目的:掌握条件语句在Verilog HDL中的使用。与常用的高级程序语言一样,为了描述较为复杂的时序关系,Verilog HDL提供了条件语句供分支判断时使用。在可综合风格的Verilog HDL模型中常用的条件语句有ifelse和caseendcase两种结构,用法和C程序语言中类似。两者相较,ifelse用于不很复杂的分支关系,实际编写可综合风格的模块、特别是用状态机构成的模块时,更常用的是caseendcase风格的代码。这一节我们给的是有关ifelse的范例,有关caseendcase结构的代码已后会经常用到。下面给出的范例也是一个可综合风格的分频器,是将10M的时钟分频为500K的时钟。基本原理与1/2分频器是一样的,但是需要定义一个计数器,以便准确获得1/20分频模块源代码:/ - fdivision.v -module fdivision(reset,f10m,f500k);input f10m,reset;output f500k;reg f500k;reg 7:0j; always (posedge f10m) if(!RESET) /低电平复位。 begin f500k = 0; j = 0; end else begin if(j=19) /对计数器进行判断,以确定F500K信号是否反转。 begin j = 0; f500k = f500k; end else j = j+1; endendmodule测试模块源代码:/- fdivision_Top.v -timescale 1ns/100psdefine clk_cycle 50module division_Top;reg f10m=0,reset;wire f500k;always #clk_cycle f10m = f10m; initial begin reset=1;#100 reset=0;#100 reset=1;#10000 $stop; endfdivision fdivision (.reset(reset),.f10m(f10m),.f500k(f500k);endmodule Verilog HDL实例(四)练习四. 设计时序逻辑时采用阻塞赋值与非阻塞赋值的区别 目的:1.明确掌握阻塞赋值与非阻塞赋值的概念和区别; 2.了解阻塞赋值的使用情况。阻塞赋值与非阻塞赋值,在教材中我们已经了解了它们之间在语法上的区别以及综合后所得到的电路结构上的区别。在always块中,阻塞赋值可以理解为赋值语句是顺序执行的,而非阻塞赋值可以理解为赋值语句是并发执行的。实际的时序逻辑设计中,一般的情况下非阻塞赋值语句被更多地使用,有时为了在同一周期实现相互关联的操作,也使用了阻塞赋值语句。(注意:在实现组合逻辑的assign结构中,无一例外地都必须采用阻塞赋值语句。下例通过分别采用阻塞赋值语句和非阻塞赋值语句的两个看上去非常相似的两个模块blocking.v和non_blocking.v来阐明两者之间的区别。模块源代码:/ - blocking.v -module blocking(clk,a,b,c); output 3:0 b,c; input 3:0 a; input clk; reg 3:0 b,c; always (posedge clk) begin b = a; c = b; end endmodule/- non_blocking.v -module non_blocking(clk,a,b,c); output 3:0 b,c; input 3:0 a; input clk; reg 3:0 b,c; always (posedge clk) begin b = a; c = b; endendmodule测试模块源代码:/- compareTop.v -timescale 1ns/100psinclude ./blocking.vinclude ./non_blocking.vmodule compareTop; wire 3:0 b1,c1,b2,c2; reg 3:0 a; reg clk; initial begin clk = 0; forever #50 clk = clk; end initial begin a = 4h3; $display(_); # 100 a = 4h7; $display(_); # 100 a = 4hf; $display(_); # 100 a = 4ha; $display(_); # 100 a = 4h2; $display(_); # 100 $display(_); $stop; end non_blocking non_blocking(clk,a,b2,c2); blocking blocking(clk,a,b1,c1);endmodule Verilog HDL实例(五) 练习五. 用always块实现较复杂的组合逻辑电路 目的: 1.掌握用always实现组合逻辑电路的方法; 2.了解assign与always两种组合逻辑电路实现方法之间的区别。 仅使用assign结构来实现组合逻辑电路,在设计中会发现很多地方会显得冗长且效率低下。而适当地采用always来设计组合逻辑,往往会更具实效。已进行的范例和练习中,我们仅在实现时序逻辑电路时使用always块。从现在开始,我们对它的看法要稍稍改变。下面是一个简单的指令译码电路的设计示例。该电路通过对指令的判断,对输入数据执行相应的操作,包括加、减、与、或和求反,并且无论是指令作用的数据还是指令本身发生变化,结果都要作出及时的反应。显然,这是一个较为复杂的组合逻辑电路,如果采用assign语句,表达起来非常复杂。示例中使用了电平敏感的always块,所谓电平敏感的触发条件是指在后的括号内电平列表中的任何一个电平发生变化,(与时序逻辑不同,它在后的括号内没有沿敏感关键词,如posedge 或negedge)就能触发always块的动作,并且运用了case结构来进行分支判断,不但设计思想得到直观的体现,而且代码看起来非常整齐、便于理解。/- alu.v -define plus 3d0define minus 3d1define band 3d2define bor 3d3define unegate 3d4module alu(out,opcode,a,b);output7:0 out;reg7:0 out;input2:0 opcode;input7:0 a,b; /操作数。always(opcode or a or b) /电平敏感的always块begin case(opcode) plus: out = a+b; /加操作。 minus: out = a-b; /减操作。 band: out = a&b; /求与。 bor: out = a|b; /求或。 unegate: out=a; /求反。 default: out=8hx;/未收到指令时,输出任意态。 endcaseend endmodule 同一组合逻辑电路分别用always块和连续赋值语句assign描述时,代码的形式大相径庭,但是在always中适当运用default(在case结构中)和else(在ifelse结构中),通常可以综合为纯组合逻辑,尽管被赋值的变量一定要定义为reg型。不过,如果不使用default或else对缺省项进行说明,则易生成意想不到的锁存器,这一点一定要加以注意。指令译码器的测试模块源代码:/- alu_Top.v -timescale 1ns/1nsmodule alutest; wire7:0 out; reg7:0 a,b; reg2:0 opcode; parameter times=5; initial begin a=$random%256; /Give a radom number blongs to 0,255 . b=$random%256; /Give a radom number blongs to 0,255. opcode=3h0; repeat(times) begin #100 a=$random%256; /Give a radom number. b=$random%256; /Give a radom number. opcode=opcode+1; end #100 $stop; end alu alu1(out,opcode,a,b);endmodule Verilog HDL实例(六) 练习六. 在Verilog HDL中使用函数 目的:掌握函数在模块设计中的使用。与一般的程序设计语言一样,Veirlog HDL也可使用函数以适应对不同变量采取同一运算的操作。Veirlog HDL函数在综合时被理解成具有独立运算功能的电路,每调用一次函数相当于改变这部分电路的输入以得到相应的计算结果。下例是函数调用的一个简单示范,采用同步时钟触发运算的执行,每个clk时钟周期都会执行一次运算。并且在测试模块中,通过调用系统任务$display在时钟的下降沿显示每次计算的结果。模块源代码:module tryfunct(clk,n,result,reset); output31:0 result; input3:0 n; input reset,clk; reg31:0 result; always (posedge clk) /clk的上沿触发同步运算。begin if(!reset) /reset为低时复位。 result=0; else begin result = factorial(n); end end function 31:0 factorial; /函数定义。 input 3:0 operand; reg 3:0 index; begin factorial = 1; for(index = 1; index = operand; index = index + 1) factorial = index * factorial; end endfunctionendmodule测试模块源代码:timescale 1ns/100psmodule tryfuctTop;reg3:0 n,i;reg reset,clk;wire31:0 result;initial begin n=0; reset=1; clk=0; #10 reset=0; #10 reset=1; for(i=0;iy) begin tmp=x; /x与y变量的内容互换,要求顺序执行,所以采用阻塞赋值方式。 x=y; y=tmp; end endtaskendmodule值得注意的是task中的变量定义与模块中的变量定义不尽相同,它们并不受输入输出类型的限制。如此例,x与y对于task sort2来说虽然是inout型,但实际上它们对应的是always块中变量,都是reg型变量。测试模块源代码: timescale 1ns/100ps module task_Top; reg3:0 a,b,c,d; wire3:0 ra,rb,rc,rd; ss my (.a(a),.b(b),.c(c),.d(d), .ra(ra),.rb(rb),.rc(rc),.rd(rd); initial begin a=0;b=0;c=0;d=0; #100 a =$random%15; b =$random%15; c =$random%15; d =$random%15; #100 $stop; end endmodule 【例3.5】“与-或-非”门电路module AOI(A,B,C,D,F); /模块名为AOI(端口列表A,B,C,D,F)input A,B,C,D; /模块的输入端口为A,B,C,Doutput F; /模块的输出端口为Fwire A,B,C,D,F; /定义信号的数据类型assign F= (A&B)|(C&D); /逻辑功能描述endmodule【例5.2】同步置数、同步清零的计数器module count(out,data,load,reset,clk);output7:0 out;input7:0 data;input load,clk,reset;reg7:0 out;always (posedge clk) /clk 上升沿触发beginif (!reset) out = 8h00; /同步清0,低电平有效else if (load) out = data; /同步预置else out = out + 1; /计数endendmodule【例5.14】隐含锁存器举例module buried_ff(c,b,a);output c;input b,a;reg c;always (a or b)beginif(b=1)&(a=1) c=a&b;endendmodule【例5.16】用for 语句实现2 个8 位数相乘module mult_for(outcome,a,b);parameter size=8;inputsize:1 a,b; /两个操作数output2*size:1 outcome; /结果reg2*size:1 outcome;integer i;always (a or b)beginoutcome=0;for(i=1; i=size; i=i+1) /for 语句if(bi) outcome=outcome +(a (i-1);endendmodule【例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) /过程赋值beginF=(A&B)|(B&C&D);endendmodule【例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);inout7:0 bidir;input en,clk;reg7:0 temp;assign bidir= en ? temp : 8bz;always (posedge clk)beginif(en) temp=bidir;else temp=temp+1;endendmodule 【例9.13】用组合电路实现的ROMmodule rom(addr,data);input3:0 addr;output7:0 data;function7:0 romout;input3: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 = 8hxx;endcaseendfunctionassign data = romout(addr);endmodule【例9.14】基本D 触发器module DFF(Q,D,CLK);output Q;input D,CLK;reg Q;always (posedge CLK)beginQ = D;endendmodule【例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)beginif (!reset) beginq = 0; /异步清0,低电平有效qn = 1;endelse if (!set) beginq = 1; /异步置1,低电平有效qn = 0;endelse beginq = d;qn = d;endendendmodule【例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)beginif (reset) beginq = 0; qn = 1; /同步清0,高电平有效endelse if (set) beginq =1; qn =0; /同步置1,高电平有效endelse beginq = d; qn = d;endendendmodule【例9.17】带异步清0、异步置1 的JK 触发器module JK_FF(CLK,J,K,Q,RS,SET);input CLK,J,K,SET,RS;output Q;reg Q;always (posedge CLK or negedge RS or negedge SET)beginif(!RS) Q = 1b0;else if(!SET) Q = 1b1;else case(J,K)2b00 : Q = Q;2b01 : Q = 1b0;2b10 : Q = 1b1;2b11 : Q = Q;default: Q= 1bx;endcaseendendmodule【例9.18】电平敏感的1 位数据锁存器module latch_1(q,d,clk);output q;input d,clk;assign q = clk ? d : q; /时钟信号为高电平时,将输入端数据锁存endmodule【例9.19】带置位和复位端的1 位数据锁存器module latch_2(q,d,clk,set,reset);output q;input d,clk,set,reset;assign q = reset ? 0 : (set ? 1 : (clk ? d : q);endmodule【例9.20】8 位数据锁存器module latch_8(qout,data,clk);output7:0 qout;input7:0 data;input clk;reg7:0 qout;always (clk or data)beginif (clk) qout=data;endendmodule【例9.21】8 位数据寄存器module reg8(out_data,in_data,clk,clr);output7:0 out_data;input7:0 in_data;input clk,clr;reg7:0 out_data;always (posedge clk or posedge clr)beginif(clr) out_data =0;else out_data =in_data;endendmodule【例9.22】8 位移位寄存器module shifter(din,clk,clr,dout);input din,clk,clr;output7:0 dout;reg7:0 dout;always (posedge clk)beginif (clr) dout= 8b0; /同步清0,高电平有效elsebegindout = dout 1; /输出信号左移一位dout0 = din; /输入信号补充到输出信号的最低位endendendmodule【例9.23】可变模加法/减法计数器module updown_count(d,clk,clear,load,up_down,qd);input7:0 d;input clk,clear,load;input up_down;output7:0 qd;reg7:0 cnt;assign qd = cnt;always (posedge clk)beginif (!clear) cnt = 8h00; /同步清0,低电平有效else if (load) cnt = d; /同步预置else if (up_down) cnt = cnt + 1; /加法计数else cnt = cnt - 1; /减法计数endendmodule【例9.24】4 位Johnson 计数器(异步复位)module johnson(clk,clr,out);input clk,clr;output3:0 out;reg3:0 out;always (posedge clk or posedge clr)beginif (clr) out= 4h0;elsebegin out= out 1;out0= out3;endendendmodule【例9.25】2568 RAM 模块module ram256x8(data,address,we,inclock,outclock,q);input7:0 data;input7:0 address;input we,inclock,outclock;output7:0 q;lpm_ram_dq myram(.q(q),.data(data),.address(address),.we(we),.inclock(inclock),.outclock(outclock);defparam myram.lpm_width=8; /定义数据宽度defparam myram.lpm_widthad=8; /定义地址宽度endmodule【例9.26】25616 RAM 块module map_lpm_ram(dataout,datain,addr,we,inclk,outclk);input15:0 datain; /端口定义input7:0 addr;input we,inclk,outclk;output15:0 dataout;/lpm_ram_dq 元件例化lpm_ram_dq ram(.data(datain),.address(addr),.we(we),.inclock(inclk),.outclock(outclk),.q(dataout);defparam ram.lpm_width=16; /参数赋值defparam ram.lpm_widthad=8;defparam ram.lpm_indata=REGISTERED;defparam ram.lpm_outdata=REGISTERED;defparam ram.lpm_file=map_lpm_ram.mif; /RAM 块中的内容取自该文件endmodule【例9.27】4 位串并转换器module serial_pal(clk,reset,en,in,out);input clk,reset,en,in;output3:0 out;reg3:0 out;always (posedge clk)beginif(reset) out=4h0;else if(en) out=out,in; /使用连接运算符endendmodule 【例10.6】自动转换量程频率计控制器/*信号定义:clk: 输入时钟;clear: 为整个频率计的异步复位信号;reset: 用来在量程转换开始时复位计数器;std_f_sel: 用来选择标准时基;cntover: 代表超量程;cntlow: 代表欠量程。状态A,B,C,D,E,F 采用一位热码编码 */module control(std_f_sel,reset,clk,clear,cntover,c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论