本文参考https://blog.csdn.net/wenxinwukui234/article/details/42119265/ 关于2进制补码的思考和讨论。

======================================================================================================

即使在变量声明的时候定义了signed属性, 在Verilog中使用>(大于),>=(大于等于),<(小于)和<=(小于等于)进行有符号数的大小比较时还是没有想要的结果。

现在需要实现一个有符号数比较的功能。

1、一些注记。

以8位有符号数(signed int)为例,表示范围是-128~+127,有一些边缘的数很有特征,记下来方便使用:

0000_0000 表示 0;

0000_0001 表示 +1;

1111_1111 表示 -1;

0111_1111 表示 +127;

1000_0001 表示 -127;

1000_0000 表示 -128.

我们发现,(1)除了0和-128,其他相反数按无符号相加,得到的是0000_0000(即0000_0000)。

(2)非负数的MSB(最高位)=0;负数的MSB=1。

2、比较规则。

我们设a和b为输入的两个signed 8类型的比较数,并且a>=b(GE)时输出信号y为1,否则输出为0。比较的规则如下:

(1)非负数一定大于负数。

(2)负数一定小于非负数。

(3)a、b同是非负数,则按unsigned比较两个数:a>=b则y=1;a<b则y=0。

(4)a、b同是负数,则按unsigned比较a和b的[6:0]即除去符号位:a[6:0]>=b[6:0]则y=1;a[6:0]<b[6:0]则y=0。

3、Verilog模块。

//************************************
//        A >= B -> 1
//        A <  B -> 0
//
//************************************
module ageb_s8(
    rst_n,
    sys_sam_clk,
    a,
    b,
    cmp_out

    );

    //****************************************
    //            Port Def.
    //
    //****************************************
    input wire rst_n;
    input wire sys_sam_clk;

    input wire[7:0] a;
    input wire[7:0] b;

    output wire cmp_out;

    //****************************************
    //            Define
    //
    //****************************************
    localparam YES = 1'b1;
    localparam NO = 1'b0;

    //****************************************
    //            Variables
    //
    //****************************************
    reg cmp_reg;

    //****************************************
    //            Behaviour
    //
    //****************************************
    assign cmp_out = cmp_reg;

    //***    Compare Logic
    always@(posedge sys_sam_clk)begin
        if(!rst_n)begin
            cmp_reg <= 1'b0;
        end
        else begin
            case({a[7], b[7]})
                2'b01:begin // a+, b-
                    cmp_reg <= 1'b1;
                end
                2'b10:begin // a-, b+
                    cmp_reg <= 1'b0;
                end
                2'b00:begin // a+, b+, Compare Amplitude
                    if(a[6:0] >= b[6:0])begin // Unsigned Compare
                        cmp_reg <= 1'b1;
                    end
                    else begin
                        cmp_reg <= 1'b0;
                    end
                end
                2'b11:begin // a-, b-, Compare [6:0]
                    if(a[6:0] >= b[6:0])begin
                        cmp_reg <= 1'b1;
                    end
                    else begin
                        cmp_reg <= 1'b0;
                    end
                end
                default:begin
                    cmp_reg <= 1'b0;
                end
            endcase
        end
    end

endmodule

4、仿真

仿真结果满足我的需要。

01-10 05:47