第9章数字系统设计verilog HDL(第6版)王金明

合集下载

精品课件-Verilog HDL数字系统设计-Verilog HDL数字系统设计-第1章

精品课件-Verilog HDL数字系统设计-Verilog HDL数字系统设计-第1章

编程器件的基础上进一步发展的产物,它是作为ASIC领域中的 一种半定制电路而出现的,既解决了定制电路的不足,又克服 了原有可编程器件门电路有限的缺点。
第1章 概 述
26
如前所述,FPGA是由存放在片内的RAM来设置其工作状态的, 因此工作时需要对片内RAM进行编程。用户可根据不同的配置模 式,采用不同的编程方式。FPGA有如下几种配置模式:
第1章 概 述
1
第1章 概

1.1 EDA技术简介 1.2 可编程器件 1.3 Verilog HDL简介
第1章 概 述
2
1.1 EDA技术简介
现代电子设计技术的核心已日趋转向基于计算机的电子设 计自动化(EDA,Electronic Design Automation)技术。所谓 EDA技术,就是依赖功能强大的计算机,在EDA工具软件平台上, 对以硬件描述语言(HDL,Hardware Description Language)为 系统逻辑描述手段完成的设计文件,自动地进行逻辑编译、化 简、分割、综合、布局布线以及逻辑优化和仿真测试,直至实 现既定的电子线路系统功能。
6.目标器件的编程/下载 7.硬件仿真与测试
第1章 概 述
18
1.2 可 编 程 器 件
1.2.1 可编程逻辑器件概述 随着数字电路的普及,传统的定制数字集成电路器件已满
足不了应用的需求,可编程逻辑器件(PLD)应运而生,并逐渐地 成为主流产品。PLD与传统定制器件的主要区别是它的可编程性, 它的逻辑功能是由用户设计的,并且一般都可重复编程和擦除, 即PLD是能够为客户提供范围广泛的多种逻辑能力、特性、速度 和电压特性的标准成品部件,而且此类器件的功能可在任何时 间修改,从而实现多种不同的功能。对于可编程逻辑器件,设 计人员可利用价格低廉的软件工具快速开发、仿真和测试其设 计。

数字系统设计verilog HDL 第 版 王金明

数字系统设计verilog HDL 第 版 王金明

第3章 Quartus Prime使用指南3.1 Quartus Prime原理图设计n3.1.1 半加器原理图设计输入Quartus Prime的主界面Quartus Prime的主界面3.1.1 半加器原理图设计输入输入元件Quartus Prime的主界面3.1.1 半加器原理图设计输入半加器电路图Quartus Prime的主界面3.1.1 半加器原理图设计输入使用New Project Wizard创建工程Quartus Prime的主界面3.1.1 半加器原理图设计输入设置Directory,Name,Top-Level Entity对话框Quartus Prime的主界面3.1.1 半加器原理图设计输入将设计文件加入当前工程中Quartus Prime的主界面3.1.1 半加器原理图设计输入选择目标器件Quartus Prime的主界面3.1.1 半加器原理图设计输入选择综合器、仿真器Quartus Prime的主界面3.1.1 半加器原理图设计输入工程信息汇总显示Quartus Prime的主界面3.1.2 1位全加器设计输入Quartus Prime的主界面创建元件符号对话框3.1.2 1位全加器设计输入Quartus Prime的主界面1位全加器原理图3.1.3 1位全加器的编译n选择菜单Processing→Start Compilation,或者单击按钮,即启动了完全编译,完全编译包括如下5个过程:n分析与综合(Analysis & Synthesis);n适配(Fitter);n装配(Assembler);n定时分析(TimeQuest Timing Analysis);n网表文件提取(EDA Netlist Writer)。

Quartus Prime的主界面3.1.3 1位全加器的编译Quartus Prime的主界面编译信息汇总3.1.4 1位全加器的仿真Quartus Prime的主界面建立Quartus Prime和Modelsim的链接3.1.4 1位全加器的仿真Quartus Prime的主界面设置仿真文件的格式和目录3.1.4 1位全加器的仿真Quartus Prime的主界面自动生成的Test Bench模板文件3.1.4 1位全加器的仿真Quartus Prime的主界面对Test Bench进一步设置3.1.4 1位全加器的仿真1位全加器时序仿真波形图Quartus Prime的主界面3.1.5 1位全加器的下载n本例针对的下载板为DE2-115,故目标器件应为:EP4CE115F29C7。

《EDA技术》教学大纲

《EDA技术》教学大纲

课程编号:04021144《EDA技术》课程教学大纲学时:48 学分:3一、教学大纲的说明1、授课对象:电子信息工程专业、四年制本科2、课程性质:专业方向类必修课3、任务及要求:电子设计自动化(EDA)是电子信息类专业的一门重要课程。

EDA是20世纪90年代初发展起来的新技术。

本课程的任务是使学生学习和掌握可编程逻辑器件、EDA开发系统软件以及硬件描述语言(VHDL),为掌握EDA技术打下必要的基础;初步学会应用EDA技术解决一些简单的电子设计问题。

4、与其它课程的联系:先修课程:模拟电子技术、数字电子技术、Java语言与程序设计后续课程:电子系统设计二、教学大纲1、课程内容:第一章EDA技术概述EDA技术的由来、可编程逻辑器件的发展历程、可编程逻辑器件产品简介、硬件描述语言简介。

通过本章的学习,使学生对EDA技术有一个初步的认识。

第二章EDA设计流程及其工具设计流程、EDA开发工具简介。

通过本章的学习,使学生对常用EDA开发工具有一个初步的认识。

第三章FPGA/CPLD结构与应用本章具体介绍数种可编程逻辑器件。

通过本章的学习,使学生深入了解可编程逻辑器件,为掌握EDA技术打下坚实的基础。

第四章原理图输入设计方法本章通过实例详细介绍了Quartus II软件中原理图输入设计方法、波形输入设计方法。

第五、六、七、八、九章VHDL设计VHDL程序结构、VHDL语言要素、VHDL顺序语句、VHDL并行语句、VHDL的描述风格、仿真、综合。

本章内容是介绍一种通用的硬件描述语言VHDL。

该语言与一般的计算机高级语言有相似之处,但是它是以硬件为目标的。

通过本章的学习,应掌握VHDL的主要内容,并通过上机操作,学会编程方法。

第十章设计优化和设计方法介绍面积优化、速度优化的常用方法,并详细介绍如何在Quartus II软件中实现上述优化。

第十一章EDA工具软件接口介绍Quartus II软件与常用第三方EDA软件如Synplify、ModelSim的接口方法。

数字系统设计与veriloghdl课后答案

数字系统设计与veriloghdl课后答案

