问题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