网上一个能用的也没有,自己写一个把。

1.计算原理:

 整数部分

网上找到了一个c语言的计算方法如下:

int flog2(float x) {
return ((unsigned&)x>>23&255)-127;
}

用matlab测试了一下,得到的结果是一个log2的整数部分

小数部分

发现小数部分其实都是  1+一个小数  ,然后这个小数值其实可通过最高位是0.5 然后0.25,0.125.......这样累加得到。

比如:

100 0000 0000 0000 0000 0000 ->  1+0.5

110 0000 0000 0000 0000 0000 ->  1+0.5+0.25

这样我只要算出这个然后查表就好了。由于对精度要求不高,只取六位数字进行查表,matlab获取表值的仿真程序如下:

for i = :
temp = i/;
templog = log2(+temp);
fprintf('the value of log is%6.2f\n',templog)
end

 至此,小数部分和整数部分就都得到了。 

2.开始写Verilog:

电路结构:

 Verilog代码

其中用了3个IP核,包括ROM、定点转浮点单元、浮点加法单元,不做详述

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 10:20:43 03/29/2019
// Design Name:
// Module Name: log2fun
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module log2fun(
input clk,
input dataclk,
input rst_n,
input data_enable,
input [:] log_input,
output [:] log_output
); reg [:] exp_data;
reg [:] fix_data;
reg fix_enable;
wire [:] float_exp;
wire float_enable; wire [:] point_float;
reg [:] point_addr;
wire [:] point_addwire; wire result_enable;
//reg [31:0] Mem [3:0];
reg [:] fifo_data1;
reg [:] fifo_data2; reg sign_flag; always @(posedge clk or posedge rst_n)
begin
if(!rst_n) begin
exp_data <= 'd127;
sign_flag <= 'd0;
end
else begin
//fix_data <= log_input[30:23] > exp_data ? log_input[30:23]-exp_data:exp_data-log_input[30:23];
fix_data <= log_input[:] - exp_data;
point_addr <= log_input[:];
end
end always @(posedge dataclk or posedge rst_n)
begin
if(!rst_n) begin
fifo_data2 <= 'd0;
fifo_data1 <= 'd1;
end
else begin
if(data_enable)begin
//Mem[fifo_addr1] <= point_float;
//point_floatDelay <= Mem[fifo_addr2];
fifo_data1 <= point_float;
fifo_data2 <= fifo_data1;
end
end
end assign point_addwire = point_addr; int2float INTCONVERT(
.aclk(clk),
.s_axis_a_tvalid(data_enable),
.m_axis_result_tvalid(float_enable),
.s_axis_a_tdata(fix_data),
.m_axis_result_tdata(float_exp)
); log_sheet LOG_DATA (
.clka (clk),
.addra(point_addwire),
.douta(point_float)
); float_add ADD_FLOAT (
.aclk(clk),
.s_axis_a_tvalid(float_enable),
.s_axis_b_tvalid(float_enable),
//.s_axis_a_tready(s_axis_a_tready),
//.s_axis_b_tready(s_axis_b_tready),
.m_axis_result_tvalid(result_enable),
.s_axis_a_tdata(float_exp),
.s_axis_b_tdata(fifo_data1),
.m_axis_result_tdata(log_output)
);
endmodule

