1.
现在输入了一个压缩的16位数据,其实际上包含了四个数据[3:0][7:4][11:8][15:12],
现在请按照sel选择输出四个数据的相加结果,并输出valid_out信号(在不输出时候拉低)
0: 不输出且只有此时的输入有效
1:输出[3:0]+[7:4]
2:输出[3:0]+[11:8]
3:输出[3:0]+[15:12]
这道题的重点是 只有sel=0时输入有效!!所以需要在sel=0时将数据寄存下来!!在sel!=0时用寄存下来的值进行后续计算
module data_cal(
input clk,
input rst,
input [15:0]d,
input [1:0]sel,
output [4:0]out,
output validout
);
//*************code***********//
reg [4:0] out;
reg validout;
reg [15:0] d_reg;
always@(posedge clk or negedge rst)
if(!rst)begin
out <= 5'd0;
validout <= 1'b0;
d_reg <= 16'd0;
end
else begin
case(sel)
2'b00:begin
validout <= 1'b0;
d_reg <= d;
out <= 'd0;
end
2'b01:begin
validout <= 1'b1;
d_reg <= d_reg;
out <= d_reg[3:0] + d_reg[7:4];
end
2'b10:begin
validout <= 1'b1;
d_reg <= d_reg;
out <= d_reg[3:0] + d_reg[11:8];
end
2'b11:begin
validout <= 1'b1;
d_reg <= d_reg;
out <= d_reg[3:0] + d_reg[15:12];
end
endcase
end
//*************code***********//
endmodule
2. 使用子模块实现三输入数的大小比较
在数字芯片设计中,通常把完成特定功能且相对独立的代码编写成子模块,在需要的时候再在主模块中例化使用,以提高代码的可复用性和设计的层次性,方便后续的修改。
请编写一个子模块,将输入两个8bit位宽的变量data_a,data_b,并输出data_a,data_b之中较小的数。并在主模块中例化,实现输出三个8bit输入信号的最小值的功能。
子模块的信号接口图如下:
这里很多习惯于软件思维的人写代码会只例化2次子模块,是将a,b比较之后的结果min_ab与c进行比较,进而得到min_abc。由于比较器是时序逻辑,需要一个时钟周期才能得到结果,所以可能存在a
和b
比较结束时c
已经更新的情况。
但是这样是错误的,因为当min_ab与c比较时,是上一时刻a,b的最小值与此时c的值比较,也就是拍数上是差一拍的,因此做不到比较同一拍下的a,b,c。
module main_mod(
input clk,
input rst_n,
input [7:0]a,
input [7:0]b,
input [7:0]c,
output [7:0]d
);
wire [7:0] min_1;
wire [7:0] min_2;
sub_module u1_sub(.clk(clk), .rst_n(rst_n), .data_a(a), .data_b(b), .data_c(min_1));
sub_module u2_sub(.clk(clk), .rst_n(rst_n), .data_a(a), .data_b(c), .data_c(min_2));
sub_module u3_sub(.clk(clk), .rst_n(rst_n), .data_a(min_1), .data_b(min_2), .data_c(d));
endmodule
module sub_module(
input clk,
input rst_n,
input [7:0] data_a,
input [7:0] data_b,
output [7:0] data_c
);
reg [7:0] c_r;
always@(posedge clk or negedge rst_n)
if(~rst_n)
c_r <= 'd0;
else
c_r <= data_a<data_b?data_a:data_b;
assign data_c = c_r;
endmodule