0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

HLS最全知识库

OpenFPGA 来源:OpenFPGA 2023-01-15 11:27 次阅读

HLS最全知识库

副标题-FPGA高层次综合HLS(二)-Vitis HLS知识库

高层次综合(High-level Synthesis)简称HLS,指的是将高层次语言描述的逻辑结构,自动转换成低抽象级语言描述的电路模型的过程。

对于AMD Xilinx而言,Vivado 2019.1之前(包括),HLS工具叫Vivado HLS,之后为了统一将HLS集成到Vitis里了,集成之后增加了一些功能,同时将这部分开源出来了。Vitis HLS是Vitis AI重要组成部分,所以我们将重点介绍Vitis HLS。

官方指南:

https://docs.xilinx.com/r/_lSn47LKK31fyYQ_PRDoIQ/root

重要术语

LUT 或 SICE

LUT 或 SICE是构成了 FPGA 的区域。它的数量有限,当它用完时,意味着您的设计太大了!

BRAM 或 Block RAM

FPGA中的内存。在 Z-7010 FPGA上,有 120 个,每个都是 2KiB(实际上是 18 kb)。

Latency延迟

  • 设计产生结果所需的时钟周期数。
  • 循环的延迟是一次迭代所需的时钟周期数。

Initiation Interval (or II, or Interval间隔)

  • 在接受新数据之前必须执行的时钟周期数。

这与延迟不同!如果函数是流水线的,许多数据项会同时流过它。延迟是一个数据项被推入后弹出的时间,而时间间隔决定了数据可以被推入的速率。

  • 循环的间隔是可以开始循环迭代的最大速率,以时钟周期为单位。
18af9486-947b-11ed-bfe3-dac502259ad0.png

上图中,左边是函数右边是循环,左边的时间间隔(接收新数据之前)是3个时钟周期,右边循环的间隔则是一个时钟周期;对于左边的延迟是这个函数产生结果的时钟周期数,是func_C运行完毕产生的周期数,为5个时钟周期,右边循环的延迟是一次迭代所需的时钟数,是4个时钟周期。

上面的概念非常重要,要不然下面的一些指令作用也看不懂~

重要的指令

这是在实际使用过程中重要的指令列表(不是全部)。

  • Functions-函数

  • loops-循环

  • Various-所有都适合

  • Arrays-数组

  • parameters-参数

