当前位置: 首页 > article >正文

FPGA 第7讲 简单组合逻辑译码器

时间:2024.11.15

一、学习内容

1.译码器

       译码是编码的逆过程,在编码时,每一种二进制代码,都赋予了特定的含义,即都表示了一个确定的信号或者对象。把代码状态的特定含义翻译出来的过程叫做译码,实现译码操作的电路称为译码器。或者说,译码器是可以将输入二进制代码的状态翻译成输出信号,以表示其原来含义的电路。

       译码器(decoder)是一类多输入多输出组合逻辑电路器件,其可以分为:变量译码和显示译码两类。

1.1变量译码器

变量译码器一般是一种较少输入变为较多输出的器件,常见的有 n 线-2^n线译码和 8421BCD 码译码两类。

1.2显示译码器

       显示译码器用来将二进制数转换成对应的七段码,一般其可分为驱动 LED 和驱动 LCD 两类。

2.实验目标

        设计并仿真验证 3-8 译码器。
注:3-8 译码器的上板验证需要用到 8 个 led 灯或者数码管,因为板卡 led 灯数目不够且数码管部分还未作讲解,3-8 译码器只进行仿真验证,不再上板测试。

二、实验

1.准备工作

建立文件夹存放工程,进行文件体系的构建,建立visio文件

2.绘制波形和框图

在visio软件里绘制波形和框图

2.1模块框图 

 根据功能分析,工程只需实现一个 3-8 译码器的功能,所以设计成一个模块即可。
       模块命名 decoder3_8,模块的输入为 3 个 1bit 信号,输出为 1 个 8bit 信号,实现通过输入3 个信号组成的二进制的 8 种情况来控制对应输出 8bit 的 8 种不同状态。

TIPS:

     输出信号定义为8位宽,在框图里要进行加粗处理,用以区别

2.2波形图绘制

       输入为 3 个 1bit 信号,其任意二进制组合有 8 种情况,每种组合与 out 输出 8bit 的 8 种状态一一对应,实现由 3 种输入控制对应的 8 种输出的译码效果。

TIPS:

用X表示初始波形未知

 3.代码编写

方法一:always 中 if-else 实现方法

