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

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

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

  • 减少重复代码

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

相关推荐
dMing`44 分钟前
基于FPGA的简易数据采集系统
fpga开发·fpga·adc·dac
LCMICRO-133108477464 小时前
长芯微LD9689完全P2P替代AD9689,是一款双通道、14位、2.0 GSPS/2.6 GSPS模数转换器(ADC)
网络·单片机·嵌入式硬件·网络协议·fpga开发·硬件工程·高速adc
萨文 摩尔杰15 小时前
GPS原理学习
学习·fpga开发
Huangichin15 小时前
跟着Gemini学System Verilog
fpga开发
LCMICRO-1331084774618 小时前
长芯微LDC90810完全P2P替代ADC128D818,是一款八通道系统监控器,专为监控复杂系统状态而设计。
stm32·单片机·嵌入式硬件·fpga开发·硬件工程·模数转换芯片adc
s090713620 小时前
保姆级教程十二:USB摄像头接入!ZYNQ+OpenCV+FPGA硬件加速图像处理实战(视觉终极篇)
图像处理·opencv·fpga开发·zynq·硬件加速
CoderIsArt1 天前
FPGA-based 量子电路仿真
fpga开发
碎碎思1 天前
升级版流水灯:用FPGA控制上千颗RGB LED
fpga开发
FPGA-ADDA1 天前
第二篇:Xilinx 7系列FPGA详解——从Spartan到Virtex
fpga开发·fpga·sdr·rfsoc
逐步前行2 天前
STM32_SysTick_寄存器操作
stm32·嵌入式硬件·fpga开发