数字系统设计与veriloghdl课后答案数字系统设计与veriloghdl课后答案【篇一:数字逻辑与数字系统设计习题参考答案】>第1章习题解答1.3 (1)86(2)219(3)106.25(4)0.6875 (4)0.1011.4 (1)101111(2)1001000(3)100001l.111.5 (1)(117)10=(165)8=(1110101)2=(75)16(2)(3452)10=(6574)8=(110101111100)2=(d7c)16(3)(23768.6875)10=(56330.54)8=(101110011011000.1011)2 =(5cd 8.b)16 (4)(0.625)10=(0.5)8=(0.101)2=(0.a)16 1.6(1)(117)8=(1001111)2=(79)10(2)(7456)8=(111100101110)2=(3886)10(3)(23765.64)8=(10 0111 1111 0101.1101)2=(10229.8125)10(4)(0.746)8=(0.11111)2=(0.96875)10 1.7 (1)(9a)16=(10011010)2=(154)10(2) (3cf6)16=(11110011110110)2=(15606)10(3) (7ffe.6)16=(111111*********.011)2=(32766.375)10 (4)(0.c4)16=(0.110001)2=(0.765625)10 1-8(1)(125)10=(000100100101)8421bcd(2)(7342)10=(0111001101000010)8421bcd(3)(2018.49)10=(0010000000011000.01001001)8421bcd(4)(0.785)10=(0.011110000101)8421bcd1.9(1)(106)10=(1101010)2 原码=反码=补码=01101010 (2)(-98)10=(-1100010)2原码=11100010反码=10011101 补码=11100011(3)(-123)10=(-1111011)2 原码=11111011反码=10000101 补码=11111011(4)(-0.8125)10=(-0.1101)2 原码=1.1101000反码=1.0010111 补码=1.00110001.10(1)(104)10=(1101000)2 [1101000]补=01101000(-97)10=(-1100001)2 [-1100001]补=1001111101101000 + 10011111 0000011110000011 + 01001111 11010010[104-97]补=01101000+10011111=00000111, 104-97=(00000111)2=7 (2) (-125)10=(-1111101)2(79)10=(01001111)2[-1111101]补=10000011 [01001111]补=0100111101111000 [-125+79]补=10000011+01001111=11010010,- 125+79=(-0101110)2=-46 (3) (120)10=(1111000)2[01111000]补=01111000(-67)10=(-1000011)2[-1000011]补=10111101[120-67]补=10000011+01001111=00110101,-125+79=(00110101)2=53 (4) (-87)10=(-1010111)2[-1010111]补=10101001(12)10=(1100)2[1100]补=00001100[-87+12]补=10101001+00001100=10110101,-125+79=(-1001011)2=-75+ 10111101 0011010110101001+ 00001100 10110101第2章习题解答2.3 解:根据逻辑图可直接写出逻辑表达式:(a) f=ab?bc;(b)f=abbcac解:设3个输入变量分别为a、b、c,输出为f,按题意,其中有奇数个为1,则输出f=1,因此可写出其逻辑表达式为f=abc?abc?abc?abc。

第9章数字系统设计verilog HDL(第6版)王金明

第9章数字系统设计verilog HDL(第6版)王金明

