matlabC语言verilog之间的区别.docx
- 文档编号:7513350
- 上传时间:2023-01-24
- 格式:DOCX
- 页数:18
- 大小:40.73KB
matlabC语言verilog之间的区别.docx
《matlabC语言verilog之间的区别.docx》由会员分享,可在线阅读,更多相关《matlabC语言verilog之间的区别.docx(18页珍藏版)》请在冰豆网上搜索。
matlabC语言verilog之间的区别
C语言、verilog与Matlab语言的运算符号的区别
C语言
verilog
Matlab
功能描述
*,/,+,-
乘除一般不能直接写
*,/,+,-
乘,除,加,减
%
%
rem(x,y)
取余(在matlab中%表示注释)
!
!
(逻辑非)
~
取反即非
&&
&&
&
逻辑与
||
||
|
逻辑或
>,<,==
>,<,==
>,<,==
大于,小于,等于
>=,<=
>=,<=(<=也是非阻塞赋值符号)
>=,<=
大于等于,小于等于
!
=
!
=
~=
不等于
===
!
==
条件相等和条件不相等
~
~
无
位反相
&
&
无
按位逻辑与
|
|
无
按位逻辑或
^
^
无
异或
~^
~^
无
同或
>>
>>
无
右移
<<
<<
无
左移
一行注释:
//
多行注释:
/**/
同c语言
一行注释:
%
注释
?
:
?
:
无
等同于if-else叙述
{}
beginend等同于{},执行语句多于一句就要用beginend包含起来;
verilog中{}是拼接运算符,例:
{a[0],b[14:
0]}
{{}}为复制算子:
{3{2‘b10}}结果是6’b101010
forkjoin也等同于{},与beginend
的区别是,前者内部的语句是并行执行的,后者内部的语句是顺序执行的。
十进制:
直接表示
八进制:
以0开头,例如0123;
十进制(’d或‘D):
16’D255
数据格式
十六进制:
0x开头
(在一个整常数后面加上一个字母u或U,认为是无符号整型;在一个常数后面加上l或L,表示长整型)
十六进制(‘h或’H)
二进制(‘b或’B)
八进制(‘o或’O)
#后面加上数值,表示延时多秒个周期
C语言、verilog、Matlab语言的关键字的区别
C语言
verilog
Matlab
功能描述
parametera=1’b1;
状态机里面都用parameter
参数定义,模块中a代表二进制1
definea=1’b1;
a代表1’b1
parameter 作用于声明的那个文件;`define 从编译器读到这条指令开始到编译结束都有效,或者遇到`undef命令使之失效
if(条件a)
{执行指令A};
elseif(条件b)
{执行指令B};
……
else
{执行指令N};
if()
begin语句end;
elseif()
begin语句end;
……
else
;
注:
verilog的elseif是分开的
if表达式
语句
elseif表达式
语句
else
语句
end
if条件判断语句
for(表达式的;表达式样;表达式3)
{执行语句}
或者
for(循环变量赋初值;循环条件;循环变量增值)
{执行语句}
硬件描述语言一般禁用for语句。
只在测试模块中使用。
格式同C语言。
for(循环变量赋初值;循环条件;循环变量增值)
begin
执行语句;
for变量=向量
语句
end
例子:
x=0;
fori=1:
1:
10
x=x+1;
end
for循环语句
end
while(表达式)
{执行语句}
或者
do
{语句}
while(表达式)
同for语句;
格式同C语言;但没有dowhile。
while()
begin
执行语句;
end
while表达式
语句
end
while循环语句
无
repeat(表达式)
begin
执行语句;
end
无
repeat循环语句
switch(表达式)
{
case常量表达式1:
{语句1}
case常量表达式2:
{语句2}
case常量表达式3:
{语句3}
.........
default:
{语句n+1}
}
case语句
case()
x:
;
y:
;
z:
;
default:
;
endcase
用的最多。
Switch表达式
Case常量表达式1语句1
Case常量表达式2语句2
Case常量表达式3语句3
………
Otherwise语句
end
switch分支语句
Break:
结束for或while整个循环
Continue:
结束for或while单次循环
无
Break:
结束for或while整个循环
Continue:
结束for或while单次循环
Break和while语句
类型标识符函数名(形式参数表列)
{声明部份
语句部分
}
例:
Intmax(intx,inty)
{intz ;
z=x>y ?
x :
y ;
return(z);
}
function<返回值的类型或范围>(函数名);
<端口及数据类型说明>;
<语句>;
Endfunction
例:
function[7:
0]getbyte
input[15:
0]address
begin
执行语句;
getbyte=result_expresstion;
end
endfunction
function[out1,out2,...]=funname(in1,in2,...)
例:
function[mean,stdev]=stat(x)
n=length(x);
mean=sum(x)/n;
stdev=sqrt(sum((x-mean).^2/n));
function语句
说明:
1定义数时至少有一个输入参量
2必须有一条赋值语句给函数中的一个内部变量赋与函数的结果值,该内部变量与函数名相同
assigna=b;连续赋值
组合逻辑语言,always外面的赋值语句;
always模块里面的
阻塞赋值=
非阻塞赋值<=
赋值语句
module<模块名>(<引脚列表>);
input<引脚名>;定义类型
output;
reg;
<子模块名><在本模块的名称>(<引脚列表>);
(例:
dspi1(.clk(clk)
……
);
.clk表示子模块中的名称,(clk)表示本模块中的名称)
endmodule
一个文件的形式
Taskendtask
Eg:
Taskand;//定义任务名
Inputa,b;
Outputc;
Begin
C=a+b;
End
endtask
任务定义
wire组合逻辑数据类型
reg时序逻辑数据类型
定义数据类型
1、always语句,连续执行;用于时序逻辑
always@(posedgeclk1ornegedge)边沿(上升沿)触发
结构语句
beginend
用于组合逻辑
always@(aorb)敏感列表
beginend
2、initial语句,只用于测试模块,只执行一次
initial
begin语句end
(一个模块中可以有多个initial块,它们都是并行运行的,initial块常用于测试文件虚拟模块。
)
3、task语句,任务
task模块名;
<端口及数据类型说明>;
<语句>;
endtask
4、function语句,函数,返回一个表达式的值。
function<返回值的类型或范围>(函数名);
<端口及数据类型说明>;
<语句>;
endfunction
*3、4不常用
可综合的verilog语法子集
常用的RTL语法结构如下:
☆模块声明:
module……endmodule
☆端口声明:
input,output,inout(inout的用法比较特殊,需要注意)
☆信号类型:
wire,reg,tri等,integer常用语for语句中(reg,wire时最常用的,一般tri和integer不用)
☆参数定义:
parameter
☆运算操作符:
各种逻辑操作符、移位操作符、算术操作符大多时可综合的(注:
===与!
==是不可综合的)
☆比较判断:
if……else,case(casex,casez)……defaultendcase
☆连续赋值:
assign,问号表达式(?
:
)
☆always模块:
(敏感表可以为电平、沿信号posedge/negedge;通常和@连用)
☆begin……end(通俗的说,它就是C语言里的“{}”)
☆任务定义:
task……endtask
☆循环语句:
for(用的也比较少,但是在一些特定的设计中使用它会起到事半功倍的效果)
☆赋值符号:
=和<=(阻塞和非阻塞赋值,在具体设计中时很有讲究的)
可综合的语法时verilog可用语法里很小的一个子集,用最精简的语句描述最复杂的硬件,这也正是硬件描述语言的本质。
对于做RTL级设计来说,掌握好上面这些基本语法是很重要。
关于C语言的一点总结
头文件中常用
1类型定义:
typedef
(1)定义一般的类型
例如:
typedefintint16;
typedeflongint32;
typedefunsignedintUint16;
typedefunsignedlongUint32;
typedeffloatfloat32;
typedeflongdoublefloat64;
(2)定义结构体为一种数据类型:
typedefstruct{
_iqfs;/*Input:
samplingfrequency(Q15)*/
_iqfn;/*Input:
thenotchfrequency(Q15)*/
_iqBW;/*theband_widthofattenuationby3DB(Q15)*/
_iqb0;/*Output:
thecoficientofnumerator(Q15)*/
_iqb1;/*Output:
thecoficientofnumerator(Q15)*/
_iqb2;/*Output:
thecoficientofnumerator(Q15)*/
_iqa0;/*Output:
thecoficientofdenominator(Q15)*/
_iqa1;/*Output:
thecoficientofdenominator(Q15)*/
_iqUk;/*input:
thecurrentinputofsignal*/
_iqUk_1;/*input:
thepreviousinputofsignal*/
_iqUk_2;/*input:
thepreviousinputofsignal*/
_iqYk;/*output:
thecurrentoutputoffilteredsignal*/
_iqYk_1;/*output:
thepreviousoutputoffilteredsignal*/
_iqYk_2;/*output:
thepreviousoutputoffilteredsignal*/
void(*calc)(void*);/*Pointertothe1st_Lowpass_Filterfunction*/
}NF;
NF为一种结构体类型,可以用NF来定义变量;
例如:
NFnf=NF_initial;//定义一个变量nf,nf为NF类型的,并赋初值。
(采用这种方式与直接采用struct的区别是直接用NF,不用带struct,struct的用法见下面)
(3)定义一种指向结构体的指针类型
typedefNF*NF_handle;//NF_handle是一种指针类型,
voidnotch_calc(NF_handle);//头文件中的函数申明中,函数notch_calc的输入值是一//个NF型的指针变量;
2结构体定义struct
(1)先定义结构,再说明结构变量。
如:
structstu
{intnum;
charname[20];
charsex;
floatscore;
};
structstuboy1,boy2;
说明了两个变量boy1和boy2为stu结构类型。
也可以用宏定义使一个符号常量来表示
一个结构类型。
例如:
#defineSTUstructstu
STUboy1,boy2;这样可以省掉struct
(2)在定义结构类型的同时说明结构变量。
例如:
structstu
{
intnum;
charname[20];
charsex;
floatscore;
}boy1,boy2;
这种形式的说明的一般形式为:
struct结构名
{
成员表列
}变量名表列;
(3)直接说明结构变量。
例如:
struct
{
intnum;
charname[20];
charsex;
floatscore;
}boy1,boy2;
这种形式的说明的一般形式为:
struct
{
成员表列}变量名表列;
(4)定义结构体的位域
structSCIFFCT_BITS{//bitsdescription
Uint16FFTXDLY:
8;//7:
0FIFOtransmitdelay
Uint16rsvd:
5;//12:
8reserved
Uint16CDC:
1;//13Autobaudmodeenable
Uint16ABDCLR:
1;//14Autobaudclear
Uint16ABD:
1;//15Autobauddetect
};
同位体定义union
unionSCIFFCT_REG{
Uint16all;
structSCIFFCT_BITSbit;
};
3宏定义#define
#define标识符字符串
4文件包含:
‘..\’表示跳出该文件夹
‘.\’表示本文件夹中
例如:
#include".\include\DSP281x_Device.h"表示DSP281x_Device.h文件在当前位置中的include文件夹中。
"..\include\DSP281x_Device.h"表示DSP281x_Device.h文件在当前位置外的include文件夹中
5指针的总结
1.指针是C语言中一个重要的组成部分,使用指针编程有以下优点:
(1)提高程序的编译效率和执行速度。
(2)通过指针可使用主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯。
(3)可以实现动态的存储分配。
(4)便于表示各种数据结构,编写高质量的程序。
2.指针的运算
(1)取地址运算符&:
求变量的地址
(2)取内容运算符*:
表示指针所指的变量
(3)赋值运算
·把变量地址赋予指针变量
·同类型指针变量相互赋值
·把数组,字符串的首地址赋予指针变量
·把函数入口地址赋予指针变量
(4)加减运算
对指向数组,字符串的指针变量可以进行加减运算,如p+n,p-n,p++,p--等。
对指向同一数组的两个指针变量可以相减。
对指向其它类型的指针变量作加减运算是无意义的。
(5)关系运算
指向同一数组的两个指针变量之间可以进行大于、小于、等于比较运算。
指针可与0比较,p==0表示p为空指针。
3.与指针有关的各种说明和意义见下表。
int*p; p为指向整型量的指针变量
int*p[n]; p为指针数组,由n个指向整型量的指针元素组成。
int(*p)[n]; p为指向整型二维数组的指针变量,二维数组的列数为n
int*p() p为返回指针值的函数,该指针指向整型量
int(*p)() p为指向函数的指针,该函数返回整型量
int**p p为一个指向另一指针的指针变量,该指针指向一个整型量。
4.有关指针的说明很多是由指针,数组,函数说明组合而成的。
但并不是可以任意组合,例如数组不能由函数组成,即数组元素不能是一个函数;函数也不能返回一个数组或返回另一个函数。
例如
inta[5]();就是错误的。
5.关于括号
在解释组合说明符时,标识符右边的方括号和圆括号优先于标识符左边的“*”号,而方括号和圆括号以相同的优先级从左到右结合。
但可以用圆括号改变约定的结合顺序。
6.阅读组合说明符的规则是“从里向外”。
从标识符开始,先看它右边有无方括号或园括号,如有则先作出解释,再看左边有无*号。
如果在任何时候遇到了闭括号,则在继续之前必须用相同的规则处理括号内的内容。
例如:
int*(*(*a)())[10]
↑↑↑↑↑↑↑
7642135
上面给出了由内向外的阅读顺序,下面来解释它:
(1)标识符a被说明为;
(2)一个指针变量,它指向;
(3)一个函数,它返回;
(4)一个指针,该指针指向;
(5)一个有10个元素的数组,其类型为;
(6)指针型,它指向;
(7)int型数据。
因此a是一个函数指针变量,该函数返回的一个指针值又指向一个指针数组,该指针数组的元素指向整型量。
因为C语言所有复杂的指针声明,都是由各种声明嵌套构成的。
如何解读复杂指针声明呢?
右左法则是一个既著名又常用的方法。
不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。
C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。
右左法则:
首先从最里面的圆括号看起,然后往右看,再往左看。
每当遇到圆括号时,就应该掉转阅读方向。
一旦解析完圆括号里面所有的东西,就跳出圆括号。
重复这个过程直到整个声明解析完毕。
(括号里面从右到左,括号外面从左到右)
笔者要对这个法则进行一个小小的修正,应该是从未定义的标识符开始阅读,而不是从括号读起,之所以是未定义的标识符,是因为一个声明里面可能有多个标识符,但未定义的标识符只会有一个。
现在通过一些例子来讨论右左法则的应用,先从最简单的开始,逐步加深:
int (*func)(int *p);
首先找到那个未定义的标识符,就是func,它的外面有一对圆括号,而且左边是一个*号,这说明func是一个指针,然后跳出这个圆括号,先看右边,也是一个圆括号,这说明(*func)是一个函数,而func是一个指向这一类函数的指针,就是一个函数指针,这一类函数具有int*类型的形参,返回值类型是 int。
int (*func)(int *p, int (*f)(int*));
func被一对括号包含,且左边有一个*号,说明func是一个指针,跳出括号,右边也有个括号,那么func是一个指向函数的指针,这类函数具有int *和int (*)(int*)这样的形参,返回值为int类型。
再来看一看func的形参int (*f)(int*),类似前面的解释,f也是一个函数指针,指向的函数具有int*类型的形参,返回值为int。
int (*func[5])(int *p);
func右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰 func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。
跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。
int (*(*func)[5])(int *p);
func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针(一个指针指向数组),现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。
总结一下,就是:
func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。
int (*(*func)(int *p))[5];
func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。
(疑问:
如果int(*func(intp))[5],是不是就是一个函数,它的形参是int型的,返回值是一个指向5个元素的数组的指针).
要注意有些复杂指针声明是非法的,例如:
int func(void) [5];
func是一个返回值为具有5个int元素的数组的函数。
但C语言的函数返回值不能为数组,这是因为如果允许函数返回值为数组,那么接收这个数组的内容的东西,也必须是一个数组,但C语言的数组名是一个右值,它不能作为左值来接收另一个数组,因此函数返回值不能为数组。
int func[5](void);
func是一个具有5个元素的数组,这个数组的元素都是函数。
这也是非法的,因为数组的元素除了类型必须一样外,每个元素所占用的内存空间也必须相同,显然函数是无法达到这个要求的,即使函数的类型一样,但函数所占用的空间通常是不相同的。
作为练习,下面列几个复杂指针声明给读者自己来解析。
int (*(*func)[5][6])[7][8];
(自己给的解答:
func是一个指针,它指向一个二维数组,并且这个二维数组的元素是指针,这个指针指向一个二维的int型数组.)
int (*(*(*func)(int *))[5])(int *);
(自己给的解答:
func是一个指针,它是一个指向参数为int型指针,返回值是指针的函数指针;这个函数的返回值是指向5个元素的数组的指针,每个元素的指针是一个指向参数为int型指针,返回值是int型的函数指针.)
int (*(*func[7][8][9])(int*))[5];
(自己给的解答:
func是一个数组,数组的每个元素都是一个指针;这个指针指向一个形参为int型指针,返回值为一个指针;这个返回值的指针指向一个5个int型的数组)
实际当中,需要声明一个复杂指
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- matlabC 语言 verilog 之间 区别