zl程序教程

您现在的位置是:首页 >  其他

当前栏目

关于“1”的verilig相关手撕代码

代码 关于 相关
2023-09-27 14:20:42 时间

从高位开始找出第一个1出现的位置

第一种方法

设计思路:因为从高位开始找出第一个1出现的位置,我们可以考虑新建立一个与之等长度的信号,与之想与后产生独热码,该独热码为1的位置即为需要找的位置。现在主要问题是如何产生这样的一个新信号。
大致思路如图所示,从低位找出第一个1的位置同理。

在这里插入图片描述
rtl代码:




module find_1(
		input [7:0] data,
		output [7:0] sigal
		);
		
		
		wire [7:0] pre;
		
		assign pre[7] = 0;
		
		assign pre[6:0] = pre[7:1] | data[7:1];、
		///下面两行代码是从低位找出第一个1的位置
		//assign pre[0] = 0;
		//assign pre[7:1] = data[6:0] | pre[6:0];
		
		assign sigal = data & ~pre;

				
	
	
		
	
endmodule

第二种方法:
第二种方法也称为二分法
rtl代码

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

还有类似于找出第一个0的位置,其实就把原始输入取反就变成了找1的位置了。

从低位开始找出第一个1出现的位置

第一种方法与从高位找的第一种方法类似

第二种方法
二分法,注意这里需要考虑输入为0的特殊情况;

// find the last one
module find_one(
input [7:0] data,
output [2:0] sigal);

wire[2:0] index;
wire [3:0] data_4;
wire [1:0] data_2;

assign index[2] = ~|data[3:0];
assign data_4 = index[2] ? data[7:4]:data[3:0];
assign index[1] = ~|data_4[1:0];
assign data_2 = index[1] ? data_4[3:2] : data_4[1:0];
assign index[0] = ~data_2[0];

assign sigal = |data?index:3'd0;//考虑输入全为0的特殊情况

endmodule

第三种方法
注意data_in_r=~(data_in-1)&data_in;这个也是为了产生独热码;

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

统计输入中1的个数

第一种方法,把每bit相加的结果就是1的个数

module top_module( 
    input [2:0] in,
    output [1:0] out );
    
    reg [1:0] out_temp;
    integer i;
    
    always@(*)begin
        out_temp = 2'd0;
        for(i = 0; i <= 2; i = i + 1)begin
            out_temp = out_temp + in[i];
        end
    end
    
    assign out = out_temp;
 
endmodule

第二种方法

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