D2I | Anibal.Yeh‎ > ‎D2I | FPGA‎ > ‎

fpga | External Reference


一种matlab调用signaltap采集数据的方法

posted May 4, 2014, 6:46 PM by 葉宏

http://bbs.ednchina.com/BLOG_ARTICLE_3001675.HTM

         最近,在利用FPGA采集数据,前端是通过AD采集,然后直接输出给FPGA,需要分析采集到的数据,通常的办法只能在signaltap中,右击信号列表然后点击”Create SignalTap II List File”生成数据文件,操作如图1所示,图2为生成的数据文件,处理数据时先将文件中所有数据拷贝到ultraedit中,然后通过列模式提取需要处理的那列数据,拷贝到matlab中进行后续分析处理。

 

snap1.jpg

图1

 

snap2.jpg

图2

         上述操作方法过程比较繁琐,主要是手动操作比较多,如果需要采集的数据较多,则需要多次重复操作,真是体力活儿啊,难免然操作者产生厌烦心理。下面介绍一种通过matlab直接调用signaltap采集数据的方法。

         在matlab端只需要一下语句:

         addpath ('d:/altera/11.0sp1/quartus/bin');

         din = alt_signaltap_run('stp1.stp','signed');

         alt_signaltap_run('END_CONNECTION');

         其中addpath语句是将quartus软件路径加入进来;alt_signaltap_run语句执行数据的采集工作,当然此时对应的*.sof文件应该已经下载到FPGA中了,’signed’返回的是有符号数据;alt_signaltap_run('END_CONNECTION')语句表示断开由matlab建立的jtag连接。

         采用此方法,无需打开signaltap,matlab直接获取数据进行处理,免除了大量重复的手动操作,大大提高了工作效率。



[博客大赛]CPLD入门笔记2----驱动蜂鸣器ost

posted May 4, 2014, 6:43 PM by 葉宏

http://bbs.ednchina.com/BLOG_ARTICLE_3019872.HTM

驱动蜂鸣器的实验,实验参考EDN网站的akuei2的SOS的思想,利用蜂鸣器鸣叫不同时间模拟SOS,但遇到的问题。

 

一开始程序写好后,下载到板子上,蜂鸣器几乎没有声音输出,或者说很小的声音间隔输出。原认为是驱动时间的原因,就加长了驱动的时间,发现周期加至24S,short音段至1000ms,long音段至5000ms,invertal音段至200ms,仍然没有声音输出,声音反而比原来还要小,时间无论加长还是缩短,均不能发出满意的声音,测量蜂鸣器两端电压也正常。想了想,好像最开始的声音是最响的,突然想到,蜂鸣器会不会是无源的(无源蜂鸣器要求一定的脉冲频率,大概2KHz左右,才能驱动它,有源蜂鸣器加上电就可响),拆下来果然是无源的,换上有源蜂鸣器后,仍然不响,以为是驱动时间问题,便将引脚输出赋值给LED,发现LED基本按照程序变化。说明蜂鸣器出问题,便又查蜂鸣器端电压,引脚有电压,蜂鸣器就是没声音,换了个蜂鸣器,便“滴滴”鸣叫。晕,蜂鸣器竟然还有坏的。

 

这下听到了声音,但是声音不对,不是那种SOS的“滴滴滴,滴~滴~滴~,滴滴滴”,而是“滴滴滴,滴~滴~滴~,滴滴”,用LED看闪烁,发现也是这种现象。怎么也没有发现问题,以为是定义值,case(i)

 

定义错误,无论改变变量值,还是减少case语句,都不能显示出来。用示波器看也是少一个脉冲,重新找程序错误,发现定义变量a时这样定义的:reg[3:0] a;

 

     计算了下,当a计数满值时为:1111,换算为十进制为15,而最后一个脉冲要求计数值为:17,这样a计数不到17,便少一个脉冲,重新定义变量reg[4:0] a;这样a计数满值时为11111,为31,大于17,。这样用示波器就看到了9个脉冲,LED显示和蜂鸣器响也正常了。

 

总结几个小问题:

1、          硬件要保证没有问题,再去考虑软件的事。

