#include "io.h"
#include "parameter.h"
#include "const.h"
#include "logic.h"
#include "basic_circuit.h"
#include <iostream>
#include <algorithm>
#include "XML_Parse.h"
#include <string>
#include <cmath>
#include <assert.h>
#include "memoryctrl.h"
#include "basic_components.h"
MCBackend::MCBackend(InputParameter* interface_ip_, const MCParam & mcp_, enum MemoryCtrl_type mc_type_)
:l_ip(*interface_ip_),
mc_type(mc_type_),
mcp(mcp_)
{
local_result = init_interface(&l_ip);
compute();
}
void MCBackend::compute()
{
double C_MCB, mc_power, backend_dyn, backend_gates; double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
double NMOS_sizing, PMOS_sizing;
if (mc_type == MC)
{
if (mcp.type == 0)
{
area.set_area((2.7927*log(mcp.peakDataTransferRate*2)-19.862)/2.0*mcp.dataBusWidth/128.0*(l_ip.F_sz_um/0.09)*mcp.num_channels*1e6); mc_power = 4.32*0.1; C_MCB = mc_power/1e9/72/1.1/1.1*l_ip.F_sz_um/0.065;
power_t.readOp.dynamic = C_MCB*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(mcp.dataBusWidth); power_t.readOp.leakage = area.get_area()/2 *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd; power_t.readOp.gate_leakage = area.get_area()/2 *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;
}
else
{ NMOS_sizing = g_tp.min_w_nmos_;
PMOS_sizing = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r;
area.set_area(0.15*mcp.dataBusWidth/72.0*(l_ip.F_sz_um/0.065)* (l_ip.F_sz_um/0.065)*mcp.num_channels*1e6); backend_dyn = 0.9e-9/800e6*mcp.clockRate/12800*mcp.peakDataTransferRate*mcp.dataBusWidth/72.0*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(l_ip.F_sz_nm/65.0); backend_gates = 50000*mcp.dataBusWidth/64.0;
power_t.readOp.dynamic = backend_dyn;
power_t.readOp.leakage = (backend_gates)*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd; power_t.readOp.gate_leakage = (backend_gates)*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;
}
}
else
{ cout<<"Unknown memory controllers"<<endl;exit(0);
area.set_area(0.243*mcp.dataBusWidth/8); C_MCB = mc_power/1e9/72/1.1/1.1*l_ip.F_sz_um/0.065;
power_t.readOp.leakage = area.get_area()/2 *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd; power_t.readOp.gate_leakage = area.get_area()/2 *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd; power_t.readOp.dynamic *= 1.2;
power_t.readOp.leakage *= 1.2;
power_t.readOp.gate_leakage *= 1.2;
}
double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device);
power_t.readOp.longer_channel_leakage = power_t.readOp.leakage * long_channel_device_reduction;
double pg_reduction = power_gating_leakage_reduction(false);
power_t.readOp.power_gated_leakage = power_t.readOp.leakage*pg_reduction;
power_t.readOp.power_gated_with_long_channel_leakage = power_t.readOp.power_gated_leakage * long_channel_device_reduction;
}
void MCBackend::computeEnergy(bool is_tdp)
{
if (is_tdp)
{
stats_t.readAc.access = 0.5*mcp.num_channels;
stats_t.writeAc.access = 0.5*mcp.num_channels;
tdp_stats = stats_t;
}
else
{
stats_t.readAc.access = mcp.reads;
stats_t.writeAc.access = mcp.writes;
tdp_stats = stats_t;
}
if (is_tdp)
{
power = power_t;
power.readOp.dynamic = (stats_t.readAc.access + stats_t.writeAc.access)*power_t.readOp.dynamic;
}
else
{
rt_power.readOp.dynamic = (stats_t.readAc.access + stats_t.writeAc.access)*mcp.llcBlockSize*8.0/mcp.dataBusWidth*power_t.readOp.dynamic;
rt_power = rt_power + power_t*pppm_lkg;
rt_power.readOp.dynamic = rt_power.readOp.dynamic + power.readOp.dynamic*0.1*mcp.clockRate*mcp.num_mcs*mcp.executionTime;
}
}
MCPHY::MCPHY(InputParameter* interface_ip_, const MCParam & mcp_, enum MemoryCtrl_type mc_type_)
:l_ip(*interface_ip_),
mc_type(mc_type_),
mcp(mcp_)
{
local_result = init_interface(&l_ip);
compute();
}
void MCPHY::compute()
{
double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio() ;
double power_per_gb_per_s, phy_dyn,phy_gates, NMOS_sizing, PMOS_sizing;
if (mc_type == MC)
{
if (mcp.type == 0)
{
power_per_gb_per_s = mcp.LVDS? 0.01:0.04;
area.set_area((6.4323*log(mcp.peakDataTransferRate*2)-48.134)*mcp.dataBusWidth/128.0*(l_ip.F_sz_um/0.09)*mcp.num_channels*1e6/2); power_t.readOp.dynamic = power_per_gb_per_s*sqrt(l_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;
power_t.readOp.leakage = area.get_area()/2 *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd; power_t.readOp.gate_leakage = area.get_area()/2 *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;
}
else
{
NMOS_sizing = g_tp.min_w_nmos_;
PMOS_sizing = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r;
double non_IO_percentage = 0.2;
area.set_area(1.3*non_IO_percentage/2133.0e6*mcp.clockRate/17066*mcp.peakDataTransferRate*mcp.dataBusWidth/16.0*(l_ip.F_sz_um/0.040)* (l_ip.F_sz_um/0.040)*mcp.num_channels*1e6); phy_gates = 200000*mcp.dataBusWidth/64.0;
power_per_gb_per_s = 0.01;
power_t.readOp.dynamic = power_per_gb_per_s*(l_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;
power_t.readOp.leakage = (mcp.withPHY? phy_gates:0)*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd; power_t.readOp.gate_leakage = (mcp.withPHY? phy_gates:0)*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd; }
}
else
{
area.set_area(0.4e6/2*mcp.dataBusWidth/8); }
double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device);
power_t.readOp.longer_channel_leakage = power_t.readOp.leakage * long_channel_device_reduction;
double pg_reduction = power_gating_leakage_reduction(false);
power_t.readOp.power_gated_leakage = power_t.readOp.leakage*pg_reduction;
power_t.readOp.power_gated_with_long_channel_leakage = power_t.readOp.power_gated_leakage * long_channel_device_reduction;
}
void MCPHY::computeEnergy(bool is_tdp)
{
if (is_tdp)
{
stats_t.readAc.access = 0.5*mcp.num_channels; stats_t.writeAc.access = 0.5*mcp.num_channels;
tdp_stats = stats_t;
}
else
{
stats_t.readAc.access = mcp.reads;
stats_t.writeAc.access = mcp.writes;
tdp_stats = stats_t;
}
if (is_tdp)
{
double data_transfer_unit = (mc_type == MC)? 72:16;
power = power_t;
power.readOp.dynamic = power.readOp.dynamic * (mcp.peakDataTransferRate*8*1e6/1e9)*mcp.dataBusWidth/data_transfer_unit*mcp.num_channels/mcp.clockRate;
}
else
{
rt_power = power_t;
rt_power.readOp.dynamic=power_t.readOp.dynamic*(stats_t.readAc.access + stats_t.writeAc.access)*(mcp.llcBlockSize)*8/1e9/mcp.executionTime*(mcp.executionTime);
rt_power.readOp.dynamic = rt_power.readOp.dynamic + power.readOp.dynamic*0.1*mcp.clockRate*mcp.num_mcs*mcp.executionTime;
}
}
MCFrontEnd::MCFrontEnd(ParseXML *XML_interface,InputParameter* interface_ip_, const MCParam & mcp_, enum MemoryCtrl_type mc_type_)
:XML(XML_interface),
interface_ip(*interface_ip_),
mc_type(mc_type_),
mcp(mcp_),
MC_arb(0),
frontendBuffer(0),
readBuffer(0),
writeBuffer(0)
{
int tag, data;
bool is_default =true;
tag = mcp.addressBusWidth + EXTRA_TAG_BITS + mcp.opcodeW;
data = int(ceil((XML->sys.physical_address_width + mcp.opcodeW)/8.0));
interface_ip.cache_sz = data*XML->sys.mc.req_window_size_per_channel;
interface_ip.line_sz = data;
interface_ip.assoc = 0;
interface_ip.nbanks = 1;
interface_ip.out_w = interface_ip.line_sz*8;
interface_ip.specific_tag = 1;
interface_ip.tag_w = tag;
interface_ip.access_mode = 0;
interface_ip.throughput = 1.0/mcp.clockRate;
interface_ip.latency = 1.0/mcp.clockRate;
interface_ip.is_cache = true;
interface_ip.pure_cam = false;
interface_ip.pure_ram = false;
interface_ip.obj_func_dyn_energy = 0;
interface_ip.obj_func_dyn_power = 0;
interface_ip.obj_func_leak_power = 0;
interface_ip.obj_func_cycle_t = 1;
interface_ip.num_rw_ports = 0;
interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc;
interface_ip.num_wr_ports = interface_ip.num_rd_ports;
interface_ip.num_se_rd_ports = 0;
interface_ip.num_search_ports = XML->sys.mc.memory_channels_per_mc;
frontendBuffer = new ArrayST(&interface_ip, "MC ReorderBuffer", Uncore_device);
frontendBuffer->area.set_area(frontendBuffer->area.get_area()+ frontendBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc);
area.set_area(area.get_area()+ frontendBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc);
interface_ip.assoc = 1; MC_arb = new selection_logic(is_default, XML->sys.mc.req_window_size_per_channel,1,&interface_ip, Uncore_device);
data = (int)ceil(mcp.dataBusWidth/8.0); interface_ip.cache_sz = data*XML->sys.mc.IO_buffer_size_per_channel; interface_ip.line_sz = data;
interface_ip.assoc = 1;
interface_ip.nbanks = 1;
interface_ip.out_w = interface_ip.line_sz*8;
interface_ip.access_mode = 1;
interface_ip.throughput = 1.0/mcp.clockRate;
interface_ip.latency = 1.0/mcp.clockRate;
interface_ip.is_cache = false;
interface_ip.pure_cam = false;
interface_ip.pure_ram = true;
interface_ip.obj_func_dyn_energy = 0;
interface_ip.obj_func_dyn_power = 0;
interface_ip.obj_func_leak_power = 0;
interface_ip.obj_func_cycle_t = 1;
interface_ip.num_rw_ports = 0; interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc;
interface_ip.num_wr_ports = interface_ip.num_rd_ports;
interface_ip.num_se_rd_ports = 0;
readBuffer = new ArrayST(&interface_ip, "MC ReadBuffer", Uncore_device);
readBuffer->area.set_area(readBuffer->area.get_area()+ readBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc);
area.set_area(area.get_area()+ readBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc);
data = (int)ceil(mcp.dataBusWidth/8.0); interface_ip.cache_sz = data*XML->sys.mc.IO_buffer_size_per_channel; interface_ip.line_sz = data;
interface_ip.assoc = 1;
interface_ip.nbanks = 1;
interface_ip.out_w = interface_ip.line_sz*8;
interface_ip.access_mode = 0;
interface_ip.throughput = 1.0/mcp.clockRate;
interface_ip.latency = 1.0/mcp.clockRate;
interface_ip.obj_func_dyn_energy = 0;
interface_ip.obj_func_dyn_power = 0;
interface_ip.obj_func_leak_power = 0;
interface_ip.obj_func_cycle_t = 1;
interface_ip.num_rw_ports = 0;
interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc;
interface_ip.num_wr_ports = interface_ip.num_rd_ports;
interface_ip.num_se_rd_ports = 0;
writeBuffer = new ArrayST(&interface_ip, "MC writeBuffer", Uncore_device);
writeBuffer->area.set_area(writeBuffer->area.get_area()+ writeBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc);
area.set_area(area.get_area()+ writeBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc);
}
void MCFrontEnd::computeEnergy(bool is_tdp)
{
if (is_tdp)
{
frontendBuffer->stats_t.readAc.access = frontendBuffer->l_ip.num_search_ports;
frontendBuffer->stats_t.writeAc.access = frontendBuffer->l_ip.num_wr_ports;
frontendBuffer->tdp_stats = frontendBuffer->stats_t;
readBuffer->stats_t.readAc.access = readBuffer->l_ip.num_rd_ports*mcp.frontend_duty_cycle;
readBuffer->stats_t.writeAc.access = readBuffer->l_ip.num_wr_ports*mcp.frontend_duty_cycle;
readBuffer->tdp_stats = readBuffer->stats_t;
writeBuffer->stats_t.readAc.access = writeBuffer->l_ip.num_rd_ports*mcp.frontend_duty_cycle;
writeBuffer->stats_t.writeAc.access = writeBuffer->l_ip.num_wr_ports*mcp.frontend_duty_cycle;
writeBuffer->tdp_stats = writeBuffer->stats_t;
}
else
{
frontendBuffer->stats_t.readAc.access = XML->sys.mc.memory_reads *mcp.llcBlockSize*8.0/mcp.dataBusWidth*mcp.dataBusWidth/72;
frontendBuffer->stats_t.writeAc.access = XML->sys.mc.memory_writes*mcp.llcBlockSize*8.0/mcp.dataBusWidth*mcp.dataBusWidth/72;
frontendBuffer->rtp_stats = frontendBuffer->stats_t;
readBuffer->stats_t.readAc.access = XML->sys.mc.memory_reads*mcp.llcBlockSize*8.0/mcp.dataBusWidth; readBuffer->stats_t.writeAc.access = XML->sys.mc.memory_reads*mcp.llcBlockSize*8.0/mcp.dataBusWidth; readBuffer->rtp_stats = readBuffer->stats_t;
writeBuffer->stats_t.readAc.access = XML->sys.mc.memory_writes*mcp.llcBlockSize*8.0/mcp.dataBusWidth;
writeBuffer->stats_t.writeAc.access = XML->sys.mc.memory_writes*mcp.llcBlockSize*8.0/mcp.dataBusWidth;
writeBuffer->rtp_stats = writeBuffer->stats_t;
}
frontendBuffer->power_t.reset();
readBuffer->power_t.reset();
writeBuffer->power_t.reset();
frontendBuffer->power_t.readOp.dynamic += (frontendBuffer->stats_t.readAc.access +
frontendBuffer->stats_t.writeAc.access)*frontendBuffer->local_result.power.searchOp.dynamic
+ frontendBuffer->stats_t.readAc.access * frontendBuffer->local_result.power.readOp.dynamic
+ frontendBuffer->stats_t.writeAc.access*frontendBuffer->local_result.power.writeOp.dynamic;
readBuffer->power_t.readOp.dynamic += (readBuffer->stats_t.readAc.access*
readBuffer->local_result.power.readOp.dynamic+
readBuffer->stats_t.writeAc.access*readBuffer->local_result.power.writeOp.dynamic);
writeBuffer->power_t.readOp.dynamic += (writeBuffer->stats_t.readAc.access*
writeBuffer->local_result.power.readOp.dynamic+
writeBuffer->stats_t.writeAc.access*writeBuffer->local_result.power.writeOp.dynamic);
if (is_tdp)
{
power = power + frontendBuffer->power_t + readBuffer->power_t + writeBuffer->power_t +
(frontendBuffer->local_result.power +
readBuffer->local_result.power +
writeBuffer->local_result.power)*pppm_lkg;
}
else
{
rt_power = rt_power + frontendBuffer->power_t + readBuffer->power_t + writeBuffer->power_t +
(frontendBuffer->local_result.power +
readBuffer->local_result.power +
writeBuffer->local_result.power)*pppm_lkg;
rt_power.readOp.dynamic = rt_power.readOp.dynamic + power.readOp.dynamic*0.1*mcp.clockRate*mcp.num_mcs*mcp.executionTime;
}
}
void MCFrontEnd::displayEnergy(uint32_t indent,int plevel,bool is_tdp)
{
string indent_str(indent, ' ');
string indent_str_next(indent+2, ' ');
bool long_channel = XML->sys.longer_channel_device;
bool power_gating = XML->sys.power_gating;
if (is_tdp)
{
cout << indent_str << "Front End ROB:" << endl;
cout << indent_str_next << "Area = " << frontendBuffer->area.get_area()*1e-6<< " mm^2" << endl;
cout << indent_str_next << "Peak Dynamic = " << frontendBuffer->power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str_next << "Subthreshold Leakage = " << frontendBuffer->power.readOp.leakage <<" W" << endl;
if (power_gating) cout << indent_str_next << "Subthreshold Leakage with power gating = "
<< (long_channel? frontendBuffer->power.readOp.power_gated_with_long_channel_leakage : frontendBuffer->power.readOp.power_gated_leakage) << " W" << endl;
cout << indent_str_next << "Gate Leakage = " << frontendBuffer->power.readOp.gate_leakage << " W" << endl;
cout << indent_str_next << "Runtime Dynamic = " << frontendBuffer->rt_power.readOp.dynamic/mcp.executionTime << " W" << endl;
cout <<endl;
cout << indent_str<< "Read Buffer:" << endl;
cout << indent_str_next << "Area = " << readBuffer->area.get_area()*1e-6 << " mm^2" << endl;
cout << indent_str_next << "Peak Dynamic = " << readBuffer->power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str_next << "Subthreshold Leakage = " << readBuffer->power.readOp.leakage << " W" << endl;
if (power_gating) cout << indent_str_next << "Subthreshold Leakage with power gating = "
<< (long_channel? readBuffer->power.readOp.power_gated_with_long_channel_leakage : readBuffer->power.readOp.power_gated_leakage) << " W" << endl;
cout << indent_str_next << "Gate Leakage = " << readBuffer->power.readOp.gate_leakage << " W" << endl;
cout << indent_str_next << "Runtime Dynamic = " << readBuffer->rt_power.readOp.dynamic/mcp.executionTime << " W" << endl;
cout <<endl;
cout << indent_str << "Write Buffer:" << endl;
cout << indent_str_next << "Area = " << writeBuffer->area.get_area() *1e-6 << " mm^2" << endl;
cout << indent_str_next << "Peak Dynamic = " << writeBuffer->power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str_next << "Subthreshold Leakage = " << writeBuffer->power.readOp.leakage << " W" << endl;
if (power_gating) cout << indent_str_next << "Subthreshold Leakage with power gating = "
<< (long_channel? writeBuffer->power.readOp.power_gated_with_long_channel_leakage : writeBuffer->power.readOp.power_gated_leakage) << " W" << endl;
cout << indent_str_next << "Gate Leakage = " << writeBuffer->power.readOp.gate_leakage << " W" << endl;
cout << indent_str_next << "Runtime Dynamic = " << writeBuffer->rt_power.readOp.dynamic/mcp.executionTime << " W" << endl;
cout <<endl;
}
else
{
cout << indent_str << "Front End ROB:" << endl;
cout << indent_str_next << "Area = " << frontendBuffer->area.get_area()*1e-6<< " mm^2" << endl;
cout << indent_str_next << "Peak Dynamic = " << frontendBuffer->rt_power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str_next << "Subthreshold Leakage = " << frontendBuffer->rt_power.readOp.leakage <<" W" << endl;
cout << indent_str_next << "Gate Leakage = " << frontendBuffer->rt_power.readOp.gate_leakage << " W" << endl;
cout <<endl;
cout << indent_str<< "Read Buffer:" << endl;
cout << indent_str_next << "Area = " << readBuffer->area.get_area()*1e-6 << " mm^2" << endl;
cout << indent_str_next << "Peak Dynamic = " << readBuffer->rt_power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str_next << "Subthreshold Leakage = " << readBuffer->rt_power.readOp.leakage << " W" << endl;
cout << indent_str_next << "Gate Leakage = " << readBuffer->rt_power.readOp.gate_leakage << " W" << endl;
cout <<endl;
cout << indent_str << "Write Buffer:" << endl;
cout << indent_str_next << "Area = " << writeBuffer->area.get_area() *1e-6 << " mm^2" << endl;
cout << indent_str_next << "Peak Dynamic = " << writeBuffer->rt_power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str_next << "Subthreshold Leakage = " << writeBuffer->rt_power.readOp.leakage << " W" << endl;
cout << indent_str_next << "Gate Leakage = " << writeBuffer->rt_power.readOp.gate_leakage << " W" << endl;
}
}
MemoryController::MemoryController(ParseXML *XML_interface,InputParameter* interface_ip_, enum MemoryCtrl_type mc_type_)
:XML(XML_interface),
interface_ip(*interface_ip_),
mc_type(mc_type_),
frontend(0),
transecEngine(0),
PHY(0),
pipeLogic(0)
{
interface_ip.wire_is_mat_type = 2;
interface_ip.wire_os_mat_type = 2;
interface_ip.wt =Global;
set_mc_param();
frontend = new MCFrontEnd(XML, &interface_ip, mcp, mc_type);
area.set_area(area.get_area()+ frontend->area.get_area());
transecEngine = new MCBackend(&interface_ip, mcp, mc_type);
area.set_area(area.get_area()+ transecEngine->area.get_area());
if (mcp.type==0 || (mcp.type==1&&mcp.withPHY))
{
PHY = new MCPHY(&interface_ip, mcp, mc_type);
area.set_area(area.get_area()+ PHY->area.get_area());
}
}
void MemoryController::computeEnergy(bool is_tdp)
{
frontend->computeEnergy(is_tdp);
transecEngine->computeEnergy(is_tdp);
if (mcp.type==0 || (mcp.type==1&&mcp.withPHY))
{
PHY->computeEnergy(is_tdp);
}
if (is_tdp)
{
power = power + frontend->power + transecEngine->power;
if (mcp.type==0 || (mcp.type==1&&mcp.withPHY))
{
power = power + PHY->power;
}
}
else
{
rt_power = rt_power + frontend->rt_power + transecEngine->rt_power;
if (mcp.type==0 || (mcp.type==1&&mcp.withPHY))
{
rt_power = rt_power + PHY->rt_power;
}
}
}
void MemoryController::displayEnergy(uint32_t indent,int plevel,bool is_tdp)
{
string indent_str(indent, ' ');
string indent_str_next(indent+2, ' ');
bool long_channel = XML->sys.longer_channel_device;
bool power_gating = XML->sys.power_gating;
if (is_tdp)
{
cout << "Memory Controller:" << endl;
cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl;
cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str<< "Subthreshold Leakage = "
<< (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl;
if (power_gating) cout << indent_str << "Subthreshold Leakage with power gating = "
<< (long_channel? power.readOp.power_gated_with_long_channel_leakage : power.readOp.power_gated_leakage) << " W" << endl;
cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl;
cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic/mcp.executionTime << " W" << endl;
cout<<endl;
cout << indent_str << "Front End Engine:" << endl;
cout << indent_str_next << "Area = " << frontend->area.get_area()*1e-6<< " mm^2" << endl;
cout << indent_str_next << "Peak Dynamic = " << frontend->power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str_next << "Subthreshold Leakage = "
<< (long_channel? frontend->power.readOp.longer_channel_leakage:frontend->power.readOp.leakage) <<" W" << endl;
if (power_gating) cout << indent_str_next << "Subthreshold Leakage with power gating = "
<< (long_channel? frontend->power.readOp.power_gated_with_long_channel_leakage : frontend->power.readOp.power_gated_leakage) << " W" << endl;
cout << indent_str_next << "Gate Leakage = " << frontend->power.readOp.gate_leakage << " W" << endl;
cout << indent_str_next << "Runtime Dynamic = " << frontend->rt_power.readOp.dynamic/mcp.executionTime << " W" << endl;
cout <<endl;
if (plevel >2){
frontend->displayEnergy(indent+4,is_tdp);
}
cout << indent_str << "Transaction Engine:" << endl;
cout << indent_str_next << "Area = " << transecEngine->area.get_area()*1e-6<< " mm^2" << endl;
cout << indent_str_next << "Peak Dynamic = " << transecEngine->power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str_next << "Subthreshold Leakage = "
<< (long_channel? transecEngine->power.readOp.longer_channel_leakage:transecEngine->power.readOp.leakage) <<" W" << endl;
if (power_gating) cout << indent_str_next << "Subthreshold Leakage with power gating = "
<< (long_channel? transecEngine->power.readOp.power_gated_with_long_channel_leakage : transecEngine->power.readOp.power_gated_leakage) << " W" << endl;
cout << indent_str_next << "Gate Leakage = " << transecEngine->power.readOp.gate_leakage << " W" << endl;
cout << indent_str_next << "Runtime Dynamic = " << transecEngine->rt_power.readOp.dynamic/mcp.executionTime << " W" << endl;
cout <<endl;
if (mcp.type==0 || (mcp.type==1&&mcp.withPHY))
{
cout << indent_str << "PHY:" << endl;
cout << indent_str_next << "Area = " << PHY->area.get_area()*1e-6<< " mm^2" << endl;
cout << indent_str_next << "Peak Dynamic = " << PHY->power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str_next << "Subthreshold Leakage = "
<< (long_channel? PHY->power.readOp.longer_channel_leakage:PHY->power.readOp.leakage) <<" W" << endl;
if (power_gating) cout << indent_str_next << "Subthreshold Leakage with power gating = "
<< (long_channel? PHY->power.readOp.power_gated_with_long_channel_leakage : PHY->power.readOp.power_gated_leakage) << " W" << endl;
cout << indent_str_next << "Gate Leakage = " << PHY->power.readOp.gate_leakage << " W" << endl;
cout << indent_str_next << "Runtime Dynamic = " << PHY->rt_power.readOp.dynamic/mcp.executionTime << " W" << endl;
cout <<endl;
}
}
else
{
cout << "Memory Controller:" << endl;
cout << indent_str_next << "Area = " << area.get_area()*1e-6<< " mm^2" << endl;
cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*mcp.clockRate << " W" << endl;
cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage <<" W" << endl;
cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl;
cout<<endl;
}
}
void MemoryController::set_mc_param()
{
if (mc_type==MC)
{
mcp.clockRate =XML->sys.mc.mc_clock*2; mcp.clockRate *= 1e6;
mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);
mcp.llcBlockSize =int(ceil(XML->sys.mc.llc_line_length/8.0))+XML->sys.mc.llc_line_length; mcp.dataBusWidth =int(ceil(XML->sys.mc.databus_width/8.0)) + XML->sys.mc.databus_width;
mcp.addressBusWidth =int(ceil(XML->sys.mc.addressbus_width)); mcp.opcodeW =16;
mcp.num_mcs = XML->sys.mc.number_mcs;
mcp.num_channels = XML->sys.mc.memory_channels_per_mc;
mcp.reads = XML->sys.mc.memory_reads;
mcp.writes = XML->sys.mc.memory_writes;
mcp.peakDataTransferRate = XML->sys.mc.peak_transfer_rate;
mcp.memRank = XML->sys.mc.number_ranks;
mcp.frontend_duty_cycle = 0.5; mcp.LVDS = XML->sys.mc.LVDS;
mcp.type = XML->sys.mc.type;
mcp.withPHY = XML->sys.mc.withPHY;
if ( XML->sys.mc.vdd>0)
{
interface_ip.specific_hp_vdd = true;
interface_ip.specific_lop_vdd = true;
interface_ip.specific_lstp_vdd = true;
interface_ip.hp_Vdd = XML->sys.mc.vdd;
interface_ip.lop_Vdd = XML->sys.mc.vdd;
interface_ip.lstp_Vdd = XML->sys.mc.vdd;
}
if ( XML->sys.mc.power_gating_vcc > -1)
{
interface_ip.specific_vcc_min = true;
interface_ip.user_defined_vcc_min = XML->sys.mc.power_gating_vcc;
}
}
else
{
cout<<"Unknown memory controller type: neither DRAM controller nor Flash controller" <<endl;
exit(0);
}
}
MCFrontEnd ::~MCFrontEnd(){
if(MC_arb) {delete MC_arb; MC_arb = 0;}
if(frontendBuffer) {delete frontendBuffer; frontendBuffer = 0;}
if(readBuffer) {delete readBuffer; readBuffer = 0;}
if(writeBuffer) {delete writeBuffer; writeBuffer = 0;}
}
MemoryController ::~MemoryController(){
if(frontend) {delete frontend; frontend = 0;}
if(transecEngine) {delete transecEngine; transecEngine = 0;}
if(PHY) {delete PHY; PHY = 0;}
if(pipeLogic) {delete pipeLogic; pipeLogic = 0;}
}