`timescale 1ns/1ns
module data_select(
input clk,
input rst_n,
input signed[7:0]a,//已经定义了有符号数,直接加减也没问题
input signed[7:0]b,
input [1:0]select,
output reg signed [8:0]c
);
//基础只是补充-----计算机的底层存储都是反码,还有有符号反码不够高位补1,无符号补0
//正数:原码=补码=反码
//负数:负数反码等于原码除符号位外,所有位取反;负数补码等于反码加一
//举例;6-12=-6,先都将6和12算为二进制,然后分别取其补码,变成两个补码相加,最后得到的结果变为原码
//对于+*都是一样的 无符号*(+)无符号=无符号;有符号*(+)有符号=有符号
//如果表达式中有一个数是无符号数,所有的操作数都会被强制转换成无符号数
//此题特别注意是有符号数,通过补码的形式表示负数,为1的话是负数,声明的时候全都要加signed
//select为0,输出a,select为1,输出b;select为2,输出a+b,select为3,输出a-b
//有符号数+有符号数=有符号数;无符号数+无符号数=无符号数;如果表达式中有一个为无符号数,
//则所有操作结果都会变成无符号数
//举例:有符号A +无符号B时,会将补码表示的有符号A当成无符号数A1,,再计算A1+B,这样得到的结果就是错的了
//解决①,涉及到有符号数的运算和有符号相关的输入,输出中间变量均定义成signed的有符号数,这样全部遵循有符号运算规则
//解决方案②用位拼接符补齐符号位
//答案1:自己做,不严谨版本,但对于本题输入类型直接定义为有符号数可以直接相加减
/*
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
c<=9'b0;
end
else begin
case(select)
2'b00:begin
c<=a;
end
2'b01:begin
c<=b;
end
2'b10:begin
c<=a+b;
end
2'b11:begin
c<=a-b;
end
default:begin
c<=9'b0;
end
endcase
end
end */
//答案二:有符号位的话,直接是补码的形式进行计算,正数不变,负数取其最高位做拼接运算,因为负数的话
//高位补1,正数位数不够高位补0,最终的结果底层都是按照反码的形式来进行存储的。
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
c<=9'b0;
end
else begin
case(select)
0:begin
c<={a[7],a};
end
1:begin
c<={b[7],b};
end
2:begin
c<={a[7],a}+{b[7],b};
end
3:begin
c<={a[7],a}-{b[7],b};
end
endcase
end
end
endmodule
module data_select(
input clk,
input rst_n,
input signed[7:0]a,//已经定义了有符号数,直接加减也没问题
input signed[7:0]b,
input [1:0]select,
output reg signed [8:0]c
);
//基础只是补充-----计算机的底层存储都是反码,还有有符号反码不够高位补1,无符号补0
//正数:原码=补码=反码
//负数:负数反码等于原码除符号位外,所有位取反;负数补码等于反码加一
//举例;6-12=-6,先都将6和12算为二进制,然后分别取其补码,变成两个补码相加,最后得到的结果变为原码
//对于+*都是一样的 无符号*(+)无符号=无符号;有符号*(+)有符号=有符号
//如果表达式中有一个数是无符号数,所有的操作数都会被强制转换成无符号数
//此题特别注意是有符号数,通过补码的形式表示负数,为1的话是负数,声明的时候全都要加signed
//select为0,输出a,select为1,输出b;select为2,输出a+b,select为3,输出a-b
//有符号数+有符号数=有符号数;无符号数+无符号数=无符号数;如果表达式中有一个为无符号数,
//则所有操作结果都会变成无符号数
//举例:有符号A +无符号B时,会将补码表示的有符号A当成无符号数A1,,再计算A1+B,这样得到的结果就是错的了
//解决①,涉及到有符号数的运算和有符号相关的输入,输出中间变量均定义成signed的有符号数,这样全部遵循有符号运算规则
//解决方案②用位拼接符补齐符号位
//答案1:自己做,不严谨版本,但对于本题输入类型直接定义为有符号数可以直接相加减
/*
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
c<=9'b0;
end
else begin
case(select)
2'b00:begin
c<=a;
end
2'b01:begin
c<=b;
end
2'b10:begin
c<=a+b;
end
2'b11:begin
c<=a-b;
end
default:begin
c<=9'b0;
end
endcase
end
end */
//答案二:有符号位的话,直接是补码的形式进行计算,正数不变,负数取其最高位做拼接运算,因为负数的话
//高位补1,正数位数不够高位补0,最终的结果底层都是按照反码的形式来进行存储的。
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
c<=9'b0;
end
else begin
case(select)
0:begin
c<={a[7],a};
end
1:begin
c<={b[7],b};
end
2:begin
c<={a[7],a}+{b[7],b};
end
3:begin
c<={a[7],a}-{b[7],b};
end
endcase
end
end
endmodule