2、          软件中,要注意计数变量的范围,,可以用多种方法检测芯片引脚输出是否符合预想值。

 

777777777777777.jpg
 
88888888888888888.jpg
附件:
变量修改前波形.png下载次数: 2
变量修改后波形.png下载次数: 1


Untitle[博客大赛]CPLD入门笔记1----点亮LEDd Post

posted May 4, 2014, 6:42 PM by 葉宏

http://bbs.ednchina.com/BLOG_ARTICLE_3019841.HTM

今天看了CPLD的教程,发现可编程芯片几乎都是以点亮LED作为最开始的入门实验,无论51单片机、STM8单片机、STM32单片机亦或是其他的芯片,感觉都是在控制它的引脚的电平,主要是了解如何让指定的引脚输出指定数的脉冲,指定的电平。好了,不多说了,看下代码,实现3个LED的轮番点亮

  计时一个单位时间,让LED0点亮,后进行移位,移位后等待下一个单位时间到来,便点亮LED1,后再移位,依次进行

module CPLD_LED_Delay(clk,rst_n,LED0,LED1,LED2);
   input clk;
   input rst_n;
   output LED0,LED1,LED2;
   
   reg[23:0] Counter;          //定义计数器,设置为寄存器类型
   //如果复位按键,计数器清零,否则进行计数
   always @(posedge clk or negedge rst_n)
      if(!rst_n)  Counter <= 1'd0;
      else Counter <= Counter + 1'b1;
   reg[2:0] led_reg;
   //如果Counter计数到值,
   always @(posedge clk or negedge rst_n)
      if(!rst_n) led_reg <= 4'b001;
      else 
        if(Counter == 24'd15_000_000)
          begin 
            if(led_reg == 4'b100)
            led_reg <= 4'b001;
            else
            led_reg <= led_reg << 1;    //led_reg执行左移一位  
          end
        
  assign {LED2,LED1,LED0} = led_reg;
 
endmodule
代码很简单,不用多解释
对“{}”的一点理解,例如assign {LED2,LED1,LED0} = led_reg;,如果变量led_reg = 100;则LED2 = 1,LED1= 0,LED0 = 0;
另外,若assign Num = {Numa , Numb};
Numa = 1010,Numb = 0110;
则Num = 1010 0110;



FPGA power consumption

posted Apr 6, 2014, 6:25 PM by 葉宏

http://bbs.ednchina.com/BLOG_ARTICLE_3019406.HTM

 【博客大赛】FPGA功耗的那些事儿发布时间:2014-03-13 09:09:08
技术类别:CPLD/FPGA     个人分类:xilinx FPGA

       在项目设计初期,基于硬件电源模块的设计考虑,对FPGA设计中的功耗估计是必不可少的。笔者经历过一个项目,整个系统的功耗达到了100w,而单片FPGA的功耗估计得到为20w左右,有点过高了,功耗过高则会造成发热量增大,温度高最常见的问题就是系统重启,另外对FPGA内部的时序也不利,导致可靠性下降。其它硬件电路的功耗是固定的,只有FPGA的功耗有优化的余地,因此硬件团队则极力要求笔者所在的FPGA团队尽量多做些低功耗设计。笔者项目经历尚浅,还是第一次正视功耗这码事儿,由于项目时间比较紧,而且xilinx方面也比较重视这个项目,因此当时有xilinx的工程师过来对我们做了些培训,并且专门请了美国总部的专家过来与我们协同进行设计功耗估计,还是比较给力的。

       以下是笔者在这比较短的时间内学习到的一些关于功耗估计和如何进行低功耗设计的知识:

 

1.      功耗分析

       整个FPGA设计的总功耗由三部分功耗组成:1. 芯片静态功耗;2. 设计静态功耗;3. 设计动态功耗。

l  芯片静态功耗:FPGA在上电后还未配置时,主要由晶体管的泄露电流所消耗的功耗

l  设计静态功耗:当FPGA配置完成后,当设计还未启动时,需要维持I/O的静态电流,时钟管理和其它部分电路的静态功耗

l  设计动态功耗:FPGA内设计正常启动后,设计的功耗;这部分功耗的多少主要取决于芯片所用电平,以及FPGA内部逻辑和布线资源的占用

       显而易见,前两部分的功耗取决于FPGA芯片及硬件设计本身,很难有较大的改善。可以优化是第3部分功耗:设计动态功耗,而且这部分功耗占总功耗的90%左右,因此所以降低设计动态功耗是降低整个系统功耗的关键因素。上面也提到过功耗较大会使FPGA发热量升高,那有没有一个定量的分析呢?答案当然是有,如下式:

       Tjmax > θJA * PD + TA

       其中Tjmax表示FPGA芯片的最高结温(maximum junction temperature);θJA表示FPGA与周围大气环境的结区热阻抗(Junction to ambient thermal resistance),单位是°C/WPD表示FPGA总功耗(power dissipation),单位是WTA表示周围环境温度。

       XC7K410T-2FFG900I系列芯片为例,θJA = 8.2°C/W,在TA = 55°C的环境中,想要结温Tjmax不超过100°C的情况下,可以推算FPGA的总功耗:PD < (Tjmax – TA)/θJA=(100 - 55)/8.2=5.488W,之前估算的20W与之相差太远,因此优化是必不可少的:

1)      降低θJA:热阻抗取决于芯片与环境的热传导效率,可通过加散热片或者风扇减小热阻抗

1

2)      减小PD:通过优化FPGA设计,降低总功耗,这也是本文重点讲解的部分。

 

