当前位置: 首页 > ops >正文

FPGA学习笔记——Verilog中可综合和不可综合语句

目录

一、 绝对可综合的语句(RTL核心)

1. 模块声明 (Module Declaration)

2. 端口定义 (Input, Output, Inout)

3. wire和reg变量声明

4. 参数和局部参数 (Parameter, Localparam)

5. 赋值语句 (Assignments)

6. 过程块 (Always Blocks)

7. 条件语句 (If-Else)

8. 多路选择语句 (Case)

9. 循环语句 (For Loops)

10. 算术和逻辑运算符

11. 位选择和部分选择

12. 模块实例化 (Module Instantiation)

13. Generate 语句

二、 通常(或绝对)不可综合的语句

1.初始语句 (initial):

2.时间延迟 (#delay):

3.仿真系统任务 (System Tasks):

4.实时事件触发器 (event):

5.wait 语句:

6.while, repeat, forever 循环(非固定边界):

7.force 和 release:

三、 需要谨慎使用或工具相关的语句

可综合的意思是,这些代码能够被EDA工具(如Synopsys Design Compiler, Vivado, Quartus等)转换成确定的数字电路网表(由基本门、触发器、宏单元等组成)。其核心是描述硬件结构寄存器传输级(RTL)行为


一、 绝对可综合的语句(RTL核心)

1. 模块声明 (Module Declaration)

module module_name (input  clk,       // 输入端口input  rst_n,input  [7:0] data_in,output reg [7:0] data_out // 输出端口
);
// ... 逻辑代码 ...
endmodule

2. 端口定义 (Input, Output, Inout)

inputoutputinout 关键字用于定义模块的端口方向。

3. wire和reg变量声明

wire表示电路中的物理连线,用于连接元件。通常由assign语句或模块实例化驱动。

reg:不一定代表触发器! 它表示一个保持值的存储体。在always块中赋值的变量必须声明为reg类型,它可能被综合成触发器(时序逻辑)或组合逻辑(如多路选择器)。

4. 参数和局部参数 (Parameter, Localparam)

parameter   WIDTH = 8;
localparam STATE_IDLE = 2'b00;

5. 赋值语句 (Assignments)

连续赋值 (Continuous Assignment assign): 用于描述组合逻辑,等式右端操作数的任何变化都会立即导致左端更新。

wire a, b, c;
assign c = a & b; // 综合为一个与门

过程赋值 (Procedural Assignment): 在alwaysinitial块中使用(但initial通常不可综合)。

阻塞赋值 (=):顺序执行,用于组合逻辑建模。非阻塞赋值 (<=):并行执行,用于时序逻辑建模(触发器)。

6. 过程块 (Always Blocks)

时序逻辑 (Flip-Flops):使用时钟(clk)或时钟+复位(rst)的边沿作为敏感列表。

always @(posedge clk or negedge rst_n) beginif (!rst_n) begin// 复位逻辑:异步复位data_out <= 8‘b0;end else begin// 时钟上升沿触发的逻辑data_out <= data_in; // 一个8位寄存器end
end

组合逻辑 (Combinational Logic):使用电平敏感的通配符*或列出所有输入信号。

always @(*) begin // 或 always @(a, b, sel)case (sel)2‘b00: y = a;2’b01: y = b;default: y = 1‘b0;endcase
end
// 这会综合为一个多路选择器(MUX)

注意描述组合逻辑的always块中,必须确保所有条件下每个输出都有赋值,否则会隐含锁存器(Latch)!可以使用default分支或赋默认值来避免。

7. 条件语句 (If-Else)

通常被综合为多路选择器(MUX)或优先级编码逻辑。

if (enable) beginout = in1;
end else beginout = in2;
end

8. 多路选择语句 (Case)

通常被综合为一个多路选择器。比同等功能的if-else结构更并行,面积可能更优。

case (opcode)3‘b000: result = a + b;3’b001: result = a - b;3‘b010: result = a & b;default: result = 8’b0; // 防止产生锁存器!
endcase

9. 循环语句 (For Loops)

可综合,但有严格条件:循环次数必须在编译时是固定的(即循环边界是常量)。
它会被综合工具展开(Unroll),生成多份硬件电路。

// 可综合:循环8次,被展开为8个相同的逻辑单元
integer i;
always @(*) beginfor (i = 0; i < 8; i = i + 1) beginparity[i] = ^data[((i+1)*8)-1 : i*8]; // 计算每个字节的奇偶校验位end
end

不可综合示例:循环次数在运行时才确定的for循环。

10. 算术和逻辑运算符

+-*&|^~<<>> 等都可综合。

注意:*(乘法)和 /(除法)会综合成乘法器/除法器,可能很耗资源。对于大位宽操作,需要谨慎。

<< n(逻辑左移n位)通常综合为连线的重排,不消耗逻辑资源。

>> n(逻辑右移n位)同上。

11. 位选择和部分选择

wire [31:0] bus;
wire [7:0] byte = bus[15:8]; // 部分选择
wire bit = bus[0];           // 位选择

12. 模块实例化 (Module Instantiation)

这是层次化设计的基础,用于调用其他模块或供应商提供的IP核(如PLL, RAM等)。

and_gate u_and_gate (.a (input_a), // 端口连接.b (input_b),.c (output_c)
);

13. Generate 语句

用于生成重复的硬件结构或有条件地实例化代码,在编译时确定。

genvar i;
generatefor (i=0; i<4; i=i+1) begin : gen_loopmy_module u_mod (.in(a[i]), .out(b[i]));end
endgenerate

二、 通常(或绝对)不可综合的语句

1.初始语句 (initial):

用于testbench初始化信号,生成激励。

除FPGA上用于初始化reg变量的少数情况外(如reg var = 0;),绝大多数initial块不能被ASIC综合工具接受。

// 在模块中尝试初始化寄存器(ASIC综合通常不支持)
reg [7:0] counter = 8'b0; // 这种写法在FPGA综合中可能被接受,用于上电初始化initial begin// 这种在initial块中对信号进行赋值的写法绝对不可综合state = IDLE;data_bus = 32'hFFFF_FFFF;enable = 0;
end

2.时间延迟 (#delay):

如 #5 a = b;。RTL设计是功能描述,不关心绝对延时。

initial beginclk = 0;#10;        // 延迟10个时间单位rst_n = 1;  // 10个时间单位后,将复位信号拉高#5 data = 8'hFF; // 再延迟5个时间单位后赋值
end

3.仿真系统任务 (System Tasks):

$display$monitor$finish$stop$random等,用于仿真调试和测试。

always @(posedge clk) beginif (data_valid) begin$display("At time %t, data = %h", $time, data_out); // 打印信息$monitor("Signal changed: a = %b, b = %b", a, b);   // 监控信号变化data_array[addr] = $random;                         // 使用随机数end
endinitial begin#1000 $finish; // 仿真1000个单位后结束
end

4.实时事件触发器 (event):

用于进程间同步,无直接硬件对应。

event start_operation; // 声明一个事件initial begin-> start_operation; // 触发事件
endalways @(start_operation) begin // 等待事件发生// ... 执行操作
end

5.wait 语句:

基于电平的无限等待,综合工具无法处理。

// 等待“start”信号变为高电平
always @(posedge clk) beginwait (start == 1'b1); // 等待start变高// ... 后续操作
end

6.whilerepeatforever 循环(非固定边界):

综合工具无法确定其运行时间和硬件规模。

// 不确定循环次数,直到满足条件
always @(posedge clk) beginwhile (data != 8‘hAA) begin // 循环次数在编译时未知data <= data + 1;end
end// 无限循环
initial beginforever begin // 永远运行,没有边界#5 clk = ~clk; // 常用于testbench生成时钟end
end

7.force 和 release:

仿真中的强制信号操作。

initial begin#100;force top.dut.counter = 8‘d255; // 强制将层次化路径中的某个信号拉高#200;release top.dut.counter;        // 释放强制
end

三、 需要谨慎使用或工具相关的语句

  1. integer 和 real:

    • integer 通常可综合,它只是一个32位的寄存器。

    • real(浮点数)基本不可综合,除非使用特殊的IP核。

  2. 用户自定义原语 (UDP):

    • 理论上可综合,但支持度因工具而异,现在基本被模块替代,不推荐使用。

  3. tri (三态线):

    • 可综合,但通常只用于顶层接口(连接片外总线)或FPGA内部的一些特殊资源(如IOB)。芯片内部绝大多数是单向信号。


以上就是Verilog中可综合和不可综合语句。(如果有错误,还请大家指出来,谢谢!)

http://www.xdnf.cn/news/18853.html

相关文章:

  • 2025软件测试面试八股文(完整版)
  • 【科研绘图系列】R语言在海洋生态学数据可视化中的应用:以浮游植物叶绿素和初级生产力为例
  • SFTP服务器可以通过同一个登录到SFTP服务器的账号密码连接上控制台吗
  • “上门经济”的胜利:深度解析家政O2O如何用“用户体验”重塑传统行业
  • 【小白笔记】网速
  • 支持向量机(SVM)学习总结
  • 德克西尔氢气探测器:工业安全守护核心
  • 从高层 PyTorch 到中层 CUDA Kernel 到底层硬件 Tensor Core
  • 深度解析BiTGAN:基于双向Transformer生成对抗网络的长期人体动作预测
  • Linux 把启动脚本制作成系统服务(通过 systemctl start xxx 启动)
  • JHipster-从零开始学习指南
  • Autodesk Maya 2026.2 全新功能详解:MotionMaker AI 动画、LookdevX 材质增强、USD 工作流优化
  • 实现自己的AI视频监控系统-第二章-AI分析模块3(核心)
  • Python常见设计模式3: 行为型模式
  • OpenCV4.X库功能全解---个人笔记
  • 【解锁Photonics for AI:系统学习光学神经网络与超表面设计,成就下一代光芯片工程师】
  • TCP并发服务器构建
  • Linux 离线环境下 Anaconda3 与核心机器学习库(scikit-learn/OpenCV/PyTorch)安装配置指南
  • React内网开发代理配置详解
  • 安装了TortoiseSVN但是在idea的subversion里面找不到svn.exe
  • LangChain4J-(3)-模型参数配置
  • 力扣 30 天 JavaScript 挑战 第41天 (第十二题)对异步操作,promise,async/await有了更深理解
  • 部署k8s-efk日志收集服务(小白的“升级打怪”成长之路)
  • 在 Ubuntu 系统上安装 MySQL
  • Spring Cloud 高频面试题详解(含代码示例与深度解析)
  • 浏览器与计算机网络
  • 计算机网络:服务器处理多客户端(并发服务器)
  • 【Redis#8】Redis 数据结构 -- Zset 类型
  • Java 大视界 -- Java 大数据机器学习模型在电商推荐系统冷启动问题解决与推荐效果提升中的应用(403)
  • Containerd 安装与配置指南