speed2000软件学习及C++学习

  1. 只有虚函数才能被覆盖;
    #include
    #include

using namespace std;

void process(int& i)
{
std::cout<<i<<" is lvalue"<<endl;
}
void process(int&& i)
{
std::cout<<i<<" is rvalue"<<endl;
}

template
void test(T&& i) //万能引用只能发生在模板中
{
process(i);
}

int main()
{
int i = 0;
process(i);
process(1);
return 0;
}

2)可变参数模板实例:
#include
#include

using namespace std;

template
ostream& printMsg(ostream& os,const T& t)
{
os <<t<<endl;
return os;
}

template<typename T,typename… Args>
ostream& printMsg(ostream& os,const T& t,Args… args )
{
os <<t<<" ";
printMsg(os,args…);
return os;
}

int main(void)
{
printMsg(cout,1,“string”,0.0,3L,“aaa”,“bbb”);
return 0;
}

//为什么模板的程序声明和定义在同一个文件:因为模块实例化是在链接之前进行的,如果分开写的话,找不到定义文件;
类模板可以封装通用的数据容器;
模板参数分为「类型形参」与「非类型形参」;
聚合初始化也叫列表初始化;

template<class T,size_t N>
class arr
{
public:
T dat[N];
T operator[](size_t n)
{
if(n < N)
{
return dat[n];
}
throw “index out of range!”;
}
};

template
struct A
{
public:
A(T v) : age(v){}
T age;
};

int main(void)
{
Aa = 20;
cout<<a.age<<endl;
return 0;
}

1)过孔加工工艺介绍,包括树脂塞孔,半塞孔,背钻等;
PCB的装配流程,包括回流焊接与波峰焊接;主要步骤:来料检测,元器件配置,涮锡膏,贴片,焊接,检测PCB焊接,测试等等;
2)传输线:
传输线定义,传播方式,传输线方程;
两种参数:集总参数和分布参数介绍;
老师课件中,频率为50hz的交流电波长为什么是6000km? 公式如:C= λf;或者V = λf //λ读作拉姆达
300000km÷50=6000km
电磁波在介质中传播速度只与介质的介电常数有关;
传输延时 τ = √LC;
传播方式:TEM,TE,TM以及其场合应用的概要;
传输线方程的意义:传输线方程也叫电报方程,根据电报方程可以推导出特征阻抗、反射系数、输入阻抗等;
特征阻抗: Z0=√L/C;
3)阻抗计算,层叠方案分析,si9000软件的使用;
蚀刻因子定义及对信号的影响,常用的板材规格和铜箔规格;
叠层总原则:包括信号层与回流层,信号层与信号层(注意串扰)及叠层设计规则中的各个优缺点;
学会了两层板的阻抗控制:人为的设计一个参考平面;
Si软件的使用及各个参数介绍,如何用si9000软件设计一个合格的层叠结构;

//函数模板学习
函数模板使用也叫实例化;
inline和constexpr必须放到模板参数列表之后,返回类型之前;
绑定到非类型整型参数必须是一个常量表达式,在模板定义中,非类型参数就是常量值;

2)类模板的声明和定义分开案例:
#include
#include

using namespace std;

template
class A
{
public:
void printMsg(const T& a);
};

template
void A::printMsg(const T& a)
{
cout<<a<<endl;
}

int main(void)
{
A a;
a.printMsg(4);
return 0;
}

3)成员模板案例:

第三天:电平学习:
常用逻辑电平:TTL,CMOS,LVDS,ECL,PECL,SSTL,POD12;
逻辑电平应该满足的参数关系:Voh>Vih>Vt>Vil>Vol;
TTL使用注意事项:TTL电平一般过冲都比较严重,会在始端串22Ω或者33Ω,TTL电平悬空时默认高电平,下拉则用1K电阻;
晶体管-晶体管逻辑电平(TTL)transistor transistor logic [ˈɑːksaɪd]
CMOS全称:互补型金属氧化物半导体 (Complementary metal oxide semiconductor);
CMOS电平是由pmos电路和电路nmos电平构成;
CMOS相对于TTL有了更大的噪声容器,输入阻抗远大于TTL的输入阻抗;
空穴的电导率低于电子,所以CMOS电路的上升时间比下降时间长;
sstl电平:stub series termination logic;和HSTL基本相同;
[ˈsudoʊ]
POD电平:pesudo open drain,pod和sstl最大的区别在于接收端的终端电压,pod为vddq,sstl为vddq/2。POD可以降低i/o功耗;

