数字IC前端学习笔记:脉动阵列的设计方法学(以串行FIR滤波器为例)

news2025/1/11 15:10:58

相关阅读数字IC前端_日晨难再的博客-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/weixin_45791458/category_12173698.html?spm=1001.2014.3001.5482


引言

        脉动结构(也称为脉动阵列)表示一种有节奏地计算并通过系统传输数据的处理单元(PEs)网络。这些处理单元有规律地泵入泵出数据以保持规则的数据流。因此,脉动阵列的特征是模块化和规则化,这对于VLSI设计来说是一个重要的性质。脉动阵列可以作为与主机配合的协处理器,从主机接收数据进行计算并将最终结果返回主机。这个操作类似心脏的血液流动,因此被称为“脉动”。

        典型情况下,脉动阵列的所有处理单元是相同的,且全流水的(即PE包含寄存器等延时单元),通常只包含局部互联。然而,为了增加脉动阵列的实用性,一些设计也存在放宽。这些放宽包括:不仅使用局部互连,还使用邻近(接近,但不是最近的)互连,使用数据广播操作,以及在系统中使用不同的处理单元,特别是在边界处。通过这些放宽措施,可以为数字信号处理(DSP)应用设计一系列模块化、规则和高效的数据驱动阵列架构。

        本文以串行FIR滤波器为例介绍了脉动阵列设计方法学,其中可以使用线性映射或投影技术为任何给定的规则迭代算法设计多种流线架构。

脉动阵列设计方法学

        流线架构是通过在规则依赖图上使用线性映射技术来设计的。依赖图中的边表示前置约束。一个依赖图(DG)如果在任何节点中某个方向上的边的存在,意味着在依赖图中的所有节点在同一方向上都有相应的边,那么该依赖图被称为规则依赖图。

        作为一个例子,考虑如下所示的3抽头FIR滤波器的依赖图,如图1所示。

y(n) = \omega _{0}x(n) + \omega _{1}x(n - 1) + \omega _{2}x(n - 2)

图1 FIR滤波器的依赖图(空间表示)

        这个依赖图有3个基本的边(用\boldsymbol{e}表示):输入用向上的边用向量表示为(0, 1),系数用向右的边用向量表示为(1, 0),输出用下右下角移动的边用向量表示为(1, -1)。由于依赖图中的所有节点都包含这3种边,因此该依赖图是规则的。

        该依赖图对应于一个空间表示,因为其中没有为任何计算分配时间不。映射技术将空间表示转换为空间-时间表示,在空间-时间表示中,每个节点被映射到某个处理单元,并且被调度到某个时间步。

        脉动阵列设计方法学将一个N维的依赖图映射到一个低维的脉动阵列。在本文中,只考虑一级映射,即将一个N维的依赖图映射到一个(N-1)维的脉动阵列(对于FIR滤波器而言是将2维依赖图映射到1维脉动阵列)。

        下面定义脉动阵列设计中的基本向量:

  • 投影向量(也称迭代向量):\boldsymbol{d} = (d_{1}, d_{2}),如果两个节点间的距离为投影向量的整数倍,则他们由同一个处理单元计算。
  • 处理器空间向量:\boldsymbol{p} = (p_{1}, p_{2}),任何坐标为\boldsymbol{I} = (i, j)的节点由处理单元\boldsymbol{p} \cdot \boldsymbol{I}计算。
  • 调度向量:\boldsymbol{s} = (s_{1}, s_{2}),任何坐标为\boldsymbol{I} = (i, j)的节点在时间步\boldsymbol{s} \cdot \boldsymbol{I}计算。
  • 硬件利用率:\boldsymbol{HUE} = 1 / ( \boldsymbol{s} \cdot \boldsymbol{d}),这是因为同一个处理单元的两次计算相隔\boldsymbol{s} \cdot \boldsymbol{d}

        对于给定的问题,可以通过选择不同的投影向量、处理器空间向量和调度向量来设计多种脉动阵列,但这些向量必须满足以下推导出的两个可行性约束。

        1、处理器空间向量和投影向量必须彼此正交(内积为0)。如果节点A和B间的距离等于投影向量的整数倍,即\boldsymbol{I_{A}} - \boldsymbol{I_{B}} = n\boldsymbol{d},则这两个节点由同一个处理单元计算,所以\boldsymbol{p} \cdot \boldsymbol{I_{A}} = \boldsymbol{p} \cdot \boldsymbol{I_{B}},即\boldsymbol{p} \cdot (\boldsymbol{I_{A}} - \boldsymbol{I_{B}}) = 0 \rightarrow n\boldsymbol{p} \cdot \boldsymbol{d} = 0

        2、如果节点A和B被映射到同一个处理器,那么它们不能同时计算,所以\boldsymbol{s} \cdot \boldsymbol{I_{A}} \neq \boldsymbol{s} \cdot \boldsymbol{I_{B}},即\boldsymbol{s} \cdot (\boldsymbol{I_{A}} - \boldsymbol{I_{B}}) \neq 0 \rightarrow n\boldsymbol{s} \cdot \boldsymbol{d} \neq 0

        将空间表示转换为空间-时间表示时,引入处理器轴\boldsymbol{j^{'} }= \boldsymbol{p} \cdot \boldsymbol{I},时间步轴\boldsymbol{t^{'}} = \boldsymbol{s} \cdot \boldsymbol{I}。 

        将依赖图映射到脉动阵列时,每个依赖图中的边\boldsymbol{e}对应脉动阵列中的一个延时边,方向\boldsymbol{p} \cdot \boldsymbol{e},延时值为\boldsymbol{s} \cdot \boldsymbol{e}

