【低功耗设计学习笔记】二By-passing & Clock Gating

一、原理说明

背景和理解

a.CPU指令可以在多周期内完成,即把一条指令分成多个部分,然后依次在每个周期内完成。但是每个指令的所用周期数并不一样,如下图所示,以五级流水线为例子,有些指令需要4个周期(这里实际就是级数,但是若单独看暂且称作周期),有的指令需要3个周期,有的指令需要整整5个周期;
b.流水线(pipeline)的发明提高了人们生产效率,同样将流水线应用在CPU指令处理中,可以提高CPU的吞吐率。在单周期内在不同级同时执行多个指令的小操作,亦可看做是并行处理指令,提高了效率;
c.抽象,将共同的部分进行提取;
d.结合a、b和c我们可以看到:为了使CPU能够应用流水线,我们从更高的一个层次抽象指令的行为,把CPU分成多个级数,通过一级一级加工,逐步来完成指令执行。这样对于所有指令共有的部分而言,这样做是好的,有益的;但是凡事有利弊,指令偶尔也会闹别扭,自己需要额外完成某些操作,如写回操作,那么此时就需要给它在WB级跑一遍。但这样还是好的,因为该做的毕竟还是得做的。最要命的就是有些指令,它本身不用跑WB这一级,但我们为了能够统一整个流水线,我们硬生生让它跑一遍。那这里它就做了无用功。
d.对于MIPS这样架构的处理器,本身它的ISA就是精简指令集,那么对于这些指令的重复利用是必然的,那么无用功随着积累也成了大大的功耗。
e.对于无用功,很显然,我们有两个方式去避免它:
(1)跳过它(By-passing):用控制的手段对指令进行预判,抄小路直接跳到后续的级数,从而减短了路径。
(2)不管它(Clock gating):同样也是用控制的手段,在它进入下一级的时候,我们同时告诉这一级,让它什么都不要做,避免了不必要的运算,从而减少了信号翻转,降低功耗。

二、仿真验证

1.验证方式:在ISE开发平台上进行总线仿真,利用Xpower Analyzer比较功率变化。
2.方法设计:
说明(从左到右):

1.测试数据生成器:并非完全随机,相邻两数相同的概率为1/2;
2.测试数据ROM;
3.测试黑盒:a.clock gating处理;b.未处理;
4.测试结果:由XPA生成功率结果;

3.测试代码:

a.测试数据生成(.py):

import random
print 'memory_initialization_radix = 16;'
print 'memory_initialization_vector = '
TEST_DATA_NUM = 1024

pre = random.randint(0,1)
pre_num = random.randint(0,128)

for i in range(TEST_DATA_NUM):
    if(i % 32 == 0):
        print ''
    elif(i % 8 == 0):
        print ' ',cur = random.randint(0,1)

    if(cur == pre): 
        print('%02X'%pre_num),else:
        cur_num = random.randint(0,128)
        pre = cur
        pre_num = cur_num
        print('%02X'%cur_num),if(i != TEST_DATA_NUM -1):
        print(','),else:
        print(';')
b.未处理:
module tbox(
input wire clk,input wire clr,input wire [3:0] a,input wire [3:0] b,output reg [3:0] c,output reg [9:0] addr
    );

always@(posedge clk or posedge clr)
begin
    if(clr == 1)
        addr <= 9'b0;
    else begin
        addr <= addr + 1'b1;
    end
end

always@(posedge clk or posedge clr)
begin
    if(clr == 1)
        c <= 4'b0;
    else
        c <= (a * b + a) * b;
end


endmodule
c.Clock gating
module tbox(
input wire clk,output reg [9:0] addr,output reg [3:0] c
    );
reg gate;
reg [3:0] atmp,btmp;

always@(posedge clk or posedge clr)
begin
    if(clr == 1)
        addr <= 0;
    else 
        addr <= addr + 1'b1;
end

always@(posedge clk or posedge clr)
begin
    if(clr == 1)
        gate = 0;
    else begin
        if(a == atmp && b == btmp)
            gate = 1;
        else
            gate = 0;
    end
end

always@(posedge clk or posedge clr)
begin
    if(clr == 1)
        c <= 4'b0;
    else if(gate == 1)
        ;
    else if(gate == 0)begin
        c <= (a * b + a) * b;
        atmp <= a;
        btmp <= b;
    end
end

endmodule

4.验证结果:

a、未处理:
b、Clock gating:

分析:在这里我们理论上,clockgating后的功率应该减少的,但是这里反而不减倒增。反复更改了测试数据和程序,最后发现还是自己的理解不到位所致,总结原因如下:
1.clock gating的使用有条件的,那就是门控的所控制的操作所消耗的功耗要(远)大于门控自身的功耗,不能拣了芝麻丢了西瓜;
2.门控信号自身切换要不那么频繁,也就是要求系统在很长一段时间是稳定的,如像待机状态一样;

题外话:此次用的是MarkDown编辑器,算是新尝试!不过感觉最后排版很乱,还需要好好学习才行!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


什么是设计模式一套被反复使用、多数人知晓的、经过分类编目的、代码 设计经验 的总结;使用设计模式是为了 可重用 代码、让代码 更容易 被他人理解、保证代码 可靠性;设计模式使代码编制  真正工程化;设计模式使软件工程的 基石脉络, 如同大厦的结构一样;并不直接用来完成代码的编写,而是 描述 在各种不同情况下,要怎么解决问题的一种方案;能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免引
单一职责原则定义(Single Responsibility Principle,SRP)一个对象应该只包含 单一的职责,并且该职责被完整地封装在一个类中。Every  Object should have  a single responsibility, and that responsibility should be entirely encapsulated by t
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强烈推荐。原文截图*************************************************************************************************************************原文文本************
适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,它是针对软件开发中经常遇到的一些设计问题,总结出来的一套通用的解决方案。
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
迭代器模式提供了一种方法,用于遍历集合对象中的元素,而又不暴露其内部的细节。
外观模式又叫门面模式,它提供了一个统一的(高层)接口,用来访问子系统中的一群接口,使得子系统更容易使用。
单例模式(Singleton Design Pattern)保证一个类只能有一个实例,并提供一个全局访问点。
组合模式可以将对象组合成树形结构来表示“整体-部分”的层次结构,使得客户可以用一致的方式处理个别对象和对象组合。
装饰者模式能够更灵活的,动态的给对象添加其它功能,而不需要修改任何现有的底层代码。
观察者模式(Observer Design Pattern)定义了对象之间的一对多依赖,当对象状态改变的时候,所有依赖者都会自动收到通知。
代理模式为对象提供一个代理,来控制对该对象的访问。代理模式在不改变原始类代码的情况下,通过引入代理类来给原始类附加功能。
工厂模式(Factory Design Pattern)可细分为三种,分别是简单工厂,工厂方法和抽象工厂,它们都是为了更好的创建对象。
状态模式允许对象在内部状态改变时,改变它的行为,对象看起来好像改变了它的类。
命令模式将请求封装为对象,能够支持请求的排队执行、记录日志、撤销等功能。
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 基本介绍 **意图:**在不破坏封装性的前提下,捕获一个对象的内部状态,并在该
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为
享元模式(Flyweight Pattern)(轻量级)(共享元素)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结