TCP protocol
This section describes the chosen and implemented protocol for the frames sent and received to/from the Verisocks server TCP socket by any client that wishes to connect to it.
Note
A reference Python client implementation can be found in the Verisocks github repository.
A plethora of tools and languages on many platforms support socket programming with convenient built-in libraries and methods (C, Ruby, Perl, Tcl, Labview, Matlab, Java, etc.). Any could be used to implement a client that could connect to the Verisocks server.
Frames format
Note
The TCP message format follows the proposal for a message format in the RealPython’s guide on sockets programming. It allows to deal easily with variable-length messages while making sure that it is possible to verify that the full message has been received and that it is not overlapping with the next message. Moreover, while it is not really foreseen at this time to be used in this project, it also allows to cope with the transmission of binary data.
The chosen frame format contains in order:
Fixed-length pre-header: Indicates the length in bytes of the following variable-length header.
Type: Integer value
Encoding: Big endian byte ordering (most significant byte sent first)
Length: 2 bytes – This limits the size of the following variable-length header to a maximum of 65535 bytes. This is more than enough…
Variable-length header: Gives information on the message payload’s content.
Type: Unicode text, JSON format
Encoding: UTF-8
Length: As specified by the pre-header integer value
Content: Follows partially RFC 9110 (HTTP semantics); only the following fields are being used:
content-type
: Type of content for the variable-length payload. For Verisocks current implementation, only application/json is currently supported.
content-encoding
: Encoding for the variable-length payload. OnlyUTF-8
currently supported (supporting encodings other than system’s default is a nightmare with the GNU standard C library).
content-length
: Length in bytes of the variable-length payload.For example, the following constitutes a valid Verisocks header (assuming that the following payload is indeed 110-byte long):
{ "content-type": "application/json", "content-encoding": "UTF-8", "content-length": 110 }
Variable-length payload
Type: As specified in the header’s
content-type
field.Encoding: As specified in the header’s
content-encoding
field.Length: As specified in the header’s
content-length
field.Content: At the moment, the only supported content correspond to a
request (or command) from the client to the Verisocks server, respectively a response (or return message) from the Verisocks server to the client, formatted as a JSON object.
Full message example
As an example of a valid Verisocks full message, you can consider the following (taken from the SPI master example provided in the verisocks github repository):
Pre-header: value 88, first byte =
0x00
, second byte =0x58
Header:
{ "content-type": "application/json", "content-encoding": "utf-8", "content-length": 110 }
Payload:
{ "command": "set", "path": "spi_master_tb.i_spi_master.tx_buffer", "value": [132, 201, 31, 71, 178, 192, 137] }
Commands
Commands are messages sent from a client to the Verisocks server intending to trigger specific actions for the simulator or the server. The supported commands are exhaustively listed below.
Information frame (info)
Provides an arbitary information text from the client to the server. This arbitrary text is then printed out to the VPI standard output.
JSON payload fields:
"command": "info"
"value":
Arbitrary text content to be printed out to VPI stdout
Returned frame (normal case):
"type": "ack"
(acknowledgement)"value": "command info received"
With the provided Python client reference implementation, the method
Verisocks.info()
corresponds to this command.
Finish simulation (finish)
Finishes the simulation (equivalent to a verilog $finish()
statement). This will also result in the simulator process being terminated as
well as the Verisocks server. The socket used will also be closed. After this
command, the execution focus goes to
Verisocks.
JSON payload fields:
"command": "finish"
Returned frame (normal case):
"type": "ack"
(acknowledgement)"value": "Processing finish command - Terminating simulation."
With the provided Python client reference implementation, the method
Verisocks.finish()
corresponds to this command.
Stop simulation (stop)
Stops the simulation (equivalent to the verilog $stop()
statement).
Contrary to the finish command, the socket is not
closed. After this command, the execution focus
goes to Verisocks.
JSON payload fields:
"command": "stop"
Returned frame (normal case):
"type": "ack"
(acknowledgement)"value": "Processing stop command - Stopping simulation."
With the provided Python client reference implementation, the method
Verisocks.stop()
corresponds to this command.
Exit (exit)
Exits Verisocks and closes the socket. After this command, the execution focus goes to the simulator and the simulation continues its course until it ends.
JSON payload fields:
"command": "exit"
Returned frame (normal case):
"type": "ack"
(acknowledgement)"value": "Processing exit command - Quitting Verisocks."
With the provided Python client reference implementation, the method
Verisocks.exit()
corresponds to this command.
Run simulation (run)
Transfers the execution focus to the simulator and runs it until a callback event which is specified by the command arguments (see description below). After the callback is reached, the focus gets back to Verisocks.
JSON payload fields:
"command": "run"
Command nameA callback needs to be defined in order to specify when the run command has to yield the execution focus back to Verisocks. The different available possibilities are:
"cb": "for_time"
- The simulation shall run for a certain amount of time,"cb": "until_time"
- The simulation shall run until a certain (simulator) time,"cb": "until_change"
- The simulation shall run until a certain simulator variable changes to a given value,"cb": "to_next"
- The simulation shall run until the next simulation time step.
If the
"cb"
field is"for_time"
or"until_time"
, the following fields are further expected in the command frame:"time":
(number): Time value (either as a time difference or as an absolute simulation time). For example"time": 3.2
"time_unit":
(string): Time unit ("s"
,"ms"
,"us"
,"ns"
,"ps"
or"fs"
) which applies to the"time"
field value. Be aware that depending on the simulator time resolution, the provided time value can be truncated.
If the
"cb"
field is"until_change"
, the following fields are further expected in the command frame:"path":
(string): Path to verilog object used for the callback"value":
(number): Condition on the verilog object’s value for the callback to be executed. This argument is not required if the path corresponds to a named event.
If the
"cb"
field is"to_next"
, no further fields are required.Returned frame (normal case):
"type": "ack"
(acknowledgement)"value": "Reached callback - Getting back to Verisocks main loop"
With the provided Python client reference implementation, the method
Verisocks.run()
corresponds to this command.
Get information from simulation (get)
This command can be used to get pieces of information from the simulator.
JSON payload fields:
"command": "get"
Command nameIt is possible to select which shall be the returned information, using the following possibilities:
"sel": "sim_info"
- The simulator information (name and version) is returned,"sel": "sim_time"
- The simulator (absolute) time is returned,"sel": "value"
- The value of a simulator variable is returned,"sel": "type"
- The VPI type of a simulator variable is returned.
If the
"sel"
field is"value"
or"type"
, the following field is required in the command frame:"path":
(string): Path to the verilog variable
Returned frame (for
"sel": "sim_info"
):"type": "result"
"product":
(string): Simulator product name"version":
(string): Simulator version
Returned frame (for
"sel": "sim_time"
):"type": "result"
"time":
(number): Simulator absolute time, in seconds
Returned frame (for
"sel": "value"
):"type": "result"
"value":
(number or array): Value for the queried variable
Returned frame (for
"sel": "type"
):"type": "result"
"vpi_type":
(number): Value for the queried variable’s VPI type (see VPI objects types definitions in IEEE 1364-2001)
With the provided Python client reference implementation, the method
Verisocks.get()
corresponds to this command.
Set variables in simulation (set)
This command can be used to forcefully set the value of a simulator variable.
JSON payload fields:
"command": "set"
Command name"path":
(string): Path to the simulator variable to be set"value":
(number or array): Value to be set. If the path corresponds to a verilog named event, this argument is not required. If the path corresponds to a memory array, this argument needs to be provided as an array of the same length.
Returned frame (normal case):
"type": "ack"
(acknowledgement)"value": "Processed command set"
With the provided Python client reference implementation, the method
Verisocks.set()
corresponds to this command.