verilog——74HC85四位数值比较器并扩展为16位数值比较器
- 74HC85的仿真
- 设计思路
- 代码
- 设计模块
- 测试模块
- 仿真结果
- 扩展为16位比较器
- 设计思路
- 串行代码实现
- 设计模块
- 测试模块
- 串行仿真
- 并行代码
- 设计模块
- 测试模块
- 仿真结果
- 问题总结
74HC85的仿真
设计思路
根据数据比较的原理写出真值表,如下图
代码
设计模块
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 | //filename:74HC85.V module _74HC85 ( input [2:0]I, input [3:0] A,B, output reg [2:0] L); /*参数说明: I为扩展输入端,是来自高位的比较结果,扩展输入端与其他数值比较器的输出连接,以便组成位数更多的数值比较器。 AB:为需要比较的两个四位二进制数值。 L为输出结果。L2=1时,表示a大于b;L1=1时,表示a小于b,;L0=1时,表示a等于b。 */ always@(*) begin if(I==3'b100) L=3'b100; else if(I==3'b010) L=3'b010; //扩展输入端的优先级最高,最先判断。 else begin if(A[3]>B[3]) L=3'b100; else if(A[3]<B[3]) L=3'b010; //高位优先级高,先进行判断。 else begin if(A[2]>B[2]) L=3'b100; else if(A[2]<B[2]) L=3'b010; else begin if(A[1]>B[1]) L=3'b100; else if(A[1]<B[1]) L=3'b010; else begin if(A[0]>B[0]) L=3'b100; else if(A[0]<B[0]) L=3'b010; else L=3'b001; end end end 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 25 26 27 | //filename:tb_74HC85.v `timescale 10ns/1ns module tb_74HC85(); reg [2:0]I; reg [3:0] A,B; wire [2:0] L; _74HC85 U(I,A,B,L); initial $monitor($time,"\tI=%b,A=%b,B=%b,L=%b",I,A,B,L); initial begin I=3'b100;A=4'b0000;B=4'b1111; //扩展输入端A大于b为真。 #5; I=3'b001;A=4'b0000;B=4'b1111; //扩展输入端A等于b为真。 #5; I=3'b010;A=4'b1111;B=4'b0000; //扩展输入端A小于b为真。 #5; I=3'b001;A=4'b1111;B=4'b0000; //扩展输入端A等于b为真。 #5; I=3'b001;A=4'b0100;B=4'b0010;//扩展输入端A等于b为真。 #5; I=3'b001;A=4'b0001;B=4'b0001;//扩展输入端A等于b为真。 #5; $stop; end endmodule |
仿真结果
扩展为16位比较器
设计思路
1)采用串联方式扩展数值比较器的位数。
高四位的比较结果应作为低四位的条件,即高四位比较器的输出端应分别于低四位比较器的扩展输入端连接。原理图如下,图中数值高位低位的存储地址与我设计的不同,按照我的设计,应该将图中的0-7顺序改成7-0;
2)采用并联方式扩展数值比较器的位数。
当位数较多且要满足一定的速度要求时,采用并联方式。并联方式采用两级比较方法。将16位按高低位次序分成四组,每组四位,各组的比较比较是并行进行的。将每组的比较数据再经四位比较器进行比较后得出结果。原理图如下,
串行代码实现
设计模块
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | //filename:74HC85.V module _74HC85 ( input [2:0]I, input [3:0] A,B, output reg [2:0] L); /*参数说明: I为扩展输入端,是来自高位的比较结果,扩展输入端与其他数值比较器的输出连接,以便组成位数更多的数值比较器。 AB:为需要比较的两个四位二进制数值。 L为输出结果。L2=1时,表示a大于b;L1=1时,表示a小于b,;L0=1时,表示a等于b。 */ always@(*) begin if(I==3'b100) L=3'b100; else if(I==3'b010) L=3'b010; //扩展输入端的优先级最高,最先判断。 else begin if(A[3]>B[3]) L=3'b100; else if(A[3]<B[3]) L=3'b010; //高位优先级高,先进行判断。 else begin if(A[2]>B[2]) L=3'b100; else if(A[2]<B[2]) L=3'b010; else begin if(A[1]>B[1]) L=3'b100; else if(A[1]<B[1]) L=3'b010; else begin if(A[0]>B[0]) L=3'b100; else if(A[0]<B[0]) L=3'b010; else L=3'b001; end end end end end endmodule module _16com( input [15:0] A16,B16, input [2:0] I, output [2:0] F); wire [2:0] F3,F2,F1; wire [3:0] AC3,BC3,AC2,BC2,AC1,BC1,AC0,BC0; /* 参数说明: 输入: AB为需要进行比较的两个16位二进制数; I为扩展输入端。 输出: F为输出结果。F2=1时,表示a大于b;F1=1时,表示a小于b,;F0=1时,表示a等于b。 */ /*将16位以四位一组,分到四个74HC85上*/ genvar k; // 定义循环变量。 for(k=15;k>=12;k=k-1) begin assign AC3[k-12]=A16[k]; assign BC3[k-12]=B16[k]; end for(k=11;k>=8;k=k-1) begin assign AC2[k-8]=A16[k]; assign BC2[k-8]=B16[k]; end for(k=7;k>=4;k=k-1) begin assign AC1[k-4]=A16[k]; assign BC1[k-4]=B16[k]; end for(k=3;k>=0;k=k-1) begin assign AC0[k]=A16[k]; assign BC0[k]=B16[k]; end //高位的比较结果作为低位的条件,高四位比较器的输出端应分别与低四位比较器的扩展输入端相连。 _74HC85 C3(I,AC3,BC3,F3); _74HC85 C2(F3,AC2,BC2,F2); _74HC85 C1(F2,AC1,BC1,F1); _74HC85 C0(F1,AC0,BC0,F); 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 | //filename:tb_74HC85.v `timescale 10ns/1ns module tb_16com(); reg [2:0]I; reg [15:0] A16,B16; wire [2:0] F; _16com U(A16,B16,I,F); initial $monitor($time,"\tI=%b,A=%b,B=%b,F=%b",I,A16,B16,F); initial begin I=3'b001;A16=16'b1111_1111_1111_1111;B16=16'b1111_1111_1111_1110; //扩展输入端中A等于b为真,A大于b的情况。 #5; I=3'b001;A16=16'b0111_1111_1111_1111;B16=16'b1111_1111_1111_1111;//扩展输入端中A等于b为真,A小于b的情况。 #5; I=3'b001;A16=16'b1111_1111_1111_1111;B16=16'b1111_1111_1111_1111;//扩展输入端中A等于b为真,A等于B的情况。 #5; I=3'b100;A16=16'b0111_1111_1111_1111;B16=16'b1111_1111_1111_1111;//扩展输入端中A大于b为真的情况。 #5; I=3'b010;A16=16'b1111_1111_1111_1111;B16=16'b0111_1111_1111_1111;//扩展输入端中A小于b为真的情况。 #5; $stop; 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 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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | //filename:74HC85.V module _74HC85 ( input [2:0]I, input [3:0] A,B, output reg [2:0] L); always@(*) begin if(I==3'b100) L=3'b100; else if(I==3'b010) L=3'b010; else begin if(A[3]>B[3]) L=3'b100; else if(A[3]<B[3]) L=3'b010; else begin if(A[2]>B[2]) L=3'b100; else if(A[2]<B[2]) L=3'b010; else begin if(A[1]>B[1]) L=3'b100; else if(A[1]<B[1]) L=3'b010; else begin if(A[0]>B[0]) L=3'b100; else if(A[0]<B[0]) L=3'b010; else L=3'b001; end end end end end endmodule module _16com( input [15:0] A16,B16, input [2:0] I, output [2:0] F); wire [2:0] F3,F2,F1,F0; wire [3:0] AC3,BC3,AC2,BC2,AC1,BC1,AC0,BC0,AC,BC; /* 参数说明: 输入: AB为需要进行比较的两个16位二进制数; I为扩展输入端。 输出: F为输出结果。F2=1时,表示a大于b;F1=1时,表示a小于b,;F0=1时,表示a等于b。 */ /*将16位以四位一组,分到四个74HC85上*/ genvar k; for(k=15;k>=12;k=k-1) begin assign AC3[k-12]=A16[k]; assign BC3[k-12]=B16[k]; end for(k=11;k>=8;k=k-1) begin assign AC2[k-8]=A16[k]; assign BC2[k-8]=B16[k]; end for(k=7;k>=4;k=k-1) begin assign AC1[k-4]=A16[k]; assign BC1[k-4]=B16[k]; end for(k=3;k>=0;k=k-1) begin assign AC0[k]=A16[k]; assign BC0[k]=B16[k]; end //将16位按高低为次序分成四组,每组四位各组的比较是并行进行的。 _74HC85 C3(3'b001,AC3,BC3,F3); _74HC85 C2(3'b001,AC2,BC2,F2); _74HC85 C1(3'b001,AC1,BC1,F1); _74HC85 C0(3'b001,AC0,BC0,F0); //将每组的比较结果在经四位比较器进行比较后得出结果。 assign AC[3]=F3[2]; assign AC[2]=F2[2]; assign AC[1]=F1[2]; assign AC[0]=F0[2]; assign BC[3]=F3[1]; assign BC[2]=F2[1]; assign BC[1]=F1[1]; assign BC[0]=F0[1]; _74HC85 C4(I,AC,BC,F); endmodule |
测试模块
同串行
仿真结果
经验证,同前。
问题总结
1.16位比较器编写过程中出现了参数不对照的问题,后来发现是实参的位置错了,导致与形参不匹配。下次一定要注意,形参和实参的匹配。
2.在实际单片机,CPU的IO口等实际应用中,数学上的高位通常分配到低位地址,所以数学上的1000,对应计算机上的数组为A= {0,0,0,1},A【0】=1,表示数值最高位上的1存放在低位地址中(A[0])。因此我本次设计的16位比较器虽然能够实现功能,但是应用性 低。
3.书上两种四片16位比较器的扩展输入端直接取3‘b001,不能进一步级联构成更多位比较器,再此做出改进。