完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
作者:张宇弘, 王界兵, 汪乐宇, 严晓浪
引 言 片上系统( system on chip,SOC) 已经成为21世纪全球瞩目的关键核心技术。SOC 具有垂直整合的特性,并注重创新和创意,产品非常个人化、应用差异化、样式多元化。SOC 应用需求的广泛性,以及大部分SOC 应用功能单一、性质确定的特点,决定了SOC 目前大多是针对专门的应用领域进行专门设计来满足高性能、低成本和低功耗的要求。目前SOC 的发展趋势是:体系结构需要在新技术与产品、市场和应用需求之间取得平衡;设计方法趋向于走专用、定制和自动化的道路。 一方面由于SOC 的专用化设计要求,另一方面由于IP 提供商的支持, SOC 的集成设计方法正向参数化设计发展。SOC 的参数可能影响系统功耗、性能和面积,每个参数的选择范围是一个有限集合,因此一个SOC 设计可以理解为一组SOC 参数的选择。在系统结构形成后,SOC 设计问题就转变为参数配置问题。随着参数的增多,手工对代码进行修改是不可接受的,这不仅效率低,而且会增加错误率。本文对原有的硬件描述语言进行扩展,并建立了参数自动配置环境,通过分析SOC 参数属性,利用邻域搜索算法针对功耗进行自动参数优化。 |
|
相关推荐
3个回答
|
|
参数自动配置设计方法
采用传统的硬件描述语言(HDL) ,参数自动配置的难点在于:首先模块本身的描述随参数配置的改变而变化; 其次当模块被更上层的父模块例化(instance) 时,其接口逻辑在不同参数配置下也可能不同。在进行参数化设计时,只能采用硬件描述语言的宏定义,这种方法不仅不够灵活,而且代码复杂,冗余很多。 参数自动配置环境由一组运行脚本组成,主要通过两个工具Eperl 和Vperl 来进行参数配置,实现了代码的即配置即生成。Eperl 的作用是定制内部的逻辑,Vperl 的作用是生成模块间的连接关系。基于Verilog 硬件描述语言的参数自动配置过程如下。 1) 参数首先被送到3.evp 文件,这是同时包括Eperl 语法和Vperl 语法的文件,因为Eperl 和Vperl 电路的语法非常简洁,所以设计师不仅不用担心会在这里陷入困境,反而会大大减少设计强度。 2) 3.evp 文件经过Eperl 处理后生成3.vp 文件,这是只包含Vperl 语法的文件,这时所有的参数都被解析,模块内参数配置都已经完成了。 3) 3.vp 经过Vperl 处理后, 最后生成3.v 文件, 即电路的Verilog 描述。因此在参数化设计中,与传统设计不同,设计师的描述文件是3.evp 文件,而Verilog 代码只是作为设计的中间代码出现。参数自动配置环境建立了一系列脚本程序来自动解析相关文件的相互关系,并生成整个系统的硬件描述语言描述。 Eperl 最初用作HTML 页面生成,适合于静态文本相当多,但是又有一部分代码需要动态生成的场合。因为大多数硬件描述是静态代码,只有一小部分需要可配置,所以Eperl 非常适用于电路的硬件描述。Eperl 结合了Perl 的解释功能,相当于在原文本结构中插入了一段内嵌代码。这段内嵌代码最终可以生成想要配置的硬件结构。Eperl 利用Print 结构来传递所有的内嵌代码。Eperl 所做的相当于程序员写一个用于生成代码的Perl 脚本。下面所示程序段是从dma _fifo.evp 文件中提取的一部分代码。 ∥Synchronous FIFO.fifo_depth x fifo_width bit words. &ModuleBeg ; &Ports ; &Regs ; &Wires ; < : $width_m***=$fifo_width21 ; $depth_m***=$fifo_depth21 ; $ptr_width=log ( $fifo_depth)/log (2) ; $ptr_m***=$ptr_m***21 ; : > &Force (mem,fifomem, < :=$width_m*** : >,0, < :=$depth_m*** : >,0) ; …… ∥Update FIFO memory. always @(posedge clk) begin if ( rstp== 1′b0 & & writep== 1′b1 & & fullp== 1′b0) fifomem [ head ] <=din [ < :=$width_m*** : > :0 ] ; end ∥Update the head register. always @(posedge clk) begin if ( rstp== 1’b1) head [:0]<=′b0 ; else if (writep== 1′b1 & & fullp== 1′b0) head [ < :=$pt r_m*** : > :0 ] < = head [ < :=$pt r_m*** : > :0 ] + 1 ; end .. |
|
|
|
在< :…… : > 中的就是Eperl 代码,以& 开始的是Vperl 代码, 如&ModuleBeg 表示模块的开始。在FIFO 中,可配置的参数主要是2 个: FIFO 深度和FIFO 宽度,所以dma_fif.evp 文件对外只有2 个参数可调, 而其他的比如定义信号所需要的FIFO 寄存器的最高位width_m*** 、head 指针的宽度ptr_width 等都可以用Eperl 脚本生成。这与宏定义相比体现了Eperl 的灵活性。再比如可以通用寄存器组gpr.evp 文件利用for 循环来例化每一个寄存器,更充分地体现了使用Eperl 的灵活性。for 循环的代码如下所示。
for($i = 0;$iprint&Instance (iu_register,iu_register_$i ); ; } : > …… 3.evp 格式的文件经过Eperl 解析后生成 3.vp格式的文件。dma _fifo.evp 经过Eperl 解析后生成的3.vp 文件如下所示。 ∥Synchronous FIFO.fifo_depth x fifo _width bit words。 &ModuleBeg ; &Ports ; &Regs ; &Wires ; &Force (mem ,fifomem ,15 ,0 ,3 ,0) ; …… ∥Update FIFO memory。 always @(posedge clk) begin if (rstp== 1′b0 & & writep==1′b1 & &fullp==1′b0) fifomem [head]<= din [15 :0] ; end ∥Update the head register。 always @(posedge clk) begin if (rstp = = 1′b1) head [1 :0 ] < = 2′b0 ; else if (writep = = 1′b1 & & fullp = = 1′b0) head [1 :0 ] < = head [1 :0 ] + 1 ; end …… |
|
|
|
当然IP 模块的不同配置会造成SOC 系统信号的不同。如向系统中添加通用异步收发器(UART)模块,SOC 系统就要增加输入输出端口,并且要增加很多内部的连线,比如把IP 总线引入UART.Vperl 程序可以解决这个问题。
Vperl 的工作原理是通过分析模块内使用的信号的属性来确定模块的信号定义。HDL 具有一定的语法结构,比如Verilog 有2 种信号类型,always 块中的<= 操作符左边一定是reg 类型信号,由此取reg 类型的补集就是wire 类型,除非显式地通过&Force()声明为其他类型,如在dma_fifo.vp 中的第6 行代码,声明为二维reg 数组类型。分析模块也可以确定模块的输入输出,如果一个信号在模块中自始至终没有被赋值过,那么这个信号必然是input信号;同理,如果一个信号被赋值但从来没被使用过,就是output 信号; 如果既被赋值过,又被使用过,那么这个信号有很大可能是这个模块的内部信号,不是模块的端口,除非显式地通过&Force ( ) 声明为inout类型。对于模块中例化的子模块(在3.vp 中用&Instance() 语句声明) ,Vperl 程序首先分析模块间的从属关系,并先处理最底层的子模块代码,在自动分析子模块接口的输入输出属性后,缺省地把子模块的输入输出信号作为上层模块的接入信号,并在上层模块中自动进行连接,当然Vperl 也提供了&Connect () 语句来更改子模块接入上层模块的信号名。所以用Vperl 的格式书写的文件3.vp不需要在文件头部定义信号名。如下所示是dma_fifo.vp 文件的示例代码。 ∥Synchronous FIFO.fifo _depth x fifo _width bit words。 module dma _fifo (clk,rstp,din,writep,readp,dout ,emptyp,fullp); input clk; input rstp; input [15:0] din; input readp; input writep; output [15:0]dout; output emptyp; output fullp; reg emptyp; reg fullp; reg [15:0]dout; reg [ (DEPTH-1):0 ] tail; reg [ (DEPTH-1):0 ] head; reg [ (DEPTH-1):0 ] count; reg [15:0 ] fifomem [0:MAX_COUNT]; …… ∥Update FIFO memory。 always @(posedge clk) begin if ( rstp==1′b0 && writep==1′b1 &&fullp==1′b0) fifomem [head]<= din [15:0]; end ∥Update the head register。 always @(posedge clk) begin if ( rstp==1′b1) head[1:0 ]<=2′b0; else if (writep==1′b1 & & fullp==1′b0) head[1:0 ]<=head[1:0 ] + 1; end …… |
|
|
|
只有小组成员才能发言,加入小组>>
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 06:53 , Processed in 0.971257 second(s), Total 80, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号