找回密码
 立即注册
查看: 231|回复: 0

【数字逻辑 & Verilog】全面剖析数据选择器——从基础到拓展,从理论到设计的实现,从表面到本质

[复制链接]
发表于 2022-6-27 08:43 | 显示全部楼层 |阅读模式
4.2 模块实现

4.2.1 设计块
  1. // 4位八选一数据选择器
  2. module choose_8to1_4sizes (
  3.     input [3:0] i0,i1,i2,i3,i4,i5,i6,i7,// 数据输入端
  4.     input s2,s1,s0,// 地址输入端
  5.     input [3:0] e,// 新的使能端
  6.     output [3:0] out      // 数据输出端);
  7.    
  8.     wire [3:0] out1,out2;// 两个四选一的输出
  9.         
  10.     choose_4to1_4sizes DT4_0 (i4,i5,i6,i7,s1,s0,s2,out1);// 高4位
  11.     choose_4to1_4sizes DT4_1 (i0,i1,i2,i3,s1,s0,~s2,out2);// 低4位
  12.    
  13.     assign out =(out1 | out2)& e;
  14. endmodule
复制代码
4.2.2 激励块
  1. module test();
  2.    
  3.     reg [3:0] I0 =1,I1 =2,I2 =3,I3 =4,I4 =5,I5 =6,I6 =7,I7 =8;
  4.     reg S2,S1,S0;
  5.     reg [3:0] E =4'b1111;
  6.     wire [3:0] OUT;
  7.    
  8.     choose_8to1_4sizes CT0 (I0,I1,I2,I3,I4,I5,I6,I7,S2,S1,S0,E,OUT);
  9.    
  10.     initial
  11.         #1 $monitor("S2 = %b,  S1 = %b,  S0 = %b,  OUT = %d\n",S2,S1,S0,OUT);
  12.    
  13.     initial
  14.     begin
  15.         $display("I0 = %b, I1 = %b, I2 = %b, I3 = %b\nI4 = %b, I5 = %b, I6 = %b, I7 = %b\n\n",I0,I1,I2,I3,I4,I5,I6,I7);
  16.         #1 S2 =0;  S1 =0;  S0 =0;
  17.         #1 S2 =0;  S1 =0;  S0 =1;
  18.         #1 S2 =0;  S1 =1;  S0 =0;
  19.         #1 S2 =0;  S1 =1;  S0 =1;
  20.         
  21.         #1 S2 =1;  S1 =0;  S0 =0;
  22.         #1 S2 =1;  S1 =0;  S0 =1;
  23.         #1 S2 =1;  S1 =1;  S0 =0;
  24.         #1 S2 =1;  S1 =1;  S0 =1;
  25.     end
  26.    
  27. endmodule
复制代码
4.2.3 结果验证



4.3 重要知识点与思维方法

4.3.1 解决错误的方法论

    分析程序的行为是什么,而不是为什么程序不按照你想的来注意使用单元测试
      保证低层模块没有问题,再实现高层模块如果高层模块出了问题,先从高层找问题再逐一找到之前没有问题的低层模块,进行修正

4.3.2 按位运算与逻辑运算

    按位运算是二进制位的每一位进行运算,其结果位数为:两个操作数的最小位数逻辑运算把操作数都当成0,1,x,z,其结果也是0,1,x,z(这里是粗略说明,详细内容可以百度一下对应真值表)
4.3.2.1 按位运算:位宽不匹配时的注意事项

当按位运算的两操作数位宽不相等时,短位宽数会在左侧补0,使两操作数位宽一致。
在上述4位八选一数据选择器的设计块中,模块结尾处有这样一条语句:assign out = (out1 | out2) & e;
并且,我在前面使用的是位宽为4的使能端,这里,我想有必要详细解释一下为什么这样做,并且我会告诉你更好的解决方案。
我们知道以下的事实:
    使能端的作用: 它就相当于选择器的开关,打开它选择器才能正常工作,关闭它选择器就不能工作。开关的两种形式: 低电平有效和高电平有效,这里我采用的是高电平有效,也就是e = 1的时候才有效(但是事实上,大多数情况我们都采用低电平有效的使能端,可是,你想过为什么吗?我在后面将解释为什么要这样做)
接下来,我将会讲解为什么使用4位的使能端:
4位的使能端,只有当e = 4b'_1111的时候才能启动选择器,如果它是1位的,我们则只能为他赋值e = 1'b_1,此后它将与4位的数据进行逻辑与运算,我们知道,位宽不匹配的时候,短位宽将会自动补0再运算,此时的e将会被虚拟地增加3个0e = 4'b_0001,显然这样运算的结果是错误的。
我想你能够明白为什么高电平有效的使能端,在这里要使用4位位宽了。
不过,这样会对未来造成麻烦,我非常不建议你这样做,试想一下,如果用这样的八选一数据选择器,去扩展为十六选一的,将会出现一些问题。
那么,如何保证使能端依然是1位呢?
请注意一个事实,那就是,位宽不匹配的时候,系统会自动补0,因为补的是0,所以,我们应该采用低电平有效的使能端,将前面的逻辑表达式改一下就可以assign out = (out1 | out2) & (~e);
5 组合型扩展:一位/多位双四选一数据选择器

这个就是简单的组合而已,没什么好说的,除了使能端共用,输入输出端口依然还是各自独立的。

6 深入浅出:将数据选择器讲给孩子听

尝试将专业的知识将给孩子听,并让他听懂,就说明你真的掌握了,我给你一些提示:
    输入:香蕉,苹果,橘子,大鸭梨控制:开关 X 1,控制端 X 2输出:某一个水果

7 一句话总结

数据选择器就是,将多组数据输入,通过地址控制和开关控制,输出其中一组指定的数据。

8 科技黑箱:直接应用“数据选择器”解决现实问题

——现实生活中有项目需求,但是没有问题,也没有答案
8.0 对数据选择器新的理解

使用数据选择器,实现:数据输入端的并联,不同的地址,输出同一个结果
8.1 需求:红绿灯故障检测系统

    正常情况:三盏灯只有一个是亮的故障情况:正常情况均为故障
现要求,能够实现故障的检测,出现故障的时候系统会自动报警,请使用数据选择器设计逻辑电路
8.2 设计部分:组合逻辑电路

8.2.1 信息符号化

两个核心要点:
    信息的符号表示逻辑值的含义


  • 三盏灯 1代表亮,0代表不亮
      红灯 R黄灯 Y绿灯 G

  • 故障检测 F
      F = 1,代表故障F = 0,代表没有故障
    检测开关:使能端E,低电平有效
8.2.2 求逻辑表达式

真值表如下:
EbarRYG输出:Fbar
1xxxx
00000
00011
00101
00110
01001
01010
01100
01110
0xxxx
逻辑表达式如下:
Fbar = Rbar·Ybar·G + Rbar·Y·Gbar + R·Ybar·Gbar
= m0·G + m1·Gbar + m2·Gbar + m3·0
8.2.3 器件选择

使用四选一数据选择器
    地址输入端:R,Y数据输入端:G,Gbar使能端:E数据输出端:F
8.3 实现部分:Verilog实现逻辑电路

8.3.0 构建模型



8.3.1 设计块
  1. // 红绿灯故障检测
  2. module RYG_Flault_test (
  3.     input G,// 数据输入
  4.     input R,Y,// 地址输入
  5.     input E,// 使能端
  6.     output F
  7.     );
  8.    
  9.     wire F1;
  10.     choose_4to1 RYG_test (G,~G,~G,0,R,Y,E,F1);// 为什么不能输出端口不能连接“~F”??
  11.    
  12.     assign F =~F1;
  13. endmodule
复制代码
特别注意:输出端口不能连接~F,只能多加一步导一下
8.3.2 激励块
  1. // 红绿灯故障检测系统测试
  2. module test;
  3.    
  4.     reg R,Y;
  5.     reg G;
  6.     reg E =1;
  7.     wire F;
  8.    
  9.     RYG_Flault_test RYG_Test(G,R,Y,E,F);// 红绿灯检测模块实例
  10.    
  11.     initial
  12.         $monitor($time,"  R = %b,  Y = %b,  G = %b,  F = %b\n",R,Y,G,F);// 显示红绿灯的状况
  13.         
  14.     initial
  15.     begin
  16.         #1 R =0;   Y =0;   G =0;
  17.         #1 R =0;   Y =0;   G =1;
  18.         #1 R =0;   Y =1;   G =0;
  19.         #1 R =0;   Y =1;   G =1;
  20.         
  21.         #1 R =1;   Y =0;   G =0;
  22.         #1 R =1;   Y =0;   G =1;
  23.         #1 R =1;   Y =1;   G =0;
  24.         #1 R =1;   Y =1;   G =1;
  25.     end   
  26.         
  27. endmodule
复制代码
8.3.3 结果验证



9 深入剖析数据选择器的本质

数据选择器的本质,是多路选择器!,它可以应用于任何需要做出功能选择的电路中去,它是非常常见并且实用的,数据选择器的设计思想可以推广到任意功能的选择上去,而不仅仅是数据的选择。

10 组合逻辑电路的设计

各种器件的本质,不过是逻辑表达式,对于期间的使用,需要进行实际需求表达式与器件逻辑表达式的对应关系即可!
这个部分我将会在其他文章阐述,敬请期待。

11 Verilog之行为级建模的魅力

事实上,对于以上的Verilog代码,并不需要那样繁琐,也不需要那么多行,为什么我依然坚持使用呢?
    充分深入底层逻辑,并通过实战帮助你理解数据选择器,为后面使用多路选择器打基础充分使用层次建模思想解决问题,锻炼核心思维
请记住,即便有了更为简单的方法,我们依然不应该完全放弃底层知识的学习,没有底层积累,是不能设计出优秀的顶层设计的。
行为级仿真代码留给读者自行完成。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-26 05:30 , Processed in 0.130030 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表