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是一个强大的元编程工具,用于:

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

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

  • 减少重复代码

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

相关推荐
s090713616 小时前
【FPGA实战】基于Verilog的MCP2515 CAN控制器SPI驱动详解 | 附完整代码
fpga开发·硬件设计·can通信·mcp2515
szxinmai主板定制专家16 小时前
基于 ARM+FPGA 数据机床实时工业控制设计--以雕刻机为例
arm开发·人工智能·嵌入式硬件·fpga开发
XMAIPC_Robot17 小时前
基于RK3588 ARM+FPGA电火花数控机床控制系统设计,兼顾ethercat软硬件实时
linux·arm开发·人工智能·嵌入式硬件·fpga开发
XMAIPC_Robot17 小时前
基于 ARM+FPGA 数据机床控制系统设计--以雕刻机为例
arm开发·fpga开发
GateWorld17 小时前
LCD显示技术完全指南:原理·制造·驱动·FPGA实现之点屏一
fpga开发·lcd显示·fpga点亮屏幕·minilvds·fpga点屏
風清掦1 天前
【STM32学习笔记-14】WDG看门狗 - 14.2 WWDG窗口看门狗
笔记·stm32·单片机·嵌入式硬件·学习·fpga开发
尤老师FPGA1 天前
HDMI数据的接收发送实验(十二)
fpga开发
坏孩子的诺亚方舟2 天前
FPGA神经网络数学基础0
人工智能·神经网络·线性代数·fpga开发
熠速2 天前
PolarBox高性能实时仿真系统
arm开发·fpga开发·嵌入式实时数据库·硬件在环半实物仿真
南檐巷上学2 天前
基于Zynq-7020的带有正弦波发生器的8051软核设计
单片机·嵌入式硬件·fpga开发·fpga