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(数据都是用二进制表示)

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

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

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

二、参数化实现

先考虑找到第一个出现的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

2、010000110

 3、全1的情况 


  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: emmc.rar是一个压缩文件的格式,其中包含了一些与emmc(嵌入式多媒体卡)相关的代码资源。这些资源包括vhdl、fpgaverilog的源码,都是用于开发设计与emmc通信的硬件电路的。 VHDL是一种硬件描述语言,用于描述数字电路中的行为和结构,可以用于实现emmc的硬件接口电路。FPGA即现场可编程门阵列,是一种可编程逻辑器件,可以用于实现各种数字电路,并且可以通过加载VHDL源码来实现emmc相关功能。Verilog也是一种硬件描述语言,与VHDL类似,可以用于实现emmc的硬件接口功能。因此,emmc.rar中的VHDL和Verilog源码是为了在FPGA上实现emmc的通信功能。 HS400是一种emmc的传输协议,具有高速数据传输的特性。因此,emmc.rar中的源码可以用于实现emmc与其他设备之间的高速数据传输。 CSDN文库是一个在线的技术资源共享平台,其中包含了各种技术文档和代码资源。emmc.rar中的代码资源在CSDN文库上共享,可以供开发者们学习和参考。 综上所述,emmc.rar中的vhdl/fpga/verilog源码是用于实现emmc的硬件接口电路和高速数据传输的。这些资源在CSDN文库上共享,供开发者们学习和参考。 ### 回答2: emmc.rar是指一个压缩包文件,其中包含有关emmc主题的一些文件和资源。其中也包括了一些与emmc相关的VHDL、FPGAVerilog代码。 VHDL是VHSIC硬件描述语言(Very High Speed Integrated Circuit Hardware Description Language)的缩写,它是一种用于描述和设计数字电路的硬件描述语言FPGA是现场可编程门阵列(Field-Programmable Gate Array)的缩写,它是一种可编程逻辑门电路,可以根据用户的需要配置其内部的逻辑门电路和连线。 Verilog是一种硬件描述语言,用于描述和设计数字电路,以及进行硬件仿真。 因此,emmc.rar中的VHDL、FPGAVerilog代码很可能是用于与emmc(嵌入式多媒体卡)相关的设计和实现。这些代码可能包括与emmc通信、控制和处理相关的功能。 关于hs400fpga和其他代码类资源,它们可能是一些用于FPGA开发的相关资源和代码示例。hs400fpga可能是指用于高速接口HS400(High-Speed Interface 400)的FPGA实现。 CSDN文库是一个知识分享平台,用户可以在上面分享和下载相关资源、文档和代码。因此,emmc.rar_vhdl/fpga/verilog_verilog_源码_hs400fpga-其它代码类资源-csdn文库可能是指在CSDN文库上分享的与emmc、VHDL、FPGAVerilog和HS400相关的源代码和其他代码类资源。用户可以通过CSDN文库下载和学习这些资源,用于相关的开发设计工作。 ### 回答3: emmc.rar是一个文件,其中包含了一些与VHDL、FPGAVerilog相关的源代码和其他代码类资源。CSDN文库是一个网络平台,在这个平台上你可以找到各种技术文档、源代码、教程等。在emmc.rar文件中,有一些与HS400FPGA相关的代码资源。 VHDL是一种硬件描述语言,用于描述数字电路和系统的结构和行为。FPGA是现场可编程门阵列,它是一种可编程逻辑器件,可以根据需要修改内部逻辑。Verilog也是一种硬件描述语言,与VHDL类似,可以用于设计电路和系统。 在emmc.rar文件中,可能包含了一些与这些技术相关的源代码和设计示例。这些源代码可以帮助开发者理解和实现相关的功能。也许还包含了一些其他代码类资源,比如常用的函数库、驱动程序等。 CSDN文库是一个很方便的资源平台,你可以通过搜索或者浏览来找到你需要的技术文档和代码资源。在CSDN文库中,你可以找到很多关于VHDL、FPGAVerilog的教程和指南,这些资源可以帮助你学习和应用这些技术。 总的来说,emmc.rar文件是一个包含了VHDL、FPGAVerilog相关的源码和其他代码类资源的文件。通过CSDN文库,你可以获取更多与这些技术相关的文档和资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clock_926

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值