LVDS电平:低压差分电平,其主要特点如下:
低压摆率:约350mV,低电流驱动模式意味着可以实现高速传输;
低功耗:恒流源电流驱动(3.5mA),使跳变期间的干扰最少,产生的功耗也较少;
具有相对较慢的边沿速率(dV/dt约为0.3V/0.3nS,即1V/ns);
差分模式输入输出,则具有抗干扰能力;
空闲输入引脚应悬空,以防输入噪声;空闲输出引脚应悬空,以减少功耗;

ECL电平(Emitter coupled logic),发射极耦合逻辑电路;
ECL电路是一种非饱和型的数字逻辑电路,其内部晶体管工作在线性区或截止区,所以是最快的电路形式之一;
ECL电路采用负电压工作,其特点是速度快,驱动能力强,噪声低,便于集成,缺点是直流功耗大;

CML电平(电流模式逻辑)是内部做好匹配,差分线形式,速度到达3G,只能点对点;
GTL电平(Gunning Transceiver Logic)射电收发器逻辑,其特点是输入为比较器结构;
HSTL电平主要应用与QDR存储器,采用出入比较器结构;

差分电平互联:
以LVDS互联为例:如果是直流匹配,则需要在接收端加100Ω电阻;如果是交流匹配,则不用,但注意是否有直流偏置电压,如果没有需要外加1.2V;

第四天:眼图、S参数及反射学习
高速串行总线与并行总线对比:主要电气规范发生变化,损耗占据了主导地位;
眼图定义:眼图是一系列数字信号在示波器上叠加而显示的图形,是反映传输链路中所有数字信号的整体特征;
反射学习:
T型连接也会造成阻抗不连续;
反射的结果是:对模拟信号形成驻波,对数字信号形成振铃,会破坏信号的完整性;
反射系数:反射系数分为源端反射系数(Rs-Z0/Rs+Z0)和末端反射系数(Rl-Z0/Rl+Z0);
常见匹配方式:源端串联(Rs加上驱动源的匹配电阻=传输线阻抗Z0);
负载端并联端接,戴维南匹配,二极管端接匹配,RC端接;
不考虑反射的条件:当延时小于上升时间的20%,突变的传输线长度小于信号上升时间,stub的长度小于信号的上升时间;

第五天学习:拓扑结构及串扰学习:
拓扑结构对信号质量非常重要,好的拓扑结构特点:保证信号波形质量,提高产品噪声裕量,提高产品可靠性,方便PCB布局;
菊花链拓扑,串行匹配和并联匹配;
fly-by拓扑;
Fly-by拓扑实际上是菊花链拓扑中的一种特殊情况。当菊花链拓扑中的支路,也就是“SUB线”相当短的时候,可以将其称作为“fly-by”;
fly-by加上拉电阻;
星型拓扑,远端簇拓扑;
串扰分析:奇模和偶模,串扰只在信号上升或下降电流变化时产生;
串扰分为容性串扰和感性串扰;
近端串扰:当干扰源对被干扰源的发送端产生的干扰。
远端串扰:干扰源对被干扰源的接收端产生的第一次干扰;

//函数模板的具体化
using namespace std;
class gril
{
public:
string name;
int age;
};

template
void swapNum(T& a,T& b)
{
T tmp = a;
a = b;
b = tmp;
cout<<“function template running”<<endl;
}

template<>
void swapNum(gril& g1,gril& g2) //函数模板的(具体化)特例化
{
int tmp = g1.age;
g1.age = g2.age;
g2.age = tmp;
cout<<“function template detail running”<<endl;
}

int main(void)
{
int a = 10,b = 20;
swapNum(a,b);
cout<<"a: “<<a<<” b: "<<b<<endl;

gril g1,g2;
g1.age = 4;
g2.age = 7;
swapNum(g1,g2); //使用了函数模板的具体化
cout<<"g1.age: “<< g1.age<<” g2.age : "<< g2.age <<endl;
return 0;
}

2)auto和decltype的在函数模板中的组合使用
template<typename T1,typename T2>
auto fun(T1 x,T2 y) -> decltype(x + y) //在c++14标准以后,"-> decltype(x + y)"可以省略尾置返回类型;
{
decltype(x + y) tmp;
tmp = x + y;
return tmp;
}
int main(void)
{
auto num = fun(3,4.6);
cout<<num<<endl;
return 0;
}

3)类模板的案例
#include
#include
#include

using namespace std;

