verilog的generate

generate是 Verilog/SystemVerilog 中的生成语句,用于在编译时根据参数条件生成重复的硬件结构或选择性地包含代码模块。

主要用途:

1. 生成重复结构​ - 类似 for 循环

复制代码
// 生成 8 个 D 触发器
genvar i;
generate
  for (i = 0; i < 8; i = i + 1) begin : gen_dff
    d_ff dff_inst (
      .clk(clk),
      .rst(rst),
      .d(data_in[i]),
      .q(data_out[i])
    );
  end
endgenerate

2. 条件生成​ - 类似 if-else

复制代码
parameter WIDTH = 8;
generate
  if (WIDTH > 16) begin : wide_bus
    // 宽总线逻辑
    adder_32bit adder_inst (...);
  end
  else if (WIDTH > 8) begin : medium_bus
    // 中等宽度逻辑
    adder_16bit adder_inst (...);
  end
  else begin : narrow_bus
    // 窄总线逻辑
    adder_8bit adder_inst (...);
  end
endgenerate

3. case 生成

复制代码
parameter IMPLEMENTATION = "FAST";
generate
  case (IMPLEMENTATION)
    "FAST" : begin
      fast_multiplier mult_inst (...);
    end
    "SMALL" : begin
      small_multiplier mult_inst (...);
    end
    default : begin
      generic_multiplier mult_inst (...);
    end
  endcase
endgenerate

重要特点:

1. genvar 类型变量

复制代码
genvar i;  // 专门用于 generate 的变量

2. 块标签必须要有

复制代码
generate
  for (i = 0; i < 4; i++) begin : my_block  // 这个标签必须有
    // 实例化代码
  end
endgenerate

3. 编译时确定

generate 语句在编译时展开,不是运行时逻辑。

实用示例:

例1:可配置宽度的移位寄存器

复制代码
module shift_register #(
  parameter WIDTH = 8,
  parameter DEPTH = 4
)(
  input clk, rst,
  input [WIDTH-1:0] data_in,
  output [WIDTH-1:0] data_out
);
  
  wire [WIDTH-1:0] stage [0:DEPTH];
  assign stage[0] = data_in;
  assign data_out = stage[DEPTH];
  
  genvar i;
  generate
    for (i = 0; i < DEPTH; i = i + 1) begin : gen_stage
      d_ff #(WIDTH) dff_inst (
        .clk(clk),
        .rst(rst),
        .d(stage[i]),
        .q(stage[i+1])
      );
    end
  endgenerate
  
endmodule

例2:参数化多路选择器

复制代码
module param_mux #(
  parameter WIDTH = 8,
  parameter NUM_INPUTS = 4
)(
  input [clog2(NUM_INPUTS)-1:0] sel,
  input [WIDTH-1:0] data_in [0:NUM_INPUTS-1],
  output [WIDTH-1:0] data_out
);
  
  generate
    if (NUM_INPUTS == 1) begin : single_input
      assign data_out = data_in[0];
    end
    else begin : multiple_inputs
      assign data_out = data_in[sel];
    end
  endgenerate
  
  // 计算 log2 的函数
  function integer clog2(input integer value);
    // ...
  endfunction
  
endmodule

与普通 for 循环的区别:

特性 generate for 普通 for
执行时间 编译时 运行时
用途 实例化硬件 描述行为
变量类型 genvar integer
可实例化模块 可以 不可以

常见错误:

复制代码
// 错误:在 generate 中使用 reg/integer
genvar i;
generate
  for (i = 0; i < 4; i++) begin
    reg temp;  // 错误!不能在 generate 中声明 reg
  end
endgenerate

// 正确:在 generate 块内实例化模块或 assign
generate
  for (i = 0; i < 4; i++) begin
    assign out[i] = in[i];  // 正确
  end
endgenerate

总结:

generate是一个强大的元编程工具,用于:

  • 创建可重用的参数化设计

  • 根据配置生成不同的硬件结构

  • 减少重复代码

  • 提高代码的可维护性和可配置性

相关推荐
吉他英雄一里16 小时前
zynq入门教程
fpga开发·zynq
XMAIPC_Robot18 小时前
RK3576/RK3588+FPGA+AI数据采集系统:实时性与边缘AI算力兼顾
人工智能·fpga开发·机器人·数据采集·rk3588+fpga·rk3576+fpga
156082072192 天前
JFMRFVU3P5G的bit正常,但烧录mcs程序后加载异常
fpga开发
狂奔蜗牛(bradley)2 天前
把 EtherCAT 初始化从 FPGA 搬到 ARM:命令通道的接口设计与11个坑
arm开发·人工智能·fpga开发·架构
女神下凡3 天前
芯参谋(37):EEPROM_电路设计指南
arm开发·单片机·嵌入式硬件·fpga开发·设计规范
szxinmai主板定制专家4 天前
工业视觉新思路:FPGA图像预处理+RK NPU推理,实现高速缺陷检测
人工智能·嵌入式硬件·fpga开发·rk3576+codesys
FPGA小徐4 天前
【硬件实战】立创 EDA 绘制 TF/SD 卡模块电路|SPI 模式原理图 + 阻抗匹配 + PCB 布局布线全教程
单片机·嵌入式硬件·fpga开发
狂奔蜗牛(bradley)4 天前
EtherCAT DC 分布式时钟同步的 ModelSim 仿真:从帧模板到从站行为建模
人工智能·嵌入式硬件·fpga开发·架构
ALINX技术博客4 天前
8 通道同步采样 ADC!AN706 波形显示实验 【FPGA黑金云课堂】
fpga开发
szxinmai主板定制专家5 天前
RK3568+FPGA+CODESYS异构控制方案:赋能半导体设备与工业自动化升级
人工智能·fpga开发·自动化·rk3576·半导体设备