丧尸暴龙兽的个人空间 https://blog.eetop.cn/1277016 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

《verilog数字系统设计教程——夏宇闻(第一部分)》一些注意点

已有 2500 次阅读| 2016-11-29 18:13 |个人分类:verilog|系统分类:芯片设计

天气: 冷
心情: 平静
1、系统函数$random。
可用于产生随机数。返回一个32位的带符号整形数。一般使用方法如下:
($random) % b,其中b是一个大于0的整数。则该式会返回一个(-b+1)到(b-1)之间的随机数。

2、门实例化引用中 #+数字表示的是输入到输出的延时。如and #2 a1(out,a,b)。这个延时在综合的时候会被忽略。

3、编译预处理命令 `include。作用为将一个文件中的内容全部包含进另一个文件中标有`include命令的位置。该命令可出现在源程序的任何位置。主要作用是简便程序的编写。

4、reg型变量不一定是寄存器或触发器的输出。

5、memory型变量。可用于对RAM型存储器、ROM存储器和reg文件建模。
定义方式如: reg [7:0] mema[255:0]; 表示定义了一个位宽为8,深度为256的存储器。
读写方式为按地址进行操作,如:mema[3]=8'd0;

6、取模运算“%”的结果的符号与第一个操作数的符号相同。

7、移位运算符  a<<n 或 a>>n,其中n表示要移的位数。

8、非阻塞赋值<=,阻塞赋值=。因为在一个块中,相邻的<=赋值语句在模块结束后一起赋值。而相邻的=赋值语句是按照顺序一条一条赋值。因而前者称为非阻塞赋值,后者称为阻塞赋值。

9、可以给代码中的模块命名。命名方式如下:
begin : block1       fork : block2 

end                         join
模块命名的作用:1、命名块可以声明局部变量。2、可通过模块名层次引用模块内变量。3、可使用disable+模块名的方式禁用命名块。

10、repeat语句常见用法:
repeat(n)
begin

end
即将后面的语句执行n次。需要写在always块中。

11、进行仿真的时候,由于CPU是顺序执行的。可能会引入竞争。

12、生成块的概念。
生成块主要是方便了参数化模块的生成。对大量的重复操作或根据参数决定是否使用某段代码,大大简化程序的编写过程。
由generate和endgenerate来限定了范围。生成语句中的变量定义为genvar型变量。
主要有三种创建生成语句的方法:
1、循环生成。2、条件生成。3、case生成。
例如下面的阵列全加器代码:
module systolic_adder_extensible(a,b,cin,s,cout
    );
parameter WIDTH=4;

input [WIDTH-1:0] a,b;
input cin;
output [WIDTH-1:0] s;
output cout;

wire [WIDTH:0] carry;
assign carry[0]=cin;

genvar i;

generate
    for (i=0;i<WIDTH;i=i+1)
    begin:adder
       wire t1,t2,t3;
        xor #1 x1(t1,a[i],b[i]);
        xor x2(s[i],carry[i],t1);
        and a1(t2,t1,carry[i]);
        and a2(t3,a[i],b[i]);
        or  o1(carry[i+1],t2,t3);
    end
endgenerate

assign cout=carry[WIDTH];

endmodule
借助生成块,可实现任意数据长度的加法器。

13、localparam型的变量为本地参数,不能被实例引用时参数传递修改其值。

14、模块参数传递,上面的阵列加法器,可通过systolic_adder_extensible #(8) adder(a,b,cin,s,cout)的方式,将参数WIDTH值修改为8。

15、任务与函数
任务与函数的不同点:
(1)函数只能与主模块公用一个仿真时间,而任务可以定义自己的仿真时间单位;
(2)函数不能启动任务,而任务可以启动函数和其他任务;
(3)函数至少有一个输入变量,而任务可以没有或有多个任意类型的变量;
(4)函数返回一个值,而任务不返回值。
对函数和任务的理解:
函数类似C语言中的定义,在模块中某处调用,根据输入传入的值,进行运算,最后返回一个结果。即函数返回的结果被当做了表达式中的一个操作数。而任务不返回值,根据输入输出端口的变量进行数据传送。

