verilog generate

news2025/8/3 15:45:26

generate块允许乘以模块实例或执行任何模块的条件实例化。它提供了基于 Verilog 参数构建设计的能力。当需要多次重复相同的操作或模块实例,或者必须根据给定的 Verilog 参数有条件地包含某些代码时,这些语句特别方便。

generate块不能包含端口、参数、声明specparamspecify块。但是,其他模块项目和其他生成块是允许的。所有生成的实例都在module关键字generate和之间进行编码endgenerate

生成的实例化可以有模块、连续赋值alwaysinitial块和用户定义的原语。有两种类型的生成结构——循环和条件。

  • 生成for循环
  • 否则生成
  • 生成案例

生成for循环

半加器将在另一个名为my_design的顶级设计模块中使用for 循环构造实例化N次。必须使用关键字声明循环变量,该关键字告诉工具该变量将在生成块的详细说明期间专门使用。generategenvar

// Design for a half-adder
module ha ( input   a, b,
            output  sum, cout);

  assign sum  = a ^ b;
  assign cout = a & b;
endmodule

// A top level design that contains N instances of half adder
module my_design
	#(parameter N=4)
		(	input [N-1:0] a, b,
			output [N-1:0] sum, cout);

	// Declare a temporary loop variable to be used during
	// generation and won't be available during simulation
	genvar i;

	// Generate for loop to instantiate N times
	generate
		for (i = 0; i < N; i = i + 1) begin
          ha u0 (a[i], b[i], sum[i], cout[i]);
		end
	endgenerate
endmodule

试验台

testbench 参数用于控制设计中半加器实例的数量。当N为 2 时,my_design将有两个半加器实例。

module tb;
	parameter N = 2;
  reg  [N-1:0] a, b;
  wire [N-1:0] sum, cout;

  // Instantiate top level design with N=2 so that it will have 2
  // separate instances of half adders and both are given two separate
  // inputs
  my_design #(.N(N)) md( .a(a), .b(b), .sum(sum), .cout(cout));

  initial begin
    a <= 0;
    b <= 0;

    $monitor ("a=0x%0h b=0x%0h sum=0x%0h cout=0x%0h", a, b, sum, cout);

    #10 a <= 'h2;
    		b <= 'h3;
    #20 b <= 'h4;
    #10 a <= 'h5;
  end
endmodule

a[0]b[0]给出输出sum[0]cout[0]a[1]b[1]给出输出sum[1]cout[1]

模拟日志
ncsim > 运行
a=0x0 b=0x0 sum=0x0 cout=0x0
a=0x2 b=0x3 总和=0x1 cout=0x2
a=0x2 b=0x0 sum=0x2 cout=0x0
a=0x1 b=0x0 sum=0x1 cout=0x0
ncsim: *W,RNQUIE:模拟完成。
ncsim > 退出

看到详细的 RTL 确实有两个由generate块生成的半加器实例。

生成如果

下面显示的是一个使用if else内部generate结构在两个不同的多路复用器实现之间进行选择的示例。第一个设计使用assign语句来实现多路复用器,而第二个设计使用case语句。在顶层设计模块中定义了一个名为USE_CASE的参数,用于在两个选项之间进行选择。

// Design #1: Multiplexer design uses an "assign" statement to assign
// out signal
module mux_assign ( input a, b, sel,
                   output out);
  assign out = sel ? a : b;

  // The initial display statement is used so that
  // we know which design got instantiated from simulation
  // logs
  initial
  	$display ("mux_assign is instantiated");
endmodule

// Design #2: Multiplexer design uses a "case" statement to drive
// out signal
module mux_case (input a, b, sel,
                 output reg out);
  always @ (a or b or sel) begin
  	case (sel)
    	0 : out = a;
   	 	1 : out = b;
  	endcase
  end

  // The initial display statement is used so that
  // we know which design got instantiated from simulation
  // logs
  initial
    $display ("mux_case is instantiated");
endmodule

