# Open-Source Verification with Chisel and Scala

Andrew Dobis, Tjark Petersen, Kasper Juul Hesse Rasmussen, Enrico Tolotto,
Hans Jakob Damsgaard, Simon Thye Andersen, Richard Lin, Martin Schoeberl
Department of Applied Mathematics and Computer Science
Technical University of Denmark
Lyngby, Denmark

Department of Electrical Engineering and Computer Sciences
UC Berkeley
Berkeley, CA

<EMAIL_ADDRESS><EMAIL_ADDRESS><EMAIL_ADDRESS><EMAIL_ADDRESS>
<EMAIL_ADDRESS><EMAIL_ADDRESS><EMAIL_ADDRESS><EMAIL_ADDRESS>
###### Abstract

Performance increase with general-purpose processors has come to a halt. We
can no longer depend on Moore’s Law to increase computing performance. The
only way to achieve higher performance or lower energy consumption is by
building domain-specific hardware accelerators. To efficiently design and
verify those domain-specific accelerators, we need agile hardware development.
One of the main obstacles when proposing such a modern method is the lack of
modern tools to attack it. To be able to verify a design in such a time-
constrained development method, one needs to have efficient tools both for
design and verification.

This paper thus proposes ChiselVerify, an open-source tool for verifying
circuits described in any Hardware Description Language. It builds on top of
the Chisel hardware construction language and uses Scala to drive the
verification using a testing strategy inspired by the Universal Verification
Methodology (UVM) and adapted for designs described in Chisel. ChiselVerify is
created based on three key ideas. First, our solution highly increases the
productivity of the verification engineer, by allowing hardware testing to be
done in a modern high-level programming environment. Second, the framework
functions with any hardware description language thanks to the flexibility of
Chisel blackboxes. Finally, the solution is well integrated into the existing
Chisel universe, making it an extension of currently existing testing
libraries.

We implement ChiselVerify in a way inspired by the functionalities found in
SystemVerilog. This allows one to use functional coverage, constrained-random
verification, bus functional models, transaction-level modeling and much more
during the verification process of a design in a contemporary high-level
programming ecosystem.

###### Index Terms:

digital design, verification, Chisel, Scala

##  I Introduction

We can no longer depend on Moore’s Law to increase computing performance [9].
Performance increase with general-purpose processors has come to a halt. The
only way to achieve higher performance or lower energy consumption is by
building domain-specific hardware accelerators [7]. These accelerators can be
built in chips or in FPGAs in the cloud. The production of a chip is costly.
Therefore, it is essential to get the design right at the first tape-out.
Thorough testing and verification of the design is mandatory.

To efficiently develop and verify those accelerators, we can learn from
software development trends such as agile software development [6]. We believe
that we need to adapt to agile hardware development [11].

Furthermore, as accelerators become part of the cloud service, i.e. FPGAs in
the cloud, software developers will increasingly need to adapt critical
algorithms to FPGAs to enhance performance. Hence, it is imperative to make
accelerator design accessible for software developers. By adapting hardware
accelerator design to the methods and tools of contemporary software design,
it is possible to bridge both domains catering for a more uniform
hardware/software development process.

Up until a few years ago, the two main design languages, Verilog and VHDL,
dominated the design and testing of digital circuits. However, compared to
software development and testing, digital design and testing methods/tools
lack several decades of development. We propose a tool that leverages software
development and testing methods for digital design. Based in the hardware
construction language Chisel [4], which itself is embedded in Scala, our
framework reimagines functionalities form Universal Verification Method (UVM)
with SystemVerilog [1] and adapts them for the existing Chisel ecosystem.

We thus developed a method and concrete tools for agile hardware development.
ChiselVerify combines tools, languages, development, and testing methods from
the last decades in software development and applies them to hardware design.
We aim to raise the tooling level for a digital design to increase
productivity. The workload demanded for the verification (testing) of digital
systems is about double the time of developing them in the first place.

Using the power and flexibility of Chisel Blackboxes, our tool can be used to
verify designs implemented in any of the major hardware description languages
(i.e., VHDL or Verilog) with little overhead. Furthermore, golden models
described in any programming language can be used using the Java JNI. Our work
builds upon existing open-source projects and is thus also open-source.

We developed an object-oriented and functional framework for verification in
Scala. This framework is inspired by UVM, but leverages Scala’s conciseness
with the combination of object-oriented programming with functional
programming. An initial experiment of testing the accumulator circuit of the
Leros processor [16] showed the that a test written with UVM was about 800
lines of code, where a Scala based test was around 80 lines of code [15].
However, UVM supports more functionality that a plain ChiselTest in Scala.

Within our verification framework, we support mixed language verification.
Verilog can easily be combined with Chisel, as Chisel generates Verilog, and
we use ChiselTest as a driver for the open-source Verilog simulator Verlator.
With Yosys synthesis suite [18] and GHDL [10] we can translate VHDL into
Verilog.

A verification method is only usable when it can handle mixed-source designs.
This means a Scala driven method must be able to test components written in
Verilog, VHDL, and SystemVerilog.

Chisel has support for black boxes, which allows the use of Verilog code
within the Chisel design. Therefore, it is relatively easy to integrate
Verilog components when wrapped into a black box. However, this forces Chisel
to use Verilator instead of Treadle to run the simulation, impacting startup
time.

Chisel does not fully support VHDL. It can support VHDL using VCS, but there
is no open-source solution available for VHDL simulation. For companies with a
lot of source code written in VHDL this is a concern, as they must be able to
integrate their existing IP in a Scala/Chisel based design and verification
workflow. All major commercial simulation and synthesis tools support mixed-
language designs, but no open-source tools exist that provide the same
functionality.

To alleviate this issue, we use the open-source Yosys synthesis suite [18].
Yosys is an open-source digital hardware synthesis suite for Verilog. Yosys
also has a variety of plugins, one of these being a plugin for using GHDL
[10], an open-source VHDL simulator. By using Yosys in conjunction with GHDL,
VHDL files are compiled to an RTL-based intermediate representation, which is
then written to a Verilog file using Yosys. GHDL has full support for IEEE
1076 VHDL 1987, 1993, 2002, and a subset of 2008. A working solution named
VHDL2Verilog has been made for this, which has been tested with certain simple
VHDL designs [2].

This paper is an extension of [15].

In the following sections, we will explore the different backgrounds on which
ChiselVerify was based.

##  II Background and State-of-the-Art

VHDL and Verilog are the classic hardware description languages, first
appeared in the 1980s. SystemVerilog [1], as an extension to Verilog, adds
features from VHDL for the hardware description and object-oriented features
for verification. Recent advances with SystemVerilog and Chisel [4, 14] have
brought object-oriented programming into the digital design and verification
process.

Chisel is a “Hardware Construction Language” embedded in Scala, to describe
digital circuits [4]. Scala/Chisel brings object-oriented and functional
programming into the world of digital design. For hardware generation and
testing, the full Scala language and Scala and Java libraries are available.
As Scala and Java’s full power is available to the verification engineer, the
verification process is also made more efficient.

Chisel is a hardware construction language embedded in Scala. Chisel allows
the user to write hardware generators in Scala, an object-oriented and
functional language. For example, we read in the string based schedules for a
network-on-chip [17] and convert them with a few lines of Scala code into a
hardware table to drive the multiplexer of the router and the network
interface.

Chisel is solely a hardware _construction_ language, and thus all valid Chisel
code maps to synthesizable hardware. By separating the hardware construction
and hardware verification languages, it becomes impossible to write non-
synthesizable hardware and in turn, speeds up the design process.

Chisel and Scala are executing on the Java virtual machine and therefore have
a very good interoperability with Java. Therefore, we can leverage a large
pool of Java libraries for hardware design and verification. Furthermore, the
name space of packets in Scala/Java simplifies integration of external
components. Open source hardware components in Chisel can be organized like
software libraries at Maven servers.

SystemVerilog adds object-oriented concepts for the non-synthesizable
verification code. The SystemVerilog direct programming interface [8] allows
the programmer to call C functions inside a SystemVerilog (UVM) testbench.
This enables co-simulation with a “golden model” written in C, and the
testbench verifying the device under test (DUT). With ChiselTest we can co-
simulate with Java and Scala models and use the Java Native Interface to co-
simulate with models in C.

The Universal Verification Method (UVM) is an open source collection of
SystemVerilog, which is becoming popular in industry. SystemVerilog has become
a complex language with more than 250 keywords, and it is unclear which tools
support which language constructs for hardware description. In contrast with
Chisel, when the program compiles, it is synthesizable hardware. Chisel is a
small language, where the cheat sheet fits on two pages. The power of Chisel
comes from the embedding in Scala. Furthermore, as classic hardware
description languages are niche products, not many tools or libraries are
available. With Chisel on Scala we have the choice of different integrated
development environments (IDE), testing infrastructure (e.g., ScalaTest), and
many free libraries.

The Java JNI (Java Native Interface) allows for a similar functionality in
Java programs, allowing them to call C functions and use their functionality.
By using Scala, which is built on Java, it is our hope to use the JNI together
with Scala’s test frameworks. The aim is to develop a framework for co-
simulation with Scala/Chisel testers and a C-based golden model. This should
allow companies to keep their existing C models, but move their simulation
workflow into Scala/Chisel testers.

The digital design described in Chisel can be tested and verified with
ChiselTest [12], a non-synthesizable testing framework for Chisel. ChiselTest
emphasizes usability and simplicity while providing ways to scale up
complexity. Fundamentally, ChiselTest is a Scala library that provides access
into the simulator through operations like poke (write value into circuit),
peek (read value from circuit, into the test framework), and step (advance
time). As such, tests written in ChiselTest are just Scala programs,
imperative code that runs one line after the next. This structure uses the
latest programming language developments that have been implemented into Scala
and provides a clean and concise interface, unlike approaches that attempt to
reinvent the wheel like UVM.

Furthermore, ChiselTest tries to enable testing best practices from software
engineering. Its lightweight syntax encourages writing targeted unit tests by
making small tests easy. A clear and clean test code also enables the test-as-
documentation pattern, demonstrating a module’s behavior from a temporal
perspective.

##  III Constraint Random Verification

The complexity of digital design is growing with the capacity of the silicon.
A decade ago, the industry started to move away from “direct” testing towards
functional coverage and formal methods. One of the pillars of functional
verification is constraint programming. Constraint programming (CP) is a
programming paradigm that has been developed since the mid-1980s and emerged
as a further development of logic programming. Constraint-based programming
allows constraints and their solution mechanisms to be integrated into a
programming language. With constraint programming, the user describes the
problem in a declarative way, while the solution process takes a back seat
from the user’s perspective. A subset of these problems is the so-called
Constraint Satisfaction Problems (CSP), which are mathematical problems
defined as a set of objects such that their state must satisfy several
constraints. CSP represents the entities of a problem as a finite homogeneous
collection of constraints.

⬇

1typedef enum {UNICAST=11,MULTICAST,BROADCAST} pkt_type;

3class frame_t;

4 rand pkt_type ptype;

5 rand integer len;

6 rand bit [7:0] payload [];

7 constraint common {

8 payload.size() == len;

9 }

10 // Constraint the members

11 constraint unicast {

12 len <= 2;

13 ptype == UNICAST;

14 }

15 // Constraint the members

16 constraint multicast {

17 len >= 3;

18 len <= 4;

19 ptype == MULTICAST;

20 }

21endclass

Listing 1: Random object in SystemVerilog

