【FPGA开发】Verilog-数据截断实现四舍五入效果、模块化改造、对比Matlab验证,Modelsim覆盖率

目录

  • 实现目标
  • 直接截断低位
  • 考虑四舍五入
  • 模块化实现四舍五入功能
  • Matlab对比验证程序
  • Testbench编写
  • Modelsim查看验证覆盖率(简易)

实现目标

由于FPGA以定点数运算为主,随着数字信号处理的流程增加,数据位宽会逐渐变大,有时,考虑到资源量问题,会对定点数进行截断处理。

对于定点数来说,低位表示小数部分,截断低位,意味着抛弃小数,也就是损失精度。

假设一乘法器的运算结果是32-bits,后续要对该结果进行滤波处理,由于32-bits过大,需要对齐进行截断处理。

直接截断低位

直接截断低位是最简单的办法,相当于FLOOR()函数。

考虑四舍五入

以32-bits截断成17-bits为例。
在这里插入图片描述

想保留的是[31:15]这部分数据,如果直接截断,直接舍弃[14:0]即可,也就是说,把[14:0]这部分看成了小数。

所以在理解定点数的四舍五入时,把[31:15]看做整数,把[14:0]看做小数,小数部分大于等于0.5,就进位1;小数部分不超过0.5,就舍弃。

得到下述代码:

module fixed_point_rounding (input wire [31:0] in_data,  // 假设输入是 32位定点数,小数点在第 15 位后output reg [17:0] out_data   // 输出是 17 位整数
);always @(*) begin// 判断要舍弃部分的最高位if (in_data[14]) begin// 如果该位为 1,向前进位out_data = in_data[31:15] + 1;end else begin// 如果该位为 0,直接舍弃out_data = in_data[31:15];end
endendmodule

再次基础上,考虑正数和负数在四舍五入时的区别。

1.3 四舍五入成 1
1.6 四舍五入成 2
-1.3 四舍五入成 -1
-1.6 四舍五入成 -2

正数向0的方向(数值变小的方向)舍,向数值变大的方向 入。
负数向0的方向(数值变大的方向)舍,向数值变小的方向 入。

这里的实现方法有很多,可以参考Verilog对数据进行四舍五入(round)与饱和(saturation)截位

这里再补充一种写法:

 assign buf_data = in_data[31] ? in_data + 15'b011_1111_1111_1111 : in_data + 15'b100_0000_0000_0000 ;assign out_data = buf_data[31:15];

考虑正数情况,把要截断的尾数看成小数,要截断15位, .100_0000_0000_0000 就是0.5,比这个大,就应该进位,所以正数情况要加 15’b100_0000_0000_0000,这样就能保证大于等于0.5的情况都能进位上去。

考虑负数情况,同样把要截断的尾数看成小数,要截断15位,.100_0000_0000_0000也是0.5,不过要注意的是,对于负数的补码来说,符号位的权值是负数((10.10) = (-2+0.5=-1.5)),对于负数来说,-1.5四舍五入后是要变成-2的,如果-1.5的小数位要是进位给整数位,会变成-1,这与实际不符合!所以,要保证.100_0000_0000_0000正好不产生进位,也就是要加15’b011_1111_1111_1111。

模块化实现四舍五入功能

module round_module #(parameter   P_PRE_DATA_WIDTH  = 32 , // 截断前数据位宽P_POST_DATA_WIDTH = 18   // 截断后数据位宽
)(input   [P_PRE_DATA_WIDTH - 1  : 0] i_data      ,  // 输入数据output  [P_POST_DATA_WIDTH - 1 : 0] o_data         // 输出数据
);wire [P_PRE_DATA_WIDTH - 1 : 0] buf_data;//正确的四舍五入操作
assign buf_data = i_data[P_PRE_DATA_WIDTH - 1] ? (i_data +  {{1'b0},{(P_PRE_DATA_WIDTH - P_POST_DATA_WIDTH -1){1'b1}}}) : &i_data[P_PRE_DATA_WIDTH-2:P_PRE_DATA_WIDTH - P_POST_DATA_WIDTH] ? i_data : (i_data + {{1'b1},{(P_PRE_DATA_WIDTH - P_POST_DATA_WIDTH -1){1'b0}}}); //最好补写成1<<14格式,因为涉及补高位做加法,可能会出现错误  // 截断操作
assign o_data = buf_data[P_PRE_DATA_WIDTH - 1 : P_PRE_DATA_WIDTH - P_POST_DATA_WIDTH];endmodule

