向量前导1检测器的3种verilog实现方案

本文介绍了一种组合逻辑电路的设计方案,用于检测32位0/1向量中从高到低第一个1的位置。提供了三种实现方式:使用casex/casez语句、逐项比较if...else...及二分法,并展示了仿真结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、要求

设计一个组合逻辑电路,检测输入320/1向量中从高到低第一个1出现的位置,如果向量为全0则输出32。例如:

输入00011000 10000000 00000000 00000000,输出3;

输入00000000 11111111 00000000 00000000,输出8;

输入00000000 00000000 00000000 00001010,输出28.

模块输入输出功能定义:

名称

方向

位宽

描述

data_in

I

32

输入0/1向量

pos_out

O

6

前导1出现位置,取值范围0 ~ 32

设计要求:

Verilog实现代码可综合,逻辑延迟越小越好,给出仿真结果。

 二、实现

 1.casex/casez

代码实现如下:

module seq_head_detect(
	input 	[31:0]	data_in,
	output 	    	pos_out
);

reg [31:0] tmp;
reg [5:0]  pos_out_tmp;
reg [5:0]  pos_out;

always @(*) begin

	tmp = data_in;
	
	casex(tmp)
	
		32'b1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd0;
		32'b01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd1;
		32'b001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd2;
		32'b0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd3;	//第4位为1
		32'b0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd4;
		32'b0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd5;
		32'b0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd6;
		32'b0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd7;	//8
		32'b0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd8;
		32'b0000_0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd9;
		32'b0000_0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd10;
		32'b0000_0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd11;	//12
		32'b0000_0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd12;
		32'b0000_0000_0000_01xx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd13;
		32'b0000_0000_0000_001x_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd14;
		32'b0000_0000_0000_0001_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd15;	//16
		32'b0000_0000_0000_0000_1xxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd16;
		32'b0000_0000_0000_0000_01xx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd17;
		32'b0000_0000_0000_0000_001x_xxxx_xxxx_xxxx : pos_out_tmp = 6'd18;
		32'b0000_0000_0000_0000_0001_xxxx_xxxx_xxxx : pos_out_tmp = 6'd19;	//20
		32'b0000_0000_0000_0000_0000_1xxx_xxxx_xxxx : pos_out_tmp = 6'd20;
		32'b0000_0000_0000_0000_0000_01xx_xxxx_xxxx : pos_out_tmp = 6'd21;
		32'b0000_0000_0000_0000_0000_001x_xxxx_xxxx : pos_out_tmp = 6'd22;
		32'b0000_0000_0000_0000_0000_0001_xxxx_xxxx : pos_out_tmp = 6'd23;	//24
		32'b0000_0000_0000_0000_0000_0000_1xxx_xxxx : pos_out_tmp = 6'd24;
		32'b0000_0000_0000_0000_0000_0000_01xx_xxxx : pos_out_tmp = 6'd25;
		32'b0000_0000_0000_0000_0000_0000_001x_xxxx : pos_out_tmp = 6'd26;
		32'b0000_0000_0000_0000_0000_0000_0001_xxxx : pos_out_tmp = 6'd27;	//28
		32'b0000_0000_0000_0000_0000_0000_0000_1xxx : pos_out_tmp = 6'd28;
		32'b0000_0000_0000_0000_0000_0000_0000_01xx : pos_out_tmp = 6'd29;
		32'b0000_0000_0000_0000_0000_0000_0000_001x : pos_out_tmp = 6'd30;
		32'b0000_0000_0000_0000_0000_0000_0000_0001 : pos_out_tmp = 6'd31;	//32
		default 									: pos_out_tmp = 6'd32;	//全0
		
	endcase                                          

	pos_out = pos_out_tmp;

end

endmodule

2.逐项比较if...else...

module seq_head_detect(
	input 	[31:0]	data_in,
	output 	        pos_out
);

reg [31:0] tmp;
reg [5:0]  pos_out_tmp;
reg [5:0]  pos_out;

