设计方法:    分析真值表规律
 
      两种描述方式:
    • 方式1:用assign描述,用阻塞赋值=
    • 方式2:用always@(*)描述,用非阻塞赋值<=
 
    选择功能的三种描述方式:
    • 方式1:三目运算符 ? :  ;
    • 方式2:if...else if.....else(有优先级)
    • 方式3:case....default...(并行)
  例1.mux2二选一数据选择器

      

//方式1(先列出端口,后定义端口属性)
module mux2(
a,
b,
sel,
out
);
//端口属性定义(输入/输出,位宽)
input a;
input b;
input sel; //sel = 0,out输出a
output out;     //位宽1位
//功能描述
//阻塞赋值语句
assign out = (sel == )?a:b;
//assign out = (!sel)?a:b;
//assign out = sel?b:a;
endmodule

  

//方式2(在声明端口的同时定义属性)
module mux2(
//端口属性定义
input a,
input b,
input sel,
output out //此处没有分号
);
//功能描述
//阻塞赋值语句
assign out = (sel == )?a:b;
endmodule

  testbench测试文件(组合逻辑电路一般都采用穷举法):

`timescale 1ns / 1ps
module mux2_tb(); reg a;
reg b;
reg sel;
wire c; //例化测试模块
mux2 mu2_test(
.a(a),
.b(b),
.sel(sel),
.c(c)
); initial begin
a = ; b = ; sel = ;
#; //延时100ns(时间步进前面第一行代码已经设置为1ns)
a = ; b = ; sel = ;
#;
a = ; b = ; sel = ;
#;
a = ; b = ; sel = ;
#;
a = ; b = ; sel = ;
#;
a = ; b = ; sel = ;
#;
a = ; b = ; sel = ;
#;
a = ; b = ; sel = ;
#;
$stop;
end
endmodule 

  测试结果(modelsim):

  

  分析出的电路:

  

   例2.三态门控制

//三态门控制
assign oe = sel;
assign io = oe?out[]:'bz; //z高阻态(输入)

  三态门和二选一多路器类似,不再进行仿真测试;

   例3.加法器
        1、半加器halfadder

module half_adder(
input a,
input b,
output out, //结果输出
output cout //进位输出
);
//功能描述
assign out = a ^ b;
assign cout = a & b; endmodule
  testbench测试代码:
`timescale 1ns / 1ps
module half_adder_tb();
reg a;
reg b;
wire out;
wire cout; //例化测试模块
half_adder half_adder_test(
.a(a),
.b(b),
.out(out), //结果输出
.cout(cout) //进位输出
);
//开始测试
initial begin
a = ; b = ;
#;
a = ; b = ;
#;
a = ; b = ;
#;
a = ; b = ;
#;
$stop;
end
endmodule

  测试结果(modelsim):

  

  分析出的电路(和上一篇数字电路设计的一模一样,由一个异或门和与门构成):

  

    2、全加器adder
           设计方式1:层次化设计,由两个半加器和一个或门组成
           设计方式2:根据真值表采用verilog直接描述(如下图)

module adder(
input a,
input b,
input cin, //进位输入
output out, //结果输出
output cout //进位输出
);
//功能描述
assign out = a ^ b ^ cin;
assign cout = a&b | a&cin | b&cin;
endmodule 

  testbench测试文件

