Verilog写一个对数计算模块Log2(x)
网上一个能用的也没有,自己写一个把。
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)的更多相关文章
- 是否有必要学习使用纯Verilog写一个SDRAM控制器
在做这个SDRAM控制器之前,博主有一个疑问,对于学生来说,是否有必要学习用纯Verilog写一个SDRAM控制器?因为目前X家和A家都有了DDR IP Core,对于要实现一个应用可以直接调用IP ...
- 给出两个单词word1和word2,写一个函数计算出将word1 转换为word2的最少操作次数。
问题: 给出两个单词word1和word2,写一个函数计算出将word1 转换为word2的最少操作次数. 你总共三种操作方法: 1.插入一个字符 2.删除一个字符 3.替换一个字符 格式: 输入行输 ...
- 我为什么要再给lua写一个json模块
最近要给自己编写的服务器加上json解析模块.根据我当前的项目,可以预测服务器中使用json的地方: 通信.由于与客户端通信使用google protocolbuffer,仅在与SDK通信中使用jso ...
- 有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果(转)
引用 前几天在网上看到一个淘宝的面试题:有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果.一:分析题目 从题中可以看到“很大的List”以及“ ...
- 写一个MySql存储过程实现房贷等额本息还款计算(另外附javascript代码)
写一个MySql存储过程实现房贷等额本息还款计算 MySql存储过程代码如下: DROP procedure IF EXISTS `calc_equal_interest_proc`; DELIMIT ...
- 动手写一个简单版的谷歌TPU
谷歌TPU是一个设计良好的矩阵计算加速单元,可以很好的加速神经网络的计算.本系列文章将利用公开的TPU V1(后简称TPU)相关资料,对其进行一定的简化.推测和修改,来实际编写一个简单版本的谷歌TPU ...
- 使用Verilog搭建一个单周期CPU
使用Verilog搭建一个单周期CPU 搭建篇 总体结构 其实跟使用logisim搭建CPU基本一致,甚至更简单,因为完全可以照着logisim的电路图来写,各个模块和模块间的连接在logisim中非 ...
- 【模块化编程】理解requireJS-实现一个简单的模块加载器
在前文中我们不止一次强调过模块化编程的重要性,以及其可以解决的问题: ① 解决单文件变量命名冲突问题 ② 解决前端多人协作问题 ③ 解决文件依赖问题 ④ 按需加载(这个说法其实很假了) ⑤ ..... ...
- JavaScript写一个连连看的游戏
天天看到别人玩连连看, 表示没有认真玩过, 不就把两个一样的图片连接在一起么, 我自己写一个都可以呢. 使用Javascript写了一个, 托管到github, 在线DEMO地址查看:打开 最终的效果 ...
随机推荐
- 机器审核图片学习(2)安装pornDetector所用环境-python、scikit-learn、opencv
1.安装python 下载安装即可:最好是C盘 路径:https://www.python.org/ 将Python的安装路径加到path环境变量中,Python/Scripts加到path环境变量 ...
- 显示dll里的QWidget
1 新建库->C++库 2 命名(此处为mydll)并选择共享库--下一步--下一步 3 选择所需要的模块(有使用到的都选上)此处勾选前三项QtCore+QtGui+QtWidgets 4 完成 ...
- Java设计模式透析之 —— 单例(Singleton)
写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至像f ...
- Linux性能测试 KSysguard工具
KDE System Guard (KSysguard)是KDE的任务管理和性能监控工具.它采用client/server架构,可以监控本机也可以监控远端主机. KDE System Guard默认的 ...
- jquery.cookie.js用法详解
创建一个会话cookie: $.cookie(‘cookieName’,'cookieValue’); 注:当没有指明cookie时间时,所创建的cookie有效期默认到用户浏览器关闭止,故被称为会话 ...
- Emgu-WPF学习使用 - 颜色映射
原文:Emgu-WPF学习使用 - 颜色映射 string sFile = ""; if (!String.IsNullOrEmpty(AppConstUtils.GDefault ...
- Stream转Byte数组
//获得当前文件目录 string rootPath = Directory.GetCurrentDirectory(); string path = rootPath + "Your Fi ...
- ASP .NET Views文件夹下面的文件找不到
习惯将页面和它对应的js,css文件放在一个文件夹下,将这些都放在Views文件夹下 运行的时候发现找不到js和css文件 因为在MVC中,是不建议直接去访问Views文件夹的我们建立的ASP ...
- 修改Hosts不生效的一个场景-web 专题
准备工作 1.在 QQ互联 申请成为开发者,并创建应用,得到APP ID 和 APP Key.2.了解QQ登录时的 网站应用接入流程.(必须看完看懂) 为了方便各位测试,直接把我自己申请的贡献出来:A ...
- WPF DataGrid的LoadingRow事件
<Window x:Class="DataGridExam.MainWindow" xmlns="http://schemas.microsoft.c ...