第9章 Verilog设计进阶9.1 加法器设计(1)级连加法器8位级连加法器module add_jl(sum,cout,a,b,cin);input[7:0] a,b;input cin;output[7:0] sum;output cout;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); full_add1 f3(a[3],b[3],cin3,sum[3],cin4); full_add1 f4(a[4],b[4],cin4,sum[4],cin5); full_add1 f5(a[5],b[5],cin5,sum[5],cin6); full_add1 f6(a[6],b[6],cin6,sum[6],cin7); full_add1 f7(a[7],b[7],cin7,sum[7],cout); endmodule(2)数据流描述的加法器module add_bx(cout,sum,a,b,cin); parameter WIDTH=8; input cin; output cout; input[WIDTH-1:0] a,b; output[WIDTH-1:0] sum; assign {cout,sum}=a+b+cin;endmodule(3) 8位超前进位加法器moduleadd_ahead(sum,cout,a,b,cin); input[7:0] a,b;input cin;output[7:0] sum;output cout;wire[7:0] G,P;wire[7:0] C,sum;assign G[0]=a[0]&b[0]; assign P[0]=a[0]|b[0]; assign C[0]=cin;assign sum[0]=G[0]^P[0]^C[0]; assign G[1]=a[1]&b[1]; assign P[1]=a[1]|b[1]; assign C[1]=G[0]|(P[0]&cin); assign sum[1]=G[1]^P[1]^C[1]; assign G[2]=a[2]&b[2]; assign P[2]=a[2]|b[2]; assign C[2]=G[1]|(P[1]&C[1]); assign sum[2]=G[2]^P[2]^C[2]; assign G[3]=a[3]&b[3]; assign P[3]=a[3]|b[3]; assign C[3]=G[2]|(P[2]&C[2]); assign sum[3]=G[3]^P[3]^C[3];assign G[4]=a[4]&b[4]; assign P[4]=a[4]|b[4]; assign C[4]=G[3]|(P[3]&C[3]); assign sum[4]=G[2]^P[2]^C[2]; assign G[5]=a[5]&b[5]; assign P[5]=a[5]|b[5]; assign C[5]=G[4]|(P[4]&C[4]); assign sum[5]=G[5]^P[5]^C[5]; assign G[6]=a[6]&b[6]; assign P[6]=a[6]|b[6]; assign C[6]=G[5]|(P[5]&C[5]); assign sum[6]=G[6]^P[6]^C[6]; assign G[7]=a[7]&b[7]; assign P[7]=a[7]|b[7]; assign C[7]=G[6]|(P[6]&C[6]); assign sum[7]=G[7]^P[7]^C[7]; assign cout=G[7]|(P[7]&C[7]); endmodule(4)流水线加法器module adder8(cout,sum,a,b,cin,enable); input[7:0] a,b; input cin,enable; output[7:0] sum; reg[7:0] sum;output cout;reg cout;reg[3:0] tempa,tempb,firsts; reg firstc; always @(posedge enable)begin{firstc,firsts}=a[3:0]+b[3:0]+cin; tempa=a[7:4]; tempb=b[7:4];endalways @(posedge enable)begin{cout,sum[7:4]}=tempa+tempb+firstc; sum[3:0]=firsts;endendmodule9.2 乘法器)并行乘法器(1module mult(outcome,a,b); parameter size=8;input[size:1] a,b;output[2*size:1] outcome; assign outcome=a*b;endmodule8×8并行乘法器的门级综合原理图(2)移位相加乘法器4×4移位相加乘法操作示意图8位移位相加乘法器顶层设计8位移位相加乘法器时序仿真波形(3)布斯乘法器(4)查找表乘法器9.3 奇数分频与小数分频(1)奇数分频module count7(reset,clk,cout);input clk,reset; output wire cout;reg[2:0] m,n; reg cout1,cout2;assign cout=cout1|cout2;//两个计数器的输出相或always @(posedge clk)beginif(!reset) begin cout1<=0; m<=0; endelse begin if(m==6) m<=0; else m<=m+1;if(m<3) cout1<=1;else cout1<=0; end endalways @(negedge clk)beginif(!reset) begin cout2<=0; n<=0; endelse begin if(n==6) n<=0; else n<=n+1;if(n<3) cout2<=1; else cout2<=0; end endendmodule模7奇数分频器功能仿真波形图(Quartus Ⅱ)module count_num(reset,clk,cout);parameter NUM=13;input clk,reset; output wire cout;reg[4:0] m,n; reg cout1,cout2;assign cout=cout1|cout2;always @(posedge clk)begin if(!reset) begin cout1<=0; m<=0; endelsebegin if(m==NUM-1) m<=0; else m<=m+1;if(m<(NUM-1)/2) cout1<=1; else cout1<=0;endendalways @(negedge clk)begin if(!reset) begin cout2<=0; n<=0; endelse beginif(n==NUM-1) n<=0; else n<=n+1;if(n<(NUM-1)/2) cout2<=1; else cout2<=0; end endendmodule模13奇数分频器功能仿真波形图(Quartus Ⅱ)module fdiv5_5(clkin,clr,clkout);input clkin,clr; output reg clkout;reg clk1; wire clk2; integer count;xor xor1(clk2,clkin,clk1); //异或门always@(posedge clkout or negedge clr) //2分频器begin if(~clr) begin clk1<=1'b0; endelse clk1<=~clk1;endalways@(posedge clk2 or negedge clr) //模5分频器begin if(~clr)begin count<=0; clkout<=1'b0; endelse if(count==5) //要改变分频器的模,只需改变count的值begin count<=0; clkout<=1'b1; endelse begin count<=count+1; clkout<=1'b0; end endendmodule功能仿真波形5.5倍半整数分频器功能仿真波形图(Quartus Ⅱ)小数分频module fdiv8_1(clk_in,rst,clk_out);input clk_in,rst; output reg clk_out;reg[3:0] cnt1,cnt2;//cnt1计分频的次数always@(posedge clk_in or posedge rst)begin if(rst) begin cnt1<=0; cnt2<=0; clk_out<=0; endelse if(cnt1<9)//9次8分频begin if(cnt2<7) begin cnt2<=cnt2+1; clk_out<=0; end else begin cnt2<=0; cnt1<=cnt1+1; clk_out<=1; end end else begin //1次9分频if(cnt2<8) begin cnt2<=cnt2+1; clk_out<=0; end else begin cnt2<=0; cnt1<=0; clk_out<=1; endend endendmodule8.1小数分频功能仿真波形(Quartus Ⅱ)9.4 VGA图像显示控制器设计VGA 行扫描时序VGA 场扫描时序标准VGA显示模式行、场扫描的时序行扫描时序要求(单位:像素,输出一个Pixel的时间间隔)行同步头行图像行周期对应位置H_Tf H_Ta H_Tb H_Tc H_Td H_Te H_Tg时间/Pixels8964086408800场扫描时序要求(单位:行,输出一行Line的时间间隔)场同步头场图像场周期对应位置V_Tf V_Ta V_Tb V_Tc V_Td V_Te V_Tg时间/Lines222584808525VGA图像显示控制器设计VGA图像显示控制器结构框图R,G,B三基色信号分别采用5 bit,6 bit,5 bit表示的LENA图像9.5 点阵式液晶显示控制GDM12864的结构及指令“写数据”时序图液晶控制9.6 乐曲演奏电路乐曲演奏的原理乐曲演奏电路原理框图习题 9习题 9习题 9实验与设计。

verilogHDL(王金明版源码)

verilogHDL(王金明版源码)

王金明:《Verilog HDL 程序设计教程》- 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)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`timescale 1ns/1ns`include "alu.v"module alu_tb;wire [7:0] out;reg [7:0] a,b;reg [2:0] opcode;initialbegina = 8'h12;b = 8'h34;opcode = `add;#10 opcode = `minus;#10 opcode = `band;#10 opcode = `bor;#10 opcode = `bnot;endalu alu(.out(out),.a(a),.b(b),.opcode(opcode)); endmodule【例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`timescale 1ns/1ns`include "block.v"module block_tb;wire c,b;reg clk,a;initialbeginclk = 0;a = 0;#30 a = 1;#30 a = 0;#30 a = 1;#30 $stop;endalways #10 clk = ~clk;block block(.c(c),.b(b),.clk(clk),.a(a));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 上升沿时刻计数beginif (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`timescale 1ns/1ns`include "count60.v"module count60_tb;wire [7:0] qout;wire cout;reg [7:0] data;reg load,cin,clk,reset;always #5 clk = ~clk;count60cnt(.qout(qout),.cout(cout),.data(data),.load(load),.cin(cin),.cl k(clk),.reset(reset));initialbeginclk = 0;reset = 1;load = 1; cin = 0; data = 8'h25;#20 reset = 0;#20 load = 0;#30 cin = 1;#100 load = 1;#30 load = 0;#300 cin = 0;#50 cin = 1;#500 $stop;endendmodule【例5.12】BCD 码—七段数码管显示译码器module decode4_7(decodeout,indec);output[6:0] decodeout;input[3:0] indec;reg[6:0] decodeout;always @(indec)begincase(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;endcaseendendmodule【例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'b1: 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;- 9 -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 左移一位程序文本- 10 -temp_b=temp_b>>1; //操作数b 右移一位endendendmodule`include "mult_repeat.v"module mult_repeat_tb;parameter size = 8;reg [size:1] a,b;wire [2*size:1] outcome;initialbegina = 8'h25;b = 8'h16;#10 a = 8'ha4; b = 8'h20;endmult_repeat mult(.a(a),.b(b),.outcome(outcome)); endmodule【例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 位加法器- 11 -`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 //宏名为addassign 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;程序文本- 12 -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 my_and; //任务定义,注意无端口列表input[3:0] a,b; //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- 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 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;程序文本- 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;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; //阶乘运算end- 15 -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 #1 `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);output q,a;程序文本- 16 -input clk;reg q,a;always @(posedge clk)begina=~q;q=~q;endendmodule【例6.10】并行执行模块1module 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】并行执行模块2module paral2(q,a,clk);output q,a;input clk;reg q,a;always @(posedge clk)begina=~q;endalways @(posedge clk)beginq=~q;endendmodule【例7.1】调用门元件实现的4 选1 MUX- 17 -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 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程序文本- 18 -【例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 选1MUX module MUX2_1c(out,a,b,sel); output out;- 19 -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; end endcaseendendmodule【例7.12】采用行为描述的1 位半加器module half_add4(a,b,sum,cout); input a,b;output sum,cout;程序文本- 20 -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;output sum,cout;- 21 -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);程序文本- 22 -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- 23 -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;程序文本- 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,则进位输出肯定为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;// 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- 25 -1 0 1 : 1;0 1 : 0; //当s2s1=1?时,Y=in21 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;initial Q = 1'b1; //初始化table// clk reset D : state : Q1 : : 0 ; //reset=1,则不管其他端口为什么值,输出都为0 0 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 保持原值() : : - ; //时钟不变,输出也不变程序文本- 26 -endtableendprimitive【例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 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; //异步置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;- 27 -endspecifyendmodule【例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; //读使能信号,低电平有效程序文本- 28 -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 mult8_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; //乘法运算符- 29 -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;程序文本- 30 -MUX2_1 m1(out,a,b,sel); //调用待测试模块initialbegina=1'b0; b=1'b0; sel=1'b0;#5 sel=1'b1;#5 a=1'b1; sel=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 counter8_tp;reg clk,reset; //输入激励信号定义为reg 型wire[7:0] qout; //输出信号定义为wire 型parameter DELY=100;counter8 C1(qout,reset,clk); //调用测试对象always #(DELY/2) clk = ~clk; //产生时钟波形initialbegin //激励波形定义clk =0; reset=0;- 31 -#DELY reset=1;#DELY reset=0;#(DELY*300) $finish;end//结果显示initial $monitor($time,,,"clk=%d reset=%d qout=%d",clk,reset,qout); endmodulemodule counter8(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;程序文本- 32 -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- 33 -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;。

