当前位置: 首页 > news >正文

VL8 使用generate_for语句简化代码

写在前面

  1. 这个专栏的内容记录的是Verilog题库刷题过程,附带RTL\TestBench,并进行代码覆盖率收集
  2. 该题库算是一个Verilog宝藏刷题网站了,提供在线仿真环境(题库),<刷题记录>专栏,持续打卡中…

文章目录

  • 一、题目
  • (1)题目描述
  • (2) 原程序
  • 二、分析
  • 三、RTL
  • 四、Testbench
  • 五、结果分析
  • (1)TB结果
  • (2)波形图
  • (3)覆盖率


一、题目

(1)题目描述

  在某个module中包含了很多相似的连续赋值语句,请使用generate…for语句编写代码,替代该语句,要求不能改变原module的功能。使用Verilog HDL实现以上功能并编写testbench验证。


(2) 原程序

module template_module( 
    input [7:0] data_in,
    output [7:0] data_out
);
    assign data_out [0] = data_in [7];
    assign data_out [1] = data_in [6];
    assign data_out [2] = data_in [5];
    assign data_out [3] = data_in [4];
    assign data_out [4] = data_in [3];
    assign data_out [5] = data_in [2];
    assign data_out [6] = data_in [1];
    assign data_out [7] = data_in [0];
    
endmodule

二、分析

1、generate语法结构

  • 定义genvar,作为generate中的循环变量。
  • generate语句中定义的for语句,必须要有begin
  • begin必须要有名称,也就是必须要有标签,因为标签会作为generate循环的实例名称。

  
2、generate:循环语句(loop)

//例子
'timescale 1 ns /1 ps
module nbic xor
#(parameter SIZE = 16)
(
	input  [SIZE-1 : 0] a, 
	input  [SIZE-1 : 0] b, 
	output [SIZE-1 : 0] y 
	);

	genvar gv_i; //这这类型的变量只能在generate循环语句中使用
	generate
		for (gv_i = o ; gv_i < SIZE ; gv_i = gv_i +1) begin : label
		// label用来表示generate循环的实例名称
		
			xor u_xor (y[gv_i] , a[gv_i] , b[gv_i]);
			//实例化后的结果如下:
			// label [0].u_xor (y[0] , a[0] , b[0]); 
			// label [1].u xor (y[1] , a[1] , b[1]);
			// label [2],u_xor (y[2] , a[2] , b[2]);
			// ... ...
			// label [SIZE-1].u_xor (y[SIZE-1] , a[SIZE-1] , b[SIZE-2]);
			//实例化后的层次路径如下:
			// nbit xor.label [0].u_xor;
			//... ...
			//同理,还可以引用别的已经定义的module在generate语句中实例化
		end 
	endgenerate
endmodule

  
3、generate:条件语句(conditional)

