CD4532 8-3线优先编码器以及应用
目标
- 一片CD4532构成8-3线编码器
- 两片CD4532串行构成16-4线译码器
一.一片CD45232
设计思路
采用逻辑电路的行为级建模,参考CD4532的功能表,运用always,casex,else if语句实现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.循环语句定义循环变量时刚开始使用的是integer,出现错误,查询后发现循坏变量需要定义为genvar型。其次是在verilog中不能使用k++,k–,只能写k=k加减1表达式。
2.采用数据流描述方式时,注意连续赋值语句需要加上assign。
3.变量类型需求:
1)always@程序块中赋值语句左边必须为reg型变量
2)测试平台搭建中,输入必须为reg型,输出必须为wire型。