小梅哥——38译码器

2023-05-16

  1. 三八译码器,即是 3 种输入状态翻译成 8 种输出状态。

  1. 真值表

  1. 代码展示

module decoder_3_8(a,b,c,out);
    input a;//输入端口a
    input b;//输入端口b
    input c;//输入端口c
    output [7:0] out;//输出端口out
    reg [7:0] out;
    //或者用output reg [7:0] out

//以always块描述的信号赋值,被赋值的对象必须要定义成reg类型
always@(a,b,c)begin //相当于always@(*),*就代指以上所有输入变量
        case({a,b,c})//位拼接,{a,b,c}变成了一个三位的信号
            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'd5 :out = 8'b0010_0000
            3'b110:out = 8'b0100_0000;
            3'b111:out = 8'b1000_0000;
            
            /* 
            3'd0:out = 8'b0000_0001;//下划线 _ 是为了增强代码的可读性。
            3'd1:out = 8'b0000_0010;
            3'd2:out = 8'b0000_0100;
            3'd3:out = 8'b0000_1000;
            3'd4:out = 8'b0001_0000;
            3'd5:out = 8'b0010_0000;
            3'd6:out = 8'b0100_0000;
            3'd7:out = 8'b1000_0000;  //注意这里的跨行注释方法 /*和*/
            */
            
        endcase
    end       
endmodule

testbench