template<class T1,class T2 = double >
class AA
{
public:
AA(T1 a,T2 b) : a_(a),b_(b){}
T1 geta() { T1 n = 3; return a_ + n;}
T2 getb() { T2 n = 3; return b_ + n;}
T1 a_;
T2 b_;
};
int main(void)
{
AA aa(“3”,6); //使用类模板时,数据类型必须适应类模板的代码;
// cout<<aa.geta()<<endl; //如果放开的话,会编译错误
cout<<aa.getb()<<endl;
return 0;
}

template<class T1,class T2 = string > //不能在类外定义默认的模板参数,所以string应该去掉!
T1 AA<T1,T2>::geta() { T1 n = 3; return a_ + n;}

auto aptr = new AA<int,int>(5,8); //可以用new创建模板类对象
cout<geta()<<endl;
//在程序中,模板类的成员函数使用了才会创建;
//在程序中,虽然创建类的指针,但没有创建类的对象,所以不会调用构造函数;

4)利用类模板,编写了一个堆栈的相关的函数,代码如下:
#include
#include

using namespace std;

// typedef string DataTpye;
template
class MyStack
{
private:
T* items;
int top; //位置指针
int stackSize;
public:
MyStack(int size) : stackSize(size),top(0)
{
items = new T[stackSize];
}
~MyStack(void)
{
delete[] items; items = nullptr;
}
bool isEmpty(void)
{
return top == 0;
}
bool isFull(void)
{
return top == stackSize;
}
bool push(const T& item)
{
if(top < stackSize)
{
items[top++] = item;
return true;
}
return false;
}
bool pop(T& item)
{
if(top > 0){item = items[–top]; return true;}
return false;
}
};

int main(void)
{
MyStack ss(5);
ss.push(“aaa”); ss.push(“bbb”); ss.push(“ccc”); ss.push(“ddd”); ss.push(“eee”);
string item;
while(ss.isEmpty() == false)
{
ss.pop(item); cout<<"item is: "<<item<<endl;
}
}

5)模板类的案例应用,定长数组和变长数组的应用:
用const对成员函数进行声明,表示这个函数不会修改类中的任何数据成员;
#include
#include
#include <string.h>
using namespace std;

#define MaxLen 10

template
class MyArray
{
private:
T arr[MaxLen];
public:
MyArray(){ memset(arr,0,sizeof(arr)); }
~MyArray(){}
T& operator[](int ii){ return arr[ii]; } //重载下标运算符,可以修改数组中的元素
const T& operator[](int ii)const { return arr[ii];} //不能修改数组中的元素;
};

template
class Vector
{
private:
int len;
T* items; //数组元素
public:
Vector(int size = 10) : len(size){ items = new T[len]; }
~Vector()
{
delete[] items; items = nullptr;
}
void resize(int size) //扩展数组的内存空间
{
if(size < len) return;
T* tmp = new T[size];
for (int ii = 0; ii < len; ii++) tmp[ii] = items[ii];
delete[] items; // 释放原来的数组。
items = tmp; // 让数组指针指向新数组。
len = size; // 扩展后的数组长度。
}
T& operator[](int ii) // 重载操作符[],可以修改数组中的元素。
{
if (ii >= len)
{
resize(ii + 1); // 扩展数组。
cout<<“running extern array function-----”<<endl;
}
return items[ii];
}
};

int main(void)
{
Vector aa(1);
aa[0] = “西施”; aa[1] = “冰冰”; aa[2] = “幂幂”; aa[3] = “金莲”; aa[4] = “小乔”;
for (int ii=0; ii<5;ii++) cout << “aa[” << ii << “]=” << aa[ii] << endl;
}

6)嵌套使用模板类的案例:
#include
#include
#include <string.h>
using namespace std;

template
class MyStack
{
private:
T* items;
int top; //位置指针
int stackSize;
public:
MyStack(int size = 3) : stackSize(size),top(0)
{
items = new T[stackSize];
}
~MyStack(void)
{
delete[] items; items = nullptr;
}
bool isEmpty(void)
{
return top == 0;
}
bool isFull(void)
{
return top == stackSize;
}
bool push(const T& item)
{
if(top < stackSize)
{
items[top++] = item;
return true;
}
return false;
}
bool pop(T& item)
{
if(top > 0){item = items[–top]; return true;}
return false;
}
MyStack& operator=(const MyStack& v)
{
delete[] items;
stackSize = v.stackSize;
items = new T[stackSize];
for(int ii = 0; ii < stackSize; ii++) items[ii] = v.items[ii];
top = v.top;
return *this;
}
};