第5章数字系统设计verilog HDL(第6版)王金明

第5章数字系统设计verilog HDL(第6版)王金明

第5章 Verilog语法与要素5.1 Verilog语言要素空白符和注释标识符(Identifiers)=count=COUNT //COUNT与count是不同的=_A1_d2 //以下划线开头=R56_68=FIVE关键字(Keywords)5.2 常量实数(Real)字符串(Strings)5.3 数据类型数据类型5.3.1 net型5.3.2 Variable型5.4 参数(parameter)【例5.2】采用参数定义的数据比较器module compare_w(a,b,larger,equal,less); parameter SIZE=6; //参数定义input[SIZE-1:0] a,b;output larger,equal,less;wire larger,equal,less;assign larger=(a>b);assign equal=(a==b);assign less=(a<b);endmodule【例5.3】采用参数定义的加法器module add_w(a,b,sum); parameter MSB=15; //参数定义input[MSB:0] a,b;output[MSB+1:0] sum;assign sum=a+b; endmodule【例5.4】采用参数定义的二进制计数器module count_w(en,clk,reset,out); input clk,reset,en;parameter WIDTH=8; //参数定义output[WIDTH-1:0] out;reg[WIDTH-1:0] out;always @(posedge clk or negedge reset) if(!reset) out=0;else if(en) out=out+1; endmodule5.5 向量n1.标量与向量宽度为1位的变量称为标量,如果在变量声明中没有指定位宽,则默认为标量(1位)。

EDA技术与Verilog设计王金明版第12章Verilog语言的发展

EDA技术与Verilog设计王金明版第12章Verilog语言的发展

EDA技术与Verilog设计王金明版第12章Verilog语言的发展EDA技术与Verilog设计是现代数字电路设计中非常重要的两个方面。

EDA技术(Electronic Design Automation)是指利用计算机辅助设计工具来帮助进行电子系统的设计和验证。

Verilog是一种硬件描述语言(HDL),用于设计和描述数字电路。

本文将重点介绍Verilog语言的发展。

Verilog语言最初由Gateway Design Automation公司的Phil Moorby和Prabhu Goel于1983年开始开发,用于辅助数字电路设计。

当时的数字电路设计主要使用原理图和编程方式,导致设计效率低下和错误的增多。

为了解决这些问题,硬件描述语言应运而生。

最早的Verilog语言是在原始C语言的基础上进行扩展,引入了许多与硬件相关的特性。

这使得Verilog的语法相对于C语言更加接近硬件描述。

Verilog语言可以描述电路的功能和结构,包括时序逻辑、组合逻辑、寄存器和存储器等。

随着硬件设计需求的不断增加,Verilog语言不断发展。

VerilogHDL 1364标准于1995年发布,引入了许多新的功能和特性。

其中最重要的是系统任务和函数,用于模拟系统级行为。

SystemVerilog语言于2002年推出,是Verilog HDL的扩展,引入了更多的高层次设计特性和验证特性。

Verilog语言的发展主要有以下几个方面的影响:1. 高层次综合(High-Level Synthesis,HLS)技术的发展对Verilog语言产生了深远的影响。

HLS技术允许设计者以高层次的抽象描述电路功能,然后将其自动转化为硬件电路。

这大大提高了设计的效率和可移植性。

Verilog语言的发展也使得其更加适合进行高层次综合。

2. 验证技术的发展也推动了Verilog语言的演进。

在设计过程中,验证是非常重要的一环。

随着电路规模的不断增加,传统的模拟仿真已经无法满足验证的需求。

第7章数字系统设计verilog HDL(第6版)王金明

第7章数字系统设计verilog HDL(第6版)王金明