`timescale 1ns / 1ps
module adder_tb();
reg a;
reg b;
reg cin;
wire out;
wire cout; //例化测试模块
adder adder_test(
.a(a),
.b(b),
.cin(cin), //进位输入
.out(out), //结果输出
.cout(cout) //进位输出
);
//开始测试
initial begin
a = ; b = ; cin = ;
#; a = ; b = ; cin = ;
#; a = ; b = ; cin = ;
#; a = ; b = ; cin = ;
#; a = ; b = ; cin = ;
#; a = ; b = ; cin = ;
#; a = ; b = ; cin = ;
#; a = ; b = ; cin = ;
#; $stop;
end
endmodule 

  测试结果(modelsim):

  

  分析出的电路:

  

  例4.数码管显示译码器

    通常我们用的数码管有共阳极和共阴极之分,共阳极段码给0,位选给1全部点亮;共阴极段码给1,位选给0全部点亮;数码管都是7段数码管显示+一位小数点,Basys3开发板数码管原理图和数码管显示原理如下图:

    

  

    这样每个数字都会有对应的7段编码,但我们熟悉的是二进制码或者BCD码,所以需要设计一个显示译码器,将输入的4bitBCD码转换为数码管对应的8bit段码;由Basys3原理图可知,要让数码管显示,还需要选中位选,所以还需要设计一个2-4译码器,用两个开关控制哪一位显示,设计图如下:

  

    Verilog描述组合逻辑电路中的译码器通常采用case语句,完整的代码如下:

/////////////////////////////////////////////////////////////////////////////////////////////////
// Module Name: seg_display
// Description: 数码管显示模块,由一个显示译码器模块decoder_display和一个2-4译码器decoder2_4构成;
//////////////////////////////////////////////////////////////////////////////////////////////////
module seg_display(
input [:]data_display, //数码管待显示数据
input [:]wei, //选择哪一位显示
output [:]segments, //数码管段码
output [:]wei_sel //数码管位码
);
//功能描述
//例化显示译码模块
decoder_display decoder_display_0(
.data_in(data_display),
.segments(segments)
);
//例化位选模块
decoder2_4 decoder2_4_0(
.data_in(wei),
.wei_sel(wei_sel)
);
endmodule //数码管显示译码模块
//note:只包含7位段码,不包括小数点控制
module decoder_display(
input [:]data_in,
output reg [:]segments
);
//显示译码功能描述
always@(*)
case(data_in)
//对应段 abc_defg
'h0: segments = 7'b000_0001;
'h1: segments = 7'b100_1111;
'h2: segments = 7'b001_0010;
'h3: segments = 7'b000_0110;
'h4: segments = 7'b100_1100;
'h5: segments = 7'b010_0100;
'h6: segments = 7'b010_0000;
'h7: segments = 7'b000_1111;
'h8: segments = 7'b000_0000;
'h9: segments = 7'b000_1100;
'hA: segments = 7'b000_1000;
'hB: segments = 7'b110_0000;
'hC: segments = 7'b011_0001;
'hD: segments = 7'b100_0010;
'hE: segments = 7'b011_0000;
'hF: segments = 7'b011_1000;
default: segments = 'b111_1111;
endcase
endmodule module decoder2_4(
input [:]data_in,
output reg [:]wei_sel //4位数码管选中位
);
//位选2-4译码器功能描述
always@(*)
case(data_in)
//对应位
'h0: wei_sel = 4'b1110;
'h1: wei_sel = 4'b1101;
'h2: wei_sel = 4'b1011;
'h3: wei_sel = 4'b0111;
default: wei_sel = 'b1111;
endcase
endmodule

  testbench测试代码如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Module Name: seg_display_tb
// Description: 数码管显示模块seg_display测试模块
////////////////////////////////////////////////////////////////////////////////// module seg_display_tb();
reg [:]data_display; //数码管待显示数据
reg [:]wei; //选择哪一位显示
wire [:]segments; //数码管段码
wire [:]wei_sel; //数码管位码 //例化测试模块
seg_display seg_display_test(
.data_display(data_display), //数码管待显示数据
.wei(wei), //选择哪一位显示
.segments(segments), //数码管段码
.wei_sel(wei_sel) //数码管位码
);
//开始测试
initial begin
wei = 'h0; //选中第一位显示0-F
data_display = 'h0; //显示"0"
#; data_display = 'h1; //显示"1"
#; data_display = 'h2; //显示"2"
#; data_display = 'h3; //显示"3"
#; data_display = 'h4; //显示"4"
#; data_display = 'h5; //显示"5"
#; data_display = 'h6; //显示"6"
#; data_display = 'h7; //显示"7"
#; data_display = 'h8; //显示"8"
#; data_display = 'h9; //显示"9"
#; data_display = 'ha; //显示"A"
#; data_display = 'hb; //显示"b"
#; data_display = 'hc; //显示"C"
#; data_display = 'hd; //显示"d"
#; data_display = 'he; //显示"E"
#; data_display = 'hf; //显示"F" #; wei = 'h1; //选中第二位显示"F"
#; wei = 'h2; //选中第三位显示"F"
#; wei = 'h3; //选中第四位显示"F" #; $stop; //测试停止
end endmodule

  仿真结果如下图:

  综合分析出的电路如图:

  

  小结 —— 组合逻辑电路的设计方法

  1、verilog描述方法

     对于组合逻辑电路,有两个步骤,一是描述端口,二是描述功能(最重要的是得出真值表,然后根据真值表得出逻辑表达式,描述功能);

  2、testbench编写方法

      对于组合逻辑电路的testbench测试文件的编写:

      1)定义时间步进/时间精度:`timescale 1ns/1ps

      2)定义一些测试模块输入所用到的寄存器,用于产生对测试模块输入信号(即将测试模块input类型信号改为reg类型信号);

         定义用于观察的输出信号接到测试模块的输出(即将测试模块output类型信号改为wire类型信号);

      3)例化测试模块(注意要定义例化模块名称)

      4) 开始测试

         ①基本结构  initial begin .......   end......$stop;

         ②延时100ns的表示方法  #100;  (注意一定要加上分号)

         ③穷举出所有可能的情况