// Top Level Design: Use a parameter to choose either one
module my_design (	input a, b, sel,
         			output out);
  parameter USE_CASE = 0;

  // Use a "generate" block to instantiate either mux_case
  // or mux_assign using an if else construct with generate
  generate
  	if (USE_CASE)
      mux_case mc (.a(a), .b(b), .sel(sel), .out(out));
    else
      mux_assign ma (.a(a), .b(b), .sel(sel), .out(out));
  endgenerate

endmodule

试验台

Testbench 实例化顶层模块my_design并将参数USE_CASE设置为 1,以便实例化设计 usingcase语句。

module tb;
	// Declare testbench variables
  reg a, b, sel;
  wire out;
  integer i;

  // Instantiate top level design and set USE_CASE parameter to 1 so that
  // the design using case statement is instantiated
  my_design #(.USE_CASE(1)) u0 ( .a(a), .b(b), .sel(sel), .out(out));

  initial begin
  	// Initialize testbench variables
  	a <= 0;
    b <= 0;
    sel <= 0;

    // Assign random values to DUT inputs with some delay
    for (i = 0; i < 5; i = i + 1) begin
      #10 a <= $random;
      	  b <= $random;
          sel <= $random;
      $display ("i=%0d a=0x%0h b=0x%0h sel=0x%0h out=0x%0h", i, a, b, sel, out);
    end
  end
endmodule

当参数USE_CASE为1时,从仿真日志可以看出,multiplexer design usingcase语句被实例化了。当USE_CASE为零时,多路复用器设计 usingassign语句被实例化。这可以从模拟日志中打印的显示语句中看出。

模拟日志
// 当 USE_CASE = 1 时
ncsim > 运行
mux_case 被实例化
i=0 a=0x0 b=0x0 选择=0x0 输出=0x0
i=1 a=0x0 b=0x1 选择=0x1 输出=0x1
i=2 a=0x1 b=0x1 选择=0x1 输出=0x1
i=3 a=0x1 b=0x0 选择=0x1 输出=0x0
i=4 a=0x1 b=0x0 选择=0x1 输出=0x0
ncsim: *W,RNQUIE:模拟完成。

// 当 USE_CASE = 0 时
ncsim > 运行
mux_assign 被实例化
i=0 a=0x0 b=0x0 选择=0x0 输出=0x0
i=1 a=0x0 b=0x1 选择=0x1 输出=0x0
i=2 a=0x1 b=0x1 选择=0x1 输出=0x1
i=3 a=0x1 b=0x0 选择=0x1 输出=0x1
i=4 a=0x1 b=0x0 选择=0x1 输出=0x1
ncsim: *W,RNQUIE:模拟完成。

生成案例

generate case 允许模块、initial 和 always 块根据case表达式在另一个模块中实例化,以从多个选项中选择一个。

// Design #1: Half adder
module ha (input a, b,
           output reg sum, cout);
  always @ (a or b)
  {cout, sum} = a + b;

  initial
    $display ("Half adder instantiation");
endmodule

// Design #2: Full adder
module fa (input a, b, cin,
           output reg sum, cout);
  always @ (a or b or cin)
  {cout, sum} = a + b + cin;

    initial
      $display ("Full adder instantiation");
endmodule

// Top level design: Choose between half adder and full adder
module my_adder (input a, b, cin,
                 output sum, cout);
  parameter ADDER_TYPE = 1;

  generate
    case(ADDER_TYPE)
      0 : ha u0 (.a(a), .b(b), .sum(sum), .cout(cout));
      1 : fa u1 (.a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));
    endcase
  endgenerate
endmodule

试验台

module tb;
  reg a, b, cin;
  wire sum, cout;

  my_adder #(.ADDER_TYPE(0)) u0 (.a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));

  initial begin
    a <= 0;
    b <= 0;
    cin <= 0;

    $monitor("a=0x%0h b=0x%0h cin=0x%0h cout=0%0h sum=0x%0h",
             a, b, cin, cout, sum);

    for (int i = 0; i < 5; i = i + 1) begin
      #10 a <= $random;
      b <= $random;
      cin <= $random;
    end
  end
endmodule

请注意,由于实例化了半加器,因此cin对输出sumcout没有任何影响。