设计1(输入广播、权重保持、输出移动)

        设计1通过选择如下投影向量、处理器向量和调度向量得到:

\boldsymbol{d} = (1, 0)\, \, \, \, \, \boldsymbol{p} = (0, 1)\, \, \, \, \, \boldsymbol{s} = (1, 0)

        可以很容易地验证,这些向量满足提到的两个可行性约束,并且可得到:

  • 任何坐标为\boldsymbol{I} = (i, j)的节点由处理单元\boldsymbol{p} \cdot \boldsymbol{I} = j计算,即同一条水平线上的节点由同一个处理单元计算。
  • 任何坐标为\boldsymbol{I} = (i, j)的节点在时间步\boldsymbol{s} \cdot \boldsymbol{I} = i计算。
  • 硬件利用率为\boldsymbol{HUE} = 1 / ( \boldsymbol{s} \cdot \boldsymbol{d}) = 1

        在空间-时间表示中,处理器轴\boldsymbol{j^{'} }= \boldsymbol{p} \cdot \boldsymbol{I}对应空间表示中的\boldsymbol{j}轴,时间步轴\boldsymbol{t^{'}} = \boldsymbol{s} \cdot \boldsymbol{I}对应空间表示中的\boldsymbol{i}轴,如图2所示。

图2 FIR滤波器的依赖图(空间-时间表示)

        由图2可以看出,输入在同一时间步会被广播到所有的处理单元,权重会保持在相应处理单元中而输出则出现在不同的处理单元和时间步。

        将依赖图映射到脉动阵列时,边映射的情况如表1所示。

表1 设计1的边映射情况

\boldsymbol{e}\boldsymbol{p}\boldsymbol{s}\boldsymbol{p} \cdot \boldsymbol{e}(方向)\boldsymbol{s} \cdot \boldsymbol{e}(延迟)

输入:(0, 1)

(0, 1)(1, 0)10
权重:(1, 0)01
输出:(1, -1)-11

        图3给出了设计1的脉动阵列框图,其中D代表有延时单元(如寄存器)的边。

图3 设计1的脉动阵列框图

        设计1的具体实现如图4所示。

图4 设计1的具体实现

Verilog实现

module PE #(
    parameter WEIGHT = 8'shA5   // 定义参数,默认为8位有符号常数A5
)(
    input wire clk,                    // 时钟信号
    input wire rst,                    // 重置信号
    input wire signed [7:0] data_in,   // 8位有符号输入数据
    input wire signed [31:0] sum_in,   // 32位有符号加法输入值
    output wire signed [31:0] sum_out  // 32位有符号输出结果
);

    reg signed [7:0]  weight = WEIGHT;   // 使用参数传递的值来代替内部常数
    reg signed [31:0] mul_result;        // 存储乘法结果
    reg signed [31:0] add_result;        // 存储加法结果
    reg signed [31:0] reg_out;           // 存储输出寄存器的值

    // 乘法操作(组合逻辑)
    always @(*) begin
        mul_result = data_in * weight;    // 乘法操作,乘以PE内部的常数值
    end

    // 加法器操作
    always @(*) begin
        add_result = mul_result + sum_in; // 乘法结果与加法输入相加
    end

    // 输出寄存器
    always @(posedge clk or posedge rst) begin
        if (rst) begin
            reg_out <= 32'b0;      // 复位时清零输出寄存器
        end else begin
            reg_out <= add_result; // 输出加法器的结果
        end
    end

    // 输出信号
    assign sum_out = reg_out;

