Verilog设计_找到1的位置

这篇具有很好参考价值的文章主要介绍了Verilog设计_找到1的位置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在输入数据中找到1的位置:找到第一个1的位置和最后一个1的位置。

给出了两种设计方法:第一种使用二分法,但是有一定局限性;第二种则是通用的参数化设计方法。


目录

一、二分法实现

二、参数化实现


一、二分法实现

输入一个数据,输出第一个1所在的位置和最后一个1所在的位置。

代码实现:

module pos(
    input clk,
    input rst_n,
    input  [7:0] din,
    output [2:0] first_pos,
    output [2:0] last_pos
);

    wire [3:0] first_data_4;
    wire [1:0] first_data_2;
    wire [3:0] last_data_4;
    wire [1:0] last_data_2;

    assign first_pos[2] = ~|din[3:0]? 1:0;
    assign first_data_4 = first_pos[2]? din[7:4] : din[3:0];
    assign first_pos[1] = ~|first_data_4[1:0];
    assign first_data_2 = first_pos[1]? first_data_4[3:2] : first_data_4[1:0];
    assign first_pos[0] = ~first_data_2[0];


    assign last_pos[2] = |din[7:4];
    assign last_data_4 = last_pos[2] ? din[7:4] : din[3:0];
    assign last_pos[1] = |last_data_4[3:2];
    assign last_data_2 = last_pos[1] ? last_data_4[3:2] : last_data_4[1:0];
    assign last_pos[0] = last_data_2[1];

endmodule

第一个1的位置和最后一个1的位置都是从低位算起的位置。在这里定义输入数据是8位,一开始我想直接做成参数化,但在实现过程中遇到一些小问题,所以目前先把数据的位数固定。

主体思路是不断做二分,比如找到第一个1的逻辑

(1)首先判断输入数据低4位,按位进行或运算后取反,如果低4位中出现了1则first_pos[2]等于0,反之如果低4位中都没有出现1则first_pos[2]等于1

(2)借助中间变量first_data_4,如果first_pos[2]等于1则取输入数据的高4位(说明低4位中没有1),如果first_pos[2]等于0则取输入数据的低4位(说明低4位中有1)

(3)first_data_4再进行二分,将低两位按位或运算后取反赋值给first_pos[1],根据first_pos[1]的值再对first_data_2进行赋值

举一个典型例子,比如最高位在第7位:1000_0000

(1)首先低四位都是0,first_pos[2]值为1,first_data_4取值高四位

(2)first_data_4的低两位是00,first_pos[1]值也为1,则first_data_2的值取first_data_4的高两位

(3)first_data_2的第0位是0,则first_pos[0]值位1,得出结果是111即第7位。

找到最后一个1的位置的思路类似,取值和赋值的逻辑则需要相应取反。

测试了几个数据,波形如下:

1、0110_0000,第一个1的位置是5,最后一个1的位置是6(数据都是用二进制表示)

Verilog设计_找到1的位置

 2、1000_0001,第一个1的位置是0,最后一个1的位置是7

Verilog设计_找到1的位置

3、0001_0000, 第一个1的位置和最后一个1的位置都是4

Verilog设计_找到1的位置

这个方法可以实现功能,但是有一定的局限性,尤其是奇数位宽的情况,做二分显然就不适用。整体逻辑还有优化的空间,尤其是参数化的实现。

二、参数化实现

先考虑找到第一个出现的1的情况。如果给输入信号减去1会得到什么?

假设din的第i位是1,第0到第i-1位都是0,那么减去1之后低位不够减,就需要向高位借位,而直到第一次出现1的位,借位才会完成。即从第i位借位,第0到i-1位都变成了1,而第i位变为了0,更高位不变。

然后再给减1之后的结果取反,然后把结果再和din本身按位与,可以得出只有第i位在取反之后又变成了1,而其余位都是和din本身相反的,按位与之后是0,这样就提取出来了第一个为1的一位。

其实减1再取反,也就是在计算2的补码。2的补码的一个特性是,一个数和它的补码相与,得到的结果是一个独热码,独热码为1的那一位是这个数最低的1。所以这个设计方法可以用一句话来概括:

输入信号和它的2的补码按位与,可以找到第一个1出现的位置。

而对于最后一个1的位置,将输入信号高低位转换一下,再同样用之前的思路即可。

代码实现:

module pos #(parameter N=9)(
             input   clk,rst_n,
             input   [N-1:0] din,
            output   [N-1:0] first_pos,
            output   [N-1:0] first_pos_out,
            output   [N-1:0] last_pos,
            output   [N-1:0] last_pos_out
         );

         assign first_pos = din & (~(din-1));
         assign first_pos_out = $clog2(first_pos);

         genvar i,j;
         reg [N-1:0] tmp;
         reg [N-1:0] tmp_pos;

         generate 
             for(i=0;i<N;i=i+1)begin
                 assign tmp[N-1-i] = din[i];
             end
         endgenerate

         assign tmp_pos = tmp & (~(tmp-1));

         generate 
             for(j=0;j<N;j=j+1)begin
                 assign last_pos[N-1-j] = tmp_pos[j];
             end
         endgenerate

         assign last_pos_out = $clog2(last_pos);


