数字IC面试手撕代码(六)

问题1

一次输入一个32bit的数据,实时输出最大值次大值

方法

设置两个寄存器,分别用于保存当前的最大值和次大值,当下一个数据到来时,根据这三个数据的情况,更新这两个寄存器:
设这两个寄存器为most_max和sec_max,下一个到来的数据为din,则
当din>most_max时
most_max<=din;
sec_max<=most_max;
当sec_max<din<=most_max时
most_max<=most_max;
sec_max<=din;

当sec_max>=din时,所有寄存器保持不变。

代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/03/18 21:37:17
// Design Name: 
// Module Name: demo
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module demo
(
    input logic [31:0] din,
    input logic clk,
    input logic rst,
    output logic [31:0] max1,              //最大值
    output logic [31:0] max2               //次大值
);
logic [31:0] most_max;
logic [31:0] sec_max;                            //most_max>=sec_max
always_ff@(posedge clk,posedge rst)
if(rst)
begin
    most_max<=0;
    sec_max<=0;
end
else 
begin
    if(din>most_max)                //sec_max<=most_max<=din
    begin
        most_max<=din;
        sec_max<=most_max;
    end
    else if(din>sec_max)            //sec_max<din<=most_max
    begin
        sec_max<=din;
    end
end
assign max1=most_max;
assign max2=sec_max;
endmodule

问题2

给定一个16bit的数据,求从高位到低位,第一次出现的1在哪一位。

方法

我们采用二分法的思想,设输入数据为din,输出为out,out应该为4位,则
当din高8位有1的时候,out[3]必为1,否则为0;
如果out[3]==1,则将din的高8位取出,否则取出低8位;
在取出的8位中,如果高4位有1,则out[2]必为1,否则为0;
以此类推…
至于这个问题的镜像问题:给定一个16bit的数据,求从低位到高位,第一次出现的1的位置。我们可以采用如下方法
1.将该数据逆序,得到y;
2.求y的从高到低第一次出现的1的位置z;
3.16-1-z即为最终结果。
例如:x=0100_0010_1101_0100
则y=0010_1011_0100_0010,最高位1的位置为13,16-1-13=2即为正确结果。
而当输入数据的位宽不是2的幂时,我们也只需要将它扩展到大于等于这个数的最小的2的幂即可。例如35bit—>64bit。

代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/03/19 12:45:53
// Design Name: 
// Module Name: demo2
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module demo2(
input logic [15:0] din,
output logic [3:0] out
    );
logic [7:0] tmp1;
logic [3:0] tmp2;
logic [1:0] tmp3;
assign out[3]=|din[15:8];                 //检测高8位是否有1
assign tmp1=(out[3])?din[15:8]:din[7:0];  //从8位中继续检测1
assign out[2]=|tmp1[7:4];                 //检测高4位是否有1
assign tmp2=(out[2])?tmp1[7:4]:tmp1[3:0]; //从4位中继续检测1
assign out[1]=|tmp2[3:2];                 //检测高2位是否有1
assign tmp3=(out[1])?tmp2[3:2]:tmp2[1:0]; //从2位中继续检测
assign out[0]=tmp3[1];                    //若tmp3[1]为1,则为1,否则为0
endmodule

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGA硅农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值