SV中$unit编译单元

SV 知识点细节(一) 1. `ifndef 条件编译 它是if not define 的简写,最主要目的是防止头文件的重复包含和编译; 用法如下: 'ifndef DV_CHECK //先测试DV_CHECK 是否被宏定义过 'define DV_CHECK(T_, MSG_="") 程序段1 //如果没有被宏定义过,定义DV_CHECK ,并编译程序段 1 'endif 程... 阅读详情

SV $unit编译单元

SV中增加了编译单元的概念,就是SV源文件编译的时候,一起编译的所有源文件

  • 当多个源文件一起编译时,只有一个$unit域,包导入$unit域中的所有子项对这些源文件都是可见的
  • 当多个源文件单独编译时,会产生多个$unit域,一个$unit中导入的包对其他$unit是不可见的

1. 编译单元域搜索规则

编译单元域在搜索顺序中排第三位

举个栗子

package a_dpk;  //创建一个名为a_dpk的包
    function print();
        $display("\t This is in a_dpk!");
    endfunction
endpackage

package b_dpk;  //创建一个名为b_dpk的包
    function print();
        $display("\t This is in b_dpk!");
    endfunction
endpackage

import b_dpk:: *; //导入$unit编译单元域

module test_tb;
    
    import a_dpk:: *; //通配符导入

    function print();
        $display("\t This is in module!");
    endfunction

    initial begin
        $display("\t**********************");
        print;
        $display("\t***********End*********");
    end
endmodule

这里我们创建了两个包(a_dpk和b_dpk),两个包中的都只有一个打印函数,同时module中也有一个打印函数,(打印函数用于指示所在位置)

打印结果如下:

image-20211216201944989

从打印结果可以看出,当三者都存在时,打印的是module中声明的函数

那么如果把module中声明的函数注释掉会打印哪个函数呢?

package a_dpk;  //创建一个名为a_dpk的包
    function print();
        $display("\t This is in a_dpk!");
    endfunction
endpackage

package b_dpk;  //创建一个名为b_dpk的包
    function print();
        $display("\t This is in b_dpk!");
    endfunction
endpackage

import b_dpk:: *; //导入$unit编译单元域

module test_tb;
    
    import a_dpk:: *; //通配符导入

    //function print();
    //    $display("\t This is in module!");
    //endfunction

    initial begin
        $display("\t**********************");
        print;
        $display("\t***********End*********");
    end
endmodule

运行结果如下:

image-20211216203025254

可以看到此时打印的是在module中导入的包

那么接下来我们把在module中导入的包注释掉,即把import a_dpk::*;注释掉

package a_dpk;  //创建一个名为a_dpk的包
    function print();
        $display("\t This is in a_dpk!");
    endfunction
endpackage

package b_dpk;  //创建一个名为b_dpk的包
    function print();
        $display("\t This is in b_dpk!");
    endfunction
endpackage

import b_dpk:: *; //导入$unit编译单元域

module test_tb;
    
   // import a_dpk:: *; //通配符导入

    //function print();
    //    $display("\t This is in module!");
    //endfunction

    initial begin
        $display("\t**********************");
        print;
        $display("\t***********End*********");
    end
endmodule

下面运行结果:

此时终于把导入$unit编译单元域的内容打印出来了

通过这个过程不难发现,在运行过程中,先从module内部找有没有声明,如果没有声明再从module内部import的包找,如果还是没有才会在module外部import的包中找

这也就是为什么 编译单元域在搜索规则中排第三

那么为什么编译单元域叫$unit呢?我们可以再把代码更改一下

package a_dpk;  //创建一个名为a_dpk的包
    function print();
        $display("\t This is in a_dpk!");
    endfunction
endpackage

//package b_dpk;  //创建一个名为b_dpk的包
//    function print();
//        $display("\t This is in b_dpk!");
//    endfunction
//endpackage

import b_dpk:: *; //导入$unit编译单元域

module test_tb;
    
   // import a_dpk:: *; //通配符导入

    //function print();
    //    $display("\t This is in module!");
    //endfunction

    initial begin
        $display("\t**********************");
        print;
        $display("\t***********End*********");
    end
endmodule

我们把b_dpk注释掉,但依旧将其导入,看看运行结果

这里直接显示错误在 $unit,或许$unit只是一个名称,就好像上例中module命名为test_tb一样

2. 单独编译将包导入到$unit中(条件编译)

格式为:

`ifndef xxx
	`define xxx
`endif

这是C语言中常用的技巧,如果第一次遇到导入语句将其编译到$unit中,再次出现则不会编译

下面我们将上篇笔记中的包用这种方式仿真一下,先给出上篇笔记中包的内容