2.      功耗估计

       在讲解低功耗设计之前,介绍一下xilinx的功耗估计工具XPE(Xilinx Power Estimator)XPE主要是在项目初期,处于系统设计,RTL代码并未完善阶段功耗估计时使用。大家可以在xilinx官网上下载到:http://www.xilinx.com/power,它是一个基于EXCEL的工具,如图2所示,功能做的十分丰富,感叹EXCEL也未免太强大了吧。

2

       在设计完成综合实现后,则可以使用vivado自带的功耗分析工具进行精确计算功耗。打开综合实现后的设计,点击report power即可得到功耗分析的结果,如图34所示。

3

4

3.      低功耗设计

       关于FPGA低功耗设计,可从两方面着手:1算法优化;2. FPGA资源使用效率优化。

1)      算法优化

       算法优化可分为两个层次说明:实现结构和实现方法

       首先肯定需要设计一种最优化的算法实现结构,设计一种最优化的结构,使资源占用达到最少,当然功耗也能降到最低,但是还需要保证性能,是FPGA设计在面积和速度上都能兼顾。比如在选择采用流水线结构还是状态机结构时,流水线结构同一时间所有的状态都在持续工作,而状态机结构只有一个状态是使能的,显而易见流水线结构的功耗更多,但其数据吞吐率和系统性能更优,因此需要合理选其一,使系统能在面积和速度之间得到平衡;

     另一个层面是具体的实现方法,设计中所有吸收功耗的信号当中,时钟是罪魁祸首。虽然时钟可能运行在 100 MHz,但从该时钟派生出的信号却通常运行在主时钟频率的较小分量(通常为 12%15%)。此外,时钟的扇出一般也比较高。这两个因素显示,为了降低功耗,应当认真研究时钟。 首先,如果设计的某个部分可以处于非活动状态,则可以考虑禁止时钟树翻转,而不是使用时钟使能。时钟使能将阻止寄存器不必要的翻转,但时钟树仍然会翻转,消耗功率。其次,隔离时钟以使用最少数量的信号区。不使用的时钟树信号区不会翻转,从而减轻该时钟网络的负载。

2)      资源使用效率优化

       资源使用效率优化是介绍一些在使用FPGA内部的一些资源如BRAMDSP48E1时,可以优化功耗的方法。FPGA动态功耗主要体现为存储器、内部逻辑、时钟、I/O消耗的功耗。

其中存储器是功耗大户,如xilinx FPGA中的存储器单元Block RAM,因此在这边主要介绍对BRAM的一些功耗优化方法。

如图5中实例,虽然BRAM只使用了7%,但是其功耗0.601W占了总设计的42%,因此优化BRAM的功耗能有效地减小FPGA的动态功耗。

