在秋招中,很多求职者都遇到过关于找1的手撕代码题,其中平头哥面试就会让面试者手撕这种类型的题,其中出题套路大多为从最高位/最低位开始找到1个8bit/16bit数的第一个位置,统计8bit/16bit数中1的个数。
大家不妨先想想自己遇到这个问题会怎么写这个代码?下面小编给出几种思路:
1、从最高位开始找出一个8bit数的第一个1的位置(二分法)(1)设计代码
module find_first1_h2L(
input [7:0]x,
output wire [2:0]y
);
wire [3:0]data_4;
wire [1:0]data_2;
assign y[2]=|x[7:4];
assign data_4=y[2]?x[7:4]:x[3:0];
assign y[1]=|data_4[3:2];
assign data_2=y[1]?data_4[3:2]:data_4[1:0];
assign y[0]=data_2[1];
endmodule
(2)仿真代码
module find_first1_h2L_tst();
reg [7:0]x;
wire [2:0]y;
find_first1_h2L U_find_first1_h2L(
.x(x),
.y(y)
);
initial begin
x=8'b00101110;
#20 x=8'b01100000;
#20 x=8'b00000000;
#20 x=8'b00000001;
end
endmodule
2、输入[15:0]data_in中,从低位开始找到第一个1出现的位置。
(1)设计代码
module find_one(
input clk,
input rst_n,
input [15:0]data_in,
input data_in_valid,
output reg[3:0]position
);
wire [15:0]data_in_r;
assign data_in_r=~(data_in-1)&data_in;
always@(posedge clk)
if(!rst_n)
position<=0;
else begin
case(data_in_r)
16'b0000000000000001:position<=4'd0;
16'b0000000000000010:position<=4'd1;
16'b0000000000000100:position<=4'd2;
16'b0000000000001000:position<=4'd3;
16'b0000000000010000:position<=4'd4;
16'b0000000000100000:position<=4'd5;
16'b0000000001000000:position<=4'd6;
16'b0000000010000000:position<=4'd7;
16'b0000000100000000:position<=4'd8;
16'b0000001000000000:position<=4'd9;
16'b0000010000000000:position<=4'd10;
16'b0000100000000000:position<=4'd11;
16'b0001000000000000:position<=4'd12;
16'b0010000000000000:position<=4'd13;
16'b0100000000000000:position<=4'd14;
16'b1000000000000000:position<=4'd15;
default:position<=0;
endcase
end
endmodule
(2)仿真代码
module find_one_tst();
reg clk ;
reg rst_n ;
reg [15:0]data_in ;
reg data_in_valid;
wire[3:0] position;
find_one U_find_one(
.clk (clk ),
.rst_n (rst_n ),
.data_in (data_in ),
.data_in_valid(data_in_valid),
.position (position)
);
initial begin
clk=1;
rst_n=0;
data_in=0;
data_in_valid=0;
#20 rst_n=1;
data_in=16'd12;
data_in_valid=1;
#40 data_in=16'd9;
#20 data_in_valid=0;
end
always #10 clk=~clk;
endmodule
大家也可以用二分法试试!
3、统计输入[7:0]data_in中1的个数,要求优化资源使用
(1)设计代码
module find_number1(
input [7:0]data,
output [7:0]number
);
parameter m1 = 8'b01010101;
parameter m2 = 8'b00110011;
parameter m3 = 8'b00001111;
wire [7:0]data1;
wire [7:0]data2;
assign data1 = (data & m1) + ({data[0],data[7:1]} & m1);
assign data2 = (data1 & m2) + ({data1[1:0],data1[7:2]} & m2);
assign number = (data2 & m3) + ({data2[3:0],data2[7:4]} & m3);
endmodule
(2)仿真代码
module tst_find_number1();
reg [7:0]data;
wire [7:0]number;
find_number1 u1(
.data (data),
.number (number)
);
initial begin
data = 8'b11010100;
end
endmodule
上面的解法并非最优,仅给大家提供一种思路。如果大家有更好的写法,欢迎与小编交流。大家对文章中的内容如果有疑问,欢迎留言,我们看到了会给大家解答的。也欢迎大家加入下面的qq群或者添加IC媛加入微信群进行讨论交流!