testbench

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 10:39:38 03/29/2019
// Design Name: log2fun
// Module Name: C:/Users/ray5w/OneDrive/benchmark/code/verylog_vad/verylog_vad/log2fun_tb.v
// Project Name: verylog_vad
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: log2fun
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////// module log2fun_tb; // Outputs
reg clk;
reg dataclk;
reg rst;
reg data_enable;
reg [:] din;
wire [:] dout; // Instantiate the Unit Under Test (UUT)
log2fun uut (
.clk(clk),
.dataclk(dataclk),
.rst_n(rst),
.log_input(din),
.data_enable(data_enable),
.log_output(dout)
); initial begin
data_enable <= 'b0;
rst <= 'b1;
din <= 'b0;
#
rst <= 'b0; #
rst <= 'b1;
data_enable <= 'b1; din <= 'h3d23d70a; //0.4
#
din <= 'h3e800000; //0.25
#
din <= 'h3d23d70a; //0.4
#
din <= 'h3e800000; //0.25
#
din <= 'h3d23d70a; //0.4
#
din <= 'h3e800000; //0.25
#
din <= 'h3d23d70a; //0.4
#
din <= 'h3e800000; //0.25
#
din <= 'h3d23d70a; //0.4
#
din <= 'h3e800000; //0.25
#
din <= 'h3d23d70a; //0.4
#
din <= 'h3e800000; //0.25
#
din <= 'h3d23d70a; //0.4
#
din <= 'h3e800000; //0.25
#
din <= 'h3d23d70a; //0.4
#
din <= 'h3e800000; //0.25
#
din <= 'h3d23d70a; //0.4
#
din <= 'h3e800000; //0.25
// Add stimulus here
end initial begin
clk = ;
forever
# clk = !clk;
end initial begin
dataclk = ;
#
dataclk = ;
forever
# dataclk = !dataclk;
end
endmodule

一个c代码方便进行浮点核定点转换的,用来看看最终结果是不是对的:

#include <stdio.h>
int float2int(float data);
int flog2(float x);
float int2float(int data);
float datasheet[] = {0.00, 0.04, 0.09, 0.13, 0.17, 0.21, 0.25, 0.29, 0.32, 0.36, 0.39, 0.43, 0.46, 0.49, 0.52, 0.55, 0.58, 0.61, 0.64, 0.67, 0.70, 0.73, 0.75, 0.78, 0.81, 0.83, 0.86, 0.88, 0.91, 0.93, 0.95, 0.98 };
int main(void) {
int i ;
/*for(i=0;i<32;i++){
printf("%x,\n",float2int(datasheet[i]));
}*/
printf("%d,\n",flog2(0.04));
printf("%d,\n",flog2(0.25)); printf("%f,\n",int2float(0x40a00000));
return ;
}
float int2float(int data){
float *idata ;
int idata2 = data;
idata =(float*)&idata2;
return *idata;
} int float2int(float data){
int *idata ;
float idata2 = data;
idata =(int*)&idata2;
return *idata;
} int flog2(float x){
return ((unsigned&)x>>&)-;
}

仅用作思路参考,我是Verilog菜鸟。

下面是实验结果:

matlab验证一下,(3d23d70a就是0.04,输出的e095c28f是-4.68)

有一定误差,要提高精度只要查表那一步增大rom多存点就好了吧

Verilog写一个对数计算模块Log2(x)的更多相关文章

  1. 是否有必要学习使用纯Verilog写一个SDRAM控制器

    在做这个SDRAM控制器之前,博主有一个疑问,对于学生来说,是否有必要学习用纯Verilog写一个SDRAM控制器?因为目前X家和A家都有了DDR IP Core,对于要实现一个应用可以直接调用IP ...

  2. 给出两个单词word1和word2,写一个函数计算出将word1 转换为word2的最少操作次数。

    问题: 给出两个单词word1和word2,写一个函数计算出将word1 转换为word2的最少操作次数. 你总共三种操作方法: 1.插入一个字符 2.删除一个字符 3.替换一个字符 格式: 输入行输 ...

  3. 我为什么要再给lua写一个json模块

    最近要给自己编写的服务器加上json解析模块.根据我当前的项目,可以预测服务器中使用json的地方: 通信.由于与客户端通信使用google protocolbuffer,仅在与SDK通信中使用jso ...

  4. 有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果(转)

    引用 前几天在网上看到一个淘宝的面试题:有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果.一:分析题目 从题中可以看到“很大的List”以及“ ...

  5. 写一个MySql存储过程实现房贷等额本息还款计算(另外附javascript代码)

    写一个MySql存储过程实现房贷等额本息还款计算 MySql存储过程代码如下: DROP procedure IF EXISTS `calc_equal_interest_proc`; DELIMIT ...

  6. 动手写一个简单版的谷歌TPU

    谷歌TPU是一个设计良好的矩阵计算加速单元,可以很好的加速神经网络的计算.本系列文章将利用公开的TPU V1(后简称TPU)相关资料,对其进行一定的简化.推测和修改,来实际编写一个简单版本的谷歌TPU ...

  7. 使用Verilog搭建一个单周期CPU

    使用Verilog搭建一个单周期CPU 搭建篇 总体结构 其实跟使用logisim搭建CPU基本一致,甚至更简单,因为完全可以照着logisim的电路图来写,各个模块和模块间的连接在logisim中非 ...

  8. 【模块化编程】理解requireJS-实现一个简单的模块加载器

    在前文中我们不止一次强调过模块化编程的重要性,以及其可以解决的问题: ① 解决单文件变量命名冲突问题 ② 解决前端多人协作问题 ③ 解决文件依赖问题 ④ 按需加载(这个说法其实很假了) ⑤ ..... ...

  9. JavaScript写一个连连看的游戏

    天天看到别人玩连连看, 表示没有认真玩过, 不就把两个一样的图片连接在一起么, 我自己写一个都可以呢. 使用Javascript写了一个, 托管到github, 在线DEMO地址查看:打开 最终的效果 ...

