CD4532 8-3线优先编码器以及应用


CD4532 8-3线优先编码器以及应用

目标

  1. 一片CD4532构成8-3线编码器
  2. 两片CD4532串行构成16-4线译码器

一.一片CD45232

设计思路

采用逻辑电路的行为级建模,参考CD4532的功能表,运用always,casex,else if语句实现CD4532的功能。
CD4532功能表

代码实现

设计模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//filename:CD4532.v
module CD4532(EI,I,Y,GS,EO);
input EI;
input [7:0] I;
output reg [2:0] Y;
output reg GS,EO;

always @(*) begin
if(EI==0)begin
    Y[2:0]=3'b000;
    GS=0;
    EO=0;
    end
else begin
    GS=1;
    EO=0;
casex(I[7:0])       //含有无关项的casex选择
    8'b1xxxxxxx:Y[2:0]=3'b111;
    8'b01xxxxxx:Y[2:0]=3'b110;
    8'b001xxxxx:Y[2:0]=3'b101;
    8'b0001xxxx:Y[2:0]=3'b100;
    8'b00001xxx:Y[2:0]=3'b011;
    8'b000001xx:Y[2:0]=3'b010;
    8'b0000001x:Y[2:0]=3'b001;
    8'b00000001:Y[2:0]=3'b000;
    default begin
    GS=0;
    EO=1;
    Y[2:0]=3'b000;
    end
endcase
end
end
endmodule

测试模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//filename test_CD4532.v
`timescale 10ns/1ns
module test_CD4532;
reg [7:0] I;
reg EI;
wire [2:0]Y;
wire GS,EO;

CD4532 U0(EI,I,Y,GS,EO);
initial
    $monitor($time,":\tI=%b,EI=%b,EO=%b,GS=%b,Y=%b\n",I,EI,EO,GS,Y);   //监视器的显示
initial begin
EI = 0; I=8'b1111_1111;        //生成输入信号的数据
#1
EI = 0; I=8'b0111_1111;
#1
EI = 1; I=8'b1111_1111;
#1
EI = 1; I=8'b0111_1111;
#1
EI = 1; I=8'b0001_1111;
$stop;            //暂停模拟仿真
end
endmodule

仿真

逻辑仿真

二.两片CD4532构成16-4线编码器

设计思路

分析
逻辑图原理

代码实现

采用自顶向下的方式,综合行为级建模,门级描述数据流建模编写verilog程序。

设计模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//filename:_2CD4532.v
module CD4532(EI,I,Y,GS,EO);
input EI;
input [7:0] I;
output reg [2:0] Y;
output reg GS,EO;

always @(*) begin
if(EI==0)begin
    Y[2:0]=3'b000;
    GS=0;
    EO=0;
    end
else begin
    GS=1;
    EO=0;
casex(I[7:0])
        8'b1xxxxxxx:Y[2:0]=3'b111;
    8'b01xxxxxx:Y[2:0]=3'b110;
    8'b001xxxxx:Y[2:0]=3'b101;
    8'b0001xxxx:Y[2:0]=3'b100;
    8'b00001xxx:Y[2:0]=3'b011;
    8'b000001xx:Y[2:0]=3'b010;
    8'b0000001x:Y[2:0]=3'b001;
    8'b00000001:Y[2:0]=3'b000;
    default begin
    GS=0;
    EO=1;
    Y[2:0]=3'b000;
    end
endcase
end
end
endmodule


module _2CD4532(EI,IN,L,GS,EO);
input EI;
input [15:0] IN;
output  [3:0] L;
output  GS,EO;
wire EO1,GS1,GS0;
wire [2:0] Y1,Y0;
wire [7:0] I1;
wire [7:0] I0;        
genvar k;    //循环变量k
for(k=7;k>=0;k=k-1)  assign I0[k]=IN[k];      
for(k=15;k>=8;k=k-1)  assign I1[k-8]=IN[k];
CD4532 U1(EI,I1,Y1,GS1,EO1);
CD4532 U2(EO1,I0,Y0,GS0,EO);
assign L[3]=GS1;
or G3(GS,GS1,GS0);
or G2(L[2],Y1[2],Y0[2]);
or G1(L[1],Y1[1],Y0[1]);
or G0(L[0],Y1[0],Y0[0]);
endmodule

测试模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//filename:test_2CD4532
`timescale 10ns/1ns
module test_2CD4532();
reg EI;
reg [15:0] IN;
wire [3:0] L;
wire GS;
wire EO;

_2CD4532 U0(EI,IN,L,GS,EO);
initial
    $monitor($time,":\tEI=%b,I=%b,L=%b,GS=%b,EO=%b\n",EI,IN,L,GS,EO);
initial begin
    EI=0;IN=16'b1000_0000_0000_0000;
    #5
    EI=1;IN=16'b1000_0000_0000_0000;
    #5 
    EI=1;IN=16'b0001_0000_0000_0000;
    #5
    EI=1;IN=16'b0000_0000_0001_0000;
    #5
    EI=1;IN=16'b0000_0000_0000_0000;
    #5
    $stop;
end
endmodule

仿真结果

1
monitor检测

问题与总结

1.循环语句定义循环变量时刚开始使用的是integer,出现错误,查询后发现循坏变量需要定义为genvar型。其次是在verilog中不能使用k++,k–,只能写k=k加减1表达式。
2.采用数据流描述方式时,注意连续赋值语句需要加上assign
3.变量类型需求:
1)always@程序块中赋值语句左边必须为reg型变量
2)测试平台搭建中,输入必须为reg型,输出必须为wire型。