资源预览内容
第1页 / 共15页
第2页 / 共15页
第3页 / 共15页
第4页 / 共15页
第5页 / 共15页
第6页 / 共15页
第7页 / 共15页
第8页 / 共15页
第9页 / 共15页
第10页 / 共15页
亲,该文档总共15页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
Verilog HDL 语言2.2 层 次 建 模【例2-3】 实现一个1位全加器。1位全加器的Verilog HDL实现代码如下:/*以下为全加器顶层模块*/module f_adder(ain,bin,cin,cout,sum);output cout,sum;input ain,bin,cin;wire ain,bin,cin,cout,sum;wire d,e,f;h_adder u0(ain,bin,d,e);h_adder u1(e,cin,f,sum);or2a u2(d,f,cout);endmodule/*以下为半加器模块*/module h_adder(a,b,co,so);output co,so;input a,b;wire a,b,co,so,bbar;and and2(co,a,b);not not1(bbar,b);xnor xnor2(so,a,bbar);endmodule/*以下为或门模块*/module or2a(a,b,c);output c;input a,b;wire a,b,c;assign c=a | b;endmodule程序说明:(1) 语句assign c=a | b; 中,“|”是按位或运算符,其功能是将a与b按位或的结果赋给信号c。(2) 语句wire a,b,c; 中,wire是线网数据类型,表示a、b、c是线网,是硬件单元之间的连接。(3) 一个Verilog HDL模块内部的实现方式有多种。本例中,在或门模块内部使用了数据流语句assign;在半加器模块内部调用了基本逻辑门原语;在全加器模块内部调用了半加器模块和或门模块。 (4) 在全加器模块中有两处调用了半加器:h_adder u0(ain,bin,d,e);和h_adder u1(e,cin,f,sum);。每次调用均给出一个唯一的实例名,而且调用时端口列表名称不同。在Verilog HDL设计中,在模块调用的时候,可以按顺序将模块定义的端口与外部环境中的信号连接起来,这种方法称为“按顺序连接”。h_adder u0(ain,bin,d,e);调用将ain、bin、d、e分别与模块定义中的端口a、b、co、so连接;h_adder u1(e,cin,f,sum);调用将e、cin、f、sum分别与模块定义中的端口a、b、co、so连接。【例2-4】 二选一数据选择器示例。module mux21a(a,b,s,y);input wire a,b,s;output reg y;always (a,b,s)if(s=1) y=b;else y=a;endmodule程序说明:(1) 在模块中,输入端口只能为wire类型,输出端口可以为wire类型,也可以为reg类型。通常情况下,如果输出端口在always语句中使用,则必须声明为reg类型。(2) if(s=1) y=b;else y=a;为条件语句结构,表达的意思是当s为1时y=b,否则y=a。条件语句只能用在always语句中。 【例2-7】 设计参数型N位加法器。module add_N( X, Y, sum, co);parameter N=4;input N-1: 0 X, Y;output N-1: 0 sum;output co;assign co, sum = X + Y;endmodule/16位加法器只需要调用参数型N位加法器即可module add_16(X, Y, s, c);input 15 : 0 X, Y;output 15 : 0 s;output c;add_N #(16) add16(X, Y, s, c);endmodule/8位加法器只需要调用参数型N位加法器即可module add_8(X, Y, s, c);input 7 : 0 X, Y;output 7 : 0 s;output c;add_N add8(X, Y, s, c);defparam add8.N=8;endmodule程序说明:(1) 在调用add_N模块时,可用#(16)使参数N的值变为16,从而使模块功能变为16位加法器,具体实现语句为add_N #(16) add16(X, Y, s, c);。(2) 也可以使用defparam来改变参数。用后缀改变引用模块的参数要用被引用模块的实例名作为参数的前缀,如add8.N=8,从而使被引用模块的功能变为8位加法器。具体实现语句为:add_N add8(X, Y, s, c); defparam add8.N=8;。通过使用参数,用户可以更加灵活地对模块进行说明。用户不但可以根据参数来定义模块,还可以方便地通过参数值重定义来改变模块的行为。3.3 数据流级建模连续赋值语句:以关键词assign开始的语句为连续赋值语句,连续赋值语句是Verilog数据流建模的基本语句,用于对线网进行赋值。【例3-10】 使用数据流建模,实现一位半加器。module adder_half(ain,bin,sum,co); input ain,bin; output sum,co;assign co,sum= ain+bin;endmodule程序说明:(1) assign co,sum= ain+bin; 是一条连续赋值语句,它将ain和bin的和存放在co,sum中。该语句中,“ ”为位拼接符,其功能是将co和sum拼接成一个两位的数。(2) 连续赋值语句的左边必须是一个标量或向量线网,或者是标量或向量线网的拼接,而不能是任何形式的寄存器。例如下面的形式是非法的:reg sum;assign co,sum= ain+bin; /非法,sum不能为寄存器类型 【例3-9】 表示时序逻辑的UDP举例:D触发器。primitive d_edge_ff (q, clk, data); output q; input clk, data; reg q; table / clk dat state next(01) 0 : ? : 0 ;(01) 1 : ? : 1 ;/时钟下降沿(?0) ? : ? : - ; /时钟稳定时忽略data的变化? (?) : ? : - ; endtableendprimitive程序说明:(1) 使用Quartus 软件综合的结果如图3-9所示。 从综合结果可以看出,该设计实现了一个D触发器。(2) 程序中的“?”表示逻辑值可以为0、1或x。(3) 端口列表中的第一个端口q为输出端口,其余为输入端口。3.4 行为级建模 结构化过程语句always:always语句是行为建模的基本语句,每个always语句代表一个独立的执行过程,也称为进程。与C语言不同,Verilog HDL的各个always进程是并发执行的,而不是顺序执行的。 过程赋值语句:Verilog HDL包括两种类型的过程赋值语句:阻塞赋值语句和非阻塞赋值语句。【例3-15】 使用always语句描述D触发器。module mydff(q, clk, d);input clk, d;output q; reg q;always (posedge clk) q=d;endmodule程序说明:(1) 本程序的功能是在时钟上升沿时刻,将数据d赋予触发器输出q,其功能同D触发器一样。(2) always语句由于其不断重复执行的特性,只有和一定的时序控制结合在一起才有用。always (posedge clk)语句表示只有在clk上升沿时才开始执行always语句块,否则不执行。这种时序控制是always语句最常用的。(3) always 的时序控制除沿触发时序控制外,还可以是电平触发的,也可以是单个信号或多个信号,中间需要用关键字or 或“,”连接,如: always (posedge clock or posedge reset) /由两个沿触发的always块 begin endalways ( a or b or c ) /由多个电平触发的always块 begin end沿触发的always块常用来描述时序逻辑,如果符合可综合风格要求,则可用综合工具将其自动转换为表示时序逻辑的寄存器组和门级逻辑;而电平触发的always块常用来描述一般组合逻辑和带锁存器的组合逻辑,如果符合可综合风格要求,则可转换为表示组合逻辑的门级逻辑或带锁存器的组合逻辑。一个模块中可以有多个always块,它们都是并行运行的。从综合结果来看,本例实现了一个上升沿触发的D触发器。【例3-16】 阻塞赋值方式描述的移位寄存器1。module block1(Q0,Q1,Q2,D,clk);output Q0,Q1,Q2;input clk,D;reg Q0,Q1,Q2;always (posedge clk) begin Q2=Q1; /注意赋值语句的顺序 Q1=Q0; Q0=D; end endmodule 综合结果如图3-13所示。【例3-17】 阻塞赋值方式描述的移位寄存器2。module block2(Q0,Q1,Q2,D,clk);output Q0,Q1,Q2;input clk,D;reg Q0,Q1,Q2;always (posedge clk) beginQ1=Q0; /该句与下句的顺序与例3-16颠倒Q2=Q1;Q0=D; endendmodule综合结果如图3-14所示。 【例3-18】 阻塞赋值方式描述的移位寄存器3。module block3(Q0,Q1,Q2,D,clk);output Q0,Q1,Q2;input clk,D;reg Q0,Q1,Q2;always (posedge clk) beginQ0=D; /3条赋值语句的顺序与例3-16完全颠倒Q1=Q0;Q2=Q1; endendmodule综合结果如图3-15所示。 【例3-19】 非阻塞赋值方式描述的移位寄存器1。module non_block1(Q0,Q1,Q2,D,clk);output Q0,Q1,Q2;input clk,D;reg Q0,Q1,Q2;always (posedge clk) beginQ1=Q0;Q2=Q1;Q0=D; endE ndmodule【例3-20】 非阻塞赋值方式描述的移位寄存器2。module non_block2(Q0,Q
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号