Listing LABEL:lst:randobjsysv shows a class named ”frame_t”. It uses the
”rand” keyword for variables ”len”, ”ptype”, and payload. Therefore these are
the variables that can be randomized. Then constraints to these variables are
applied and declared by the “common” ”unicast,” and ”multicast” constraint
groups. Each class in SystemVerilog has an intrinsic method called
”randomize(),” which causes new values to be selected for all the variables
declared with the rand keyword. The selected value for each variable will
respect the constraints applied to it. If there are “rand” variables that are
unconstrained, a random value inside their domain will be assigned. Combining
random classes using the inheritance OOP paradigm allows the creation of
general-purpose models that can be constrained to perform domain-specific
functions. In the research process, a CSP solver was implemented in Scala
based on the method described in [13]. The implementation is composed of two
main components. The first one is the CSP solver itself, which uses a
combination of backtracking and arc consistency to generate solutions for
well-defined problems. The second component is a small DSL, which allows users
to declare and randomize objects.

⬇

2object pktType extends SVEnumeration {

3 val UNICAST: Value = Value(11)

4 val MULTICAST: Value = Value(0)

5 val BROADCAST: Value = Value(1)

7 val domainValues = {

8 values.map(x => x.id).toList

9 }

11}

12class Frame extends Random {

13 import pktType._

14 var pType: RandInt =

15 rand(pType, pktType.domainValues())

16 var len: RandInt =

17 rand(len, 0 to 10 toList)

18 var noRepeat: RandCInt =

19 randc( noRepeat, 0 to 1 toList)

20 var payload: RandInt =

21 rand(payload, 0 to 7 toList)

23 val common = constraintBlock (

24 binary ((len, payload) => len == payload)

25 )

27 val unicast = constraintBlock(

28 unary (len => len <= 2),

29 unary (pType => pType == UNICAST.id)

30 )

32 val multicast = constraintBlock(

33 unary (len => len >= 3),

34 unary (len => len <= 4),

35 unary (pType => pType == MULTICAST.id)

36 )

37}

Listing 2: Random object in Scala

Listing LABEL:lst:randobjscala, shows an example of random a object. Contrary
to SystemVerilog, to declare a random object, the user has to extend the class
from the Random base-class provided by the library. After that each random
variable has to be declared of type ”RandInt” and initialized with the ”rand”
macro. Finally, like for SystemVerilog, in Scala inheriting the Random base
class exposes the method ”random” which assigns random values to the random
fields of the class.

##  IV Verification of AXI4 Interfaced Components

Another solution to the ever-increasing complexity of digital designs is to
use standardized interfaces, which enable greater reuse. One of such standard
interfaces is AXI4, an open standard by ARM [3], which is used in particular
to connect processor nodes to memories. As such, most available synthesis
tools, including Xilinx’ Vivado, provide IP generators whose output IP blocks
are equipped with AXI interfaces along with optional verification structures
written in (System-)Verilog [19].

Typically, verification of components with such standard interfaces is
provided through so-called bus functional models (BFMs) that abstract complex
low-level signal transitions between bus masters and slaves to a transaction
level (e.g., write and read transactions). Unfortunately, such BFMs are not
yet available in Chisel – hence, why we include an example BFM based around
ChiselTest in our framework.

###  IV-A Introduction to AXI4

The Advanced eXtensible Interface protocol by ARM is a highly flexible
interconnect standard based around five separate channels; three for write
operations and two for read operations. Operations, known as transactions,
consist of a number of transfers across either set of channels. All channels
share a common clock and active-low reset and base their transfers on classic
ready-valid handshaking. It is designed with DMA-based memories in focus
supporting multiple outstanding transactions and out-of-order completion. The
five channels are:

  * •

Write Address for transferring transaction attributes from master to slave

  * •

Write Data for transferring write data and strobe from master to slave

  * •

Write Response for transferring transaction status of a writes from slave to
master

  * •

Read Address same as Write Address, but for reads

  * •

Read Data for transferring read data from slave to master

Consider for example a write transaction of 16 data elements. First, the
master provides transaction attributes (e.g., target address, burst length,
and data size) as a single transfer over the Write Address channel, then the
master transfers the 16 data elements one at a time over the Write Data
channel, and finally, the slave indicates the status of the transaction over
the Write Response channel. The Read Address and Read Data channels may
operate independently at the same time. A full description is available in
[3].

###  IV-B Implementation

Our implementation includes bundles definining the five different channels,
abstract classes representing both master and slave entities, transaction-
related classes, and of course the BFM itself; the FunctionalMaster class. The
BFM is parameterized with a DUT that extends the slave class and provides a
simple, transaction level interface to control the DUT. As such, its two most
important public methods are createWriteTrx and createReadTrx which do exactly
as their names indicate; create and enqueue write and read transactions.

Internally, the BFM makes use of ChiselTest’s multithreading features to allow
for (a) non-blocking calls to the aforementioned methods (i.e., one can
enqueue multiple transactions without waiting for their completion) and (b)
emulating the channel independence more closely. As such, when, for example, a
write transaction is enqueued and no other write transactions are in-flight,
the BFM spawns three new threads, one for each required channel. The threads
each handle the handshaking necessary to operate the channels.

###  IV-C A Simple Example

Returning to the example used before, using the BFM to test a module called
Memory is as simple as shown below. Creating a write transaction with 16 data
elements (minimum burst length is 1, hence len = 15 means a burst of 16 items)
takes just one call to a method the majority of whose arguments have default
values. It is equally simple to create a subsequent read transaction – but
beware that due to the BFM’s parallel execution style, the channels are indeed
independent. As such, not waiting for a write to complete before starting to
read from the same address may return incorrect results depending on the
implementation of the DUT.

⬇

1class MemoryTester extends FlatSpec with ChiselScalatestTester with Matchers
{

2 behavior of "My␣Memory␣module"

3 it should "write␣and␣read" in {

4 test(new Memory()) {

5 dut =>

6 val bfm = new FunctionalMaster(dut)

7 master.createWriteTrx(0, Seq.fill(16)(0x7FFFFFFF), len = 15, size = 2)

8 master.createReadTrx(0, len = 15, size = 2)

9 }

10 }

11}

Listing 3: Using the AXI4 BFM with ChiselTest

##  V Coverage in Chisel

One of the main tools used in verification is test coverage. This allows
verification engineers to measure their progress throughout the testing
process and have an idea of how effective their tests actually are. Coverage
can be separated into two distinct categories: code coverage and functional
coverage. code coverage defines a quantitative measure of the testing
progress, ”How many lines of code have been tested?”, whereas functional
coverage gives a rather qualitative measure, ”How many functionalities have we
tested?”. Our solution gives the verification engineer access to two ways of
obtaining their code coverage and new constructs allowing the definition of a
verification plan and the creation of a functional coverage report directly
integrated into the Chisel testing framework.

#### Code Coverage with Treadle

The first part of our solution is about code coverage, more specifically line
coverage that was added to the Treadle FIRRTL execution engine. Treadle is a
common FIRRTL execution engine used to simulate designs implemented in Chisel.
This engine runs on the FIRRTL intermediate representation code generated by a
given Chisel implementation and allows one to run user-defined tests on the
design using frameworks like iotesters or the more recent testers2. In our
pursuit of creating a verification framework, we found that one way to obtain
line coverage would be to have our framework run on an extended version of
Treadle that was capable of keeping track of said information.

The solution that was used to implement line coverage was based off of a
method presented by Ira. D. Baxter [5]. The idea is to add additional outputs
for each multiplexer in the design. These new ports, which we will call
Coverage Validators, are set depending on the paths taken by each multiplexer
and that information is then gathered at the end of each test and maintained
throughout a test suite. Once the testing is done, we used the outputs
gathered from the Coverage Validators to check wether or not a certain
multiplexer path was taken during the test, all of this resulting in a branch
coverage percentage.

This was implemented in Treadle by creating a custom pass of the FIRRTL
compiler that traverses the Abstract Syntax Tree (AST) and adds the wanted
outputs and coverage expressions into the source tree. Once that is done, the
TreadleTester samples those additional outputs every time the expect method is
called and keeps track of their values throughout a test suite. Finally it
generates a Scala case class containing the following coverage information:

  * •

The multiplexer path coverage percentage.

  * •

The coverage Validator lines that were covered by a test.

  * •

The modified LoFIRRTL source code in the form of a List[String].

The CoverageReport case class can then be serialized, giving the following
report:

    COVERAGE: 50.0% of multiplexer paths tested
    COVERAGE REPORT:

    + circuit Test_1 :
    +   module Test_1 :
    +     input io_a : UInt<1>
    +     input io_b_0 : UInt<2>
    +     input io_b_1 : UInt<2>
    +     input clock : Clock
    +     output io_cov_valid_0 : UInt<1>
    +     output io_cov_valid_1 : UInt<1>
    +     output out : UInt<2>
    +
    +     io_cov_valid_0 <= io_a
    -     io_cov_valid_1 <= not(io_a)
    +     out <= mux(io_a, io_b_0, io_b_1)

The example above is taken for a simple test, where we are only testing the
path where in_a is 1. This means that, since we only have a single
multiplexer, only half of our branches have been tested and we would thus want
to add a test for the case where in_a is 0. The report can thus be interpreted
as follows:

  * •

”+” before a line, means that it was executed in at least one of the tests in
the test suite.

  * •

”-” before a line, means that it wasn’t executed in any of the tests in the
test suite.

Treadle thus allows us to obtain coverage at the FIRRTL level. A more
interesting result would be if the FIRRTL line coverage would be mapped to the
original Chisel source. This is possible but challenging, since Treadle only
has access to the original source code through Source locators which map some
of the FIRRTL lines back to Chisel. This means that the code can only be
partially mapped and the remainder will have to be reconstructed using some
smart guessing.

#### Functional Coverage Directly in Scala

Functional Coverage is on the principal tools used during the verification
process, since it allows one to have a measurement of ”how much of the
specification has been implemented correctly”. A verification framework would
thus not be complete without constructs allowing one to define a verification
plan and retrieve a functional coverage report. The main language used for
functional coverage is SystemVerilog, which is why our solution is based on
the same syntax. There are three main components to defining a verification
plan:

  * •

Bin: Defines a range of values that should be tested for (i.e. what values can
we expect to get from a given port).

  * •

CoverPoint: Defines a port that needs to be sampled in the coverage report.
These are defined using a set of bins.

  * •

CoverGroup: Defines a set of CoverPoints that need to be sampled at the same
time.

Using the above elements, one can define what’s known as a verification plan,
which tells the coverage reporter what ports need to be sampled in order to
generate a report. In order to implement said elements in Scala we needed to
be able to do the following:

  * •

Define a verification plan (using constructs similar to coverpoint and bins).

  * •

Sample DUT ports (for example by hooking into the Chisel Testers2 framework).

  * •

Keep track of bins to sampled value matches (using a sort of DataBase).

  * •

Compile all of the results into a comprehensible Coverage Report.

Implementing these elements was done using a structure where we had a top-
level element, known as our Coverage Reporter which allows the verification
engineer to define a verification plan using the register method, which itself
stores the coverpoint to bin mappings inside of our CoverageDB. Once the
verification plan is defined, we can sample our ports using the sample method,
which is done by hooking into Chisel Testers2 in order to use its peeking
capabilities. At the end of the test suite a functional coverage report can be
generated using the printReport method, which shows us how many of the
possible values, defined by our bin ranges, were obtained during the
simulation.

⬇

1val cr = new CoverageReporter

2cr.register(

3 //Declare CoverPoints

4 //CoverPoint 1

5 CoverPoint(dut.io.accu , "accu",

6 Bins("lo10", 0 to 10)::

7 Bins("First100", 0 to 100)

8 ::Nil)::

9 //CoverPoint 2

10 CoverPoint(dut.io.test, "test",

11 Bins("testLo10", 0 to 10)

12 ::Nil)::

13 Nil,

14 //Declare cross points

15 Cross("accuAndTest", "accu", "test",

16 CrossBin("both1", 1 to 1, 1 to 1)

17 ::Nil)::

18 Nil)

