一、题目
根据指示信号select的不同,对输入信号a,b实现不同的运算。输入信号a,b为8bit有符号数,当select信号为0,输出a;当select信号为1,输出b;当select信号为2,输出a+b;当select信号为3,输出a-b.
接口信号图如下:
输入描述:
clk:系统时钟
rst_n:复位信号,低电平有效
a,b:8bit位宽的有符号数
select:2bit位宽的无符号数
输出描述:
c:9bit位宽的有符号数
二、思路
select信号共有4种不同的取值,需要声明为2比特无符号数据。输入信号和输出信号为有符号数,输出信号可能是输入信号的和,所以需要拓展一位,防止溢出。
可以使用if else语句,但是有四种情况显得特别冗余,所以改用case语句。
在复位信号有效时,输出置为0,否则根据指示信号select的不同取值,对数据做不同的运算。另外,对于case语句的使用,保持良好的代码风格,需要添加default情况,防止select出现以上列举的取值之外的数值,导致电路中出现不必要的锁存器。另一方面,当每个取值情况下执行的代码超过一句,需要使用begin…end包含,如果只有一句,则可以省略begin…end。
三、设计文件
`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
);
always@(posedge clk or negedge rst_n)
if (rst_n == 0)
c <= 9'b0;
else begin
case (select)
2'b00: c<=a;
2'b01: c<=b;
2'b10: c<=a+b;
2'b11: c<=a-b;
default c<= 9'b0;
endcase
end
endmodule
四、补充总结
1、因为输入输出都已经直接定义了signed有符号数类型,所以直接相加、相减也没有问题,不会出现运算错误。
有符号数+有符号数=有符号数
这其中,如果加数中有无符号数,那么就会按照无符号运算。
如果表达式中有一个无符号数,则所有的操作数都会被强行转换为无符号数;
即:有符号A +无符号B时,会将补码表示的有符号A当成无符号数A1,,再计算A1+B,这样得到的结果就是错的了。
解决方法:
涉及到有符号数运算时,和有符号相关的输入、输出、中间变量均定义成signed有符号数,这样全部遵循有符号数运算规则