FPGA学习笔记(五)—— 组合逻辑电路功能的描述的更多相关文章

  1. Redis学习笔记五:独立功能之事务

    Redis 事务提供了一种将多个命令请求打包,然后一次性.按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断,会将事务中的所以命令都执行完毕才去处理其他客户端的命令请求. 事务的实现 事务 ...

  2. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  3. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  4. python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍

    python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ...

  5. 【opencv学习笔记五】一个简单程序:图像读取与显示

    今天我们来学习一个最简单的程序,即从文件读取图像并且创建窗口显示该图像. 目录 [imread]图像读取 [namedWindow]创建window窗口 [imshow]图像显示 [imwrite]图 ...

  6. Linux学习笔记(五) 账号管理

    1.用户与组账号 用户账号:包括实际人员和逻辑性对象(例如应用程序执行特定工作的账号) 每一个用户账号包含一个唯一的用户 ID 和组 ID 标准用户是系统安装过程中自动创建的用户账号,其中除 root ...

  7. go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])

    目录 go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时]) 静态配置 flag注入 在线热加载配置 远程配置中心 go微 ...

  8. C++基础 学习笔记五:重载之运算符重载

    C++基础 学习笔记五:重载之运算符重载 什么是运算符重载 用同一个运算符完成不同的功能即同一个运算符可以有不同的功能的方法叫做运算符重载.运算符重载是静态多态性的体现. 运算符重载的规则 重载公式 ...

  9. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

随机推荐

  1. spring boot之入门配置(一)

    yml.properties配置文件 yml相比properties配置文件,yml可以省略不必要的前缀,并且看起来更加的有层次感.推荐使用yml文件. @Value 根据配置文件的配置项获取对应的v ...

  2. 查询linux机器的公网ip

    在linux终端提示符下,输入以下命令: curl members.3322.org/dyndns/getip 可以看到下图已经查询到公网IP地址了,就是这么简单

  3. windows安装weblogic和域的建立

    Copyright ©2014 Manchester United

  4. Java反射之调用内部类

    1. 反射调用默认访问权限的内部类 package com.blueStarWei.invoke; import java.lang.reflect.Method; import com.blueSt ...

  5. mobile angualar ui的简单使用

    最近做一个微信App形式的业务平台,之前从别人的推荐文中知道了mobile angualar ui这个东西,这次纯做mobile Web就试用了一下,之前PCWeb中用过AngularJS,Hybri ...

  6. Jmeter(二十七)_Beanshell保存响应内容到本地

    利用Jmeter-BeanShell PostProcessor可以提取响应结果并保存到本地文件,这种操作在jmeter做爬虫时非常有用,可以帮助你迅速的获取想要的内容到本地文件! 1:在本地新建一个 ...

  7. redis 设置

    设置成服务命令,redis目录下,执行cmd命令 redis-server --service-install redis.windows-service.conf --loglevel verbos ...

  8. lvs+keepalive实现主从效果,以及RS健康监测和tcp,udp实现非web的负载均衡

    前面文章讲到了tcp和udp负载均衡,但是没有健康监测,这几天我优化了一下上次的操作.当然,我也是用的跨网段的通讯,因为线上业务主要是海外业务,所以做了iptables流量转发 IP: lvs-mas ...

  9. centOS7虚拟环境搭建

    今天来记录一下使用WMware虚拟机来搭建centOS虚拟机的过程. 本次使用工具为VMware Workstation 14 Pro,可以从https://www.vmware.com/来获取所需工 ...

  10. Java开源生鲜电商平台-支付模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-支付模块的设计与架构(源码可下载) 开源生鲜电商平台支付目前支持支付宝与微信.针对的是APP端(android or IOS)   1. 数据库表设计. 说明:无论是支付宝还 ...