基于模型设计的FPGA开发与实现
数字滤波器的设计与实现之基本流程
数字滤波器辅助设计
2011年6月26日
11:18
AuthorbyMcCrocodile
http://blog.sina.com.cn/McCrocodile
如何快速高效的设计数字滤波器时本章节的重点。
数字滤波器通常用于改变信号的时域或者频域的某个特性。最简单的数字滤波器时
LTI先行时间不变滤波器。通常分为有限冲击相应FIR和无限冲击相应IIR。
传统的模拟滤波器是借助RLC和运算放大器实现,随着DSP和FPGA的出现,数字滤
波器借助其优势在某些领域正在逐渐取代模拟滤波器。使用拉普拉斯域分析的模拟原型方
法只适用于IIR设计,FIR设计需要新的计算算法。此处主要介绍基于Matlab的设计与实现,
随后还探讨基于FPGA的实现和改进。
这里首先来回顾下滤波器的理论知识,
屏幕剪辑的捕获时间:2011/8/2222:09
屏幕剪辑的捕获时间:2011/8/2222:10
下面主要介绍基于GUI和Fdesign的方式设计滤波器,和基本的定点化功能以及HDL代码
生成功能的使用。由于介绍命令行设计滤波器的资料比较多,这里就不错介绍。
滤波器设计之GUI
2011年8月22日
21:32
使用GUI设计的方式有两种:FDATool和filterbuilder。
FDATool
设计实例:
这儿以设计一个低通滤波器分离两个信号为例,介绍使用fdatool设计FIR滤波器。
要求:输入信号x1+x2,x1为100Hz正弦信号,x2为300Hz正弦信号,采样率为
3KHz
期望输出为x1.
屏幕剪辑的捕获时间:2011/8/2222:38
如上图所示为使用Equiripple等纹波法设计一个直接型FIR滤波器,Fs为采样率为
3KHz,Fpass通带最大频率110Hz,Fstop阻带最小频率为230Hz,Apass通带纹波
0.1dB,Astop阻带衰减60dB。[通俗来讲可以认为是在0~230Hz,通带的纹波不会超过
0.1dB,阻带从230Hz起最小衰减不小于60dB].下面是帮助文档中的描述,详细查阅帮
助和其他参考资料了。
屏幕剪辑的捕获时间:2011/8/2222:52
观察设计的滤波器的性能:
这儿采用两种方法来测试,首先使用Matlab的脚本测试。
1)导出滤波器系数到MatlabWorksapce中,File-->Export….可以选择导出系数或
者对象,此处我选择导出为对象,
fs=3e3;
t=0:1/fs:0.1;
x1=sin(1002pi.t);
x2=sin(3002pi.t);
x=x1+x2;%inputSignal
y=filter(Hd_firlp,x);%滤波
%观察结构
figure;subplot(4,1,1);plot(t,x1);title(''100Hz'')
subplot(4,1,2);plot(t,x2);title(''300Hz'')
subplot(4,1,3);plot(t,x);title(''Inputsignal'')
subplot(4,1,4);plot(t,y);title(''Filteroutput'')
屏幕剪辑的捕获时间:2011/8/2223:15
有图可以分析FIR滤波器的性质,可以调整滤波器设计的参数观察结构的差异。
2)使用Simulink模型测试结构,有时候是非常必要的,也是MBD-FPGA数
字信号处理中我所建议的。
在File-->ExporttoSimulink对话框中选择导出模块类型。
屏幕剪辑的捕获时间:2011/8/2223:25
屏幕剪辑的捕获时间:2011/8/2223:25
等纹波法经常用于设计FIR,甚至可以用来设计希尔伯特滤波器和积分器。选择窗
口中左侧和上边的不同菜单,熟悉其功能,尝试修改参数,观察对滤波的影响,更多
地东西你可以查阅帮助文档。
FilterBuilder
使用命令行:filterbuilder启动GUI,如下图,之后选择需要设计的滤波器类型。
屏幕剪辑的捕获时间:2011/8/2820:45
同样以上面的例子为例,设计一个滤波器,下面的图可以看出来,里面的选项大同小
异,所以使用也是大致差不多,喜欢用哪个就用哪个就用那个了。
屏幕剪辑的捕获时间:2011/8/2820:47
同样的方式也可以用于设计IIR滤波器,总结下这种滤波器的设计方法基本步骤为:
A、选择一个设计方法
B、尝试(猜测)参数,然后设计滤波器
C、观察滤波器的响应是否符合要求
D、测试知道满足要求
你尝试过上面所有的方法的吗?如果还没有抓紧,只有尝试你才会真正的
明白。
滤波器设计之Fdesign
2011年8月22日
21:33
首先说说Matlab字r2008a之后面向对象的功能变得越来越强大,尤其是在
R2011a中的DSPSystemToolBox,CommunicationsystemToolbox等系统级的工具箱的
整合和出现,面向对象编程方式变得更重要了。如设计DUC和DDC等都可以使用,也
是MBD相SystemDesign发展的一个重要体现吧。
fdesign是一个filterdesignobject滤波器设计对象,使用fdesign作为一种比较新的
设计滤波方法。滤波器实现的对象主要有三种:
dfilt:单速滤波器(本小节主要涉及到的)
mfilt:多速率滤波器(后面会介绍到)
adaptfilt:自适应滤波器(后面会介绍到)
上一小节最后部分总结了基于GUI的设计方法的基本步骤,这些步骤对于基于传
统的命令行方式设计的同样也使用。那么问题就出来了:对设计的权衡是低效的。Not
efficientforassessingdesigntrade-offs。效率就是基于fdesign设计方法的优势。
面向对象的滤波器设计方法的基本步骤:
1、创建fdesign对象,设置设计的需求
2、找出满足需求的设计方法
3、使用各种可能的方法设计滤波器,并比较选择。
4、分析权衡各设计之间的性能资源:滤波器阶数与阻带衰减和通带波纹,滤波器阶数与
过渡带宽度,算法延时和计算复杂度。
下面还是以一个例子简要说明基于fdesign的单速滤波器设计,完成目标还是分离上一
节中的两个信号:
%使用fdesign方式设计简单单速滤波器
d=fdesign.lowpass%创建一个低通滤波器对象
%%设置设计要求
d.Fpass=100/3e3;
d.Fstop=250/3e3;
d.Apass=1;
d.Astop=60
%d=fdesign.lowpass(''Fp,Fst,Ap,Ast'',100,250,1,60,3e3);%另外的方式1
%d=fdesign.lowpass(0.0333,0.0833,1,60);%另外的方式2
%%查找满足要求的方法
designmethods(d)
%designmethods(d,''fir'')
%%设计滤波器
hd=design(d,''equiripple'');
%%分析滤波器
fvtool(hd);
cost(hd)%计算开销
info(hd)
cost(hd)
ans=
NumberofMultipliers:86
NumberofAdders:85
NumberofStates:85
MultiplicationsperInputSample:86
AdditionsperInputSample:85
上面采用了等纹波法设计了滤波器,还以采用其他的方式设计并比较观察。
%%仿真测试
fs=3e3;
t=0:1/fs:0.1;
x1=sin(1002pi.t);
x2=sin(3002pi.t);
x=x1+x2;%inputSignal
y=filter(hd,x);%滤波
plot(t,y);title(''Filteroutput'')
%%生成Simulink模块
realizemdl(hd)
同样生成Simulik模块可以加入Simulink模型中仿真测试。具体的用法请查阅帮助文档。
屏幕剪辑的捕获时间:2011/8/2523:48
这儿由于还没有定点化,所以给HDL代码生成的部分放到后面一小节介绍。下面是
Mathworks给出的资料图。
屏幕剪辑的捕获时间:2011/8/3021:08
如果你想深入了解基于fdesign的滤波器设计,建议你深入阅读帮助文档,
并尝试里面提供的Demo,这儿仅仅作为简单的入门介绍。尝试之后你才会
理解到功能的强大和高效省事。
滤波器定点化
2011年8月29日
22:18
AuthorbyMcCrocodile
通常在FPGA中做信号处理为达到比较高的fMax和较少的资源占用,通常使用定点
化数字信号处理,虽然FPGA厂商和IP提供商提供了一些浮点IP,但是目前大多数应
用还是趋向定点化处理。这里主要介绍在设计滤波器中使用工具中的定点化选项,实
现滤波器的定点化,为后面一节的HDL代码生成做铺垫。
这儿还是使用前面的例子,来实施定点化。
FDAtool中定点化
如下图所示为FDATool中的定点化过程中截图,选择左侧设置量化参数(Set
QuantizationParameters)按钮,在滤波器结构栏选择定点,滤波器精度有最高精度和
指定精度,通常使用指定精度这样比较节约资源,最后部分为对滤波器的参数,输入
数出和滤波器内部进行定点化设计。
在设置滤波器内部的参数,如乘法器,累加器的精度和整数的溢出模式。在设置
精度是通常开始设置较大的精度和动态范围,满足要求后再优化。整数溢出的模式
Wrap模式占用资源最少,但是如果正式部分动态范围不够会带来糟糕情况,而且不利
于整体的稳定性;Staturate会占用额外的逻辑资源。
FilterBuilder中定点化
从下图可以看得出与FDATool的定点化设置是一致的。这儿就不再做介绍了。
fdesign中的定点化
(准确的应该成为使用面向对象的方式的滤波器定点化)
详细的帮助中搜索Fixed-PointFilterDesign。
前面介绍的基于GUI的定点化都是一个根据经验的迭代化的优化过程,下面来详
细的说下基于fdesign的定点化过程。
滤波器的定点化包含两个主要的部分:滤波器数的量化和动态范围分析。(The
dynamicrangeanalysisisaprocessoffinetuningthescalingofeachnodetoensurethatthe
fractionlengthsaresetforfullinputrangecoverageandmaximumprecision。)
1、首先修改滤波器对象属性为定点的:(当然这儿的滤波器对象也可以来自于fdatool
等设计的导出的滤波器对象)
Hf=hd;
Hf.Arithmetic=''fixed'';
2、初步设置滤波器系数的字长
set(Hf,''CoeffWordLength'',9);%设置滤波器系数的字长
fvtool(Hf)%,比较不同字长设置
屏幕剪辑的捕获时间:2011/8/3022:22
可以清晰的观察到定点化和浮点的幅频响应的区别,通过观察是否满足要
求进一步优化滤波器系数的字长,增加字长达到更高的性能,缩减字长节约资源
减小面积。如在Altera的QII中,如果乘数是固定且位宽比较小(比如小于10bit
时),综合时会使用移位和加法实现乘法(有点类似于RAG算法),但当乘数
比较大时则需要使用硬件乘法器。如果较小片子硬件乘法器不足就是个糟糕的事
情了。
3、设置滤波器内部的位宽:累加器,乘法器,输出信号
info(Hf)%有观察到的信息可以看出位宽过宽
屏幕剪辑的捕获时间:2011/8/3022:32
如图所示可以看到,自动设置的位宽以及其动态范围,这些自动设置的位
宽通常是首先满足精度,还需要根据硬件(DSP,FPGA)特性做修改。下面针对
Altera的CIII片子给出一个设置:(不同的滤波器结构设置的选项不同)
set(Hf,''InputWordLength'',10);%输入ADC位宽
set(Hf,''FilterInternals'',''SpecifyPrecision'');%设置滤波器内部参数
set(Hf,''ProductWordLength'',18);%如Altera的CIII片子的乘法器为9的倍数,这
儿选18bit
set(Hf,''AccumWordLength'',22);%累加器的字长,通常累加器比乘法器多4比特作
为保护位宽
set(Hf,''OutputWordLength'',16);%输出数据总线
输入信号位宽通常和ADC是保持一致的,乘法器的位宽通常设置9的倍数
(某些高档片子含有DSP40,那就设置为40)。诸如硬件乘法器资源,如果想要
充分利用,那么你就需要参考器件的硬件特性。累加器通常要比乘法器宽4bit作
为保护比特。如果设置得过宽会造成累加器的时延过大,得不到一个较大的
fMax。
到这里滤波器的基本设置算是完成了,但是还是有可能在使用的使用发生溢
出等错误。动态分析将进一步优化滤波器的定点化设置,以降低溢出的发生。
4、动态分析:进一步精细调整系数的比例(Scaling)。
系数最好是又能覆盖所有输入信号,同时保持最大的精度,但这是互相矛盾的。
所以在动态分析过程中用于测试的输入数据的选择是非常重要的。如果设置较大
的动态范围,可以覆盖输入信号的范围,但是精度会损失;如果设置较窄的动态
范围,可以保持较好的精度,但是输入信号可能超出范围引起溢出。
最坏情况测试法:
1)源代码和报告如下,首先使用脉冲响应的取符号函数,设置信号最大幅度,
作为信号的激励。
2)以测试激励自动调整动态范围,如果不使用这个选项观察一下3中的报告时
什么样子的。
3)创建fipref对象开启记录模式,定点化滤波,观察定点化滤波过程的报告。
tx=2sign(fliplr(impz(Hf)));%激励
Hf2=autoscale(Hf,tx);%自动调整动态范围
fipref(''LoggingMode'',''on'',''DataTypeOverride'',''ForceOff'');%创建fipref对象打开记
录
y=filter(Hf2,tx);
fipref(''LoggingMode'',''off'');
R=qreport(Hf2)%查看报告,报告最近的顶点滤波计算报告
屏幕剪辑的捕获时间:2011/9/521:29
下面是对信号分离的定点化测试:
%%对信号分离的定点化测试
fipref(''LoggingMode'',''on'',''DataTypeOverride'',''ForceOff'');%创建fipref对象打开记
录
y=filter(Hf2,x);
fipref(''LoggingMode'',''off'');
R1=qreport(Hf2)%查看报告,报告最近的顶点滤波计算报告
figure;plot(y);title(''定点化滤波信号分离测试'')
屏幕剪辑的捕获时间:2011/9/521:39
屏幕剪辑的捕获时间:2011/9/521:39
通过上面的报告和滤波结果观察可以看出,定点化达到了效果。这就为后面HDL
代码生成做好基本的准备。
总结:
通过上面的例子,可以得知使用面向对象方式实现定点化是一个更优秀的方式。
根据测试的激励可以自动调整滤波器的精度以达到不同的动态范围,达到精度和动态
范围(过小会引起溢出)的权衡,那么也就看出合适的测试激励的重要性。这种滤波
器的定点化方法对IIR滤波器的定点化优势尤其明显。这里先不介绍,由于IIR的定点
化有时比较复杂,放到后面单独讨论。
所以建议亲自试试使用fdesign的方式。
滤波器的HDL代码生成
2011年8月29日
22:16
这里要介绍的内容可以在帮助文档FilterDesignerHDLCoder章节查找到相应的内容,包括:
如何在Matlab中生成滤波器的HDL代码,以及对生成的HDL代码加以测试(联合仿真)。
1、代码生成GUI的启动:
主要有三种方式:从Fdatool启动,从filterbuilder启动,命令行启动。
1)如下图所示从fdatool中启动代码生成,但是在这个之前你需要量化(定点化)滤波器
SetQuantizationParameters,甚至设置滤波器的结构Filterarithmetic。
2)filterbuilder中直接在代码生成面板CodeGeneration中,单击GenerateHDL启动HDL
生成GUI。
屏幕剪辑的捕获时间:2011/9/77:22
3)命令行启动:
fdhdltool(Hf2)
2、滤波器生成HDL的GUI及其设置:
屏幕剪辑的捕获时间:2011/9/922:28
与SimulinkHDLCoder相同的GlobalSettings选项这儿就不做介绍,留在SimulinkHDL
Coder中来介绍。这儿主要介绍滤波器HDL生成中的独有选项进行详细介绍,通过这些设
置可以优化生成的HDL代码,来满足要求。
1)生成HDL代码
简单设置之后就可以生成HDL代码了,我们这儿直接使用Generate按钮生成HDL,
以便和后面的精细设置之后的代码。下图为生成的代码部分截图。
屏幕剪辑的捕获时间:2011/9/922:43
2)生成测试激励或联合仿真模型:
如下图所示,在TestBench面板中选择Cosimulationmodelforusewith就可以生
成联合仿真模型。红色部分为联合仿真是需要测试的几个相应。包括脉冲响应、阶
跃响应、斜坡信号响应、啁啾响应、白噪声响应、自定义测试(此处是用第一节中
的测试用的x=x1+x2)
生成的联合仿真模型,如下图所示。这儿启动ModelSim的是单击StartHDLSimulator,
和Simulink模型生成联合仿真模型有一点区别。在启动ModelSim后不需要做任何设
置直接可以启动Simulink联合仿真。
屏幕剪辑的捕获时间:2011/9/923:08
来看下联合仿真的结果如下图。在观察下自定义测试的局部放大图。
最后看下ModelSim中观察到的结果及局部放大图。
总结:
利用filterdesignHDLCoder可以很方便的生成HDL和联合仿真,大大的减少了工作
量,可以让设计人员集中精力在算法和思想上来满足需求,不再拘泥于代码。
这时很多人可能有这么个问题,那么就是生成的滤波器所能到达的性能和效率?这
个问题的答案是:MBD可以做到一切!生成代码可以达到手写代码所能达到的任何需求甚
至更好,只要你使用合适。后面的一节将讨论滤波器代码生成简单优化和FPGA工程的时
序分析以及上片测试。
HDL代码优化
2011年9月9日
23:40
先来看看前面章节设计的滤波器对于实际应用是个多糟糕的设计!!!
上面一节中我们使用分离两个信号的滤波器高达60阶,如果我们要放大EP3C25中,
基本上是不可接受的,如果我们还有其他逻辑。EP3C25只有132个9bit的嵌入式乘法器。
屏幕剪辑的捕获时间:2011/9/1021:33
下面看下上一节生成代码的编译报告。可以从看出资源占用情况和可以工作的最大频率
fMax=3.28MHz,在很多应用中这个可以认为是一个失败的设计。原因和滤波器的阶数、滤波
器的结构等多个方面的有关系,如何针对FPGA优化设计,提高吞吐量等问题时本节主要
讨论的内容。
屏幕剪辑的捕获时间:2011/9/118:41
屏幕剪辑的捕获时间:2011/9/118:41
Fmax最大时钟速率很多情况下是最重要的问题。
1、滤波器的结构:info(Hf2)
上图所示为滤波器时直接型的FIR,下图为直接型FIR的结构,连串的加法器是最坏
路径,也是Fmax比较小的罪魁祸首。
这个问题需要在设计滤波器的时候选择合适的滤波器结构。下面看看直接传输
型FIR滤波器的结构。可以看出最坏路径是一个常数乘法器和一个加法器。这时候引
入新的问题:输入的信号有太多的扇出,着同样可能会造成FMax比较小,不过这个
问题很好解决,在滤波器的输入端口采用2~4级寄存器,并在HDL综合器中选择自
动复制寄存器,就可以解决问题。这儿不做深入讨论主要是说明解决问题的途径,
后面滤波器结构将分别对FIR和IIR滤波器做专门讨论。实现的过程在这节结尾有两
个例子,以供学习。
上面的结果可以看得出,滤波器的结构所带来的性能差异。FIR滤波器结构的
问题后面会在单速滤波器的FIR结构中详细介绍了。下面是以直接传输型的FIR为例
说明的,下面是源程序。
%提升滤波器性能之转换为直接传输型
%AuthorbyMcCrocodile@20110911
clearall;closeall;
loadTD2.mat
%%查看滤波器的结构
info(hd)
%%转换滤波器结构并定点化
Hf3=convert(hd,''df1t'')%转换滤波器结构,也可以在FDATool中手动转换
Hf3.Arithmetic=''fixed'';%滤波器做定点化处理
set(Hf3,''CoeffWordLength'',9);%设置滤波器系数的字长
%根据FPGA特性详细设置
set(Hf3,''InputWordLength'',10);%输入ADC位宽
set(Hf3,''ProductMode'',''SpecifyPrecision'');%设置滤波器内部乘法模式
set(Hf3,''ProductWordLength'',18);%如Altera的CIII片子的乘法器为9的倍数,这儿选
18bit
set(Hf3,''AccumMode'',''SpecifyPrecision'');%累加器的字长,通常累加器比乘法器多4比
特作为保护位宽
set(Hf3,''AccumWordLength'',28);%输出数据总线
set(Hf3,''OverflowMode'',''saturate'');%修改溢出模式,会增加面积
%自动调整
tx=2sign(fliplr(impz(Hf3)));%激励
Hf3=autoscale(Hf3,tx);%自动调整动态方位
fvtool(Hf3)%,比较不同字长设置
%%测试
%最坏情况测试
fipref(''LoggingMode'',''on'',''DataTypeOverride'',''ForceOff'');%创建fipref对象打开记录
y=filter(Hf3,tx);
fipref(''LoggingMode'',''off'');
R=qreport(Hf3)%查看报告,报告最近的顶点滤波计算报告
%对信号分离的定点化测试
fipref(''LoggingMode'',''on'',''DataTypeOverride'',''ForceOff'');%创建fipref对象打开记录
y1=filter(Hf3,x);
fipref(''LoggingMode'',''off'');
R1=qreport(Hf3)%查看报告,报告最近的顶点滤波计算报告
figure;plot(y1);title(''定点化滤波信号分离测试'')
%%生成Simulink模型
%直接传输型FIR滤波器不能直接生成代码,不过可以生成Simulink模型之后生成
HDL代码
realizemdl(Hf3)
2、滤波器中乘法器和加法器引起的最坏路径
这里以一个例子说明对乘法或者加法寄存器设置加入寄存器,来增加时序收敛
性。这里给出一个问题,是加法器设置寄存器在这儿起了作用?还是乘法器?还是
两者共同其做了?
源程序:
%提升滤波器性能之转换为直接传输型
%AuthorbyMcCrocodile@20110911
clearall;closeall;
loadTD2.mat
%%查看滤波器的结构
info(hd)
%%转换滤波器结构并定点化
Hf4=convert(hd,''dfsymfir'')%转换滤波器结构,也可以在FDATool中手动转换
Hf4.Arithmetic=''fixed'';%滤波器做定点化处理
set(Hf4,''CoeffWordLength'',9);%设置滤波器系数的字长
%根据FPGA特性详细设置
set(Hf4,''InputWordLength'',10);%输入ADC位宽
set(Hf4,''FilterInternals'',''SpecifyPrecision'');%设置滤波器内部乘法模式
set(Hf4,''ProductWordLength'',18);%如Altera的CIII片子的乘法器为9的倍数,这儿选
18bit
set(Hf4,''AccumWordLength'',22);%累加器的字长,通常累加器比乘法器多4比特作为保
护位宽
set(Hf4,''OutputWordLength'',16);%输出数据总线
set(Hf4,''OverflowMode'',''saturate'');%修改溢出模式,会增加面积
%自动调整
tx=2sign(fliplr(impz(Hf4)));%激励
Hf4=autoscale(Hf4,tx);%自动调整动态方位
fvtool(Hf4)%,比较不同字长设置
%%测试
%最坏情况测试
fipref(''LoggingMode'',''on'',''DataTypeOverride'',''ForceOff'');%创建fipref对象打开记录
y=filter(Hf4,tx);
fipref(''LoggingMode'',''off'');
R=qreport(Hf4)%查看报告,报告最近的顶点滤波计算报告
%对信号分离的定点化测试
fipref(''LoggingMode'',''on'',''DataTypeOverride'',''ForceOff'');%创建fipref对象打开记录
y1=filter(Hf4,x);
fipref(''LoggingMode'',''off'');
R1=qreport(Hf4)%查看报告,报告最近的顶点滤波计算报告
figure;plot(y1);title(''定点化滤波信号分离测试'')
%%生成HDL代码
fdhdltool(Hf4)
saveTD5.mat
不设置乘法器和加法流水寄存器
generatehdl(Hf4,''ResetType'',''Synchronous'',...
''OptimizeForHDL'',''on'',...
''Name'',''filter_Hf4'',...
''ResetAssertedLevel'',''Active-low'',...
''TargetLanguage'',''Verilog'');
设置加法流水寄存器
generatehdl(Hf4,''ResetType'',''Synchronous'',...
''OptimizeForHDL'',''on'',...
''Name'',''filter_Hf4'',...
''ResetAssertedLevel'',''Active-low'',...
''TargetLanguage'',''Verilog'');
或者使用GUI设置
上面的例子可以看出生成的代码性能差异明显。诸如对称性的滤波器可以节约,
但是并不是所有的滤波器都能够这样设置,这就需要根据滤波器的机构不同参考帮
助予以设置。
3、滤波器面积与速度平衡
最后给出了一些生成滤波器的其他几个优化选项。这些选项需要对照帮助文档
实践,再根据需要设置,一般都可以达到需要的性能。
屏幕剪辑的捕获时间:2011/9/1322:30
1)面积与速度平衡
在Architecture中设置为全并行还是串行,来实现面积与速度平衡。如果资源
不足可以采用串行节约资源,如果需要吞吐量则可以采用全并行。
2)使用流水线
请查看帮助
3)自定义HDL代码
请查看帮助
|
|