数字电路基础

devtools/2025/4/2 2:47:57/

组合逻辑——多路选择器:

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

verilog代码:

module mux4_1(
input              in1 ,//输入四个信号
input              in2 ,
input              in3 ,
input              in4 ,
input        [1:0] sel ,//输入条件信号
output  reg        out  //输出信号);always@(*)begincase(sel)2'b00:out <= in1;2'b01:out <= in2;2'b10:out <= in3;2'b11:out <= in4;default:;endcase
endendmodule

tb代码:

`timescale 1ns / 1psmodule tb_test();
reg       in1 ;
reg       in2 ;
reg       in3 ;
reg       in4 ;
reg [1:0] sel ;
wire      out ;initial begin
in1 = 0;
in2 = 1;
in3 = 1;
in4 = 0;
sel = 2'b00;
#100
sel = 2'b10;
#100
sel = 2'b11;
#100
sel = 2'b01;endmux4_1 u_mux4_1(
.   in1  (in1),//输入四个信号
.   in2  (in2),
.   in3  (in3),
.   in4  (in4),
.   sel  (sel),//输入条件信号
.   out  (out) //输出信号);endmodule

在仿真中我们分别给四个输入信号赋初值,每次间隔100ns更改sel的值

仿真结果:

由仿真结果可以出,四个输入信号成功赋初值,每当sel发生改变时,out输出的值也在发生改变。自此多路选择器成功实现。


组合逻辑——译码器:

译码器是一种多输入多输出的组合逻辑电路,译码是编码的逆过程,同时去掉比特流在传播过程中混入的噪声。利用译码表把文字译成一组组数码或用译码表将代表某一项信息的一系列信号译成文字的过程称之为译码。在数码管等部分需要使用,这里将介绍其中一种——38译码器。

verilog代码:

module yima3_8(
input            A    ,//输入三个数据信号
input            B    ,//
input            C    ,//
output reg [7:0] out   //输出译码后的8位二进制数);
wire [2:0] sel;//定义一个3位的信号assign sel = {A,B,C};//通过拼接的方式将输入的三个数据组成在一起 000 001 010等always@(*)begincase(sel)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:;
endcase
endendmodule

tb代码:

`timescale 1ns / 1psmodule tb_test();
reg A ;
reg B ;
reg C ;
wire [7:0] out;initial begin
A = 0;B = 0;C = 0;
#100
A = 0;B = 0;C = 1;
#100
A = 0;B = 1;C = 0;
#100
A = 0;B = 1;C = 1;
#100
A = 1;B = 0;C = 0;
#100
A = 1;B = 0;C = 1;
#100
A = 1;B = 1;C = 0;
#100
A = 1;B = 1;C = 1;endyima3_8 u_yima3_8(
.    A    (A  ),
.    B    (B  ),
.    C    (C  ),
.    out  (out)
);endmodule

在仿真代码中每间隔100ns给A、B、C三个输入信号赋不同的值

仿真结果:

由于这里是组合逻辑,因此在仿真代码中并没有加入时钟,根据仿真结果可以看到每相隔100ns,A、B、C数据跳变一次,同时输出的8位数据也在跳变。那么译码器就编写成功,感兴趣的可以去尝试一下其它多路输入输出。


边沿检测电路:

在实际设计中,通常需要观测信号是否发生跳变,这里通常需要有一个边沿检测电路,它也是一种非常典型的电路设计。一般可分为上边沿检测、下边沿检测、双边沿检测电路。

verilog代码:

module edge_test(input  wire clk       ,//时钟input  wire rst_n     ,//复位input       a         ,//输入待检测信号output      a_posedge ,//输出上边沿检测output      a_negedge ,//输出下边沿检测output      a_edge     //输出双沿检测);reg a_dly ;//将待检测信号寄存打一拍always @(posedge clk or negedge rst_n)beginif(!rst_n)a_dly <= 0;elsea_dly <= a;endassign    a_posedge = a & ~a_dly;//待检测信号与上打拍后取反信号
assign    a_negedge = ~a & a_dly;//取反待检测信号与上打拍后信号
assign    a_edge    = a ^ a_dly ;//待检测信号异或打拍后信号endmodule

tb代码:

`timescale 1ns / 1psmodule tb_test();
reg   clk       ;  
reg   rst_n     ;  
reg   a         ;  
wire  a_posedg  ;
wire  a_negedg  ;
wire  a_edge    ;initial begin
clk   = 0;
rst_n = 0;
a     = 0;#101 rst_n = 1;
#20  a     = 1;
#100 a     = 0;endalways #10 clk = ~clk;edge_test u_edge_test(.   clk        (clk      ),//时钟.   rst_n      (rst_n    ),//复位.   a          (a        ),//输入待检测信号.   a_posedge  (a_posedge),//输出上边沿检测.   a_negedge  (a_negedge),//输出下边沿检测.   a_edge     (a_edge   ) //输出双沿检测);endmodule

仿真结果:

由仿真结果可以看到,在经过101ns后复位拉高,再经过20ns后信号a到来,a_dly打一拍后在下一个时钟周期拉高。经过100ns后a信号拉低,a_dly信号也随之拉低。

上升沿:粉色信号线

下降沿:紫色信号线

双边沿检测:黄色信号线


分频电路:

在开发过程中,通常会遇到对时钟进行分频或倍频,一般情况下使用的是PLL(锁相环),但由于其特性,可能在某些特定环境下无法实现分频,这时候就可以使用verilog代码来设计分频电路。

偶分频:

这里设计一个四分配电路为例,实现方法就是套用公式n/2-1,得到cnt计数为1,每次cnt加到1,清零时钟翻转

verilog代码:

module divider_4(
input   wire clk     ,//输入系统时钟
input   wire rst_n   ,//输入复位信号
output  reg  out_clk  //输出分频后时钟);reg [1:0] cnt;//用于分频计数always @(posedge clk or negedge rst_n)beginif(!rst_n)cnt <= 0;else if(cnt == 1)cnt <= 0;elsecnt <= cnt + 1;
endalways @(posedge clk or negedge rst_n)beginif(!rst_n)out_clk <= 0;else if(cnt == 1)out_clk <= ~out_clk;elseout_clk <= out_clk;
endendmodule

tb代码:

`timescale 1ns / 1psmodule tb_test();
reg   clk       ;  
reg   rst_n     ;  
wire  out_clk   ;initial begin
clk   = 0;
rst_n = 0;#101 rst_n = 1;endalways #10 clk = ~clk;divider_4 u_divider_4(
.   clk      (clk    ),//输入系统时钟
.   rst_n    (rst_n  ),//输入复位信号
.   out_clk  (out_clk) //输出分频后时钟);endmodule

仿真结果:

由上图可以看出,粉色是分频后的时钟,分频后的一个完整的时钟周期相当于分频前的四个时钟周期,根据cnt计数进行翻转。

奇分频:

这里设计一个7分频电路,将会存在两个delay,第一个是n-1为6,第二个是n-/2为3,同时一个检测上升沿,一个检测下降沿,最后再将两者用或门输出。

verilog代码:

module divider_7(
input  wire clk     ,//时钟
input  wire rst_n   ,//复位
output      out_clk  //分频后时钟);parameter delay  = 6    ;//定义分频次数 N-1reg [2:0] cnt     ;//分频计数
reg       out_clk1;//上升沿
reg       out_clk2;//下降沿always @(posedge clk or negedge rst_n)beginif(!rst_n)cnt <= 0;else if(cnt == delay)//计数器等于6清零cnt <= 0;elsecnt <= cnt + 1;
endalways @(posedge clk or negedge rst_n)begin//检测上升沿if(!rst_n)out_clk1 <= 0;else if(cnt == 3 || cnt == 6)out_clk1 <= ~out_clk1;elseout_clk1 <= out_clk1;
endalways @(negedge clk or negedge rst_n)begin//检测下降沿if(!rst_n)out_clk2 <= 0;else if(cnt == 3 || cnt == 6)out_clk2 <= ~out_clk2;elseout_clk2 <= out_clk2;
endassign out_clk = out_clk1 || out_clk2;//用或门将两者合并输出endmodule

tb仿真:

`timescale 1ns / 1psmodule tb_test();
reg   clk       ;  
reg   rst_n     ;  
wire  out_clk   ;initial begin
clk   = 0;
rst_n = 0;#101 rst_n = 1;endalways #10 clk = ~clk;divider_7 u_divider_7(
.   clk      (clk    ),//时钟
.   rst_n    (rst_n  ),//复位
.   out_clk  (out_clk) //分频后时钟);endmodule

仿真结果:

由上图可以看出,黄色的线是最终合并输出的7分频后时钟,它由7个原本的时钟构成。

总结:

以上是一些常见的FPGA数字电路基础设计,感兴趣的可以去尝试一下。有错误的地方希望能够指出,谢谢!

文章来源:https://blog.csdn.net/joker0518/article/details/146404986
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ppmy.cn/devtools/172306.html

相关文章

1.25-20GHz/500ns超快跳频!盛铂SWFA300国产捷变频频率综合器模块赋能雷达/5G/电子战高频精密控制 本振/频综模块

盛铂SWFA300捷变频频率综合器模块简述&#xff1a; 盛铂科技国产SWFA300捷变频频率综合器是一款在频率范围内任意两点频率的跳频时间在500nS以内的高速跳频源&#xff0c;其输出频率范围为1.25GHz至20GHz&#xff0c;频率的最小步进为10kHz。同时它拥有优秀的相位噪声特性&…

Linux探秘坊-------10.基础IO

1.文件理解 1.狭义理解 2.⼴义理解 3.⽂件操作的归类认知 2.c语言的文件操作复习 1.读文件 #include <stdio.h> #include <string.h> int main() {FILE* fp fopen("myfile", "r");if (!fp) {printf("fopen error!\n");return 1;…

2025年CNG 汽车加气站操作工考试练习题库

CNG 汽车加气站操作工考试练习题库&#xff1a; 1、燃气管道降压作业时可将压力控制在&#xff08; &#xff09;范围内。 A. 300Pa&#xff5e;800Pa B. 500Pa&#xff5e;1000Pa C. 800Pa&#xff5e;1200Pa D. 1000Pa&#xff5e;1500Pa 答案&#xff1a;A 2、CNG 的…

数据结构与算法-数据结构-线段树1(单点修改,区间查询):最大数,你能回答这些问题吗

介绍&#xff1a; 概念 线段树是一种二叉树数据结构&#xff0c;它用于高效处理区间查询&#xff08;如求区间和、区间最大值等&#xff09;和单点修改、区间修改操作。线段树的每个节点代表一个区间&#xff0c;根节点代表整个待处理的区间&#xff0c;每个内部节点将其代表的…

CentOS 7 如何挂载ntfs的移动硬盘

CentOS 7 如何挂载ntfs的移动硬盘 前言一、查看硬盘并尝试挂载(提示无法挂载)二、yum安装epel-release提示yum被锁定三、强行终止yum的进程四、yum安装epel-release完成五、yum安装ntfs-3g六、此时可正常挂载NTFS硬盘 前言 CentOS 7默认情况下是不支持NTFS的文件系统&#xff…

TraeAI结合Proteus实现AI编程并仿真一个复杂工业物联网控制系统的开发(视频)

简介&#xff1a; 本视频聚焦基于国内首个 AI 原生集成开发环境&#xff08;AI IDE&#xff09;的 AI 编程实践。借助提示词&#xff0c;在 Proteus 环境下结合 ESP32 - S3&#xff0c;运用 MicroPython 进行状态机程序设计。展示如何通过在Trae CN人工智能集成编程开发环境&am…

深入理解 Android Intent:Action 与 Category 详解

在 Android 开发中&#xff0c;Intent 是组件之间通信的核心机制&#xff0c;其中 Action&#xff08;动作&#xff09;和 Category&#xff08;类别&#xff09;决定了 Intent 的用途和目标。在本文中&#xff0c;我们将详细解析常见的 Action 和 Category 及其应用场景&#…

StarRocks 中 CURRENT_TIMESTAMP 和 CURRENT_TIME 分区过滤问题

背景 本文基于Starrocks 3.3.5 最近在进行Starrocks 跑数据的时候&#xff0c;发现了一个SQL 扫描了所有分区的数据&#xff0c;简化后的SQL如下&#xff1a; select date_created from tableA where date_createddate_format(current_time(), %Y-%m-%d %H:%i:%S) limit 20其…