第7章 Verilog设计的层次与风格7.1 Verilog设计的层次Verilog设计的描述风格7.2 结构(Structural)描述内置门元件【例7.1】调用门元件实现的4选1 MUXmodule mux4_1a(out,in1,in2,in3,in4,s0,s1); input in1,in2,in3,in4,s0,s1; output out; wire s0_n,s1_n,w,x,y,z;not (sel0_n,s0),(s1_n,s1);and (w,in1,s0_n,s1_n),(x,in2,s0_n,s1), (y,in3,s0,s1_n),(z,in4,s0,s1);or (out,w,x,y,z);endmodule用基本门实现的4选1 MUX7.3 行为描述【例7.2】用case语句描述的4选1 MUXmodule mux4_1b(out,in1,in2,in3,in4,s0,s1); input in1,in2,in3,in4,s0,s1;output reg out;always@(*) //使用通配符 case({s0,s1})2'b00:out=in1;2'b01:out=in2;2'b10:out=in3;2'b11:out=in4;default:out=2'bx;endcaseendmodule采用行为描述方式时需注意7.4 数据流描述【例7.4】数据流描述的4选1 MUXmodule mux4_1c(out,in1,in2,in3,in4,s0,s1); input in1,in2,in3,in4,s0,s1;output out;assign out=(in1 & ~s0 & ~s1)|(in2 & ~s0 & s1)| (in3& s0 & ~s1)|(in4 & s0 & s1); endmodule数据流描述7.5 不同描述风格的设计【例7.12】调用门元件实现的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数据流描述的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行为描述的1位全加器【例7.14】行为描述的1位全加器module full_add3(a,b,cin,sum,cout); input a,b,cin;output reg sum,cout;always @*//或写为always @(a or b or cin) begin{cout,sum}=a+b+cin;endendmodule采用层次化方式设计1位全加器两个半加器构成一个全加器【例7.15】用模块例化方式设计的1位全加器顶层设计module full_add(ain,bin,cin,sum,cout); input ain,bin,cin;output sum,cout;wire d,e,f; //用于内部连接的节点信号half_add u1(ain,bin,e,d);//半加器模块调用,采用位置关联方式half_add u2(e,cin,sum,f);or u3(cout,d,f); //或门调用endmodule【例7.16】半加器定义module half_add(a,b,so,co); input a,b;output so,co;assign co=a&b; assign so=a^b; endmodule4位加法器设计结构描述的4位级连全加器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); full_add1 f3(a[3],b[3],cin3,sum[3],cout); endmodule【例7.18】数据流描述的4位加法器module add4_2(cout,sum,a,b,cin); input cin; input[3:0] a,b; output[3:0] sum;output cout;assign {cout,sum}=a+b+cin; endmodule7.6 多层次结构电路的设计1.图形与文本混合设计8位全加器module add8(sum,cout,b,a,cin); output[7:0] sum;output cout;input[7:0] a,b;input cin;assign {cout,sum}=a+b+cin; endmodule 8位寄存器module reg8(qout,in,clk,clear); output[7:0] qout;input[7:0] in;input clk,clear;reg[7:0] qout;always @(posedge clk or posedge clear)beginif(clear) qout<=0; //异步清0 else qout<=in;endendmodule2.文本设计module acc(accout,cout,accin,cin,clk,clear); output[7:0] accout;output cout;input[7:0] accin;input cin,clk,clear;wire[7:0] sum;add8 accadd8(sum,cout,accout,accin,cin);//调用add8子模块reg8 accreg8(accout,sum,clk,clear);//调用reg8子模块endmodule累加器顶层文本描述模块调用7.7 基本组合电路设计门级结构描述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数据流描述module gate2(F,A,B,C,D);input A,B,C,D;output F;assign F=(A&B)|(B&C&D);endmodule【例7.24】 74138的Verilog描述module ttl74138(a,y,g1,g2a,g2b);input[2:0] a; input g1,g2a,g2b; output reg[7:0] y; always @(*)begin if(g1 & ~g2a & ~g2b)//只有当g1、g2a、g2b为100时,译码器使能begin case(a)3'b000:y=8'b11111110; //译码输出3'b001:y=8'b11111101;3'b010:y=8'b11111011;3'b011:y=8'b11110111;3'b100:y=8'b11101111;3'b101:y=8'b11011111;3'b110:y=8'b10111111;3'b111:y=8'b01111111;default:y=8'b11111111;endcase endelse y=8'b11111111;endendmodule【例7.25】 8线—3线优先编码器74148的Verilog描述module ttl74148(din,ei,gs,eo,dout);input[7:0] din; input ei; output reg gs,eo; output reg[2:0] dout;always @(ei,din)begin if(ei) begin dout<=3'b111;gs<=1'b1;eo<=1'b1; end else if(din==8'b111111111) begindout<=3'b111;gs<=1'b1;eo<=1'b0;endelse if(!din[7]) begin dout<=3'b000;gs<=1'b0;eo<=1'b1;end else if(!din[6]) begin dout<=3'b001;gs<=1'b0;eo<=1'b1;end else if(!din[5]) begin dout<=3'b010;gs<=1'b0;eo<=1'b1;end else if(!din[4]) begin dout<=3'b011;gs<=1'b0;eo<=1'b1;end else if(!din[3]) begin dout<=3'b100;gs<=1'b0;eo<=1'b1;end else if(!din[2]) begin dout<=3'b101;gs<=1'b0;eo<=1'b1;end else if(!din[1]) begin dout<=3'b110;gs<=1'b0;eo<=1'b1;end else begin dout<=3'b111;gs<=1'b0;eo<=1'b1;endendendmodule【例7.27】奇偶校验位产生器module parity(even_bit,odd_bit,a); input[7:0] a;output even_bit,odd_bit;assign even_bit=^a;//生成偶校验位assign odd_bit=~even_bit;//生成奇校验位endmodule7.8 基本时序电路设计【例7.29】带异步清0/异步置1的JK触发器module jkff_rs(clk,j,k,q,rs,set);input clk,j,k,set,rs; output reg q;always @(posedge clk, negedge rs, negedge set) begin if(!rs) q<=1'b0;else if(!set) q<=1'b1;else case({j,k})2'b00:q<=q;2'b01:q<=1'b0;2'b10:q<=1'b1;2'b11:q<=~q;default:q<=1'bx;endcaseendendmodule【例7.30】电平敏感的1位数据锁存器module latch1(q,d,le);input d,le; output q;assign q=le?d:q;//le为高电平时,将输入端数据锁存endmodule【例7.31】带置位/复位端的1位数据锁存器module latch2(q,d,le,set,reset); input d,le,set,reset;output q;assign q=reset?0:(set? 1:(le?d:q)); endmodule【例7.32】 8位数据锁存器(74LS373)module ttl373(le,oe,q,d);input le,oe; input[7:0] d; output reg[7:0] q;a l w a y s@*//或写为always @(le,oe,d)begin if(~oe & le) q<=d;//或写为if((!oe) && (le))else q<=8'bz;endendmodule【例7.33】数据寄存器module reg_w(dout,din,clk,clr); parameter WIDTH=7;input clk,clr; input[WIDTH:0] din; output reg[WIDTH:0] dout; always @(posedge clk, posedge clr) beginif(clr) dout<=0;else dout<=din; endendmodule【例7.35】可变模加法/减法计数器module updown_count(d,clk,clear,load,up_down,qd); input clk,clear,load,up_down;input[7:0] d; output[7:0] qd; reg[7:0] cnt; assign qd=cnt;always @(posedge clk)begin if(!clear) cnt<=8'h00;//同步清0,低电平有效else if(load) cnt<=d;//同步预置else if(up_down) cnt<=cnt+1;//加法计数else cnt<=cnt-1;//减法计数endendmodule7.9 三态逻辑设计【例7.39】行为描述的三态门module tristate1(in,en,out);input in,en; output reg out;always @(in or en)begin if(en) out<=in;else out<=1'bz; endendmodule【例7.40】调用门元件bufif1描述的三态门module tristate2(in,en,out);input in,en; output out; tri out;bufif1 b1(out,in,en);//注意三态门端口的排列顺序endmodule【例7.41】数据流描述的三态门module tristate3(out,in,en);input in,en; output out;assign out=en?in:1‘bz; //若en=1,out=in;//若en=0,out为高阻态endmodule【例7.42】三态双向驱动器module bidir(y,a,en,b); input a,en; output b; inout y;assign y=en?a:'bz; assign b=y; endmodule【例7.44】三态双向总线缓冲器module ttl245(a,b,oe,dir);input oe,dir; //使能信号和方向控制inout[7:0] a,b; //双向数据线assign a=({oe,dir}==2'b00)?b:8'bz; assign b=({oe,dir}==2'b01)?a:8'bz; endmodule习题 7习题 7实验与设计module vote5(vote,pass);input [5:1] vote;output reg pass;always @(vote)begin case(vote)5'b00111: pass=1;5'b01011: pass=1;5'b01101: pass=1; 5'b01110: pass=1;5'b01111: pass=1;5'b10011: pass=1; 5'b10101: pass=1;5'b10110: pass=1;5'b10111: pass=1; 5'b11001: pass=1;5'b11010: pass=1;5'b11011: pass=1; 5'b11100: pass=1;5'b11101: pass=1;5'b11110: pass=1; 5'b11111: pass=1; default: pass=1'b0;endcase endendmodulemodule vote5f(pass,vote);input[5:1] vote;output pass; reg[2:0] sum; integer i; reg pass;always@(vote)begin sum=0;for(i=1;i<=5;i=i+1)if (vote[i]) sum=sum+1;if (sum>=3) pass=1; else pass=0; end endmodulemodule vote7(pass,vote);input[7:1] vote;output pass; reg[2:0] sum;integer i; reg pass;always@(vote)begin sum=0;for(i=1;i<=7;i=i+1)if(vote[i]) sum=sum+1;if(sum>=4) pass=1; else pass=0; end endmoduleSave IP Variation 对话框实验与设计定制FIFO模块的数据宽度和深度。

Verilog HDL数字设计与综合(第二版) 第九章课后习题答案

Verilog HDL数字设计与综合(第二版) 第九章课后习题答案

1.使用assign和deassign语句,设计一个带异步clear (q = 0)和preset (q = 1)端口的由上升沿触发的D触发器。

