verilog之组合逻辑电路(附代码)
前⾔
刚学前端设计的时候,听到的就是组合逻辑、时序逻辑,很重要!但是究竟有什么⽤?到底怎么体现,没有多少⽼师可以明确指出来,当⾃⼰看的东西多了,就可以理解了,甚⾄可以得出⾃⼰的范式。
到⽬前为⽌,要想掌握组合逻辑,就请先掌握本⽂列出的编码器、译码器、数据选择器、加法器等简单的组合逻辑电路。
1.编码器和译码器
刚开始听verilog的时候,估计都听过3-8译码器,但是听过编码器吗?
编码器和译码器可以将不同输⼊数据变换为不同的输出数据。
编码器的数据输⼊⽐编码后的输出位数⼤,编码器常⽤来减少数据通道数⽬;⽽译码器与之相反。
1.1 编码器
编码器把输⼊信号编写成⼀个对应的⼆进制信号,即把2^N个输⼊信号转化为N位编码输出。还可以分为:
普通编码器和优先编码器。
普通编码器:只能⼀个⼀个的输⼊,如果同时输⼊两个信号,编码器不能识别;
优先编码器:如果输⼊两个信号,对⾼位优先识别。(联想if-else的优先级)
1.1.1 8-3普通编码器
8-3普通编码器功能真值表
设计代码code8_3.v
module code8_3(
I,
O
);
input  [7:0] I;
output  [2:0] O;
reg  [2:0] O;
always@(I)
begin
case(I)
8'b0000_0001:O = 3'b111;
8'b0000_0010:O = 3'b110;
8'b0000_0100:O = 3'b101;
8'b0000_1000:O = 3'b100;
8'b0001_0000:O = 3'b011;
8'b0010_0000:O = 3'b010;
8'b0100_0000:O = 3'b001;
8'b1000_0000:O = 3'b000;
default: O=3'bxxx;
endcase
end
endmodule
仿真⽂件code8_3_tb.v
`timescale 1ns/1ns
`define clk_period 20
module code8_3_tb;
reg  [7:0] I;
wire  [2:0] O;
reg clk;
code8_3 code8_3_inst(
.I(I),
.O(O)
);
initial clk =1'b1;
always #`clk_period clk =~clk;
initial begin
I =8'b0000_0001;
#`clk_period;
I =8'b0000_0010;
#`clk_period;
I =8'b0000_0100;
#`clk_period;
I =8'b0000_1000;
#`clk_period;
I =8'b0001_0000;
#`clk_period;
I =8'b0010_0000;
#`clk_period ;
I =8'b0100_0000;
#`clk_period;
I =8'b1000_0000;
#`clk_period;
I =8'b0000_0000;
#`clk_period;
$stop;
end
endmodule
功能仿真
1.1.1 8-3优先编码器
详细介绍见:
8-3优先编码器功能真值表
上⾯这个真值表有问题,在⽹上到了下⾯这⼀个。
8-3优先编码器的逻辑符号
设计代码code_8_3.v
module code_8_3(
EI_n,
I,
Y,
GS_n,
EO_n
);
input    EI_n;
input  [7:0] I;
output  [2:0] Y;
output    GS_n;
output    EO_n;
reg  [2:0] Y;
reg    GS_n;
reg    EO_n;
always@(EI_n or I)
begin
if(!EI_n)begin
if(~I[7])  begin Y =3'd0;EO_n =1;GS_n =0;end else if(~I[6])  begin Y =3'd1;EO_n =1;GS_n =0;end else if(~I[5])  begin Y =3'd2;EO_n =1;GS_n =0;end else if(~I[4])  begin Y =3'd3;EO_n =1;GS_n =0;end else if(~I[3])  begin Y =3'd4;EO_n =1;GS_n =0;end else if(~I[2])  begin Y =3'd5;EO_n =1;GS_n =0;end else if(~I[1])  begin Y =3'd6;EO_n =1;GS_n =0;end else if(~I[0])  begin Y =3'd7;EO_n =1;GS_n =0;end else    begin Y =3'd7;EO_n =0;GS_n =1;end
end
else      begin Y =3'd7;EO_n =1;GS_n =1;end
end
endmodule
仿真⽂件code_8_3_tb.v
`timescale 1ns/1ns
`define clk_period 20
module code_8_3_tb;
reg    EI_n;
reg  [7:0] I;
wire  [2:0] Y;
wire    GS_n;
wire    EO_n;
reg    clk;
code_8_3 code_8_3_inst(
.EI_n(EI_n),
.I(I),
.Y(Y),
.GS_n(GS_n),
.EO_n(EO_n)
);
initial clk =1'b1;
always #`clk_period clk =~clk;
initial begin
EI_n =1'b1;
I =8'b1101_1111;
#`clk_period;
EI_n =1'b0;
I =8'b1111_1110;
#`clk_period;
I =8'b0111_1101;
#`clk_period;
I =8'b1010_1010;
#`clk_period;
I =8'b1100_1111;
#`clk_period;
I =8'b1111_1111;
#`clk_period ;
I =8'b1110_0100;
#`clk_period;
I =8'b1111_1111;
#`clk_period;
I =8'b1110_0100;
#`clk_period;
I =8'b1110_0110;
#`clk_period;
I =8'b1111_1010;
#`clk_period;
I =8'b1111_1100;
#`clk_period;
$stop;
end
endmodule
功能仿真
1.2 译码器
从电路功能上看,译码器和编码器没有实质的差别。
编码器把输⼊信号编写成⼀个对应的⼆进制信号,即把2^N个输⼊信号转化为N位编码输出。⽽译码器是把输⼊的N位⼆进制信号转换成2^N个代表代码原意的状态信号并输出。
1.2.1 3-8译码器74LS138逻辑符号
3-8译码器74LS138的功能真值表
设计代码decoder3_8
module decoder3_8(
Y,
S,
A
);
output  [7:0] Y;
input  [2:0] S;
input  [2:0] A;
reg  [7:0] Y;
always@(*)
begin
if(S[0]&(S[1]==0)&(S[2]==0))begin
case(A)
3'b000:Y = 8'b1111_1110;
3'b001:Y = 8'b1111_1101;
decoder3'b010:Y = 8'b1111_1011;
3'b011:Y = 8'b1111_0111;
3'b100:Y = 8'b1110_1111;
3'b101:Y = 8'b1101_1111;
3'b110:Y = 8'b1011_1111;
3'b111:Y = 8'b0111_1111;
default Y=8'bX;
endcase
end
else Y =8'b1111_1111;
end
endmodule
仿真⽂件decoder3_8_tb.v

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。