task说明语句:
task <任务名>;
   <端口及数据类型声明>;
   <语句>;
endtask
调用方式: <任务名> (端口1,端口2,···,端口n);端口顺序要与task定义中端口出现的顺序一致。

function说明语句:
function <返回值的类型或范围>(函数名);
   <端口及数据类型声明>;
   begin
   <语句>;
   end
endfunction
举例如下:
function [7:0] getbyte;
  input [15:0] address;
  begin
     ······
    getbyte=result
  end
endfunction
(1)返回的类型不写默认为寄存器类型;范围不写则默认为1位;
(2)函数默认定义了一个与函数名同名,类型范围一样的变量;
(3)调用方法:<函数名>(表达式1,···,表达式n);
(4)函数的使用规则:函数的定义不能包含任意的时间控制语句,如#,@或wait等;
                                函数不能启动任务;
                                函数至少有一个输入参数;
                                函数定义中必须有一条赋值语句给函数中的与函数名相同名的变量赋以函数的结果值。

定义递归函数时,需要在函数声明时加上关键字 automatic。
如:function automatic integer factorial;  书P88。


16、$display和$write任务
$display("answer=%d",sum);
$write("answer=%d",sum);
前者在输出后自动换行,后者不会。
具体的格式定义,参见书P91。
注意:\\ 输出 \; \"输出";%%输出%;\1~3位数  输出  1~3位八进制数代表的字符。

输出数的位宽,根据定义,如果是十进制输出,则高位0省略,如果是其他进制,则高位0保留。若输出为"answer=%0d"形式,其中插值一个0,自动调整输出数据宽度,以最少的位数来显示数据,及去掉高位的0。

17、文件输出
<文件句柄>=$fopen(“文件名”);
文件句柄是一个只有一位为1的32位数据。可通过对文件句柄进行操作,一次往多个文件中存储数据。
写文件的函数有:$fdisplay,$fwrite,$fmonitor,$fstrobe。写文件的用法与上面方法一样,至少第一个参数变成了句柄名。
最后$fclose(文件句柄);

 
18、显示层次
当一个模块被在上一级模块中被多个实例化调用时,为了查看当前是哪个实例在调用模块,可使用$display,$write,$monitor,$strobe函数(“%m”)来查看,无需其它参数。

19、$strobe语句总是在同一时刻的其他赋值语句执行完之后才执行。

20、值变转储文件(VCD)
将仿真信息转储到VCD文件中;
$dumpfile("文件名"); VCD文件
$dumpvars;     将设计中全部信号转储
$dumpvars(1,top);   将top模块下第一层信号进行转储,及只转储top模块中的信号
$dumpvare(0,top);   将top模块下所有层次信号进行转储
$dumpon;   开始转储
$dumpoff;   结束转储

21、$monitor函数
常用格式$monitor($time,,"····=%d",data);
monitor函数只要其监视的变量一有变化,便会输出结果。一般在initial块中调用。
若有多个monitor函数,则需要配合使用$monitoron 和$monitoroff来将不用的$monitor函数关闭。

22、$time返回一个64位整数来表示当前的仿真时刻值
$realtime返回一个实数。

23、$finish;退出仿真器;
$stop;暂停仿真器

24、$readmemb和$readmemh
这两个函数用于读取文件初始化存储器变量。
格式:$readmemb(“数据文件名”,存储器变量名,起始地址,结束地址);
其中起始地址和结束地址是可选参数。
数据文件中可用 @+地址(十六进制) 来表明下面数据将要存放的地址。

25、宏定义  `define 标识符  字符串
在引用已定义的宏名时,前面需要加"`"。
宏定义最后不要加分号。
如:`define WIDTH 8     
  reg [`WIDTH:1] data;

26、`timescale  <时间单位>/<时间精度>
有效数字是1,10,100
其它有用的编译预处理指令:
`include
`ifdef 宏名   `else   `endif  :条件编译,根据不同的条件选择不同的代码进行编译。



点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 0

    获赞
  • 0

    评论
  • 1063

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-27 17:26 , Processed in 0.015323 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部