答:代码如下:module my_dff(q,d,clock,clear,preset);output q;input d,clock,clear,preset;reg q;always @(posedge clock)beginq=d;endalways @(clear or preset)if(clear)assign q=1'b0;else if (preset)assign q=1'b1;elsedeassign q;endmodule仿真输出如下:2.使用基本逻辑门设计一个一位全加器FA。

在激励模块中调用这个全加器。

在15至35个时间单位之间强迫输出值sum为a & b & c_in。

答:代码及激励模块见chapter9.v。

仿真输出如下,在15ns时,输出变化,在35ns时,由于和值与强迫输出值相同,故没有变化。

Verilog HDL 数字设计与综合(第二版)126 3.由逻辑门定义的带延迟参数的一位全加器FA ,如下面的模块所示:定义一个如例5.8所示的四位全加器fulladd4,使用本书中讨论的两种方法,传送下表所示的参数值给所引用的实例:实 例 延 迟 值 fa0 d_sum = 1, d_cout = 1 fa1 d_sum = 2, d_cout = 2 fa2 d_sum = 3, d_cout = 3 fa3d_sum = 4, d_cout = 4a .编写fulladd4模块,用defparam 语句改变实例参数的值。

使用例5.9中的激励文件对这个四位全加器进行仿真。

解释全加器的结果延迟,什么时候出现加法器的输出(在该激励文件中使用20作为延迟值,而不是用5)。

b .编写fulladd4模块,把延迟值传送到调用的实例fa0,fa1,fa2和fa3中。

第10章数字系统设计verilog HDL(第6版)王金明

第10章数字系统设计verilog HDL(第6版)王金明

第10章 Verilog设计的优化10.1 设计的可综合性综合过程10.2 流水线设计技术流水线操作的概念流水线操作的示意图非流水线方式8位全加器module adder8(cout,sum,ina,inb,cin,clk); input[7:0] ina,inb; input cin,clk; output[7:0] sum; output cout;reg[7:0] tempa,tempb,sum; reg cout,tempc; always @(posedge clk)begin tempa=ina;tempb=inb;tempc=cin; end //输入数据锁存always @(posedge clk)begin {cout,sum}=tempa+tempb+tempc; end endmodule两级流水实现的8位加法器module adder_pipe2(cout,sum,ina,inb,cin,clk); input[7:0] ina,inb; input cin,clk;output reg[7:0] sum;output reg cout;reg[3:0] tempa,tempb,firsts;reg firstc;always @(posedge clk)begin {firstc,firsts}=ina[3:0]+inb[3:0]+cin; tempa=ina[7:4]; tempb=inb[7:4];endalways @(posedge clk)begin {cout,sum[7:4]}=tempa+tempb+firstc; sum[3:0]=firsts;endendmodule四级流水线实现的8位加法器module pipeline(cout,sum,ina,inb,cin,clk);output[7:0] sum;output cout;input[7:0] ina,inb;input cin,clk; reg[7:0] tempa,tempb,sum;reg tempci,firstco,secondco,thirdco, cout;reg[1:0] firsts, thirda,thirdb;reg[3:0] seconda, secondb, seconds; reg[5:0] firsta, firstb, thirds; always @(posedge clk)begin tempa=ina; tempb=inb; tempci=cin; end //输入数据缓存always @(posedge clk)begin {firstco,firsts}=tempa[1:0]+tempb[1:0]+tempci; //第一级加(低2位)firsta=tempa[7:2]; firstb=tempb[7:2]; //未参加计算的数据缓存endalways @(posedge clk)begin {secondco,seconds}={firsta[1:0]+firstb[1:0]+firstco,firsts}; seconda=firsta[5:2]; secondb=firstb[5:2]; //数据缓存endalways @(posedge clk)begin {thirdco,thirds}={seconda[1:0]+secondb[1:0]+secondco,seconds}; thirda=seconda[3:2];thirdb=secondb[3:2];//数据缓存endalways @(posedge clk)begin{cout,sum}={thirda[1:0]+thirdb[1:0]+thirdco,thirds}; //第四级加end endmodule设计综合到不同器件的最高工作频率器件非流水线设计/MHz 2级流水线设计/MHz4级流水线设计/MHzEP1K10TC100-3(FPGA)138.89158.73166.67 EPM3064ALC44-4(CPLD)105.26149.25158.732个加法器和1个选择器的实现方式module resource1(sum,a,b,c,d,sel);parameter SIZE=4; input sel; input[SIZE-1:0] a,b,c,d;output reg[SIZE:0] sum;always @(*) //使用通配符begin if(sel) sum=a+b;else sum=c+d;end endmodule 10.3 资源共享(Resource Sharing )资源共享可用来减少系统所耗用的器件资源,尤其是将一些耗用资源较多的模块进行共享,能有效降低整个系统耗用的资源。

数字系统设计与veriloghdl课后答案

数字系统设计与veriloghdl课后答案

数字系统设计与veriloghdl课后答案【篇一:数字逻辑与数字系统设计习题参考答案】>第1章习题解答1.3 (1)86(2)219(3)106.25(4)0.6875 (4)0.1011.4 (1)101111(2)1001000(3)100001l.111.5 (1)(117)10=(165)8=(1110101)2=(75)16(2)(3452)10=(6574)8=(110101111100)2=(d7c)16(3)(23768.6875)10=(56330.54)8=(101110011011000.1011)2=(5cd 8.b)16 (4)(0.625)10=(0.5)8=(0.101)2=(0.a)16 1.6(1)(117)8=(1001111)2=(79)10(2)(7456)8=(111100101110)2=(3886)10(3)(23765.64)8=(10 0111 1111 0101.1101)2=(10229.8125)10(4)(0.746)8=(0.11111)2=(0.96875)10 1.7 (1)(9a)16=(10011010)2=(154)10(2) (3cf6)16=(11110011110110)2=(15606)10(3) (7ffe.6)16=(111111*********.011)2=(32766.375)10 (4)(0.c4)16=(0.110001)2=(0.765625)10 1-8(1)(125)10=(000100100101)8421bcd(2)(7342)10=(0111001101000010)8421bcd(3)(2018.49)10=(0010000000011000.01001001)8421bcd(4)(0.785)10=(0.011110000101)8421bcd1.9(1)(106)10=(1101010)2 原码=反码=补码=01101010 (2)(-98)10=(-1100010)2原码=11100010反码=10011101 补码=11100011(3)(-123)10=(-1111011)2 原码=11111011反码=10000101 补码=11111011(4)(-0.8125)10=(-0.1101)2 原码=1.1101000反码=1.0010111 补码=1.00110001.10(1)(104)10=(1101000)2 [1101000]补=01101000(-97)10=(-1100001)2 [-1100001]补=1001111101101000 + 10011111 0000011110000011 + 01001111 11010010[104-97]补=01101000+10011111=00000111, 104-97=(00000111)2=7 (2) (-125)10=(-1111101)2(79)10=(01001111)2[-1111101]补=10000011 [01001111]补=0100111101111000 [-125+79]补=10000011+01001111=11010010,-125+79=(-0101110)2=-46 (3) (120)10=(1111000)2[01111000]补=01111000(-67)10=(-1000011)2[-1000011]补=10111101[120-67]补=10000011+01001111=00110101,-125+79=(00110101)2=53 (4) (-87)10=(-1010111)2[-1010111]补=10101001(12)10=(1100)2[1100]补=00001100[-87+12]补=10101001+00001100=10110101,-125+79=(-1001011)2=-75+ 10111101 0011010110101001+ 00001100 10110101第2章习题解答2.3 解:根据逻辑图可直接写出逻辑表达式:(a) f=ab?bc;(b)f=abbcac解:设3个输入变量分别为a、b、c,输出为f,按题意,其中有奇数个为1,则输出f=1,因此可写出其逻辑表达式为f=abc?abc?abc?abc。

