Verilog基础知识(数值表示总结,signed,原码,反码,补码)

定点数

原码表示

MSB是符号位,0表示正数,1表示负数。

D = ( 1 ) a B 1 i = 0 B 2 a i 2 i B + 1

比如,二进制 0.110 = ( 1 ) 0 ( 1 2 1 + 1 2 2 ) = + 0.75 1.110 = ( 1 ) 1 ( 1 2 1 + 1 2 2 ) = 0.75

反码表示(1’s complement)

正数的反码与原码相同,负数的反码是原码除符号位的所有位取反。

补码表示(2’s complement)

正数的原码、反码、补码相同;负数的补码等于反码加1,负数的原码与补码之间的相互转化关系均为除了符号位取反再加1。

补码的好处在于加减运算不需要判断符号位。B-A=B+(-A),-A的补码是A的补码所有位取反再加1

三种数制之间转换关系

正数原码、反码、补码相同;
负数补码为原码除符号位取反加1;
相反数数补码转换为所有位取反加1.

verilog中的常量类型



verilog中常量编译为二进制,均为补码(整数与原码相同,负数为除符号为取反加1)

在verilog中声明端口或者信号时,默认是无符号数,

wire [7:0] number;
reg [7:0] number;

转换为十进制为

D = i = 0 B 1 a i 2 i

如果需要指定为有符号数,需要特殊声明,则在硬件底层的二进制数均为补码形式

wire signed [7:0] number;
reg signed [7:0] number;

转换为十进制为

D = i = 0 B 1 a i 2 i 2 B × a B 1

在verilog2001中可以特别地用’s来声明符号数,比如-4表示成一个3bit十六进制数位-3’sh4。
十进制的数永远都是有符号数.

举个例子

比如产生一个三角波,无符号8bit能产生0-255之间的数

module counter(
    clk,
    rst,

    out,
    );

input clk;    //clk
input rst;    //reset, high active

output reg [7:0] out;

reg [7:0] cnt;
reg state;

always @(posedge clk or posedge rst) begin
    if (rst) begin
        cnt <= 0;
        state <= 1'b0;
    end
    else begin
        case(state)
            1'b0: begin
                if(cnt==255) begin
                    cnt <= cnt;
                    state <= 1'b1;
                end
                else begin
                    cnt <= cnt+1;
                    state <= 1'b0;
                end
            end
            1'b1: begin
                 if(cnt==0) begin
                    cnt <= cnt;
                    state <= 1'b0;
                end
                else begin
                    cnt <= cnt-1;
                    state <= 1'b1;
                end
            end
        endcase
    end
end

always @(posedge clk or posedge rst) begin
    if (rst) begin
        out <= 0;    // reset
    end
    else
        out <= cnt;
end

endmodule


可以看到输出信号out[7:0]是从8‘b0000_0000(8’d0)到8’b1111_1111(8’d255)

而对于一个有符号的8bit三角波发生器

module signed_counter(
    clk,
    rst,

    out,
    );

input clk;    //clk
input rst;    //reset, high active

output reg signed [7:0] out;

reg signed [7:0] cnt;
reg state;

always @(posedge clk or posedge rst) begin
    if (rst) begin
        cnt <= -128;
        state <= 1'b0;
    end
    else begin
        case(state)
            1'b0: begin
                if(cnt==127) begin
                    cnt <= cnt;
                    state <= 1'b1;
                end
                else begin
                    cnt <= cnt+1;
                    state <= 1'b0;
                end
            end
            1'b1: begin
                 if(cnt==-128) begin
                    cnt <= cnt;
                    state <= 1'b0;
                end
                else begin
                    cnt <= cnt-1;
                    state <= 1'b1;
                end
            end
        endcase
    end
end

always @(posedge clk or posedge rst) begin
    if (rst) begin
        out <= -128;    // reset
    end
    else
        out <= cnt;
end

endmodule


可以看到输出是从8’b1000_0001(-8d’127)到8’b0000_0000(8d’127)这样的补码形式变化的。

猜你喜欢

转载自blog.csdn.net/maxwell2ic/article/details/80596210