深度学习神经网络中LOSS函数使用硬件描述语言实现

目录

一、python重现实现LOSS函数

二、关于指数爆炸(inf)的问题

三、Verilog实现(可处理小数)

1. Verilog实现2^n(n包含小数)

2. Verilog实现log2(m)(m包含小数)

四、功能验证

1. 验证2^n计算的verilog代码误差

2. 验证log2计算的verilog代码误差 


一、python重现实现LOSS函数

        由于resnet18深度学习网络在代码实现过程中直接调用的库里边的loss函数,如下图所示,所以我们首先要用python代码重现对loss函数进行复现,才能准确理解其定义实现过程,进而编写verilog函数。

 with torch.no_grad():
                        for batch_idx, (inputs, targets) in enumerate(testloader):
                            inputs, targets = inputs.to(device), targets.to(device)
                            outputs = swa_net(inputs)
                            loss = criterion(outputs, targets)
                            test_swa_loss += loss.item()
                            _, predicted = outputs.max(1)

根据查阅相关资料,交叉熵损失函数loss的原理如公式所示: 

 使用python代码对其进行实现并对其进行测试,如下所示:

import torch

def CrossEntropyLoss(output, target):
    res = -output.gather(dim=1, index=target.view(-1, 1))
    res += torch.log(torch.exp(output).sum(dim=1).view(-1, 1))
    #res += torch.max(output).view(-1, 1)
    res = res.mean()
    return res

output = torch.tensor([
    [1, 2, 3],
    [4, 5, 6]
], dtype=torch.float32)

target = torch.tensor(
    [0, 1],
)

print(torch.nn.CrossEntropyLoss()(output, target))
print(CrossEntropyLoss(output, target))

由打印的结果可知,用该方法实现与系统结果一致。

注:由论文:A 2.25 TOPS/W Fully-Integrated Deep CNN Learning Processor with On-Chip Training 可知,底数e可用2替代,并可使用求最大值来代替求和。

 但是在应用到cifar100数据集进行训练时,发现交叉熵损失函数难以收敛,与用e求和的结果有着较大差距。并在实验过程中发现,底数使用e或者2,相对应的使用log(e)或者log(2)对loss的结果几乎不影响。

二、关于指数爆炸(inf)的问题

 如果直接使用上述函数在深度学习神经网络中进行训练,对于分类较多的问题则有可能出现数据溢出的情况,原因在于loss函数的分母指数求和时数据会非常大。

 可以对其分子分母同时除以一个最大值

分离到log外边后也就是每一项都减去最大值,代码如下所示:

def myCrossEntropyLoss(output, target):
    # temp0 = torch.max(output,dim=1)[0]
    # output -= temp0[...,None]
    # res = -output.gather(dim=1, index=target.view(-1, 1))

    # temp = torch.exp(output)
    # temp = torch.sum(temp,dim=1)
    # temp = torch.log(temp)
    # res +=temp.view(-1,1)
    x = torch.max(output,dim=1)[0]
    res = -output.gather(dim=1, index=target.view(-1, 1)) + x.view(-1, 1)
    res += torch.log((torch.exp(output-x[...,None]).sum(dim=1)).view(-1, 1))
    
    #cunchu = torch.log((torch.exp(output).sum(dim=1)+0.000001).view(-1, 1))
    #res += torch.log((2**output).sum(dim=1).view(-1, 1))
    res = res.mean()
    cunchu =  output
    return res, cunchu

三、Verilog实现(可处理小数)

最基础的2^n及log2函数用Verilog进行实现时可以用简单的移位操作,前者左移,后者右移,举例:verilog实现log2如下所示:

    function integer clog2;
        input   integer v;
        integer value;
        begin 
            value = v - 1;
            for(clog2 = 0; value > 0; clog2 = clog2 + 1)begin 
                value = value >> 1;
            end
        end 
    endfunction 

 然而,在实际应用过程中,比如神经网络加速器的loss函数对数据进行处理,2^n及log2难免会产生小数,为了保证数据的准确性,以及和原网络使用软件算法的结果尽可能保证一致,本人实现了一种新的方法。

1. Verilog实现2^n(n包含小数)