第8章数字系统设计verilog HDL(第6版)王金明

第8章数字系统设计verilog HDL(第6版)王金明

第8章 Verilog有限状态机设计8.1 有限状态机摩尔型(Moore)状态机米里型(Mealy)状态机用状态机设计模5计数器module fsm(clk,clr,z,qout);input clk,clr; output reg z; output reg[2:0] qout; always @(posedge clk or posedge clr) //此过程定义状态转换begin if(clr) qout<=0; //异步复位else case(qout)3'b000: qout<=3'b001;3'b001: qout<=3'b010;3'b010: qout<=3'b011;3'b011: qout<=3'b100;3'b100: qout<=3'b000;default: qout<=3'b000;/*default语句*/endcaseendalways @(qout) /*此过程产生输出逻辑*/ begin case(qout)3'b100: z=1'b1;default:z=1'b0;endcaseendendmodule8.2 有限状态机的几种描述方式“101”序列检测器的Verilog 描述(三个过程)module fsm1_seq101(clk,clr,x,z);input clk,clr,x; output reg z; reg[1:0] state,next_state;parameter S0=2'b00,S1=2'b01,S2=2'b11,S3=2'b10; /*状态编码,采用格雷(Gray )编码方式*/always @(posedge clk or posedge clr) /*该过程定义当前状态*/begin if(clr) state<=S0; //异步复位,s0为起始状态else state<=next_state;end always @(state or x) /*该过程定义次态*/begin case (state)S0:begin if(x) next_state<=S1;else next_state<=S0; end S1:begin if(x) next_state<=S1;else next_state<=S2; endS2:beginif(x) next_state<=S3; else next_state<=S0; end S3:b e g i ni f(x)next_state<=S1;else next_state<=S2; enddefault:next_state<=S0;/*default语句*/ endcaseend always @(state)/*该过程产生输出逻辑*/ begin case(state)S3: z=1'b1;default:z=1'b0; endcaseendendmodule“101”序列检测器的Verilog描述(三个过程)“101”序列检测器(单过程描述)module fsm4_seq101(clk,clr,x,z);input clk,clr,x; output reg z; reg[1:0] state; parameter S0=2'b00,S1=2'b01,S2=2'b11,S3=2'b10;/*状态编码,采用格雷(Gray)编码方式*/always @(posedge clk or posedge clr)Begin if(clr) state<=S0; //异步复位,s0为起始状态else case(state)S0:begin if(x) begin state<=S1; z=1'b0;endelse begin state<=S0; z=1'b0;endendS1:begin if(x) begin state<=S1; z=1'b0;endelse begin state<=S2; z=1'b0;endendS2:begin if(x) begin state<=S3; z=1'b0;endelse begin state<=S0; z=1'b0;endendS3:begin if(x) begin state<=S1; z=1'b1;endelse begin state<=S2; z=1'b1;endenddefault:begin state<=S0; z=1'b0;end /*default语句*/ endcase endendmodule8.3 状态编码常用的编码方式一位热码编码选择对话框(Quartus Ⅱ)在Verilog语言中,有两种方式可用于定义状态编码,分别用parameter和'define语句实现,比如要为state0、state1、state2、state3四个状态定义码字为:00、01、11、10,可采用下面两种方式。

EDA技术与Verilog设计王金明版

EDA技术与Verilog设计王金明版

sum=((ab)(a+b)+ab(a+b)) cin
sum=(ab) (a+b) cin
8位超前进位加法器
module add_ahead(sum,cout,a,b,cin); input[7:0] a,b; input cin; output[7:0] sum; output cout; wire[7:0] G,P; wire[7:0] C,sum; assign G[3]=a[3]&b[3]; assign P[3]=a[3]|b[3]; assign sum[3]=G[3]^P[3]^C[3]; assign C[4]=G[3]|(P[3]&C[3]); assign G[4]=a[4]&b[4]; assign P[4]=a[4]|b[4]; assign sum[4]=G[2]^P[2]^C[2]; assign C[5]=G[4]|(P[4]&C[4]); assign G[5]=a[5]&b[5]; assign P[5]=a[5]|b[5]; assign sum[5]=G[5]^P[5]^C[5]; assign C[6]=G[5]|(P[5]&C[5]);
结构描述方 式实现
8位级连加法器
1)速度特性: N位级联加法器运算的延时是1位全 加器的N倍,延时时间较长,不适宜在 需要高性能的设计中采用; 2)资源占用: 相对较低,在EPF10K10LC84-3器件 中,耗费16个LC单元。
8位并行加法器
module add_bx(cout,sum,a,b,cin); input[7:0] a,b; input cin; output[7:0] sum; output cout; assign {cout,sum}=a+b+cin; endmodule

