译码器
首先从大家最熟悉的38译码器开始讲解,38译码器是指将3位2进制数(ABC)通过电路转换成八路不同状态的输出(Y0-Y7),真值表入下图:
框图如下:
在clk到来时,译码器每输入一个3位2进制的变量a,译码器encode会输出一个8位2进制的b,a和b对应38译码器真值表
译码器输入输出说明:
方向 |
位宽 |
类型 |
说明 |
|
clk |
I |
1 |
wire |
时钟信号,高电平有效 |
reset |
I |
1 |
wire |
复位信号,高电平复位 |
a |
I |
3 |
wire |
输入信号 |
b |
O |
8 |
reg |
输出信号 |
代码如下:
module encode(
input clk ,
input reset,
input [2:0] a,
output reg [7:0] b
);
always@(posedge clk)begin
if(reset)begin
b<=8'd0;
end
else begin
case(a)
3'd0:begin
b<=8'b0000_0001;//注意真值表为非
end
3'd1:begin
b<=8'b0000_0010;
end
3'd2:begin
b<=8'b0000_0100;
end
3'd3:begin
b<=8'b0000_1000;
end
3'd4:begin
b<=8'b0001_0000;
end
3'd5:begin
b<=8'b0010_0000;
end
3'd6:begin
b<=8'b0100_0000;
end
3'd7:begin
b<=8'b1000_0000;
end
endcase
end
end
endmodule
下面进行仿真:
module TB_encode(
);
reg clk ;
reg reset;
reg [2:0]a =0 ;
wire [7:0]b ;
encode inst_encode(
.clk (clk) ,
.reset (reset) ,
.a (a) ,
.b (b)
);
initial begin
clk=0;
reset=1;
#20;
reset=0;
end
always #20 clk=~clk;
always@(posedge clk)begin
if(reset)begin
a<=3'd0;
end
else begin
if(a==3'd7)begin
a<=3'd0;
end
else begin
a<=a+1;
end
end
end
endmodule
仿真结果正确:
解码器
依然先举例最熟悉的83解码器,83解码器是将8输入的二进制变量,得到3输出变量,与38编码器正好相反,框图如下:
在clk到来时,译码器每输入一个8位2进制的b,译码器encode会输出一个3位2进制的c,c和b对应83解码器真值表
输入输出说明:
名称 |
方向 |
位宽 |
类型 |
说明 |
clk |
I |
1 |
wire |
时钟信号,高电平有效 |
reset |
I |
1 |
wire |
复位信号,高电平复位 |
a |
I |
8 |
wire |
输入信号 |
c |
O |
3 |
reg |
输出信号 |
module decode(
input clk,
input reset,
input [7:0] b,
output [3:0] c
);
always@(posedge clk)begin
if(reset)begin
c<=3'd0;
end
else begin
case(b)
8'b1111_1110:begin
c<=3'd0;
end
8'b1111_1101:begin
c<=3'd1;
end
8'b1111_1011:begin
c<=3'd2;
end
8'b1111_0111:begin
c<=3'd3;
end
8'b1110_1111:begin
c<=3'd4;
end
8'b1101_1111:begin
c<=3'd5;
end
8'b1011_1111:begin
c<=3'd6;
end
8'b0111_1111:begin
c<=3'd7;
end
endcase
end
end
endmodule
显而易见,就是38译码器的反过程,写一个仿真文件进行仿真,代码如下:
module TB_decode(
);
reg clk ;
reg reset ;
reg [7:0]b=8'b0000_0001 ;
wire [3:0]c;
decode inst_decode(
.clk (clk),
.reset (reset),
.b (b),
.c (c)
);
initial begin
clk=0;
reset=1;
#20
reset=0;
b<=8'b0000_0001;
end
always #20 clk=~clk;
always@(posedge clk)begin
if(reset)begin
b<=8'b0000_0001;
end
else begin
if(b==8'b1000_0000)begin
b<=8'b0000_0001;
end
else begin
b<=b<<1;//1左移
end
end
end
endmodule
仿真结果正确:
译码器-解码器联合
把a输入编码器,将译码器输出的b,输入编码器b,最后输出c。系统框图如下:
将系统输入的50MHZ的clk输给PLL,输出25MHZ的clk
PLL的locked信号与encode和decode的reset相连接
输入[2:0]a给encode输出[7:0]的b,把输出[7:0]的b输入decode(用b_wire连接),输出[2:0]c
系统需将clk_25m输出,用于系统a的输入
关于PLL配置的大家可以看这篇 使用锁相环输出时钟信号_居安士的博客-CSDN博客_锁相环时钟
输入输出说明:
名称 |
方向 |
位宽 |
类型 |
Clk_50m |
In |
1 |
Wire |
a |
In |
3 |
Wire |
Clk_25m |
Out |
1 |
Wire |
c |
out |
3 |
reg |
最后结果如上图,a等于c,b是8位
完整代码放这里: