lab4 OOP encapsulation
Experimental overview
OOP encapsulation means object-oriented encapsulation. What Lab4 does is encapsulate some group information into a Packet class. Then call the class to implement the same function of lab3. Implementation block diagram

You can see. The experiment deals with the data sent and collected by gen(). The rest is lab3 consistent.
Task code parsing
First implement the Packet.sv file, and then modify the test program
Package implementation and understanding
Similarly, here is a simple modification to compare. Students can compare the writing method in the original solution with that here. The code is as follows.
`ifndef INC_PACKET_SV `define INC_PACKET_SV class Packet; rand bit[3:0] sa, da; rand logic[7:0] payload[$]; string name; constraint valid { sa inside { [0:15] }; da inside { [0:15] }; payload.size() inside { [2:8] }; } extern function new(string name = "Packet");//The default parameter passed in here is Packet extern function bit compare(Packet pkt2cmp, ref string message);// need a package extern function void display(string prefix = "NOTE"); endclass: Packet function Packet::new(string name); this.name = name; endfunction: new function bit Packet::compare(Packet pkt2cmp, ref string message); if(payload.size() != pkt2cmp.payload.size()) begin//The payload.size of the incoming package is compared with that of the class variable message = "Payload size Mismatch:\n"; message = { message, $sformatf("payload.size() = %0d, pkt2cmp.payload.size() = %0d\n", payload.size(), pkt2cmp.payload.size()) }; return (0); end if(payload == pkt2cmp.payload) ; else begin message = "Payload Content Mismatch:\n"; message = { message, $sformatf("Packet Sent: %p\nPkt Received: %p", payload, pkt2cmp.payload) }; return (0); end message = "Successfully Compared"; return(1); endfunction: compare function void Packet::display(string prefix); $display("[%s]%t %s sa = %0d, da = %0d", prefix, $realtime, name, sa, da); foreach(payload[i]) $display("[%s]%t %s payload[%0d] = %0d", prefix, $realtime, name, i, payload[i]); endfunction
Let's first look at the specific members in the package. The variable members contained in the package are as follows.
- Random variables sa and da. Is the sending address and the source address.
- The random variable queue payload is used to store the data sent or received.
- String variable name. The ID of each Packet class, which is used for debugging and printing related information. For debugging
- Constructor new()
- The compare function is used to compare whether the received and transmitted data are consistent
- Finally, the display function is used to print the comparison results
Syntax point parsing
extern
SV allows you to declare examples outside a block. Use the keyword extern. Examples are as follows
class Transaction; extern function void display (); endclass function void Transaction::display (); $display ("..."); endfunction
`Use of ifndef macro definition
`ifndef/`define/`endif is used to prevent repeated compilation. Take an example.
a. SV contains two files b.sv and c.sv. At the same time, b.sv and c.sv contain d.sv respectively. When compiling a.sv at this time, d.sv will be compiled repeatedly. Adding ` ifndef/`define/`endif will not introduce the above problems.
this.name = name;
Assign the passed parameter to a variable in a class
When you use a variable name, system Verilog will first look in the current scope, and then look in the upper scope until the variable is found. This is also the algorithm used by Verilog. But what if you want to explicitly reference class level objects in the deep underlying scope of a class? This style of code is most common in constructors because programmers use the same class variable name and parameter name. The keyword this can realize this function.
class Scoping; string oname; function new ( string oname ) ; this.oname = oname // Class variable oname = local variable oname endfunction endclass
$sformatf
$sformatf("payload.size() = %0d, pkt2cmp.payload.size() = %0d\n", payload.size(), pkt2cmp.payload.size())
The return value of $sformatf is a string. The incoming content will be sorted and a string property will be returned.
Random constraint
Random and constrained time are two concepts. Refer to Chapter 6 of the green paper, randomization
random | constraint |
---|---|
rand bit[3:0] sa, da; A random variable is defined, and the RAND modifier is used to indicate that each time the class is randomized, a value will be given to the variable. | Use constraints to process random values. The keyword is constraint |
sa inside { [0:15] }; SA is in the range of 0-15
Implementation and understanding of main program
We have omitted the code consistent with lab3. The main modifications are gen(),recv() and check. Relevant comments are placed in the code
`include "Packet.sv" program automatic test(router_io.TB rtr_io); int run_for_n_packets; bit[3:0] sa; bit[3:0] da; logic[7:0] payload[$]; logic[7:0] pkt2cmp_payload[$]; // actual packet data array Packet pkt2send = new(); //Use similar classes. The new() function opens up space for two packets. The packet is used for sending and is used in the gen() function. It is also used in the check() function Packet pkt2cmp = new(); initial begin ...//Consistent with lab3 end task reset(); ...//Consistent with lab3 endtask: reset task gen(); static int pkts_generated = 0;//Static variable pkt2send.name = $sformatf("Packet[%0d]", pkts_generated++); if(!pkt2send.randomize()) begin //Call the function to check whether the initialization status is successful. call function randomize. meanwhile check it's work situation $display("\n%m\n [ERROR] %t: Randomize Error!!", $realtime); $finish; end sa = pkt2send.sa; //Transmit random results to sa da = pkt2send.da; $display("this package from sa = %0d ,and da = %0d",sa,da); payload = pkt2send.payload; endtask: gen task send(); ...//Consistent with lab3 endtask: send task recv(); static int pkt_cnt = 0; get_payload(); pkt2cmp.da = da;//Send the received address to the received packet variable pkt2cmp.payload = pkt2cmp_payload;//Send the received data to the received packet variable pkt2cmp.name = $sformatf("rcvdPkt[%0d]", pkt_cnt++); endtask : recv task get_payload(); ...//Consistent with lab3 endtask: get_payload task check(); string message; static int pkts_checked = 0; if (!pkt2send.compare(pkt2cmp, message)) begin // need two package,need to use payload data compare with introduce package data. will print two package some information about address,data. //Pass pkt2cmp into the pkt2send.compare() function. Compare the variables of the original class with those sent in. Judge whether it is successful. The ref parameter is used for the string parameter here. You can change the value of message in the function $display("\n%m\n[ERROR]%t Packet #%0d %s\n", $realtime, pkts_checked, message); pkt2send.display(); pkt2cmp.display(); $finish; end $display("[NOTE]%t Packet #%0d %s", $realtime, pkts_checked++, message); endtask: check endprogram: test
Syntax point parsing
`include
The so-called "file inclusion" processing means that one source file can include all the contents of another source file, that is, another file can be included in this file. You can compose some common macro definition commands or tasks into a file, and then use the ` include command to include these macro definitions in your own source file, which is equivalent to the standard components in the industry.
Understanding of ref
click here ref . The simple explanation is that if you change message in the function, the value of the message variable will change.