一、补码转换
所需软件
Verilog编程软件:Lattice Diamond(3.11.0.396.4_Diamond_x64)
Verilog仿真软件:ModelSim SE-64 10.2c(modelsim-win64-10.2c-se)
方法:用问号冒号语句和位拼接实现补码转换逻辑
符号图:
Verilog代码:
Part1:Test6_comp_conv.v文件(Verilog工程文件)
//2022-05-26
//补码转换逻辑-Test6_comp_conv
module Test6_comp_conv(
a,
a_comp
);
input[7:0] a; //原码:8位的输入。注:若原码的最高位为1,则原码是负数;若原码的最高位为0,则原码是正数。
output[7:0] a_comp; //8位的输出
//wire[6:0] b; //方法一:按位取反的幅度位
//wire[7:0] y; //方法一、方法二、方法三:负数的补码
//assign b=~a[6:0]; //方法一:对8位的输入a的低7位进行按位取反,得到中间变量b
//assign y[6:0]=b+1; //方法一:对中间变量b+1
//assign y[6:0]=~a[6:0]+1; //方法二:对中间变量b+1
//assign y[7]=a[7]; //方法一、方法二:符号位不变
//assign y={a[7],~a[6:0]+1}; //方法三:位拼接:用大括号把不同的位拼接起来。
//assign a_comp=a[7]?y[7:0]:a[7:0] //二选一。当原码的最高位为1,得到其补码为符号位不变,幅度位按位取反后+1;当原码的最高位为0,得到其补码与原码相同
//assign a_comp=a[7]?y:a; //方法一、方法二、方法三:二选一。当原码的最高位为1,得到其补码为符号位不变,幅度位按位取反后+1;当原码的最高位为0,得到其补码与原码相同
assign a_comp=a[7]?{a[7],~a[6:0]+1}:a; //方法四(推荐使用)。在设计、编写取补等逻辑不太多的代码时,优选位拼接、二选一的方法,一句话就能表达。
endmodule
Part2:Test6_comp_conv_tb.v文件(Verilog仿真文件)
//2022-05-26
//补码转换逻辑--testbench of Test6_comp_conv
`timescale 1ns/10ps
module Test6_comp_conv_tb;
reg[7:0] a_in; //原码的输入,因要“动”着运行,将其定义为reg型的变量
wire[7:0] y_out; //补码的输出,因为要看到此输出结果,因此将其定义为wire型的变量
Test6_comp_conv Test6_comp_conv(
.a(a_in),
.a_comp(y_out)
);
initial begin
a_in<=0; //定义原码的初值为0
#3000 $stop; //定义仿真时长为3000ns。
//注:八位二进制可组成256(2^8)种数据,令原码a_in每过10ns加1,因此仿真时长大于2560ns就可遍历完成一轮仿真
end
always #10 a_in<=a_in+1; //每过10ns,原码a_in就加1
endmodule
仿真波形:
注意事项
1、在补码转换中,若原码的最高位为1,则原码是负数;若原码的最高位为0,则原码是正数;
2、正数的补码与原码相同,比如0x7f的补码也为0x7f;
3、负数的补码转换方法为:符号位(即最高位)不变、幅度位按位取反后+1,比如0x88的补码为0xf8;
4、可用大括号“{}”将一个数的不同的位拼接在一起来表示这个数,不同的位之间用“,”隔开,比如Test6_comp_conv.v文件中的“{a[7],~a[6:0]+1}”,意为把a的第8位和a的低7位拼接在一起来表示a;
5、八位二进制可组成256(2^8)种数据,令原码a_in每过10ns加1,因此仿真时长大于2560ns就可遍历完成一轮仿真;
6、在设计、编写取补等逻辑不太多的代码时,优选位拼接、二选一的方法,一句话就能表达。