二、Verilog基础语法学习

一、Verilog基础知识

1、Verilog的逻辑值

我们先看下逻辑电路中有四种值,即四种状态:

  • 逻辑 0:表示低电平,也就是对应我们电路的GND;
  • 逻辑 1:表示高电平,也就是对应我们电路的VCC;
  • 逻辑 X:表示未知,有可能是高电平,也有可能是低电平;
  • 逻辑 Z:表示高阻态,外部没有激励信号是一个悬空状态。
     

2、Verilog的标识符

        标识符(identifier)用于定义模块名端口名信号名等。 Verilog的标识符可以是任意一组字母、数字、 $和_(下划线)符号的组合,但标识符的第一个字符必须是字母或者下划线。另外,标识符是区分大小写的。不建议大小写混合使用,普通内部信号建议全部小写, 参数定义建议大写
 

3、Verilog的数字进制格式

 二进制表示如下: 4’b0101表示4位二进制数字0101;
十进制表示如下: 4’d2表示4位十进制数字2(二进制0010) ;
十六进制表示如下: 4’ha表示4位十六进制数字a(二进制1010) 。
当代码中没有指定数字的位宽与进制时,默认为32位的十进制。

4、Verilog的数据类型

寄存器类型(reg、 integer、 real)

        寄存器类型表示一个抽象的数据存储单元,它只能在always语句和initial语句中被赋值,如果该过程语句描述的是时序逻辑,即always语句带有时钟信号,则该寄存器变量对应为寄存器;如果该过程语句描述的是组合逻辑, 即always语句不带有时钟信号,则该寄存器变量对应为硬件连线;

reg [31:0] delay_cnt; //延时计数器
reg key_flag ; //按键标志

线网类型(tri、wire)

        线网表示Verilog结构化元件间的物理连线。它的值由驱动元件的值决定,例如连续赋值
或门的输出。

wire data_en; //数据使能信号
wire [7:0] data ; //数据

参数类型(parameter)

        参数其实就是一个常量,常被用于定义状态机的状态、数据位宽和延迟大小等,由于它可以在编译时修改参数的值,因此它又常被用于一些参数可调的模块中,使用户在实例化模块时,可以根据需要配置参数。参数的定义是局部的,只在当前模块中有效。

parameter DATA_WIDTH = 8; //数据位宽为8位

5、Verilog的运算符

算术运算符

关系运算符

 逻辑运算符

条件运算符

 位运算符

移位运算符

拼接运算符

6、关键字
 

 二、Verilog程序框架

module led(
    input sys_clk ,                 // 系统时钟
    input sys_rst_n,                // 系统复位,低电平有效
    output reg [3:0] led            // 4位LED灯
);

parameter define
parameter WIDTH = 25 ;              // 位宽
parameter COUNT_MAX = 25_000_000;   // 板载50M时钟=20ns, 0.5s/20ns=25000000,需要25bit

 //reg define
 reg [WIDTH-1:0] counter ;
 reg [1:0] led_ctrl_cnt;

 //wire define
 wire counter_en ;

 //***********************************************************************************
 //** main code
 //***********************************************************************************
 //计数到最大值时产生高电平使能信号
 assign counter_en = (counter == (COUNT_MAX - 1'b1)) ? 1'b1 : 1'b0;

 //用于产生0.5秒使能信号的计数器
 always @(posedge sys_clk or negedge sys_rst_n) begin
    if (sys_rst_n == 1'b0)
        counter <= 1'b0;
    else if (counter_en)
        counter <= 1'b0;
    else
        counter <= counter + 1'b1;
end

//led流水控制计数器
always @(posedge sys_clk or negedge sys_rst_n) begin
    if (sys_rst_n == 1'b0)
        led_ctrl_cnt <= 2'b0;
    else if (counter_en)
        led_ctrl_cnt <= led_ctrl_cnt + 2'b1;
end

//通过控制IO口的高低电平实现发光二极管的亮灭
always @(posedge sys_clk or negedge sys_rst_n) begin
    if (sys_rst_n == 1'b0)
        led <= 4'b0;
    else begin
        case (led_ctrl_cnt)
            2'd0 : led <= 4'b0001;
            2'd1 : led <= 4'b0010;
            2'd2 : led <= 4'b0100;
            2'd3 : led <= 4'b1000;
        default : ;
        endcase
    end
end
endmodule

三、Verilog高级知识点
 

1、顺序块语句 

1.1、阻塞赋值( Blocking)

也就是说always块内的语句是一种顺序关系,这里和C语言很类似。 符号“ =”用于阻塞的赋值(如:b = a;) ,阻塞赋值“ =”在begin和end之间的语句是顺序执行,属于串行语句。

 1.2、非阻塞赋值( Non-Blocking)

        符号“ <=”用于非阻塞赋值(如:b <= a;), 非阻塞赋值是由时钟节拍决定,在时钟上升到来时,执行赋值语句右边,然后将begin-end之间的所有赋值语句同时赋值到赋值语句的左边,注意:是begin—end之间的所有语句,一起执行,且一个时钟只执行一次, 属于并行执行语句。 这个是和C语言最大的一个差异点,大家要逐步理解并行执行的概念。

2、分支语句

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello Jason

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值