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

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

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

  • 减少重复代码

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

相关推荐
国科安芯10 小时前
ASL706S:让 MCU 不再“失忆跑飞“的守护芯片
分布式·单片机·嵌入式硬件·安全·fpga开发·架构
明德扬12 小时前
多路MIPI摄像头如何同步聚合?一文看懂FPGA视频汇聚方案
fpga开发·音视频
松小白song17 小时前
FPGA开发三大铁律:位宽、逻辑与连接,为何仿真通过上板却挂?
fpga开发
FPGA小徐1 天前
FPGA 时钟频率计算与单位换算
fpga开发
h×31 天前
FPGA视频4分屏项目 - 系统架构详细讲解
fpga开发·音视频
秋91 天前
硬件工程师全岗位薪资全景解析(2026版):IC设计·嵌入式·板级硬件·FPGA·晶圆制造
fpga开发·制造
博览鸿蒙1 天前
FPGA 工程师到底有哪些方向?每个岗位都在干什么?一篇给你讲清楚
fpga开发
xiaojiaohuazi2 天前
国产安陆EG4S20 FPGA实现千兆以太网TCP/IP:AD7606C 8通道1 MSPS采集、SDRAM缓存与Python上位机
tcp/ip·缓存·fpga开发
尤老师FPGA2 天前
HDMI数据的接收发送实验(二十四)
fpga开发
MDYFPGA2 天前
明德扬 Kintex-7 FPGA核心板及多接口扩展底板介绍
fpga开发·fpga