[数字系统设计与Verilog HDL(第7版 (9)[24页]

[数字系统设计与Verilog HDL(第7版 (9)[24页]

LCD12864B的初始化指令
初始化过程 1 2 3 4
行地址/XY
字符显示
图形显示
8 ' h38
8 ' h30
8 ' h0C
8 ' h3E
8 ' h01
8 ' h36
8 ' h06
8 ' h01
1: ' h80 2: ' h903: ' h88 4: ' h98
Y: ' h80~ ' h9FX: ' h80/ ' h88
LCD1602B的初始化指令
初始化过程 1 2
初始化指令 8 ' h38 8 ' h01
功能
设置显示模式:16×2显示,5×7点 阵,8位数据接口
清屏,将以前的显示内容清除
3 4 行地址
8 ' h06
光标设置:光标右移,字符不移
8 ' h0c
开显示,光标不显示(如要显示光标 可改为8 ' h0e)
1行:' h802行:' hc0
第1行地址第2行地址
LCD1602图形点阵液晶显示模块广泛应用于智能仪器仪表、工业控 制领域、通信和家用电器中。本节用FPGA控制 LCD12864B汉字图形点阵液晶实现字符和图形的显示。 LCD12864B可显示汉字及图形,内置8192个中文汉字 (16×16点阵)、128个字符(8×16点阵)及64×256点 阵显示RAM(GDRAM)。
15
F0 15
8
3E
F0 3E
R
2D
F0 2D
9
46
F0 46
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第9章 Verilog设计进阶9.1 加法器设计(1)级连加法器8位级连加法器module add_jl(sum,cout,a,b,cin);input[7:0] a,b;input cin;output[7:0] sum;output cout;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); full_add1 f3(a[3],b[3],cin3,sum[3],cin4); full_add1 f4(a[4],b[4],cin4,sum[4],cin5); full_add1 f5(a[5],b[5],cin5,sum[5],cin6); full_add1 f6(a[6],b[6],cin6,sum[6],cin7); full_add1 f7(a[7],b[7],cin7,sum[7],cout); endmodule(2)数据流描述的加法器module add_bx(cout,sum,a,b,cin); parameter WIDTH=8; input cin; output cout; input[WIDTH-1:0] a,b; output[WIDTH-1:0] sum; assign {cout,sum}=a+b+cin;endmodule(3) 8位超前进位加法器moduleadd_ahead(sum,cout,a,b,cin); input[7:0] a,b;input cin;output[7:0] sum;output cout;wire[7:0] G,P;wire[7:0] C,sum;assign G[0]=a[0]&b[0]; assign P[0]=a[0]|b[0]; assign C[0]=cin;assign sum[0]=G[0]^P[0]^C[0]; assign G[1]=a[1]&b[1]; assign P[1]=a[1]|b[1]; assign C[1]=G[0]|(P[0]&cin); assign sum[1]=G[1]^P[1]^C[1]; assign G[2]=a[2]&b[2]; assign P[2]=a[2]|b[2]; assign C[2]=G[1]|(P[1]&C[1]); assign sum[2]=G[2]^P[2]^C[2]; assign G[3]=a[3]&b[3]; assign P[3]=a[3]|b[3]; assign C[3]=G[2]|(P[2]&C[2]); assign sum[3]=G[3]^P[3]^C[3];assign G[4]=a[4]&b[4]; assign P[4]=a[4]|b[4]; assign C[4]=G[3]|(P[3]&C[3]); assign sum[4]=G[2]^P[2]^C[2]; assign G[5]=a[5]&b[5]; assign P[5]=a[5]|b[5]; assign C[5]=G[4]|(P[4]&C[4]); assign sum[5]=G[5]^P[5]^C[5]; assign G[6]=a[6]&b[6]; assign P[6]=a[6]|b[6]; assign C[6]=G[5]|(P[5]&C[5]); assign sum[6]=G[6]^P[6]^C[6]; assign G[7]=a[7]&b[7]; assign P[7]=a[7]|b[7]; assign C[7]=G[6]|(P[6]&C[6]); assign sum[7]=G[7]^P[7]^C[7]; assign cout=G[7]|(P[7]&C[7]); endmodule(4)流水线加法器module adder8(cout,sum,a,b,cin,enable); input[7:0] a,b; input cin,enable; output[7:0] sum; reg[7:0] sum;output cout;reg cout;reg[3:0] tempa,tempb,firsts; reg firstc; always @(posedge enable)begin{firstc,firsts}=a[3:0]+b[3:0]+cin; tempa=a[7:4]; tempb=b[7:4];endalways @(posedge enable)begin{cout,sum[7:4]}=tempa+tempb+firstc; sum[3:0]=firsts;endendmodule9.2 乘法器)并行乘法器(1module mult(outcome,a,b); parameter size=8;input[size:1] a,b;output[2*size:1] outcome; assign outcome=a*b;endmodule8×8并行乘法器的门级综合原理图(2)移位相加乘法器4×4移位相加乘法操作示意图8位移位相加乘法器顶层设计8位移位相加乘法器时序仿真波形(3)布斯乘法器(4)查找表乘法器9.3 奇数分频与小数分频(1)奇数分频module count7(reset,clk,cout);input clk,reset; output wire cout;reg[2:0] m,n; reg cout1,cout2;assign cout=cout1|cout2;//两个计数器的输出相或always @(posedge clk)beginif(!reset) begin cout1<=0; m<=0; endelse begin if(m==6) m<=0; else m<=m+1;if(m<3) cout1<=1;else cout1<=0; end endalways @(negedge clk)beginif(!reset) begin cout2<=0; n<=0; endelse begin if(n==6) n<=0; else n<=n+1;if(n<3) cout2<=1; else cout2<=0; end endendmodule模7奇数分频器功能仿真波形图(Quartus Ⅱ)module count_num(reset,clk,cout);parameter NUM=13;input clk,reset; output wire cout;reg[4:0] m,n; reg cout1,cout2;assign cout=cout1|cout2;always @(posedge clk)begin if(!reset) begin cout1<=0; m<=0; endelsebegin if(m==NUM-1) m<=0; else m<=m+1;if(m<(NUM-1)/2) cout1<=1; else cout1<=0;endendalways @(negedge clk)begin if(!reset) begin cout2<=0; n<=0; endelse beginif(n==NUM-1) n<=0; else n<=n+1;if(n<(NUM-1)/2) cout2<=1; else cout2<=0; end endendmodule模13奇数分频器功能仿真波形图(Quartus Ⅱ)module fdiv5_5(clkin,clr,clkout);input clkin,clr; output reg clkout;reg clk1; wire clk2; integer count;xor xor1(clk2,clkin,clk1); //异或门always@(posedge clkout or negedge clr) //2分频器begin if(~clr) begin clk1<=1'b0; endelse clk1<=~clk1;endalways@(posedge clk2 or negedge clr) //模5分频器begin if(~clr)begin count<=0; clkout<=1'b0; endelse if(count==5) //要改变分频器的模,只需改变count的值begin count<=0; clkout<=1'b1; endelse begin count<=count+1; clkout<=1'b0; end endendmodule功能仿真波形5.5倍半整数分频器功能仿真波形图(Quartus Ⅱ)小数分频module fdiv8_1(clk_in,rst,clk_out);input clk_in,rst; output reg clk_out;reg[3:0] cnt1,cnt2;//cnt1计分频的次数always@(posedge clk_in or posedge rst)begin if(rst) begin cnt1<=0; cnt2<=0; clk_out<=0; endelse if(cnt1<9)//9次8分频begin if(cnt2<7) begin cnt2<=cnt2+1; clk_out<=0; end else begin cnt2<=0; cnt1<=cnt1+1; clk_out<=1; end end else begin //1次9分频if(cnt2<8) begin cnt2<=cnt2+1; clk_out<=0; end else begin cnt2<=0; cnt1<=0; clk_out<=1; endend endendmodule8.1小数分频功能仿真波形(Quartus Ⅱ)9.4 VGA图像显示控制器设计VGA 行扫描时序VGA 场扫描时序标准VGA显示模式行、场扫描的时序行扫描时序要求(单位:像素,输出一个Pixel的时间间隔)行同步头行图像行周期对应位置H_Tf H_Ta H_Tb H_Tc H_Td H_Te H_Tg时间/Pixels8964086408800场扫描时序要求(单位:行,输出一行Line的时间间隔)场同步头场图像场周期对应位置V_Tf V_Ta V_Tb V_Tc V_Td V_Te V_Tg时间/Lines222584808525VGA图像显示控制器设计VGA图像显示控制器结构框图R,G,B三基色信号分别采用5 bit,6 bit,5 bit表示的LENA图像9.5 点阵式液晶显示控制GDM12864的结构及指令“写数据”时序图液晶控制9.6 乐曲演奏电路乐曲演奏的原理乐曲演奏电路原理框图习题 9习题 9习题 9实验与设计。

相关文档
最新文档