5

       下面介绍一下优化BRAM功耗的方法:

a)       使用“NO CHANGE”模式:在BRAM配置成True Dual Port时,需要选择端口的操作模式:“Write First”“Read First” or “NO CHANGE”,避免读操作和写操作产生冲突,如图6所示;其中“NO CHANGE”表示BRAM不添加额外的逻辑防止读写冲突,因此能减少功耗,但是设计者需要保证程序运行时不会发生读写冲突。

6

       5中的功耗是设置成“Write First”时的,图7中是设置成“NO CHANGE”后的功耗,BRAM的功耗从0.614W降到了0.599W,因为只使用了7%BRAM,如果设计中使用了大量的BRAM,效果能更加明显。

7

b)      控制“EN”信号:BRAM的端口中有clock enable信号,如图8所示,在端口设置中可以将其使能,模块例化时将其与读/写信号连接在一起,如此优化可以使BRAM在没有读/写操作时停止工作,节省不必要的功耗。

8

       如图9所示为控制“EN”信号优化后的功耗情况,BRAM功耗降到了0.589W

9

c)       拼深度:当设计中使用了大量的存储器时,需要多块BRAM拼接而成,如需要深度32K,宽度32-bit32K*32Bit的存储量,但是单块BRAM如何配置是个问题?7 series FPGA中是36Kb BRAM,其中一般使用32Kb容量,因此可以配置成32K*1-bit或者1K*32-bit,多块BRAM拼接时,前者是“拼宽度”(见图10),后者是“拼深度”(见图11)。两种结构在工作时,拼宽度结构所有的BRAM需要同时进行读写操作;而拼深度结构只需要其中一块BRAM进行读写,因此在需要低功耗的情况下采用拼深度结构,

注:拼深度结构需要额外的数据选择逻辑,增加了逻辑层数,为了降低功耗即牺牲了面积又牺牲了性能。

10

11

 



Verilog For

posted Apr 6, 2014, 6:22 PM by 葉宏

http://bbs.ednchina.com/BLOG_ARTICLE_3019676.HTM?click_from=8800020767,8914786776,2014-04-07,EDNCOL,NEWSLETTER

 [博客大赛]Verilog之for语句发布时间:2014-03-25 12:03:07
技术类别:CPLD/FPGA

以前很少用for语句,以为是不可综合的。在印象中好像只用循环生成(for...generate)语句综合过多个模块。最近在仔细研读《轻松成为设计高手——Verilog HDL使用精解》这本书,才知道for语句在组合逻辑中大有用处。

 
(1)for用在纯组合逻辑中
举例:4位左移器(将低4位输入的数移到高4位)
//Leftshift for 4 bits
module For_Leftshift(
input wire [3:0]inp,
input wire L_EN,
output reg [7:0]result
);
 
integer i;
always@(inp or L_EN)
begin
 result[7:4] = 0;
 result[3:0] = inp;
 if(L_EN == 1)
 begin
  for(i=4;i<=7;i=i+1)
  begin
   result[i] = result[i-4];
  end
  result[3:0] = 0;
 end
end
 
endmodule
 
综合结果(RTL视图,实际是一个4位选择器)
1.jpg
(2)for不仅可以用在组合逻辑中,而且还可以用在时序逻辑中,用于在1个周期类完成整个for循环。
举例:在一个周期类完成对输入总线中高电平位的计数,则利用for循环实现加法器
module For_Counter(
input wire clk,
input wire rst_n,
input wire [12:0] data,
output wire [3:0] numout
);
integer i;
reg[3:0] num;
 
always @(posedge clk)
 begin
 if(!rst_n)
  num = 0;
 else
  begin
  for(i=0;i<13;i=i+1)
   if(data[i]) num = num + 1;
  end
 end
 
assign numout = num;
 
endmodule
 
综合结果(RTL视图,加法器+触发器)
 
2.jpg
 
综上,可以看出for循环是可以综合的,而且效率很高。但所消耗的逻辑资源较大。在对速度(时钟周期数)要求不是很高的情况下,可以多用几个时钟周期完成任务,而没有必要用for循环来做。



1-5 of 5