不知为何,人是一种对3和1情有独钟的生物
简报
众所周知,74ls148是和74ls283、74ls151还有74ls138一样应用广泛的电子元器件。而且功能还存在一些微妙的地方。其本体共1+1+1+1+1+8+3=16根引脚。鉴于接地和电源引脚还是没有什么大用处,笔者将使用Verilog HDL语言在Vivado上面对其余14根引脚的功能进行实现。
引脚
74ls148的逻辑符号共1+1+1+8+3=14根引脚,分别为使能输入端,使能输出端,组信号输出端,十进制输入端8根,二进制输出端3根。下面为具体说明。
- 使能输入端:共1根,低电平有效,是元件的“开关”。
- 使能输出端:共1根,根据真值表(笔者不想插入了…插入就要重新设计排版的说…)当且仅当十进制输入端的八根引脚输入为11111111时,才会输出低电平(0),其余情况均输出高电平(1),在级联时有意义,表示触发低位编码器工作。
- 组信号输出端:共1根,在级联时作为进位输出。
- 十进制输入端:共8根,输入待编码的信号。
- 二进制输出端:共3根,输出编码。
注意:74ls148为优先编码器,优先顺序为自高位向低位编码,由于其所有引脚均为反码输入,所以对输入信号左边最后一个1进行编码。这种规定可避免由信号重复造成的混乱。
代码
下面为74ls148对应的Verilog HDL代码。
module x74x148(
input EI,
input [7:0] I,
output reg GS,
output reg [2:0] Q,
output reg EO
);
always@ *
begin
Q=3'b111;
EO=1;
GS=1;
if(~EI)
begin
casez(I)
8'b11111111:
begin
EO=0;
end
8'b0???????:
begin
GS=0;
Q=3'b000;
end
8'b10??????:
begin
GS=0;
Q=3'b001;
end
8'b110?????:
begin
GS=0;
Q=3'b010;
end
8'b1110????:
begin
GS=0;
Q=3'b011;
end
8'b11110???:
begin
GS=0;
Q=3'b100;
end
8'b111110??:
begin
GS=0;
Q=3'b101;
end
8'b1111110?:
begin
GS=0;
Q=3'b110;
end
8'b11111110:
begin
GS=0;
Q=3'b111;
end
endcase
end
end
endmodule
笔者根据真值表对其功能进行编码,其中EI为使能输入端,EO为使能输出端,GS为组信号输出端,I为十进制待编码信号,Q为二进制输出。
然而,事情却并没有那么简单……
module x74x148(
input EI,
input [7:0] I,
output reg [2:0] Q,
output reg EO,
output reg GS
);
integer i;
reg [7:0] _reg;
always @ *
begin //A
Q=3'b111;
EO=1;
GS=1;
if(~EI)
begin //B
if(I==8'b11111111)
begin //C
EO=0;
end //C
else
begin //D
Q=3'b000;
_reg=I;
GS=0;
EO=~EI;
for(i=0;i<8;i=i+1)
begin:one //E
if(_reg[7]==1)
begin //F
_reg=(I<<i);
Q=Q+1'b1;
end //F
else
disable one;
end //E
end //D
end //B
end //A
endmodule
这是实现74ls148功能的另外一种编码,利用for循环语句,根据元件的逻辑功能与工作模式进行的编码。本没有编写的必要,毕竟case比for要简单,何况循环中还利用了disable命令。然而,这组代码可以让我们更好的理解74ls148的功能,因此,列举出来,以供学习(其实就是笔者没事找事…)
然而,这两组代码对应的电路图……不说了……大家自行体会吧……
(这是挨个比较对应的电路图)
(这是掰手指头算对应的电路图)
这是挨个比较的代码使用的仿真代码
module SIM;
reg EI;
reg [7:0] I;
wire GS;
wire [2:0] Q;
wire EO;
x74x148 u1(EI,I,GS,Q,EO);
initial begin
EI=1;I=8'b0;
#100;
EI=0;
I=8'b11111111;
end
always #100 I=I<<1;
x74x148 us(EI,I,GS,Q,EO);
initial begin
EI=1;I=8'b0;
#100;
EI=0;
I=8'b11111111;
end
endmodule
这是掰手指头数对应的仿真文件代码
module SIM;
reg EI;
reg [7:0] I;
wire [2:0] Q;
wire EO;
wire GS;
x74x148 u1(EI,I,Q,EO,GS);
initial begin
EI=1;I=8'b0;
#100;
EI=0;
I=8'b11111111;
end
always #100 I=I<<1;
x74x148 us(EI,I,Q,EO,GS);
initial begin
EI=1;I=8'b0;
#100;
EI=0;
I=8'b11111111;
end
endmodule
(其实也就引脚顺序编了那么一丢丢…这次真的是一丢丢…)
仿真效果
(因为只有输出顺序的区别,笔者在此只展示一个仿真波形图)
根据波形图并对照真值表,我们可以发现两组代码均可实现74ls148的功能。(级联暂不展示。可利用顶层文件进行编码),符合预期。
小结
《神探夏洛克》第四季第二集撒谎的侦探中,福尔摩斯对阵史密斯时说道:“人们总是喜欢‘3’这个数字。”所以,笔者就写了这第四篇博客[doge](夏洛克因言语过激被踢出直播间)。现在,编码器,译码器,超前进位全加器,选择器均被笔者用Verilog HDL描述了一遍,现在只剩下比较器(比如74ls85)一个人躲在墙角孤零零的看着笔者猥琐的眼神[doge],然而,我想在这里说一句,为什么我们学校的数电课本讲得那么笼统啊————前面四个我勉强还能理解,这个比较器他讲的是什么玩意……哎呦为什么我们学校连课本都欺负大一学生了啊——