组合逻辑电路设计—多路选择器

多路选择器就是一个数电比较经典入门的逻辑电路。我们将使用 Verilog 语言描述一个具有多路选择器功能的电路,带领大家掌握新的语法知识和基本模块框图、波形、代码设计方法,以及最后通过仿真来验证设计的可行性。

一. 多路选择器简介

多路选择器 MUX(multiplexer) 是一个多输入、单输出的组合逻辑电路,一个 N 输入的多路选择器就
是一个 N 路的数字开关,可以根据通道选择控制信号的不同,从 N 个输入中选取一个输出到公共的输出端。多路选择器也是 FPGA 内部的一个基本资源,主要用于内部信号的选通。简单的多路选择器还可以通过级联生成更大的多路选择器。

二. 硬件设计

领航者底板的右下侧,板载了 5 个按键开关以及 4 个 LED 灯。其中最左边红色按键为 PL 端复位按键,
PL 端复位按键右边两个按键连接至 ZYNQ 的 PL 引脚,最右边两个按键连接至 ZYNQ 的 PS 引脚;最左边
两个 LED 灯也是连接至 ZTNQ 的 PL 端,最右边两个 LED 灯连接到 PS 端。实物图如下图所示:

按键跟LED的原理图如下:

从原理图可以看出,按键默认状态为高电平,按下后为低电平, LED 灯则为高电平点亮

三. FPGA实现

我们就不介绍整个FPGA设计的整个流程了

1. 需求分析

本次实验的功能是一个二选一的多路选择器,因此给模块命名为 mux2_1。模块中的输入为三个 1 位的
信号,其中 in1 和 in2 为两个输入信号, sel 为输入的控制信号, out 为单 bit 的输出信号。通过选通控制信号 sel 确定输入信号 in1 和 in2 哪一个信号作为输出。当选通控制信号 sel 为 1 时,输出为 in1 端信号;当选通控制信号 sel 为 0 时,信号输出为in2 端信号。

模块图如下图所示:

根据实验任务所述,可以列出二选一多路选择器的真值表,如下表所示:

2. 绘制波形图

json代码如下:

{ signal: [
  { name: "IN1",    wave: "101.010." },
  { name: "IN2",    wave: "0.101.01" },
  { name: "SEL",    wave: "0...1..." },
  { name: "OUT",    wave: "0.10.10." },
]}

可以看到当SEL为0的时候,那么OUT就输出IN2的值,如果SEL为1的时候,那么OUT就输出IN2的值

3. 编写rtl

module mux_2_1(
    input in1,
    input in2,
    input sel,

    output reg out
    );

always @(*) begin
    if(sel == 1'b1)
       out <= in1;
    else
        out <= in2;  
end

endmodule

其实可以这样写哈·一条语句搞定

assign out = (sel == 1'b1) ? in1 : in2;

但是为了想练习下其他写法,就按照我上面写的了,但是我上面的写法有个注意的点,就是output只能用reg类型,否则报错如下:

这个错误是因为在Verilog中,试图在 always 块中对一个没有被声明为 reg 类型的输出信号 out 进行赋值(使用 <==)。在Verilog中,只有在 alwaysinitial 块中被赋值的信号必须声明为 reg 类型,即使它本质上是一个组合逻辑输出。

4. 创建工程

对于创建工程不了解的,可以详细参照下我这篇文档

一灯大师,FPGA通过按键点亮LED灯-CSDN博客

以下所有的关于vivado的操作,我们都不再额外贴链接,都在上面的链接中

5. 工程仿真

我们先编写TestBench,代码如下:

`timescale 1ns / 1ns

module tb_mux_2_1();

reg in1;
reg in2;
reg sel;

wire out;

initial
    begin
        in1 = 1'b0;
        in2 = 1'b0;
        sel = 1'b0;

        #100
        in1 = 1'b1;
        in2 = 1'b0;
        sel = 1'b0;

        #100
        in1 = 1'b0;
        in2 = 1'b1;
        sel = 1'b0;

        #100
        in1 = 1'b1;
        in2 = 1'b1;
        sel = 1'b0;

        #100
        in1 = 1'b0;
        in2 = 1'b0;
        sel = 1'b1;

        #100
        in1 = 1'b1;
        in2 = 1'b0;
        sel = 1'b1;

        #100
        in1 = 1'b0;
        in2 = 1'b1;
        sel = 1'b1;

        #100
        in1 = 1'b1;
        in2 = 1'b1;
        sel = 1'b1;
    end

mux_2_1 u_mux_2_1(
    .in1(in1),
    .in2(in2),
    .sel(sel),

    .out(out)
);

endmodule

可以看到仿真结果是符合我们预期的:

当sel为0的时候,输出的是in2的值,当sel为1的时候,输出的结果是in1的值

6. 引脚约束

通过这里做引脚约束

7. 上板验证

从前面的原理图可知,按键默认状态为高电平,所以此时的 in1、 in2 和 sel 均为高电平,高电平点亮
LED 灯。因为 sel 为高电平,此时只有输入的 PL_KEY0(in1)可以控制 LED 灯的亮灭。同理,如果想要
使用 PL_KEY1(in2)来控制 LED 的亮灭,必须将 PL_RESET(sel)转换为低电平(按下 PL_RESET)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wireless_Link

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值