FPGA系统性学习笔记连载_Day7【16位比较器设计】 【原理及verilog实现、仿真】篇

2021-04-01 17:59:52 浏览数 (1)

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

十一、仿真结果

从仿真结果,知道代码实现正确。

0 人点赞