指令 适用范围 描述
PIPELINE 流水线指令 Functions, loops 简单解释就是使输入更频繁地传递给函数或循环。流水线后的函数或循环可以每 N 个时钟周期处理一次新输入,其中 N 是启动间隔(Initiation Interval)。'II' 默认为 1,是 HLS 应针对的启动间隔(即尝试将新数据项输入管道的速度应该多快)。
UNROLL loops 创建循环的因子副本,让其并行执行(如果满足数据流依赖性)。但是会浪费资源(以资源换取速度)。尽可能将程序展开以提高速度。
ALLOCATION Various 限制某事物的实例数。例如,如果只想在另一个函数toplevel中获得函数foo的三个副本,请使用位置toplevel、限制设置为3、实例设置为foo、类型设置为“function”的分配。这也适用于特定的运算。
ARRAY_MAP Arrays 将多个较小的阵列映射成一个较大的阵列,以牺牲访问时间为代价来节省访问逻辑或 BRAM。'instance' 可以设置为任何未使用的名称。ARRAY_MAP 对同一个实例使用多个 来告诉 HLS 创建一个名为“instance”的新数组,其中包含所有较小的数组。保留“偏移”未设置。请注意,有些人在将三个或更多初始化数组映射到单个 RAM 时遇到了此指令引起的错误。如果在仿真和实现的设计之间遇到行为差异,请尝试删除此指令。
ARRAY_PARTITION Arrays 将一个大数组拆分为多个较小的数组(与ARRAY_MAP相反)。这对于增加并行访问的可能性很有用。如果“type”是“block”,则源数组将分成block。如果它是“cyclic”,那么元素将被交错到目标数组中。在这两种情况下,“factor因子”都是要创建的较小数组的数量。如果 'type' 是 'complete' 则忽略 'factor' 并且阵列被完全分割成组件寄存器,因此不使用任何 Block RAM。
DATAFLOW Functions 见下文
INLINE Functions 该指令不是将函数视为单个硬件单元,而是在每次调用 HLS 时将函数内联。这是以硬件为代价增加了潜在的并行性。如果 'recursive' 为真,则内联函数调用的所有函数也被视为标有 INLINE。
INTERFACE Function,parameters 告诉 HLS 如何在函数之间传递参数。这在顶层函数中至关重要,因为它定义了设计的引脚排列。在 EMBS 中,我们有一个应该坚持使用的模板(上图)。
LATENCY Functions, loops HLS 通常会尝试在综合时实现最小延迟。如果使用此指令指定更大的最小延迟,HLS 将“pad out”函数或循环并减慢一切。这有助于资源共享(减少资源),并且对于创建延迟很有用。如果 HLS 无法达到要求的延迟,它将发出警告。
LOOP_FLATTEN loops 将嵌套循环展平为单个循环。应用于 最里面的 循环。如果成功,将生成更快的硬件代码。
LOOP_TRIPCOUNT loops 如果循环具有可变的循环边界,HLS 将不知道它需要多少次迭代。这意味着它无法为设计延迟提供明确的值。这允许我们为设计指定循环的最小、平均和最大行程计数(迭代次数)。这只会影响报告,不会影响硬件代码生成。
RESOURCE Various 这用于指定应使用特定硬件资源来实现源代码元素。指定是否应使用 BRAM 或 LUT 实现ARRAY。见下文详解。

任意精度类型

可以在 HLS 中使用普通的 C 类型(int、 char等)变量。但是,设计中的常用的寄存器并不完全需要 4、8 或 16 位宽,那么可以使用任意精度类型来准确定义需要多宽的数据类型,而不是接受这种低效率的通用定义。

下面展示了如何使用 C 和 C++ 风格的任意精度类型。我们建议使用 C++,除非有特定的理由不这样做。

在 C 中:

包含 头文件。然后,可以声明具有如下类型的变量:

uint5 x 无符号整数,5 位宽
int19 x 有符号整数,19 位宽

在 C++ 中:

包含 头文件。然后,可以声明具有如下类型的变量:

ap_uint<5> x 无符号整数,5 位宽
ap_int<19> x 有符号整数,19 位宽

按照上面的设置应该能够正常打印任意精度类型,但是如果在调试过程中得到奇怪的值,请先使用printf调用to_int():