随机推荐

  1. INSERT ... ON DUPLICATE KEY UPDATE Syntax 专题

    ON DUPLICATE KEY UPDATE :不用用于批量,除 insert into t1  select * from t2 on duplicated key update k1=v1,k2 ...

  2. 1 tcp/ip协议

    该协议是一个协议族,并是说具体某个协议下图中的协议都属于tcp/ip协议.他是用来规范互联网中电脑间数据传输的. 该协议可以分为4层或者7层 4层,实际层数: 链路层 网络层 传输层 应用层 7层,理 ...

  3. uva 11892 - ENimEN(推理)

    题目链接:uva 11892 - ENimEN 题目大意:给定n堆石子的个数,两人轮流选择石子堆取石子,直到不能取为失败,附加条件,假设前一次操作,即队手的操作,没有将选中石子堆中的石子取完,那么当前 ...

  4. Andrdoid适当的执行行为拦截的应用----从底部C截距

    前一个概要文章称这项研究我的一些主要细节.这里就不在说.但还需要指出的是.关于三大感谢上帝愿意分享知识(在我看来,人们懂得分享和慎重考虑之神,奥地利不一定是技术牛~~) 第一篇:http://blog ...

  5. 初步STL该容器适配器

    容器适配器 特点 容器一定的顺序来实现(让现有的以集装箱堆放/式工作) 分类 1) stack: 头文件 <stack> • 栈 -- 后进先出 2) queue: 头文件 <que ...

  6. AngularJS radio绑定与取值

    <div id="commentModal" class="modal fade" role="dialog" ng-app=&quo ...

  7. DELPHI下多线程编程的几个思维误区(QDAC)

    有几个网友私下问我一些有关线程的事情.过节写个东西上来大家交流. 思维误区1,自己新建的THREAD是线程,自己的主程序不是线程. 很多人在多线程编程没有把主线程也当作线程.其实主线程也是线程.看起来 ...

  8. mysql 在不删除数据的时,同时重新更新主键id

    1,删除原有主键: ALTER TABLE `table_name` DROP `id`; 2,添加新主键字段:ALTER TABLE `table_name` ADD `id` MEDIUMINT( ...

  9. Hive-分组之后取前n个

    1. 统计国家每个省份出现次数最高的5个城市的名称 直观思维来考虑: 把 数据组织成: 国家     省份     出现次数(倒序)  城市 row_number() 根据partition by 生 ...

  10. C#连接oracle 数据库查询时输入中文查询不出来,用plsql就可以

    查询语句为:select * from Per where khmc like '%李%',其实是字符集的问题. 解决方案:在连接字符串加一个“Unicode=True;”