endmodule

module FIR_ststolic_arrays (
    input wire clk,                   // 时钟信号
    input wire rst,                   // 重置信号
    input wire signed [7:0] data_in,  // 顶层输入数据
    output wire signed [31:0] sum_out // PE0的输出
);

    // 中间信号
    wire signed [31:0] sum_out_1_wire;  // PE1的sum_out连接到PE0的sum_in
    wire signed [31:0] sum_out_2_wire;  // PE2的sum_out连接到PE1的sum_in

    // 实例化PE0
    PE #(
        .WEIGHT(8'shA5)  // 设置PE0的weight值
    ) PE0 (
        .clk(clk),
        .rst(rst),
        .data_in(data_in),        // 顶层的data_in连接到PE0的data_in
        .sum_in(sum_out_1_wire),  // PE0的sum_in连接到PE1的sum_out
        .sum_out(sum_out)         // PE0的sum_out输出到顶层sum_out_0
    );

    // 实例化PE1
    PE #(
        .WEIGHT(8'shB7)  // 设置PE1的weight值
    ) PE1 (
        .clk(clk),
        .rst(rst),
        .data_in(data_in),       // 顶层的data_in连接到PE1的data_in
        .sum_in(sum_out_2_wire), // PE1的sum_in连接到PE2的sum_out
        .sum_out(sum_out_1_wire) // PE1的sum_out输出到PE0的sum_in
    );

    // 实例化PE2
    PE #(
        .WEIGHT(8'shC3)  // 设置PE2的weight值
    ) PE2 (
        .clk(clk),
        .rst(rst),
        .data_in(data_in),       // 顶层的data_in连接到PE2的data_in
        .sum_in(32'b0),          // PE2的sum_in设为0
        .sum_out(sum_out_2_wire) // PE2的sum_out输出到PE1的sum_in
    );

endmodule

        本文参考《VLSI Digital Signal Processing Systems Design and Implementation》,作者为
Keshab K.Parhi。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot mvn 打包,jar和资源文件分离打包

默认打包方式如下&#xff1a; <build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><execution…

5G CPE核心器件-基带处理器(三)

5G CPE 核心器件 -5G基带芯片 基带芯片简介基带芯片组成与结构技术特点与发展趋势5G基带芯片是5G CPE中最核心的组件,负责接入5G网络,并进行上下行数据业务传输。移动通信从1G发展到5G,终端形态产生了极大的变化,在集成度、功耗、性能等方面都取得巨大的提升。 基带芯片简…

【JavaWeb后端学习笔记】SpringBoot框架下Http请求参数接收

Http请求参数接收 1、简单参数2、实体参数3、数组参数4、集合参数5、日期参数6、Json格式参数&#xff08;常用&#xff09;7、路径参数&#xff08;常用&#xff09;8、接收请求参数常用的几个注解 Http请求能携带各种格式的请求参数。因此也就需要不同的接收方式。 1、简单参…

在 MacOS 上为 LM Studio 更换镜像源

在 MacOS 之中使用 LM Studio 部署本地 LLM时&#xff0c;用户可能会遇到无法下载模型的问题。 一般的解决方法是在 huggingface.co 或者国内的镜像站 hf-mirror.com 的项目介绍卡页面下载模型后拖入 LM Studio 的模型文件夹。这样无法利用 LM Studio 本身的搜索功能。 本文将…

Vue工程化开发中各文件的作用

1.main.js文件 main.js文件的主要作用&#xff1a;导入App.vue&#xff0c;基于App.vue创建结构渲染index.html。

Grule前端表单post后端执行grule引擎规则

Grule前端表单post后端执行grule引擎规则 编写前端表单和后端接口 编写test.go执行grule引擎规则 示例都是 go test 执行的测试代码&#xff0c;所以将里面的测试代码去除 由于之前 NumberExponentExample_test.go 已经验证可运行, 所以将 err 的异常处理去除 package mai…

Android hid 数据传输(device 端 )

最近一直在处理hid 数据需求&#xff0c;简而言之就是两台设备直接可以通过usb 线互相传递数据。 项目架构 为什么Device 端要采用HID&#xff08;人机接口设备&#xff09;的方式发送和接收数据呢&#xff1f; 主要是速度快&#xff0c;举个例子&#xff0c;就是鼠标移动&am…

【Unity基础】Unity中Transform.forward的详解与应用

在Unity中&#xff0c;Transform.forward 是一个常用属性&#xff0c;它表示物体的“前方”方向&#xff0c;即物体本地坐标系中 Z 轴&#xff08;蓝色轴&#xff09;在世界坐标系中的方向。它动态反映物体的旋转情况&#xff0c;非常适合用于移动、检测、方向控制等场景。 什么…

基于 RWKV 的视觉语言模型 VisualRWKV 被 COLING 2025 接收!

基于 RWKV 的视觉语言模型 VisualRWKV 被 COLING 2025 接收&#xff01; COLING&#xff0c;国际计算语言学会议&#xff08;International Conference on Computational Linguistics&#xff09;&#xff0c;是自然语言处理和计算语言学领域的顶级国际会议&#xff08;CCF 推…

如何加强游戏安全,防止定制外挂影响游戏公平性

在现如今的游戏环境中&#xff0c;外挂始终是一个困扰玩家和开发者的问题。尤其是定制挂&#xff08;Customized Cheats&#xff09;&#xff0c;它不仅复杂且隐蔽&#xff0c;更能针对性地绕过传统的反作弊系统&#xff0c;对游戏安全带来极大威胁。定制挂通常是根据玩家的需求…

斯坦福李飞飞《AI Agent:多模态交互前沿调查》论文

多模态AI系统很可能会在我们的日常生活中无处不在。将这些系统具身化为物理和虚拟环境中的代理是一种有前途的方式&#xff0c;以使其更加互动化。目前&#xff0c;这些系统利用现有的基础模型作为构建具身代理的基本构件。将代理嵌入这样的环境中&#xff0c;有助于模型处理和…

Lua面向对象实现

Lua中的面向对象是通过表&#xff08;table&#xff09;来模拟类实现的&#xff0c;通过setmetatable(table,metatable)方法&#xff0c;将一个表设置为当前表的元表&#xff0c;之后在调用当前表没有的方法或者键时&#xff0c;会再查询元表中的方法和键&#xff0c;以此来实现…

flex布局容易忽略的角色作用

目录 清除浮动 作用于行内元素 flex-basis宽度 案例一&#xff1a; 案例二&#xff1a; 案例三&#xff1a; flex-grow设置权重 案例一&#xff1a; 案例二&#xff1a; 简写flex-grow:1 0 auto; flex作为一维布局,行和列的使用&#xff0c;忽略的小角色&#xff0c;大…

Arduino IDE for mac 无法加载界面

打开软件后&#xff0c;无法加载界面的问题 1.手动删除“~/Library/Arduino15”文件夹 2.终端中输入sudo nano /etc/hosts&#xff0c;在里面添加“127.0.0.1 localhost”

【短视频SEO矩阵源码开发技术解析——框架应用分享】

为了部署短视频SEO矩阵系统&#xff0c;需要遵循以下核心步骤&#xff1a;首先&#xff0c;需掌握一系列关键技术和知识&#xff0c;涵盖但不限于相关领域的专业技能。 为了确保短视频SEO矩阵系统源代码能够顺利部署&#xff0c;首先需要构建一个适宜的服务器环境。您可以选择…

探索前端世界的无限可能:玩转Excel文件

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

本地运行打包好的dist

首先输入打包命令 每个人设置不一样 一般人 是npm run build如果不知道可以去package.json里去看。 打包好文件如下 命令行输入 :npm i -g http-server 进入到dist目录下输入 命令cmd 输入 http-server 成功

鸿蒙 DevEco Studio 设置状态栏,调用setWindowSystemBarProperties不生效

参考文章&#xff1a;设置状态栏&#xff0c;调用setWindowSystemBarProperties不生效 我使用 setWindowSystemBarProperties 设置状态栏&#xff0c;不生效。 import window from ohos.window;export default {data: {title: World},setSystemBar() {var windowClass null;…

MacOS安装软件后无法启动报错:“已损坏,无法打开,你应该将它移到废纸篓“

目录 报错截图 解决方法 知识科普 报错截图 解决方法 1. 打开系统设置->安全性与隐私->选择任何来源 2. 如果打开没有看到"任何来源"&#xff0c;如果不开启“任何来源”的选项&#xff0c;会直接影响到无法运行的第三方应用。开启“任何来源”的方法如下&a…

Linux-用户和权限

文章目录 一. 用户1. 用户分类① root用户(超级管理员)② 普通用户Ⅰ. 创建普通用户命令 ③ root用户与普通用户Ⅰ. 权限区别Ⅱ. 切换用户命令Ⅲ. sudo命令Ⅳ. 为普通用户配置sudo认证 2. 用户组① 用户,用户组② 创建用户组命令② 删除用户组命令② 用户管理命令③ getent 二.…