template
class Vector
{
private:
int len;
T* items; //数组元素
public:
Vector(int size = 2) : len(size){ items = new T[len]; }
int size() const { return len; } // 获取数组长度。
~Vector()
{
delete[] items; items = nullptr;
}
void resize(int size) //扩展数组的内存空间
{
if(size < len) return;
T* tmp = new T[size];
for (int ii = 0; ii < len; ii++) tmp[ii] = items[ii];
delete[] items; // 释放原来的数组。
items = tmp; // 让数组指针指向新数组。
len = size; // 扩展后的数组长度。
}
T& operator[](int ii) // 重载操作符[],可以修改数组中的元素。
{
if (ii >= len)
{
resize(ii + 1); // 扩展数组。
cout<<“running extern array function-----”<<endl;
}
return items[ii];
}
};

int main(void)
{
Vector<MyStack> vs;
vs[0].push(“111”);
vs[0].push(“222”);
vs[0].push(“333”);
vs[1].push(“aaa”);
vs[1].push(“bbb”);
vs[1].push(“ccc”);
for (int ii = 0; ii < vs.size(); ii++) // 遍历Vector容器。
{
while (vs[ii].isEmpty() == false) // 遍历Stack容器。
{
string item; vs[ii].pop(item); cout << "item = " << item << endl;
}
}
vs[2].push(“666”);
vs[2].push(“444”);

for (int ii = 0; ii < vs.size(); ii++)         // 遍历Vector容器。
{
	while (vs[ii].isEmpty() == false)      // 遍历Stack容器。
	{
		string item; vs[ii].pop(item); cout << "item = " << item << endl;
	}
}    

}

6)类模板的具体化案例:
#include
#include
#include <string.h>
using namespace std;

//类模板具体化分为:完全具体化和部分具体化;在与没有具体化的类在一起时,有先后顺序;
template<class T1,class T2> //这个没有具体化的类是不能屏蔽的,否则会找不到模板类
class AA
{
public:
T1 a1;
T2 b1;
AA(const T1& a,const T2& b) : a1(a),b1(b){cout<<“class constructor is running”<<endl; }
void show() const;
};
template<class T1,class T2>
void AA<T1,T2>::show()const
{
cout<<“没有具体化的类:”<<"a1 is: “<<a1<<” b1 is: "<<b1<<endl;
}

template
class AA<int,T> //部分具体化
{
public:
int a1;
T b1;
AA(const int& a,const T& b) : a1(a),b1(b){cout<<“class constructor is running”<<endl; }
void show() const;
};
template
void AA<int,T>::show()const
{
cout<<"部分具体化: "<<"a1 is: “<<a1<<” b1 is: "<<b1<<endl;
}

template<>
class AA<int,string> //完全具体化
{
public:
int a1;
string b1;
AA(const int& a,const string& b) : a1(a),b1(b){cout<<“class constructor is running”<<endl; }
void show() const;
};
void AA<int,string>::show()const
{
cout<<"完全具体化: "<<"a1 is: “<<a1<<” b1 is: "<<b1<<endl;
}

int main(void)
{
AA<int,string>aa(3,“abc”); //执行的优先级顺序:先执行完全具体化>部分具体化>没有具体化;
aa.show();
return 0;
}

1)speed2000软件设置:
//选择generator软件,之后打开相关软件,选择file->new-power ground noise simulation对话框;
//选择tool->option->edit option->grid and unit对话框,layout unit选择mil,snap object to grid 勾选;
//—>electric models,选择用户定义最大频率提取参数;
//—>field solver,选择自然边界条件;
2)添加网络:
//在net manager中,右键选择new,生成网络,可以更改名字,完成后可以classify为电源网络或者地网络,或者信号网络;
3)添加导线:
在edit中,选择trace->add,则可以添加导线,选择导线后,可以设置线宽,并赋予其网络,可以移动导线;
4)设置过孔:
添加自定义过孔:edit->stackup->pad stack->选择下面new按钮,添加新的过孔;
在shape选择圆形,宽度22,高度22,anti 32mil,out diameter选10mil,最后设置 set as default使其作为默认过孔;
5)过孔与走线铜箔相连:
务必显示node,这样在node上打过孔,则会出现via editing对话框,选择property,选择对应网络,如果过孔连接到对应网络,则颜色会变;
如果在一个导线上添加过孔,需添加一个node,加过孔才可以;
6)铜箔处理:
选择-edit->shape->可以进行添加、删除铜箔,最后执行shape process使其merge铜箔完整;

//模板类与函数
#include //157 模板类与函数
using namespace std;