Matlab对比验证程序

主函数:

clc;clear;close all;% 参数设置
P_PRE_DATA_WIDTH = 32;  % 输入数据位宽
P_POST_DATA_WIDTH = 18; % 输出数据位宽% 生成随机测试数据
num_tests = 10000-3; % 测试用例数量min = -2^(P_PRE_DATA_WIDTH-1);max = 2^(P_PRE_DATA_WIDTH-1)-1;num_rand = fix(min + (max - min)*rand(1,num_tests)) ;num_rand = fix([num_rand min max 0]);fileID = fopen('data.txt', 'w');
for i=1:num_tests+3num_rand_comp(i,:) = twos_complement(num_rand(i),P_PRE_DATA_WIDTH);% 将二进制字符串写入文件fprintf(fileID, '%s\n', num_rand_comp(i,:));
endnum_q = num_rand / 2^(P_PRE_DATA_WIDTH - P_POST_DATA_WIDTH);ref = round(num_q); %标准的数值decimal_data = read_binary_twos_complement("output_data.txt", 18);decimal_data = decimal_data.';count = 0;
for i=1:num_testsif(ref(i) == decimal_data(i))count = count + 1;end
enddisp(['数据准确率为:',num2str(count/num_tests*100),'%']);

twos_complement函数:

function binary_str = twos_complement(decimal_num, bit_width)% 将十进制有符号数转换为补码形式的二进制字符串% decimal_num: 输入的十进制数% bit_width: 二进制位数% 检查输入是否为有符号数if decimal_num < 0% 负数:计算补码complement = 2^bit_width + decimal_num; % 补码 = 2^N + 负数binary_str = dec2bin(complement, bit_width);else% 正数:直接转换为二进制binary_str = dec2bin(decimal_num, bit_width);end
end

read_binary_twos_complement函数:

function decimal_data = read_binary_twos_complement(filename, bit_width)% 读取二进制补码文件并转换为十进制数% filename: 文件名% bit_width: 二进制位数% 打开文件并读取内容fileID = fopen(filename, 'r');if fileID == -1error('无法打开文件');end% 读取文件内容binary_data = textscan(fileID, '%s', 'Delimiter', '\n');fclose(fileID);% 初始化输出数组num_values = length(binary_data{1});decimal_data = zeros(num_values, 1);% 遍历每一行二进制数据for i = 1:num_valuesbinary_str = binary_data{1}{i}; % 获取二进制字符串decimal_data(i) = binary_twos_complement_to_decimal(binary_str, bit_width);endend

binary_twos_complement_to_decimal函数:

