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

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.dtcms.com/a/352953.html

相关文章:

  • 德克西尔氢气探测器:工业安全守护核心
  • 【Linux】用户与用户组管理
  • 6.8 学习ui组件方法和Element Plus介绍
  • 嵌入式C语言进阶:高效数学运算的艺术与实战
  • Java全栈开发面试实战:从基础到微服务架构的深度解析
  • 革新固态电池失效分析技术:AFM-SEM联用技术助力突破瓶颈
  • Java 大视界 -- Java 大数据机器学习模型在电商推荐系统冷启动问题解决与推荐效果提升中的应用(403)
  • Unity Shader unity文档学习笔记(二十一):几种草体的实现方式(透明度剔除,GPU Instaning, 曲面细分+几何着色器实现)
  • Axios 整理常用形式及涉及的参数
  • Vue3 + Vue Router 实现动态面包屑导航(支持点击跳转)
  • Techub News 与 TOKENPOST 达成战略合作以推动中韩 Web3 资讯互通
  • 有鹿机器人如何用科技与创新模式破解行业难题
  • 「LangChain 学习笔记」LangChain大模型应用开发:模型链(Chains)
  • 外汇中高频 CTA 风控策略回测案例
  • 宝塔面板零基础搭建 WordPress 个人博客与外贸网站 | 新手10分钟上手指南
  • 国内股指期货合约的最小变动价位是多少?
  • 大语言模型的“引擎室”:深入剖析现代计算与算法优化
  • 企业落地版 AutoGen 工程示例:自动化市场分析报告生成系统
  • 代码随想录刷题Day42
  • 【芯片低功耗设计中的UPF:从理论到实践详解】
  • windows 子系统 wsl 命令的用法
  • lvgl(一)
  • Java全栈工程师面试实录:从基础到实战的深度技术探索
  • 集成电路学习:什么是YOLO一次性检测器
  • nginx结合lua做转发,负载均衡
  • 解决VSCode中Cline插件的Git锁文件冲突问题
  • 第三章 UI框架设定 流程逻辑
  • 测试分类(超详解)
  • 网络编程-TCP的并发服务器构建
  • FactoryBean接口作用