verilog多模块编程实例

Verilog多模块编程实例
1. 介绍
Verilog是一种硬件描述语言,被广泛应用于数字电路设计。

Verilog
具有模块化设计的特点,可以将一个大型的电路设计分解成多个小模块,然后逐个实现和调试。

本文将介绍Verilog多模块编程的实例,
以帮助读者了解如何使用Verilog进行模块化设计。

2. 模块化设计的优势
模块化设计是一种将大型系统分解成多个小模块的设计方法。

在Verilog中,模块化设计有以下几个优势:
- 提高代码可读性:通过将大型系统分解成多个小模块,可以提高代码的可读性和可维护性。

- 便于调试:每个小模块相对独立,可以单独调试和测试,提高了系统的可靠性和稳定性。

- 提高复用性:将功能相似的代码封装成模块,可以提高代码的复用性,减少代码冗余。

3. 多模块编程实例
接下来,我们将通过一个简单的数字电路设计来演示Verilog多模块
编程的实例。

假设我们要设计一个4位全加器电路,首先我们需要实
现一个单位全加器模块,然后将四个单元全加器模块连接成一个4位
全加器模块。

3.1 单位全加器模块
我们定义一个单位全加器模块,代码如下:
```verilog
module Adder_unit (
input a, b, cin,
output sum, cout
);
assign {cout, sum} = a + b + cin;
endmodule
```
在单位全加器模块中,我们定义了三个输入信号a、b、cin和两个输出信号sum、cout。

其中,sum表示相加的结果,cout表示进位。

在模块内部,我们通过assign语句实现了全加器的功能。

3.2 4位全加器模块
接下来,我们将四个单位全加器模块连接成一个4位全加器模块,代码如下:
```verilog
module Adder_4bit (
input [3:0] a, b,
input cin,
output [3:0] sum,
output cout
);
Adder_unit U0
(.a(a[0]), .b(b[0]), .cin(cin), .sum(sum[0]), .cout(cout0));
Adder_unit U1
(.a(a[1]), .b(b[1]), .cin(cout0), .sum(sum[1]), .cout(cout1)); Adder_unit U2
(.a(a[2]), .b(b[2]), .cin(cout1), .sum(sum[2]), .cout(cout2)); Adder_unit U3
(.a(a[3]), .b(b[3]), .cin(cout2), .sum(sum[3]), .cout(cout));
endmodule
```
在4位全加器模块中,我们首先定义了四个输入信号a、b和一个输入信号cin,以及四个输出信号sum和一个输出信号cout。

通过实例化四个单位全加器模块,并将它们连接成一个4位全加器模块。

4. 编译和仿真
完成了模块化设计后,我们可以对整个电路进行编译和仿真。

在Verilog中,可以使用常见的编译工具如Quartus、Vivado等对代码
进行编译,然后使用仿真工具进行波形仿真,验证电路设计的正确性。

5. 结论
本文介绍了Verilog多模块编程的实例,以帮助读者了解如何使用Verilog进行模块化设计。

在实际应用中,模块化设计是一种重要的设计方法,可以提高代码的可读性、可维护性和复用性。

希望本文能对
读者有所帮助,同时也欢迎读者在实践中进一步探索Verilog多模块
编程的技术。

合集下载

verilog中generate的用法

verilog中generate的用法

verilog中generate的用法
1. 嘿,你知道吗?generate 可以用来生成多个模块实例呢!就像有个魔法盒子,能变出好多一样的东西。

比如可以用它生成多个相同功能的计数器。

2. generate 还能根据条件来生成代码呀!这不就像是根据天气来决定穿什么衣服嘛,条件不同,生成的代码也不同。

比如根据参数决定是生成加法器还是减法器。

3. 哇塞,generate 能做循环生成代码呢!这简直就如同工厂的流水线,一批批地生产出代码模块。

像用它来循环生成一组寄存器。

4. 嘿,你想过没,generate 可以把复杂的代码结构变得清晰简洁呀!就好像把一团乱麻整理得整整齐齐。

比如说把多个相似的逻辑块用 generate 来组织。

5. 哎呀呀,generate 能让代码的灵活性大大增强呢!就好像给代码装上了灵活的关节,可以随意摆动。

比如根据不同的配置生成不同的电路结构。

6. 嘿,你瞧,generate 还能用来创建数组呢!这不就跟摆棋子一样,可以整齐地摆成一排。

像用它创建一个二维的信号数组。