The above code snippet is an example of how to define a verification plan
using our coverage framework. The concepts are directly taken from
SystemVerilog, so it should be accessible to anyone coming from there. One
concept, that is used in the example verification plan, which we haven’t
presented yet is the idea of Cross Coverage defined using the Cross construct.
Cross Coverage allows one to specify coverage relations between CoverPoints.
This means that a cross defined between, let’s say, coverpoint a and
coverpoint b will be used to gather information about when a and b had certain
values simultaneously. Thus in example verification plan we are checking that
accu and test take the value 1 at the same time.
Once our verification plan is defined, we need to decide when we want to
sample our cover points. This means that at some point in our test, we have to
tell our CoverageReporter to sample the values of all of the points defined in
our verification plan. This can be done, in our example, simply by calling
cr.sample() when we are ready to sample our points. Finally once our tests are
done, we can ask for a coverage report by calling cr.printReport() which
results in the following coverage report:

    ============== COVERAGE REPORT ==============
    ================ GROUP ID: 1 ================
    COVER_POINT PORT NAME: accu
    BIN lo10 COVERING Range 0 to 10 HAS 8 HIT(S)
    BIN First100 COVERING Range 0 to 100 HAS 9 HIT(S)
    ============================================
    COVER_POINT PORT NAME: test
    BIN testLo10 COVERING Range 0 to 10 HAS 8 HIT(S)
    ============================================
    CROSS_POINT accuAndTest FOR POINTS accu AND test
    BIN both1 COVERING Range 1 to 1 CROSS Range 1 to 1
    HAS 1 HIT(S)
    ============================================

An other option would be, for example if we want to do automated constraint
modifications depending on the current coverage, to generate the coverage as a
Scala case class and then to use it’s binNcases method to get numerical and
reusable coverage results.

One final element that our framework offers is the possibility to gater
delayed coverage relationships between two coverage points. The idea is
similar to how a Cross works, but this time rather than sampling both points
in the same cycle, we rather look at the relation between one point at the
starting cycle and an other point sampled a given number of cycles later. This
number of cycles is called the delay and there are currently three different
ways to specify it:

  * •

Exactly delay, means that a hit will only be considered if the second point is
sampled in its range a given number of cycles after the first point was.

  * •

Eventually delay, means that a hit will be considered if the second point is
sampled in its range at any point within the following given number of cycles
after the first point was.

  * •

Always delay, means that a hit will be considered if the second point is
sampled in its range during every cycle for a given number of cycles after the
first point was sampled.

##  VI Use Case: Hardware sorting

In the process of the research a use case provided by Microchip was
implemented in order to apply developed testing and verification features. In
the following section the implementation of the use case and the connected
testing will be discussed. The code can be found in the project repository.

###  VI-A Specification

The provided specification document describes a priority queue which can be
used in real time systems for the scheduling of deadlines by providing
information about the next timer expiration to the host system. Sorting of the
enqueued elements is conducted by applying the heap sort algorithm. Elements
are structured in a so-called heap which is a tree data structure. The tree
needs to be balanced in order for the timer closest to expiring to get to the
top of the tree and thus to the head of the queue. This means verifying that
every parent node is smaller than the connected child nodes.

The $\log_{k}N$ deepness of the tree provides good scalability in terms of
insertion and removal times when the queue size increases, since worst case
$\log_{k}N-1$ swap operations need to be conducted in order to rebalance the
heap. Here $k$ is the number of child elements per parent and $N$ is the
number of elements in the heap. A trade-off is the varying delay connected to
the rebalancing of the tree where the queue is unresponsive. If queuing
happens in bursts, a buffer could be added. Here the introduced delay from
insertion request to actual appearance of the enqueued value in the heap of
course needs to be taken into account.

In order for the host system to have the ability to distinguish between
multiple consecutive super cycles and clock cycles in a super cycle, the
values inserted into the queue are split into the fields cyclic and normal
priority (time out value). The removal functionality of the queue requires a
reference system. A reference ID is therefore given together with the element
at insertion, where ID generation and uniqueness are handled by the host
system.

###  VI-B Implementation

The implemented priority queue is described in chisel. It is split into 3
modules: The Heapifier, responsible for the sorting, the QueueControl, taking
care of the general control flow in the queue and the Memory module which
handles memory accesses and can search the memory for a specific reference ID.

In order for the priority queue to work efficiently it is crucial to optimize
memory accesses. Therefore a layout is proposed in the specification where all
child elements of a certain node are stored together under one memory address.
This allows single memory access fetches of all $k$ children. Since the root
node has no siblings it is stored alone in a register. This enables even
faster access in certain scenarios which are discussed later on.

One memory row contains $k$ elements each consisting of the 3 introduced
fields: cyclic priority, normal priority and the connected reference ID. In
the implemented Memory module a single sequential memory is instantiated where
masking is used to be able to over-write specific elements in one memory row.

There are a variety of solutions to the problem of content addressability
which is required here in order to find positions of elements in the heap by
providing their reference ID. Cache-like memory relying on parallel tag
comparison could be used to achieve fast and constant search times. On the
other hand, the existing sequential memory could be searched linearly, where
$k$ reference ID’s are compared in parallel until the searched reference ID is
found. A compromise between the two solutions could include splitting memory
space over multiple instances of the latter and thus reducing worst case
search time. The priority queue is designed to be independent of the specific
implementation. As a reference, the linear search is implemented.

The Heapifier loops from a given starting point in the tree either upwards or
downwards until it hits the root or a childless node. In each iteration it is
checked whether the parent element is smaller than its child elements and if
not a swap occurs. Once the parent element and child elements of the starting
point are fetched from memory, only the next parent or block of children
respectively needs to be fetched depending on the looping direction (up/down).
Thus only 3 cycles (1 fetch, 2 write backs) are required per swap. The state
diagram of the Heapifier is shown in Figure 1.

Figure 1: The state diagram of the Heapifier

The task of the QueueControl is to insert or remove elements and then
signalize to the Heapfier to balance the tree. As it can be seen in Figure 2,
there are a series of special cases where insertion or removal times can be
reduced for instance by taking advantage of the head element being saved in a
register. The achieved best and worst case insertion as well as removal times
are presented in Table I.

Figure 2: The state diagram of the QueueControl Head insertion | 2 cycles
---|---
Normal insertion | min 7 cycles and max $5+3\cdot\mathrm{log}_{k}(N)$
Head removal | min 8 cycles and max $6+3\cdot\mathrm{log}_{k}(N)$
Tail removal | 3 cycles
Normal removal |  | min 12 cycles + search time
---
max $13+3\cdot\mathrm{log}_{k}(N)$ \+ search time
($N=$ queued elements, $k=$ number of child elements per node)
TABLE I: Best and worst case insertion and removal times Size | $k=2$ | $k=4$ | $k=8$ | $k=16$
---|---|---|---|---
16+1 | 9.38/14.56 | 7.86/11.51 | 7.47/10.42 | -
32+1 | 9.9/15.15 | 7.96/12.29 | 7.34/11.22 | 7.54/11.00
64+1 | 9.79/16.34 | 8.01/13.80 | 7.41/12.38 | 7.32/11.18
128+1 | 9.96/17.37 | 8.14/14.47 | 7.54/13.14 | 7.26/11.62
256+1 | 9.73/17.39 | 8.15/15.54 | 7.53/14.21 | 7.34/12.89
TABLE II: Simulated insertion/removal times.

###  VI-C Testing and Verification

All modules and the fully assembled queue were tested with random stimuli in
scala by employing the ChiselTest framework. In order to check whether the dut
matched the specification, reference models were written for each module. Most
modules could be modelled by a single or multiple functions. As a reference
model for the whole priority queue, a class was written which simulates state
and interaction on a operation based level. In order to abstract interaction
with the DUT, wrapper classes were employed. These make it easy to think on a
transaction or operation based level when writing tests.

In the test of the priority queue, purely random pokes are produced. In order
to evaluate how well these pokes were spread over the spectrum of possible or
interesting input combinations, the developed functional coverage feature is
used. This allows to evaluate whether interesting or important edge cases are
reached by the random input sequence. Furthermore, metrics on how many of the
generated pokes actually are valid operations, are collected. The average
insertion and removal times measured under a random test run are shown in
table II. These numbers are of course heavily dependent on access patterns and
are as such only representative for the completely random test case used here.
The tests can be found in the project repository.

##  VII UVM, SystemVerilog and Verification

This section serves as a reference on what the UVM can do, how it works, and
how some of this (namely the SystemVerilog Direct Programming Interface (DPI))
may be implemented in a Scala based testing framework.

The Universal Verification Methodology (UVM) is a verification framework built
on top of the testing capabilities of SystemVerilog. Prior to the introduction
of the UVM, the major EDA simulation vendors supported different frameworks /
methodologies. This meant that a verification environment designed for one
simulator might not run under another simulator. The main purpose of the UVM
was to standardize the testing framework used across EDA vendors, making it
easier for users to use their testbenches across different software suites.

The testbench in the UVM is built up around a number of components. Each
component performs only one task in the testbench, allowing the engineer to
make changes to some components without affecting others. For example, the
sequencer is the component responsible for generating transactions for the
DUT, whereas the driver is responsible for converting the transaction into
pin-level wiggles, i.e., generating correct start/stop conditions and driving
signals. If a new sequence of transactions is to be generated, only the
sequencer is affected. Likewise, the sequencer does not care how the
transactions are converted into pin-level signals—this is the sole
responsibility of the driver. This separation into several components results
in a more structured testbench design as there are fewer dependencies than in
a monolithic testbench.

The main components of a UVM testbench are as follows:

A Sequence(r): defines the order of transactions necessary for a given
purpose, e.g., synchronization or reset sequence. The sequencer is responsible
for transferring the transactions, defined by the sequence, to the driver.

A Driver converts transactions into pin-level signals and drives these signals
onto the DUT.

An Interface is a SystemVerilog construct which allows the user to group
related signals. A DUT may have several interfaces attached. The interface is
used to avoid hooking directly into the DUT, making it easier to test multiple
DUT versions.

A Monitor monitors all traffic on the interface, converting pin-level signals
into transaction-level objects that can be operated on by other components,
such as a coverage collector or scoreboard.

An Agent encapsulates monitor, sequencer and driver, setting configuration
values. Agents may be set active or passive (with or without a driver and
sequencer). An agent is useful when it is necessary to have multiple instances
of the same components, e.g., when a 4-port network switch needs four
identical drivers with different configurations.

A Scoreboard is used to check whether correct functionality is achieved.
Usually does so by using a “golden model” for co-simulation via the
SystemVerilog direct programming Interface.

The Environment is used to configure and instantiate all child components.
Environments are typically application-specific and may be modified by the
test.

The Test is the top-level verification component. The test designer may choose
to perform factory overrides of classes and set configuration values here,
which modify the child components.

As shown above, even a “Hello, World” example using the UVM requires that the
user understands how and why each of the different UVM components should be
used. The use of so many components causes UVM to have a very steep learning
curve, which may discourage adoption. This also means that UVM is not the
proper testing methodology for small designs or one-off tests due to the
initial workload. However, once the initial setup of the testbench is finished
for large and complex designs, generating new tests becomes easier.

###  VII-A Scoreboard and DPI

The purpose of the scoreboard is to ensure that the DUT matches specification.
When using directed tests (i.e. hand-written tests meant to test a single part
of the specification), this may be as simple as constructing a list of
input/output values and checking these in order. When using randomized
testing, the scoreboard is usually implemented as a software model (sometimes
called a golden model) which is defined to be correct. The software model
should exactly mimic the functionality of the DUT, and thus provide the same
outputs given the same inputs.