`timescale 1ns/1ns
module decoder_3_8_tb();
    reg s_a;
    reg s_b;
    reg s_c;
    wire [7:0] out;
    
    
    decoder_3_8 decoder_3_8(
     .a(s_a),
     .b(s_b),
     .c(s_c),
     .out(out)
    );
    initial begin
        s_a=0;s_b=0;s_c=0; //在0时刻三个输入均为0
        #200;              //经过200ns的延时
        s_a=0;s_b=0;s_c=1; //在200ns时输入信号的值
        #200;              //又经过200ns的延时
        s_a=0;s_b=1;s_c=0; //在400ns时输入信号的值
        #200;              //又经过200ns的延时
        s_a=0;s_b=1;s_c=1; //在600ns时输入信号的值
        #200;
        s_a=1;s_b=0;s_c=0;
        #200;
        s_a=1;s_b=0;s_c=1;
        #200;
        s_a=1;s_b=1;s_c=0;
        #200;
        s_a=1;s_b=1;s_c=1;
        #200;      
        $stop;             //停止仿真
    end
endmodule
  1. 仿真图

  1. 补充

(1)always语句两种触发方式

a、第一种是电平触发,例如always @(a or b or c),a、b、c均为变量,当其中一个发生变化时,下方的语句将被执行。

b、第二种是沿触发,例如always @(posedge clk or negedge rstn),即当时钟处在上升沿或下降沿时,语句被执行。

c、而对于always@(),意思是以上两种触发方式都包含在内,任意一种发生变化都会触发该语句

(2)数字声明

数字声明时,合法的基数格式有 4 种,包括:十进制('d 或 'D),十六进制('h 或 'H),二进制('b 或 'B),八进制('o 或 'O)。

数字10的不同表示方式,'前面的数字表示位数,'后面的一个字母字母表示进制格式
b 二进制   4'b1010 
0 八进制   2'o12 
d 十进制   2'd10
h 十六进制 1'ha

(3)数值的种类

wire 和reg这两种数据类型的变量在定义时要设置位宽缺省为1位。变量的每一位可以是0,1,X,Z。其中x代表一个未被预置初始状态的变量或者是由于由两个或多个驱动装置试图将之设定为不同的值而引起的冲突型线型变量。z代表高阻状态或浮空量

Verilog HDL 有下列四种基本的值来表示硬件电路中的电平逻辑:
0:逻辑 0 或 "假"
1:逻辑 1 或 "真"
x 或 X:未知
z 或 Z:高阻
x 意味着信号数值的不确定,即在实际电路里,信号可能为 1,也可能为 0。
z 意味着信号处于高阻状态,常见于信号(input, reg)没有驱动时的逻辑结果。例如一个 pad 的 input 呈现高阻状态时,其逻辑值和上下拉的状态有关系。上拉则逻辑值为 1,下拉则为 0 。

(4)数据的类型

Verilog 最常用的 2 种数据类型就是线型(wire)与寄存器型(reg),其余类型可以理解为这两种数据类型的扩展或辅助。

a、线网(wire)使用在连续赋值语句中

相当于一根电线,用来连接电路,不能存储数据,无驱动能力,只能在assign左侧赋值。

wire型数据常用来表示以assign关键字指定的组合逻辑信号。模块的输入输出端口类型默认为wire型(默认初始值是z)不指定就默认为1位wire类型,专门指定出wire类型,可能是多位或为使程序易读。

wire表示直通,即只要输入有变化,输出马上无条件地反映。

线网型还有其他数据类型,包括 wand,wor,wri,triand,trior,trireg 等。这些数据类型用的频率不是很高。

b、寄存器(reg)使用在过程赋值语句中

always模块内被赋值的信号,必须定义为reg型,默认初始值是x。

reg表示一定要有触发,输出才会反映输入。

reg只能在initial和always中赋值。

reg可以综合成register,latch,甚至wire(当其只是中间变量的时候),可以用于组合逻辑或者时序逻辑,能存储数据,有驱动能力,在always @模块表达式左侧被赋值。

寄存器(reg)用来表示存储单元它会保持数据原有的值,直到被改写

c、两者的共同点

都能用于assign与always @模块表达式的右侧。

d、连续赋值语句和过程赋值语句

连续赋值语句中,表达式右侧的计算结果可以立即更新表达式的左侧。在理解上,相当于一个逻辑之后直接连了一条线,这个逻辑对应于表达式的右侧,而这条线就对应于wire

过程赋值语句中,表达式右侧的计算结果在某种条件的触发下放到一个变量当中,而这个变量可以声明成reg类型的。根据触发条件的不同,过程赋值语句可以建模不同的硬件结构:如果这个条件是时钟的上升沿或下降沿,那么这个硬件模型就是一个触发器;如果这个条件是某一信号的高电平或低电平,那么这个硬件模型就是一个锁存器;如果这个条件是赋值语句右侧任意操作数的变化,那么这个硬件模型就是一个组合逻辑。

e、综合之后的区别

wire型的变量综合出来一般是一根导线;

reg变量在always块中有两种情况: always后的敏感表中是(a or b or c)形式的,也就是不带时钟边沿的,综合出来还是组合逻辑 always后的敏感表中是(posedge clk)形式的,也就是带边沿的,综合出来一般是时序逻辑,会包含触发器(Flip-Flop)

在设计中,输入信号一般来说你是不知道上一级是寄存器输出还是组合逻辑输出,那么对于本级来说就是一根导线,也就是wire型。而输出信号则由你自己来决定是寄存器输出还是组合逻辑输出,wire型、reg型都可以。但一般的,整个设计的外部输出(即最顶层模块的输出),要求是寄存器输出,较稳定、扇出能力也较好。

(5)

输入端口可以由net/reg驱动,但输入端口只能是net,如a = b & c,输入端口a 只能是net型,但其驱动b,c可以是net/reg型;

输出端口可以使net/reg类型,输出端口只能驱动net,如a = b & c,模块的输出端口b,c可以是net/reg型,但它们驱动的a必须是net型;若输出端口在过程块(always/initial)中赋值则为reg型,若在过程块外赋值则为net型。用关键词inout声明一个双向端口, inout端口不能声明为寄存器类型,只能是net类型。


(6)课后作业

实现4-16译码器

a、原理框图

`timescale 1ns / 1ns
module decoder_4_16(a,b,c,d,out
   );
   input a;
   input b;
   input c;
   input d;
   output reg[15:0] out;