7. 哇哦,generate 能帮助我们更好地管理大型设计呢!就如同有个厉害的管家,把一切都安排得井井有条。

比如在大规模的芯片设计中用它来组织模块。

8. 嘿,generate 在处理复杂逻辑关系时可太有用啦!就像解开一团纠结的线,让一切都清楚明白。

比如用它来实现根据多种条件切换的逻辑。

9. 你知道吗,generate 的用法真的是超级多呀!它简直就是我们写Verilog 代码的神器。

所以,一定要好好掌握它呀!。

system verilog 实例化参数模块

system verilog 实例化参数模块

system verilog 实例化参数模块如何在SystemVerilog中实例化参数化模块在SystemVerilog中,模块是一种组织硬件描述的方式。

参数化模块是一种允许用户在实例化时为模块参数传递值的工具。

在本篇文章中,我们将详细介绍如何在SystemVerilog中实例化参数化模块,并展示一些示例代码来帮助读者更好地理解。

参数化模块允许用户在实例化时为模块的参数传递不同的值。

这样可以根据实例化时提供的参数值,生成不同的硬件描述。

这对于设计具有不同配置或不同功能的模块非常有用。

参数化模块也可以提供一种动态生成硬件描述的方式。

首先,我们需要定义一个参数化模块。

在模块声明中,我们可以使用`#`符号来定义一个或多个参数。

例如,下面是一个具有两个参数的参数化模块的声明:systemverilogmodule MyParameterizedModule #(parameter WIDTH = 8, parameter DEPTH = 16) (input logic [WIDTH-1:0] data, input logic [DEPTH-1:0] address, output logic [WIDTH-1:0] output);模块的具体实现endmodule在这个例子中,我们定义了两个参数:`WIDTH`和`DEPTH`。

这些参数被用于定义`data`,`address`和`output`端口的位宽。

接下来,我们可以使用实际的参数值来实例化此参数化模块。

要在SystemVerilog中实例化一个参数化模块,我们需要在实例化语句中为参数提供值。

以下是一个实例化带有具体参数值的参数化模块的示例:systemverilogmodule MyTopModule;实例化参数化模块MyParameterizedModule #(8, 32)myInst(.data(in_data), .address(in_address), .output(out_data));顶层模块的其余部分endmodule在这个例子中,我们使用`(8, 32)`作为参数值实例化了`MyParameterizedModule`模块。

Verilog硬件描述语言(7)设计实例

Verilog硬件描述语言(7)设计实例

[例5]. 3-8译码器设计实例(利用赋 值语句设计组合逻辑) module decoder(out,in); output [7:0] out; input [2:0] in; assign out = 1‘b1<<in;/**** 把最低位的1 左移 in(根据从in口输入的值)位,并 赋予out ****/ endmodule
多路器设计方案之三: module mux3( out, a, b, sel); output out; input a, b, sel; reg out; always @( a or b or sel ) begin if( sel ) out = a; else out = b; end endmodule
[例9]. 输出驱动器设计实例 三态输出驱动器设计方案之一: module trist1( out, in, enable); output out; input in, enable; assign out = enable? in: 'bz; endmodule
三态输出驱动器设计方案之二: module trist2( out, in, enable ); output out; input in, enable;
[例3].利用task和电平敏感的always块设 计比较后重组信号的组合逻辑. module sort4(ra,rb,rc,rd,a,b,c,d); parameter t=3; output [t:0] ra, rb, rc, rd; input [t:0] a, b, c, d; reg [t:0] ra, rb, rc, rd; always @(a or b or c or d) //用电平敏感的always块描述组合逻辑

Verilog的135个经典设计实例

Verilog的135个经典设计实例

Verilog的135个经典设计实例1、立即数放大器:立即数放大器是一种用于将输入电平放大到更高电平的电路,它可以实现任意输入到输出的映射,并且可以在Verilog中使用。

立即数放大器的Verilog实现如下:module immedamp(in, out);input in;output out;reg [3:0] immed;assign out = immed[3];begincase (in)4'b0000: immed = 4'b1000;4'b0001: immed = 4'b1001;4'b0010: immed = 4'b1010;4'b0011: immed = 4'b1011;4'b0100: immed = 4'b1100;4'b0101: immed = 4'b1101;4'b0110: immed = 4'b1110;4'b0111: immed = 4'b1111;4'b1000: immed = 4'b1000;4'b1001: immed = 4'b1001;4'b1010: immed = 4'b1010;4'b1011: immed = 4'b1011;4'b1100: immed = 4'b1100;4'b1101: immed = 4'b1101;4'b1110: immed = 4'b1110;4'b1111: immed = 4'b1111;endcaseendendmodule2、多路复用器:多路复用器是一种用于将多个输入选择转换为单个输出的电路,它可以实现由多种方式选择的输出,并可以使用Verilog实现。