The scoreboard may be implemented purely in SystemVerilog, or it may be
implemented in a C-like language (C, C++ or SystemC). One of the benefits that
SystemVerilog adds to the verification environment is the ability to interface
with C-code through the use of the SystemVerilog Direct Programming Interface
(DPI). This is an interface which allows C code to be called from inside the
SystemVerilog testbench, and likewise allows for SystemVerilog code to be
called from inside of a C program. Programming low-level simulations of
hardware is most likely easier in C than in plain SystemVerilog. In listing
LABEL:lst:dpi is shown a simple example of some SystemVerilog code calling C
code through the SystemVerilog DPI.

Notice the inclusion of the header file svdpi.h, which contains the
definitions necessary for interoperability. Once this is done, the function
must be imported in SystemVerilog by use of the import "DPI-C" statement,
after which the function may be called as any other SystemVerilog function.
Using the DPI is surprisingly simple and painless, and makes it very simple to
integrate a C model in the testbench.

It should be noted that a scoreboard doesn’t necessarily ”rate” the
performance of the DUT by comparing it to other modules, as one might expect
from the name. The DUT is only compared against the reference model, and the
”rating” is how many assertions pass/fail in a given test.

⬇

1// hello.c

2#include "svdpi.h"

3#include <stdlib.h>

5void c_hello(char* name) {

6 printf("Hello␣from␣C,␣%s", name);

7}

9// hello.sv

10module tb;

11import "DPI-C" function void c_hello(string name);

13 initial main();

14 task main();

15 c_hello("SystemVerilog");

16 endtask

17endmodule

19// Outputs: "Hello from C, SystemVerilog"

Listing 4: Short example showing how to use the SystemVerilog DPI to execute
C-code from within SystemVerilog.

###  VII-B Constrained Random Verification

Most UVM testbenches employ ”Constrained Random Verification” (CRV) for
generating test stimulus. This is as opposed to using directed testing, where
input vectors are predefined to test a certain behaviour. With CRV, random
test stimuli are generated. The ”Constrained” part of CRV implies that these
values aren’t entirely random, but are chosen to fulfill a series of criteria.
If eg. the DUT is an ALU with a 5-bit opcode field of which only 20 bit-
patterns are used, it would be prudent to only generate the 20 valid opcodes
for most test purposes. Specific tests could then be written to ensure proper
operation if an invalid opcode was asserted.

An example of a class with randomized variables is seen in listing
LABEL:lst:crv.

The keyword constraint is used to constrain a variable defined with the rand
keyword. One randomized variable, bcd, is a 4-bit field which only takes on
values in the range 0 and 9. The field value has a $1/3$ chance of being 0,
$1/3$ of being 255 and $1/3$ of being any other value. The fields a,b,c must
satisfy $0<a<b<c$. The field op has no constraints, and will thus randomly
toggle between 0, 1, 2 and 3, the only values it can take on.

⬇

1//Myclass.svh

2class Myclass;

3 rand logic [3:0] bcd;

4 rand logic [7:0] value;

5 rand logic [3:0] a, b, c;

6 rand logic [1:0] op;

8 constraint c_BCD {

9 bcd inside {[0:9]};

10 }

11 constraint c_value {

12 value dist {

13 0:/1,

14 [1:254]:/1,

15 255:/1

16 };

17 }

18 constraint c_abc {

19 0 < a;

20 a < b;

21 b < c;

22 }

23 // op isn’t constrained, but is randomized

24endclass: Myclass

Listing 5: Example SystemVerilog code showing how different values are
constrained.

In listing LABEL:lst:usingcrv, an object of type Myclass is instantiated and
randomized using the mc.randomize() command. Finally, the SystemVerilog
function $display is used to print the value of the BCD field. The randomize
keyword is a SystemVerilog construct which will try to randomize all random
fields of given class.

⬇

1//top.sv

2‘include "Myclass.svh"

3‘include "Cover.svh"

4module top;

5 Myclass mc;

6 Cover cov;

7 initial begin;

8 mc = new;

9 cov = new;

10 cov.mc = mc;

11 for(int i=0; i<20; i++) begin

12 mc.randomize();

13 cov.sample();

14 end

15 end

16endmodule

Listing 6: Example SystemVerilog code showing how to instantiate and randomize
a class with random fields.

###  VII-C Coverage collection

The purpose of coverage collection, in this case functional coverage
collection, is to check whether all ”necessary” (as defined by the
verification engineer) input combinations have been generated. For the ALU
mentioned above, it might be interesting to check whether all opcodes work
correctly when asserted after a reset, and whether over/underflow flags are
correctly set when performing arithmetic operations. In general, functional
coverage is concerned with evaluating whether all functionality of a device
has been tested. This is opposed to line coverage, which evaluates which lines
of code were run during a simulation.

⬇

1//Cover.svh

2class Cover;

3 Myclass mc;

4 covergroup cg_bcd;

5 BCD: coverpoint mc.bcd {

6 bins valid[] = {[0:9]};

7 bins others = default;

8 }

9 endgroup: cg_bcd

11 covergroup cg_others;

12 VAL: coverpoint mc.value {

13 bins low = {[0:20]};

14 bins high = {[235:255]};

15 bins bad = {[110:130]};

16 bins others = default;

17 }

19 A: coverpoint mc.a;

20 OP: coverpoint mc.op {

21 bins toggle = (0 => 1);

22 }

23 cross A, OP;

24 endgroup: cg_others

26 function new();

27 cg_bcd = new;

28 cg_others = new;

29 endfunction: new

31 function void sample();

32 cg_bcd.sample();

33 cg_others.sample();

34 endfunction: sample

35endclass: Cover

Listing 7: Examle SystemVerilog code showing how covergrups and coverpoints
are organized.

An example of functional coverage collection is seen in listing LABEL:lst:cov
where the randomized values from before are covered. A covergroup is a label
used to collect relevant values under the same heading. A coverpoint is a
directive instructing the simulator that the given value should be monitored
for changes. In the declaration of the coverpoint, several bins are generated.
These bins correspond to the bins of a histogram. Every time an event occurs
which matches the declaration inside a bin, the counter associated with that
bin is incremented by one. An event may cause multiple bins to increment at
the same time.

In the coverage declarations shown in listing LABEL:lst:cov, the covergroup
cg_bcd only covers one field, bcd. The bin is labeled by prepepending BCD: in
front of the coverpoint directive. 10 bins are generated which each sample the
values 0-9, and the remaining values 10-15 are sampled into the default bin
others.

In the covergroup cg_others three coverpoints are set up. The VAL coverpoint
samples 3 ranges of values. Any value in the range [0:20]will cause the
counter on bin low to increment by one. Likewise for the other bins in that
coverpoint. The A coverpoint auto-generates one bin for each possible value it
may take on, 16 bins in total, since no bins are explicitly declared. The
coverpoint OP has one bin, toggle which only increments when mode toggles from
0x0 to 0x1. Finally, the cross statement implements cross coverage. Cross
coverage tracks what values were sampled at multiple coverpoints at the same
time.

Using the cross of A and OP, it may be possible to have 100% coverage on both
coverpoints (ie. all bins have been hit at least once), but the cross coverage
may not be at 100% if eg. OP never toggled while A was 1. Increasing the
number of random samples that are generated may alleviate this problem. If it
doesn’t, it may be indicative that something is wrong in the structure of the
testbench or DUT.

In listing LABEL:lst:usingcov, the module from LABEL:lst:usingcrv has been
expanded to also use the coverage collector.

⬇

1//top.sv

2‘include "Myclass.svh"

3‘include "Cover.svh"

4module top;

5 Myclass mc;

6 Cover cov;

7 initial begin;

8 mc = new;

9 cov = new;

10 cov.mc = mc;

11 for(int i=0; i<20; i++) begin

12 mc.randomize();

13 cov.sample();

14 end

15 end

16endmodule

Listing 8: Showcasing how multiple random values are generated and sampled by
the coverage collector.

In Figure 3, the result of running the 20 iterations is seen for coverpoints
BCD, A, VAL.

Figure 3: Coverage bins generated by running the code in listing
LABEL:lst:usingcov

###  VII-D C Integration in Scala

The SystemVerilog DPI is a great addition to the verification workflow, as it
allows the designer to easily implement a C model into the SystemVerilog
testbench. Similar functionality is available in Scala by leveraging the Java
Native Interface (JNI). This is an interface which allows Java / Scala
programs to call native code, i.e. code compiled for the specific CPU it is
running on. This is typically encountered as .DLL files on Windows or .so
files on linux.

When using Chisel and other external libraries, it is recommended to use the
Scala Build Tool (sbt) to manage the build. However, doing this makes it more
difficult to use the default JNI integration in Scala. This can be alleviated
by use of the plugin sbt-jni by Jakob Odersky.

Listing LABEL:lst:jni-scala shows an example of a Scala file with a native
function.

⬇

1import ch.jodersky.jni.nativeLoader

3nativeLoader("native0") //use NativeLoader to simplify code-reuse in other
places class Myclass // --- Native methods native def digitsum(num: Int): Int

4 native def hello(string: String): String

5}

7object Myclass {

8 // Main method to test our native library

9 def main(args: Array[String]): Unit = {

10 val mc = new MyClass

11 val sum = mc.digitsum(1234)

12 val string = mc.hello("Scala")

13 println(s"$string")

14 println(s"Digit␣sum␣is␣$sum")

16 }

17}

18//Outputs:

19//Hello from C, Scala

20//Digit sum is 10

Listing 9: Example Scala code showing how to integrate native code in Scala.

The annotation @native informs the Scala compiler that the function should be
found in native code. The annotation @nativeLoader is necessary for use with
the plugin. The name ”native0” is the name of the current SBT project,
appended with a 0.

Once the above file has been written, the corresponding C header file is
generated by running sbt javah. The contents of the generated header file
should then be copied into a C code file, where the functions can be
implemented. In this case, it may look like the contents of listing
LABEL:lst:jni-c.

⬇

1#include "MyClass.h"

2#include <stdlib.h>

4JNIEXPORT jint JNICALL Java_MyClass_digitsum

5(JNIEnv * env, jobject obj, jint num) {

6 int i = num;

7 int sum = 0;

8 while(i) {

9 sum += i % 10;

10 i = i / 10;

11 }

12 return sum;

13}

15JNIEXPORT jstring JNICALL Java_MyClass_hello

16(JNIEnv * env, jobject obj, jstring string) {

17 const char* str = (*env)->GetStringUTFChars(env, string, 0);

18 char buf[128];

19 snprintf(buf, 128, "Hello␣from␣C,␣%s", str);

20 (*env)->ReleaseStringUTFChars(env, string, str);

21 return (*env)->NewStringUTF(env,buf);

22}

Listing 10: C implementation of the methods declared in Myclass from listing
LABEL:lst:jni-scala.

Notice that primitives such as int can be autocast from a jint, whereas a
string must be obtained used using the function pointers defined in the JNIEnv
structure. Once this is done, a CMake makefile is generated by running sbt
"nativeInit cmake", and the C files are compiled using sbt nativeCompile. If
all goes well, the code can then be run with sbt run.

If changes are made to any of the function definitions or Scala file, no other
steps are necessary than running sbt run again. This will also invoke the
CMake script generation and compilation steps if necessary. If new native
methods are added to the Scala file, sbt javah must be run again to generate
new C headers.

For more information regarding the plugin setup, see the plugin page on Github
or the file HowToJni.md in the documentation repository.

##  VIII Conclusion

In this paper, we introduced ChiselVerify, an open-source solution that should
increase a verification engineer’s productivity by following the trend of
moving towards a more high-level and software like ecosystem for hardware
design. With this, we brought functional coverage, statement coverage,
constraint random verification and transactional modelling to the Chisel/Scala
ecosystem, thus allowing for the improvement of current engineer’s efficiency
and easing the way for software engineers to join the hardware verification
world.

