网站建设首选公司,大丰专业做网站,电脑网站怎样给网页做适配,什么网站做效果图最多1、简介 Verilog的语法和C语言非常类似#xff0c;相对来说还是非常好学的。和C语言一样#xff0c;Verilog语句也是由一连串的令牌#xff08;Token#xff09;组成。1个令牌必须由1个或1个以上的字符#xff08;character#xff09;组成#xff0c;令牌可以是#x…1、简介 Verilog的语法和C语言非常类似相对来说还是非常好学的。和C语言一样Verilog语句也是由一连串的令牌Token组成。1个令牌必须由1个或1个以上的字符character组成令牌可以是
注释Comment空白符White space运算符Operator数字Number字符串String标识符Identifier关键字Keyword Verilog是区分大小写的所以下面两个变量是不相同的 var_a //小写 var_A; //大写 Verilog的书写格式很自由既可以把代码写在同一行也可以写在多行。不过一般来讲我都建议一条代码写一行这样的代码格式美观阅读起来也没那么累。每一条Verilog语句的末尾都应使用 ; 即分号作为结束。下面两种写法是等价的 //换行写法推荐写法 reg a; wire b; //不换行写法眼睛看得累写法 reg a;wire b; 除了转义字符escaped identifiers外的空白符和换行符都没有实际意义在编译阶段会被编译工具忽略。 2、注释Comment 子曾经曰过我平生最讨厌两件事----写代码的时候写注释和看没注释的代码。 写注释是一个很好的开发习惯虽然有些麻烦但确实可以帮助其他开发者阅读代码也可以在自己更改代码的时候提供一些思路上的帮助。因为编译器不会对注释进行编译所以注释可以看做是给开发者阅读的设计说明----也就是说注释可以是英文也可以是中文。 Verilog 有 2 种注释方式
用 // 进行单行注释在 // 后面的单行内容均会被编译器视为注释。。例如 reg cnt//定义一个寄存器cnt 用 /* 与 */ 进行跨行注释 /* 与 */ 内的内容均会被编译器视为注释/* 与 */ 可以是多行也可以是一行。例如 reg cnt/* 定义一个寄存器cnt */。 reg cnt /* 定义一个 寄存器 cnt */ 该种注释方式不可嵌套注释一般也没必要嵌套。 3、空白符White space 空白符是指 空格符spaces, 制表符tabs, 换行符newlines, 和换页符formfeeds。当空白符用于独立的令牌时编译器通常会忽略它但当空格符和制表符在字符串中则不能被忽略它们会起到作用。 空白符通常被用来对齐以调整代码格式从而使代码更具可读性。比如下面的代码看起来有点拥挤不够美观的同时也不方便阅读 reg[3:0]cnt;//定义一个4位宽的寄存器cnt wire[15:0]blk;//定义一个15位宽的线网blk 由于空白符是对编译不起作用的所以上面的代码可以通过空白符来等价地修改为 reg [3 :0] cnt; //定义一个4位宽的寄存器cnt wire [15:0] blk; //定义一个15位宽的线网blk 这样的代码看起来就舒服多了。 4、运算符Operator Verilog中有3种类型的运算符
一元运算符unary一元运算符必须放在运算数的左边。例如 x ~y // ~是一元运算符y是运算数该句表示对y值取反后赋给x 二元运算符binary二元运算符必须放在两个运算数的中间。例如 z x y // 是二元运算符x、y是运算数该句表示将x、y值相与后赋给z 三元运算符ternary 或者叫 条件运算符conditional条件运算符由两个独立的运算符来分开三个运算数。例如 x (y 5) ? 1 : 0 // ?和是条件运算符表达式(y 5)、1和0是运算数。该句表示当 y5 成立时将1赋给x否则将0赋给x。 5、数字Number Verilog中的数字有两种形式整数integer constants和实数real constants。
整数 整数除了可以使用我们最熟悉同时也是默认使用的10进制decimal外还可以使用2进制binary、8进制octal和16进制hexadecimal。例如 16 //10进制的16 0x10 //16进制的16 10000 //2进制的16 20 //8进制的16 整数的写法可以指明位宽也可以不指明位宽。
指明位宽 这种写法的一般格式为 [size][base_format][number] size用来指定数字的位宽这个数只能用10进制表示即10一定表示位宽为10进制的10而不是位宽为16进制的16撇号apostrophe character 介于size和base_format之间base_format用来指定数字的进制可以是2进制(b or B)、8进制 (o or O)、10进制 (d or D)、和16进制(h or H) number即为数字本身2进制的0和1、8进制的0~7、10进制的0~9和16进制的0~9/a/b/c/d/e/f不区分大小写 例如 4b1010 //位宽为4的2进制数字1010 5d3 //位宽为5的10进制数字3 不指明位宽 不指名位宽直接写数字时默认为10进制位宽取决于所用的编译器位宽一般为32写法有2种 d10 //位宽根据编译器而定一般为32即32d10 10 //位宽根据编译器而定一般为32即32d10 4af //非法写法f为16进制数字但是这里没有表明进制 负数 在表示位宽的数字前面加一个负号 - 来表示负数例如 -6d3 //位宽为6的数字-3 如果把负号 - 放在进制和数字之间则是非法的例如 6d-3 //这是非法写法。一定要注意因为与日常写法很相似。 可以在base_format前添加一个s或S来指明这是一个有符号数当然也可以不添加。有符号数的最高位将被视为符号位----0表示正数1表示负数。例如 4b1111 //无符号数等于10进制的15 4sb1111 //有符号数最高位1表示负数剩余三位111转化等于10进制的7 负数应以二进制的补码形式表示例如 -8d6 // 这定义了6的补码 4shf // 等价于有符号数4b1111最高位1表示为负数剩余三位111的补码取反1是1所以等价于 -4h1 -4sd15 // 等价于有符号数-4b1111最高位1表示为负数剩余三位111的补码取反1是1所以等价于 -(-4d1)即4d1 下划线 当数字过多的时候可以用下划线underscore character _ 来拆分数字提高阅读效率但是下划线不可以放在数字的最开始。下划线无实际意义仅用于辅助阅读。例如 16‘b1010111101010111 //数字太多阅读起来不太方便 16‘b1010_1111_0101_0111 //用下划线拆分数字后阅读起来方便多了 16‘b_1010_1111_0101_0111 //非法写法下划线不能放在数字的最前面 实数 实数的表示方法有2种10进制表示法decimal notation和 科学计数法scientific notation。
10进制表示法 该方法有小数点且小数点两边都必须存在至少一位数字。例如 1.2 //合法写法 0.1 //合法写法 2394.26331 //合法写法 .12 //非法写法小数点左侧不存在至少一位数字 9. //非法写法小数点右侧不存在至少一位数字 科学计数法 把一个数表示成 a1≤|a|与10的nn为整数次幂相乘的形式其中10的整数次幂用e或E 数字来表示例如10的8次幂即为e8或E8。例如 1.2E2 //大小为120 0.1e-0 //大小为0.1 29E-2 //大小为0.29 .2e-7 //非法写法小数点左侧不存在至少一位数字 4.E3 //非法写法小数点右侧不存在至少一位数字 转换 实数到整数的转换采用四舍五入round的方法而非直接截取整数部分。例如 35.7 36 1.5 2 -1.5 -2 6、字符串String 字符串是由包含在双引号double quotes 内的多个字符组成的有限序列。字符串存储在reg变量中每个字符都需要8 bits的空间。例如 reg [8*12:1] stringvar; //位宽96 bits initial begin stringvar Hello world!; //12个字符共需要12*896 bits end 字符串不能跨行书写即字符串中不能包含回车符。下面是跨行的非法写法 reg [8*12:1] stringvar; initial begin stringvar Hello world!; //非法写法 end 如果字符串的内容大于存储空间则最高测最左侧的多余内容会被截掉如果字符串的内容小于存储空间则最高测最左侧的多余空间会填充0。例如
module tb_test;reg [3*8 : 1] str1;
reg [7*8 : 1] str2;initial beginstr1 Hello; //5字符放入3个byte左侧多余的 He 会被截掉$display(%s is stored as %h, str1,str1); //打印str1str2 Hello; //5字符放入7个byte左侧多余空间会用0填充$display(%s is stored as %h, str2,str2); //打印str2
endendmodule 字符串是以字符的ASCII码形式存储的H e l l o的ASCII码分别为 0x48 0x65 0x6c 0x6c 0x6f所以上面代码的打印内容是这样的 llo is stored as 6c6c6f //多余的左侧两位 He 被截断 Hello is stored as 000048656c6c6f //多出的左侧两位空间被填充 0 还有一类字符被称为转义字符----以反斜杠 \ 为开头后面跟一个或几个字符其意思是将反斜杠 \ 后面的字符转变成为另外的意义。例如 \n 不代表字母n而作为换行字符。类似的转义字符还有
转义字符说明\n换行字符\t制表字符\\\\ 7、标识符Identifier 标识符是指用来标识某个实体如变量、信号、模块等object的独特符号它可以是任意一组字母、数字、$ 美元符号和 _(下划线)符号的组合但标识符的第1个字符必须是字母或者下划线且不能以数字或者美元符号开始。此外标识符是区分大小写的。 shiftreg_a //合法标识符 busa_index //合法标识符 error_condition //合法标识符 merge_ab //合法标识符 _bus3 //合法标识符 n$657 //合法标识符 23 //非法标识符不能以数字开始 2var //非法标识符不能以数字开始 $var //非法标识符不能以美元符号开始 标识符的长度限制取决于具体使用的编译器但是这个限制长度至少要大于1024个字符。如果标识符超出长度那么编译器需要发出错误警告。 为了能够使用标识符集合以外的字符或标号除了普通的标识符外 Verilog还定义了转义标识符Escaped identifiers。采用转义标识符可以在一条标识符中包含任何可打印的字符。转义标识符以反斜杠 \ 开头以空白字符空格字符、制表字符或换行字符结尾。例如 \busaindex \-clock \***error-condition*** \net1/\net2 \{a,b} \a*(bc) 开头的反斜杠和结尾的空白字符都不会被视为转义标识符的一部分例如 \cpu3 就等价于 cpu3 。 8、关键字Keyword 关键字是 Verilog 中预留的用于定义语言结构的特殊标识符。关键字不能转义且关键字全部为小写。下图是Verilog-2005中的所有关键字 9、其他 除了上述的7类语法外Verilog中还有一些特殊的语法。
系统任务和函数 系统任务和函数System tasks and functions是一类预定义好的系统子函数用于实现特定的功能。它们不是Verilog的功能语法一般只能用于仿真。所有的系统任务都以美元符号$作为开始例如 $display (display a message); //打印系统任务用于仿真时打印信息 $finish; //结束仿真系统任务用于结束仿真 编译指令 以反引号 开始的编译指令Compiler directives 为Verilog代码的编写、编译、调试等提供了极大的便利。例如 define wordsize 8 //定义wordsize等价于8 属性 属性Attributes通俗来讲就是Verilog开放的某些特定操作的接口。例如 (* fsm_state *) reg [7:0] state1; //指定这是状态机的状态编码 如果不添加属性(* fsm_state *)那么后面定义的reg state1有可能不会被综合工具指定为状态机的状态编码。 您有任何问题都可以在评论区和我交流本文由 孤独的单刀 原创首发于CSDN平台博客主页wuzhikai.blog.csdn.net您的支持是我持续创作的最大动力如果本文对您有帮助还请多多点赞、评论和收藏⭐