题意整理

题目要求根据指示信号select的不同取值,执行不同的操作,有两种方法可以实现:一种是使用嵌套的if-else语句,第二种是使用case语句。使用if-else语句逻辑层次上不够清晰,代码也稍显冗余,所以本题采用case语句。注意题目要求输入信号为有符号数,另外输出信号可能是输入信号的和,所以需要拓展一位,防止溢出。

题解主体

根据题目的要求,模块的输入端口包括:
系统时钟和复位信号:clk,rst_n;

两个8bit输入信号a,b;

一个指示信号select.

       输出端口包括:

               输出信号c.

select信号共有4种不同的取值,需要声明为2比特无符号数据。输入信号和输出信号为有符号数,输出信号可能是输入信号的和,所以需要拓展一位,防止溢出。再加上系统时钟信号和复位信号,完整的模块端口声明是:

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

);

       在复位信号有效时,输出置为0,否则根据指示信号select的不同取值,对数据做不同的运算。另外,对于case语句的使用,保持良好的代码风格,需要添加default情况,防止select出现以上列举的取值之外的数值,导致电路中出现不必要的锁存器。另一方面,当每个取值情况下执行的代码超过一句,需要使用begin…end包含,如果只有一句,则可以省略begin…end。代码如下:

       always @(posedge clk or negedge rst_n)

       if(!rst_n)

              c <= 9'd0;                   //当复位信号有效时,输出置为0

       else case(select)                  //select作为关键字case的参数

       2'b00:    c <= a;                 //根据select的不同取值,执行不同的操作。

       2'b01:    c <= b;

       2'b10:    c <= a+b;

       2'b11:    c <= a-b;

       default: c <= 9'd0;              //表示当select取值不在上述列举的范围内,将输出置0

       endcase                              //以endcase关键字结束case语句

参考答案

`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)
		c <= 9'd0;
	else case(select)
	2'b00:	c <= a;
	2'b01:	c <= b;
	2'b10:	c <= a+b;
	2'b11:	c <= a-b;
	default: c <= 9'd0;
	endcase

endmodule