模拟日志
ncsim > 运行
半加器实例化
a=0x0 b=0x0 cin=0x0 cout=00 sum=0x0
a=0x0 b=0x1 cin=0x1 cout=00 sum=0x1
a=0x1 b=0x1 cin=0x1 cout=01 sum=0x0
a=0x1 b=0x0 cin=0x1 cout=00 sum=0x1
ncsim: *W,RNQUIE:模拟完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/34806.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

centos7 clamav 杀毒软件安装

壹&#xff1a;编译安装 1&#xff0c;官网获取源码包 clamav官网地址 2&#xff0c;创建clamav 用户和存放病毒库目录 a, 创建clamav 用户和用户组 groupadd clamav && useradd -g clamav clamav && id clamavb,日志存放目录 mkdir -p /henan/clamav/lo…

Spring中的ApplicationContext所体现出来的工厂模式

Spring初体验 通常我们写代码时&#xff0c;先定义一个Class&#xff0c;然后再别的地方实例化&#xff0c;再进行调用&#xff0c;比如下边的Hello World的例子&#xff0c;类Hello有一个say()方法&#xff0c;用于打印出“Hello World”的字符串&#xff0c;另一个类App&…

python和R绘制箱线图+抖动点

python和R绘制箱线图抖动点 散点箱线图 IPCC AR6 https://www.ipcc.ch/ 通过散点展示数据的直观分布 x轴刻度标签如果是“连续”数据&#xff0c;可添加渐变背景。通过渐变来体现升温幅度&#xff0c;美观形象。 python版本&#xff1a; 先手搓数据&#xff1a; import pan…

【构建ML驱动的应用程序】第 11 章 :监控和更新模型

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

c++11 unique_lock 使用

我们知道c11 提供了很多的类模板供我们使用&#xff0c;其中就有 lock_guard&#xff0c;这个用法也很简单&#xff0c;像这样&#xff1a; std::mutex m_mutex; std::lock_guard<std::mutex> guard(m_mutex); mutex 的 lock 和 unlock 完全是自动的&#xff0c;无需我…

新鲜出炉|基于深度学习的运维日志领域新进展

作者&#xff1a;云智慧算法工程师 Hugo Guo 运维日志领域研究方向主要包含异常日志检测、日志模式解析、日志内容分类、日志告警等。本篇文章介绍了热门异常检测模型 DeepLog、A2Log 等模型&#xff0c;以及云智慧自研模型 Translog 等。与此同时&#xff0c;在文章最后介绍了…

springboot自定义starter实践

创建一个spring项目 仿照spring的规范&#xff0c;artifact命名为xxx-spring-boot-starter 按需添加必要的依赖 这里只作为测试&#xff0c;就按最低的需求来只勾选如下三个 lombok、spring-boot-configuration-processor、spring-boot-autoconfigure 默认生成的项目结构如下…

使用HuggingFace实现 DiffEdit论文的掩码引导语义图像编辑

在本文中&#xff0c;我们将实现Meta AI和Sorbonne Universite的研究人员最近发表的一篇名为DIFFEDIT的论文。对于那些熟悉稳定扩散过程或者想了解DiffEdit是如何工作的人来说&#xff0c;这篇文章将对你有所帮助。 什么是DiffEdit? 简单地说&#xff0c;可以将DiffEdit方法…

【论文解读】Self-Explaining Structures Improve NLP Models

&#x1f365;关键词&#xff1a;性能提升、文本分类、信息推理 &#x1f365;发表期刊&#xff1a;arXiv 2020 &#x1f365;原始论文&#xff1a;https://arxiv.org/pdf/2012.01786.pdf &#x1f365;代码链接https://github.com/ShannonAI/Self_Explaining_Structures_Impro…

Java内部类

Java当中内部类主要有4种&#xff0c;分别是静态内部类、实例内部类/非静态内部类、局部内部类&#xff08;几乎不用&#xff09;、匿名内部类。静态内部类&#xff1a;被static修饰的内部成员类 ①在静态内部类只能访问外部类中的静态成员 ②创建静态内部类对象时&#xff0c;…

