MSB是符号位,0表示正数,1表示负数。
正数的反码与原码相同,负数的反码是原码除符号位的所有位取反。
正数的原码、反码、补码相同;负数的补码等于反码加1,负数的原码与补码之间的相互转化关系均为除了符号位取反再加1。
补码的好处在于加减运算不需要判断符号位。B-A=B+(-A),-A的补码是A的补码所有位取反再加1
正数原码、反码、补码相同;
负数补码为原码除符号位取反加1;
相反数数补码转换为所有位取反加1.
verilog中常量编译为二进制,均为补码(整数与原码相同,负数为除符号为取反加1)
在verilog中声明端口或者信号时,默认是无符号数,
wire [7:0] number;
reg [7:0] number;
转换为十进制为
如果需要指定为有符号数,需要特殊声明,则在硬件底层的二进制数均为补码形式
wire signed [7:0] number;
reg signed [7:0] number;
转换为十进制为
比如产生一个三角波,无符号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)这样的补码形式变化的。