ap_uint<23>myAP;
printf("%d
",myAP.to_int());

复位行为

在 HLS 中,所有静态和全局变量都被初始化为零(如果给定了初始化值,则初始化为其他值)。这包括 RAM,其中每个元素都被清除为零。然而,这种初始化只发生在 FPGA 首次编程时。任何后续处理器复位都不会触发初始化过程。

如果需要清除设备的内部状态,那么应该包含某种复位协议(根据复位状态处理所需要的程序)。

AXI 从接口和 AXI 主接口

可以在 HLS 组件中使用两个接口,即 AXI Slave 和 AXI Master。

  • AXI Slave:ARM 内核使用此接口来启动和停止 HLS 组件。他们还可以使用此接口来读取和写入相对少量的用户定义值。

  • AXI Master:如果需要更大量的共享数据,HLS 组件可以使用 AXI Master 接口启动事务以从主系统内存读取和写入数据。

可以通过toplevel在 HLS 组件中为函数指定参数并将指令附加到这些参数来定义所需的接口。下面显示了一个只有从接口的组件:

带有AXI Slave的 HLS 组件

uint32toplevel(uint32*arg1,uint32*arg2,uint32*arg3,uint32*arg4){
#pragmaHLSINTERFACEs_axiliteport=arg1bundle=AXILiteSregister
#pragmaHLSINTERFACEs_axiliteport=arg2bundle=AXILiteSregister
#pragmaHLSINTERFACEs_axiliteport=arg3bundle=AXILiteSregister
#pragmaHLSINTERFACEs_axiliteport=arg4bundle=AXILiteSregister
#pragmaHLSINTERFACEs_axiliteport=returnbundle=AXILiteSregister
}

而下面是一个同时具有从接口和主接口的组件:

具有从属和主接口的 HLS 组件

uint32toplevel(uint32*ram,uint32*arg1,uint32*arg2,uint32*arg3,uint32*arg4){
#pragmaHLSINTERFACEm_axiport=ramoffset=slavebundle=MAXI
#pragmaHLSINTERFACEs_axiliteport=arg1bundle=AXILiteSregister
#pragmaHLSINTERFACEs_axiliteport=arg2bundle=AXILiteSregister
#pragmaHLSINTERFACEs_axiliteport=arg3bundle=AXILiteSregister
#pragmaHLSINTERFACEs_axiliteport=arg4bundle=AXILiteSregister
#pragmaHLSINTERFACEs_axiliteport=returnbundle=AXILiteSregister
}

请注意,可以为从接口添加和删除参数,并更改它们的数据类型,只需记住也要更新关联#pragmaS。HLS 将相应地更新组件的驱动程序。

PS:主数据类型:由于 AXI 主接口会连接到 32 位宽的 RAM,因此在指定 AXI 主接口时应始终使用 32 位数据类型。

一旦决定了的接口,应该能够依靠 Vivado 自动化连线来连接一切。

请注意,返回端口的 pragma 很重要!

#pragmaHLSINTERFACEs_axiliteport=returnbundle=AXILiteSregister

//端口=返回包=AXILiteS寄存器

即使不使用函数的返回值,此 pragma 也会告诉 HLS 将 start、stop、done 和 reset 信号捆绑到 AXI Slave 接口中的控制寄存器中。因此,这将生成相应的驱动程序函数来启动和停止生成的 IP 内核。如果不包含此 pragma,则 HLS 将为这些信号生成简单的连线,并且 IP 内核将无法直接被 ARM 内核控制。

多种类型的 AXI Master

Vitis HLS在从同一主AXI端口复制值并将其解释为不同类型时非常挑剔。

例如,以下 memcpy 可能会导致“Stored value type does not match pointer operand type! (存储值类型与指针操作数类型不匹配!)” ,尝试将 RAM 视为uint32 和float类型时,综合过程中将会产生 LLVM 错误:

voidtoplevel(uint32*ram){
#pragmaHLSINTERFACEm_axiport=ramoffset=slavebundle=MAXI
uint32u_values[10];
floatf_values[10];

memcpy(u_values,ram,40);
memcpy(f_values,ram+10,40);
}

为了正确强制从 RAM 中复制数据的类型信息,可以使用union,如下所示:

typedefunion{
uint32u;
floatf;
}ram_t;

voidtoplevel(ram_t*ram){
#pragmaHLSINTERFACEm_axiport=ramoffset=slavebundle=MAXI
uint32u_values[10];
floatf_values[10];

for(inti=0;i< 10; i++) {
        ram_t data = ram[i];
        u_values[i] = data.u;
    }
    for(inti=0;i< 10; i++) {
        ram_t data = ram[i+10];
        f_values[i] = data.f;
    }
}

此外,只要循环边界从零开始(并且是固定的),HLS应该足够聪明,将其视为类似于memcpy的突发传输-在综合过程中查找“推断MAXI端口上长度为X的总线突发读取”来证实这一点。

强制和阻止使用 Block RAM

HLS 会自动将大部分ARRAY转换为 BRAM。这通常很有用,因为寄存器ARRAY在 LUT(FPGA 空间)方面非常昂贵。但是,FPGA 的 BRAM 数量有限。BRAM 也只有 2 个访问端口。这意味着在任何时候最多有两个并行进程可以访问 RAM。这可能会限制设计的并行性潜力。

如果HLS使用的是不希望使用的BRAM,则将类型设置为COMPLETE且维度设置为1的指令array_PARTITION应用于数组。这将迫使它从寄存器中生成数组。这会占用大量的FPGA空间(LUT),所以要节约!

要强制 HLS 使用 BRAM,请将指令BIND_STORAGE集应用到 RAM_2P。(添加时按下帮助按钮可查看所有各种选项的说明)。

该 ARRAY_MAP 指令(见上文)可以通过自动将多个较小的数组放入一个较大的数组来帮助节省 Block RAM。

当更改 HLS 时

当更改 HLS 代码时,请执行以下步骤以确保bitfile已更新,方便进行正确地测试。

  • 1、重新运行综合。
  • 2、重新导出 IP 核。
  • 3、在 Vivado 中,它应该已经注意到了变化,并且会出现一条消息说“IP Catalog is out-of-date”。a、如果没有,请单击 IP Status,然后单击重新运行报告

b、单击刷新 IP 目录

c、在 IP Status面板中,应选择 toplevel IP。单击 Upgrade 选项。

  • 4、在“Generate Output Products”对话框中,单击“Generate”。

  • 5、单击生成比特流。

  • 6、导出硬件到 Vitis。

  • 7、在 Vitis 中重新编程 FPGA 并运行软件。

现在应该明白了为什么测试和仿真如此重要了!

循环优化

在 HLS 中,可以将指令应用于循环以指示它展开或流水线。考虑以下循环:

myloop:for(inti=0;i< 3; i++) {
    doSomething(X[i]);
}

默认情况下,HLS 将按顺序执行循环的每次迭代。它的执行将如下所示:

18be5804-947b-11ed-bfe3-dac502259ad0.png

如果循环的每次迭代需要 10 个时钟周期,那么循环总共需要 30 个周期才能完成。

如果我们给这个循环 PIPELINE 指令,那么 HLS 将尝试在元素 0 完成之前开始计算元素 1,从而创建一个PIPELINE。这意味着循环的整体执行时间会更短,但代价是更复杂的控制逻辑和更多的寄存器来存储中间数据。循环如下所示:

18d466f8-947b-11ed-bfe3-dac502259ad0.png

只有在没有阻止此优化的依赖项时,它才能执行此操作。考虑以下代码:

intlastVal;

for(inti=0;i< 50; i++) {
    lastVal = calculateAValue(lastVal);
}

在此示例中,循环被迫按顺序执行,因为在下一次循环迭代开始时需要在循环体末尾使用计算出的值。PIPELINE 仍然会试图加快速度,但不会大幅加快。

最后,如果我们给循环 UNROLL 指令,那么 HLS 将尝试并行执行循环的迭代。这需要更多的硬件,但速度非常快。在我们的示例中,整个循环只需要 10 个周期。

18ec3f9e-947b-11ed-bfe3-dac502259ad0.png

这要求循环的元素之间没有数据依赖关系。例如,如果 doSomething() 保留一个执行次数的全局计数器,则此依赖项将阻止 UNROLL 指令工作。

请注意,UNROLL默认情况下会尝试展开循环的所有迭代。这可能会导致非常大的设计!为了使事情更合理,可以设置UNROLL的FACTOR参数来告诉工具要创建多少副本。

应用UNROLL后,最好在分析视图中查看它是否实际应用。成功展开的设计在分析视图中将非常“垂直”,表示同一列中的操作同时发生。如果视图仍然非常“水平”且有很多列,那么很可能是数据依赖项阻止了展开。可以尝试通过单击操作来确定是什么阻止了展开。该工具将绘制箭头以显示输入的内容和输出的内容。请记住,BlockRAM 一次只能进行两次访问,因此,如果有一个大型ARRAY,而这些工具是从 BlockRAM 制作的,则展开或流水线操作最多只能创建 2 个副本。可以告诉工具不要使用带有ARRAY_PARTITION指令的块RAM。这可以快得多,但要使用更多的硬件资源。

数据流优化

如果没有使用限制资源的指令(例如 ALLOCATION 指令),HLS 会寻求最小化延迟并提高并发性。但是数据依赖性可以限制这一点。例如,访问数组的函数或循环必须在完成之前完成对数组的所有读/写访问,这就阻止了下一个消耗数据的函数或循环启动。

函数或循环中的操作可能会 在前一个函数或循环完成其所有操作之前开始操作。

HLS指定数据流优化时:

  • 分析顺序函数或循环之间的数据流。

这允许函数或循环并行运行,从而减少延迟并提高 RTL 设计的吞吐量,但以增加硬件资源为代价。尝试一下DATAFLOW ,看看它是否对设计有帮助。

找不到 'crt1.o' 错误

当试图在实验室硬件以外的机器上运行测试时,可能会收到一个错误,抱怨它找不到“crt1.o”。如果是这样,就需要为项目设置自定义链接器标志。

单击顶部菜单中的“Project”,然后单击Project Settings。在此框中,单击左侧的“Simulation”,然后将以下内容粘贴到“Linker Flags”框中:

-B"/usr/lib/x86_64-linux-gnu/"

我的循环有???latency估计!

有时,HLS 综合报告将包含?而不是给出最小和最大延迟的值。这是因为设计中至少有一个循环是数据相关的,即它循环的次数取决于 HLS 无法知道的数据值。

例如,下面的代码:

18fd1ecc-947b-11ed-bfe3-dac502259ad0.png

当综合在综合报告中给出以下内容:

1912bdcc-947b-11ed-bfe3-dac502259ad0.png

如果我们检查代码,它将来自ram的元素相加,但要相加的元素的确切数量来自用户,作为arg1参数输入。因此,HLS无法提前知道该硬件执行需要多长时间,因为每次运行时它都是可变的。这就是上面我们说的运行时依赖于数据。生成的硬件将正常工作,我们只是无法预测运行需要多长时间。查看循环的细节,HLS仍然可以告诉我们循环的延迟是2,换句话说,它不知道它将迭代多少次,但每次迭代将花费2个时钟周期。

一般来说,应该尽量避免这种情况。如果 HLS 无法预测最坏的情况,那么它会过于“谨慎”,并且它可能会制造比我们需要的更大的硬件。此外,不能展开具有可变循环边界的循环。

一些算法从根本上是依赖于数据的,如果这种情况无法避免,那么可以通过将LOOP_TRIPCOUNT指令添加到循环中来告诉 HLS ,假设循环将进行给定次数的迭代,但这仅用于报告目的。生成的硬件将完全相同,但HLS将在循环迭代该次数的假设下生成延迟数。这意味着延迟数字不“正确”,但这仍然有助于了解其他优化是否具有总体积极效果。

定点类型

当需要使用小数运算但又不想支付使用浮点的大量硬件成本时,定点类型很有用。Vitis HLS 用户指南(https://www.xilinx.com/support/documentation/sw_manuals/xilinx2020_2/ug1399-vitis-hls.pdf)中详细描述了定点类型,下面是一个简短示例:

定点示例

#include
#include

ap_fixed<15, 5>a=3.45;
ap_fixed<15, 5>b=9.645;
ap_fixed<20, 6>c=a/b*2;
std::cout<< c;
//Prints 0.7148. The accurate answer is 0.7154. More bits can be allocated to the types ifmoreaccuracyisrequired.

C标准数学函数(在math.h中)仅针对浮点实现,但Xilinx在hls_math.h中提供了某些函数的定点实现。在hls::命名空间下;例如:hls::sqrt()、hls::cos()和hls::sin()。

此外,以下赛灵思示例代码显示了另一种定点平方根实现,在某些情况下可能更有效。

fxp_sqrt.h

#ifndef__FXP_SQRT_H__
#define__FXP_SQRT_H__
#include
#include
usingnamespacestd;

/*
*Providesafixedpointimplementationofsqrt()
*Mustbecalledwithunsignedfixedpointnumberssoconvertbeforecalling,follows:
*ap_ufixed<32, 20>in=input_number;
*ap_ufixed<32, 20>out;
*fxp_sqrt(out,in);
*/
template
voidfxp_sqrt(ap_ufixed&result,ap_ufixed&in_val)
{
enum{QW=(IW1+1)/2+(W2-IW2)+1};//derivemaxrootwidth
enum{SCALE=(W2-W1)-(IW2-(IW1+1)/2)};//scale(shift)toadjinitialremainervalue
enum{ROOT_PREC=QW-(IW1%2)};
assert((IW1+1)/2<= IW2); // Check that output format can accommodate full result
   ap_uintq=0;//partialsqrt
ap_uintq_star=0;//diminishedpartialsqrt
ap_ints;//scaledremainderinitializedtoextractedinputbits
if(SCALE>=0)
s=in_val.range(W1-1,0)<< (SCALE);
   else
s=((in_val.range(W1-1,0)>>(0-(SCALE+1)))+1)>>1;
//Non-restoringsquare-rootalgorithm
for(inti=0;i<= ROOT_PREC; i++) {
      if(s>=0){
s=2*s-(((ap_int(q)<< 2) | 1) << (ROOT_PREC - i));
         q_star = q << 1;
         q = (q << 1) | 1;
      } else{
s=2*s+(((ap_int(q_star)<< 2) | 3) << (ROOT_PREC - i));
         q = (q_star << 1) | 1;
         q_star <<= 1;
      }
   }
   // Round result by "extraiteration"method
if(s>0)
q=q+1;
//Truncateexcessbitandassigntooutputformat
result.range(W2-1,0)=ap_uint(q>>1);
}
#endif

总结

这是《FPGA高层次综合HLS》系列教程第二篇,后面会按照专题继续更新,文章有什么问题,欢迎大家批评指正~感谢大家支持。


审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1625

    文章

    21648

    浏览量

    601482
  • HLS
    HLS
    +关注

    关注

    1

    文章

    128

    浏览量

    24014

原文标题:总结

文章出处:【微信号:Open_FPGA,微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    腾讯云手动下发指令到设备_云端与设备联调方案

    即可 本文章源自奇迹物联开源的物联网应用知识库Cellular IoT Wiki,更多技术干货欢迎关注收藏Wiki: Cellular IoT Wiki 知识库 (https
    的头像 发表于 09-30 15:25 270次阅读
    腾讯云手动下发指令到设备_云端与设备联调方案

    【实操文档】在智能硬件的大模型语音交互流程中接入RAG知识库

    非常明显的短板。尽管这些模型在理解和生成自然语言方面有极高的性能,但它们在处理专业领域的问答时,却往往不能给出明确或者准确的回答。 这时就需要接一个专有知识库来满足产品专有和专业知识的回复需求,理论
    发表于 09-29 17:12

    优化 FPGA HLS 设计

    优化 FPGA HLS 设计 用工具用 C 生成 RTL 的代码基本不可读。以下是如何在不更改任何 RTL 的情况下提高设计性能。 介绍 高级设计能够以简洁的方式捕获设计,从而
    发表于 08-16 19:56

    一种在HLS中插入HDL代码的方式

    很多人都比较反感用C/C++开发(HLS)FPGA,大家第一拒绝的理由就是耗费资源太多。但是HLS也有自己的优点,除了快速构建算法外,还有一个就是接口的生成,尤其对于AXI类接口,按照标准语法就可以很方便地生成相关接口。
    的头像 发表于 07-16 18:01 652次阅读
    一种在<b class='flag-5'>HLS</b>中插入HDL代码的方式

    如何手撸一个自有知识库的RAG系统

    用于自然语言处理任务,如文本生成、问答系统等。 我们通过一下几个步骤来完成一个基于京东云官网文档的RAG系统 数据收集 建立知识库 向量检索 提示词与模型 数据收集 数据的收集再整个RAG实施过程中无疑是最耗人工的,涉及到收集、清洗、格式化、切分等过程。这里我们使用京东云的官方文档作为
    的头像 发表于 06-17 14:59 500次阅读

    OpenAI推出Vision模型版GPT-4 Turbo,融合文本与图像理解

    据悉,此模型沿用GPT-4 Turbo系列特有的12.8万token窗口规模及截至2023年12月的知识库架构,其创新亮点则是强大的视觉理解功能。
    的头像 发表于 04-10 10:49 368次阅读

    英特尔集成显卡+ChatGLM3大语言模型的企业本地AI知识库部署

    在当今的企业环境中,信息的快速获取和处理对于企业的成功至关重要。为了满足这一需求,我们可以将RAG技术与企业本地知识库相结合,以提供实时的、自动生成的信息处理和决策支持。
    的头像 发表于 03-29 11:07 745次阅读
    英特尔集成显卡+ChatGLM3大语言模型的企业本地AI<b class='flag-5'>知识库</b>部署

    智能制造的六大核心驱动力

    通过运用智能化的设计工具和先进的设计信息化系统(如CAX、网络化协同设计、设计知识库等),企业产品研发设计的各个环节能够得到智能化的提升和优化。
    发表于 01-30 10:04 548次阅读

    Access数据基础知识介绍

    电子发烧友网站提供《Access数据基础知识介绍.pdf》资料免费下载
    发表于 01-02 10:24 3次下载

    AMD-Xilinx的Vitis-HLS编译指示小结

    流水线指令 pragma HLS pipeline 通过流水线提高性能是计算机架构设计的8个伟大思想之一,不管是硬件设计还是软件设计,流水线设计(pipeline)都能够用更多的资源来实现高速
    发表于 12-31 21:20

    基于AI的兵棋类模拟开发项目

    该方法的难点是如何为知识库设定良好的角色以及如何选择相关中间概念。同时,充分利用SOAR内的分块学习能力尤为重要,因为最初的直觉,当前的系统因其学习能力受限。
    的头像 发表于 12-18 09:20 488次阅读

    如何基于亚马逊云科技LLM相关工具打造知识库

    背景 本篇将为大家阐述亚马逊云科技大语言模型下沉到具体行业进行场景以及实施案例的介绍,是亚马逊云科技官方《基于智能搜索和大模型打造企业下一代知识库》系列的第四篇博客。感兴趣的小伙伴可以进入官网深入
    的头像 发表于 11-23 17:53 966次阅读
    如何基于亚马逊云科技LLM相关工具打造<b class='flag-5'>知识库</b>

    sql数据入门基础知识

    SQL(Structured Query Language,结构化查询语言)是一种用于管理关系型数据的编程语言。它被广泛应用于企业应用、数据仓库和网站开发等领域。了解SQL的基础知识是成为一名数据
    的头像 发表于 11-23 14:24 1875次阅读

    MySQL数据基础知识

    的基础知识,包括其架构、数据类型、表操作、查询语句和数据导入导出等方面。 MySQL 数据架构 MySQL 数据由多个组件组成,包括服务器、存储引擎和客户端等。MySQL 服务器是数据
    的头像 发表于 11-21 11:09 940次阅读

    如何用HLS实现UART

    UART 是一种旧的串行通信机制,但仍在很多平台中使用。它在 HDL 语言中的实现并不棘手,可以被视为本科生的作业。在这里,我将通过这个例子来展示在 HLS 中实现它是多么容易和有趣。
    的头像 发表于 11-20 09:48 526次阅读
    如何用<b class='flag-5'>HLS</b>实现UART