赞
踩
设计一个组合逻辑电路,检测输入32位0/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实现代码可综合,逻辑延迟越小越好,给出仿真结果。
代码实现如下:
- 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

- 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

- 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

- `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

仿真结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。