### Acknowledgment

This work has been performed as part of the “InfinIT – Innovationsnetværk for
IT”, UFM case no. 1363-00036B, “High-Level Design and Verification of Digital
Systems”.

## References

  * [1] IEEE standard for SystemVerilog – unified hardware design, specification, and verification language, 2018.
  * [2] S. Andersen.  Vhdl2verilog.  https://github.com/chisel-uvm/vhdl2verilog.
  * [3] ARM.  Amba axi and ace protocol specification axi3, axi4, and axi4-lite ace and ace-lite.  https://developer.arm.com/documentation/ihi0022/e/.
  * [4] J. Bachrach, H. Vo, B. Richards, Y. Lee, A. Waterman, R. Avizienis, J. Wawrzynek, and K. Asanovic.  Chisel: constructing hardware in a scala embedded language.  In The 49th Annual Design Automation Conference (DAC 2012), pages 1216–1225, San Francisco, CA, USA, June 2012. ACM.
  * [5] I. D. Baxter.  Branch coverage for arbitrary languages made easy.  http://www.semdesigns.com/Company/Publications/TestCoverage.pdf, 2002.
  * [6] K. Beck, M. Beedle, A. van Bennekum, A. Cockburn, W. Cunningham, M. Fowler, J. Grenning, J. Highsmith, A. Hunt, R. Jeffries, J. Kern, B. Marick, R. C. Martin, S. Mellor, K. Schwaber, J. Sutherland, and D. Thomas.  Manifesto for agile software development.  https://agilemanifesto.org/, 2001.
  * [7] W. J. Dally, Y. Turakhia, and S. Han.  Domain-specific hardware accelerators.  Commun. ACM, 63(7):48–57, June 2020.
  * [8] Doulos.  Doulos — SystemVerilog DPI Tutorial.  http://www.doulos.com/knowhow/systemverilog/systemverilog-tutorials/systemverilog-dpi-tutorial/.
  * [9] H. Esmaeilzadeh, E. Blem, R. St. Amant, K. Sankaralingam, and D. Burger.  Dark silicon and the end of multicore scaling.  In Proceedings of the 38th Annual International Symposium on Computer Architecture, ISCA ’11, pages 365–376, New York, NY, USA, 2011. Association for Computing Machinery.
  * [10] T. Gingold.  Ghdl.  https://github.com/ghdl/ghdl.
  * [11] J. L. Hennessy and D. A. Patterson.  A new golden age for computer architecture.  Commun. ACM, 62(2):48–60, Jan. 2019.
  * [12] R. Lin.  ChiselTest.  https://github.com/ucb-bar/chisel-testers2.
  * [13] S. Russell and P. Norvig.  Artificial intelligence: a modern approach.  Prentice Hall, 2002.
  * [14] M. Schoeberl.  Digital Design with Chisel.  Kindle Direct Publishing, 2019.  available at https://github.com/schoeberl/chisel-book.
  * [15] M. Schoeberl, S. T. Andersen, K. J. H. Rasmussen, and R. Lin.  Towards an open-source verification method with chisel and scala.  In Proceedings of the Third Workshop on Open-Source EDA Technology (WOSET), 2020.
  * [16] M. Schoeberl and M. Petersen.  Leros: The return of the accumulator machine.  In M. Schoeberl, T. Pionteck, S. Uhrig, J. Brehm, and C. Hochberger, editors, Architecture of Computing Systems - ARCS 2019 - 32nd International Conference, Proceedings, pages 115–127. Springer, May 2019.
  * [17] M. Schoeberl, L. Pezzarossa, and J. Sparsø.  S4noc: a minimalistic network-on-chip for real-time multicores.  In Proceedings of the 12th International Workshop on Network on Chip Architectures, pages 8:1–8:6. ACM, October 2019.
  * [18] C. Wolf.  Yosys open synthesis suite.  http://www.clifford.at/yosys/.
  * [19] Xilinx.  Axi verification ip (vip).  https://www.xilinx.com/products/intellectual-property/axi-vip.html.


# Peccei-Quinn-like Symmetries for Nonabelian Axions

Debashis Chatterjee
Bijaygarh Jyotish Ray College, Calcutta 700032
P<EMAIL_ADDRESS>
Saha Institute of Nuclear Physics, Calcutta 700064, India

###### Abstract

Axions were first introduced in connection with chiral symmetry but are now
being looked for mainly as dark matter. In this paper we introduce a
nonabelian analogue of axions which can also be potential candidates for dark
matter. Their nonabelian symmetries, which are generalizations of the Peccei-
Quinn symmetry, are interesting in their own right. Detailed analysis, using
fermion measure and zeta function approaches, shows that these symmetries are
not anomalous.

##  1 Introduction

The chiral symmetry which holds in classical Dirac theory with massless
fermions interacting with gauge fields is broken by what is called an anomaly
[1]: the transformation

$\displaystyle\psi\rightarrow
e^{i\alpha\gamma_{5}}\psi,\quad\bar{\psi}\rightarrow\bar{\psi}e^{i\alpha\gamma_{5}},$
(1)

is a symmetry of the kinetic term $\bar{\psi}[i\not{\partial}]\psi$ and also
of the interaction term $\bar{\psi}[i\not{A}]\psi$ with the gauge field
$A_{\mu}$, but the axial current $\bar{\psi}\gamma_{\mu}\gamma_{5}\psi$, which
is classically conserved, is found to violate this conservation when the
fermion triangle diagram is regularized and evaluated. The divergence of the
axial current is finite and proportional to ${\rm tr}F\tilde{F}$ [2].

In general, a classical symmetry may or may not survive quantization. The
simple phase symmetry, whereby $\psi$ is multiplied by a phase factor, does
survive quantization for all masses $m$. To see whether a symmetry survives
quantization, the action has to be regularized. If the regularized action
still has the symmetry, the symmetry obviously has no anomaly. If the
regularized action does not possess the symmetry, one tends to think that the
symmetry has an anomaly, but there are different ways of regularizing fermion
field theories and one must check whether a different regularization can
preserve the symmetry. Familiarity with the chiral anomaly may make one
suspect all classical symmetries involving chiral rotations in any manner to
be anomalous. But whether a symmetry is anomalous or not has to be checked
individually for each symmetry.

Below we review the example of the Peccei-Quinn symmetry which occurs in the
presence of the hypothetical field called the axion and was introduced by
these authors. It has been shown to survive quantization [3]. We point out
that the symmetry can even be made local. In section II, a new nonabelian
analogue of axions is introduced: the new Peccei-Quinn symmetry too has no
anomaly, as shown by a measure analysis and a zeta function approach.

### Peccei-Quinn symmetry and the axion

Chiral symmetry is explicitly broken by the mass term $m\bar{\psi}\psi$ and
also by quantum effects, i.e. the anomaly. However, an artificial chiral
symmetry for massive fermions works by letting a new field ${\varphi}$ absorb
the chiral transformation. The mass term is replaced by [4]

$\displaystyle\bar{\psi}me^{i{\varphi}\gamma_{5}}\psi,$ (2)

which is invariant if the field $\varphi$ transforms under

$\displaystyle\psi\rightarrow
e^{i\alpha\gamma_{5}}\psi,\quad\bar{\psi}\rightarrow\bar{\psi}e^{i\alpha\gamma_{5}},\quad\varphi\rightarrow{\varphi}-2\alpha.$
(3)

This transformation leaves the action invariant provided the new field
$\varphi$ is massless. This is the Peccei-Quinn symmetry. The particle [5]
corresponding to the new field $\varphi$ introduced by them is called the
axion, but it has not been seen in any experiment [6]. It is being studied
extensively because it is expected to contribute to the elusive dark matter.
For a discussion of strong CP symmetry in the absence of axions, one may look
at [7].

Careful regularization has been shown to respect the Peccei-Quinn symmetry,
which accordingly is not anomalous but survives quantization [3].

In spite of this subtlety about the Peccei-Quinn symmetry, the axion can still
be used to remove any $F\tilde{F}$ term in the action dynamically by coupling
the axion directly to $F\tilde{F}$ so that its vacuum expectation value
cancels the coefficient of the $F\tilde{F}$ term.

Observe that the axial symmetry can be made local by introducing an extra
gauge field $B_{\mu}$ for this purpose:

$\displaystyle\bar{\psi}[i\not{D}+\not{B}\gamma_{5}-me^{i\varphi\gamma_{5}}]\psi+\frac{1}{2}F^{2}(\partial_{\mu}\varphi+2B_{\mu})(\partial^{\mu}\varphi+2B^{\mu}),$
(4)

where

$\displaystyle B_{\mu}\rightarrow B_{\mu}+\partial_{\mu}\alpha$ (5)

under a local chiral transformation. Here $F$ is a constant of mass dimension
such that the axion kinetic term is
$\frac{1}{2}F^{2}\partial_{\mu}\varphi\partial^{\mu}\varphi$ and there are
additional kinetic terms of the gauge fields. It is to be noted that this
provides a formulation of a chiral gauge theory similar to but different from
the Wess-Zumino formulation suggested in [8]. The similarity is that in both
cases there is an extra degree of freedom. The difference is that gauge
invariance occurs at both the classical and quantum levels in the present
formulation, while in the old formulation gauge invariance occurs only at the
quantum level [9].

##  2 Nonabelian chiral symmetry and nonabelian axions

The usual chiral symmetry is under a transformation of the fermion in spinor
space. If the fermion is an $SU(N)$ multiplet, there exist nonabelian chiral
symmetries. The kinetic piece

$\displaystyle\bar{\psi}i\not{\partial}\psi=\bar{\psi}_{L}i\not{\partial}\psi_{L}+\bar{\psi}_{R}i\not{\partial}\psi_{R}$
(6)

is invariant under the chiral transformations

$\displaystyle\psi_{L}\rightarrow U_{L}\psi_{L},\quad\psi_{R}\rightarrow
U_{R}\psi_{R},$ (7)

where $U_{L},U_{R}$ are spacetime independent $SU(N)$ matrices acting on the
two chiral projections of $\psi$. The gauge interactions will also be
invariant under these provided the matrix $A_{\mu}$ commutes with
$U_{L},U_{R}$. For instance, the $SU(N)$ could be a flavour group and the
colour $SU(3)$ or the $U(1)$ could be gauged.

The usual mass term $m(\bar{\psi}_{L}\psi_{R}+\bar{\psi}_{R}\psi_{L})$ is not
invariant under (7) unless $U_{L}=U_{R}$, in which case of course the
transformation is not a chiral transformation. An analogue of the Peccei-Quinn
mass term can be introduced:
$m(\bar{\psi}_{L}W\psi_{R}+\bar{\psi}_{R}W^{\dagger}\psi_{L})$. Here $W$ is a
hypothetical $SU(N)$ matrix field analogous to the axion. Considering that the
original axion has not been detected, we must be cautious about such an
object. However, just as the usual axion is expected to be a kind of dark
matter, this nonabelian object too could be relevant as dark matter. Note that
it is visualized as a new degree of freedom and not as mesonic matter. The
mathematical construction may in any case be useful for calculations because
of the symmetry. This term is invariant under (7) if $W$ transforms as

$\displaystyle W\rightarrow U_{L}WU^{\dagger}_{R}.$ (8)

As an $SU(N)$ matrix it involves $N^{2}-1$ parameters which become fields. The
kinetic term for this matrix field has to be of the form
$Tr[\partial_{\mu}W\partial^{\mu}W^{\dagger}]$, familiar from chiral models.
This is invariant under (8). Thus the full action is invariant under the
generalized Peccei-Quinn symmetry