module decorder
(//编写输入输出列表
   input   wire       in_1,
   input   wire       in_2,
   input   wire       in_3,
   output  reg   [7:0] out

);
//进行输入输出的赋值
always@(*)
//if-else条件分支语句
if({in_1,in_2,in_3}==3'b000)      //{in_1,in_2,in_3}对三路信号进行拼接
   out = 8'b0000_0001;
     else if({in_1,in_2,in_3}==3'b001)      
    out = 8'b0000_0010;
     else if({in_1,in_2,in_3}==3'b010)      
    out = 8'b0000_0100;
     else if({in_1,in_2,in_3}==3'b011)      
    out = 8'b0000_1000;
     else if({in_1,in_2,in_3}==3'b100)      
    out = 8'b0001_0000;
     else if({in_1,in_2,in_3}==3'b101)      
    out = 8'b0010_0000;
     else if({in_1,in_2,in_3}==3'b110)      
    out = 8'b0100_0000;
     else if({in_1,in_2,in_3}==3'b111)      
    out = 8'b1000_0000;
else 
out = 8'b0000_0001;

endmodule
TIPS:

     最后一个 else 对应的 if 中的条件只有一种情况,还可能产生以上另外的 7 种情况,如果不加这个else 综合器会把不符合该 if 中条件的上面另外 7 种情况都考虑进去,会产生大量的冗余逻辑并产生 latch(锁存器),所以在组合逻辑中最后一个 if后一定要加上 else,并任意指定一种确定的输出情况

 

方法二:always 中 case 实现方法

module decorder
(//编写输入输出列表
   input   wire       in_1,
   input   wire       in_2,
   input   wire       in_3,
   output  reg   [7:0] out

);
//进行输入输出的赋值
/* always@(*)
//if-else条件分支语句
if({in_1,in_2,in_3}==3'b000)      //{in_1,in_2,in_3}对三路信号进行拼接
   out = 8'b0000_0001;
     else if({in_1,in_2,in_3}==3'b001)      
    out = 8'b0000_0010;
     else if({in_1,in_2,in_3}==3'b010)      
    out = 8'b0000_0100;
     else if({in_1,in_2,in_3}==3'b011)      
    out = 8'b0000_1000;
     else if({in_1,in_2,in_3}==3'b100)      
    out = 8'b0001_0000;
     else if({in_1,in_2,in_3}==3'b101)      
    out = 8'b0010_0000;
     else if({in_1,in_2,in_3}==3'b110)      
    out = 8'b0100_0000;
     else if({in_1,in_2,in_3}==3'b111)      
    out = 8'b1000_0000;
else 
out = 8'b0000_0001; */
always@(*)
     case({in_1,in_2,in_3})
     3'b000:out = 8'b0000_0001;
     3'b001:out = 8'b0000_0010;
     3'b010:out = 8'b0000_0100;
     3'b011:out = 8'b0000_1000;
     3'b100:out = 8'b0001_0000;
     3'b101:out = 8'b0010_0000;
     3'b110:out = 8'b0100_0000;
     3'b111:out = 8'b1000_0000;
     default:out = 8'b1000_0000;  //避免latch
     endcase

endmodule

 

总结:

       经过验证对比发现两种方法虽然最后实现的功能是一样的,而所得到的 RTL 视图差别较大,但最后的逻辑资源使用却是相同的(时序逻辑中不一定相同),说明综合器进行了适当的优化。

       if-else 的这种写法是存在优先级的,即第一个 if 中的条件的优先级最高,后面的 if 中的条件的优先级依次递减,好在该 if 中的条件只有一个,也只会产生一种情况,并不会产生优先级的冲突,所以这里优先级的高低关系并不会对最后的功能产生任何影响。而 case 在任何时候都不存在优先级的问题,而是通过判断case 中的条件来选择对应的输出。
        通过 RTL 视图我们也能够发现 if 括号里面的条件会生成名为“EQUAL”的比较器单元,而 case 则会生成名为“DECODER”的译码器单元,这些单元并不是 FPGA 硬件底层中最小单元,而只是一种用于 RTL 视图中易于表达的抽象后的图形,使之更易于我们观察、理解其代码所实现功能的硬件结构的大致样子,也符合了“HDL(硬件描述语言)”所表述的含义。

4.仿真验证

`timescale 1ns/1ns
module tb_decorder();
reg          in_1;
reg          in_2;
reg          in_3;
wire  [7:0]  out;
//输入信号的初始化
initial
begin
   in_1 <= 1'b0;
   in_2 <= 1'b0;
   in_3 <= 1'b0;

end
//使用always进行随机数的赋值
always #10  in_1 <={$random}%2;
always #10  in_2 <={$random}%2;
always #10  in_2 <={$random}%2;

initial
begin
   $timeformat(-9,0,"ns",6);//时间格式的设置
   $monitor("@time %t:in_1=%b in_2=%b in_3=%b out=%b",$time,in_1,in_2,in_3,out);  //监测函数
end
//实例化
decorder decorder_inst
(
.in_1(in_1),
.in_2(in_2),
.in_3(in_3),
.out (out)
);
endmodule

 

三、实验结果

打印信息

波形结果

四、知识点和小技巧

输出等级

        速度等级表示的是FPGA芯片在正常工作时速度的快慢,在ultra系列芯片中,数字越小,速度越快;对于赛琳斯公司的器件,数字越大,速度越快。


http://www.kler.cn/a/400374.html

相关文章:

  • 【MySql】实验十六 综合练习:图书管理系统数据库结构
  • 学习threejs,使用AnimationMixer实现变形动画
  • Spring Events在大型项目中的最佳实践
  • Restful API接⼝简介及为什么要进⾏接⼝压测
  • 使用Python和BeautifulSoup进行网页抓取:通过Python编程语言,结合BeautifulSoup库,可以轻松地从网站上抓取所需的信息。
  • VMWare虚拟机安装华为欧拉系统
  • 案例精选 | 某知名教育集团基于安全运营平台的全域威胁溯源实践
  • 解决Ubuntu18.04及以上版本高分辨率下导致字体过小问题
  • linux开机不显示转到window
  • 鸿蒙中位置权限和相机权限
  • 远程jupyter lab的配置
  • H.265流媒体播放器EasyPlayer.js H.264/H.265播放器chrome无法访问更私有的地址是什么原因
  • ubuntu24.04设置开机自启动Eureka
  • VSCode 常用的快捷键
  • 使用WebHooks实现自动化工作流程的技术详解
  • django从入门到实战(三)——CBV视图介绍
  • QT QLineEdit失去焦点事件问题与解决
  • SQLite Truncate Table
  • 电商系统架构演进
  • Kotlin return与return@forEachIndexed
  • etcd defrag
  • React Native 全栈开发实战班 - 用户界面进阶之流行 UI 库使用与集成
  • 数据库的三大范式
  • shell bash---类似数组类型
  • Spring Boot中集成Redis与MySQL
  • npm上传自己封装的插件(vue+vite)