systemverilog 实验
systemverilog的例子

systemverilog的例子摘要:一、SystemVerilog 简介1.SystemVerilog 的发展历程2.SystemVerilog 在EDA 领域的应用二、SystemVerilog 的基本语法1.数据类型a.整型b.实型c.布尔型d.字符串型2.变量声明与赋值3.运算符与表达式4.控制结构a.顺序结构b.选择结构c.循环结构三、SystemVerilog 的模块与接口1.模块定义2.模块端口声明3.模块实例化4.接口定义与实现四、SystemVerilog 的行为描述1.过程声明2.连续赋值与事件驱动赋值3.函数声明与调用五、SystemVerilog 的仿真与测试1.仿真驱动2.测试序列3.波形查看与分析正文:SystemVerilog 是一种基于Verilog 的硬件描述语言,它被广泛应用于电子设计自动化(EDA)领域,特别是在验证和仿真方面具有显著优势。
本文将简要介绍SystemVerilog 的基本语法、模块与接口、行为描述以及仿真与测试方面的知识。
一、SystemVerilog 简介SystemVerilog 起源于Verilog,是在其基础上进行扩展的一种硬件描述语言。
自1995 年由Cadence 公司推出以来,SystemVerilog 逐渐成为业界标准,被广泛应用于EDA 领域,尤其在验证方面取得了显著成果。
二、SystemVerilog 的基本语法SystemVerilog 提供了丰富的数据类型,包括整型(integer)、实型(real)、布尔型(boolean)和字符串型(string)等。
此外,SystemVerilog 还支持变量声明与赋值、运算符与表达式、以及控制结构(顺序结构、选择结构和循环结构)。
三、SystemVerilog 的模块与接口模块是SystemVerilog 的基本组织单位,用户可以通过模块定义、模块端口声明、模块实例化以及接口定义与实现等方式组织代码。
systemverilog的例子

systemverilog的例子(原创版)目录1.SystemVerilog 概述2.SystemVerilog 的例子3.例子的解析4.总结正文SystemVerilog 是一种硬件描述语言,主要用于设计和验证数字电路和模拟混合信号电路。
它基于 Verilog,并添加了许多新的功能,如类、继承、多态和封装等,使得 Verilog 更加强大和灵活。
SystemVerilog 的一个关键应用是模块化设计和验证,可以将电路划分为多个模块,然后对每个模块进行验证,最后将所有模块组合在一起进行系统级验证。
下面是一个简单的 SystemVerilog 例子,用于演示如何使用SystemVerilog 进行模块化设计和验证。
假设我们要设计一个 4 位加法器,可以将其划分为两个模块:一个用于实现 4 位全加器,另一个用于实现进位处理。
首先,我们创建一个名为"full_adder"的模块,用于实现 4 位全加器。
```verilogmodule full_adder (input [3:0] A,input [3:0] B,input Cin,output [3:0] Sum,output Cout);assign Sum[0] = A[0] ^ B[0] ^ Cin;assign Sum[1] = A[1] ^ B[1] ^ (Cin << 1);assign Sum[2] = A[2] ^ B[2] ^ (Cin << 2);assign Sum[3] = A[3] ^ B[3] ^ (Cin << 3);assign Cout = (Sum[0] & Sum[1] & Sum[2] & Sum[3]) | (Sum[0] & Sum[1] & Sum[2] & (Cin << 1)) | (Sum[0] & Sum[1] & (Cin << 2)) | (Sum[0] & (Cin << 3));endmodule```接下来,我们创建一个名为"adder_module"的模块,用于实现进位处理。
system verilog 实例化参数模块

system verilog 实例化参数模块如何在SystemVerilog中实例化参数化模块在SystemVerilog中,模块是一种组织硬件描述的方式。
参数化模块是一种允许用户在实例化时为模块参数传递值的工具。
在本篇文章中,我们将详细介绍如何在SystemVerilog中实例化参数化模块,并展示一些示例代码来帮助读者更好地理解。
参数化模块允许用户在实例化时为模块的参数传递不同的值。
这样可以根据实例化时提供的参数值,生成不同的硬件描述。
这对于设计具有不同配置或不同功能的模块非常有用。
参数化模块也可以提供一种动态生成硬件描述的方式。
首先,我们需要定义一个参数化模块。
在模块声明中,我们可以使用`#`符号来定义一个或多个参数。
例如,下面是一个具有两个参数的参数化模块的声明:systemverilogmodule MyParameterizedModule #(parameter WIDTH = 8, parameter DEPTH = 16) (input logic [WIDTH-1:0] data, input logic [DEPTH-1:0] address, output logic [WIDTH-1:0] output);模块的具体实现endmodule在这个例子中,我们定义了两个参数:`WIDTH`和`DEPTH`。
这些参数被用于定义`data`,`address`和`output`端口的位宽。
接下来,我们可以使用实际的参数值来实例化此参数化模块。
要在SystemVerilog中实例化一个参数化模块,我们需要在实例化语句中为参数提供值。
以下是一个实例化带有具体参数值的参数化模块的示例:systemverilogmodule MyTopModule;实例化参数化模块MyParameterizedModule #(8, 32)myInst(.data(in_data), .address(in_address), .output(out_data));顶层模块的其余部分endmodule在这个例子中,我们使用`(8, 32)`作为参数值实例化了`MyParameterizedModule`模块。
system verilog 调用 python 案例

