matlabC语言verilog之间的区别.docx

上传人:b****6 文档编号:7513350 上传时间:2023-01-24 格式:DOCX 页数:18 大小:40.73KB
下载 相关 举报
matlabC语言verilog之间的区别.docx_第1页
第1页 / 共18页
matlabC语言verilog之间的区别.docx_第2页
第2页 / 共18页
matlabC语言verilog之间的区别.docx_第3页
第3页 / 共18页
matlabC语言verilog之间的区别.docx_第4页
第4页 / 共18页
matlabC语言verilog之间的区别.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

matlabC语言verilog之间的区别.docx

《matlabC语言verilog之间的区别.docx》由会员分享,可在线阅读,更多相关《matlabC语言verilog之间的区别.docx(18页珍藏版)》请在冰豆网上搜索。

matlabC语言verilog之间的区别.docx

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型的数组)

        实际当中,需要声明一个复杂指

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1