'timescale 1 ns /1 ps
module shift register 
#(parameter BITS = 8)
( 
	input shift_in , 
	inpuc clk      , 
	input resetn   ,
	output shift_out 
);
	wire [BITS-1 : 0] tq;
	
	genvar gv_1; //这种类型的变量只能在generateim环语句中使用
	// generate-condiciona1语句实质上是将条件语句放入到generate-for结构中
	/*在该条件语句结构中,if语句的条件必须是静态的,这样的条件表达式
		必须是由常数或者参数组成,也意味着在程序运行期间保持不变*/
	generate
		for (gv_1 =o : gv_i < BITS : gv_1 = gv_1 +1)begin : label
			if (gvi == BITS-1) begin//此条件成立时, u0dff
				dflip_flop uodff (
												 .d(serial_in) ,
												 .resetn (resetn) ,
												 .ck (clk) , 
												 .q(ta[gv_1])
											);
			end
			else begin
				if (gv_i == 0)begin //此条件成立时, uldff
					dflip_flop uldff (
												  .d(tg[gv_1 + 1]) , 
												  .resetn (resetn) , 
												  .ck (clk) , 
												  .g(serial_out));
				end
				else begin//其他情况下, u2dff
					dflip_flop u2dff (
													.d(tq[gv_i + 1]) ,
													.resetn (resetn) , 
													.ck(clk) , 
													.q(t[gv_11)
												);
				end
			end
	end 
endgenerate
endmodule

generate允许对语句进行条件选择,即将条件选择加入到generate中的for循环中,只例化条件成立时对应的语句或者module。


4、generate:分支语句(case)

'timescale 1 ns /1 ps
module adder
# (parameter N =4)
(
	input 		 	 ci,
	input  [N-1 : 0] ao, 
	input  [N-1 : 0] al,
	output 			 co,
	output [N-1 : 0] sum 
)//注意:未定义genvar变量//根据总线的位宽,调用相应的加法器
// 参数N在调用时可以重新定义,但是该值也是静态的,因为每次调用时N都是必须确定的
//调用不同位宽的加法器是根据不同的N来决定的
generate
	case (N)
		//N=1或者2时分别选用位宽为1位或2位的加法器
		1: adder_lbit adder1 (co , sum, ao , al , ci); // 1位的加法器
		2 : adder_2bie adder2 (co sum, ao, al , ci): // 2位的加法器1/默认的情况下选用位宽为N位的加法器
		default : adder_cla # (N) adder3 (co , sum , ao , al , ci);
	endcase
endgenerate
endmodule

三、RTL

module gen_for_module( 
  input  [7:0] data_in ,
  output [7:0] data_out
);

/*
  assign data_out [0] = data_in [7];
  assign data_out [1] = data_in [6];
  assign data_out [2] = data_in [5];
  assign data_out [3] = data_in [4];
  assign data_out [4] = data_in [3];
  assign data_out [5] = data_in [2];
  assign data_out [6] = data_in [1];
  assign data_out [7] = data_in [0];
*/
genvar gv_i;

generate
  for(gv_i=0;gv_i<8;gv_i=gv_i+1)begin:gv_label
    assign data_out[gv_i] = data_in[7-gv_i];
  end
endgenerate

endmodule



四、Testbench

`timescale 1ps/1ps
module tb_gen_for_module;
  reg [7:0] data_in ;
  reg [7:0] data_out;

/*-----------------------------------------------\
 --    --
\-----------------------------------------------*/
initial begin
    repeat(10000)begin
      d_case(data_in,{$random}%256);
      #5000 ;
  end
end

/*-----------------------------------------------\
 --    --
\-----------------------------------------------*/
task d_case;
  output  [7:0] a;
  input   [7:0] b;

  a = b;

endtask

/*-----------------------------------------------\
 --  display  --
\-----------------------------------------------*/
always @ (data_out)begin
  if(data_out == {data_in[0],data_in[1],data_in[2],data_in[3],
                  data_in[4],data_in[5],data_in[6],data_in[7]})begin
  end
  else begin
    $display($realtime,", error:gv_i = ;data_in = %d;data_out = %d",data_in,data_out);
  end
end

gen_for_module u_gen_for_module(
                                .data_in  (data_in  ),
                                .data_out (data_out )
                               );

initial #60000000 $finish;
initial begin
  $fsdbDumpfile("gen_for_module.fsdb");
  $fsdbDumpvars            ;
  $fsdbDumpMDA             ;
end
endmodule

五、结果分析

(1)TB结果

在这里插入图片描述在这里插入图片描述

display无打印错误信息


(2)波形图

在这里插入图片描述

由上图可以知道,输出是输入的一个移位,使用generate-for简化代码的运行结果和原来一致。


(3)覆盖率

在这里插入图片描述

代码覆盖率100%


✍✍☛ 题库入口
  经过一段时间的沉淀,发现入行IC行业,自己的底子还是很差,写的文章质量参差不齐,也没能解答大家的疑问。决定还是要实打实从基础学起,由浅入深。因此决定通过补充/完善基础知识的同时,通过题库刷题不断提高自己的设计水平,题库推荐给大家(点击直达),<题库记录>栏目不定期更新,欢迎前来讨论。


作者:xlinxdu
版权:本文版权归作者所有
转载:未经作者允许,禁止转载,转载必须保留此段声明,必须在文章中给出原文连接。

相关文章:

  • 从零开始搭建uni-app框架的小程序开发环境
  • 【web】TCP/UDP协议详解(字节二面:TCP三次握手、四次挥手)
  • C++打怪升级(二)- 引用详解
  • MongoDB的日志目录被删除了,导致无法启动:(code=exited, status=1/FAILURE)
  • 数据我爬定了,限流也挡不住,我说的
  • 可持久化线段树
  • 计算机网络-网络层篇-子网划分
  • DataX 初识
  • 工程项目管理——第十章 软件项目团队计划
  • 基于Java+SpringBoot+Thymeleaf+Mysql摄影图片分享网站系统设计与实现
  • C#的Dictionary类使用说明
  • 【FPGA教程案例90】机器视觉1——通过FPGA实现基于颜色模型的交通灯检测,使用MATLAB辅助测试
  • winform中c#调用第三方、opencv原生dll库图像处理
  • DS1302 / DS1307 不起振可能是寄存器配置原因
  • 大数据讲课笔记1.7 软件包管理器RPM与yum
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • css属性的继承、初识值、计算值、当前值、应用值
  •  D - 粉碎叛乱F - 其他起义
  • Django 博客开发教程 8 - 博客文章详情页
  • iOS 系统授权开发
  • Lucene解析 - 基本概念
  • PAT A1092
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • SpringBoot 实战 (三) | 配置文件详解
  • vue 配置sass、scss全局变量
  • vue-cli在webpack的配置文件探究
  • 百度地图API标注+时间轴组件
  • 如何设计一个微型分布式架构?
  • 国内开源镜像站点
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • $.ajax()参数及用法
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (转) Android中ViewStub组件使用
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .net 4.0发布后不能正常显示图片问题
  • .NET MVC第五章、模型绑定获取表单数据
  • .Net Web窗口页属性
  • .NET 服务 ServiceController
  • .Net 知识杂记
  • .net6使用Sejil可视化日志
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • ?php echo ?,?php echo Hello world!;?
  • @Responsebody与@RequestBody
  • [ 转载 ] SharePoint 资料
  • [20160807][系统设计的三次迭代]
  • [2017][note]基于空间交叉相位调制的两个连续波在few layer铋Bi中的全光switch——
  • [20170705]lsnrctl status LISTENER_SCAN1