草庐IT

Verilog语法之generate for、generate if、generate case

孤独的单刀 2023-10-28 原文

0、前言

        Verilog-2005中有3个generate 语句可以用来很方便地实现重复赋值和例化(generate for)或根据条件选择性地进行编译(generate if和generate case)等功能。接下来就一起看下这3个语句的应用场景和应用方法吧。


1、generate for

        假设我希望把2个输入a[4:0]和b[4:0]做一个异或操作,但是顺序要颠倒,也就是这样:

module xor_test(
	input	[4:0]	a,
	input	[4:0]	b,
	output	[4:0]	out
);
	
assign	out[4] = a[4] ^ b[0];
assign	out[3] = a[3] ^ b[1];
assign	out[2] = a[2] ^ b[2];
assign	out[1] = a[1] ^ b[3];
assign	out[0] = a[0] ^ b[4];
			
endmodule

        在vivado中分析出来是这样的:很简单就是两个输出的不同为做一个异或运算。

        vivado综合出来是这样的:用了几个LUT来实现异或功能。


1.1、应用场景

        上面的例子限于篇幅我只假设了输入为5bit的位宽,所以这样写并不会让人觉得有多麻烦,但是假想一下如果位宽变成10、20、100呢?那我手不写断去?

        当你需要进行一些重复性的工作时,比如多次例化同一模块、同一语句等,可以使用generate for语句来解放双手,节省工作量。当然你用脚本语言来生成或者直接用某些编辑器也能很快地实现这个功能,不过在这里我们就不提了。     

        上面的例子用generate for语句写是这样的:

module xor_test(
	input	[4:0]	a,
	input	[4:0]	b,
	output	[4:0]	out
);

genvar i;										//定义常量作为重复判断条件

generate
	for (i = 0; i < 8; i = i + 1)				//重复条件
		begin: XOR_INST							//begin要起个名字
			assign	out[i] = a[i] ^ b[4-i];		//需要重复的语句
		end
endgenerate
				
			
endmodule

        在vivado中分析出来是这样的:(与上面的方式一致)

        vivado综合出来是这样的: (仍然与上面的方式一致)

       

        这样看, generate for是个不错的提高效率的方案。当然,该语句不光可以对assign进行重复赋值,还适用以下场景:

                (1)模块module;(2)用户定义原语UDP;(3)门级语句;(4)连续赋值语句assign;(5)initial和always块。


1.2、格式

        generate for语句的一般用法:

// Declare the loop variable

genvar <name>;
 

// Code for the

generate

  for (<initial_condition>; <stop_condition>; <increment>) begin

    // Code to execute

  end

endgenerate

        如果你是一个基于xilinx的开发者,可以使用vivado自带的语法模板:

        (1)打开语法模板:

        (2)搜索generate:

        (3)把上图右侧的语句复制到你自己的代码里边。

        关于generate for语句的使用需要注意:

  • generate for 语句必须使用genvar关键字定义for循环变量
  • generate for 循环必须加 begin…end, 哪怕只有一句
  • 不要使用 i++这种C语言式的自增语句(Verilog没有i++这个语法),而是使用 i = i + 1
  • generate后不加begin,里面的语法:for循环、if…else…、case语句 后面的begin后面一定要加名字,且名字唯一,否则会导致无法比对通过的问题
  • 过多的generate会导致收集覆盖率缓慢,要注意使用

2、generate if

        generate if的使用场景和条件编译语句类似,比如你的代码中包含了一个加法模块和一个减法模块,对于2个输入a和b,希望使用POL来进行控制:如POL=1则进行加法,反之亦然----POL=1----out = a + b;POL=0----out = a - b。

        代码是这样写的:

module xor_test(
	input	[4:0]	a,
	input	[4:0]	b,
	output	[4:0]	out
);

localparam	integer	POL = 1;		//根据POL的值来生成对应的电路

generate
	if (POL == 1) begin: POL1
		assign	out = a + b;
	end else begin: POL0
		assign	out = a - b;
	end
endgenerate
							
endmodule

        定义成POL = 1时会由vivado综合成一个加法器:

        定义成POL = 0时则会由vivado综合成一个减法器: 

        

        假如不使用generate if语法,则代码是这样的:

module xor_test(
	input		[4:0]	a,
	input		[4:0]	b,
	input				POL,
	output	reg	[4:0]	out
);

always@(*)begin
	if(POL == 1)
		out = a + b;
	else
		out = a - b;
