加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Verilog模块声明例化

(2019-12-29 14:53:29)
分类: Verilog基础知识
1、模块输入输出的接口声明方法;
2、基本运算符号使用;
3、组合逻辑复制assign语句、时序逻辑always块的写法;
 Verilog Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
`timescale 1ms/1ps
module  module_ex(
    input   wire            rst_n,
    input   wire            Clk_a,      //模块的输入必须是wire类型的,接口使用逗号结束
    //input   wire        Data_i,       //没有声明位宽的信号,默认为1bit位宽
    input   wire    [7:0  Data_i,     //位宽声明用[],高低位,左端是MSB,右端是LSB,用":"分开

    output  wire            Data_oa,    //模块声明时,输出变量可以是wire类型,也可以是reg类型
    output  wire            Data_ob     //最后一个接口不需要加逗号结束
); //模块名最好和文件名一致
//比对符号: 两个变量的对比符号==,返回真/假;<;>;<=;>=;!=;

//wire变量的赋值
//wire变量必须用“=”即阻塞赋值语句,赋值关键字是assign
//组合逻辑实现 当Data_i等于1时立即给Data_oa赋值1,否则等于0
//wire变量赋值语句,连续赋值语句
//assign Data_oa Data_i;
//assign Data_oa (Data_i == 1'b1); //(用==号实现)4'b0001:4bit位宽表示的2进制的数值1;4'h1:4bit十六进制的数值1;4'd1:4bit表示的十进制的数值1
//assign Data_ob 1'b0;

//若data_i大于等于10,Data_oa等于1;若data_i小于10,Data_oa等于0;
assign Data_oa (Data_i >= 8’d10);
assign Data_oa (Data_i >= 8’d10) 1'b1 1'b0; //三目运算符  ()?<>:<>;可理解为一个选择器

//时序逻辑 关键字always 沿触发关键字上升沿触发posedge 下降沿触发negedge
//时序逻辑总是用 <= 非阻塞赋值语句
reg [7:0  reg_a;
//总是在clk_a上升沿位置触发下面逻辑; 异步复位; 敏感列表里的复位信号,在内部always块中一定要使用
always @(posedge Clk_a or negedge rst_n) 
begin
    if(rst_n == 0)
        reg_a <= 8'd0;
    else
        reg_a <= Data_i;
end

    
assign Data_oa reg_a;


endmodule


design目录下
1、模块接口声明,模块例化方法;
2、按位或、按位与使用方法。
Verilog Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
module ex_cnt(
    input   wire            sclk,
    input   wire            rst_n,
    
    output  wire    [7:0  cnt_w  

);
//--------------------------------------------------------------------
//*推荐的模块接口和内部变量声明方法:
//*1、最好使用2001版Verilog语法的接口声明方式,而非95版。
//*2、要在变量使用前对变量进行定义声明,否则会编译报错。具体变量是在模块接口声明之后的区域进行定义(看起来整齐),还是在首次使用变量的always块或assign语句前进行声明(逻辑清晰适用于代码量大的工程,个人推荐)因人而异。
//--------------------------------------------------------------------

//在接口定义部分,可以将输入输出接口都定义为wire类型变量,在需要输出的时候,使用assign语句将reg类型变量赋值给wire类型的输出变量。也就是将寄存器的Q端连接在了输出端口上
//reg类型变量才能在always块内赋值;wire变量不行
reg     [7:0  cnt;
reg             ctrl_flag;

assign cnt_w cnt;

//异步复位 altera器件最好使用异步复位
always @(posedge sclk or negedge rst_n) begin 
    if(rst_n == 1'b0)
        cnt <= 8'd0;
    else if(((ctrl_flag == 1'b0) && (cnt != 8'd16)) || (cnt == 8'd0))
        cnt <= cnt 1'b1;
    else if(((ctrl_flag == 1'b1) && (cnt != 8'd0)) || (cnt == 8'd16))
        cnt <= cnt 1'b1;  
end 

//按位或: |8'b00010001 bit[0]与bit[1]相或(“||”的结果是0/1),结果与bit[2]相或,结果与bit[3]相或...结果与bit[7]相或,得到最终结果为1
//一串数据中,只要有bit位为1,最终结果就是1,否则为0;
//按位或可以有1/2个操作数:|8'b00010001=1; 8'b11110000|8'b00001111=8'b11111111;
//按位与: &8'b00010001 bit[0]与bit[1]相与(“&&”的结果是0/1),结果与bit[2]相与,结果与bit[3]相与...结果与bit[7]相与,得到最终结果为0
//一串数据中,只要有bit位为0,最终结果就是0,否则为1;
//按位与可以有1/2个操作数:&8'b00010001=0; 8'b11110000&8'b00001111=8'b0000000;

//逻辑或“||” 
//逻辑与"&&"

always (posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        ctrl_flag <= 0;
    else if(cnt == 8'd0) //((!cnt) == 1'b0)
        ctrl_flag <= 1'b0;
    else if(cnt == 8'd16) //((&cnt) == 1'b1) //255:默认使用32bit,8'd255:使用8bit
        ctrl_flag <= 1'b1;
        
        
////同步复位 xilinx器件最好使用同步复位
//always @(posedge sclk) begin
//    if(rst_n == 1'b0)
//        cnt <= 8'd0;
//    else
//        cnt <= cnt 1'b1;
//end 



endmodule


design目录下top.v
模块接口例化方法 
Verilog Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
module top(
    input   wire            sclk_i,
    input   wire            rst_n_i,
    
    output  wire    [7:0  cnt_i
);

//模块例化方法:模块例化就是将两个模块的接口相连接
//模块名    例化名<自定义>  
//(接口连接表); //详情如下:
//(
//    .sclk(sclk_i), //.连接模块例化内部信号,sclk是ex_cnt模块内部信号;()内是例化模块外部信号,sclk_i是ex_cnt模块外部信号即top模块内的信号
//    .rst_n(rst_n_i),
//    .cnt_w(cnt_i)
//);

//接口例化可连接wire类型变量,也可连接reg类型变量
ex_cnt ex_cnt_inst
(
    .sclk           (sclk_i),
    .rst_n          (rst_n_i),
    .cnt_w          (cnt_i)
);

endmodule

sim目录下tb_top.v
1、仿真模块搭建方法
2、initial语句使用 
Verilog Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//仿真的时候会使用时钟,需要知道时钟周期,因此需要在模块最开始声明仿真的时间单位和时间精度
//第1个1ns表示时间单位,意思是下面的所有仿真是以1ns为基准单位;第2个1ns是时间精度,意思最小时间分辨率是1ns,也可使用100ps即0.1ns
//`timescale 1ns/1ns 
`timescale 1ns/100ps

//"#"在不可综合模块中使用,表示延时时间
//#1.01 //错误使用,因为时间精度最小为100ps=0.1ns
//testbench的顶层可以有输入输出,也可以没有;激励信号可能就是在这里产生。
module tb_top(); //此处的“;”不要丢了!!!
reg             sclk;
reg             rst_n;
wire    [7:0  cnt; //这里的cnt需定义为wire类型

//initial语句是上电完成的操作
//initial块语句内只能对reg变量赋值,最好只用于仿真语句
initial begin //initial语句可综合,但一般不用于综合
    sclk 0;
    rst_n 0;
    #100;
    rst_n 1;
end 

always #10 sclk ~sclk;

top top_inst
(
    .sclk_i     (sclk),
    .rst_n_i    (rst_n), 
    .cnt_i      (cnt)
);

endmodule


sim目录下run.do文件
1、常用modelsim使用流程
2、run.do脚本常用语句 
Perl Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#-----------------------------------------
#modelsim GUI仿真流程
#--打开modelsim软件,新建一个工程文件夹,建立modelsim仿真工程
#--在用户窗口界面加入需要仿真的所有代码和库文件
#--编译所有文件
#--选择testbench顶层文件启动仿真
#--选择所要观察的目标信号,并将其加入到波形观察窗口,如需要更改bus显示和数据格式则需进一步设置。例如,进制转换,模拟波形切换
#--设置仿真运行时间,启动仿真波形绘制
#--如果下一次启动有其他文件更改或删除,需要重复以上步骤的部分或者全部
#
#modelsim do文件的自动化仿真
#--建立库
#vlib:创建库到物理目录即modelsim工程所在目录下,默认库的名字为work,vlib work
#--映射库到物理目录
#vmap:映射逻辑库名称,将逻辑库名称映射到物理库路径。vmap work_logic work_phy
#--编译源代码
#vlog:编译Verilog源代码,库名缺省编译到本地库,文件按顺序编译。语法格式vlog -work.v.v
#--启动仿真器
#vsim -voptargs=+acc work.tb_top
#--执行仿真
#run 10us
#-----------------------------------------

#退出前一次仿真
quit -sim                               

#vlib是创建库语句。将所有的.v文件编译到一个库里面,默认使用名为work的库。vlib work意思是创建一个名为work的库
vlib work                               

#vlog是编译语句。编译.v文件 “./”是在Modelsim工程所在的文件夹下,找到tb_top.v文件进行编译
vlog ./tb_top.v                         
#“../”是在当前Modelsim工程所在的目录下,向上翻一层到design目录,对此文件夹下的所有.v文件进行编译
vlog ./../design/*.v                    

#vsim是启动仿真语句。“-voptargs=+acc”参数优化方式死记,启动work库下面的tb_top进行仿真
vsim -voptargs=+acc work.tb_top         

#add wave是添加波形语句。添加tb_top模块下的例化的top_inst模块内的ex_cnt_inst模块内的所有信号
add wave tb_top/top_inst/ex_cnt_inst/*  

#仿真运行长时间
run 10us                                

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有