package definitions;
    parameter	version = "1.1";
    
    typedef enum {ADD, SUB, MUL} opcodes_t;

    typedef struct {
        logic	[31:0]	a, b;
        opcodes_t	opcode;	//声明的opcode中包含 ADD, SUB和MUL
    } instruction_t;
    
    function	automatic	[31:0]	multiplier	(input	[31:0]	a, b);
        return a * b;
    endfunction
endpackage 

我们将文件名命名为definitions.dpk,其中后缀.dpk是随便起的

`ifndef	PACK
	`define	PACK
	package	definitions;
        parameter	version = "1.1";
        
        typedef enum {ADD, SUB, MUL} opcodes_t;
        
        typedef struct {
            logic	[31:0]	a, b;
            opcodes_t	opcode;	//声明的opcode中包含 ADD, SUB和MUL
             } instruction_t;
        
        function	automatic	[31:0]	multiplier	(input	[31:0]	a, b);
            return a * b;
        endfunction
    endpackage

	import	definitions:: *;	//将包导入到$unit中
`endif

下面是源码和测试文件

`include "definitions.dpk"	//编译包文件

module ALU (
	input	instruction_t	IW,
    input	logic	clk,
    output	logic	[31:0]	result
);
    always @ (posedge clk) begin
        case(IW.opcode)
            ADD	:	result = IW.a + IW.b;
            SUB	:	result = IW.a - IW.b;
            MUL	:	result = multiplier(IW.a, IW.b);
        endcase
    end