system verilog 调用 python 案例SystemVerilog是一种硬件描述语言,通常用于硬件设计和验证。
而Python是一种高级编程语言,常用于软件开发和自动化脚本编写。
结合这两种语言,可以实现硬件设计与验证过程中的自动化任务,提高工作效率和准确性。
在SystemVerilog中调用Python可以实现很多功能,比如数据处理、文件操作、测试生成等。
以下是一个简单的案例,演示了如何在SystemVerilog中调用Python脚本进行数据处理:假设我们有一个SystemVerilog模块,需要对一组数据进行求和操作。
我们可以编写一个Python脚本来实现这个功能,然后在SystemVerilog中调用这个脚本来完成数据处理。
首先,我们编写一个Python脚本,比如sum.py,实现对一组数据进行求和操作。
脚本内容如下:```python# sum.pydata = [1, 2, 3, 4, 5]result = sum(data)print(result)```接着,我们在SystemVerilog中调用这个Python脚本。
可以使用SystemVerilog中的system函数来执行外部命令,如下所示:```system("python sum.py")```当SystemVerilog执行到这一行代码时,会调用Python脚本sum.py,并输出结果。
在这个例子中,Python脚本会对数据[1, 2, 3, 4, 5]进行求和操作,最后输出结果。
通过这种方式,我们可以在SystemVerilog中调用Python脚本,实现数据处理、文件操作、测试生成等功能。
这种结合硬件描述语言和高级编程语言的方式,可以帮助工程师更高效地完成硬件设计与验证任务。
System-Verilog-与功能验证分析

功能验证技术和方法学概要
功能验证技术和方法学概要
激励产生形式 1)用户直接输入,即直接测试(direct test)。 2)种子随机生成,即随机测试(random test)。 3)用户可控的随机输入,即约束随机测试 (constraint random test)
实际项目中我们通常三者结合着去检查比对结果。
功能验证技术和方法学概要
功能验证流程 验证过程可以被分解成三个主要阶段: 1)制定验证策略和验证计划; 2)创建验证平台,运行和调试; 3)覆盖率分析和回归测试。
功能验证技术和方法学概要
制定验证策略和验证计划
功能验证技术和方法学概要
创建验证平台,运行和调试;
System Verilog 与功能验证
功能验证技术和方法学概要
为什么需要IC验证 IC设计复杂度巨大,规模已达上亿门级。 70%验证, 30%设计。 验证是IC设计的关键部分。
功能验证技术和方法学概要
功能验证技术和方法学概要
什么是验证 验证是确保设计和预定的设计期望一致(吻合) 的过程。
功能验证技术和方法学概要
覆盖率驱动验证 覆盖率驱动验证方法学涉及以下技术: 事务级验证、约束随机激励产生、自动化结果 比较、覆盖率统计分析和直接测试。
功能验证技术和方法学概要
事务级验证 事务级验证允许在一个更高的抽象层次来创建 验证场景。 信号级VS事物级:低效VS高效,简单VS复杂。
功能验证技术和方法学概要
功能验证技术和方法学概要
覆盖率分析和回归测试
功能验证技术和方法学概要
SystemVerilog验证方法实例 random_generator

testbench.in/TB_15_SYSTEM_FUNCTION_RANDOM_A_MYTH.html
2/18
13-12-17
WWW.TESTBENCH.IN - Verilog for Verification signed number. This can also be used to meet the requirements. The following example shows the usage of concatenation operator and $unsigned.
EXAMPLE: module Tb(); integer add_1;
initial begin repeat(5) begin #1; add_1 = $random % 10; end end
initial $monitor("add_1 = %d",add_1);
endmodule
RESULT:
add_1 = 8; add_1 = 4294967287; add_1 = 4294967295; add_1 = 9..... The results are not what is expected. The reason is $random generates negative numbers also. The following example demonstrates proper way of generating a random number between 0 to 10. Concatenation operator returns only bit vector. Bit vectors are unsigned, so the results are correct as we expected. Verilog also has $unsigned systemtask to convert signed numbers to
用SystemVerilog验证赛灵思 FPGA

