system verilog 初探
systemverilog search()用法

systemverilog search()用法SystemVerilog search()用法SystemVerilog的search()函数是一种用于在字符串中搜索子字符串的强大工具。
它可以在字符串中定位目标子字符串,并返回其出现的位置。
在本文中,我将介绍search()函数的一些常见用法,并提供详细的解释。
1. search()函数的基本用法search()函数的基本语法如下:int search(string haystack, string needle);其中,haystack是要搜索的字符串,needle是目标子字符串。
search()函数返回目标子字符串在搜索字符串中的位置,如果找不到目标子字符串,则返回-1。
以下是search()函数的一个简单示例:string s = "Hello World";int pos = search(s, "World");在上述代码中,search()函数将在字符串s中搜索子字符串”World”。
如果找到该子字符串,则将返回它在字符串中的位置。
在本例中,pos将被赋值为6,表示”World”在字符串中的起始位置。
2. search()函数的高级用法搜索多个目标子字符串search()函数允许同时搜索多个目标子字符串。
你可以使用竖线(|)将这些目标子字符串分隔开。
以下是一个示例:string s = "Hello World";int pos = search(s, "Hello | World");在上述示例中,search()函数将在字符串中搜索”Hello”或”World”。
如果找到任何一个目标子字符串,则将返回它在字符串中的位置。
在这个例子中,pos将被赋值为0,表示”Hello”在字符串中的起始位置。
指定搜索的起始位置通过使用第三个参数,你可以指定search()函数开始搜索的位置。
SystemVerilog介绍

3
Copyright@Chang Gung University 2009
SystemVerilog的特性
• Interface簡化 • 資料型態的增加 • 驗證層級提升
4
Copyright@Chang Gung University 2009
SystemVerilog的特性
• Interface簡化
17
Copyright@Chang Gung University 2009
SystemVerilog與Verilog的語法比較
• $fflush
– 用來清空緩衝區的資料。 module top; integer fid,n,r; reg [639:0] str; initial begin fid = $fopen("./test.txt","r"); for(n=0;n<2;n=n+1) begin $fgets(str,fid); $display("Line=%s",str); //$fflush(fid);
Copyright@Chang Gung University 2009
cloes file
test if end of file
16
SystemVerilog與Verilog的語法比較
• $ferror
– 當讀取檔案發生錯誤時,會回傳error code讓我們知道原 因。
module top; integer errno,fid; reg [639:0] str; initial begin fid = $fopen("./test1.txt","r"); #5; errno = $ferror (fid,str); $display("errno:=%d",errno); end
system verilog 标准

系统Verilog是一种硬件描述语言(HDL),用于描述数字电路。
它包含了Verilog的所有特性,并添加了一些新的特性。
这些新的特性包括在设计中引入了数据类型的定义,更好地支持设计的抽象,以及更自然地支持设计的层次式描述。
在本文中,我们将深入了解System Verilog标准。
1. 介绍System Verilog标准System Verilog是IEEE标准1800,最初是由Accellera组织进行开发的。
它于2005年发行,是Verilog HDL的扩展,它添加了许多新的特性,使得它更适合于硬件验证和设计。
2. System Verilog的特性System Verilog添加了许多新的特性,以提高Verilog HDL的功能。
其中一些主要特性包括:a. 对象导向编程:System Verilog引入了面向对象的编程范式,使得设计和验证更加抽象和灵活。
b. 增强了数据类型和操作:System Verilog引入了更多的数据类型和操作,更好地支持设计和验证的需求。
c. 增加了随机性:System Verilog引入了随机性,使得验证更加全面和高效。
3. System Verilog在硬件验证中的应用System Verilog的特性使得它在硬件验证中应用广泛。
它提供了丰富的验证方法和工具,包括:a. 事务级建模(TLM):System Verilog提供了TLM的支持,使得验证更加抽象和高效。
b. Constrained随机验证:System Verilog引入了constrained random的验证方法,使得验证更加全面和高效。
c. Coverage驱动验证:System Verilog提供了coverage驱动的验证方法,使得验证更加全面和高效。
4. System Verilog在硬件设计中的应用除了在硬件验证中应用广泛外,System Verilog在硬件设计中也有着广泛的应用。
SystemVerilog语言知识介绍