end
							
endmodule

        这样综合出来的就是加法电路和减法电路一起: 

        使用generate if可以根据需要来灵活地生成对应电路,不会浪费资源,适用于某些根据特定需求来实现电路的场景。而不使用该语句则会把所有潜在的电路均综合出来,会使电路面积增大,但是灵活性却较高。

        这是vivado自带的语法模板:

   generate
      if (<condition>) begin: <label_1>
         <code>;
      end else if (<condition>) begin: <label_2>
         <code>;
      end else begin: <label_3>
         <code>;
      end
   endgenerate

3、generate case

        generate case和generate if作用上是差不多的,都是用于选择性综合电路,区别就是if语句和case语句的区别,如果你会用其中一个,那另一个也很简单,模板如下:

   generate
      case (<constant_expression>)
         <value>: begin: <label_1>
                     <code>
                  end
         <value>: begin: <label_2>
                     <code>
                  end
         default: begin: <label_3>
                     <code>
                  end
      endcase
   endgenerate

        上面的例子照着改就是这样了:

module xor_test(
	input	[4:0]	a,
	input	[4:0]	b,
	output	[4:0]	out
);

localparam	integer	POL = 1;		//根据POL的值来生成对应的电路

generate
	case(POL)
		1'b1: begin: POL1
				assign	out = a + b;
			end
		1'b0: begin: POL0
				assign	out = a - b;
			end
		default:begin:	DEFAULT end	
	endcase
endgenerate
							
endmodule

  • 📣博客主页:wuzhikai.blog.csdn.net
  • 📣本文由 孤独的单刀 原创,首发于CSDN平台🐵!
  • 📣您有任何问题,都可以在评论区和我交流📞!
  • 📣创作不易,您的支持是我持续更新的最大动力!如果本文对您有帮助,还请多多点赞👍、评论💬和收藏⭐!

有关Verilog语法之generate for、generate if、generate case的更多相关文章

  1. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  2. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  3. ruby - 覆盖相似的方法,更短的语法 - 2

    在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a

  4. ruby 语法糖 : dealing with nils - 2

    可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby​​编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some

  5. ruby - Ruby 语法糖有 "rules"吗? - 2

    我正在学习Ruby的基础知识(刚刚开始),我遇到了Hash.[]method.它被引入a=["foo",1,"bar",2]=>["foo",1,"bar",2]Hash[*a]=>{"foo"=>1,"bar"=>2}稍加思索,我发现Hash[*a]等同于Hash.[](*a)或Hash.[]*一个。我的问题是为什么会这样。是什么让您将*a放在方括号内,是否有某种规则可以在何时何地使用“it”?编辑:我的措辞似乎造成了一些困惑。我不是在问数组扩展。我明白了。我的问题基本上是:如果[]是方法名称,为什么可以将参数放在括号内?这看起来几乎——但不完全是——就像说如果你有一个方法Foo.d

  6. ruby - 如何让Ruby捕获线程中的语法错误 - 2

    我正在尝试使用ruby​​编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?

  7. ruby -::在 Ruby 语法中是什么意思? - 2

    这个问题在这里已经有了答案:WhatisRuby'sdouble-colon`::`?(12个答案)关闭8年前。什么是::?@song||=::TwelveDaysSong.new

  8. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  9. 语法类似于 GitHub Flavored Markdown 的 Ruby markdown 解释器? - 2

    我使用Jekyll运行博客,并认为我会解决RedcarpetMarkdown解释器,因为它是developedandusedbyGitHub.好吧,我只是碰巧遇到了一个错误,去检查问题,然后foundthis.Maintainersays,"Asyouprobablyhavenoticed(harharharhar)Idon'thavetimetomaintainRedcarpetanymore.It'snotapriorityforme(IfindMarkdownthoroughlyboring)andit'snotapriorityforGitHub,becausewenolong

  10. ruby - 是否有用于复杂比较的漂亮语法? - 2

    方法应返回-1,0或1分别表示“小于”、“等于”和“大于”。对于某些类型的可排序对象,通常将排序顺序基于多个属性。以下是可行的,但我认为它看起来很笨拙:classLeagueStatsattr_accessor:points,:goal_diffdefinitializepts,gd@points=pts@goal_diff=gdenddefothercompare_pts=pointsother.pointsreturncompare_ptsunlesscompare_pts==0goal_diffother.goal_diffendend尝试一下:[LeagueStats.new(

随机推荐