但通常并不会提供特别具有挑战性的向 量对其进行有针对性的测试。这里需要 的是有用的测试激励。我们建议先从最 简单的测试开始,即先检查设计的基本 功能。具体来说,我们的最初测试实例 就是在每个方向仅发送一个封包。发送 单个封包可以验证逻辑和物理层之间的 通信是正确的,并且测试平台本身也能 够正常运行。
SystemVerilog接口对内核信号进 行抽象,从而可以在测试平台和待测器 件(DUT)之间提供简单的连接。唯 一与内核接口通信的类是将事务转换为 向量的驱动器和将向量转换回事务监视 器。图1中用黑色实线表示基于向量的 接口。所有其它单元之间的连接都用灰 色虚线,代表基于事务的通信。在处理 向量流时,驱动器和监视器利用内建在 事务中的函数实现域和数据流之间的转 换,并且还使用比较(comparison)等 成员函数。
coverpoint din1_s; coverpoint din2_s; combos: cross din1_s, din2_s; endgroup
// overflow not allowed // on dout wire [WIDTH:0] tmp = din1 + din2; property p_dout_over;
4
赛灵思中国通讯 31 期
信号增加对应的输入端口。
最后一步是编写封装(wrapper) 模块,用来将验证模块绑定到现有 RTL模块。 SystemVerilog的关键字绑 定和固有的按名字连接(connect-byname)能力使得创建封装模块非常简 单。请注意,SystemVerilog并不支持 参数的隐含连接,因此在这一级必须 明确地将其作为端口调用。分层引用 (Hierarchical references)允许访问子 模块中的信号和参数。
面向硬件仿真的SystemVerilog断言检查电路生成研究