always@(a,b,c,d)begin
   case({a,b,c,d})
       4'b0000:out=16'b0000_0000_0000_0001;
       4'b0001:out=16'b0000_0000_0000_0010;
       4'b0010:out=16'b0000_0000_0000_0100;
       4'b0011:out=16'b0000_0000_0000_1000;
       4'b0100:out=16'b0000_0000_0001_0000;
       4'b0101:out=16'b0000_0000_0010_0000;
       4'b0110:out=16'b0000_0000_0100_0000;
       4'b0111:out=16'b0000_0000_1000_0000;
       4'b1000:out=16'b0000_0001_0000_0000;
       4'b1001:out=16'b0000_0010_0000_0000;
       4'b1010:out=16'b0000_0100_0000_0000;
       4'b1011:out=16'b0000_1000_0000_0000;
       4'b1100:out=16'b0001_0000_0000_0000;
       4'b1101:out=16'b0010_0000_0000_0000;
       4'b1110:out=16'b0100_0000_0000_0000;
       4'b1111:out=16'b1000_0000_0000_0000;
       
    /* 2'd00:out=16'b0000_0000_0000_0001;
       2'd01:out=16'b0000_0000_0000_0010;
       2'd02:out=16'b0000_0000_0000_0100;
       2'd03:out=16'b0000_0000_0000_1000;
       2'd04:out=16'b0000_0000_0001_0000;
       2'd05:out=16'b0000_0000_0010_0000;
       2'd06:out=16'b0000_0000_0100_0000;
       2'd07:out=16'b0000_0000_1000_0000;
       2'd08:out=16'b0000_0001_0000_0000;
       2'd09:out=16'b0000_0010_0000_0000;
       2'd10:out=16'b0000_0100_0000_0000;
       2'd11:out=16'b0000_1000_0000_0000;
       2'd12:out=16'b0001_0000_0000_0000;
       2'd13:out=16'b0010_0000_0000_0000;
       2'd14:out=16'b0100_0000_0000_0000;
       2'd15:out=16'b1000_0000_0000_0000;*/
   endcase
