概述
verilog——74HC85四位数值比较器并扩展为16位数值比较器
- 74HC85的仿真
- 设计思路
- 代码
- 设计模块
- 测试模块
- 仿真结果
- 扩展为16位比较器
- 设计思路
- 串行代码实现
- 设计模块
- 测试模块
- 串行仿真
- 并行代码
- 设计模块
- 测试模块
- 仿真结果
- 问题总结
74HC85的仿真
设计思路
根据数据比较的原理写出真值表,如下图
代码
设计模块
//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
测试模块
//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位按高低位次序分成四组,每组四位,各组的比较比较是并行进行的。将每组的比较数据再经四位比较器进行比较后得出结果。原理图如下,
串行代码实现
设计模块
//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
测试模块
//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
串行仿真
并行代码
设计模块
//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,不能进一步级联构成更多位比较器,再此做出改进。
最后
以上就是妩媚月饼为你收集整理的verilog——74HC85四位数值比较器并扩展为16位数值比较器的全部内容,希望文章能够帮你解决verilog——74HC85四位数值比较器并扩展为16位数值比较器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复