据, 一个 长度为 3的移 位 寄存 器 记 录信 号 b的历史
算 法 1显示 了把线性 序列转换 为硬 件检查 电路
数据 , 再使用 一个 长度 为 1的移 位 寄存 器来 记 录信 号 e的历史数 据 。 以下介绍 线性 序 列 的硬 件 检查 电路 综合 方 法 。
的具体 算法 。算法 中 , 入信 号 首先 通 过 它们 的位 输 置来搜 索 , 后计 算 各个 信 号 的深 度 。各个 信 号 的 然 深 度表示 在检 查 电路 中其移 位寄存器 链使 用的寄存
Ab t a t I hi a e ,a meh d t e r t a d r he k rcr u t r m y t mVe i g a s rin sr c : n t sp p r t o o g neae h r wa e c c e ic i fo S se s rl s eto s o frh r wa e e l t n i r p s d Th i de s t o sr t t e c e k r crui b s d o hf— o ad r mu ai s p o o e . o e man i a i o c n t h c e ic t a e n s i uc h t rg se h i I lo i to u e a me o o mi i z he h r wa e e o r e c n u t n b h rn e itrc an. t as nr d c t d t n mie t a d r r s u c o s mp i y s a g h o i
效性 。
关键词 : yt V r g Ss m el 断言;硬件仿真;检查电路 e i o
Ch c e ic s r i n e k r c r u t g n r to o y t m rl s e t o o
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
INTRODUCTIONIn this tutorial, we will verify the Switch RTL core. Following are the steps we follow to verify the Switch RTL core.1) Understand the specification2) Developing Verification Plan3) Building the Verification Environment. We will build the Environment in Multiple phases, so it will be easy for you to learn step by step.Phase 1) We will develop the testcase and interfaces, and integrate them in these with the DUT in top module.Phase 2) We will Develop the Environment class.Phase 3) We will develop reset and configuration methods in Environment class. Then using these methods, we will reset the DUT and configure the port address.Phase 4) We will develop a packet class based on the stimulus plan. We will also write a small code to test the packet class implementation.Phase 5) We will develop a driver class. Packets are generated and sent to DUT using driver.Phase 6) We will develop receiver class. Receiver collects the packets coming from the output port of the DUT.Phase 7) We will develop scoreboard class which does the comparison of the expected packet with the actual packet received from the DUT.Phase 8) We will develop coverage class based on the coverage plan.Phase 9) In this phase , we will write testcases and analyze the coverage report.SPECIFICATIONSwitch Specification:where the packet is driven out.Packet Format:Packet contains 3 parts. They are header, data and frame check sequence.Packet width is 8 bits and the length of the packet can be between 4 bytes to 259 bytes.Packet Header:Packet header contains three fields DA, SA and length.DA: Destination address of the packet is of 8 bits. The switch drives the packet to respective ports based on this destination address of the packets. Each output port has 8-bit unique port address. If the destination address of the packet matches the port address, then switch drives the packet to the output port.SA: Source address of the packet from where it originate. It is 8 bits.Length: Length of the data is of 8 bits and from 0 to 255. Length is measured in terms of bytes.If Length = 0, it means data length is 0 bytesIf Length = 1, it means data length is 1 bytesIf Length = 2, it means data length is 2 bytesIf Length = 255, it means data length is 255 bytesData: Data should be in terms of bytes and can take anything.FCS: Frame check sequenceThis field contains the security check of the packet. It is calculated over the header and data.Configuration:Switch has four output ports. These output ports address have to be configured to a unique address. Switch matches the DA field of the packet with this configured port address and sends the packet on to that port. Switch contains a memory. This memory has 4 locations, each can store 8 bits. To configure the switch port address, memory write operation has to be done using memory interface. Memory address (0,1,2,3) contains the address of port(0,1,2,3) respectively.Interface Specification:The Switch has one input Interface, from where the packet enters and 4 output interfaces from where the packet comes out and one memory interface, through the port address can be configured. Switch also has a clock and asynchronous reset signal.Memory Interface:Through memory interfaced output port address are configured. It accepts 8 bit data to be written to memory. It has 8 bit address inputs. Address 0,1,2,3 contains the address of the port 0,1,2,3 respectively.There are 4 input signals to memory interface. They areinput mem_en;input mem_rd_wr;input[1:0] mem_add;input[7:0] mem_data;All the signals are active high and are synchronous to the positive edge of clock signal. To configure a port address,1. Assert the mem_en signal.2. Asser the mem_rd_wr signal.3. Drive the port number (0 or 1 or 2 or 3) on the mem_add signal4. Drive the 8 bit port address on to mem_data signal.Input PortPackets are sent into the switch using input port.All the signals are active high and are synchronous to the positive edge of clock signal. input port has 2input signals. They areinput[7:0]data;input data_status;To send the packet in to switch,1. Assert the data_status signal.2. Send the packet on the data signal byte by byte.3. After sending all the data bytes, deassert the data_status signal.4. There should be at least 3 clock cycles difference between packets.Output Portport_* signal after one clock cycle.VERIFICATION PLANOverviewThis Document describes the Verification Plan for Switch. The Verification Plan is based on System Verilog Hardware Verification Language. The methodology used for Verification is Constraint random coverage driven verification.Feature ExtractionThis section contains list of all the features to be verified.1)ID: ConfigurationDescription: Configure all the 4 port address with unique values.2)ID: Packet DADescription: DA field of packet should be any of the port address. All the 4 port address should be used.3)ID : Packet payloadDescription: Length can be from 0 to 255. Send packets with all the lengths.4)ID: LengthDescription:Length field contains length of the payload.Send Packet with correct length field and incorrect length fields.5)ID: FCSDescription:Good FCS: Send packet with good FCS.Bad FCS: Send packet with corrupted FCS.Stimulus Generation Plan1) Packet DA: Generate packet DA with the configured address.2) Payload length: generate payload length ranging from 2 to 255.3) Correct or Incorrect Length field.4) Generate good and bad FCS.Coverage Plan1) Cover all the port address configurations.2) Cover all the packet lengths.3) Cover all correct and incorrect length fields.4) Cover good and bad FCS.5) Cover all the above combinations.Verification EnvironmentPHASE 1 TOPIn phase 1,1) We will write SystemVerilog Interfaces for input port, output port and memory port.2) We will write Top module where testcase and DUT instances are done.3) DUT and TestBench interfaces are connected in top module.4) Clock is generator in top module.NOTE: In every file you will see the syntax`ifndef GUARD_*`endif GUARD_*InterfacesIn the interface.sv file, declare the 3 interfaces in the following way.All the interfaces has clock as input.All the signals in interface are logic type.All the signals are synchronized to clock except reset in clocking block.Signal directional w.r.t TestBench is specified with modport.`ifndef GUARD_INTERFACE`define GUARD_INTERFACE//////////////////////////////////////////// Interface declaration for the memory/////////////////////////////////////////////interface mem_interface(input bit clock);logic[7:0] mem_data;logic[1:0] mem_add;logic mem_en;logic mem_rd_wr;clocking cb@(posedge clock);default input#1output#1;output mem_data;output mem_add;output mem_en;output mem_rd_wr;endclockingmodport MEM(clocking cb,input clock);endinterface////////////////////////////////////////////// Interface for the input side of switch.//// Reset signal is also passed hear. ////////////////////////////////////////////// interface input_interface(input bit clock);logic data_status;logic[7:0] data_in;logic reset;clocking cb@(posedge clock);default input#1output#1;output data_status;output data_in;endclockingmodport IP(clocking cb,output reset,input clock); endinterface///////////////////////////////////////////////// // Interface for the output side of the switch.//// output_interface is for only one output port/////////////////////////////////////////////////// interface output_interface(input bit clock);logic[7:0] data_out;logic ready;logic read;clocking cb@(posedge clock);default input#1output#1;input data_out;input ready;output read;endclockingmodport OP(clocking cb,input clock);endinterface//////////////////////////////////////////////////`endifTestcaseTestcase is a program block which provides an entry point for the test and creates a scope that encapsulates program-wide data. Currently this is an empty testcase which just ends the simulation after 100 time units. Program block contains all the above declared interfaces as arguments. This testcase has initial and final blocks.`ifndef GUARD_TESTCASE`define GUARD_TESTCASEprogram testcase(mem_interface.MEM mem_intf,input_interface.IP input_intf,output_i nterface.OP output_intf[4]);initialbegin$display(" ******************* Start of testcase ****************");#1000;endfinal$display(" ******************** End of testcase *****************");endprogram`endifTop ModuleThe modules that are included in the source text but are not instantiated are called top modules. This module is the highest scope of modules. Generally this module is named as "top" and referenced as "top module". Module name can be anything.Do the following in the top module:1)Generate the clock signal.bit Clock;initialforever#10 Clock =~Clock;2)Do the instances of memory interface.mem_interface mem_intf(Clock);3)Do the instances of input interface.input_interface input_intf(Clock);4)There are 4 output ports. So do 4 instances of output_interface.output_interface output_intf[4](Clock);5)Do the instance of testcase and pass all the above declared interfaces.testcase TC(mem_intf,input_intf,output_intf);6)Do the instance of DUT.switch DUT7)Connect all the interfaces and DUT. The design which we have taken is in verilog. So Verilog DUT instance is connected signal by signal.switch DUT(.clk(Clock),.reset(input_intf.reset),.data_status(input_intf.data_status),.data(input_intf.data_in),.port0(output_intf[0].data_out),.port1(output_intf[1].data_out),.port2(output_intf[2].data_out),.port3(output_intf[3].data_out),.ready_0(output_intf[0].ready),.ready_1(output_intf[1].ready),.ready_2(output_intf[2].ready),.ready_3(output_intf[3].ready),.read_0(output_intf[0].read),.read_1(output_intf[1].read),.read_2(output_intf[2].read),.read_3(output_intf[3].read),.mem_en(mem_intf.mem_en),.mem_rd_wr(mem_intf.mem_rd_wr),.mem_add(mem_intf.mem_add),.mem_data(mem_intf.mem_data));Top Module Source Code:`ifndef GUARD_TOP`define GUARD_TOPmodule top();///////////////////////////////////////////////////// // Clock Declaration and Generation /////////////////////////////////////////////////////// bit Clock;initialforever#10 Clock =~Clock;///////////////////////////////////////////////////// // Memory interface instance /////////////////////////////////////////////////////// mem_interface mem_intf(Clock);///////////////////////////////////////////////////// // Input interface instance /////////////////////////////////////////////////////// input_interface input_intf(Clock);///////////////////////////////////////////////////// // output interface instance /////////////////////////////////////////////////////// output_interface output_intf[4](Clock);///////////////////////////////////////////////////// // Program block Testcase instance /////////////////////////////////////////////////////// testcase TC(mem_intf,input_intf,output_intf);///////////////////////////////////////////////////// // DUT instance and signal connection ///////////////////////////////////////////////////////switch DUT(.clk(Clock),.reset(input_intf.reset),.data_status(input_intf.data_status),.data(input_intf.data_in),.port0(output_intf[0].data_out),.port1(output_intf[1].data_out),.port2(output_intf[2].data_out),.port3(output_intf[3].data_out),.ready_0(output_intf[0].ready),.ready_1(output_intf[1].ready),.ready_2(output_intf[2].ready),.ready_3(output_intf[3].ready),.read_0(output_intf[0].read),.read_1(output_intf[1].read),.read_2(output_intf[2].read),.read_3(output_intf[3].read),.mem_en(mem_intf.mem_en),.mem_rd_wr(mem_intf.mem_rd_wr), .mem_add(mem_intf.mem_add),.mem_data(mem_intf.mem_data)); endmodule`endif(S)Run the simulation:PHASE 2 ENVIRONMENTIn this phase, we will writeEnvironment class.Virtual interface declaration.Defining Environment class constructor.Defining required methods for execution. Currently these methods will not be implemented in this phase.All the above are done in Environment.sv file.We will write a testcase using the above define environment class in testcase.sv file.Environment Class:The class is a base class used to implement verification environments. Testcase contains the instance of the environment class and has access to all the public declaration of environment class.All methods are declared as virtual methods. In environment class, we will formalize the simulation steps using virtual methods. The methods are used to control the execution of the simulation.Following are the methods which are going to be defined in environment class.1) new() : In constructor method, we will connect the virtual interfaces which are passed as argument to the virtual interfaces to those which are declared in environment class.2) build(): In this method , all the objects like driver, monitor etc are constructed. Currently this method is empty as we did not develop any other component.3) reset(): in this method we will reset the DUT.4) cfg_dut(): In this method, we will configure the DUT output port address.5) start(): in this method, we will call the methods which are declared in the othercomponents like driver and monitor.6) wait_for_end(): this method is used to wait for the end of the simulation. Waits until all the required operations in other components are done.7) report(): This method is used to print the TestPass and TestFail status of the simulation, based on the error count..8) run(): This method calls all the above declared methods in a sequence order. The testcase calls this method, to start the simulation.We are not implementing build(), reset(), cfg_dut() , strat() and report() methods in this phase.Connecting the virtual interfaces of Environment class to the physical interfaces of top module.Verification environment contains the declarations of the virtual interfaces. Virtual interfaces are just a handles(like pointers). When a virtual interface is declared, it only creats a handle. It doesnot creat a real interface.Constructor method should be declared with virtual interface as arguments, so that when the object is created in testcase, new() method can pass the interfaces in to environment class where they are assigned to the local virtual interface handle. With this, the Environment class virtual interfaces are pointed to the physical interfaces which are declared in the top module.Declare virtual interfaces in Environment class.virtual mem_interface.MEM mem_intf ;virtual input_interface.IP input_intf ;virtual output_interface.OP output_intf[4];The construction of Environment class is declared with virtual interface as arguments.function new(virtual mem_interface.MEM mem_intf_new ,virtual input_interface.IP input_intf_new ,virtual output_interface.OP output_intf_new[4]);In constructor methods, the interfaces which are arguments are connected to the virtual interfaces of environment class.this.mem_intf = mem_intf_new ;this.input_intf = input_intf_new ;this.output_intf = output_intf_new ;Run :The run() method is called from the testcase to start the simulation. run() method calls all the methods which are defined in the Environment class.task run();$display(" %0d : Environment : start of run() method",$time); build();reset();cfg_dut();start();wait_for_end();report();$display(" %0d : Environment : end of run() method",$time); endtask: runEnvironment Class Source Code:`ifndef GUARD_ENV`define GUARD_ENVclass Environment ;virtual mem_interface.MEM mem_intf ;virtual input_interface.IP input_intf ;virtual output_interface.OP output_intf[4];function new(virtual mem_interface.MEM mem_intf_new ,virtual input_interface.IP input_intf_new ,virtual output_interface.OP output_intf_new[4]);this.mem_intf = mem_intf_new ;this.input_intf = input_intf_new ;this.output_intf = output_intf_new ;$display(" %0d : Environment : created env object",$time); endfunction:newfunction void build();$display(" %0d : Environment : start of build() method",$time); $display(" %0d : Environment : end of build() method",$time); endfunction:buildtask reset();$display(" %0d : Environment : start of reset() method",$time); $display(" %0d : Environment : end of reset() method",$time); endtask: resettask cfg_dut();$display(" %0d : Environment : start of cfg_dut() method",$time); $display(" %0d : Environment : end of cfg_dut() method",$time); endtask: cfg_duttask start();$display(" %0d : Environment : start of start() method",$time); $display(" %0d : Environment : end of start() method",$time); endtask:starttask wait_for_end();$display(" %0d : Environment : start of wait_for_end() method",$time); $display(" %0d : Environment : end of wait_for_end() method",$time); endtask: wait_for_endtask run();$display(" %0d : Environment : start of run() method",$time);build();reset();cfg_dut();start();wait_for_end();report();$display(" %0d : Environment : end of run() method",$time);endtask: runtask report();endtask: reportendclass`endifWe will create a file Global.sv for global requirement. In this file, define all the port address as macros in this file. Define a variable error as integer to keep track the number of errors occurred during the simulation.`ifndef GUARD_GLOBALS`define GUARD_GLOBALS`define P08'h00`define P18'h11`define P28'h22`define P38'h33int error =0;int num_of_pkts =10;`endifNow we will update the testcase. Take an instance of the Environment class and call the run method of the Environment class.`ifndef GUARD_TESTCASE`define GUARD_TESTCASEprogram testcase(mem_interface.MEM mem_intf,input_interface.IP input_intf,output_interface.OP output_intf[4]);Environment env;initialbegin$display(" ******************* Start of testcase ****************");env =new(mem_intf,input_intf,output_intf);env.run();#1000;endfinal$display(" ******************** End of testcase *****************");endprogram`endif(S)Run the simulation:(S)Log report after the simulation:******************* Start of testcase ****************0 : Environemnt : created env object0 : Environemnt : start of run() method0 : Environemnt : start of build() method0 : Environemnt : end of build() method0 : Environemnt : start of reset() method0 : Environemnt : end of reset() method0 : Environemnt : start of cfg_dut() method0 : Environemnt : end of cfg_dut() method0 : Environemnt : start of start() method0 : Environemnt : end of start() method0 : Environemnt : start of wait_for_end() method 0 : Environemnt : end of wait_for_end() method 0 : Environemnt : end of run() method******************** End of testcase *****************PHASE 3 RESETIn this phase we will reset and configure the DUT.The Environment class has reset() method which contains the logic to reset the DUT and cfg_dut() method which contains the logic to configure the DUT port address.NOTE: Clocking block signals can be driven only using a non-blocking assignment.Define the reset() method.1) Set all the DUT input signals to a known state.mem_intf.cb.mem_data <=0;mem_intf.cb.mem_add <=0;mem_intf.cb.mem_en <=0;mem_intf.cb.mem_rd_wr <=0;input_intf.cb.data_in <=0;input_intf.cb.data_status <=0;output_intf[0].cb.read <=0;output_intf[1].cb.read <=0;output_intf[2].cb.read <=0;output_intf[3].cb.read <=0;2) Reset the DUT.// Reset the DUTinput_intf.reset <=1;repeat(4)@ input_intf.clock;input_intf.reset <=0;3) Updated the cfg_dut method.task cfg_dut();$display(" %0d : Environment : start of cfg_dut() method",$time);mem_intf.cb.mem_en <=1;@(posedge mem_intf.clock);mem_intf.cb.mem_rd_wr <=1;@(posedge mem_intf.clock);mem_intf.cb.mem_add <=8'h0;mem_intf.cb.mem_data <=`P0;$display(" %0d : Environment : Port 0 Address %h ",$time,`P0);@(posedge mem_intf.clock);mem_intf.cb.mem_add <=8'h1;mem_intf.cb.mem_data <=`P1;$display(" %0d : Environment : Port 1 Address %h ",$time,`P1);@(posedge mem_intf.clock);mem_intf.cb.mem_add <=8'h2;mem_intf.cb.mem_data <=`P2;$display(" %0d : Environment : Port 2 Address %h ",$time,`P2);@(posedge mem_intf.clock);mem_intf.cb.mem_add <=8'h3;mem_intf.cb.mem_data <=`P3;$display(" %0d : Environment : Port 3 Address %h ",$time,`P3);@(posedge mem_intf.clock);mem_intf.cb.mem_en <=0;mem_intf.cb.mem_rd_wr <=0;mem_intf.cb.mem_add <=0;mem_intf.cb.mem_data <=0;$display(" %0d : Environment : end of cfg_dut() method",$time); endtask: cfg_dut(4) In wait_for_end method, wait for some clock cycles.task wait_for_end();$display(" %0d : Environment : start of wait_for_end() method",$time); repeat(10000)@(input_intf.clock);$display(" %0d : Environment : end of wait_for_end() method",$time); endtask: wait_for_end(S)Run the simulation:(S)Log File report******************* Start of testcase ****************0 : Environment : created env object0 : Environment : start of run() method0 : Environment : start of build() method0 : Environment : end of build() method0 : Environment : start of reset() method40 : Environment : end of reset() method40 : Environment : start of cfg_dut() method70 : Environment : Port 0 Address 0090 : Environment : Port 1 Address 11110 : Environment : Port 2 Address 22130 : Environment : Port 3 Address 33150 : Environment : end of cfg_dut() method150 : Environment : start of start() method150 : Environment : end of start() method150 : Environment : start of wait_for_end() method100150 : Environment : end of wait_for_end() method100150 : Environment : end of run() method******************** End of testcase *****************PHASE 4 PACKETIn this Phase, We will define a packet and then test it whether it is generating as expected.Packet is modeled using class. Packet class should be able to generate all possible packet types randomly. Packet class should also implement required methods like packing(), unpacking(), compare() and display() methods.We will write the packet class in packet.sv file. Packet class variables and constraints have been derived from stimulus generation plan.Revisit Stimulus Generation Plan1) Packet DA: Generate packet DA with the configured address.2) Payload length: generate payload length ranging from 2 to 255.3) Correct or Incorrect Length field.4) Generate good and bad FCS.1) Declare FCS types as enumerated data types. Name members as GOOD_FCS and BAD_FCS.typedef enum{GOOD_FCS,BAD_FCS} fcs_kind_t;2) Declare the length type as enumerated data type. Name members as GOOD_LENGTH and BAD_LENGTH.typedef enum{GOOD_LENGTH,BAD_LENGTH} length_kind_t;3) Declare the length type and fcs type variables as rand.rand fcs_kind_t fcs_kind;rand length_kind_t length_kind;4) Declare the packet field as rand. All fields are bit data types. All fields are 8 bit packet array. Declare the payload as dynamic array.rand bit[7:0] length;rand bit[7:0] da;rand bit[7:0] sa;rand byte data[];//Payload using Dynamic array,size is generated on the flyrand byte fcs;5) Constraint the DA field to be any one of the configured address.constraint address_c { da inside{`P0,`P1,`P2,`P3};}6) Constrain the payload dynamic array size to between 1 to 255.constraint payload_size_c {data.size inside{[1:255]};}7) Constrain the payload length to the length field based on the length type.constraint length_kind_c {(length_kind ==GOOD_LENGTH)-> length ==data.size;(length_kind ==BAD_LENGTH)-> length ==data.size+2;}Use solve before to direct the randomization to generate first the payload dynamic array size and then randomize length field.constraint solve_size_length {solve data.size before length;}8) Constrain the FCS field initial value based on the fcs kind field.constraint fcs_kind_c {(fcs_kind ==GOOD_FCS)-> fcs ==8'b0;(fcs_kind ==BAD_FCS)-> fcs ==8'b1;}9) Define the FCS method.function byte cal_fcs;integer i;byte result ;result =0;result = result ^ da;result = result ^ sa;result = result ^ length;for(i =0;i<data.size;i++)result = result ^data[i];result = fcs ^ result;return result;endfunction: cal_fcs10) Define display methods:Display method displays the current value of the packet fields to standard output.virtual function void display();$display("\n---------------------- PACKET KIND ------------------------- ");$display(" fcs_kind : %s ",fcs_());$display(" length_kind : %s ",length_());$display("-------- PACKET ---------- ");$display(" 0 : %h ",da);$display(" 1 : %h ",sa);$display(" 2 : %h ",length);foreach(data[i])$write("%3d : %0h ",i +3,data[i]);$display("\n %2d : %h ",data.size()+3, cal_fcs);$display("----------------------------------------------------------- \n");endfunction: display11) Define pack method:Packing is commonly used to convert the high level data to low level data that can be applied to DUT. In packet class various fields are generated. Required fields are concatenated to form a stream of bytes which can be driven conveniently to DUTinterface by the driver.virtual function int unsigned byte_pack(ref logic[7:0] bytes[]);bytes =new[data.size+4];bytes[0]= da;bytes[1]= sa;bytes[2]= length;foreach(data[i])bytes[3+ i]=data[i];bytes[data.size()+3]= cal_fcs;byte_pack = bytes.size;endfunction: byte_pack12) Define unpack method:The unpack() method does exactly the opposite of pack method. Unpacking is commonly used to convert a data stream coming from DUT to high level data packet object.virtual function void byte_unpack(const ref logic[7:0] bytes[]);this.da = bytes[0];this.sa = bytes[1];this.length = bytes[2];this.fcs = bytes[bytes.size-1];this.data=new[bytes.size-4];foreach(data[i])data[i]= bytes[i +3];this.fcs =0;if(bytes[bytes.size-1]!= cal_fcs)this.fcs =1;endfunction: byte_unpack14) Define a compare method.Compares the current value of the object instance with the current value of the specified object instance.If the value is different, FALSE is returned.virtual function bit compare(packet pkt);compare=1;if(pkt ==null)begin$display(" ** ERROR ** : pkt : received a null object ");compare=0;endelsebeginif(pkt.da !==this.da)begin$display(" ** ERROR **: pkt : Da field did not match");compare=0;endif(pkt.sa !==this.sa)begin$display(" ** ERROR **: pkt : Sa field did not match");compare=0;endif(pkt.length !==this.length)begin$display(" ** ERROR **: pkt : Length field did not match");compare=0;endforeach(this.data[i])if(pkt.data[i]!==this.data[i])begin。