在对传入的16位数据(1位符号位,8位整数,7位小数)进行处理时,首先对小数共2^7种情况进行查找表存储(原本是小数,这里存储为2进制数,相当于左移了64位),然后对整数部分的值进行右移操作,为使得结果继续保持为7位小数,此时只需要对查找表的结果进行右移(57-整数值)位即可。也就是实现了左移(64-57+整数值)位。

比如:

        2^18.75 = 2^18 * 2^0.75

        所以把2^0.75存为查找表(左移64位),再右移(64-18)位即可实现2^18.75计算

        为了使计算结果保留7位小数,所以在此只移动(57-18)位

具体的代码如下所示:

// *******************************************Declaration************************************************ //                                                               * //
// *                                                                                                    * //
// *                                                                                                    
// *  File name:        ex_sum.v                                                                        * //
// *  Author:           xz_chen                                                                         * //
// *  Date:             2023-4-22 22:19                                                                 * //
// *  Version Number:   1.0                                                                             * //
// *  Abstract:         Top module of batch normalization, including MEM.                               * //
// *                                                                                                    * //
// *  Modification history:(including time,version,author,abstract)                                     * //                                * //
// *                                                                                                    * //
// ***********************************************end**************************************************** //

// MODULE DECLARATION
`timescale 1ns/1ns

//------------------------------------------------------------------------------
// INDEX: Module 
//------------------------------------------------------------------------------
module ex_sum#(
//------------------------------------------------------------------------------
// INDEX:	1. Definitions
//------------------------------------------------------------------------------
parameter DATAWIDTH1    =  16,          // 输入预测结果位宽 | 输出loss位宽
parameter DATAWIDTH2    =  7            // 100类列索引

)(
//------------------------------------------------------------------------------
// INDEX:	2. Interface
//------------------------------------------------------------------------------
// reset & clock
input     wire                          clk,
input     wire                          rst_n,

// input
input     wire                          loss_in_valid,
input     wire    [DATAWIDTH1-1 : 0]    y_pre,
// output
output    reg                           chuli_valid,
output    wire                          sum_valid,
output    reg     [65+3-1 : 0]          sum           
);

//------------------------------------------------------------------------------
// INDEX:	3. Internal Parameters
//------------------------------------------------------------------------------
localparam    CNTWIDTH1     =  3;           //100output分7次输入 

//------------------------------------------------------------------------------
// INDEX:	4. Wire and Reg Declarations
//------------------------------------------------------------------------------
reg   [CNTWIDTH1-1 : 0]   count;
reg   [64 : 0]            xiaoshu;

reg   [7:0]               reg_y;

//------------------------------------------------------------------------------
// INDEX:	5. Verilog Instance
//------------------------------------------------------------------------------

always @(posedge clk or negedge rst_n) begin  //每个valid,加1
    if(!rst_n) begin
        reg_y      <= 0;
        count      <= 0;
        chuli_valid  <= 1;
    end
    else if(loss_in_valid) begin  
        if((count < 3'd7) ) begin
            reg_y <= y_pre[14:7];
            count <= count + 1;
            chuli_valid <= 0;     
        end
//        else if(count == 3'd7)begin           
//            count <= 0;
//            sum_valid <= 1;    
//        end          
    end
end

//always @(posedge clk or negedge rst_n) begin  //寄存
//   if(!rst_n) begin
//       s_reg_y  <= 1;
//       reg_y <= 0;
//   end
//   if(loss_in_valid) begin
//       if(s_reg_y) begin
//           reg_y <= y_pre[14:7];
//           s_reg_y <= 0;
//       end
//   end
//end


always @(posedge clk or negedge rst_n) begin  //移位(58位整数,7位小数)
    if(!rst_n) begin
       reg_y <= 0;
	   sum	<= 0;
    end
    else if(chuli_valid == 0) begin
        if(y_pre[15] == 0) begin   
            if((57-reg_y) != 0)begin
                xiaoshu <=  xiaoshu >> 1;
                reg_y <= reg_y + 1;
            end
            else if((57-reg_y) == 0)begin
                sum <= sum + xiaoshu;
        		xiaoshu <= 0;
        		chuli_valid <= 1;
            end
        end
        else if(y_pre[15] == 1) begin 
        	if(reg_y != 0)begin
        		xiaoshu <=  xiaoshu >> 1;
        		reg_y <= reg_y - 1; 	
        	end
        	else if(reg_y == 0)begin
        		sum <= sum + xiaoshu;
        		xiaoshu <= 0;
        		chuli_valid <= 1;
        	end
        end
    end
end

assign sum_valid = ((count == 3'd7) & (chuli_valid == 1))? 1'b1 : 0;


always@(*) begin
	if(y_pre[15] == 0)begin
		case(y_pre[6:0])
			7'b0000000:  xiaoshu = 65'b10000000000000000000000000000000000000000000000000000000000000000;
			7'b0000001:  xiaoshu = 65'b10000000101100011110110101001111110110011001100110101000000000000;
			7'b0000010:  xiaoshu = 65'b10000001011001001101000111110011101111000000001100001000000000000;
			7'b0000011:  xiaoshu = 65'b10000010000110001010111101000011011100111111110000101000000000000;
			7'b0000100:  xiaoshu = 65'b10000010110011011000011010011000101011000010101110100000000000000;
			7'b0000101:  xiaoshu = 65'b10000011100000110101100101001110111011111011011011110000000000000;
			7'b0000110:  xiaoshu = 65'b10000100001110100010100011000011101011001101111001000000000000000;
			7'b0000111:  xiaoshu = 65'b10000100111100011111011001010110001101111001110000011000000000000;
			7'b0001000:  xiaoshu = 65'b10000101101010101100001101100111110011000100100001111000000000000;
			7'b0001001:  xiaoshu = 65'b10000110011001001001000101011011100100100011111110111000000000000;
			7'b0001010:  xiaoshu = 65'b10000111000111110110000110010110100111101000110100010000000000000;
			7'b0001011:  xiaoshu = 65'b10000111110110110011010101111111111101101001100011011000000000000;
			7'b0001100:  xiaoshu = 65'b10001000100110000000111010000000100100101101101010001000000000000;
			7'b0001101:  xiaoshu = 65'b10001001010101011110111000000011011000011000111001100000000000000;
			7'b0001110:  xiaoshu = 65'b10001010000101001101010101110101010010010110111100000000000000000;
			7'b0001111:  xiaoshu = 65'b10001010110101001100011001000101001011000111001010001000000000000;
			7'b0010000:  xiaoshu = 65'b10001011100101011100000111100011111010101000101111011000000000000;
			7'b0010001:  xiaoshu = 65'b10001100010101111100100111000100011001000110111101010000000000000;
			7'b0010010:  xiaoshu = 65'b10001101000110101101111101011011011111100101101110101000000000000;
			7'b0010011:  xiaoshu = 65'b10001101110111110000010000100000001000101110011010100000000000000;
			7'b0010100:  xiaoshu = 65'b10001110101001000011100110001011010001011100110101010000000000000;
			7'b0010101:  xiaoshu = 65'b10001111011010101000000100010111111001101100100011101000000000000;
			7'b0010110:  xiaoshu = 65'b10010000001100011101110001000011000101000110011010110000000000000;
			7'b0010111:  xiaoshu = 65'b10010000111110100100110010001011111011101110010010110000000000000;
			7'b0011000:  xiaoshu = 65'b10010001110000111101001101110011101010110001000111000000000000000;
			7'b0011001:  xiaoshu = 65'b10010010100011100111001001111101100101010011000111111000000000000;
			7'b0011010:  xiaoshu = 65'b10010011010110100010101100101111000100111110011011101000000000000;
			7'b0011011:  xiaoshu = 65'b10010100001001101111111100001111101010110001110000001000000000000;
			7'b0011100:  xiaoshu = 65'b10010100111101001110111110101000111111101111011100001000000000000;
			7'b0011101:  xiaoshu = 65'b10010101110000111111111010000110110101101100110010000000000000000;
			7'b0011110:  xiaoshu = 65'b10010110100101000010110100110111001000000001100001011000000000000;
			7'b0011111:  xiaoshu = 65'b10010111011001010111110101001001111100010111101010110000000000000;
			7'b0100000:  xiaoshu = 65'b10011000001101111111000001010001100011011011100010101000000000000;
			7'b0100001:  xiaoshu = 65'b10011001000010111000011111100010011001101100000110001000000000000;
			7'b0100010:  xiaoshu = 65'b10011001111000000100010110010011001000001011011111111000000000000;
			7'b0100011:  xiaoshu = 65'b10011010101101100010101011111100100101001111111110001000000000000;
			7'b0100100:  xiaoshu = 65'b10011011100011010011100110111001110101010100111001011000000000000;
			7'b0100101:  xiaoshu = 65'b10011100011001010111001101101000001011101100001100110000000000000;
			7'b0100110:  xiaoshu = 65'b10011101001111101101100110100111001011001111111110111000000000000;
			7'b0100111:  xiaoshu = 65'b10011110000110010110111000011000100111010100011100101000000000000;
			7'b0101000:  xiaoshu = 65'b10011110111101010011001001100000100100011010000100010000000000000;
			7'b0101001:  xiaoshu = 65'b10011111110100100010100000100101011001000000000011100000000000000;
			7'b0101010:  xiaoshu = 65'b10100000101100000101000100001111101110010111000101010000000000000;
			7'b0101011:  xiaoshu = 65'b10100001100011111010111011001010100001010100010010111000000000000;
			7'b0101100:  xiaoshu = 65'b10100010011100000100001100000011000011000100100101101000000000000;
			7'b0101101:  xiaoshu = 65'b10100011010100100000111101101000111010000000001010111000000000000;
			7'b0101110:  xiaoshu = 65'b10100100001101010001010110101110000010011110011010000000000000000;
			7'b0101111:  xiaoshu = 65'b10100101000110010101011110000110101111101001111011110000000000000;
			7'b0110000:  xiaoshu = 65'b10100101111111101101011010101001101100010101000100111000000000000;
			7'b0110001:  xiaoshu = 65'b10100110111001011001010011001111111011101110100001101000000000000;
			7'b0110010:  xiaoshu = 65'b10100111110011011001001110110100111010010110010100111000000000000;
			7'b0110011:  xiaoshu = 65'b10101000101101101101010100010110011110110011001000010000000000000;
			7'b0110100:  xiaoshu = 65'b10101001101000010101101010110100111010100111110000010000000000000;
			7'b0110101:  xiaoshu = 65'b10101010100011010010011001010010111011001001000001111000000000000;
			7'b0110110:  xiaoshu = 65'b10101011011110100011100110110101101010010011111011010000000000000;
			7'b0110111:  xiaoshu = 65'b10101100011010001001011010100100101111100011111111101000000000000;
			7'b0111000:  xiaoshu = 65'b10101101010110000011111011101010010000101010000101001000000000000;
			7'b0111001:  xiaoshu = 65'b10101110010010010011010001010010110010100011010110111000000000000;
			7'b0111010:  xiaoshu = 65'b10101111001110110111100010101101011010010000101001000000000000000;
			7'b0111011:  xiaoshu = 65'b10110000001011110000110111001011101101101110000001001000000000000;
			7'b0111100:  xiaoshu = 65'b10110001001000111111010110000001110100101010110000101000000000000;
			7'b0111101:  xiaoshu = 65'b10110010000110100011000110100110011001100001100100000000000000000;
			7'b0111110:  xiaoshu = 65'b10110011000100011100010000010010101010010001000100101000000000000;
			7'b0111111:  xiaoshu = 65'b10110100000010101010111010100010011001010100101110011000000000000;
			7'b1000000:  xiaoshu = 65'b10110101000001001111001100110011111110011101111001101000000000000;
			7'b1000001:  xiaoshu = 65'b10110110000000001001001110101000010111101101010111111000000000000;
			7'b1000010:  xiaoshu = 65'b10110110111111011001000111100011001010001101000101111000000000000;
			7'b1000011:  xiaoshu = 65'b10110111111110111110111111001010100011001010010000100000000000000;
			7'b1000100:  xiaoshu = 65'b10111000111110111010111101000111011000101111101110100000000000000;
			7'b1000101:  xiaoshu = 65'b10111001111111001101001001000101001011000000101110100000000000000;
			7'b1000110:  xiaoshu = 65'b10111010111111110101101010110010000100110011111001001000000000000;
			7'b1000111:  xiaoshu = 65'b10111100000000110100101001111110111100101110100111111000000000000;
			7'b1001000:  xiaoshu = 65'b10111101000010001010001110011111010110000000110000111000000000000;
			7'b1001001:  xiaoshu = 65'b10111110000011110110100000001001100001100000100110010000000000000;
			7'b1001010:  xiaoshu = 65'b10111111000101111001100110110110011110100111001100010000000000000;
			7'b1001011:  xiaoshu = 65'b11000000001000010011101010100001111100001101000010010000000000000;
			7'b1001100:  xiaoshu = 65'b11000001001011000100110011001010011001100111000010011000000000000;
			7'b1001101:  xiaoshu = 65'b11000010001110001101001000110001000111100011110101101000000000000;
			7'b1001110:  xiaoshu = 65'b11000011010001101100110011011010001001001001011101101000000000000;
			7'b1001111:  xiaoshu = 65'b11000100010101100011111011001100010100110011010011001000000000000;
			7'b1010000:  xiaoshu = 65'b11000101011001110010101000010001010101010000011011011000000000000;
			7'b1010001:  xiaoshu = 65'b11000110011110011001000010110101101010100010010001100000000000000;
			7'b1010010:  xiaoshu = 65'b11000111100011010111010011001000101010111011100110110000000000000;
			7'b1010011:  xiaoshu = 65'b11001000101000101101100001011100100011111111111000110000000000000;
			7'b1010100:  xiaoshu = 65'b11001001101110011011110110000110011011100010111100101000000000000;
			7'b1010101:  xiaoshu = 65'b11001010110100100010011001011110010000101001000001111000000000000;
			7'b1010110:  xiaoshu = 65'b11001011111011000001010011111110111100100111001010000000000000000;
			7'b1010111:  xiaoshu = 65'b11001101000001111000101110000110010100000011110111010000000000000;
			7'b1011000:  xiaoshu = 65'b11001110001001001000110000010101000111111000010010000000000000000;
			7'b1011001:  xiaoshu = 65'b11001111010000110001100011001111000110010001100100011000000000000;
			7'b1011010:  xiaoshu = 65'b11010000011000110011001111011010111011110010101100101000000000000;
			7'b1011011:  xiaoshu = 65'b11010001100001001101111101100010010100010110100110011000000000000;
			7'b1011100:  xiaoshu = 65'b11010010101010000001110110010001111100010010101011101000000000000;
			7'b1011101:  xiaoshu = 65'b11010011110011001111000010011001100001011001101011000000000000000;
			7'b1011110:  xiaoshu = 65'b11010100111100110101101010101011110011111110110111111000000000000;
			7'b1011111:  xiaoshu = 65'b11010110000110110101110111111110100111111001101111010000000000000;
			7'b1100000:  xiaoshu = 65'b11010111010001001111110011001010110101101001110101101000000000000;
			7'b1100001:  xiaoshu = 65'b11011000011100000011100101001100011011011011001100110000000000000;
			7'b1100010:  xiaoshu = 65'b11011001100111010001010111000010011110001010111111011000000000000;
			7'b1100011:  xiaoshu = 65'b11011010110010111001010001101111001010101100100111010000000000000;
			7'b1100100:  xiaoshu = 65'b11011011111110111011011110010111110110101111001000111000000000000;
			7'b1100101:  xiaoshu = 65'b11011101001011011000000110000101000010000011001001010000000000000;
			7'b1100110:  xiaoshu = 65'b11011110011000001111010010000010010111100000111010010000000000000;
			7'b1100111:  xiaoshu = 65'b11011111100101100001001011011110101110001111000001001000000000000;
			7'b1101000:  xiaoshu = 65'b11100000110011001101111011101100001010101001010011100000000000000;
			7'b1101001:  xiaoshu = 65'b11100010000001010101101011111111111111101000001111010000000000000;
			7'b1101010:  xiaoshu = 65'b11100011001111111000100101110010101111101000101001011000000000000;
			7'b1101011:  xiaoshu = 65'b11100100011110110110110010100000001101110011110110101000000000000;
			7'b1101100:  xiaoshu = 65'b11100101101110010000011011100111011111001000001101001000000000000;
			7'b1101101:  xiaoshu = 65'b11100110111110000101101010101010111011100001111111010000000000000;
			7'b1101110:  xiaoshu = 65'b11101000001110010110101001010000001111000100101111100000000000000;
			7'b1101111:  xiaoshu = 65'b11101001011111000011100001000000011011000100111110010000000000000;
			7'b1110000:  xiaoshu = 65'b11101010110000001100011011100111110111010010010000111000000000000;
			7'b1110001:  xiaoshu = 65'b11101100000001110001100010110110010011000001110011000000000000000;
			7'b1110010:  xiaoshu = 65'b11101101010011110011000000011110110110011001010000101000000000000;
			7'b1110011:  xiaoshu = 65'b11101110100110010000111110011000000011011010001100000000000000000;
			7'b1110100:  xiaoshu = 65'b11101111111001001011100110011011110111001101101011111000000000000;
			7'b1110101:  xiaoshu = 65'b11110001001100100011000010100111101011010000100101001000000000000;
			7'b1110110:  xiaoshu = 65'b11110010100000010111011100111100010110011111111110110000000000000;
			7'b1110111:  xiaoshu = 65'b11110011110100101000111111011110001110100110010000011000000000000;
			7'b1111000:  xiaoshu = 65'b11110101001001010111110100010101001001001000011011010000000000000;
			7'b1111001:  xiaoshu = 65'b11110110011110100100000101101100011100110011111110001000000000000;
			7'b1111010:  xiaoshu = 65'b11110111110100001101111101110011000010101101000100111000000000000;
			7'b1111011:  xiaoshu = 65'b11111001001010010101100110111011010111011101010010111000000000000;
			7'b1111100:  xiaoshu = 65'b11111010100000111011001011011011011100100010101000000000000000000;
			7'b1111101:  xiaoshu = 65'b11111011110111111110110101101100111001011111000010100000000000000;
			7'b1111110:  xiaoshu = 65'b11111101001111100000110000001100111101001000011011000000000000000;
			7'b1111111:  xiaoshu = 65'b11111110100111100001000101011100011110111000111110001000000000000;
			default : xiaoshu = 65'b0;
        endcase
    end
    else if(y_pre[15] == 1'b1)begin
        xiaoshu = 65'b00000000000000000000000000000000000000000000000000000000010000000;
    end    
end


endmodule
// END OF MODULE

2. Verilog实现log2(m)(m包含小数)

最终,还要对求和的结果进行求log2,整数部分继续延续上述方法采用移位,小数部分使用查找表。

        对p_sum[71:7]进行判断,如果大于1,则进行右移,记录下右移的次数,即为log2的整数部分结果,根据上面2^n计算的原理,整数部分实际是对小数部分移动的结果,所以当p_sum[71:7] = 0时,p_sum[6:0] 就是小数部分对应的查找表

部分代码如下所示:

always @(posedge clk or negedge rst_n) begin  
    if(!rst_n) begin
        p_log <= 0;
        p_log_zheng <= 0;
    end
    else if(p_log_valid) begin
        if(p_sum[71:7] > 'b1) begin
            p_log[14:7] <= p_log[14:7] + 1;
            p_sum <= p_sum >> 1;
        end
        else if(p_sum[71:7] == 'b1) begin
//            p_log[6:0] <= p_sum[6:0];
            p_sum <= p_sum;
            p_log_zheng <= 1;
        end
    end
end
//找到log后的小数部分
always@(*) begin
	if(p_log_zheng == 1)begin
		case(p_sum[6:0])
			7'b0000000:   p_log[6:0] = 7'b0000000     ;
			7'b0000001:   p_log[6:0] = 7'b0000010     ;
			7'b0000010:   p_log[6:0] = 7'b0000011     ;
			7'b0000011:   p_log[6:0] = 7'b0000101     ;
			7'b0000100:   p_log[6:0] = 7'b0000110     ;
			7'b0000101:   p_log[6:0] = 7'b0001000     ;
			7'b0000110:   p_log[6:0] = 7'b0001001     ;
			7'b0000111:   p_log[6:0] = 7'b0001010     ;
			7'b0001000:   p_log[6:0] = 7'b0001100     ;
			7'b0001001:   p_log[6:0] = 7'b0001101     ;
			7'b0001010:   p_log[6:0] = 7'b0001110     ;
			7'b0001011:   p_log[6:0] = 7'b0010000     ;
			7'b0001100:   p_log[6:0] = 7'b0010001     ;
			7'b0001101:   p_log[6:0] = 7'b0010010     ;
			7'b0001110:   p_log[6:0] = 7'b0010100     ;
			7'b0001111:   p_log[6:0] = 7'b0010101     ;
			7'b0010000:   p_log[6:0] = 7'b0010110     ;
			7'b0010001:   p_log[6:0] = 7'b0011000     ;
			7'b0010010:   p_log[6:0] = 7'b0011001     ;
			7'b0010011:   p_log[6:0] = 7'b0011010     ;
			7'b0010100:   p_log[6:0] = 7'b0011011     ;
			7'b0010101:   p_log[6:0] = 7'b0011101     ;
			7'b0010110:   p_log[6:0] = 7'b0011110     ;
			7'b0010111:   p_log[6:0] = 7'b0011111     ;
			7'b0011000:   p_log[6:0] = 7'b0100000     ;
			7'b0011001:   p_log[6:0] = 7'b0100001     ;
			7'b0011010:   p_log[6:0] = 7'b0100011     ;
			7'b0011011:   p_log[6:0] = 7'b0100100     ;
			7'b0011100:   p_log[6:0] = 7'b0100101     ;
			7'b0011101:   p_log[6:0] = 7'b0100110     ;
			7'b0011110:   p_log[6:0] = 7'b0100111     ;
			7'b0011111:   p_log[6:0] = 7'b0101001     ;
			7'b0100000:   p_log[6:0] = 7'b0101010     ;
			7'b0100001:   p_log[6:0] = 7'b0101011     ;
			7'b0100010:   p_log[6:0] = 7'b0101100     ;
			7'b0100011:   p_log[6:0] = 7'b0101101     ;
			7'b0100100:   p_log[6:0] = 7'b0101110     ;
			7'b0100101:   p_log[6:0] = 7'b0101111     ;
			7'b0100110:   p_log[6:0] = 7'b0110001     ;
			7'b0100111:   p_log[6:0] = 7'b0110010     ;
			7'b0101000:   p_log[6:0] = 7'b0110011     ;
			7'b0101001:   p_log[6:0] = 7'b0110100     ;
			7'b0101010:   p_log[6:0] = 7'b0110101     ;
			7'b0101011:   p_log[6:0] = 7'b0110110     ;
			7'b0101100:   p_log[6:0] = 7'b0110111     ;
			7'b0101101:   p_log[6:0] = 7'b0111000     ;
			7'b0101110:   p_log[6:0] = 7'b0111001     ;
			7'b0101111:   p_log[6:0] = 7'b0111010     ;
			7'b0110000:   p_log[6:0] = 7'b0111011     ;
			7'b0110001:   p_log[6:0] = 7'b0111100     ;
			7'b0110010:   p_log[6:0] = 7'b0111101     ;
			7'b0110011:   p_log[6:0] = 7'b0111110     ;
			7'b0110100:   p_log[6:0] = 7'b0111111     ;
			7'b0110101:   p_log[6:0] = 7'b1000000     ;
			7'b0110110:   p_log[6:0] = 7'b1000001     ;
			7'b0110111:   p_log[6:0] = 7'b1000011     ;
			7'b0111000:   p_log[6:0] = 7'b1000100     ;
			7'b0111001:   p_log[6:0] = 7'b1000101     ;
			7'b0111010:   p_log[6:0] = 7'b1000110     ;
			7'b0111011:   p_log[6:0] = 7'b1000110     ;
			7'b0111100:   p_log[6:0] = 7'b1000111     ;
			7'b0111101:   p_log[6:0] = 7'b1001000     ;
			7'b0111110:   p_log[6:0] = 7'b1001001     ;
			7'b0111111:   p_log[6:0] = 7'b1001010     ;
			7'b1000000:   p_log[6:0] = 7'b1001011     ;
			7'b1000001:   p_log[6:0] = 7'b1001100     ;
			7'b1000010:   p_log[6:0] = 7'b1001101     ;
			7'b1000011:   p_log[6:0] = 7'b1001110     ;
			7'b1000100:   p_log[6:0] = 7'b1001111     ;
			7'b1000101:   p_log[6:0] = 7'b1010000     ;
			7'b1000110:   p_log[6:0] = 7'b1010001     ;
			7'b1000111:   p_log[6:0] = 7'b1010010     ;
			7'b1001000:   p_log[6:0] = 7'b1010011     ;
			7'b1001001:   p_log[6:0] = 7'b1010100     ;
			7'b1001010:   p_log[6:0] = 7'b1010101     ;
			7'b1001011:   p_log[6:0] = 7'b1010110     ;
			7'b1001100:   p_log[6:0] = 7'b1010110     ;
			7'b1001101:   p_log[6:0] = 7'b1010111     ;
			7'b1001110:   p_log[6:0] = 7'b1011000     ;
			7'b1001111:   p_log[6:0] = 7'b1011001     ;
			7'b1010000:   p_log[6:0] = 7'b1011010     ;
			7'b1010001:   p_log[6:0] = 7'b1011011     ;
			7'b1010010:   p_log[6:0] = 7'b1011100     ;
			7'b1010011:   p_log[6:0] = 7'b1011101     ;
			7'b1010100:   p_log[6:0] = 7'b1011110     ;
			7'b1010101:   p_log[6:0] = 7'b1011110     ;
			7'b1010110:   p_log[6:0] = 7'b1011111     ;
			7'b1010111:   p_log[6:0] = 7'b1100000     ;
			7'b1011000:   p_log[6:0] = 7'b1100001     ;
			7'b1011001:   p_log[6:0] = 7'b1100010     ;
			7'b1011010:   p_log[6:0] = 7'b1100011     ;
			7'b1011011:   p_log[6:0] = 7'b1100100     ;
			7'b1011100:   p_log[6:0] = 7'b1100100     ;
			7'b1011101:   p_log[6:0] = 7'b1100101     ;
			7'b1011110:   p_log[6:0] = 7'b1100110     ;
			7'b1011111:   p_log[6:0] = 7'b1100111     ;
			7'b1100000:   p_log[6:0] = 7'b1101000     ;
			7'b1100001:   p_log[6:0] = 7'b1101000     ;
			7'b1100010:   p_log[6:0] = 7'b1101001     ;
			7'b1100011:   p_log[6:0] = 7'b1101010     ;
			7'b1100100:   p_log[6:0] = 7'b1101011     ;
			7'b1100101:   p_log[6:0] = 7'b1101100     ;
			7'b1100110:   p_log[6:0] = 7'b1101101     ;
			7'b1100111:   p_log[6:0] = 7'b1101101     ;
			7'b1101000:   p_log[6:0] = 7'b1101110     ;
			7'b1101001:   p_log[6:0] = 7'b1101111     ;
			7'b1101010:   p_log[6:0] = 7'b1110000     ;
			7'b1101011:   p_log[6:0] = 7'b1110000     ;
			7'b1101100:   p_log[6:0] = 7'b1110001     ;
			7'b1101101:   p_log[6:0] = 7'b1110010     ;
			7'b1101110:   p_log[6:0] = 7'b1110011     ;
			7'b1101111:   p_log[6:0] = 7'b1110100     ;
			7'b1110000:   p_log[6:0] = 7'b1110100     ;
			7'b1110001:   p_log[6:0] = 7'b1110101     ;
			7'b1110010:   p_log[6:0] = 7'b1110110     ;
			7'b1110011:   p_log[6:0] = 7'b1110111     ;
			7'b1110100:   p_log[6:0] = 7'b1110111     ;
			7'b1110101:   p_log[6:0] = 7'b1111000     ;
			7'b1110110:   p_log[6:0] = 7'b1111001     ;
			7'b1110111:   p_log[6:0] = 7'b1111010     ;
			7'b1111000:   p_log[6:0] = 7'b1111010     ;
			7'b1111001:   p_log[6:0] = 7'b1111011     ;
			7'b1111010:   p_log[6:0] = 7'b1111100     ;
			7'b1111011:   p_log[6:0] = 7'b1111101     ;
			7'b1111100:   p_log[6:0] = 7'b1111101     ;
			7'b1111101:   p_log[6:0] = 7'b1111110     ;
			7'b1111110:   p_log[6:0] = 7'b1111111     ;
			7'b1111111:   p_log[6:0] = 7'b1111111     ;
			default : p_log[6:0] = 7'b0000000     ;
        endcase
    end
end

四、功能验证

1. 验证2^n计算的verilog代码误差

2. 验证log2计算的verilog代码误差 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值