FPGA系统性学习笔记连载_Day7【16位比较器设计】 【原理及verilog实现、仿真】篇
本系列为FPGA系统性学习学员学习笔记整理分享,如有学习或者购买开发板意向,可加交流群联系群主。
连载《叁芯智能fpga设计与研发-第7天》【16位比较器设计】 【原理及verilog实现、仿真】
原创作者:紫枫术河 转载请联系群主授权,否则追究责任
本篇文章,介绍16位比较器的实现原理及verilog实现及仿真
一、比较器原理
当A、B两个数比较大小时,我们都很熟悉是先比较高位,再比较低位;
在比较任何一位时,如果当前位能决定A、B的大小时就退出比较,直接给出结果。
二、16位比较器的过程
从比较结果看,有3种结果:大于、等于、小于
如果比较 A[14] 和 B[14]时,我们首先要看 A[15]和B[15]的大小关系 ;
1、A[15] > B[15],直接返回结果,整个数A > B ,退出比较;
2、A[15] = B[15],根据A[14]和B[14]的结果判断,以此向下逐次比较,直到A[0] B[0]比较完成;
3、A[15] < B[15],直接返回结果,整个数A < B ,退出比较;
从上面的比较过程,我们可以发现,当比较某一位时,会有3个输入状态表示上一位的大小,
当前位也有3个状态表示当前位的大小,输出就是根据这6个状态的组合,给出最终数据的大小。
三、我们先画一个3位比较器的电路图
从这个电路图可以看出来,我们为了重复的使用同一个电路,必须要在最高位,给大于、小于端口接地
给等于端口接VCC,因为比较BIT[3]需要看 BIT[4]的大小情况,但是我们没有BIT[4],那就必须给一个等于信号,
告诉电路BIT[4]是相等的,你继续比较本位的值吧。
四、16位比较器的verilog代码实现
我分成5个模块 cmp16.v、cmp8.v、cmp4.v、cmp2.v、cmp1.v
五、cmp16.v
代码语言:javascript复制module cmp16(
input wire [15:0] a,
input wire [15:0] b,
input wire fi_big,
input wire fi_equal,
input wire fi_small,
output wire fo_big,
output wire fo_equal,
output wire fo_small
);
wire fo_big_temp;
wire fo_equal_temp;
wire fo_small_temp;
cmp8 cmp8_inst1(
.a (a[15:8]),
.b (b[15:8]),
.fi_big (fi_big),
.fi_equal (fi_equal),
.fi_small (fi_small),
.fo_big (fo_big_temp),
.fo_equal (fo_equal_temp),
.fo_small (fo_small_temp)
);
cmp8 cmp8_inst2(
.a (a[7:0]),
.b (b[7:0]),
.fi_big (fo_big_temp),
.fi_equal (fo_equal_temp),
.fi_small (fo_small_temp),
.fo_big (fo_big),
.fo_equal (fo_equal),
.fo_small (fo_small)
);
endmodule
六、cmp8.v
代码语言:javascript复制module cmp8(
input wire [7:0] a,
input wire [7:0] b,
input wire fi_big,
input wire fi_equal,
input wire fi_small,
output wire fo_big,
output wire fo_equal,
output wire fo_small
);
wire fo_big_temp;
wire fo_equal_temp;
wire fo_small_temp;
cmp4 cmp4_inst1(
.a (a[7:4]),
.b (b[7:4]),
.fi_big (fi_big),
.fi_equal (fi_equal),
.fi_small (fi_small),
.fo_big (fo_big_temp),
.fo_equal (fo_equal_temp),
.fo_small (fo_small_temp)
);
cmp4 cmp4_inst2(
.a (a[3:0]),
.b (b[3:0]),
.fi_big (fo_big_temp),
.fi_equal (fo_equal_temp),
.fi_small (fo_small_temp),
.fo_big (fo_big),
.fo_equal (fo_equal),
.fo_small (fo_small)
);
endmodule
七、cmp4.v
代码语言:javascript复制module cmp4(
input wire [3:0] a,
input wire [3:0] b,
input wire fi_big,
input wire fi_equal,
input wire fi_small,
output wire fo_big,
output wire fo_equal,
output wire fo_small
);
wire fo_big_temp;
wire fo_equal_temp;
wire fo_small_temp;
cmp2 cmp2_inst1(
.a (a[3:2]),
.b (b[3:2]),
.fi_big (fi_big),
.fi_equal (fi_equal),
.fi_small (fi_small),
.fo_big (fo_big_temp),
.fo_equal (fo_equal_temp),
.fo_small (fo_small_temp)
);
cmp2 cmp2_inst2(
.a (a[1:0]),
.b (b[1:0]),
.fi_big (fo_big_temp),
.fi_equal (fo_equal_temp),
.fi_small (fo_small_temp),
.fo_big (fo_big),
.fo_equal (fo_equal),
.fo_small (fo_small)
);
endmodule
八、cmp2.v
代码语言:javascript复制module cmp2(
input wire [1:0] a,
input wire [1:0] b,
input wire fi_big,
input wire fi_equal,
input wire fi_small,
output wire fo_big,
output wire fo_equal,
output wire fo_small
);
wire fo_big_temp;
wire fo_equal_temp;
wire fo_small_temp;
cmp1 cmp1_inst1(
.a (a[1]),
.b (b[1]),
.fi_big (fi_big),
.fi_equal (fi_equal),
.fi_small (fi_small),
.fo_big (fo_big_temp),
.fo_equal (fo_equal_temp),
.fo_small (fo_small_temp)
);
cmp1 cmp1_inst2(
.a (a[0]),
.b (b[0]),
.fi_big (fo_big_temp),
.fi_equal (fo_equal_temp),
.fi_small (fo_small_temp),
.fo_big (fo_big),
.fo_equal (fo_equal),
.fo_small (fo_small)
);
endmodule
九、cmp1.v
代码语言:javascript复制module cmp1(
input wire a,
input wire b,
input wire fi_big,
input wire fi_equal,
input wire fi_small,
output reg fo_big,
output reg fo_equal,
output reg fo_small
);
always@(*) begin
if(fi_big == 1'b1)begin
fo_big = 1'b1;
fo_equal = 1'b0;
fo_small = 1'b0;
end
else if(fi_equal == 1'b1)begin
fo_big = a&~b | fi_big;
fo_equal = (~a&~b) | (a&b);
fo_small = ~a&b;
end
else if(fi_small == 1'b1)begin
fo_big = 1'b0;
fo_equal = 1'b0;
fo_small = 1'b1;
end
else
begin
fo_big = 1'b0;
fo_equal = 1'b1;
fo_small = 1'b0;
end
end
endmodule
十、仿真脚本cmp16_tb.v
代码语言:javascript复制`timescale 1ns/1ps
module cmp16_tb();
reg [15:0] a;
reg [15:0] b;
reg fi_big;
reg fi_equal;
reg fi_small;
wire fo_big;
wire fo_equal;
wire fo_small;
initial begin
a=6512; //先制造2个相等的情况
b=6512; //先制造2个相等的情况
fi_big = 1'b0; //必须接地,因为高位不存在
fi_equal = 1'b1; //必须接VCC,因为高位不存在,需要保持相等
fi_small = 1'b0; //必须接地,因为高位不存在
#20;
repeat(100)begin
a={$random}e536;
b={$random}e536;
fi_big = 1'b0;
fi_equal = 1'b1;
fi_small = 1'b0;
#20;
end
end
cmp16 cmp16_inst(
.a (a),
.b (b),
.fi_big (fi_big),
.fi_equal (fi_equal),
.fi_small (fi_small),
.fo_big (fo_big),
.fo_equal (fo_equal),
.fo_small (fo_small)
);
endmodule
十一、仿真结果
从仿真结果,知道代码实现正确。