$\displaystyle\psi_{L}\rightarrow U_{L}\psi_{L},\quad\psi_{R}\rightarrow
U_{R}\psi_{R},\quad W\rightarrow U_{L}WU^{\dagger}_{R}.$ (9)

The question now is whether this nonabelian symmetry survives quantization.
Anomalies arise when regularizations break some symmetries of classical
actions. In the functional integral approach, it is said that the action has a
symmetry which is broken by the measure [10].

### Fermion measure approach

To formulate the fermion measure, it is customary to expand the fermion field
in eigenfunctions of some operator. To maintain gauge invariance, the
covariant Dirac operator is considered. The eigenvalue equation is

$\displaystyle i\not{D}f_{n}=\lambda_{n}f_{n},$ (10)

where the subscript labels the eigenvalue and the eigenfunction. Under a gauge
transformation,

$\displaystyle D_{\mu}\rightarrow UD_{\mu}U^{-1},\quad\psi\rightarrow
U\psi,\quad\bar{\psi}\rightarrow\bar{\psi}U^{-1},$ (11)

so that

$\displaystyle f\rightarrow Uf.$ (12)

The field is expanded as

$\displaystyle\psi=\sum_{n}a_{n}f_{n},\quad\bar{\psi}=\sum_{n}\bar{a}_{n}f^{\dagger}_{n}.$
(13)

Each $a,\bar{a}$ is gauge invariant because $\psi$ and $f$ transform the same
way under gauge transformations and $\bar{\psi}$ and $f^{\dagger}$ also
transform like each other. The gauge invariant measure
$\prod_{n}da_{n}d\bar{a}_{n}$ is used for the fermion integration. It is well
known that the measure is not chirally invariant: chiral transformations alter
$a,\bar{a}$ and the change of the measure is a Jacobian which can be evaluated
after some regularization and yields the chiral anomaly. One needs measures
for other fields too, but these do not break symmetries.

Given this situation, it would appear that the Peccei-Quinn transformation
would also alter the measure. The above measure would certainly be altered,
but remembering that the requirement of gauge invariance led to the use of a
fermion measure involving the eigenfunctions of the Dirac operator which
contains the gauge field, we can involve the axion field now. First for the
abelian axion, we consider the new expansion

$\displaystyle\psi=e^{-i\varphi\gamma_{5}/2}\sum_{n}b_{n}f_{n},\quad\bar{\psi}=\sum_{n}\bar{b}_{n}f^{\dagger}_{n}e^{-i\varphi\gamma_{5}/2}.$
(14)

Although the fermion field changes under the Peccei-Quinn transformation, the
exponential factor too changes and cancels it, because of (3), leaving
$b,\bar{b}$ invariant. Hence the measure $\prod_{n}db_{n}d\bar{b}_{n}$ is
invariant under the transformation. In other words, although the naïve fermion
measure is altered by the Peccei-Quinn transformation, there does exist a
fermion measure which is left invariant. This is very similar to what happens
with regularizations. It is also similar to the alteration occurring in the
fermion measure in the presence of a twisted fermion mass term [11]. It may be
added that the measure for $\varphi$ is translation invariant.

For the $SU(N)$ version of axions, the construction of the measure is a bit
complicated. First, note that eigenvalues and eigenfunctions of $i\not{D}$
come in pairs:

$\displaystyle i\not{D}f_{n}=\lambda_{n}f_{n},\quad
i\not{D}\gamma_{5}f_{n}=-\lambda_{n}\gamma_{5}f_{n}.$ (15)

Hence it is possible to consider expansions in $f_{nL},f_{nR}$, which are
chiral combinations of the $f_{n},\gamma_{5}f_{n}$, though they are not
eigenfunctions of $i\not{D}$. We expand

$\displaystyle\psi_{L}=\sum_{n}a^{L}_{n}f_{nL},$
$\displaystyle\psi_{R}=\sum_{n}a^{R}_{n}f_{nR},$
$\displaystyle\bar{\psi}_{L}=\sum_{n}\bar{a}^{L}_{n}f^{\dagger}_{nL},$
$\displaystyle\bar{\psi}_{R}=\sum_{n}\bar{a}^{R}_{n}f^{\dagger}_{nR}.$ (16)

Of course, the range of $n$ is implicitly altered here. The measure
$\prod_{n}da^{L}_{n}da^{R}_{n}d\bar{a}^{L}_{n}d\bar{a}^{R}_{n}$ is not
invariant under an $SU(N)$ chiral transformation (7) because $a,\bar{a}$ have
to change unless $U_{L}=U_{R}$, in which case the common vector transformation
may be absorbed in $f$.

However, a new measure can be constructed using the generalized axion field.
Consider the expansions

$\displaystyle W^{\dagger}\psi_{L}=\sum_{n}b^{L}_{n}f_{nL},$
$\displaystyle\psi_{R}=\sum_{n}b^{R}_{n}f_{nR},$
$\displaystyle\bar{\psi}_{L}W=\sum_{n}\bar{b}^{L}_{n}f^{\dagger}_{nL},$
$\displaystyle\bar{\psi}_{R}=\sum_{n}\bar{b}^{R}_{n}f^{\dagger}_{nR}.$ (17)

As $W$ is invertible, it may also be transferred to the right if desired. This
construction is not unique, but serves the purpose. Note the asymmetric use of
$W$ here. Because of this asymmetry, the left hand sides of both equations in
the first line acquire $U_{R}$ under (9) and the left hand sides in the second
line acquire $U_{R}^{\dagger}$, so that the common vector factor $U_{R}$ may
be absorbed in $f$:

$\displaystyle f_{n}\rightarrow U_{R}f_{n},$ (18)

leaving the $b,\bar{b}$ invariant. This means that there exists a measure
$\prod_{n}db^{L}_{n}db^{R}_{n}d\bar{b}^{L}_{n}d\bar{b}^{R}_{n}$ invariant
under the $SU(N)$ version of the Peccei-Quinn transformation, exactly as
before. As regards the measure for $W$, it can be chosen to be $SU(N)$
invariant. So the measure respects the symmetry and the new nonabelian Peccei-
Quinn symmetry is not anomalous.

### Zeta function approach

Instead of considering a regularized action, one may also look at the fermion
determinant which then has to be regularized. The most convenient way to do
this in this context is the zeta function regularization [12]. The determinant
is that of the Dirac operator, which in the simple case of a singlet axion is

$\displaystyle i\not{D}-me^{i{\varphi}\gamma_{5}}.$ (19)

The zeta function regularization works for a hermitian, positive definite
operator, which has to be obtained by constructing the Laplacian,

$\displaystyle\Delta=[-i\not{D}-me^{-i{\varphi}\gamma_{5}}][i\not{D}-me^{i{\varphi}\gamma_{5}}].$
(20)

Here the gamma matrices have been taken to be antihermitian in euclidean
spacetime. The determinant of the Dirac operator is defined as the square root
of the determinant of $\Delta$. The anomaly has been checked in this framework
[13].

Now one can write

$\displaystyle\Delta=[-i\not{D}-me^{-i{\varphi}\gamma_{5}}]e^{i{\varphi}\gamma_{5}/2}e^{-i{\varphi}\gamma_{5}/2}[i\not{D}-me^{i{\varphi}\gamma_{5}}].$
(21)

This can be written after some formal manipulations as

$\displaystyle\Delta=e^{-i{\varphi}\gamma_{5}/2}[-i\not{D}+\not{\partial}\varphi\gamma_{5}/2-m][i\not{D}+\not{\partial}\varphi\gamma_{5}/2-m]e^{i{\varphi}\gamma_{5}/2}.$
(22)

Apart from the initial and final exponential factors, this depends on the
axion field $\varphi$ only through its derivative. When the determinant is
calculated, those exponential factors cancel. Hence, its determinant will also
involve only derivatives of this field and will be invariant under
translations thereof. But after the fermion is integrated out, the Peccei-
Quinn transformation is just a constant translation of the axion field, so the
determinant is invariant under Peccei-Quinn transformations and it has no
anomaly when the product of its eigenvalues is regularized through the zeta
function.

The case of the nonabelian Peccei-Quinn symmetry is more complicated. Here,
the Dirac operator is

$\displaystyle i\not{D}-m(WP_{R}+W^{\dagger}P_{L})$ (23)

So one needs the Laplacian

$\displaystyle\Delta=[-i\not{D}-m(W^{\dagger}P_{R}+WP_{L})][i\not{D}-m(WP_{R}+W^{\dagger}P_{L})].$
(24)

This can be recast as

$\displaystyle\Delta$ $\displaystyle=$
$\displaystyle[-i\not{D}-m(W^{\dagger}P_{R}+WP_{L})]$ (25)
$\displaystyle[V^{\dagger}P_{R}+YP_{L}][VP_{R}+Y^{\dagger}P_{L}][i\not{D}-m(WP_{R}+W^{\dagger}P_{L})],$

where $V,Y$ are some $SU(N)$ matrices to be constrained later. This becomes

$\displaystyle\Delta$ $\displaystyle=$
$\displaystyle[V^{\dagger}P_{L}+YP_{R}][-i\not{D}-i(VP_{L}+Y^{\dagger}P_{R})\not{\partial}(V^{\dagger}P_{R}+YP_{L})-m]$
(26)
$\displaystyle[i\not{D}-i\not{\partial}(VP_{L}+Y^{\dagger}P_{R})(V^{\dagger}P_{L}+YP_{R})-m][VP_{L}+Y^{\dagger}P_{R}],$

if

$\displaystyle
V^{\dagger}=WY,Y=W^{\dagger}V^{\dagger},VW=Y^{\dagger},Y^{\dagger}W^{\dagger}=V,$
(27)

which can all be satisfied by requiring $V,Y$ to obey the single relation

$\displaystyle VWY=1.$ (28)

When the determinant is calculated, the initial and final factors cancel out.
The remaining expression

$\displaystyle{\rm
det}\bigg{(}[-i\not{D}-iVP_{L}\not{\partial}V^{\dagger}-iY^{\dagger}P_{R}\not{\partial}Y-m][i\not{D}-i\not{\partial}VV^{\dagger}P_{L}-i\not{\partial}Y^{\dagger}YP_{R}-m]\bigg{)}$

involves $V,Y$ only in the combinations $V\partial
V^{\dagger},Y^{\dagger}\partial Y,\partial VV^{\dagger},\partial
Y^{\dagger}Y$. These are invariant under the Peccei-Quinn-like transformations
of $W$ whose $U_{R}$ actions are taken as left actions on $Y$ and $U_{L}$
actions as right actions on $V$ because of the constraint on $VWY$. Thus the
determinant is invariant under Peccei-Quinn-like transformations. This
persists upon zeta function regularization of the product of its eigenvalues.
Hence it is seen once again that these symmetries are not anomalous.

As there is no anomaly in the Peccei-Quinn-like symmetries, gauge fields can
again be used to extend these global chiral symmetries to local ones. For
example, for the left handed chiral symmetry, one needs an $SU(N)$ gauge field
matrix $B_{\mu}$:

$\displaystyle\bar{\psi}[i\not{D}+\not{B}P_{L}-m(WP_{R}+W^{\dagger}P_{L})]\psi$
(29) $\displaystyle+$
$\displaystyle\frac{1}{2}F^{2}Tr[(\partial_{\mu}-iB_{\mu})W(\partial^{\mu}W^{\dagger}+iW^{\dagger}B^{\mu})].$

Here the transformation of the new gauge field is given by

$\displaystyle(\partial_{\mu}-iB_{\mu})\rightarrow
U_{L}(\partial_{\mu}-iB_{\mu})U_{L}^{-1}.$ (30)

Gauge field kinetic terms have to be added. The right handed chiral symmetry
too can be gauged if desired in a similar way. This reformulation of a chiral
gauge theory in a gauge invariant way is again reminiscent of [8].