function decimal_value = binary_twos_complement_to_decimal(binary_str, bit_width)% 将二进制补码字符串转换为十进制数% binary_str: 二进制字符串% bit_width: 二进制位数% 检查二进制字符串长度if length(binary_str) ~= bit_widtherror('二进制字符串长度与位宽不匹配');end% 判断是否为负数(最高位为1if binary_str(1) == '1'% 负数:计算补码值decimal_value = - (2^bit_width - bin2dec(binary_str));else% 正数:直接转换decimal_value = bin2dec(binary_str);end
end

Testbench编写

`timescale 1ns/1psmodule tb_test();reg 	[31:0] in_data	;
wire  	[17:0] out_data ;reg [31:0] test_data [0:10000-1] ;initial begin$readmemb("data.txt",test_data);
end// initial begin
// 	in_data = 'd0;
// 	#100
// 	in_data = 32'b0111_0000_1111_1111_1110_0000_0000_0000;
// 	#100
// 	in_data = 32'b1000_1111_0000_0000_0010_0000_0000_0000;// 	#100
// 	in_data = 32'b0111_0000_1111_1111_1110_0110_0110_0110;
// 	#100
// 	in_data = 32'b1000_1111_0000_0000_0001_1001_1001_1010;// 	#100
// 	in_data = 32'b0111_0000_1111_1111_1101_1001_1001_1010;
// 	#100
// 	in_data = 32'b1000_1111_0000_0000_0010_0110_0110_0110;
// 	#100
// 	in_data = 32'b0111_1111_1111_1111_1111_1111_1111_1111;
// 	#100
// 	in_data = 32'd2147483648;
// end// 输入测试数据
integer i;
integer file_handle;// 初始化:打开文件
initial beginfile_handle = $fopen("output_data.txt", "w");if (!file_handle) begin$display("can not open file!");$finish;end
endinitial beginfor (i = 0; i < 10000; i = i + 1) beginin_data = test_data[i];#50;$fwrite(file_handle,"%b\n",out_data);end$fclose(file_handle);// 打印完成信息$display("data already write in :  output_data.txt file!");// 结束仿真$finish;
endround_module #(.P_PRE_DATA_WIDTH  (32	) ,.P_POST_DATA_WIDTH (18	)
)round_module_u0(.i_data      (in_data	),  // .o_data      (out_data	)   // 
);endmodule

Matlab对比数据,随机产生9997个数据,并添加最大值、最小值、0三个特殊边界值,验证程序,得到该模块的准确率为100%

在这里插入图片描述

Modelsim查看验证覆盖率(简易)

主要参考文章:
modelsim中代码覆盖率使用详解

代码覆盖率,英文Code Coverage,包含statement语句、branch分支、condition条件、expression表达、toggle信号翻转,fsm有限状态机等多种覆盖情况。

首先,准备好两个文件:testbench文件和模块文件
在这里插入图片描述
打开modelsim,新建工程。在这里插入图片描述
选择好路径后,在弹出的框中,把已经有的两个文件添进来
在这里插入图片描述
在这里插入图片描述

在Project窗口下,如果相对文件进行代码覆盖率分析,需要配置。这里的两个文件我都想分析,那就一个个来,先配置tb_test.v文件。

选中tb_test.v,右键,compile,compile properties
在这里插入图片描述

在弹出的窗口中,选择Coverage,全选后点击ok。同理,把round_module.v也重复上述操作。
在这里插入图片描述
都配置完后,进行编译在这里插入图片描述,编译通过后,会有绿色对钩出现,没出现就是代码有逻辑错误,需要回去找。下图就是编译通过。

在这里插入图片描述

编译通过后,准备开始放着,点击仿真按钮在这里插入图片描述
选择work中的tb_test,点击Others选项卡
在这里插入图片描述

勾选Enable code coverage,点击ok

在这里插入图片描述
点击ok后,modelsim的布局会kuku变,这是正常的,因为要添加很多分析的窗口。

这是需要配合Matlab进行验证。

在读取testbench输出数据的文件前,打一个断点,让matlba先生成一个输入数据的txt文件。
在这里插入图片描述
图中的data.txt就是输入数据。
在这里插入图片描述

有个这个data.txt后,可以在modelsim中restart一下在这里插入图片描述
然后再run-all在这里插入图片描述

点完后,选择否,不退出modelsim。
在这里插入图片描述
此时代码覆盖率信息就分析好了,界面的大概布局如下:

在这里插入图片描述

下面分别看看每个窗口里都有啥。首先是Files选项卡

在这里插入图片描述
拖动横向条可以看到,Stmt是Statement缩写,这里给出了语句覆盖率的的命中率,和分支Branch覆盖率。
在这里插入图片描述
analysis选项卡
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

【Bug记录】:在分析完代码覆盖率后,如果编辑了文本编码格式,utf-8这种,会报错。
Numeric coverage display disabled
尚未解决,先编辑文本编码格式,再分析代码覆盖率就没有错。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/29770.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

100天精通Python(爬虫篇)——第115天:爬虫在线小工具_Curl转python爬虫代码工具(快速构建初始爬虫代码)

文章目录 一、curl是什么&#xff1f;二、爬虫在线小工具&#xff08;牛逼puls&#xff09;三、实战操作 一、curl是什么&#xff1f; 基本概念&#xff1a;curl 支持多种协议&#xff0c;如 HTTP、HTTPS、FTP、SFTP 等&#xff0c;可用于从服务器获取数据或向服务器发送数据&a…

2025年渗透测试面试题总结-字某某动-安全研究实习生(二面)(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 字某某动-安全研究实习生&#xff08;二面&#xff09; 1. 护网行动中的核心工作 2. 防护层级选择&…

如何记录日常笔记

如何使用Obsidian来记录日常的笔记吗&#xff1f;比如会议记录、读书笔记。 我认为&#xff0c;首先需要做好的就是建立一个单独的分类&#xff0c;比如设置会议记录的文件夹、读书笔记的文件夹&#xff0c;这样各个笔记相互不干扰。 而做日常记录&#xff0c;和我们进行卡…

软件信息安全性测试流程有哪些?专业软件测评服务机构分享

在数字化时代&#xff0c;软件信息安全性测试的重要性愈发凸显。尤其是对于企业来说&#xff0c;确保软件的安全性不仅是维护用户信任的关键&#xff0c;也是满足合规要求的必要条件。 软件信息安全性测试是指通过一系列系统化的测试手段&#xff0c;评估软件应用在受到攻击时…

UVC for USBCamera in Android

基于UVC 协议&#xff0c;完成USBCamera 开发 文章目录 一、目的&#xff1a;二、USBCamera 技术实现方案难点 三、误区&#xff1a;四、基础补充、资源参考架构图了解Camera相关专栏零散知识了解部分相机源码参考&#xff0c;学习API使用&#xff0c;梳理流程&#xff0c;偏应…

智慧社区解决方案介绍

1. 应用背景 智慧社区作为新经济时代的产物&#xff0c;利用互联网和物联网技术&#xff0c;改变了人们的生活方式&#xff0c;成为信息化、虚拟化新城市的重要组成部分。智慧社区的商业价值在于利用大数据技术对消费者进行细分&#xff0c;提供高附加值服务&#xff0c;预计零…

鸿蒙生态日日新,鸿蒙原生版支付宝下载量突破230万

鸿蒙生态日日新PLOG&#xff1a;鸿蒙原生版支付宝下载量突破230万&#xff0c;持续迭代性能提升15%&#xff0c;越来越好用&#xff1b;掌上生活、美柚等多款应用功能更新。

深度学习PyTorch之13种模型精度评估公式及调用方法

深度学习pytorch之22种损失函数数学公式和代码定义 深度学习pytorch之19种优化算法&#xff08;optimizer&#xff09;解析 深度学习pytorch之4种归一化方法&#xff08;Normalization&#xff09;原理公式解析和参数使用 深度学习pytorch之简单方法自定义9类卷积即插即用 实时…

显示器长时间黑屏

现象 电脑启动后,进入登录界面前会随机黑屏,有时候十几秒,有时候几分钟 进入桌面后,长时间不操作电脑黑屏,移动鼠标,点击键盘后尝试点亮屏幕,也会消耗较长时间 尝试 重装系统,或者重新安装显卡,都能够恢复,但过段时间以后又出现黑屏情况 集成显卡,独立显卡都出现过 操作系统…

网络编程之应用层协议(http)

HTTP: 1.url(统一资源定位符) 2.http:浏览器与服务器之间的通信标准 端口号&#xff1a;80&#xff1b; 传输层协议&#xff1a;TCP; 3.http工作流程&#xff1a; 4.http的报文格式&#xff1a; 5.HTTP请求报文的方法 6.回应报文&#xff1a;状态码 注意&#xff1a;

数据结构——顺序表与链表

1. 基础介绍 1、线性结构&#xff1a; 如果一个数据元素序列满足&#xff1a; &#xff08;1&#xff09;除第一个和最后一个数据元素外&#xff0c;每个数据元素只有一个前驱数据元素和一个后继数据元素&#xff1b; &#xff08;2&#xff09;第一个数据元素没有前驱数据…

苦瓜书盘官网,免费pdf/mobi电子书下载网站

苦瓜书盘&#xff08;kgbook&#xff09;是一个专注于提供6英寸PDF和MOBI格式电子书的免费下载平台&#xff0c;专为电子阅读器用户设计。该平台为用户提供了丰富的电子书资源&#xff0c;涵盖文学、历史、科学、技术等多个领域&#xff0c;旨在打造一个全面的电子书资源库。用…

PPT 小黑第20套

对应大猫21 Word转PPT 图片也得复制 题目要求两套PPT母板&#xff0c;应用不同版式&#xff08;版式那就可以选&#xff09; 竖排文字

第六课:数据库集成:MongoDB与Mongoose技术应用

本文详细介绍了如何在Node.js应用程序中集成MongoDB数据库&#xff0c;并使用Mongoose库进行数据操作。我们将涵盖MongoDB在Ubuntu 20系统中的安装、Bash命令的CRUD操作、Mongoose数据建模&#xff08;Schema/Model&#xff09;、关联查询与聚合管道&#xff0c;以及实战案例—…

蓝桥云客 卡牌

2.卡牌 - 蓝桥云课 卡牌 问题描述 这天&#xff0c;小明在整理他的卡牌。 他一共有n种卡牌&#xff0c;第i种卡牌上印有正整数i(i∈[1,n])&#xff0c;且第i种卡牌现有a_i张。 而如果有n张卡牌&#xff0c;其中每种卡牌各一张&#xff0c;那么这n张卡牌可以被称为一套牌。小…

【Linux】——初识操作系统

文章目录 冯-诺依曼体系结构操作系统shell 冯-诺依曼体系结构 我们现在所使用的计算机就是冯-诺依曼体系结构。 存储器就是内存。 由下图可知&#xff0c;寄存器最快&#xff0c;为啥不用寄存器呢&#xff1f; 因为越快价格就最贵&#xff0c;冯诺依曼体系结构的诞生&#xf…

坐标变换介绍与机器人九点标定的原理

【备注】本文的C#代码在下面链接中可以下载:Opencv的C#九点标定代码资源-CSDN文库 https://download.csdn.net/download/qq_34047402/90452336 一、坐标变换的介绍 1.绕原点旋转的坐标变换 一个点(x,y)绕原点旋转u度,其旋转后的坐标(x1,y1)如何计算? 2.绕任意点的坐标变…

恶劣天候三维目标检测论文列表整理

恶劣天候三维目标检测论文列表 图摘自Kradar &#x1f3e0; 介绍 Hi&#xff0c;这是有关恶劣天气下三维目标检测的论文列表。主要是来源于近3年研究过程中认为有意义的文章。希望能为新入门的研究者提供一些帮助。 可能比较简陋&#xff0c;存在一定的遗漏&#xff0c;欢迎…

掌握Kubernetes Network Policy,构建安全的容器网络

在 Kubernetes 集群中&#xff0c;默认情况下&#xff0c;所有 Pod 之间都是可以相互通信的&#xff0c;这在某些场景下可能会带来安全隐患。为了实现更精细的网络访问控制&#xff0c;Kubernetes 提供了 Network Policy 机制。Network Policy 允许我们定义一组规则&#xff0c…

Mybatis集合嵌套查询,三级嵌套

三个表&#xff1a;房间 玩家 玩家信息 知识点&#xff1a;Mybatis中级联有关联&#xff08;association&#xff09;、集合&#xff08;collection&#xff09;、鉴别器&#xff08;discriminator&#xff09;三种。其中&#xff0c;association对应一对一关系、collectio…