verilog hdl语言100例详解

verilog hdl语言100例详解

verilog hdl语言100例详解Verilog HDL语言是一种硬件描述语言,用于描述数字电路和系统的行为和结构。

它是硬件设计工程师在数字电路设计中的重要工具。

本文将介绍100个例子,详细解释Verilog HDL语言的应用。

1. 基本门电路:Verilog HDL可以用于描述基本门电路,如与门、或门、非门等。

例如,下面是一个描述与门电路的Verilog HDL代码:```verilogmodule and_gate(input a, input b, output y);assign y = a & b;endmodule```2. 多路选择器:Verilog HDL也可以用于描述多路选择器。

例如,下面是一个描述2:1多路选择器的Verilog HDL代码:```verilogmodule mux_2to1(input a, input b, input sel, output y);assign y = sel ? b : a;endmodule```3. 寄存器:Verilog HDL可以用于描述寄存器。

例如,下面是一个描述8位寄存器的Verilog HDL代码:```verilogmodule register_8bit(input [7:0] d, input clk, input reset, output reg [7:0] q);always @(posedge clk or posedge reset)if (reset)q <= 0;elseq <= d;endmodule```4. 计数器:Verilog HDL可以用于描述计数器。

例如,下面是一个描述8位计数器的Verilog HDL代码:```verilogmodule counter_8bit(input clk, input reset, output reg [7:0] count);always @(posedge clk or posedge reset)if (reset)count <= 0;elsecount <= count + 1;endmodule```5. 加法器:Verilog HDL可以用于描述加法器。

verilog的15个经典设计实例

verilog的15个经典设计实例
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);
【例 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
else
out<=out+1;
end
endmodule
//同步复位 //计数
【例 3.3】4 位全加器的仿真程序
`timescale 1ns/1ns `include "adder4.v" module adder_tp; reg[3:0] a,b; reg cin; wire[3:0] sum; wire cout; integer i,j;
output[7:0] qout;
output cout;
input[7:0] data;
input load,cin,clk,reset;

用verilog-a写的一些电路模块的例子

用verilog-a写的一些电路模块的例子以下是几个用Verilog-A 语言编写的电路模块的例子:1. 增益电路模块````include "disciplines.vams"module gain_circuit(va, vb, vout, g);input va, vb;output vout;parameter real g=10.0;analog beginvout = g * (va - vb);endendmodule```这个例子展示了一个简单的增益电路模块,其中输入是两个电压va、vb,输出是vout,增益系数为g。

在模块中使用了Verilog-A 的`analog begin` 语句来定义电路的行为。

2. RC 低通滤波器模块````include "disciplines.vams"module rc_lowpass_filter(vin, vout, r, c);input vin;output vout;parameter real r=1.0, c=1e-6;real v1;analog begini(vin, v1) <+ (vin - v1)/(r*c);vout <+ v1;endendmodule```这个例子展示了一个基于RC 电路的低通滤波器模块,其中输入为vin,输出为vout,RC 电路的参数由r 和c 决定。

在模块中使用了Verilog-A 的`i()` 语句来定义电路的行为。

