牛客刷题 day2

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。由于比较器是时序逻辑,需要一个时钟周期才能得到结果,所以可能存在ab比较结束时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

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值