endmodule

为了更直观的观察结果,使用$clog2函数作了一个对数运算,直接输出位数(从低位开始算起)。

测试了几个数据,波形如下:

1、0_0110_1000

Verilog设计_找到1的位置

2、010000110

Verilog设计_找到1的位置

 3、全1的情况 

Verilog设计_找到1的位置文章来源地址https://www.toymoban.com/news/detail-499907.html


到了这里,关于Verilog设计_找到1的位置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 找到序列最高位的1和最高位的0并输出位置

     前言:         该题为睿思芯科笔试题,笔试时长20分钟。         接口如下:          target可以等于1,也可以等于0。当target等于1时,检测data_in最高位的1,并输出其位置,位置计数从0开始。举例:当target=1时,序列4\\\'b0101,存在1,所以输出exist = 1,检测1的位置pos

    2024年02月14日
    浏览(34)
  • 根据手机指南针经纬度在地图上找到其位置

    使用手机指南针获取经纬度,然后在地图上找到位置。 1、使用手机指南针获取经纬度: 2、将度分秒转换为度: 分/60+秒/3600+整数度数,得到以度为单位的数值 手机经纬度:117.1291666,31.842777 3、坐标系转换: 地图坐标系转换 - 在线工具 输入手机经纬度:117.1291666,31.842777 得到

    2024年02月09日
    浏览(39)
  • C# 在Color[] colorTable中快速找到Color的索引位置

    C# 在Color[] colorTable中快速找到Color的索引位置 第一种方法: 如果您需要在 Color[] colorTable 中快速查找特定 Color 的索引位置,可以使用C#的 Array.FindIndex 方法。这个方法接受一个回调函数作为参数,该函数定义了如何判断数组元素是否与目标匹配。 在上述代码中,我们使用 Ar

    2024年02月11日
    浏览(32)
  • python+paddleocr 进行图像识别、找到文字在屏幕中的位置

    目录 前言 1、安装paddleocr 2、安装PIL 3、安装numpy 4、 安装pyautogui 5、进行文本识别 6、识别结果 7、获取文字在图片/屏幕中的位置 8、pyautogui+paddleocr鼠标操作 9、完整代码 最近在做自动化测试,因为是处理过的界面,所以使用pywinauto,LDTP获取控件进行操作的方法不可行,于是选

    2024年02月03日
    浏览(46)
  • UE4/5如何快速找到蓝图在C++源码里面的位置

            很多时候,我们在ue中写c++代码的时候,总是找不到实现蓝图的代码,原因是我们不知道c++源码中,他们所在的是哪一个头文件。         而这一次作者就告诉大家,如何通过蓝图快速的找到这些源码的位置所在。         作者用的是VS2022,不过没有关系,因为

    2024年02月04日
    浏览(37)
  • 找到IntelliJ IDEA中下载的jdk的保存位置并添加jdk到环境变量

    在IntelliJ IDEA中通过JetBrains提供的功能下载的JDK通常会被保存在一个专门的目录中。本文以下介绍找到它以及将其添加到环境变量的步骤: 找到JDK的位置 : 打开IntelliJ IDEA。 打开任一项目(或创建一个新项目)。 点击“File”(文件) “Project Structure”(项目结构)或使用快捷

    2024年02月03日
    浏览(47)
  • 笔记本电脑没有麦克风,声音无法找到输入设备

    新买的电脑没有扬声器,电脑声音没有输入设备,在开腾讯会议的时候才发现竟然有这个问题。 网上找原因,哎,找了一大堆每一个靠谱的 这让我想起来上次电脑没有热键的问题,所有问题的终极解决方案,都在源头那里,网上的这些东西都是大家从源头那里吸收消化过的

    2024年02月07日
    浏览(77)
  • 基于FPGA的多通道数据采集系统Verilog设计

    基于FPGA的多通道数据采集系统Verilog设计 随着科技的不断发展,数据采集在许多领域变得越来越重要。为了满足高速、高精度和多通道数据采集的需求,基于FPGA的多通道数据采集系统成为了一种常见的解决方案。本文将介绍如何使用Verilog语言设计一个基于FPGA的多通道数据采

    2024年02月09日
    浏览(52)
  • verilog 模块输入输出描述

    表格 端口 从模块内部看 从模块外部看 input 输入端口 必须为线网类型 额可以线网类型或寄存器类型 output 输出端口 可以是线网类型或寄存器类型 必须为线网类型 inout 输入输出端口 必须为线网类型 必须为线网类型 说明 端口连接规则 将一个端口看成由相互链接的两个部分组

    2024年02月14日
    浏览(43)
  • 基于FPGA的多通道数据采集系统Verilog设计嵌入式

    基于FPGA的多通道数据采集系统Verilog设计嵌入式 在本文中,我们将介绍基于FPGA的多通道数据采集系统的Verilog设计,该系统可用于同时采集和处理多个通道的数据。我们将详细讨论系统的设计原理和实现步骤,并提供相应的Verilog源代码。 系统概述 多通道数据采集系统是一种

    2024年02月07日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包