透過不同層級的Model來達到Power Saving的功效.
Silicon IP:
CMOS:
藉由改變Channel length,跟thermal voltage的方式讓CMOS能夠在很低的Voltage supply也能被driver. 或者透過 inverse VT 的方式阻斷VDD 到 GND 的short, 降低Leakage power 的消耗.
Ref: Channel length modulation
GATE:
用Power Gating / Clock Gating 的方式來Gate 掉不必要的switch, 減少Dynamic Power的消耗.
Level Shift:
主要用在power supply VDD/VSS上, 藉由改變不同的電壓supply來調整Channel length的大小.做到快速/慢速的charge.來影響導通的速度.
Ref:
Dual-Supply Interface Level Shifter CMOS Logic ICs
Soc Design:
DVFS(dynamic voltage frequency scaling)
動態的調整 voltage / frequency , 利用最少的voltage / frequency 來達到最大的 performance, 且能符合 timing 的 constrain.
Refs:
Voltage and frequency scaling
DVFS emulator
Multi clock / power domain
把parting 過的結果做power / clock 的切割, 分成不同的 clock / power domain, 把相同的clock / power bound 在一起,可減少硬體控制跟routing 的複雜度.
Software :
Power management
Refs:
power management 4 Linux
peak power
power monitor part1
底下用 "Battery contain" 跟 不同 "Task" 所消耗的power, 來模擬行動裝置的 Battery condition.
battery.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define BATTERY_CONTAIN 5000 //unint power contain
#define TEST_COT 3
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t condition_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_cond = PTHREAD_COND_INITIALIZER;
enum BATTERY_STATUS{
BATTERY_FULL =0,
BATTERY_EMPTY =1,
BATTERY_HALF =2,
BATTERY_LOWER =3,
BATTERY_OK =4,
BATTERY_ERROR =5,
};
enum TASK_STATUS{
TASK_VEDIO =0,
TASK_GAME =1,
TASK_PHONE =2,
TASK_WALKMAN =3,
TASK_IDLE =4,
TASK_OFF =7,
};
struct WORK_STATUS{
char *name;
unsigned int on_upw;
unsigned int slp_upw;
unsigned int off_upw;
} WORKList [] = {
{ "TFT" ,100, 50, 10 },
{ "KEYBOARD" , 10, 5, 1 },
{ "WIFI" ,500,200, 10 },
{ "GSM" ,700,500, 30 },
};
struct BATTERY{
char *name;
unsigned int remain;
} BATTERYList [] = {
{ "iBATTERY" , 100 },
};
struct TASK{
char *name;
unsigned int sel;
} TASKList [] = {
{ "TASK_OFF" , TASK_OFF },
{ "TASK_IDLE" , TASK_IDLE },
{ "TASK_VEDIO" , TASK_VEDIO },
{ "TASK_PHONE" , TASK_PHONE },
{ "TASK_IDLE" , TASK_IDLE },
{ "TASK_WALKMAN", TASK_WALKMAN},
};
int COT =0;
void Set_WORK_STATUS(struct WORK_STATUS *Ptr,char *nm,unsigned int on,unsigned int slp,unsigned int off){
Ptr->name = nm;
Ptr->on_upw = on;
Ptr->slp_upw= slp;
Ptr->off_upw= off;
}
void Set_BATTERY(struct BATTERY *Ptr,char *nm,unsigned int rman){
Ptr->name = nm;
Ptr->remain = rman;
}
void Set_TASK(struct TASK *Ptr,char *nm,unsigned int sel){
Ptr->name = nm;
Ptr->sel = sel;
}
int Check_BATTERY_STATUS(struct BATTERY *Ptr){
if(( Ptr->remain > BATTERY_CONTAIN) ||
(0.8*BATTERY_CONTAIN < Ptr->remain && Ptr->remain <= BATTERY_CONTAIN) ){ return BATTERY_FULL; }
else if( 0.6*BATTERY_CONTAIN < Ptr->remain && Ptr->remain <= 0.8*BATTERY_CONTAIN ){ return BATTERY_OK; }
else if( 0.4*BATTERY_CONTAIN < Ptr->remain && Ptr->remain <= 0.6*BATTERY_CONTAIN ){ return BATTERY_HALF; }
else if( 0.2*BATTERY_CONTAIN < Ptr->remain && Ptr->remain <= 0.4*BATTERY_CONTAIN ){ return BATTERY_LOWER; }
else if( 0*BATTERY_CONTAIN < Ptr->remain && Ptr->remain <= 0.2*BATTERY_CONTAIN ){ return BATTERY_EMPTY; }
else { return BATTERY_ERROR; }
}
void Charge_BATTERY(struct BATTERY *Ptr){
if( Check_BATTERY_STATUS(Ptr) != BATTERY_FULL ){
Ptr->remain += 50;
}
}
int Check_TASK_STATUS(struct BATTERY *Ptr,struct TASK *Ttr){
int battery_status = Check_BATTERY_STATUS(Ptr);
unsigned int consume;
switch(Ttr->sel){
// VEDIO : TFT(ON) KEYBOARD(SLEEP) WIFI(ON) GSM(SLEEP)
// GAME : TFT(ON) KEYBOARD(ON) WIIF(SLEEP) GSM(SLEEP)
// PHONE : TFT(SLEEP) KEYBOARD(SLEEP) WIFI(SLEEP) GSM(ON)
// WALKMAN: TFT(SLEEP) KWYBOARD(ON) WIFI(SLEEP) GSM(SLEEP)
// IDLE : TFT(SLEEP) KEYBOARD(SLEEP) WIFI(SLEEP) GSM(SLEEP)
// OFF : TFT(OFF) KEYBOARD(OFF) WIFI(OFF) GSM(OFF)
case TASK_VEDIO : consume = WORKList[0].on_upw + WORKList[1].slp_upw + WORKList[2].on_upw + WORKList[3].slp_upw; break;
case TASK_GAME : consume = WORKList[0].on_upw + WORKList[1].on_upw + WORKList[2].slp_upw + WORKList[3].slp_upw; break;
case TASK_PHONE : consume = WORKList[0].slp_upw + WORKList[1].slp_upw + WORKList[2].slp_upw + WORKList[3].on_upw; break;
case TASK_WALKMAN : consume = WORKList[0].slp_upw + WORKList[1].on_upw + WORKList[2].slp_upw + WORKList[3].slp_upw; break;
case TASK_IDLE : consume = WORKList[0].slp_upw + WORKList[1].slp_upw + WORKList[2].slp_upw + WORKList[3].slp_upw; break;
case TASK_OFF : consume = WORKList[0].off_upw + WORKList[1].off_upw + WORKList[2].off_upw + WORKList[3].off_upw; break;
default : return -1; break;
}
if( battery_status != BATTERY_EMPTY || battery_status != BATTERY_ERROR ){
if( 0.9*Ptr->remain > consume ){ Ptr->remain -= consume; return 0; }
else{ return -1;}
}
}
void *Emulator_BATTERY(void *t){
int i;
struct BATTERY *BATTERYPtr = &BATTERYList[0];
while(COT <= TEST_COT){
for(i=0; i<30; i++){
pthread_mutex_lock(&count_mutex);
if( Check_BATTERY_STATUS(BATTERYPtr) == BATTERY_ERROR ){ pthread_exit(NULL); }
Charge_BATTERY(BATTERYPtr);
printf("0::%d\n", BATTERYPtr->remain);
// pthread_cond_signal(&condition_cond);
pthread_mutex_unlock(&count_mutex);
sleep(1);
}
sleep(20);
}
if( COT == TEST_COT ){ pthread_exit(NULL); }
}
void *Emulator_TASK(void *t){
int i,j,rst;
struct BATTERY *BATTERYPtr = &BATTERYList[0];
struct TASK *TASKPtr;
if( Check_BATTERY_STATUS(BATTERYPtr) == BATTERY_ERROR ){ pthread_exit(NULL); }
if(COT <= TEST_COT ){
for(i=0; i<sizeof(TASKList)/sizeof(*TASKList); i++){
TASKPtr = &TASKList[i];
j=0;
while(j<3){
pthread_mutex_lock(&count_mutex);
// pthread_cond_wait(&condition_cond,&count_mutex);
rst = Check_TASK_STATUS(BATTERYPtr,TASKPtr);
if( rst ==0 ){ printf("1::%d,%d\n", i,BATTERYPtr->remain ); }
pthread_mutex_unlock(&count_mutex);
if( rst==0 ){
j++;
sleep(0.5);
} else {
printf("Out of Battery contain...Please turn off App\n");
j =0;
sleep(50);
}
}
printf("App done ...\n");
sleep(1);
}
COT++;
}
if( COT == TEST_COT ){ pthread_exit(NULL); }
}
int main(int argc, char *argv[]){
pthread_t thread_1,thread_2;
pthread_create( &thread_1,NULL, Emulator_BATTERY, NULL);
pthread_create( &thread_2,NULL, Emulator_TASK, NULL);
pthread_join( thread_1,NULL);
pthread_join( thread_2,NULL);
return 0;
}
compile
gcc -lpthread -o tt battery.c
code download
here
Refs :
Second-Generation SmartReflex™ Power and Performance Management Technologies
Address power management issues in mobiles