##  3 Conclusion

Symmetries which appear to be anomalous because they are not consistent with
obvious regularizations may turn out to be consistent if regularized with care
and therefore may be non-anomalous. The first known case of such a faux
anomaly is the Peccei-Quinn symmetry which arises in QCD in the presence of
axions, which are now being looked for as dark matter but have not so far been
found. Our new $SU(N)$ version of this symmetry, which holds if $SU(N)$
analogues of axions are introduced, provides the second example: a fermion
measure invariant under this symmetry has been explicitly constructed and the
determinant in the zeta function approach is also invariant under nonabelian
transformations of $W$. We hope these mathematical observations will be of as
much interest as ordinary axions in the context of dark matter. While axions
have been expected to be useful in the context of the strong CP issue, there
is no such possibility with the nonabelian analogues discussed here because
they cannot be coupled in a natural way to the gluon $F\tilde{F}$ term.
However, as they couple to quarks, they may also transform into other gauge
bosons in the same way as the ordinary axions get feebly converted to photons.
They could be detected for example as decaying Z bosons just as ordinary
axions are sought to be caught in the form of photons. Apart from this,
nonabelian axions can be of use in chiral gauge theories where they are
unphysical and get swallowed up while providing mass to gauge bosons [9].

## References

  * [1] S. Adler, Phys. Rev. 177 (1969) 2426;
J. S. Bell, & R. Jackiw, Nuovo Cim. 60 (1969) 47.

  * [2] L. Brown, R. Carlitz and C. Lee, Phys Rev. D16 (1977) 417.
  * [3] P. Mitra, Journ. Phys. Communications 1 (2017) 015002.
  * [4] R. Peccei, & H. Quinn, Phys. Rev. Letters 38 (1977) 1440;
Phys. Rev. D16 (1977) 1791.

  * [5] S. Weinberg, Phys. Rev. Letters 40 (1978) 223;
F. Wilczek, Phys. Rev. Letters 40 (1978) 279.

  * [6] P. A. Zyla et al., The Review of Particle Physics, Prog. Theor. Exp. Phys. 2020 (2020) 083C01.
  * [7] H. Banerjee, D. Chatterjee & P. Mitra, Phys. Letters B573 (2003) 109.
  * [8] L. D. Faddeev and S. L. Shatashvili, Phys. Letters B167(1986) 225.
  * [9] Chiral gauge theories and nonabelian analogues of axions, in preparation
  * [10] K. Fujikawa, Phys. Rev. D21 (1980) 2848;
K. Fujikawa, Int. J. Mod. Phys. A16 (2001) 331.

  * [11] P. Mitra, Symmetries and symmetry breaking in field theory, (CRC Press, Florida, 2014)
  * [12] E. Elizalde, S. D. Odintsov, A. Romeo, A. A. Bytsenko and S. Zerbini, Zeta regularization techniques with applications (World Scientific, Singapore, 1994)
  * [13] M. Reuter, Chiral anomalies and zeta-function regularization, Phys. Rev. D31 (1985) 1374


# Revision of results on $\Upsilon(1S)$, $\Upsilon(2S)$, and $\Upsilon(3S)$
masses

A.G. Shamov  O.L. Rezanova  Budker Institute of Nuclear Physics, 11, akademika
Lavrentieva prospect, Novosibirsk, 630090, Russia  Novosibirsk State
University, 1, Pirogova street, Novosibirsk, 630090, Russia

###### Abstract

We have reconsidered the results on the masses of the narrow bottomonium
states $\Upsilon(1S)$–$\Upsilon(3S)$ obtained in 1982–1986 at CESR, DORIS and
VEPP-4 colliders in order to fix shortcomings of the mass determination
procedures. For experiments at CESR and DORIS this includes the incorrect
accounting of the radiative corrections and usage of the electron mass value
revised in 1986. In analyses of all experiments the interference of the
resonance production and the nonresonant process was ignored. The corrected
mass values for five experiments are suggested. The corrections vary from 0.1
to 0.4 MeV. The discrepancy between CESR and VEPP-4 results on $\Upsilon(1S)$
mass has been reduced from 3.3 to 1.8 standard deviations.

Table 1: Corrections to published mass values (keV). $\Upsilon$–state | $\Upsilon(1S)$ | $\Upsilon(2S)$ | $\Upsilon(3S)$
---|---|---|---
Collider | CESR | VEPP-4 | DORIS | VEPP-4 | VEPP-4
$\sigma_{W}$ (MeV) | 3.2 | 4.5 | 8.1 | 5.3 | 5.4
Electron mass | -81 |  | -86 |  |
Radiactive corrections | -81 |  | -181 |  |
Interference | -71 | -112 | -168 | -105 | -130
Resonance shape calculation | +375 |  |  |  |
Total | +140 |  | -430 |  |
Shift with correct fit | +142 | -112 | -435 | -105 | -130

## Introduction

The new experiment on the high precision measurement of the $\Upsilon$–meson
mass has been planned at the VEPP-4M collider [1] with the KEDR detector [2].
The resonant depolarization method [3, 4] will be used for the beam energy
determination. At the moment the laser polarimeter is under development [5]
and the test scan of the $\Upsilon(1S)$ has been performed [6]. In this
context it is important to overcome known drawbacks in the analyses of the
preceding experiments and correct its results.

The mass of $\Upsilon(1S)$ was measured by the MD-1 detector at VEPP-4 [7, 8]
and CUSB detector at the collider CESR with the accuracy of about 0.1 MeV [9].
With lower accuracy of 0.4-0.5 MeV the mass of $\Upsilon(2S)$ was measured by
ARGUS and Crystal Ball detectors at DORIS [10] and by MD-1 [11]. The mass of
$\Upsilon(3S)$ was determined with 0.5 MeV uncertainty by MD-1 only [11]. In
all these experiments the mass values were obtained by fitting the inclusive
hadronic cross section as function of the c.m. energy. The beam energy was
determined using resonant depolarization method.

In 2000 the results of the mass measurements at VEPP-4 were corrected [12] to
the shift of the electron mass value occurred in 1986 [13]. The results from
CESR and DORIS stayed intact.

Another problem to solve is accounting of the radiative correction in
experiments [9] and [10] according to the work [14] containing the mistake
[15]. Despite to the existence of correct studies of the narrow resonance
production since 1975, the incorrect resonance shape from Ref. [14] was
employed for determination of leptonic widths and masses of $\psi$– and
$\Upsilon$–states in many experiments. Concerning leptonic widths the problem
was solved in Ref. [16], the corrected values were included in PDG tables.
However, the masses of $\Upsilon$ states [9] and [10] were not corrected
neither in Ref. [16] nor in Ref. [12] where radiative corrections were fixed
up for $J/\psi$ mass measurement by the OLYA detector in 1980 [17]. The MD-1
experiments on masses of upsilon states [7, 8, 11, 18] were performed with
proper radiative correction accounting.

Besides, there is a mistake in the calculation of the resonance curve in Ref.
[9], that will be discussed in details below.

The common drawback of all measurements of $\psi$– and $\Upsilon$– state
masses mentioned above is ignoring of the interference between resonant and
nonresonant contributions to the hadron production. First time it was
accounted in the $J/\psi$– and $\psi(2S)$– mass measurement in the experiment
[19] and was discussed in details in Ref. [20].

In all experiments under discussion except [9], the dependence of the hadronic
cross section on c.m. energy was not published. In Refs. [12, 16], in order to
correct the resonance leptonic width [16] and mass [12], the equidistant data
points were simulated using the published values of the resonance curve
parameters. Then two fits were performed with the correct fitting function and
that of the published paper. The variation of the resonance parameter was
added to its published value. This method uses published values of parameters,
biased by the incorrect fit, and does not account for the specific layout of
energy points.

In contrast with that, in this work we obtained coordinates of data points
from the plots in electronic versions of publications using the graphical
editor and converted them to the physical quantities. Such data were not
absolutely reliable thus we shifted published values as described above. In
Ref. [9] the measured values of cross section and the energy were published
thus we could just refit the CUSB data.

In the next sections we describe the necessary corrections, discuss data
published by CUSB [9], and then obtain corrected mass values for three
resonances from five experiments.

##  1 Change of the electron mass value

As it was mentioned above, the experiments cited did employ the resonant
depolarization method for the beam energy determination. In this method the
measured ratio of the spin precession frequency $\Omega$ and the revolution
frequency $\omega$ gives the Lorentz factor $\gamma$ according to the relation

$\Omega/\omega=1+\gamma\cdot\mu^{\prime}/\mu_{0},$ (1)

where $\mu^{\prime}$ and $\mu_{0}$ are anomalous and normal parts of the
electron magnetic moment [4]. To find the beam energy $E=\gamma\,m_{e}$, the
value of the electron mass $m_{e}$ is required. Before 1986 its accuracy was
estimated to be 2.8 ppm [21] which corresponds to 26 keV uncertainty in the
mass of $\Upsilon(1S)$. In 1986 the adjustment of fundamental physical
constants [13] led to shift of the electron mass value by -8.5 ppm with
increase of its accuracy to 0.8 ppm. The corresponding shifts of
$\Upsilon(1S)$, $\Upsilon(2S)$, and $\Upsilon(3S)$ masses are -81, -86, and
-88 keV respectively [12]. For experiments [9, 10] that was not accounted yet.

##  2 Radiative corrections

Soon after the $J/\psi$–meson discovery a number of papers appeared on the
radiative corrections for a narrow resonance production in
$e^{+}e^{-}$–collisions. First of them is probably Ref. [22] which will be
considered in the next section. However, the most popular theoretical work
used for $\psi$\- and $\Upsilon$\- data analysis until 1985 was Ref.[14]. It
was directly addressed to experimentalists and published in “Nuclear
Instruments and Methods”. The calculations were performed in the approximation
of zero resonance width. For the gaussian collider energy spread distribution

$G(W^{\prime}-W)=\frac{1}{\sqrt{2\pi}\sigma_{W}}\,\exp\biggl{(}-\frac{(W^{\prime}-W)^{2}}{2\sigma_{W}^{2}}\biggr{)}$
(2)

the narrow resonance cross section in a final state $f$ at the c.m. energy $W$
was obtained in the form

$\begin{split}\sigma^{\text{R}\to
f}(W)&=\frac{6\pi^{2}}{M^{2}}\,\frac{\Gamma^{(0)}_{ee}\Gamma_{f}}{\Gamma}\,\biggl{(}G_{r}(W-M)+\delta\cdot
G(W-M)\biggr{)},\\\
G_{r}(x)&=\left(\frac{2\sigma_{W}}{M}\right)^{\\!\\!\beta}\frac{\Gamma(1+\beta)}{\sqrt{2\pi}\sigma_{W}}\exp\left(-\frac{x^{2}}{4\sigma_{W}^{2}}\right)D_{-\beta}\left(-\frac{x}{\sigma_{w}}\right),\\\
\delta&=\frac{13}{12}\,\beta+\frac{2\alpha}{\pi}\left(\frac{\pi^{2}}{6}-\frac{17}{36}\right),\>\>\beta=\frac{4\alpha}{\pi}\left(\ln\frac{W}{m_{e}}-\frac{1}{2}\right),\end{split}$
(3)

where $\alpha$ is the fine structure constant, $m_{e}$ is the electron mass,
$\Gamma()$ is the gamma-function and $D_{-\beta}$ is the Weber function of
parabolic cylinder for calculation of which the power series were specified.
The electron partial widths $\Gamma^{(0)}_{ee}$ corresponds to the lowest
order of QED. The $\delta$ includes the vertex corrections and contribution of
electron loops into the vacuum polarization, other contributions are
neglected.

