字符串 异或运算_一个异或运算引发的设计技巧(1)

65a78a97ff4426c8953629ed5ef604d2.png

上期内容:create_clock你用对了吗

1f423c06dc6468ec3c676afc213d4fe6.png

异或运算是基本的逻辑运算,在FPGA设计中经常遇到。其实现方式也很简单,例如1bit的a和b相异或,只需要一个2输入查找表(LUT2)就可以完成。但是,如果a和b的位宽达到了512位,而且实际算法包含很多此类运算,且要求时钟运行在600MHz,采用LUT实现就有点捉襟见肘了。

  高速设计中,采用LUT实现512位异或运算会有哪些弊端呢?从资源角度而言,a和b都是512位,那么就要消耗512个LUT2。如果存在很多这样的操作,意味着LUT的利用率会提升,从而增大了布线拥塞的风险。从时序角度而言,作为设计的一部分,这些LUT2很有可能分散到不同列的Slice中,如下图所示。图中红色标记即为LUT。这意味着某些LUT输出端的布线延迟会很大,从而给时序收敛带来压力。 e7dfaee173e058bbaa151357355d3541.png 为此,我们想到了DSP48。DSP48包含一个逻辑运算单元ALU,可实现多种逻辑运算,其中就包括异或运算,如下图所示(图片来源,Table 2-10, ug579)。观察图中红色方框标记的行,将相应的OPMODE和ALUMODE设置为指定的常数,就可以实现一个48位的异或运算。这就要用到DSP48E2的原语(Primitive),要求对原语中的参数、输入/输出端口的含义有所了解,这个过程较为繁琐。好在Vivado提供了一个综合属性USE_DSP,通过该属性可以将异或运算映射到DSP48中。这里我们重点讨论这种方法。 1ef466275ded1b263fa8f4c96ea2d166.png 看看如下图所示的SystemVerilog代码,属性use_dsp的值为logic,作用于module(当use_dsp值为logic时,对于SystemVerilog,只能作用于module),这里位宽为36。对输入、输出均采用了寄存,从而使得输入到输出的Latency为2。这个模块可以很好地映射到DSP48中,包括其中的寄存器,不会消耗Slice中的任何资源。这里需要注意一点的是只有当输入数据位宽大于某个值且use_dsp属性值为logic时,才可以将异或运算映射到DSP48中。两个条件缺一不可。有兴趣的同学可以测试一下,这里要求位宽的最小值是多少。 d6224af68f71c27d62cf8f7cf2ffeb8d.png 但是,如果将其中的位宽改为512,综合后的资源报告如下图所示。可以看到,此时只消耗了4个DSP48,同时消耗了320个LUT,这意味着并不是所有位的异或运算都映射到DSP48中。那么该如何解决这个问题呢?且看下回分解。

555cd6fd04a8b4b2083b68b436b2b9b2.png

技巧1 :对于大位宽且要求运行在较高时钟频率下的逻辑运算,例如:与、或、非、同或、异或等,可采用DSP48实现。 技巧2 :采用DSP48实现逻辑运算时,除了直接使用原语的方式外,采用use_dsp属性实现映射更为简洁可控。 只有当输入数据位宽大于某个值且use_dsp属性值为logic时,才可以将异或运算映射到DSP48中。两个条件缺一不可。有兴趣的同学可以测试一下,这里要求位宽的最小值是多少。 80c3f663a763cc3b72bd9528a619fadb.png

5f1d6182bcc94dc0506243c92da3cf5a.png

create_clock你用对了吗

字符串和列表之间的转换

列表排序其实不难

警惕设计中的DONT_TOUCH

老生常谈的复位,你真的用对了吗

如何优化高扇出net?

常用的跟Pblock相关的Tcl命令

比较器如何用DSP48实现

HLS案例分析:数组求和(2) HLS案例分析:数组求和(1) 关于Pblock的8个必知问题 一次创建多个Pblock Pblock可以这么画 在Vivado HLS中使用Tcl Vivado 2019.1新特性(5):更新的report_qor_suggestions Vivado 2019.1新特性(4):VHDL 2008 Generic 2019年上半年文章汇总 Tcl知识库(更新至2019.1) Vivado HLS知识库(更新至2019.1) Vivado知识库(更新至2019.1)

b526b652e25ad49335599ffee4274ee3.png

1af6e00de067dfb3b1dfbf4cfbecb503.png

文 | Lauren 图 | Lauren

Copyright @ Lauren的FPGA

转载事宜请私信 | 获得授权后方可转载

bfcb4b99ba693fee4a1d0c7edce26659.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
十六进制字符串按位异或运算是一种常用的运算操作,可以用于数据加密、错误检测等领域。在Java中,我们可以通过使用BitSet和字符串转换为十六进制来实现该功能。 首先,我们可以将十六进制字符串转换为二进制表示,然后再进行按位异或运算。可以使用Integer类的parseInt方法来将十六进制字符串转换为整型,然后使用Integer.toBinaryString方法将其转换为二进制表示。 接下来,我们可以使用BitSet类创建一个位集合,将转换后的二进制字符串按位存储到位集合中。可以使用BitSet.set方法将指定位置的位设置为指定的值。需要注意的是,位集合的大小应该与二进制字符串的长度相匹配。 然后,我们可以定义一个用于进行按位异或运算的方法。可以使用BitSet类的xor方法来实现按位异或运算。该方法将对位集合的每个位执行按位异或运算,并返回一个新的位集合。 最后,我们可以将位集合转换回二进制字符串,并使用Integer.parseInt方法将其转换为十六进制字符串。 以下是一个示例代码片段,可以用于实现十六进制字符串按位异或运算的工具类: ``` import java.util.BitSet; public class HexXorTool { public static String xorHexStrings(String hexString1, String hexString2) { int int1 = Integer.parseInt(hexString1, 16); int int2 = Integer.parseInt(hexString2, 16); String binary1 = Integer.toBinaryString(int1); String binary2 = Integer.toBinaryString(int2); int maxLength = Math.max(binary1.length(), binary2.length()); BitSet bits1 = new BitSet(maxLength); BitSet bits2 = new BitSet(maxLength); for (int i = 0; i < binary1.length(); i++) { if (binary1.charAt(i) == '1') { bits1.set(i); } } for (int i = 0; i < binary2.length(); i++) { if (binary2.charAt(i) == '1') { bits2.set(i); } } BitSet result = bits1.xor(bits2); String binaryResult = result.toString(); int intResult = Integer.parseInt(binaryResult, 2); String hexResult = Integer.toHexString(intResult); return hexResult; } public static void main(String[] args) { String hexString1 = "A5"; String hexString2 = "3C"; String xorResult = xorHexStrings(hexString1, hexString2); System.out.println("Hex XOR Result: " + xorResult); } } ``` 该工具类可以接受两个十六进制字符串作为输入,并返回经过按位异或运算后的十六进制字符串。当我们在main方法中运行该代码时,将输出按位异或运算的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值