SystemVerilog语言知识介绍SystemVerilog是一种硬件描述与验证语言(HDVL),它基于IEEE 1364-2001 Verilog硬件描述语言(HDL),并对其进行了扩展,包含扩充了C语言数据类型、结构、压缩与非压缩数组、接口、断言等等,这些都使得SystemVeri log在一个更高的抽象层次上提高了设计建模的能力。
Syst emVerilog由Accellera开发,它要紧定位在芯片的实现与验证流程上,并为系统级的设计流程提供了强大的连接能力。
下面我们从几个方面对SystemVerilog所作的增强进行简要的介绍,期望能够通过这个介绍使大家对SystemVeril og有一个概括性的熟悉。
1. 接口(Interface)Verilog模块之间的连接是通过模块端口进行的。
为了给构成设计的各个模块定义端口,我们务必对期望的硬件设计有一个全面的认识。
不幸的是,在设计的早期,我们很难把握设计的细节。
而且,一旦模块的端口定义完成后,我们也很难改变端口的配置。
另外,一个设计中的许多模块往往具有相同的端口定义,在Verilog中,我们务必在每个模块中进行相同的定义,这为我们增加了无谓的工作量。
SystemVerilog提供了一个新的、高层抽象的模块连接,这个连接被称之接口(Interface)。
接口在关键字interfac e与endinterface之间定义,它独立于模块。
接口在模块中就像一个单一的端口一样使用。
在最简单的形式下,一个接口能够认为是一组线网。
比如,能够将PCI总线的所有信号绑定在一起构成一个接口。
通过使用接口,我们在进行一个设计的时候能够不需要首先建立各个模块间的互连。
随着设计的深入,各个设计细节也会变得越来越清晰,而接口内的信号也会很容易地表示出来。
当接口发生变化时,这些变化也会在使用该接口的所有模块中反映出来,而无需更换每一个模块。
下面是一个接口的使用实例:实际上,SystemVerilog的接口不仅仅能够表示信号的绑定与互连。
systemverilog 实验

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。
systemverilog类的方法

systemverilog类的方法SystemVerilog类的方法SystemVerilog是一种硬件描述语言,用于设计和验证数字电路。
在SystemVerilog中,类是一种重要的概念,用于组织和封装代码。
类中的方法是实现类功能的关键部分。
本文将介绍一些常见的SystemVerilog类的方法。
1. 构造函数(Constructor)构造函数是一种特殊的方法,用于在创建类的实例时初始化对象的成员变量。
它的名称与类名相同,并且没有返回类型。
构造函数可以有参数,用于传递初始化值。
例如,一个名为"myClass"的类的构造函数可以如下所示:```systemverilogclass myClass;int data;function new(int value);data = value;endfunctionendclass```在实例化类时,可以通过传递参数来调用构造函数,并初始化对象的成员变量。
```systemverilogmyClass obj = new(10);```2. 成员函数(Member Function)成员函数是定义在类中的方法,可以操作类的成员变量,并实现类的功能。
成员函数可以有返回值和参数。
例如,一个名为"add"的成员函数可以如下所示:```systemverilogclass myClass;int data;function int add(int value);data += value;return data;endfunctionendclass```在类的实例上调用成员函数时,可以使用"."运算符来访问该函数,并传递参数。
例如:```systemverilogmyClass obj;obj.add(5);```3. 静态函数(Static Function)静态函数是定义在类中的方法,不依赖于类的实例,可以直接通过类名调用。
systemverilog验证方法