The $G_{r}$ function in (3) is so called “radiative gaussian”, which is a
convolution of the collider energy spread with the probability of the energy
loss due to soft photon radiation in $e^{+}e^{-}$–collision. It is known that
the probability of the QED process which is not accompanied by such emission
is zero, therefore the second term in eq. (3) is not correct. There must be
$\delta\cdot G_{r}(W\\!-\\!M)$. The $G(x)$-function unlike to $G_{r}(x)$ is
symmetric, thus using of eq. (3) for data analysis increase the
$\Upsilon(1S)$–mass by about 0.1 MeV at the energy spread $\sigma_{W}\simeq 5$
MeV, as was noted in [8].

##  3 Interference effect

The interference effects in the inclusive hadronic cross section in the
vicinity of a narrow resonance was considered already in Ref. [22]. With some
up-today modifications the resonant and interference terms in the soft photon
approximation can be written as [20]

$\begin{split}\sigma^{\text{r+i}}(W)&=\frac{12}{W^{2}}(1+\delta)\left(\frac{\Gamma_{ee}\tilde{\Gamma}_{h}}{\Gamma
M}\,\mbox{Im}f(W)-\frac{2\alpha\sqrt{R\Gamma_{ee}\tilde{\Gamma}_{h}}}{3W}\lambda\,\mbox{Re}\frac{f^{*}(W)}{1-\Pi_{0}}\right)\\!,\\\
\delta&=\frac{3}{4}\beta+\frac{\alpha}{\pi}\left(\frac{\pi^{2}}{3}-\frac{1}{2}\right)+\beta^{2}\left(\frac{37}{96}-\frac{\pi^{2}}{12}-\frac{1}{36}\ln\frac{W}{m_{\rm
e}}\right)\\!.\\\
f(W)&=\frac{\pi\beta}{\sin{\pi\beta}}\,\Bigg{(}\frac{W^{2}}{M^{2}-W^{2}-iM\Gamma}\Bigg{)}^{1-\beta}\\!\\!\\!\\!\\!.\end{split}$
(4)

Here $R$ is the hadron-to-muon cross section ratio out of the resonance peak,
$\Pi_{0}$ is the vacuum polarization with the resonance contribution excluded,
$\Gamma_{ee}\\!=\\!\Gamma^{(0)}_{ee}/|1-\Pi_{0}|^{2}$ is the physical value of
the electron width, $\tilde{\Gamma}_{h}$ is some effective value of the
hadronic partial width, and $\lambda$ is the parameter introduced in Ref. [22]
to characterize the strength of the interference effects. Due to the
interference of electromagnetic and strong decays of the resonance,
$\tilde{\Gamma}_{h}$ differs from the true hadronic partial width
$\Gamma_{h}$, but the value of $\tilde{\Gamma}_{h}$ is not of first importance
to the mass determination. The problem is discussed in details in Ref. [20].
The following result was obtained for $\lambda$:

$\lambda=\sqrt{\frac{R\mathcal{B}_{ee}}{\mathcal{B}_{h}}}+\sqrt{\frac{1}{\mathcal{B}_{h}}}\,\sum\limits_{m}\\!\sqrt{b_{m}\mathcal{B}^{(s)}_{m}\,}\left<\cos{\phi_{m}}\right>\,.$
(5)

The sum in Eq. (5) is performed over all hadronic modes, $\mathcal{B}_{ee}$
and $\mathcal{B}_{h}$ are the resonance decay probabilities to
$e^{+}e^{-}$–pairs and hadrons, respectively,
$\mathcal{B}^{(s)}_{m}\\!=\\!\Gamma^{(s)}_{m}/\Gamma$ is related to the strong
contribution to the decay mode $m$, process, $\phi_{m}$ is its phase relative
to the electromagnetic contribution and $b_{m}\\!=\\!R_{m}/R$ is the branching
fraction of the corresponding continuum. The angle brackets denote averaging
over the decay products phase space.

Following Ref. [23], we assumed that the relative phases of the strong and
electromagnetic amplitudes in different decay modes are not correlated, thus
the second term of Eq. (5) can be neglected compared to the first one, which
is about 0.31, 0.27 and 0.29 for $\Upsilon(1S)$, $\Upsilon(2S)$ and
$\Upsilon(3S)$, respectively. The same value of $\lambda$ follows from naive
parton model in which $q\bar{q}$, $ggg$ and $gg\gamma$ decay modes are
considered. For $J/\psi$-meson the measurement gave $\lambda_{J/\psi}=0.45\pm
0.07\pm 0.04$ at the expected value of 0.39 [23]. Scaling this result to
$\Upsilon(nS)$, one obtains the mass uncertainty estimate of about
$4.10^{-3}\sigma_{W}$. The correction grows with the value of the energy
spread, see Table 1 above.

Figure 1: (Color online) The profile of the $\Upsilon(1S)$ as measured with
the CUSB detector [9]. The red open circles and the dashed curve are digitized
from Fig. 10 of the paper. The blue closed circles correspond to the data
points from the published table. The blue curve shows our fit with Eq. (3).

##  4 Reanalysis of CUSB data

During the $\Upsilon(1S)$ mass measurement at the CESR collider with the CUSB
detector, 22 runs were recorded, which were jointed in 11 data points for the
fit. The beam energy during runs were determined using the value of bend
magnetic field measured with NMR according to linear relation
$E=A(B\\!-\\!B_{0})\\!+\\!C$, where $B$ is a measured NMR value and $B_{0}$ is
some reference one. The constants $A$ and $C$ were obtained by fitting of 10
measurements of the beam energy with the resonance depolarization method.

The data point number, the NMR value, the number of hadronic events, the
integrated luminosity and the cross section for each run were presented at
Table I of Ref. [9].

In Figure 1 the data points calculated by us using Table I and published
values of $A$, $C$ and $B_{0}$ are compared with these extracted from Fig. 10
of Ref. [9] using the GIMP graphical editor. Both energies and cross sections
of the points agree within the accuracy achieved with the editor. However, the
curves of the fits performed using the same formulae and with the same value
of the electron mass differ. We have checked our calculation comparing the
results obtained in the zero-width approximation using two different
implementations of the Weber function and those obtained using numerical
convolution of Eq.(4) with the gaussian energy spread. The three our results
agree with each other thus we conclude that the mass value published in Ref.
[9] is not fully correct and should be shifted by +0.375 MeV.

There is a question to Table I concerning assignment of the run 14 to the
point 8, its NMR value is closer to those of the point 9. This might be a
misprint. Blue closed points in Figure 1 are shown for the proper run-to-point
assignment. The corresponding change of the mass value is negligible.

##  5 Values of corrections to $\Upsilon(1S)$–$\Upsilon(3S)$ masses

The corrections to mass values obtained in five experiments due to effects
considered are presented in Table 1. The sum of corrections calculated
separately is in a good agreement with the shift obtained with the correct
fit. The uncertainty of reanalysis due to accuracy of the vacuum polarization
data is 1–2 keV. The similar error is connected to digitization of journal
plots. They do not reduce the accuracy of experimental data.

## Conclusion

The results of five experiments on the precision measurements of masses of
narrow $\Upsilon$ states were reanalyzed to remove substantial drawbacks of
original analyses. The following results were obtained:

$\displaystyle\text{M}_{\Upsilon(1S)}=$ $\displaystyle 9460.40\pm 0.09$
$\displaystyle\\!\\!\\!\\!\pm\>0.04\>\>\text{MeV}\>\text{(MD-1
\cite[cite]{[\@@bibref{Number}{mdU1S1992}{}{}]})}.$
$\displaystyle\text{M}_{\Upsilon(1S)}=$ $\displaystyle 9460.11\pm 0.11$
$\displaystyle\\!\\!\\!\\!\pm\>0.07\>\>\text{MeV}\>\text{(CUSB
\cite[cite]{[\@@bibref{Number}{cusbY1S}{}{}]})}.$

$\displaystyle\text{M}_{\Upsilon(2S)}=$ $\displaystyle 10023.4\pm 0.5$
$\displaystyle\\!\\!\text{MeV}\>\text{(MD-1
\cite[cite]{[\@@bibref{Number}{md1Y13}{}{}]})}.$
$\displaystyle\text{M}_{\Upsilon(2S)}=$ $\displaystyle 10022.7\pm 0.4$
$\displaystyle\\!\\!\text{MeV}\>\text{(ARGUS+CB
\cite[cite]{[\@@bibref{Number}{dorisY2S}{}{}]}) }.$
$\displaystyle\text{M}_{\Upsilon(3S)}=$ $\displaystyle 10355.1\pm 0.5$
$\displaystyle\\!\\!\text{MeV}\>\text{(MD-1
\cite[cite]{[\@@bibref{Number}{md1Y13}{}{}]})}.$

The discrepancy between MD-1 and CUSB results on the $\Upsilon(1S)$ mass has
been reduced from 3.3 to 1.8 standard deviations. The mean value of two
experiments, calculated according the PDG rules with the scale factor of 1.8
is

$\text{M}_{\Upsilon(1S)}=9460.29\pm 0.15\>\text{MeV}.$

The uncertainty is reduced from 0.33 to 0.15 MeV.

We appeal the Particle Data Group to accept these mass values as it was done
with the leptonic widths recalculated in Ref. [16].

## References

  * [1] V.E. Blinov et al., Phys. Part. Nucl. Lett. 11 (2014) 620.
  * [2] V. V. Anashin et al., Phys. of Part. and Nucl. 44 (2013) 657.
  * [3] A.D.Bukin it et al., Proceed. of the Vth Int. Symposium on High Energy and Elem. Particle Physics, Warsaw, September 1975, p.138.
  * [4] Ya.S.Derbenev et al., Part. Acc. 10 (1980) 177.
  * [5] V. E. Blinov et al., JINST 15 (2020) C08024.
  * [6] P. Piminov et al., doi:10.18429/JACoW-RuPAC2021-TUA01,
  * [7] A. S. Artamonov et al. [MD-1 collaboration], Phys. Lett. B 118 (1982) 225.
  * [8] S. E. Baru et al., Z. Phys. C 30 (1986), 551.
  * [9] W. W. MacKay et al. [CUSB], Phys. Rev. D 29 (1984), 2483.
  * [10] D. P. Barber et al. [ARGUS and Crystal Ball], Phys. Lett. B 135 (1984), 498.
  * [11] A. S. Artamonov et al. [MD-1 collaboration], Phys. Lett. B 137 (1984), 272,
  * [12] A. S. Artamonov et al. [OLYA and MD-1], Phys. Lett. B 474 (2000), 427.
  * [13] E. R. Cohen and B. N. Taylor, Rev. Mod. Phys. 59 (1987), 1121.
  * [14] J.D.Jackson and D.L.Scharre, NIM 128(I975)13
  * [15] E. A. Kuraev and V. S. Fadin, Sov. J. Nucl. Phys. 41 (1985) 466
  * [16] J. P. Alexander et al., Nucl. Phys. B 320 (1989) 45.
  * [17] A. A. Zholents et al., Phys. Lett. B 96 (1980) 214.
  * [18] S. E. Baru al. [MD-1 collaboration], Z. Phys. C56 (1992) 547.
  * [19] V. M. Aulchenko et al. [KEDR Collaboration], Phys. Lett. B 573 (2003) 63.
  * [20] V. V. Anashin et al. [KEDR Collaboration], Phys. Lett. B 711 (2012) 280.
  * [21] E. R. Cohen and B. N. Taylor, J. Phys. Chem. Ref. Data 2 (1973) 664.
  * [22] Y. I. Azimov, A. I. Vainshtein, L. N. Lipatov and V. A. Khoze, Pisma Zh. Eksp. Teor. Fiz. 21 (1975) 378.
  * [23] V. V. Anashin et al. [KEDR collaboration], Phys. Lett. B 749 (2015) 50.