endmodule
`include "definitions.dpk"	//编译包文件

module ALUtb;
    instruction_t	IW;
    logic				clk = 1;
	logic	[31:0]	result;
    
    always #10 clk = ~clk;	//生成时钟,周期为20ns
    
    initial begin
        IW.a = 'd10;
        IW.b = 'd5;
        IW.opcode = ADD;

        repeat(2)  @(negedge clk);
        	IW.a = 'd3;
        	IW.b = 'd7;
        	IW.opcode = MUL;
    
        repeat(2) @(negedge clk);
        	IW.a = 'd5;
        	IW.b = 'd1;
        	IW.opcode = SUB;
        
        repeat(3) @(negedge clk);
        	$finish; 
    end
    
    initial begin
        $monitor ($time, ,"a->%d, b->%d, opcode->%s, result->%d",IW.a, IW.b, IW.opcode, result);
    end

    ALU tb(.IW(IW), .result(result), .clk(clk));    //例化
endmodule

运行结果如下


本文主要参考

  1. 《SystemVerilog硬件设计及建模》
  2. 人人都会用到,但是大部分人不清楚是什么的“神秘空间” (baidu.com)
SV基础(二):数据类型 数据类型值类型符号位数驱动场景典型用途reg4值无符号任意(≥1)过程块赋值存储元件建模wire4值无符号任意(≥1)连续赋值或单驱动组合逻辑连接tri4值无符号任意(≥1)多驱动总线共享logic4值无符号任意(≥1)过程块或连续赋值统一替代regwireinteger4值有符号32位固定过程块赋值有符号整数运算time4值无符号64位固定系统函数赋值仿真时间记录real2值有符号64位浮点不可综合浮点数仿真(如模拟电路) 阅读详情

相关推荐

【Verilog中的条件编译】

verilog中的条件编译

li_kin的博客 1004

SystemVerilog Package实战:3个技巧帮你避免`import`和`::`的那些坑

本文深入探讨SystemVerilog Package在实际应用中的3个关键技巧,帮助开发者有效避免`import`和`::`操作中的常见陷阱。通过分析通配符导入风险、同名定义冲突解决方案以及package与include的本质区别,提供了一套完整的代码组织与调试方法论,特别适合UVM验证环境中的复杂项目管理。

weixin_30732487的博客 336

SystemVerilog句柄的使用

一、句柄的传递 句柄可以作为形式参数通过方法来完成对象指针,从外部传入方法内部 句柄也可以在方法内部首先完成修改,而后再由外部完成使用 function void create(ref Transaction tr); //ref或者inout tr = new(); tr.addr = 100; ... endfunction Transaction t; //此时t=null initial begin create(t); t.addr = 10; $display(t.add

qq_39794062的博客 1901

SystemVerilog(十二)-$unit声明空间

笔记$unit是一个危险的共享名称空间,充满危险。它的使用会导致设计难以编译和维护。下列unit代表$unit在将包添加到SystemVerilog标准之前,SV提供了一种不同的机制来创建多个模块共享的定义。这个机制是一个名为unit的伪全局名称空间,也称unit 编译单元或声明空间。声明空间之外的任何声明都在unit声明空间中。在下面的示例中,bool_t的定义在两个模...

OpenFPGA的博客 1517

[SV]SystemVerilog学习笔记之packet

SystemVerilog学习笔记(一) 一、包(package) 1.1.package的定义 package在package和endpackage这两个关键字之间定义。 包中可以包含的可综合的结构有: parameterandlocalparamconstant definitions常量 constvariable definitions变量 typedefuser-defined types用户定义类型 Fully...

元直的博客 4959

一文搞懂 RC Correlation Scale Factor 的生成与应用

pre-route 用的是统计估算模型,post-route 用的是详细布线提取,signoff 用的是第三方 QRC 或 StarRC——三个工具,三套参数体系,结果自然天差地别。不同 RC corner(rc_worst/rc_best/rc_typical)对应不同的工艺角和温度环境,每个 corner 的 R/C 偏差比例不同,必须分别生成和应用各自的 scale factor。别被名字骗了,这个工具专门干一件事——统计拟合两组 SPEF 之间的偏差,自动推荐最优 scaling factor。

weixin_47770727的博客 561

$unit编译单元声明

$unit编译单元声明 SystemVerilog含有编译单元。 相比Verilog,SystemVerilog增加了编译单元的概念。编译单元是同时编译的所有源文件。编译单元为软件工具提供了一种对整个设计子块单独编译的方法。一个子块可能包含第一个或多个模块(module)。这下模块可能包含在一个或多个文件中。设计的子块可能还包含接口块和测试程序块。 编译单元域包含外部声明。 SystemVerilog允许在包、模块、接口和程序块的外部进行声明扩展Verilog的声明域。这些外部声明在“编译单元域”中,并且对

小柚子的博客 1441

【STC8G1K08A串口使用】

STC8G1K08A串口打印“Hello world”

m0_47459564的博客 1万+

SystemVerilog 编译单元作用域 / 顶层作用域

SystemVerilog 编译单元作用域 / 顶层作用域 SV中引入了编译单元(compilation unit), 它是一起编译的源文件的一个组合。 编译单元作用域$unit, 即Module, macromodule, interface, program, package或者primitive边界之外的作用域,在此作用域内的任何成员如parameter都类似于全局成员,它可以被所有低一级的块访问,但是他们又不同于真正的全局成员,如parameter在编译时其他源文件不可见。 块外的作用域称为“顶层作

Yknjs的博客 1465

保姆级教程:用MATLAB搞定运动模糊图片修复(附完整代码与避坑指南)

本文提供了一份详细的MATLAB运动模糊图片修复教程,涵盖盲复原、图像复原等核心技术。通过傅里叶变换和Radon变换分析模糊参数,对比逆滤波、维纳滤波和Lucy-Richardson算法效果,并附完整代码与避坑指南,帮助用户实现专业级图像处理。

weixin_26765363的博客 230

【网络协议】TCP的拥塞控制机制

前言 计算机网络中的带宽、交换节点中的缓存和处理机等,都是网络的资源,在某段时间内,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏,这种情况就叫做拥塞。 所谓拥塞控制,就是防止过多的数据注入到网络中,从而使网络中的路由器或链路不致过载。要注意用拥塞控制与流量控制的区别,拥塞控制是一个全局性的过程,涉及到所有的额主机、路由器,以及与降低网 拥塞控制的算法有:慢开始、拥塞避免、快重传、快恢复四种。 慢开始和拥塞避免 发送方维持一个拥塞窗口的状态变量,其大小取决于网络的拥塞程度

兰亭风雨的专栏 1万+

unit类型是什么?_SystemVeriog什么是编译单元域$uint?

来都来了不关注一下吗来源| 杰瑞IC验证(ID:Jerry_IC)|原创作者| Jerry本文最佳阅读姿势:1.按顺序看。本文以带入探究的方式进行,而不是直接摆出结论,即每一个小节都以问题导入,进而触发新的问题,层层铺垫递进直至深刻的理解相关细节。2.建议先自己思考抛出的问题再看解释,效果更佳。3.篇幅略长,若时间不允许,可收藏分多次阅读。深吸一口气,正文开始~暗物质是宇宙中一种不...

weixin_39960793的博客 935

如何利用ADS中的耦合线设计带通滤波器并转换为HFSS模型

耦合线带通滤波器是一种常用的微带滤波器形式,由多个长度为四分之一波长的耦合线节组成,在所需频点形成谐振,构成滤波器的频率响应特性。首先我们先来了解一下耦合线带通滤波器的电路结构,见下图:包括两对耦合线,中间为公共连接点,其中两对耦合线的偶奇模阻抗为(Z1e,Z1o)和(Z2e,Z2o,端口输入阻抗为Z0)。2.指定一个初始奇偶模值,ADS优化出一个合适的结果,通过奇偶模值利用linecalc工具计算出微带耦合线尺寸。假设中心频率为2GHz,则对应频点的电长度为。5.运行结果,两个软件仿真结果基本一致。

auqihc的博客 2230

SV学习记录(四)​​​​​​​

本文系统介绍了SystemVerilog接口(interface)的设计与应用,重点阐述了如何通过接口解决测试平台与设计模块间的时序竞争问题。

2401_86318162的博客 297

告别电机啸叫!手把手教你配置TMC5160的StealthChop2静音模式(附参数自整定避坑指南)

本文详细介绍了如何通过配置TMC5160的StealthChop2模式彻底消除3D打印机电机噪音。从硬件准备到参数自整定,再到高级调优与异常处理,手把手教你实现实验室级别的静音效果,提升打印质量和使用体验。

weixin_33724659的博客 488

华为OD技术面八股文_C++_01

汇总华为OD技术面C++方向八股文真题,并提供详细解答。

qq_45776114的博客 1887

【SystemVerilog】连接设计和测试平台

本文介绍了SystemVerilog中验证设计的关键技术,重点阐述了接口(interface)、程序块(program block)和时钟块(clocking block)的应用。通过仲裁器和ATM路由器的案例,展示了接口如何封装复杂信号连接,减少代码量和连线错误。程序块将测试平台与设计在时序上分离,避免竞争状态。时钟块则确保测试信号在正确时间点被驱动和采样。文章还讲解了SystemVerilog断言(assertion)的使用方法,以及如何通过编译单元作用域($unit)和$root实现跨模块访问。

wuyufei_sun的博客 264

2、TrustZone(内含链接)——长期学习内容

ARM系列学习路径整理,希望对大家有用。

HoneyIC的博客 233

SV编译程序指令部分

文章目录持续更新一、`include1. `include是什么1) `include " filename "2) `include < filename >2. `include的示例二、ifdef、else、elsif、endif1. ifdef、else、elsif、endif是什么2. ifdef、else、elsif、endif、ifndef的示例三、`timescale1. `timescale是什么2. `timescale的用法 持续更新 工作或学习中遇到的类似知识点会及时补

被吓大的砰砰砰的博客 4529

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

SV第二章 数据类型

SystemVerilog 数据类型

li_kin的博客 2111

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

SV——自定义类型

/没有赋值的时候,将会是默认从0开始递增,既waite=0(00);load=1(01);8.如果枚举类型没有伴随typedef,那么该枚举类型指的则是一个匿名枚举类型(anonymousenumeratedtype)“自定义名字_t”typedef不一定只是和enum或者struct进行指代,它可以和任意的类型进行指代。所谓自定义就是用户用一个具有意义的词语去简单的描述一个很长,很难理解的量。[enum]描述一个抽象的变量(类似于状态机中的具有状态“idle,state,…...

qq_40567244的博客 1764

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

SV中$display有关数值的显示格式

实际中IEEE1800中,约定阈值宽度只能为正数,所以赋值域宽可能在不同的仿真工具下处理情况不一致。这个问题来自群里的小伙伴,我觉得还不错,就自己操作了一下(通过linux操作系统下的vcs来查看结果)刚好老师也讲过一次。可以看出,由于没有声明阈宽,显示的结果是默认阈宽。十进制是补空格左对齐,其他进制是补0左对齐。用十六进制表示是两位,十进制表示是2的8次方减1位。可以看出,设置了6位的域宽(大于实际位宽),即十进制左边对齐补空格,其他进制左对齐补0.1.首先是不考虑域宽的情况,即一般情况。

weixin_49068927的博客 1785

SV绿皮书提炼笔记(五)

面向对象编程基础

weixin_53833185的博客 2638

SV绿皮书笔记(四)

SV绿皮书笔记(四)

weixin_44590534的博客 2432

SV中的interface

随着设计复杂度的增加,模块之间的连接也变的复杂。通常连接DUT和Testbench的信号很多,一旦连接错误,平台就不能工作。并且很难发现其中的错误。添加信号的时候也是非常麻烦的。逻辑设计已经变的如此复杂,即使是块之间的通信也必须分割为独立的实体。SV中接口为块之间的通信建模,接口可以看成是一捆智能的连线。接口包含了连接,同步,甚至是两个块或者更多块之间的通信功能。它们连接了设计和测试平台。 `ifn

qq_30441519的博客 3443

1. SV数据类型

SV

weixin_41933824的博客 4679
上一篇: SystemVerilog package
下一篇: 用户自定义和枚举数据类型
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值