//模板类与函数
//模板类用于函数的参数和返回值有三种形式;
template<class T1,class T2>
class AA
{
public:
T1 x;
T2 y;
AA(const T1 a,const T2 b) : x(a),y(b){}
void show()const
{
cout<<"show x: “<<x<<”\t\tshow y: "<<y<<endl;
}
};

class BB
{
public:
void show()const
{
cout<<“show BB class”<<endl;
}
};

// AA<int, string> func(AA<int, string>& aa)
// {
// aa.show();
// cout << “调用了func(AA<int, string> &aa)函数。\n”;
// return aa;
// }

// template<typename T1,typename T2>
// AA<T1, T2> func(AA<T1, T2>& aa)
// {
// aa.show();
// cout << “调用了func(AA<T1, T2> &aa)函数。\n”;
// return aa;
// }

template
T func(T& aa)
{
aa.show();
cout << “调用了func(T& aa)> &aa)函数。体现了函数模板精髓\n”;
return aa;
}

int main(void)
{
AA<int,string> aa(4,“helloworld”);
func(aa);
BB bb;
func(bb);
return 0;
}

6)模板类与友元
template<class T1,class T2>
class AA
{
public:
T1 x;
T2 y;
AA(const T1 a,const T2 b) : x(a),y(b){}
friend void show(const AA<T1,T2>& a) //这种方案的本质是:编译器利用模板参数帮我们生成了友元函数;
{
cout<<"show x: “<<a.x<<”\t\tshow y: "<<a.y<<endl;
}
};

int main(void)
{
AA<int, string> a(88, “我是一只傻傻鸟。”);
show(a);

AA<char, string> b(88, "我是一只傻傻鸟。");
show(b);

return 0;

}

6)模板类的成员模板(成员模板包括类模板和函数模板)
#include //157 模板类与函数
using namespace std;

//类模板中包含类模板
template<class T1,class T2>
class AA
{
public:
T1 m_x;
T2 m_y;
AA(const T1 a,const T2 b) : m_x(a),m_y(b){}
void show(void)
{
cout<<"show m_x: “<<m_x<<”\tshow m_y: "<<m_y<<endl;
}

template<class T>
class BB	
{
public:
	T m_a;
	T1 m_b;
	BB(){}
	void show(); //只保留声明
	// void show() const {cout<<"show x: "<<m_a<<"\t\tshow y: "<<m_b<<endl;}
};
BB<string> m_bb; //m_bb类AA的一个成员变量

template<class T>
void show(T tt); //类模板AA的成员函数,所以可以访问类A的成员变量;
// {
// 	cout<<"show tt: "<<tt<<endl; 	
// 	cout<<"show x: "<<m_x<<"\t\tshow y: "<<m_y<<endl;
// 	m_bb.show();
// }

};

//模板类的成员模板类的类外定义
template<class T1,class T2>
template
void AA<T1,T2>::BB::show()
{
cout<<"show x: “<<m_a<<”\t\tshow y: "<<m_b<<endl;
}

//模板类的成员模板函数类外定义
template<class T1,class T2>
template
void AA<T1,T2>::show(T tt)
{
cout<<"show tt: "<<tt<<endl;
cout<<"show x: “<<m_x<<”\t\tshow y: "<<m_y<<endl;
m_bb.show();
}

int main(void)
{
AA<int, string> a(88, “我是一只傻傻鸟。”);
a.show();
a.m_bb.m_a = “hello world”;
a.m_bb.show();
a.show(“111111111111111111”);
return 0;
}

第七天学习
案例实操1(调用外接电源信号源):speed2000仿真一个信号经过一个电阻->过孔->负载->地路径,所观察的电压和电流分布情况;
1)打开软件,添加老师提供的文件,xxx.spd文件;
2)查看叠层信息,焊盘信息等是否标准;
3)添加激励源,会出现component manager对话框,点击下面load,添加以xxx.ckt文件的激励源;
4)为模型添加元器件,选择new可以添加元器件;
5)设置仿真时间,一般10ns;
6)设置电压观测点和电流观测点,左键鼠标正,右键鼠标负;
7)设置网格(默认值即可);
8)开始仿真,根据仿真结果查看是否合格;

案例实操2(仿真波形结果计算):
操作步骤基本和实操1相等,不同之处是:
回顾了了以前的学习过孔的添加;
添加了平面噪声,方法如:setup->simulation view->layout voltage,现在参考平面;
熟练使用speed2000软件是重中之重!!!

猜你喜欢

转载自blog.csdn.net/qq_30143193/article/details/131550169
今日推荐