systemverilog验证方法SystemVerilog验证方法引言在现代芯片设计中,验证是一个非常重要的环节。
SystemVerilog 是一种常用的硬件描述语言,有许多验证方法可以帮助设计人员有效验证设计的正确性。
本文将详细介绍一些常用的SystemVerilog验证方法。
1.仿真验证方法•使用仿真工具进行功能验证–利用Simulator工具来模拟设计行为以进行功能验证。
验证工程师可以编写testbench来生成输入数据,驱动设计的输出,并进行断言验证。
–通过创建各种激励来测试设计中的不同情况,包括边界情况、异常情况和极端情况等。
•波形分析验证–利用仿真工具生成波形,并分析波形来验证设计的正确性。
可以检查信号的时序关系、逻辑等,并比较期望结果和实际结果。
波形分析验证可以在不同抽象级别进行,包括电平验证、逻辑状态验证和功能验证等。
2.形式验证方法形式验证是一种使用形式工具来验证设计是否满足规范的方法。
形式工具基于设计的数学模型进行验证,可以全面而快速地验证设计的正确性。
•模型检查方法–使用形式工具对设计进行形式化建模,并使用模型检查器来验证设计是否满足特定的属性。
设计人员需要编写属性规范来描述设计的期望行为,并利用模型检查器来自动验证属性是否满足。
•定理证明方法–使用形式工具来进行数学定理的证明来验证设计的正确性。
设计人员需要将设计抽象为一个形式化的数学模型,并利用定理证明器来验证设计是否满足特定的性质。
3.边界扫描方法边界扫描方法是一种将设计周围的接口边界进行扫描以验证设计的方法。
•验证接口协议–针对设计中使用的接口协议,可以编写验证环境来验证接口协议是否正确地被设计所遵循。
验证环境可以利用随机算法生成各种接口交互情况,并验证设计的响应是否满足接口协议规定的规范。
•验证接口互连–针对设计中的各个接口之间的互连,可以编写验证环境来验证互连是否满足设计的要求。
验证环境可以生成接口交互的各种情况,并验证互连的正确性和稳定性。
SystemVerilog语言知识介绍

