光纤传感VHDL知识点学习笔记.docx
《光纤传感VHDL知识点学习笔记.docx》由会员分享,可在线阅读,更多相关《光纤传感VHDL知识点学习笔记.docx(19页珍藏版)》请在冰豆网上搜索。
光纤传感VHDL知识点学习笔记
此文档是笔者学习VHDL的第15天写的笔记知识点,其中不少包含了初学者容易遇到的问题,也解决了一部分遇到的问题。
本次更新包含11个知识点,力求以简单通俗的语句,解释清楚那些遇到的问题。
该文档知识点杂乱无章,笔者想到一点就会写一点进去;
力求能够给初学者理清思路,更加坚定自己不确定的概念。
知识点1:
变量&信号
<=是对信号进行赋值的赋值操作符,另外在关系运算中作为小于等于号使用;
:
=是对变量和常量进行赋值的赋值操作符,另外在声明信号、变量、常量的时候,可以用:
=对其赋初值。
变量和信号,不妨自己写个代码,其实在描述D触发器,等,有些地方,变量和信号是一样的,都能综合出一模一样的电路。
但是我们要注意,
变量的定义地点是process中的进程说明语句(过程说明,函数说明)
信号的定义地点是ARCHI结构体中的结构体说明语句。
且,变量是局部有效的,SIGNAL在整个ARCHI内都是有效的,process说明部分不允许出现信号和共享变量的定义。
可以在不同进程中读取一个信号,不能在不同进程中对同一个信号赋值。
进程和进程之间可以通过共享变量进行通信,也可以通过信号进行通信。
在同一个结构体中的多个进程可以通过对同一个信号敏感,实现各个进程同步。
变量和信号可以被连续的赋值,但是常量只能被赋值一次。
通常在申明常量的时候顺便就给它赋值,常量是指一个不变化的量。
对于可综合的整数类型的变量和信号,必须指明其大小,否则无法综合
variablea:
std_logicrange0to10
知识点2:
STD_LOGIC_VECTOR
std_logic_vector是标准逻辑矢量,定义的是长度大于1的变量,需要确定赋值方向(ndownto0)or(0ton)。
理解:
是一维的,用于存放多个bit。
std_logic是长度为1的逻辑与bit相似,只是bit只能是'0’和'1‘而std_logic有以下九种状态:
U'——初始值,'X'——不定,'0'——0,'1'——1,'Z'——高阻,'W'——弱信号不定,'L'——弱信号0,'H'——弱信号1,'-'——不可能的情况
知识点3:
行为级和RTL级
RTL级:
registertransferlevel,指的是用寄存器这一级别的描述方式来描述电路的数据流方式;
行为级:
用语句描述电路的功能(行为),不涉及描述内部电路数据是如何流动的。
理解:
通常人类容易去描述这个电路实现了什么功能,由综合工具,综合出内部电路rtl结构。
知识点4:
端口
端口是实体的对外接口,硬件对应物相当于引脚,其实它是一种隐式的信号定义。
而信号本身可看成是一种显式的信号定义,它的硬件对应物是连接线。
一句话,端口可看成信号!
只不过端口模式(in、out、buffer等)限制了端口信号的功能,例如如果端口是out模式,则不能进行内部反馈赋值,而信号则可以随便赋值了。
知识点5:
进程综合
进程语句的启动
在VHDL语言中,进程有两种工作状态:
等待和执行。
当敏感信号表中的信号没有变化时,进程处于等待状态;当敏感信号表中的信号有变化时,进程处于执行状态
进程语句的同步
同一个结构体中不仅可以有多个进程存在,同一个结构体中的多个进程还可以同步。
VHDL中通常采用时钟信号来同步进程,具体方法是:
结构体中的几个进程共用同一个时钟信号来进行激励。
多个进程本身是并行的,进程内部是顺序执行(仅仅对于仿真来说,并不代表我写出的代码综合出的电路也是顺序运行的)
如果我进程内部写组合逻辑电路,综合生成的就是一块存在在那边的电路,并没有顺序可言,因为它就是一块电路,存在在那边,它怎么工作,跟你顺不顺序有什么关系,只是一块akways通电的电路。
知识点6:
信号的具体概念
1.信号
信号是描述硬件系统的基本数据对象,它的性质类似于连接线。
信号可以作为设计实
体中并行语句模块间的信息交流通道。
信号作为一种数值容器,不但可以容纳当前值,也可以保持历史值(这决定于语句的
表达方式)。
这一属性与触发器的记忆功能有很好的对应关系,只是不必注明信号上数据流
动的方向。
信号定义的语句格式与变量相似,信号定义也可以设置初始值,定义格式是:
SIGNAL信号名:
数据类型:
=初始值;
同样,信号初始值的设置也不是必需的,而且初始值仅在VHDL的行为仿真中有效。
与变量相比,信号的硬件特征更为明显,它具有全局性特征。
例如,在实体中定义的信号,
在其对应的结构体中都是可见的,即在整个结构体中的任何位置,任何语句结构中都能获
得同一信号的赋值。
此外还需要注意,信号的使用和定义范围是实体、结构体和程序包,在进程和子程序
的顺序语句中不允许定义信号。
此外,在进程中只能将信号列入敏感表,而不能将变量列
入敏感表。
可见进程只对信号敏感,而对变量不敏感,这是因为只有信号才能把进程外的
信息带入进程内部,或将进程内的信息带出进程。
2.信号与端口
事实上,除了没有方向说明以外,信号与实体的端口(Port)概念是一致的。
对于端口来
说,其区别只是输出端口不能读入数据,输入端口不能被赋值。
信号可以看成是实体内部(设
计芯片内部)的端口。
反之,实体的端口只是一种隐形的信号,在实体中对端口的定义实质
上是作了隐式的信号定义,并附加了数据流动的方向,而信号本身的定义是一种显式的定
义。
因此,在实体中定义的端口,在其结构体中都可以看成是一个信号,并加以使用,而
不必另作定义。
参考:
3. verilog中reg和wire类型的区别和用法
reg相当于存储单元,wire相当于物理连线
Verilog中变量的物理数据分为线型和寄存器型。
这两种类型的变量在定义时要设置位宽,缺省为1位。
变量的每一位可以是0,1,X,Z。
其中x代表一个未被预置初始状态的变量或者是由于由两个或多个驱动装置试图将之设定为不同的值而引起的冲突型线型变量。
z代表高阻状态或浮空量。
线型数据包括wire,wand,wor等几种类型在被一个以上激励源驱动时,不同的线型数据有各自决定其最终值的分辨办法。
两者的区别是:
即存器型数据保持最后一次的赋值,而线型数据需要持续的驱动
输入端口可以由net/reg驱动,但输入端口只能是net;输出端口可以使net/reg类型,输出端口只能驱动net;若输出端口在过程块中赋值则为reg型,若在过程块外赋值则为net型用关键词inout声明一个双向端口,inout端口不能声明为寄存器类型,只能是net类型。
wire表示直通,即只要输入有变化,输出马上无条件地反映;reg表示一定要有触发,输出才会反映输入。
不指定就默认为1位wire类型。
专门指定出wire类型,可能是多位或为使程序易读。
wire只能被assign连续赋值,reg只能在initial和always中赋值。
wire使用在连续赋值语句中,而reg使用在过程赋值语句中。
在连续赋值语句中,表达式右侧的计算结果可以立即更新表达式的左侧。
在理解上,相当于一个逻辑之后直接连了一条线,这个逻辑对应于表达式的右侧,而这条线就对应于wire。
在过程赋值语句中,表达式右侧的计算结果在某种条件的触发下放到一个变量当中,而这个变量可以声明成reg类型的。
根据触发条件的不同,过程赋值语句可以建模不同的硬件结构:
如果这个条件是时钟的上升沿或下降沿,那么这个硬件模型就是一个触发器;如果这个条件是某一信号的高电平或低电平,那么这个硬件模型就是一个锁存器;如果这个条件是赋值语句右侧任意操作数的变化,那么这个硬件模型就是一个组合逻辑。
输入端口可以由wire/reg驱动,但输入端口只能是wire;输出端口可以使wire/reg类型,输出端口只能驱动wire;若输出端口在过程块中赋值则为reg型,若在过程块外赋值则为net型。
用关键词inout声明一个双向端口,inout端口不能声明为reg类型,只能是wire类型;输入和双向端口不能声明为寄存器类型。
简单来说硬件描述语言有两种用途:
1、仿真,2、综合。
对于wire和reg,也要从这两个角度来考虑。
从仿真的角度来说,HDL语言面对的是编译器(如Modelsim等),相当于软件思路。
这时:
wire对应于连续赋值,如assignreg对应于过程赋值,如always,initial
从综合的角度来说,HDL语言面对的是综合器(如DC等),要从电路的角度来考虑。
这时:
1、wire型的变量综合出来一般是一根导线;2、reg变量在always块中有两种情况:
(1)、always后的敏感表中是(aorborc)形式的,也就是不带时钟边沿的,综合出来还是组合逻辑
(2)、always后的敏感表中是(posedgeclk)形式的,也就是带边沿的,综合出来一般是时序逻辑,会包含触发器(Flip-Flop)
在设计中,输入信号一般来说你是不知道上一级是寄存器输出还是组合逻辑输出,那么对于本级来说就是一根导线,也就是wire型。
而输出信号则由你自己来决定是寄存器输出还是组合逻辑输出,wire型、reg型都可以。
但一般的,整个设计的外部输出(即最顶层模块的输出),要求是寄存器输出,较稳定、扇出能力也较好。
参考:
也就是说VHDL综合出来输出端口一定带寄存器,Verilog不一定?
知识点7:
Quartus建议写的状态机格式
状态机书写的步骤
1.状态寄存器
2.当前态和次态状态转换组合逻辑
下一态根据=>当前态和输入决定
casepresent_stateis
whens0=>ifdin=‘0’then
next_state<=s1;
else
next_state<=
3.present_state状态输出
●当前状态
●输入
Moore:
输出组合逻辑电路,仅和当前态有关。
Mealy:
输出组合逻辑电路,当前态+输入
--QuartusPrimeVHDLTemplate
--Four-StateMealyStateMachine
--AMealymachinehasoutputsthatdependonboththestateand
--theinputs.Whentheinputschange,theoutputsareupdated
--immediately,withoutwaitingforaclockedge.Theoutputs
--canbewrittenmorethanonceperstateorperclockcycle.
libraryieee;
useieee.std_logic_1164.all;
entityfour_state_mealy_state_machineis
port
(
clk:
instd_logic;
input:
instd_logic;
reset:
instd_logic;
output:
outstd_logic_vector(1downto0)
);
endentity;
architecturertloffour_state_mealy_state_machineis
--Buildanenumeratedtypeforthestatemachine
typestate_typeis(s0,s1,s2,s3);
--Registertoholdthecurrentstate
signalstate:
state_type;
begin
process(clk,reset)
begin
ifreset='1'then
state<=s0;
elsif(rising_edge(clk))then
--Determinethenextstatesynchronously,basedon
--thecurrentstateandtheinput
casestateis
whens0=>
ifinput='1'then
state<=s1;
else
state<=s0;
endif;
whens1=>
ifinput='1'then
state<=s2;
else
state<=s1;
endif;
whens2=>
ifinput='1'then
state<=s3;
else
state<=s2;
endif;
whens3=>
ifinput='1'then
state<=s3;
else
state<=s1;
endif;
endcase;
endif;
endprocess;
--Determinetheoutputbasedonlyonthecurrentstate
--andtheinput(donotwaitforaclockedge).
process(state,input)
begin
casestateis
whens0=>
ifinput='1'then
output<="00";
else
output<="01";
endif;
whens1=>
ifinput='1'then
output<="01";
else
output<="11";
endif;
whens2=>
ifinput='1'then
output<="10";
else
output<="10";
endif;
whens3=>
ifinput='1'then
output<="11";
else
output<="10";
endif;
endcase;
endprocess;
endrtl;
--QuartusPrimeVHDLTemplate
--Four-StateMooreStateMachine
--AMooremachine'soutputsaredependentonlyonthecurrentstate.
--Theoutputiswrittenonlywhenthestatechanges.(State
--transitionsaresynchronous.)
libraryieee;
useieee.std_logic_1164.all;
entityfour_state_moore_state_machineis
port(
clk:
instd_logic;
input:
instd_logic;
reset:
instd_logic;
output:
outstd_logic_vector(1downto0)
);
endentity;
architecturertloffour_state_moore_state_machineis
--Buildanenumeratedtypeforthestatemachine
typestate_typeis(s0,s1,s2,s3);
--Registertoholdthecurrentstate
signalstate:
state_type;
begin
--Logictoadvancetothenextstate
process(clk,reset)
begin
ifreset='1'then
state<=s0;
elsif(rising_edge(clk))then
casestateis
whens0=>
ifinput='1'then
state<=s1;
else
state<=s0;
endif;
whens1=>
ifinput='1'then
state<=s2;
else
state<=s1;
endif;
whens2=>
ifinput='1'then
state<=s3;
else
state<=s2;
endif;
whens3=>
ifinput='1'then
state<=s0;
else
state<=s3;
endif;
endcase;
endif;
endprocess;
--Outputdependssolelyonthecurrentstate
process(state)
begin
casestateis
whens0=>
output<="00";
whens1=>
output<="01";
whens2=>
output<="10";
whens3=>
output<="11";
endcase;
endprocess;
endrtl;
知识点8:
process,case顺序,敏感
process内部只能有顺序语句
例如IFTHENELSEENDIF,CASE
CASE语句无顺序无优先级
process组合逻辑电路,需要把所有输入信号写进敏感列表
描述时序逻辑电路,需要包含时钟,清零,置位等
顺序描述语句只能出现在process中
知识点9:
Generic使用方式
GENERIC写的地点,注意是ENTITY和PROT之间!
generic(N:
integer:
=4);
必须是整数才能被综合
知识点10:
withselect和case和whenelse
1.withselect赋值的目标信号必须是信号
2.case赋值信号可以是VARIABLE,也可以是SIGNAL
3.case无顺序无优先级,with…select也是并行
4.case用于process,withselect用于ARCHITECTURE
ARCHITECTURE内部有:
并行部分书写:
条件信号赋值语句
q<=d0whens1=‘0’ands0=‘0’else
d1whens1=‘1’ands0=‘1’else
```
d3whens1=‘1’ands0=‘0’else
‘Z’;
选择信号赋值语句
withcombselect
q<=表达式1when“00”,
表达式2when“10”,
‘Z’whenothers;
知识点11:
REG,latch,FP
LATCH:
E=0保持,E=1,输出Q随输入D变化,Q<=D;
FP:
↑,输出Q随着输入D变化,Q<=D;
REG:
就是由FP组成,多个FP级联,数据位D0D1D2D3…,再↑时刻,同时置入各个FP,然后输出。
libraryieee;
useieee.std_logic_1164.all;
--entitylatchfpis
--port(
--D:
inbit;
--Q:
outbit;
--en:
inbit
--);
--end;
--
--architecturebhvoflatchfpis
--signalQreg:
bit;
--begin
--process(D,en)
--begin
--ifen='1'then
--Qreg<=D;
--else
--Qreg<=Qreg;
--endif;
--endprocess;
--
--Q<=Qreg;
--end;
entitylatchfpis
port(
D:
inbit;
Q:
outbit;
clk:
instd_logic
);
end;
architecturebhvoflatchfpis
signalQreg:
bit;
begin
process(clk)
begin
ifrising_edge(clk)then
Qreg<=D;
else
Qreg<=Qreg;
endif;
endprocess;
Q<=Qreg;
end;
知识点12:
VHDL顺序语句和并行语句
◆并行语句:
1.进程语句PROCESS
2.并行信号赋值语句
●简单信号赋值语句:
目标信号<=表达式,ARCH内部
●选择信号赋值语句:
with…select(不能有重叠,包含所有条件)
●条件信号赋值语句:
when…else(有顺序,上到下逐条测试,允许重叠)
3.并行过程调用语句
4.元器件例化
5.生成语句generate
6.块语句BLOCK
◆顺序语句
1.变量赋值语句:
在PROCESS内部,和子程序内部;
注意在ARCH内赋值是并行的
2.流程控制语句:
●IF…THEN…ENDIF
●CASE(不能有重叠,包含所有条件)
●LOOP
3.空操作语句:
NULL,不满足条件,执行空条件,含义:
锁存信号。
4.等待语句
5.子程序调用
6.返回语句
知识点13:
状态机摩尔米勒
Moore:
输出仅取决于当前的状态
Mealy:
输出仅取决于当前的状态&当前的输入
--位置和信号等,在ARCHITECTURE和BEGIN之间
ARCHITECTUREBHVOFXXIS
SIGNAL···
CONSTANT···
typeState_typeis(s0,s1,s2,s3);
SIGNALState:
State_type;
···
···
BEGIN
···
···
END;
知识点14:
1164,arith,usigned等等
●std_logic_1164
定义了std_logic和std_logi_vector数据类型以及相应的运算
signaloutput:
std_logic;
●