always @(*) begin

	tmp = data_in;
	
	if(tmp[31]) pos_out_tmp = 6'd0;
	else if(tmp[30]) pos_out_tmp = 6'd1;
	else if(tmp[29]) pos_out_tmp = 6'd2;
	else if(tmp[28]) pos_out_tmp = 6'd3;
	else if(tmp[27]) pos_out_tmp = 6'd4;
	else if(tmp[26]) pos_out_tmp = 6'd5;
	else if(tmp[25]) pos_out_tmp = 6'd6;
	else if(tmp[24]) pos_out_tmp = 6'd7;
	else if(tmp[23]) pos_out_tmp = 6'd8;
	else if(tmp[22]) pos_out_tmp = 6'd9;
	else if(tmp[21]) pos_out_tmp = 6'd10;
	else if(tmp[20]) pos_out_tmp = 6'd11;
	else if(tmp[19]) pos_out_tmp = 6'd12;
	else if(tmp[18]) pos_out_tmp = 6'd13;
	else if(tmp[17]) pos_out_tmp = 6'd14;
	else if(tmp[16]) pos_out_tmp = 6'd15;
	else if(tmp[15]) pos_out_tmp = 6'd16;
	else if(tmp[14]) pos_out_tmp = 6'd17;
	else if(tmp[13]) pos_out_tmp = 6'd18;
	else if(tmp[12]) pos_out_tmp = 6'd19;
	else if(tmp[11]) pos_out_tmp = 6'd20;
	else if(tmp[10]) pos_out_tmp = 6'd21;
	else if(tmp[9]) pos_out_tmp = 6'd22;
	else if(tmp[8]) pos_out_tmp = 6'd23;
	else if(tmp[7]) pos_out_tmp = 6'd24;
	else if(tmp[6]) pos_out_tmp = 6'd25;
	else if(tmp[5]) pos_out_tmp = 6'd26;
	else if(tmp[4]) pos_out_tmp = 6'd27;
	else if(tmp[3]) pos_out_tmp = 6'd28;
	else if(tmp[2]) pos_out_tmp = 6'd29;
	else if(tmp[1]) pos_out_tmp = 6'd30;
	else if(tmp[0]) pos_out_tmp = 6'd31;
	else			pos_out_tmp = 6'd32;

	pos_out = pos_out_tmp;

end

endmodule

 3.二分法

module seq_head_detect(
	input 	[31:0]	data_in,
	output 	[ 5:0]	pos_out
);

//mark:assign不能给reg赋值,只能赋给wire
wire [4:0]  data_chk;
wire [15:0] data_1;	
wire [7:0]  data_2;
wire [3:0]  data_3;
wire [1:0]  data_4;


assign data_chk[4] = |data_in[31:16];//高16位相或,依此类推
assign data_chk[3] = |data_1[15:8];
assign data_chk[2] = |data_2[7:4];
assign data_chk[1] = |data_3[3:2];
assign data_chk[0] = |data_4[1]; 

assign	data_1	= (data_chk[4]) ? data_in[31:16] : data_in[15:0]; //若data_in高16位有1,则data1取其高16位,否则取低16位
assign	data_2 	= (data_chk[3]) ? data_1[15:8] 	: data_1[7:0];		//若data_1高8位有1,则data2取其高8位,否则取低8位
assign	data_3 	= (data_chk[2]) ? data_2[7:4] : data_2[3:0];		//若data_2高4位有1,则data3取其高4位,否则取低4位
assign	data_4 	= (data_chk[1]) ? data_3[3:2] : data_3[1:0];		//若data_3高2位有1,则data4取其高2位,否则取低2位
assign 	pos_out = (|data_in) ? {1'b0, ~data_chk} : 6'd32;	//若data_in为全0,posout = 6'd32
/*data_in中有1时,用低5位表示足够,则最高位为0*/
/*假定data_in首位为1,则data_chk = 11111,应有pos_out = 00000,类推可知data_chk取反*/

endmodule

三、仿真

 testbench:

`timescale 1ns / 1ps

module tb_seq_head_detect();
reg [31:0] data_in;
wire [5:0] pos_out;

initial begin
	data_in = 32'b0000_0000_0000_0000_0000_0000_0000_0000;
	#100
	data_in = 32'b0000_0001_0000_0000_0000_0000_0000_1101;//第8位,pos_out = 7
	#100
	data_in = 32'b0000_0000_0000_0000_0010_0000_0000_1101;//第19位,pos_out = 18
end

seq_head_detect u_seq_head_detect(
	.data_in (data_in),
	.pos_out (pos_out)
);

endmodule

仿真结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bluebub

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

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

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

打赏作者

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

抵扣说明:

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

余额充值