【FPGA】4选1多路选择器原理、设计
本文说明4-1多路选择器的原理、Verilog实现。
4选1多路选择器
在数字电路中,数据选择器(Data Selector)或多路开关(Multiplexer)用于在一组输入数据中选出某一个 来。例如输入有四路不同频率的PWM,而我们只需要其中一个输入到驱动电路,就可以用到4选1多路选择器。
74HC513逻辑示意图
四选一数据选择器74HC513 Logic diagram如图所示
我们先只看上半部分。
首先, S'1的反信号 与 最后输出的一路数字信号 相与,得到最终的结果Y1;
然后 A0和A1是两路控制信号,从D10~D13四路信号中,选择一路最后去和s'1非相与。
A0和A1在引出原/反信号后,A0的原/反信号 分别控制两组 接入输入数字信号的传输门构成的推挽/互补的数据开关;A1的原/反信号,又控制两个双传输门推挽/互补结构的数据开关,选择前两组信号的输出。
注意到,图中传输门、反相器都是MOSFET的构建的元件,在数电中反相器常常被用来做驱动MOSFET。这也是使用A0信号输入后“串联”两个反相器以后才接入传输门的原因。
再来看下半部分。
原理上,它和上半类似,值得关注的一点在:如何用一片74HC153组成8选1数据选择器。
实现也很简单,控制总线加一个A2的原/反信号,控制两个半片74HC153的使能。半片74HC153的输入分别作为高低四位的数据输入。因为s'1内部有反相器,A2原信号直接接S'1,A2反信号接S'2。具体参考[1]。
有关多路选择器具体的原理参考[1]、[2]
74HC513逻辑函数
Y = D0(A'1 A'0) + D1(A'1 A0) + D2(A1 A'0) + D3(A1 A0)
Verilog实现
case方式实现
module MUX41a (A,B,C,D,S1,S0,Y); input A,B,C,D,S1,S0; output Y; reg Y; always@(A or B or C or D or S1 or S0) begin : MUX41 // ":"后面是块名,用于描述、注释当前块的特征。综合时不参加编译 case({s1,s0}) //{} 是一种合并多个多位数据为一个多位数据的方法 2'b00: Y <= A; 2'b01: Y <= B; 2'b10: Y <= C; 2'b11: Y <= D; default: Y <= A; endcase end endmodule
###关于case结构中的default语句:
- 关键在于Verilog中有四种基本数值,Verilog描述的任何变量都可能有不同逻辑状态的取值:1、0、z、x。
- 0 : 含义包括 二进制数0、低电平、逻辑0、事件为假
- 1 : 含义包括 二进制数1、高电平、逻辑1、事件为真
- z 或 Z : 高阻态,或高阻值
x 或 X :不确定,或未知的逻辑状态。x和z都不区分大小写
default 不能够生成逻辑上的缺省
假如一个状态机有多个逻辑s0~S7,而case中你只写了s0~s6的状态,default并不会对应s7的状态。这样一个状态机可能就无法自启动。
assign语句实现
已知四选一多路选择器的逻辑函数
Y = D0(A'1 A'0) + D1(A'1 A0) + D2(A1 A'0) + D3(A1 A0)
据此写出数据流的逻辑描述方式。
module MUX41a (A,B,C,D,S1,S0,Y); input A,B,C,D,S1,S0; output Y; wire[1:0] SEL; //定义2元素位适量SEL为网线型变量wire wire AT, T, CT, DT; //定义中间变量,以作连线或信号节点 assign SEL = {S1,S0}; //并位操作,SEL[1] =S1;SEL[0]=S0 assign AT = (SEL==2'D0);assign BT = (SEL==2'D1); assign CT = (SEL==2'D2);assign DT = (SEL==2'D3); assign Y = (A&AT)|(B&BT)|(C&CT)|(D&DT); endmodule
1. 常用的逻辑操作符
2. 等式操作符
运算结果是1位的逻辑值
如果有的位是x或z 则判定为假,输出0
全等比较符奖x或z都当成确定的值进行比较,当表述完全相同时输出1
3. wire网线型变量
assign语句中的 赋值目标变量 (比如上例中的AT、BT等等) 必须是wire型的
用wire定义的网线型变量可以在任何类型的表达式或赋值语句(= 、<=)中作输入信号,也可在连续赋值语句或实例化元件中用作输出信号
条件赋值语句和wire
module MUX41a (A,B,C,D,S1,S0,Y); input A,B,C,D,S1,S0; output Y; wire AT = S0 ? D: C; wire BT = S0 ? B: A; wire Y = (S1 ? AT : BT); endmodule
条件表达式
条件表达式 ? 表达式1 : 表达式2
如果表达式为真,该条语句值为表达式1 ,vice versa
if-else-if
module MUX41a (A,B,C,D,S1,S0,Y); input A,B,C,D,S1,S0; output Y; //定义Y为输出信号 reg [1:0] SEL ; //定义一个模块内部的暂存变量SEL[1:0] reg Y; //定义输出端口信号Y为寄存器型变量 always @(A,B,C,D,SEL) begin //块语句起始 SEL = {S1,S0}; //把S1,S0并位为2元素矢量变量SEL[1:0] if (SEL==0) Y = A; //当SEL==0成立,即(SEL==0)=1时,Y=A; else if (SEL==1) Y = B; //当(SEL==1)为真,则Y=B; else if (SEL==2) Y = C; //当(SEL==2)为真,则Y=C; else Y = D; //当SEL==3,即SEL==2’b11时,Y = D; end //块语句结束 endmodule
1. 过程赋值语句
阻塞和非阻塞赋值是Verilog里面一个初学者经常混淆的问题。
y = a&b;
在a&b计算完后,y马上获得来自等号右侧表达式的计算值。
如果一个块语句里面有多个阻塞式赋值语句,当执行到其中某条赋值语句时,则其它语句被禁止执行。
<=
必须在块语句执行结束时才整体完成赋值操作
在begin块中的所有赋值语句都可以并行运行reference
^[1] 闫石,[M]数字电子技术(第5版),清华大学出版社 4.3.3节,188-191
^[2] 74HC153 DataSheet