verilog基本语法

想深耕嵌入式?这个专辑值得收藏

MCU、FPGA、工控、传感器一站式学习,实战项目直接抄

VERILOG语法

总结了最为基本的语法,忘记的时候简单查阅一下。

一、逻辑值

在这里插入图片描述

二、可综合/不可综合

□ Verilog 描述分为两大类:

➤ 可综合描述

➤ 不可综合描述

□ 可综合描述:综合 tool 能够把 Verilog 描述转化(Compile)为基本的数字电路底层 cell(与或非 gate,寄存器等)的描述。 assign y = a & b;

□ 不可综合描述:综合 tool 不能把 Verilog 描述转化为基本的数字电路底层 cell 的描述。 $display(“Hello word.\n”);

三、基本语法

1. 模块

模块是Verilog设计的基本单位,用于定义电路的结构和功能。一个模块包含端口列表、信号声明和行为描述

module module_name (input_1, output_1);
  input input_1;  // 输入端口声明
  output output_1; // 输出端口声明

  // 信号声明
  wire w1;
  reg r1;

  // 逻辑描述
  assign w1 = input_1 & r1;  // 连续赋值语句

  always @(posedge clk) begin
    r1 = input_1;
  end

endmodule

2. 数据类型

  • wire:用于连接模块中的信号或输入/输出端口,类似于电路中的导线。
  • reg:用于存储值,通常在时序逻辑块中使用。
  • integer:用于声明整数类型变量。
  • parameter:用于定义常量,在设计中使用不可变的数值。

输入端口(input):只能是wire,不能直接定义为reg

输出端口(output):可以是wirereg,取决于信号驱动方式。

3. 端口定义

  • input:输入信号端口。
  • output:输出信号端口。
  • inout:双向信号端口。

4. 赋值语句

连续赋值语句(assign):用于组合逻辑描述,使用assign语句将表达式的值分配给wire信号。

assign y = a & b;

过程赋值语句(always):用于时序逻辑描述,包含在always块中,一般用来描述寄存器或状态机的行为。

always @(posedge clk) begin
  r1 = a | b;
end

5. 关键字

  • moduleendmodule:定义模块的开始和结束。
  • always:用于定义时序逻辑块。
  • initial:用于一次性初始化信号,一般用于仿真。
  • assign:用于定义组合逻辑,进行连续赋值。

6. 逻辑操作符

  • 与(&)或(|)非(~)、**异或(^)**等。
  • 支持逻辑操作符以及位操作符,用于描述电路行为。

7. 控制语句

if-else:条件判断。

always @(posedge clk) begin
  if (a == 1'b1) begin
    y = 1;
  end else begin
    y = 0;
  end
end

case:多分支选择语句,用于状态机或复杂逻辑

always @(posedge clk) begin
  case (state)
    2'b00: y = 1;
    2'b01: y = 0;
    default: y = 1'bz;  // high impedance
  endcase
end

8. 仿真相关

$display:用于在仿真时输出信息。

$display("Simulation output: value = %d", value);

$monitor:监视信号的变化,在变化时输出信息。

initial:用于初始化信号值,在仿真中用来设置初始条件。

9. 时序控制

  • posedgenegedge:表示时钟信号的上升沿和下降沿,用于时序逻辑的触发。
always @(posedge clk) begin
  // 在时钟上升沿执行
end

10. 块语句

  • beginend:用于包含多条语句。
  • forkjoin:用于并行执行多条语句(主要用于仿真)。

四、逻辑运算符

1. 逻辑运算符

逻辑运算符用于对布尔值进行逻辑操作,其结果也是布尔值(01)。

  • !(逻辑非,NOT)
    • 用途:取反
    • 示例!a,如果a1,结果为0,如果a0,结果为1
  • &&(逻辑与,AND)
    • 用途:逻辑与,只有当所有操作数为1时,结果为1
    • 示例a && b,如果ab都为1,结果为1,否则结果为0
  • ||(逻辑或,OR)
    • 用途:逻辑或,只要有一个操作数为1,结果为1
    • 示例a || b,如果ab中有一个为1,结果为1,否则结果为0

2. 按位运算符

按位运算符用于对信号的每个位进行运算,常用于操作位向量。

  • ~(按位非,NOT)
    • 用途:对每一位取反
    • 示例~a,如果a4'b1010,结果为4'b0101
  • &(按位与,AND)
    • 用途:对每一位进行与运算
    • 示例a & b,如果a4'b1100b4'b1010,结果为4'b1000
  • |(按位或,OR)
    • 用途:对每一位进行或运算
    • 示例a | b,如果a4'b1100b4'b1010,结果为4'b1110
  • ^(按位异或,XOR)
    • 用途:对每一位进行异或运算
    • 示例a ^ b,如果a4'b1100b4'b1010,结果为4'b0110
  • ~^^~(按位同或,XNOR)
    • 用途:对每一位进行同或运算
    • 示例a ~^ b,如果a4'b1100b4'b1010,结果为4'b1001

3. 关系运算符

关系运算符用于比较两个操作数,返回布尔值1(true)或0(false)。

  • ==:等于
  • !=:不等于
  • <:小于
  • <=:小于等于
  • >:大于
  • >=:大于等于

4. 逻辑运算与按位运算的区别

  • 逻辑运算符(如&&||)用于布尔逻辑运算,操作数通常是标量布尔值(01)。
    • 运算结果是单个布尔值(01)。
    • 逻辑运算有短路特性,例如在a && b中,如果a0,则不会计算b
  • 按位运算符(如&|^)用于逐位地对多位信号进行运算。
    • 操作的结果是一个多位信号,每一位独立计算。
    • 按位运算常用于处理向量(如4位或8位的数据)。
module logic_example();
    reg a, b;
    reg [3:0] x, y;
    reg z1, z2;

    initial begin
        // 逻辑运算符
        a = 1;
        b = 0;
        z1 = a && b; // z1 = 0
        z2 = a || b; // z2 = 1

        // 按位运算符
        x = 4'b1100;
        y = 4'b1010;
        z1 = &x;     // 按位与的归约,z1 = 1 & 1 & 0 & 0 = 0
        z2 = |y;     // 按位或的归约,z2 = 1 | 0 | 1 | 0 = 1

        $display("Logical AND: %b", z1);
        $display("Logical OR: %b", z2);
        $display("Bitwise AND: %b", x & y);
        $display("Bitwise OR: %b", x | y);
    end
endmodule

总结:

逻辑运算符!&&||,用于逻辑操作,结果为布尔值。

按位运算符~&|^~^,用于位向量的逐位运算。

逻辑运算符常用于条件判断,而按位运算符通常用于信号处理和数据操作。

想深耕嵌入式?这个专辑值得收藏

MCU、FPGA、工控、传感器一站式学习,实战项目直接抄

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值