3. 三角波发生器模块````include "disciplines.vams"module triangle_wave_generator(vout, freq, amp, dc);output vout;parameter real freq=1e3, amp=1.0, dc=0.0;real t;analog begint = $abstime;vout <+ amp * (2 * (t * freq - floor(t * freq + 0.5)) - 1) + dc;endendmodule```这个例子展示了一个简单的三角波发生器模块,其中输出为vout,频率由freq 决定,幅值由amp 决定,直流分量由dc 决定。

Verilog模块的实例化

Verilog模块的实例化实例化语句1. 例化语法一个模块能够在另外一个模块中被引用,这样就建立了描述的层次。

模块实例化语句形式如下:module_name instance_name(port_associations) ;信号端口可以通过位置或名称关联;但是关联方式不能够混合使用。

端口关联形式如下:port_expr / / 通过位置。

.PortName (port_expr) / / 通过名称。

例[1]:....module and (C,A,B);input A,B;output C;...and A1 (T3, A, B ); //实例化时采用位置关联,T3对应输出端口C,A对应A,B对应B。

and A2(//实例化时采用名字关联,.C是and 器件的端口,其与信号T3相连.C(T3),.A(A),.B(B));port_expr 可以是以下的任何类型:1) 标识符(reg 或net )如 .C(T3),T3为wire型标识符。

2) 位选择,如 .C(D[0]),C端口接到D信号的第0bit 位。

3) 部分选择,如 .Bus (Din[5:4])。

4) 上述类型的合并,如 .Addr({ A1,A2[1:0]}。

5) 表达式(只适用于输入端口),如 .A (wire Zire = 0 )。

建议:在例化的端口映射中请采用名字关联,这样,当被调用的模块管脚改变时不易出错。

2. 悬空端口的处理在我们的实例化中,可能有些管脚没用到,可在映射中采用空白处理,如:DFF d1 (.Q(QS),.Qbar ( ),.Data (D ) ,.Preset ( ), // 该管脚悬空.Clock (CK)); //名称对应方式。

对输入管脚悬空的,则该管脚输入为高阻Z,输出管脚被悬空的,该输出管脚废弃不用。

3. 不同端口长度的处理当端口和局部端口表达式的长度不同时,端口通过无符号数的右对齐或截断方式进行匹配。

verilog 组合逻辑例子

verilog 组合逻辑例子Verilog组合逻辑例子Verilog是一种硬件描述语言,常用于数字逻辑综合和编写硬件模块。

组合逻辑是Verilog中的一种基本类型,用于描述没有存储功能,只有输入和输出之间逻辑关系的电路。

以下是一些Verilog组合逻辑例子及其详细讲解。

1. 逻辑门AND门module and_gate(input a,input b,output y);assign y = a && b;endmodule在这个例子中,我们定义了一个AND门的模块。

它有两个输入a 和b,一个输出y。

通过assign语句,我们将输出y赋值为输入a和b 的逻辑与结果。

OR门module or_gate(input a,input b,output y);assign y = a || b;endmodule这是一个OR门的例子。

和AND门类似,我们通过assign语句将输出y赋值为输入a和b的逻辑或结果。

2. 多路选择器module mux(input a,input b,input c,input d,input [1:0] sel,output y);assign y = (sel == 2'b00) ? a :(sel == 2'b01) ? b :(sel == 2'b10) ? c :d;endmodule这个例子演示了一个4路多路选择器。

它有4个输入a、b、c和d,一个2位选择信号sel,一个输出y。

根据选择信号的不同值,输出y将根据如下规则选择不同的输入信号:00选择a,01选择b,10选择c,11选择d。

3. 比较器module comparator(input [3:0] a,input [3:0] b,output eq,output gt,output lt);assign eq = (a == b);assign gt = (a > b);assign lt = (a < b);endmodule上面的例子展示了一个比较器。

Verilog实例代码

【例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)beginif (reset) out<=0; //同步复位else out<=out+1; //计数endendmodule【例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的取值initialbegina=0;b=0;cin=0;for(i=1;i<16;i=i+1)#10 a=i; //设定a的取值endinitialbeginfor(j=1;j<16;j=j+1)#10 b=j; //设定b的取值endinitial//定义结果显示格式begin$monitor($time,,,"%d + %d + %b={%b,%d}",a,b,cin,cout,sum);#160 $finish;endendmodule【例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; //产生时钟波形initialbegin//激励信号定义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,Doutput F; //模块的输出端口为Fwire 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;endcaseendmodule【例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上升沿触发beginif (!reset) out = 8'h00; //同步清0,低电平有效else if (load) out = data; //同步预置else out = out + 1; //计数endendmodule【例5.3】用always过程语句描述的简单算术逻辑单元`define add 3'd0`define minus 3'd1`define band 3'd2`define bor 3'd3`define bnot 3'd4module 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块begincase(opcode)`add: out = a+b; //加操作`minus: out = a-b; //减操作`band: out = a&b; //求与`bor: out = a|b; //求或`bnot: out=~a; //求反default: out=8'hx; //未收到指令时,输出任意态endcaseendendmodule【例5.4】用initial过程语句对测试变量A、B、C赋值`timescale 1ns/1nsmodule test;reg A,B,C;initialbeginA = 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 ;endendmodule【例5.5】用begin-end串行块产生信号波形`timescale 10ns/1nsmodule wave1;reg wave;parameter cycle=10;initialbeginwave=0;#(cycle/2) wave=1;#(cycle/2) wave=0;#(cycle/2) wave=1;#(cycle/2) wave=0;#(cycle/2) wave=1;#(cycle/2) $finish ;endinitial $monitor($time,,,"wave=%b",wave); endmodule【例5.6】用fork-join并行块产生信号波形`timescale 10ns/1nsmodule wave2;reg wave;parameter cycle=5;initialforkwave=0;#(cycle) wave=1;#(2*cycle) wave=0;#(3*cycle) wave=1;#(4*cycle) wave=0;#(5*cycle) wave=1;#(6*cycle) $finish;joininitial $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)beginif(sel==0) out=a; //阻塞赋值else out=b;endendmodule【例5.9】非阻塞赋值module non_block(c,b,a,clk);output c,b;input clk,a;reg c,b;always @(posedge clk)beginb<=a;c<=b;endendmodule【例5.10】阻塞赋值module block(c,b,a,clk);output c,b;input clk,a;reg c,b;always @(posedge clk)beginb=a;c=b;endendmodule【例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上升沿时刻计数if (reset) qout<=0; //同步复位else if(load) qout<=data; //同步置数else if(cin)beginif(qout[3:0]==9) //低位是否为9,是则beginqout[3:0]<=0; //回0,并判断高位是否为5if (qout[7:4]==5) qout[7:4]<=0;elseqout[7:4]<=qout[7:4]+1; //高位不为5,则加1endelse//低位不为9,则加1qout[3:0]<=qout[3:0]+1;endendassign 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;alwaysbegincase(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;endcaseend【例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) begincasez(select)4'b???1: out = a;4'b??1?: out = b;4'b?1??: out = c;4'b1???: out = d;endcaseendendmodule【例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.15】用for语句描述的七人投票表决器module voter7(pass,vote);output pass;input[6:0] vote;reg[2:0] sum;integer i;reg pass;always @(vote)beginsum=0;for(i=0;i<=6;i=i+1) //for语句if(vote[i]) sum=sum+1;if(sum[2]) pass=1; //若超过4人赞成,则pass=1else pass=0;endendmodule【例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)beginoutcome=0;for(i=1; i<=size; i=i+1) //for语句if(b[i]) outcome=outcome +(a << (i-1));endendmodule【例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)beginoutcome=0;temp_a=a;temp_b=b;repeat(size) //repeat语句,size为循环次数beginif(temp_b[1]) //如果temp_b的最低位为1,就执行下面的加法outcome=outcome+temp_a;temp_a=temp_a<<1; //操作数a左移一位temp_b=temp_b>>1; //操作数b右移一位endendendmodule【例5.18】同一循环的不同实现方式module loop1; //方式1integer i;initialfor(i=0;i<4;i=i+1) //for语句begin$display(“i=%h”,i);endendmodulemodule loop2; //方式2integer i;initial begini=0;while(i<4) //while语句begin$display ("i=%h",i);i=i+1;endendendmodulemodule loop3; //方式3integer i;initial begini=0;repeat(4) //repeat语句begin$display ("i=%h",i);i=i+1;endendendmodule【例5.19】使用了`include语句的16位加法器`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;`elseassign out=A-B;`endifendmodule【例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;always @(posedge clk) //进程1,always过程块beginif (!reset) qout= 4'h00; //同步清0,低电平有效else if (load) qout= data; //同步预置else qout=qout + 1; //加法计数endassign 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//任务定义,注意无端口列表input//a,b,out名称的作用域范围为task任务内部output[4:0] out;integer i;beginfor(i=3;i>=0;i=i-1)out[i]=a[i]&b[i]; //按位与endendtaskalways@(code or a or b)begincase(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; //相加endcaseendendmodule【例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 begincode=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;endinitial $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;begincount=0;for (i=0;i<=7;i=i+1)if (x[i]=1'b0) count=count+1;get0=count;endendfunction【例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;endcaseendfunctionassign 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的上升沿时执行运算beginif(!reset) result<=0; //复位else beginresult <= 2 * factorial(n); //调用factorial函数endendfunction[31:0] factorial; //阶乘运算函数定义(注意无端口列表)input[3:0] opa; //函数只能定义输入端,输出端口为函数名本身reg[3:0] i;beginfactorial = opa ? 1 : 0;for(i= 2; i <= opa; i = i+1) //该句若要综合通过,opa应赋具体的数值factorial = i* factorial; //阶乘运算endfunctionendmodule【例6.7】测试程序`define clk_cycle 50`include "funct.v"module funct_tp;reg[3:0] n;reg reset,clk;wire[31:0] result;initial//定义激励向量beginn=0; reset=1; clk=0;for(n=0;n<=15;n=n+1)#100 n=n;endinitial $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】顺序执行模块1module serial1(q,a,clk);output q,a;input clk;reg q,a;always @(posedge clk)beginq=~q;a=~q;endendmodule【例6.9】顺序执行模块2module serial2(q,a,clk);input clk;reg q,a;always @(posedge clk)begina=~q;q=~q;endendmodule【例6.10】并行执行模块1 module paral1(q,a,clk); output q,a;input clk;reg q,a;always @(posedge clk)beginq=~q;endalways @(posedge clk)begina=~q;endendmodule【例6.11】并行执行模块2 module paral2(q,a,clk); output q,a;input clk;reg q,a;always @(posedge clk)begina=~q;endalways @(posedge clk)beginq=~q;endendmodulemodule 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 MUXmodule 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;endcaseendmodule【例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)beginif (clr) out<=0;else out<=out+1;endendmodule【例7.4】数据流方式描述的4选1 MUXmodule 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 MUXmodule 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选1MUXmodule 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选1MUXmodule mux2_1b(out,a,b,sel);output out;input a,b,sel;reg out;always @(a or b or sel)beginif(sel) out = b;else out = a;endendmodule【例7.8】数据流描述的2选1MUXmodule MUX2_1c(out,a,b,sel);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)begincase ({a,b}) //真值表描述2'b00: begin sum=0; cout=0; end2'b01: begin sum=1; cout=0; end2'b10: begin sum=1; cout=0; end2'b11: begin sum=0; cout=1; endendcaseendendmodule【例7.12】采用行为描述的1位半加器module half_add4(a,b,sum,cout);input a,b;reg sum,cout;always @(a or b)beginsum= a^b;cout=a&b;endendmodule【例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;reg sum,cout; //在always块中被赋值的变量应定义为reg型reg m1,m2,m3;always @(a or b or cin)beginsum = (a ^ b) ^ cin;m1 = a & b;m2 = b & cin;m3 = a & cin;cout = (m1|m2)|m3;endendmodule【例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块语句beginm1 = a & b;m2 = b & cin;m3 = a & cin;cout = (m1| m2) | m3;endassign 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);- 21 -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;endendmodule【例8.1】$time与$realtime的区别`timescale 10ns/1nsmodule time_dif;reg ts;parameter delay=2.6;initialbegin#delay ts=1;#delay ts=0;#delay ts=1;#delay ts=0;endinitial $monitor($time,,,"ts=%b",ts); //使用函数$time - 22 -endmodule【例8.2】$random函数的使用`timescale 10ns/1nsmodule random_tp;integer data;integer i;parameter delay=10;initial $monitor($time,,,"data=%b",data);initial beginfor(i=0; i<=100; i=i+1)#delay data=$random; //每次产生一个随机数endendmodule【例8.3】1位全加器进位输出UDP元件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;endtableendprimitive【例8.4】包含x态输入的1位全加器进位输出UDP元件primitive carry_udpx1(cout,cin,a,b);input cin,a,b;output cout;table// cin a b : cout //真值表0 0 0 : 0;- 23 -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,则进位输出肯定为00 x 0 : 0;x 0 0 : 0;1 1 x : 1; //只要有两个输入为1,则进位输出肯定为11 x 1 : 1;x 1 1 : 1;endtableendprimitive【例8.5】用简缩符“?”表述的1位全加器进位输出UDP元件primitive carry_udpx2(cout,cin,a,b);input cin,a,b;output cout;table// cin a b : cout //真值表? 0 0 : 0; //只要有两个输入为0,则进位输出肯定为00 ? 0 : 0;0 0 ? : 0;? 1 1 : 1; //只要有两个输入为1,则进位输出肯定为11 ? 1 : 1;1 1 ? : 1;endtableendprimitive【例8.6】3选1多路选择器UDP元件primitive mux31(Y,in0,in1,in2,s2,s1);input in0,in1,in2,s2,s1;output Y;table//in0 in1 in2 s2 s1 : Y0 ? ? 0 0 : 0; //当s2s1=00时,Y=in01 ? ? 0 0 : 1;? 0 ? 0 1 : 0; //当s2s1=01时,Y=in1- 24 -? 1 ? 0 1 : 1;? ? 0 1 ? : 0; //当s2s1=1?时,Y=in2? ? 1 1 ? : 1;0 0 ? 0 ? : 0;1 1 ? 0 ? : 1;0 ? 0 ? 0 : 0;1 ? 1 ? 0 : 1;? 0 0 ? 1 : 0;? 1 1 ? 1 : 1;endtableendprimitive【例8.7】电平敏感的1位数据锁存器UDP元件primitive latch(Q,clk,reset,D);input clk,reset,D;output Q;reg Q;initial Q = 1'b1; //初始化table// clk reset D : state : Q? 1 ? : ? : 0 ; //reset=1,则不管其他端口为什么值,输出都为00 0 0 : ? : 0 ; //clk=0,锁存器把D端的输入值输出0 0 1 : ? : 1 ;1 0 ? : ? : - ; //clk=1,锁存器的输出保持原值,用符号“-”表示endtableendprimitive【例8.8】上升沿触发的D触发器UDP元件primitive DFF(Q,D,clk);output Q;input D,clk;reg Q;table//clk D : state : Q(01) 0 : ? : 0; //上升沿到来,输出Q=D(01) 1 : ? : 1;(0x) 1 : 1 : 1;(0x) 0 : 0 : 0;(?0) ? : ? : -; //没有上升沿到来,输出Q保持原值? (??) : ? : - ; //时钟不变,输出也不变- 25 -endprimitive【例8.9】带异步置1和异步清零的上升沿触发的D触发器UDP元件primitive DFF_UDP(Q,D,clk,clr,set);output Q;input D,clk,clr,set;reg Q;table// clk D clr s et : 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; //异步置1n ? 0 0 : ? : -;? * ? ? : ? : -;? ? (?0) ? : ? : -;? ? ? (?0): ? : -;? ? ? ? : ? : x;endtableendprimitive【例8.12】延迟定义块举例module delay(out,a,b,c);output out;input a,b,c;and a1(n1,a,b);or o1(out,c,n1);specify(a=>out)=2;(b=>out)=3;(c=>out)=1;- 26 -endmodule【例8.13】激励波形的描述'timescale 1ns/1nsmodule test1;reg A,B,C;initialbegin//激励波形描述A = 0;B = 1;C = 0;#100 C = 1;#100 A = 1; B = 0;#100 A = 0;#100 C = 0;#100 $finish;endinitial $monitor($time,,,"A=%d B=%d C=%d",A,B,C); //显示endmodule【例8.15】用always过程块产生两个时钟信号module test2;reg clk1,clk2;parameter CYCLE = 100;alwaysbegin{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;endinitial $monitor($time,,,"clk1=%b clk2=%b",clk1,clk2);endmodule【例8.17】存储器在仿真程序中的应用module ROM(addr,data,oe);output[7:0] data; //数据信号input[14:0] addr; //地址信号input oe; //读使能信号,低电平有效- 27 -reg[7:0] mem[0:255]; //存储器定义parameter DELAY = 100;assign #DELAY data=(oe==0) ? mem[addr] : 8'hzz;initial $readmemh("rom.hex",mem); //从文件中读入数据endmodule【例8.18】8位乘法器的仿真程序`timescale 10ns/1nsmodule mult_tp; //测试模块的名字reg[7:0] a,b; //测试输入信号定义为reg型wire [15:0] out; //测试输出信号定义为wire型integer i,j;mult8 m1(out,a,b); //调用测试对象//激励波形设定initialbegina=0;b=0;for(i=1;i<255;i=i+1)#10 a=i;endinitialbeginfor(j=1;j<255;j=j+1)#10 b=j;endinitial//定义结果显示格式begin$monitor($time,,,"%d * %d= %d",a,b,out);#2560 $finish;endendmodulemodule mult8(out, a, b); //8位乘法器源代码parameter size=8;input[size:1] a,b; //两个操作数output[2*size:1] out; //结果assign out=a*b; //乘法运算符- 28 -endmodule【例8.19】8位加法器的仿真程序`timescale 1ns/1nsmodule add8_tp; //仿真模块无端口列表reg[7:0] A,B; //输入激励信号定义为reg型reg cin;wire[7:0] SUM; //输出信号定义为wire型wire cout;parameter DELY = 100;add8 AD1(SUM,cout,A,B,cin); //调用测试对象initial begin//激励波形设定A= 8'd0; B= 8'd0; cin=1'b0;#DELY A= 8'd100; B= 8'd200; cin=1'b1;#DELY A= 8'd200; B= 8'd88;#DELY A= 8'd210; B= 8'd18; cin=1'b0;#DELY A= 8'd12; B= 8'd12;#DELY A= 8'd100; B= 8'd154;#DELY A= 8'd255; B= 8'd255; cin=1'b1;#DELY $finish;end//输出格式定义initial $monitor($time,,,"%d + %d + %b = {%b, %d}",A,B,cin,cout,SUM); endmodulemodule add8(SUM,cout,A,B,cin); //待测试的8位加法器模块output[7:0] SUM;output cout;input[7:0] A,B;input cin;assign {cout,SUM}=A+B+cin;endmodule【例8.20】2选1多路选择器的仿真`timescale 1ns/1nsmodule mux_tp;reg a,b,sel;wire out;- 29 -MUX2_1 m1(out,a,b,sel); //调用待测试模块initialbegina=1'b0; b=1'b0; sel=1'b0;#5 sel=1'b1;#5 a=1'b1; s el=1'b0;#5 sel=1'b1;#5 a=1'b0; b=1'b1; sel=1'b0;#5 sel=1'b1;#5 a=1'b1; b=1'b1; sel=1'b0;#5 sel=1'b1;endinitial $monitor($time,,,"a=%b b=%b sel=%b out=%b",a,b,sel,out);endmodulemodule MUX2_1(out,a,b,sel); //待测试的2选1MUX模块input a,b,sel;output out;not #(0.4,0.3) (sel_,sel); //#(0.4,0.3)为门延时and #(0.7,0.6) (a1,a,sel_);and #(0.7,0.6) (a2,b,sel);or #(0.7,0.6) (out,a1,a2);endmodule【例8.21】8位计数器的仿真`timescale 10ns/1nsmodule count8_tp;reg clk,reset; //输入激励信号定义为reg型wire[7:0] qout; //输出信号定义为wire型parameter DELY=100;counter C1(qout,reset,clk); //调用测试对象always #(DELY/2) clk = ~clk; //产生时钟波形initialbegin//激励波形定义clk =0; reset=0;- 30 -#DELY reset=1;#DELY reset=0;#(DELY*300) $finish;end//结果显示initial $monitor($time,,,"clk=%d reset=%d qout=%d",clk,reset,qout); endmodulemodule counter(qout,reset,clk); //待测试的8位计数器模块output[7:0] qout;input clk,reset;reg[7:0] qout;always @(posedge clk)begin if (reset) qout<=0;else qout<=qout+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;- 31 -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);inout[7:0] bidir;input en,clk;reg[7:0] temp;assign bidir= en ? temp : 8'bz;always @(posedge clk)begin- 32 -if(en) temp=bidir;else temp=temp+1;endendmodule【例9.6】3-8译码器module decoder_38(out,in);output[7:0] out;input[2:0] in;reg[7:0] out;always @(in)begincase(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;endcaseendendmodule【例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)beginif(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;- 33 -else if(b) outtemp=4'b0001;else if(a) outtemp=4'b0000;else outtemp=4'b1000;endendmodule【例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;endfunctionassign dout = code(din); //函数调用endmodule【例9.9】七段数码管译码器module decode47(a,b,c,d,e,f,g,D3,D2,D1,D0);output a,b,c,d,e,f,g;input D3,D2,D1,D0; //输入的4位BCD码reg a,b,c,d,e,f,g;always @(D3 or D2 or D1 or D0)begincase({D3,D2,D1,D0}) //用case语句进行译码4'd0: {a,b,c,d,e,f,g}=7'b1111110;4'd1: {a,b,c,d,e,f,g}=7'b0110000;4'd2: {a,b,c,d,e,f,g}=7'b1101101;4'd3: {a,b,c,d,e,f,g}=7'b1111001;4'd4: {a,b,c,d,e,f,g}=7'b0110011;4'd5: {a,b,c,d,e,f,g}=7'b1011011;- 34 -4'd6: {a,b,c,d,e,f,g}=7'b1011111;4'd7: {a,b,c,d,e,f,g}=7'b1110000;4'd8: {a,b,c,d,e,f,g}=7'b1111111;4'd9: {a,b,c,d,e,f,g}=7'b1111011;default: {a,b,c,d,e,f,g}=7'bx;endcaseendendmodule【例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 MUXmodule 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)beginif(sel==2'b00) out=in0;else if(sel==2'b01) out=in1;else if(sel==2'b10) out=in2;else out=in3;endendmodule【例9.12】用case语句描述的4选1 MUXmodule 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- 35 -。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档