SystemVerilog语言知识介绍1. 对面向对象编程(OOP)的支持:SystemVerilog引入了类和对象的概念,使得设计和验证更加模块化和可重用。
类可以包含数据成员和成员函数,可以继承和多态,从而使设计更加灵活和可扩展。
2. 接口:SystemVerilog引入了接口的概念,用于定义组件之间的通信和互连。
接口可以包含信号和方法,可以被多个模块实例化和连接在一起,从而简化了设计和验证的过程。
3. 任务和函数:SystemVerilog支持任务和函数的定义,用于执行一些特定的操作和计算。
任务是并发执行的,可以用于模拟硬件行为。
函数可以返回一个值,可以用于计算逻辑和数据处理。
4. 动态数组:SystemVerilog引入了动态数组的概念,可以在运行时动态地分配和管理内存。
这对于处理变长数据结构(如队列和堆栈)非常有用,同时也可以简化设计和验证的过程。
5. 时序建模:SystemVerilog提供了一些特性,用于描述和模拟数字系统中的时序行为。
例如,可以使用时钟、触发器和延迟来定义和控制信号的时序关系。
这使得设计和验证更加准确和可靠。
6. 断言:SystemVerilog引入了断言的概念,用于描述和验证设计的一些属性和约束。
断言可以在运行时检查设计的正确性,并在出现错误时提供错误信息。
这对于设计和验证的调试和验证非常有用。
除了以上特性,SystemVerilog还具有一些其他的功能,如并行块、并行循环、封装和配置等。
这些功能都使得SystemVerilog成为一个强大而灵活的硬件描述语言,广泛应用于数字系统的设计和验证。
总的来说,SystemVerilog是一种用于硬件设计和验证的高级硬件描述语言。
它具有面向对象编程的特性,支持接口、任务和函数,提供动态数组和时序建模等功能。
它的强大和灵活性使得它成为了工业界和学术界广泛使用的硬件描述语言之一。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
system verilog 初探转载地址:/windzjy/310477/Message.aspx#转载请声明:/Blog/post.aspx?id=310477这是一个sv的验证平台的基本框架,自己画的,对错待证!1,关于clocking block举例如下:待证设计module COUNTER (input Clock, Reset, Enable, Load, UpDn, input [7:0] Data, output reg[7:0] Q); always @(posedge Clock or posedge Reset)if (Reset)Q <= 0;else if (Enable)beginif (Load)Q <= Data;else if (UpDn)Q <= Q + 1;elseQ <= Q - 1;endendmoduletestbench:module Test_Counter_w_clocking;timeunit 1ns;reg Clock = 0, Reset, Enable, Load, UpDn;reg [7:0] Data;wire [7:0] Q;// Clock generatoralwaysbegin#5 Clock = 1;#5 Clock = 0;end// Test programprogram test_counter;// SystemVerilog "clocking block"// Clocking outputs are DUT inputs and vice versaclocking cb_counter @(posedge Clock);default input #1step output #4;output negedge Reset;output Enable, Load, UpDn, Data;input Q;endclocking // Apply the test stimulusinitial begin// Set all inputs at the beginningEnable = 0;Load = 0;UpDn = 1;Reset = 1;##1 cb_counter.Reset <= 0; // Will be applied 4ns after the clock!##1 cb_counter.Enable <= 1;##2 cb_counter.UpDn <= 0;##4 cb_counter.UpDn <= 1;// etc. ...end// Check the results - could combine with stimulus blockinitialbegin##1 // Sampled 1ps (or whatever the precision is) before posedge clock##1 assert (cb_counter.Q == 8'b00000000);##1 assert (cb_counter.Q == 8'b00000000);##2 assert (cb_counter.Q == 8'b00000010);##4 assert (cb_counter.Q == 8'b11111110);// etc. ... end // Simulation stops automatically when both initials have been completed endprogram// Instance the counterCOUNTER G1 (Clock, Reset, Enable, Load, UpDn, Data, Q);// Instance the test program - not required, because program will be// instanced implicitly.// test_COUNTER T1 ();endmodule自己分析的时序,如下图所示:1,接口interface chip_bus; // 定义接口wire read_request, read_grant;wire [7:0] address, data;endinterface: chip_busmodule RAM (chip_bus io, // 使用接口input clk);// 可以使用io.read_request引用接口中的一个信号endmodulemodule CPU(chip_bus io, input clk);...endmodule就像一个数据类型一样,可以用它来定义,或者说引用?2,如果某些变量、函数或其它信息被设计中的所有模块共享,那么我们就可以将它们作为全局声明和语句。
全局声明和语句的一个使用实例如下:reg error _flag; // 全局变量function compare (...); // 全局函数always @(error_flag) // 全局语句...module test;chip1 u1 (...)endmodulemodule chip1 (...);FSM u2 (...);always @(data)error_flag = compare(data, expected);endmodulemodule FSM (...);...always @(state)error_flag = compare(state, expected);endmodule3,抽象数据类型charintshortintlongintbytebitlogic,4 statesshortrealvoidlogic类型能够以下面的任何一种方法赋值:a,通过任意数目的过程赋值语句赋值,能够替代Verilog的reg类型;b,通过单一的连续赋值语句赋值,能够有限制地替代Verilog的wire类型;c,连接到一个单一原语的输出,能够有限制地替代Verilog的wire类型;4,用户定义的数据类型SystemVerilog通过使用typedef提供了一种方法来定义新的数据类型,这一点与C语言类似。
用户定义的类型可以与其它数据类型一样地使用在声明当中。
例如:typedef unsigned int uint;uint a, b;5,枚举类型值从初始值0开始递增,但是我们可以显式地指定初始值。
枚举类型的例子如下:enum {red, yellow, green} RGB;enum {WAIT=2’b01, LOAD, DONE} states;我们还可以使用typedef为枚举类型指定一个名字,从而允许这个枚举类型可以在许多地方使用。
例如:typedef enum {FALSE=1’b0, TRUE} boolean;boolean ready;boolean test_complete;6,结构体和联合体在Verilog语言中不存在结构体或联合体,而结构体或联合体在将几个声明组合在一起的时候非常有用。
SystemVerilog增加了结构体和联合体,它们的声明语法类似于C。
struct {reg [15:0] opcode;reg [23:0] addr;} IR;union {int I;shortreal f;} N;结构体或联合体中的域可以通过在变量名和域名字之间插入句点(.)来引用:IR.opcode = 1; // 设置IR变量中的opcode域N.f = 0.0; // 将N设置成浮点数的值我们可以使用typedef为结构体或联合体的定义指定一个名字。
typedef struct {reg [7:0] opcode;reg [23:0] addr;} instruction; // 命名的结构体instruction IR; // 结构体实例一个结构体可以使用值的级联来完整地赋值,例如:instruction = {5, 200}; //IR = {5,200}???jyz结构体可以作为一个整体传递到函数或任务,也可以从函数或任务传递过来,也可以作为模块端口进行传递。
7,数组8,assertionsassert (A == B); // Asserts that A equals B; if not, an error is generated就是如果在这个时候A不等于B的话,那么就会报出一个错误的信息供你debug。
9,A class is a user-defined data type. Classes consist of data (called properties) and tasksand functions to access the data (called methods). Classes are used in object-oriented programming.In SystemVerilog, classes support the following aspects of object-orientation – encapsulation, data hiding, inheritance and polymorphism.10,Classes may be parameterised in the same way that modules may.class #(parameter int N = 1) Register;It is also possible to pass a data type to a class:class #(parameter type T = int) Register; T data; ... endclass Register Rint;// data is int Register #(bit [7:0]) Rint; // data is bit [7:0]11,One of the key features of object-oriented programming is the ability to create new classes that are based on existing classes. A derived class by default inherits the properties and methods of its parent or base class. However, the derived class may add new properties and methods, or modify the inherited properties and methods. In other words, the new class is a more specialised version of the original class. In SystemVerilog the syntax for deriving or inheriting one class from another is this:class Derived extends BaseClass; // New and overridden property and method declarations. endclass 12,vitual classSometimes, it is useful to create a class without intending to create any objects of the class. The class exists simply as a base class from which other classes can be derived. In SystemVerilog this is called an abstract class and is declared by using the word virtual:virtual class Register; ... endclass13,Traditionally, simulation-based verification has used a directed testing approach. In other words,a testbench implements tests using specific data values.14,struct packed { bit [10:0] ID; // 11-bit identifier bit RTR; // reply required? bit [1:0] rsvd; // "reserved for expansion" bits bit [3:0] DLC; // 4-bit Data Length Code byte data[]; // data payload bit [14:0] CRC; //15-bit checksum } message;We have used struct packed to define a packed data structure. This means that the data structure can be packed into a single vector,15,Constraints direct the random generator to choose values that satisfy the properties you specify in your constraints. Within the limits of your constraints, the values are still randomly chosen. The process of choosing values that satisfy the constraints is called solving. The verification tool thatdoes this is called the solver;16,SystemVerilog 3.1a adds important new constructs to Verilog-2001, including:a, New data types: byte, shortint, int, longint, bit, logic, string, chandle.b, Typedef, struct, union, tagged union, enumc, Dynamic and associative arrays; queuesd, Classese, Automatic/static specification on a per variable instance basisf, Packages and support for Compilation Unitsg, Extensions to Always blocks for modelling combinational, latched or clocked processesh, Jump Statements (return, break and continue)i, Extensions to fork-join, disable and wait to support dynamic processes.j, Interfaces to encapsulate communicationk, Clocking blocks to support cycle-based methodologiesl, Program blocks for describing testsm, Randomization and constraints for random and directed-random verificationn, Procedural and concurrent assertions and Coverage for verificationo, Enhancements to events and new Mailbox and Semaphore built-in classes for inter-process communication.p, The Direct Programming Interface, which allows C functions to be called directly from SystemVerilog (and vice versa) without using the PLI.q, Assertions and Coverage Application Programming Interfaces (APIs) and extensions to the Verilog Procedural Interface(VPI) – details of these are outside the scope of the SystemVerilog Golden Reference Guide17,The clocking event of a clocking block can be accessed directly by using the clocking block name, e.g. @(cb) is equivalent to @(posedge Clk).18,将设计的端口和测试的端口放在同一个interface中,引用的时候可以只引用内部的一个modport 19,The program block can read and write all signals in modules, and can callroutines in modules, but a module has no visibility into a program.用于模块之间进行交互的。