PB 2019 R3 MSOLEDBSQL SQL Server not available in Database Profiles

pb2019 pb2021,安装SQL OLEDB驱动时的注意事项&#xff1a; I installed PB 2019 R3, but when I go to the Database Profiles Window, MSOLEDBSQL SQL Server is not listed. Please go to the registry to check and see the key MSOLEDBSQL exists under HKEY_LOCAL_MACHI…

Python之tkinter图形界面设计学习二

图形用户界面&#xff08;简称GUI&#xff09;&#xff0c;是指采用图形方式显示的计算机操作用户界面。与计算机的命令行界面相比&#xff0c;图形界面对于用户的操作显得更加直观和简便。 一、tkinter模块 tkinter是Python的内置GUI模块。使用tkinter可以快速地创建GUI应用…

Vue脚手架Ⅲ(浏览器本地存储,Vue中的自定义事件,全局事件总线,消息订阅与发布(pubsub),nextTick,Vue封装的过度与动画)

文章目录脚手架3.10 浏览器本地存储3.11 Vue中的自定义事件3.12 全局事件总线3.13 消息订阅与发布&#xff08;pubsub&#xff09;3.14 nextTick3.15 Vue封装的过度与动画3.15.1 动画效果3.15.2 过度效果3.15.3 多个元素过度3.15.4 集成第三方动画3.15.5 总结过度和动画脚手架 …

达梦数据库安装与初始化超详细教程

陈老老老板&#x1f9b8;&#x1f468;‍&#x1f4bb;本文专栏&#xff1a;国产数据库-达梦数据库&#xff08;主要讲一些达梦数据库相关的内容&#xff09;&#x1f468;‍&#x1f4bb;本文简述&#xff1a;本文讲一下达梦数据库的下载与安装教程&#xff08;Windows版&…

一文解读 NFT 零版税

当我们听到“版税”这两个字时&#xff0c;脑海中首先浮现的是什么&#xff1f; 是对创作者作品权属的保护&#xff0c;还是项目方、平台额外的收益&#xff1f; 长期以来&#xff0c;版税作为一种收益机制&#xff0c;让买家“为知识和内容付费”&#xff0c;又让卖家“享受…

m在ISE平台下使用verilog开发基于FPGA的GMSK调制器

目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 高斯最小频移键控&#xff08;Gaussian Filtered Minimum Shift Keying&#xff09;&#xff0c;这是GSM系统采用的调制方式。数字调制解调技术是数字蜂窝移动通信系统空中接口的重要组成…

决策树-相关作业

1. 请使用泰勒展开推导gini不纯度公式&#xff1b; 2. 请说明树的剪枝怎么实现&#xff1b; ●预剪枝&#xff08;pre-pruning&#xff09;通过替换决策树生成算法中的停止准则。&#xff08;例如&#xff0c;最大树深度或信息增益大于某一阈值&#xff09;来实现树的简化。预…

Flutter高仿微信-第39篇-单聊-删除单条信息

Flutter高仿微信系列共59篇&#xff0c;从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。 详情请查看 效果图&#xff1a; 实现代码&#xff1a; //删除对话框 Future<void> _showDeleteDialog(Ch…

要把项目问题管理好,项目经理需要这8个步骤!

项目问题时有发生&#xff0c;想让项目获得成功&#xff0c;项目经理需要有一个计划来快速有效地应对任何出现的问题。这是最佳实践问题管理过程的一部分&#xff0c;更是良好项目管理的核心本质。 项目问题的四种类型 任何事情都可能成为项目过程中影响项目计划的问题。项目…

ZYNQ之FPGA学习----FIFO IP核使用实验

1 FIFO IP核介绍 FIFO 的英文全称是 First In First Out&#xff0c; 即先进先出。与 FPGA 内部的 RAM 和 ROM 的区别是没有外部读写地址线&#xff0c; 采取顺序写入数据&#xff0c; 顺序读出数据的方式&#xff0c;使用起来简单方便&#xff0c;缺点就是不能像 RAM 和 ROM …