end       
endmodule
`timescale 1ns / 1ns

module decoder_4_16_tb(

   );
   reg s_a;
   reg s_b;
   reg s_c;
   reg s_d;
   wire [15:0] out;  
   
   decoder_4_16 decoder_4_16(
     .a(s_a),
     .b(s_b),
     .c(s_c),
     .d(s_d),
     .out(out)
   );
   initial begin
       s_a=0;s_b=0;s_c=0;s_d=0;
       #100;
       s_a=0;s_b=0;s_c=0;s_d=1;
       #100;
       s_a=0;s_b=0;s_c=1;s_d=0;
       #100;
       s_a=0;s_b=0;s_c=1;s_d=1;
       #100;
       s_a=0;s_b=1;s_c=0;s_d=0;
       #100;
       s_a=0;s_b=1;s_c=0;s_d=1;
       #100;
       s_a=0;s_b=1;s_c=1;s_d=0;
       #100;
       s_a=0;s_b=1;s_c=1;s_d=1;
       #100;
       s_a=1;s_b=0;s_c=0;s_d=0;
       #100;
       s_a=1;s_b=0;s_c=0;s_d=1;
       #100;
       s_a=1;s_b=0;s_c=1;s_d=0;
       #100;
       s_a=1;s_b=0;s_c=1;s_d=1;
       #100;
       s_a=1;s_b=1;s_c=0;s_d=0;
       #100;
       s_a=1;s_b=1;s_c=0;s_d=1;
       #100;
       s_a=1;s_b=1;s_c=1;s_d=0;
       #100;
       s_a=1;s_b=1;s_c=1;s_d=1;
       #100;   
   end
endmodule

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

小梅哥——38译码器 的相关文章

随机推荐

  • 二叉链表树的遍历

    题目 xff1a 使用二叉链表树创建算法Status CreatBiTree BiTree amp T 和其他代码 二叉树的遍历有三种 xff1a 前序遍历 xff1a 先访问根节点 xff0c 再遍历左子树 xff0c 最后遍历右子树 x
  • opencv的框架与各模块功能介绍

    记录一下自己的所学知识 xff0c 便于日后回顾与整理 文中内容多为摘录 xff0c 具体链接如下 xff1a 摘录自 xff1a https zhuanlan zhihu com p 33008701 xff08 框架介绍 xff09 h
  • Android调用C/C++库

    AndroidStudio版本2021 1 1 一 AndroidStudio将C C 43 43 库打包成so库过程 AndroidStudio新建NativeC 43 43 工程 xff1b 在Tools gt SDK Manager里
  • SocketCan 应用编程

    SocketCan 应用编程 由于 Linux 系统将 CAN 设备作为网络设备进行管理 xff0c 因此在 CAN 总线应用开发方面 xff0c Linux 提供了SocketCAN 应用编程接口 xff0c 使得 CAN 总线通信近似于
  • QT开发笔记(继承 QObject 的线程 )

    继承 QObject 的线程 在第 10 章章节开头已经说过 xff0c 继承 QThread 类是创建线程的一种方法 xff0c 另一种就是继承 QObject 类 继承 QObject 类更加灵活 它通过 QObject moveToT
  • CoppeliaSim:视觉传感器的使用与属性参数

    视觉传感器类型 http www coppeliarobotics com helpFiles index html Orthographic projection type the field of view of orthographi
  • 华为Atlas200DK环境配置指南(版本20.0.0)

    官方参考文档 https support huaweicloud com usermanual A200dk 3000 atlas200dk 02 0024 html 务必保证配置时版本 20 0 0 一致 1 配置开发环境 自己电脑 若不
  • PX4 QGC地面站自定义参数

    QGC地面站自定义参数 xff08 新手操作 xff09 v1 8 2 QGC以往版本下载地址 htps github com mavlink qgroundcontrol tags 最终的添加结果如下 xff1a 具体步骤如下 xff1a
  • Linux网络编程----UDP编程基础知识

    UDP概述 UDP 是 User Datagram Protocol 的简称 xff0c 中文名是用户数据报协议 xff0c 是一个简单的面向数据报的传输层协议 xff0c 在网络中用于处理数据包 xff0c 是一种无连接的协议 UDP 不
  • get 命令汇总

    get 命令汇总 git config 配置 Git 的相关参数 Git 一共有3个配置文件 xff1a 1 仓库级的配置文件 xff1a 在仓库的 git gitconfig xff0c 该配置文件只对所在的仓库有效 2 全局配置文件 x
  • c++ socket简单封装

    简单封装 并不实际应用 框架图 Mysocket 主要是定义TCP和UDP的一些相同的操作 xff0c 需要的他们各自去实现 Mysocket h ifndef MYSOCKET H define MYSOCKET H class MySo
  • pixhawk2飞控接头型号

    BM04B GHS TBT BM05B GHS TBT BM06B GHS TBT
  • 多种视觉SLAM方案对比

    点击上方 小白学视觉 xff0c 选择加 34 星标 34 或 置顶 重磅干货 xff0c 第一时间送达 本文转自 新机器视觉 在SLAM研究中 xff0c 我们通常需要在各数据集上测试各个方案的性能情况 如下主要对表1中6个视觉SLAM方
  • 激光雷达核心技术及行业格局梳理

    点击上方 小白学视觉 xff0c 选择加 34 星标 34 或 置顶 重磅干货 xff0c 第一时间送达 引言 xff1a 车载摄像头是ADAS 的核心传感器 车载摄像头搭载颗数稳步提升 根据 Yole 数据 xff0c 2018 年全球平
  • 2 ROS1通讯编程基础(2)

    2 ROS1通讯编程基础 2 3 配置文件的解读2 3 1 CMakeList txt解读2 3 1 1 find package的配置2 3 1 2 messages services and actions的配置2 3 1 3 动态重配
  • Rviz 使用Arbotix控制机器人运动

    需求 控制机器人模型在 rviz 中做圆周运动 实现流程 安装 Arbotix创建新功能包 xff0c 准备机器人 urdf xacro 文件添加 Arbotix 配置文件编写 launch 文件配置 Arbotix启动 launch 文件
  • VINS问题整理

    VINS的初始化过程 xff1f 首先进行纯视觉SfM xff1a 把滑窗填满 xff0c 然后选择枢纽帧 xff08 和最后一帧有足够的视野重叠保证计算的位姿精度 xff0c 并且和最后一帧有足够的视差保证三角化地图点的精度 xff09
  • 两台ubuntu电脑如何搭建局域网以及通信

    两台ubuntu电脑如何搭建局域网以及通信 功能 xff1a 用自己的电脑代替设备中的电脑进行数据处理 xff0c 以及将最后的结果传给设备电脑 需要做的内容的 xff1a 首先用网线将自己的pc与设备连接起来 1 将自己的笔记本ip地址手
  • PC偏振控制器、锁模激光器技术、AOM声光调制器、相位噪声、锁相环、光耦合器类型

    1 PC 偏振控制器 xff08 1 xff09 什么叫做偏振光 xff1f polarized light 光是一种电磁波 xff0c 电磁波是横波 xff0c 它具有偏振性 xff0c 具有偏振性的光则称为偏振光 具体体现 xff1a
  • 小梅哥——38译码器

    三八译码器 xff0c 即是 3 种输入状态翻译成 8 种输出状态 真值表 代码展示 module decoder 3 8 a b c out input a 输入端口a input b 输入端口b input c 输入端口c output