mirror of https://github.com/YosysHQ/yosys.git
Replace 010 and 012 with pdf
Comment out the body text and instead include just the abstract and a download link. Also orphan the pages so they aren't accessible except by direct link, or via search.
This commit is contained in:
parent
17749ce688
commit
abd92225a3
Binary file not shown.
Binary file not shown.
|
@ -9,9 +9,6 @@ Appendix
|
||||||
appendix/auxlibs
|
appendix/auxlibs
|
||||||
appendix/auxprogs
|
appendix/auxprogs
|
||||||
|
|
||||||
appendix/APPNOTE_010_Verilog_to_BLIF.rst
|
|
||||||
appendix/APPNOTE_012_Verilog_to_BTOR.rst
|
|
||||||
|
|
||||||
bib
|
bib
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
|
|
@ -1,333 +1,363 @@
|
||||||
|
:orphan:
|
||||||
|
|
||||||
====================================
|
====================================
|
||||||
010: Converting Verilog to BLIF page
|
010: Converting Verilog to BLIF page
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
Installation
|
Abstract
|
||||||
============
|
========
|
||||||
|
|
||||||
Yosys written in C++ (using features from C++11) and is tested on modern
|
Verilog-2005 is a powerful Hardware Description Language (HDL) that can be used
|
||||||
Linux. It should compile fine on most UNIX systems with a C++11
|
to easily create complex designs from small HDL code. It is the preferred method
|
||||||
compiler. The README file contains useful information on building Yosys
|
of design entry for many designers.
|
||||||
and its prerequisites.
|
|
||||||
|
|
||||||
Yosys is a large and feature-rich program with a couple of dependencies.
|
|
||||||
It is, however, possible to deactivate some of the dependencies in the
|
|
||||||
Makefile, resulting in features in Yosys becoming unavailable. When
|
|
||||||
problems with building Yosys are encountered, a user who is only
|
|
||||||
interested in the features of Yosys that are discussed in this
|
|
||||||
Application Note may deactivate TCL, Qt and MiniSAT support in the
|
|
||||||
Makefile and may opt against building yosys-abc.
|
|
||||||
|
|
||||||
This Application Note is based on `Yosys GIT`_ `Rev. e216e0e`_ from 2013-11-23.
|
The Berkeley Logic Interchange Format (BLIF) is a simple file format for
|
||||||
The Verilog sources used for the examples are taken from `yosys-bigsim`_, a
|
exchanging sequential logic between programs. It is easy to generate and easy to
|
||||||
collection of real-world designs used for regression testing Yosys.
|
parse and is therefore the preferred method of design entry for many authors of
|
||||||
|
logic synthesis tools.
|
||||||
|
|
||||||
.. _Yosys GIT: https://github.com/YosysHQ/yosys
|
Yosys is a feature-rich Open-Source Verilog synthesis tool that can be used to
|
||||||
|
bridge the gap between the two file formats. It implements most of Verilog-2005
|
||||||
|
and thus can be used to import modern behavioral Verilog designs into BLIF-based
|
||||||
|
design flows without dependencies on proprietary synthesis tools.
|
||||||
|
|
||||||
.. _Rev. e216e0e: https://github.com/YosysHQ/yosys/tree/e216e0e
|
The scope of Yosys goes of course far beyond Verilog logic synthesis. But it is
|
||||||
|
a useful and important feature and this Application Note will focus on this
|
||||||
|
aspect of Yosys.
|
||||||
|
|
||||||
.. _yosys-bigsim: https://github.com/YosysHQ/yosys-bigsim
|
Download
|
||||||
|
========
|
||||||
|
|
||||||
Getting started
|
This document was originally published in April 2015:
|
||||||
===============
|
:download:`Converting Verilog to BLIF PDF</_downloads/APPNOTE_012_Verilog_to_BTOR.pdf>`
|
||||||
|
|
||||||
We start our tour with the Navré processor from yosys-bigsim. The `Navré
|
..
|
||||||
processor`_ is an Open Source AVR clone. It is a single module (softusb_navre)
|
Installation
|
||||||
in a single design file (softusb_navre.v). It also is using only features that
|
============
|
||||||
map nicely to the BLIF format, for example it only uses synchronous resets.
|
|
||||||
|
|
||||||
.. _Navré processor: http://opencores.org/projects/navre
|
|
||||||
|
|
||||||
Converting softusb_navre.v to softusb_navre.blif could not be easier:
|
|
||||||
|
|
||||||
.. code:: sh
|
|
||||||
|
|
||||||
yosys -o softusb_navre.blif -S softusb_navre.v
|
|
||||||
|
|
||||||
Behind the scenes Yosys is controlled by synthesis scripts that execute
|
Yosys written in C++ (using features from C++11) and is tested on modern
|
||||||
commands that operate on Yosys' internal state. For example, the -o
|
Linux. It should compile fine on most UNIX systems with a C++11
|
||||||
softusb_navre.blif option just adds the command write_blif
|
compiler. The README file contains useful information on building Yosys
|
||||||
softusb_navre.blif to the end of the script. Likewise a file on the
|
and its prerequisites.
|
||||||
command line – softusb_navre.v in this case – adds the command
|
|
||||||
read_verilog softusb_navre.v to the beginning of the synthesis script.
|
Yosys is a large and feature-rich program with a couple of dependencies.
|
||||||
In both cases the file type is detected from the file extension.
|
It is, however, possible to deactivate some of the dependencies in the
|
||||||
|
Makefile, resulting in features in Yosys becoming unavailable. When
|
||||||
|
problems with building Yosys are encountered, a user who is only
|
||||||
|
interested in the features of Yosys that are discussed in this
|
||||||
|
Application Note may deactivate TCL, Qt and MiniSAT support in the
|
||||||
|
Makefile and may opt against building yosys-abc.
|
||||||
|
|
||||||
Finally the option -S instantiates a built-in default synthesis script.
|
This Application Note is based on `Yosys GIT`_ `Rev. e216e0e`_ from 2013-11-23.
|
||||||
Instead of using -S one could also specify the synthesis commands for
|
The Verilog sources used for the examples are taken from `yosys-bigsim`_, a
|
||||||
the script on the command line using the -p option, either using
|
collection of real-world designs used for regression testing Yosys.
|
||||||
individual options for each command or by passing one big command string
|
|
||||||
with a semicolon-separated list of commands. But in most cases it is
|
|
||||||
more convenient to use an actual script file.
|
|
||||||
|
|
||||||
Using a synthesis script
|
.. _Yosys GIT: https://github.com/YosysHQ/yosys
|
||||||
========================
|
|
||||||
|
|
||||||
With a script file we have better control over Yosys. The following
|
.. _Rev. e216e0e: https://github.com/YosysHQ/yosys/tree/e216e0e
|
||||||
script file replicates what the command from the last section did:
|
|
||||||
|
|
||||||
.. code:: yoscrypt
|
.. _yosys-bigsim: https://github.com/YosysHQ/yosys-bigsim
|
||||||
|
|
||||||
read_verilog softusb_navre.v
|
Getting started
|
||||||
hierarchy
|
===============
|
||||||
proc; opt; memory; opt; techmap; opt
|
|
||||||
write_blif softusb_navre.blif
|
We start our tour with the Navré processor from yosys-bigsim. The `Navré
|
||||||
|
processor`_ is an Open Source AVR clone. It is a single module (softusb_navre)
|
||||||
The first and last line obviously read the Verilog file and write the
|
in a single design file (softusb_navre.v). It also is using only features that
|
||||||
BLIF file.
|
map nicely to the BLIF format, for example it only uses synchronous resets.
|
||||||
|
|
||||||
The 2nd line checks the design hierarchy and instantiates parametrized
|
.. _Navré processor: http://opencores.org/projects/navre
|
||||||
versions of the modules in the design, if necessary. In the case of this
|
|
||||||
simple design this is a no-op. However, as a general rule a synthesis
|
Converting softusb_navre.v to softusb_navre.blif could not be easier:
|
||||||
script should always contain this command as first command after reading
|
|
||||||
the input files.
|
.. code:: sh
|
||||||
|
|
||||||
The 3rd line does most of the actual work:
|
yosys -o softusb_navre.blif -S softusb_navre.v
|
||||||
|
|
||||||
- The command opt is the Yosys' built-in optimizer. It can perform some
|
Behind the scenes Yosys is controlled by synthesis scripts that execute
|
||||||
simple optimizations such as const-folding and removing unconnected
|
commands that operate on Yosys' internal state. For example, the -o
|
||||||
parts of the design. It is common practice to call opt after each
|
softusb_navre.blif option just adds the command write_blif
|
||||||
major step in the synthesis procedure. In cases where too much
|
softusb_navre.blif to the end of the script. Likewise a file on the
|
||||||
optimization is not appreciated (for example when analyzing a
|
command line – softusb_navre.v in this case – adds the command
|
||||||
design), it is recommended to call clean instead of opt.
|
read_verilog softusb_navre.v to the beginning of the synthesis script.
|
||||||
|
In both cases the file type is detected from the file extension.
|
||||||
- The command proc converts processes (Yosys' internal representation
|
|
||||||
of Verilog always- and initial-blocks) to circuits of multiplexers
|
Finally the option -S instantiates a built-in default synthesis script.
|
||||||
and storage elements (various types of flip-flops).
|
Instead of using -S one could also specify the synthesis commands for
|
||||||
|
the script on the command line using the -p option, either using
|
||||||
- The command memory converts Yosys' internal representations of arrays
|
individual options for each command or by passing one big command string
|
||||||
and array accesses to multi-port block memories, and then maps this
|
with a semicolon-separated list of commands. But in most cases it is
|
||||||
block memories to address decoders and flip-flops, unless the option
|
more convenient to use an actual script file.
|
||||||
-nomap is used, in which case the multi-port block memories stay in
|
|
||||||
the design and can then be mapped to architecture-specific memory
|
Using a synthesis script
|
||||||
primitives using other commands.
|
========================
|
||||||
|
|
||||||
- The command techmap turns a high-level circuit with coarse grain
|
With a script file we have better control over Yosys. The following
|
||||||
cells such as wide adders and multipliers to a fine-grain circuit of
|
script file replicates what the command from the last section did:
|
||||||
simple logic primitives and single-bit storage elements. The command
|
|
||||||
does that by substituting the complex cells by circuits of simpler
|
.. code:: yoscrypt
|
||||||
cells. It is possible to provide a custom set of rules for this
|
|
||||||
process in the form of a Verilog source file, as we will see in the
|
read_verilog softusb_navre.v
|
||||||
next section.
|
hierarchy
|
||||||
|
proc; opt; memory; opt; techmap; opt
|
||||||
Now Yosys can be run with the filename of the synthesis script as
|
write_blif softusb_navre.blif
|
||||||
argument:
|
|
||||||
|
The first and last line obviously read the Verilog file and write the
|
||||||
.. code:: sh
|
BLIF file.
|
||||||
|
|
||||||
yosys softusb_navre.ys
|
The 2nd line checks the design hierarchy and instantiates parametrized
|
||||||
|
versions of the modules in the design, if necessary. In the case of this
|
||||||
Now that we are using a synthesis script we can easily modify how Yosys
|
simple design this is a no-op. However, as a general rule a synthesis
|
||||||
synthesizes the design. The first thing we should customize is the call
|
script should always contain this command as first command after reading
|
||||||
to the hierarchy command:
|
the input files.
|
||||||
|
|
||||||
Whenever it is known that there are no implicit blackboxes in the
|
The 3rd line does most of the actual work:
|
||||||
design, i.e. modules that are referenced but are not defined, the
|
|
||||||
hierarchy command should be called with the -check option. This will
|
- The command opt is the Yosys' built-in optimizer. It can perform some
|
||||||
then cause synthesis to fail when implicit blackboxes are found in the
|
simple optimizations such as const-folding and removing unconnected
|
||||||
design.
|
parts of the design. It is common practice to call opt after each
|
||||||
|
major step in the synthesis procedure. In cases where too much
|
||||||
The 2nd thing we can improve regarding the hierarchy command is that we
|
optimization is not appreciated (for example when analyzing a
|
||||||
can tell it the name of the top level module of the design hierarchy. It
|
design), it is recommended to call clean instead of opt.
|
||||||
will then automatically remove all modules that are not referenced from
|
|
||||||
this top level module.
|
- The command proc converts processes (Yosys' internal representation
|
||||||
|
of Verilog always- and initial-blocks) to circuits of multiplexers
|
||||||
For many designs it is also desired to optimize the encodings for the
|
and storage elements (various types of flip-flops).
|
||||||
finite state machines (FSMs) in the design. The fsm command finds FSMs,
|
|
||||||
extracts them, performs some basic optimizations and then generate a
|
- The command memory converts Yosys' internal representations of arrays
|
||||||
circuit from the extracted and optimized description. It would also be
|
and array accesses to multi-port block memories, and then maps this
|
||||||
possible to tell the fsm command to leave the FSMs in their extracted
|
block memories to address decoders and flip-flops, unless the option
|
||||||
form, so they can be further processed using custom commands. But in
|
-nomap is used, in which case the multi-port block memories stay in
|
||||||
this case we don't want that.
|
the design and can then be mapped to architecture-specific memory
|
||||||
|
primitives using other commands.
|
||||||
So now we have the final synthesis script for generating a BLIF file for
|
|
||||||
the Navré CPU:
|
- The command techmap turns a high-level circuit with coarse grain
|
||||||
|
cells such as wide adders and multipliers to a fine-grain circuit of
|
||||||
.. code:: yoscrypt
|
simple logic primitives and single-bit storage elements. The command
|
||||||
|
does that by substituting the complex cells by circuits of simpler
|
||||||
read_verilog softusb_navre.v
|
cells. It is possible to provide a custom set of rules for this
|
||||||
hierarchy -check -top softusb_navre
|
process in the form of a Verilog source file, as we will see in the
|
||||||
proc; opt; memory; opt; fsm; opt; techmap; opt
|
next section.
|
||||||
write_blif softusb_navre.blif
|
|
||||||
|
Now Yosys can be run with the filename of the synthesis script as
|
||||||
Advanced example: The Amber23 ARMv2a CPU
|
argument:
|
||||||
========================================
|
|
||||||
|
.. code:: sh
|
||||||
Our 2nd example is the `Amber23 ARMv2a CPU`_. Once again we base our example on
|
|
||||||
the Verilog code that is included in `yosys-bigsim`_.
|
yosys softusb_navre.ys
|
||||||
|
|
||||||
.. _Amber23 ARMv2a CPU: http://opencores.org/projects/amber
|
Now that we are using a synthesis script we can easily modify how Yosys
|
||||||
|
synthesizes the design. The first thing we should customize is the call
|
||||||
.. code-block:: yoscrypt
|
to the hierarchy command:
|
||||||
:caption: `amber23.ys`
|
|
||||||
:name: amber23.ys
|
Whenever it is known that there are no implicit blackboxes in the
|
||||||
|
design, i.e. modules that are referenced but are not defined, the
|
||||||
read_verilog a23_alu.v
|
hierarchy command should be called with the -check option. This will
|
||||||
read_verilog a23_barrel_shift_fpga.v
|
then cause synthesis to fail when implicit blackboxes are found in the
|
||||||
read_verilog a23_barrel_shift.v
|
design.
|
||||||
read_verilog a23_cache.v
|
|
||||||
read_verilog a23_coprocessor.v
|
The 2nd thing we can improve regarding the hierarchy command is that we
|
||||||
read_verilog a23_core.v
|
can tell it the name of the top level module of the design hierarchy. It
|
||||||
read_verilog a23_decode.v
|
will then automatically remove all modules that are not referenced from
|
||||||
read_verilog a23_execute.v
|
this top level module.
|
||||||
read_verilog a23_fetch.v
|
|
||||||
read_verilog a23_multiply.v
|
For many designs it is also desired to optimize the encodings for the
|
||||||
read_verilog a23_ram_register_bank.v
|
finite state machines (FSMs) in the design. The fsm command finds FSMs,
|
||||||
read_verilog a23_register_bank.v
|
extracts them, performs some basic optimizations and then generate a
|
||||||
read_verilog a23_wishbone.v
|
circuit from the extracted and optimized description. It would also be
|
||||||
read_verilog generic_sram_byte_en.v
|
possible to tell the fsm command to leave the FSMs in their extracted
|
||||||
read_verilog generic_sram_line_en.v
|
form, so they can be further processed using custom commands. But in
|
||||||
hierarchy -check -top a23_core
|
this case we don't want that.
|
||||||
add -global_input globrst 1
|
|
||||||
proc -global_arst globrst
|
So now we have the final synthesis script for generating a BLIF file for
|
||||||
techmap -map adff2dff.v
|
the Navré CPU:
|
||||||
opt; memory; opt; fsm; opt; techmap
|
|
||||||
write_blif amber23.blif
|
.. code:: yoscrypt
|
||||||
|
|
||||||
The problem with this core is that it contains no dedicated reset logic. Instead
|
read_verilog softusb_navre.v
|
||||||
the coding techniques shown in :numref:`glob_arst` are used to define reset
|
hierarchy -check -top softusb_navre
|
||||||
values for the global asynchronous reset in an FPGA implementation. This design
|
proc; opt; memory; opt; fsm; opt; techmap; opt
|
||||||
can not be expressed in BLIF as it is. Instead we need to use a synthesis script
|
write_blif softusb_navre.blif
|
||||||
that transforms this form to synchronous resets that can be expressed in BLIF.
|
|
||||||
|
Advanced example: The Amber23 ARMv2a CPU
|
||||||
(Note that there is no problem if this coding techniques are used to model ROM,
|
========================================
|
||||||
where the register is initialized using this syntax but is never updated
|
|
||||||
otherwise.)
|
Our 2nd example is the `Amber23 ARMv2a CPU`_. Once again we base our example on
|
||||||
|
the Verilog code that is included in `yosys-bigsim`_.
|
||||||
:numref:`amber23.ys` shows the synthesis script for the Amber23 core. In line 17
|
|
||||||
the add command is used to add a 1-bit wide global input signal with the name
|
.. _Amber23 ARMv2a CPU: http://opencores.org/projects/amber
|
||||||
``globrst``. That means that an input with that name is added to each module in the
|
|
||||||
design hierarchy and then all module instantiations are altered so that this new
|
.. code-block:: yoscrypt
|
||||||
signal is connected throughout the whole design hierarchy.
|
:caption: `amber23.ys`
|
||||||
|
:name: amber23.ys
|
||||||
.. code-block:: verilog
|
|
||||||
:caption: Implicit coding of global asynchronous resets
|
read_verilog a23_alu.v
|
||||||
:name: glob_arst
|
read_verilog a23_barrel_shift_fpga.v
|
||||||
|
read_verilog a23_barrel_shift.v
|
||||||
reg [7:0] a = 13, b;
|
read_verilog a23_cache.v
|
||||||
initial b = 37;
|
read_verilog a23_coprocessor.v
|
||||||
|
read_verilog a23_core.v
|
||||||
.. code-block:: verilog
|
read_verilog a23_decode.v
|
||||||
:caption: `adff2dff.v`
|
read_verilog a23_execute.v
|
||||||
:name: adff2dff.v
|
read_verilog a23_fetch.v
|
||||||
|
read_verilog a23_multiply.v
|
||||||
(* techmap_celltype = "$adff" *)
|
read_verilog a23_ram_register_bank.v
|
||||||
module adff2dff (CLK, ARST, D, Q);
|
read_verilog a23_register_bank.v
|
||||||
|
read_verilog a23_wishbone.v
|
||||||
parameter WIDTH = 1;
|
read_verilog generic_sram_byte_en.v
|
||||||
parameter CLK_POLARITY = 1;
|
read_verilog generic_sram_line_en.v
|
||||||
parameter ARST_POLARITY = 1;
|
hierarchy -check -top a23_core
|
||||||
parameter ARST_VALUE = 0;
|
add -global_input globrst 1
|
||||||
|
proc -global_arst globrst
|
||||||
input CLK, ARST;
|
techmap -map adff2dff.v
|
||||||
input [WIDTH-1:0] D;
|
opt; memory; opt; fsm; opt; techmap
|
||||||
output reg [WIDTH-1:0] Q;
|
write_blif amber23.blif
|
||||||
|
|
||||||
wire [1023:0] _TECHMAP_DO_ = "proc";
|
The problem with this core is that it contains no dedicated reset logic. Instead
|
||||||
|
the coding techniques shown in :numref:`glob_arst` are used to define reset
|
||||||
wire _TECHMAP_FAIL_ =
|
values for the global asynchronous reset in an FPGA implementation. This design
|
||||||
!CLK_POLARITY || !ARST_POLARITY;
|
can not be expressed in BLIF as it is. Instead we need to use a synthesis script
|
||||||
|
that transforms this form to synchronous resets that can be expressed in BLIF.
|
||||||
always @(posedge CLK)
|
|
||||||
if (ARST)
|
(Note that there is no problem if this coding techniques are used to model ROM,
|
||||||
Q <= ARST_VALUE;
|
where the register is initialized using this syntax but is never updated
|
||||||
else
|
otherwise.)
|
||||||
Q <= D;
|
|
||||||
|
:numref:`amber23.ys` shows the synthesis script for the Amber23 core. In line 17
|
||||||
endmodule
|
the add command is used to add a 1-bit wide global input signal with the name
|
||||||
|
``globrst``. That means that an input with that name is added to each module in the
|
||||||
In line 18 the :cmd:ref:`proc` command is called. But in this script the signal
|
design hierarchy and then all module instantiations are altered so that this new
|
||||||
name globrst is passed to the command as a global reset signal for resetting the
|
signal is connected throughout the whole design hierarchy.
|
||||||
registers to their assigned initial values.
|
|
||||||
|
.. code-block:: verilog
|
||||||
Finally in line 19 the techmap command is used to replace all instances of
|
:caption: Implicit coding of global asynchronous resets
|
||||||
flip-flops with asynchronous resets with flip-flops with synchronous resets. The
|
:name: glob_arst
|
||||||
map file used for this is shown in :numref:`adff2dff.v`. Note how the
|
|
||||||
``techmap_celltype`` attribute is used in line 1 to tell the techmap command
|
reg [7:0] a = 13, b;
|
||||||
which cells to replace in the design, how the ``_TECHMAP_FAIL_`` wire in lines
|
initial b = 37;
|
||||||
15 and 16 (which evaluates to a constant value) determines if the parameter set
|
|
||||||
is compatible with this replacement circuit, and how the ``_TECHMAP_DO_`` wire
|
.. code-block:: verilog
|
||||||
in line 13 provides a mini synthesis-script to be used to process this cell.
|
:caption: `adff2dff.v`
|
||||||
|
:name: adff2dff.v
|
||||||
.. code-block:: c
|
|
||||||
:caption: Test program for the Amber23 CPU (Sieve of Eratosthenes). Compiled
|
(* techmap_celltype = "$adff" *)
|
||||||
using GCC 4.6.3 for ARM with ``-Os -marm -march=armv2a
|
module adff2dff (CLK, ARST, D, Q);
|
||||||
-mno-thumb-interwork -ffreestanding``, linked with ``--fix-v4bx``
|
|
||||||
set and booted with a custom setup routine written in ARM assembler.
|
parameter WIDTH = 1;
|
||||||
:name: sieve
|
parameter CLK_POLARITY = 1;
|
||||||
|
parameter ARST_POLARITY = 1;
|
||||||
#include <stdint.h>
|
parameter ARST_VALUE = 0;
|
||||||
#include <stdbool.h>
|
|
||||||
|
input CLK, ARST;
|
||||||
#define BITMAP_SIZE 64
|
input [WIDTH-1:0] D;
|
||||||
#define OUTPORT 0x10000000
|
output reg [WIDTH-1:0] Q;
|
||||||
|
|
||||||
static uint32_t bitmap[BITMAP_SIZE/32];
|
wire [1023:0] _TECHMAP_DO_ = "proc";
|
||||||
|
|
||||||
static void bitmap_set(uint32_t idx) { bitmap[idx/32] |= 1 << (idx % 32); }
|
wire _TECHMAP_FAIL_ =
|
||||||
static bool bitmap_get(uint32_t idx) { return (bitmap[idx/32] & (1 << (idx % 32))) != 0; }
|
!CLK_POLARITY || !ARST_POLARITY;
|
||||||
static void output(uint32_t val) { *((volatile uint32_t*)OUTPORT) = val; }
|
|
||||||
|
always @(posedge CLK)
|
||||||
int main() {
|
if (ARST)
|
||||||
uint32_t i, j, k;
|
Q <= ARST_VALUE;
|
||||||
output(2);
|
else
|
||||||
for (i = 0; i < BITMAP_SIZE; i++) {
|
Q <= D;
|
||||||
if (bitmap_get(i)) continue;
|
|
||||||
output(3+2*i);
|
endmodule
|
||||||
for (j = 2*(3+2*i);; j += 3+2*i) {
|
|
||||||
if (j%2 == 0) continue;
|
In line 18 the :cmd:ref:`proc` command is called. But in this script the signal
|
||||||
k = (j-3)/2;
|
name globrst is passed to the command as a global reset signal for resetting the
|
||||||
if (k >= BITMAP_SIZE) break;
|
registers to their assigned initial values.
|
||||||
bitmap_set(k);
|
|
||||||
}
|
Finally in line 19 the techmap command is used to replace all instances of
|
||||||
}
|
flip-flops with asynchronous resets with flip-flops with synchronous resets. The
|
||||||
output(0);
|
map file used for this is shown in :numref:`adff2dff.v`. Note how the
|
||||||
return 0;
|
``techmap_celltype`` attribute is used in line 1 to tell the techmap command
|
||||||
}
|
which cells to replace in the design, how the ``_TECHMAP_FAIL_`` wire in lines
|
||||||
|
15 and 16 (which evaluates to a constant value) determines if the parameter set
|
||||||
Verification of the Amber23 CPU
|
is compatible with this replacement circuit, and how the ``_TECHMAP_DO_`` wire
|
||||||
===============================
|
in line 13 provides a mini synthesis-script to be used to process this cell.
|
||||||
|
|
||||||
The BLIF file for the Amber23 core, generated using :numref:`amber23.ys` and
|
.. code-block:: c
|
||||||
:numref:`adff2dff.v` and the version of the Amber23 RTL source that is bundled
|
:caption: Test program for the Amber23 CPU (Sieve of Eratosthenes). Compiled
|
||||||
with yosys-bigsim, was verified using the test-bench from yosys-bigsim. It
|
using GCC 4.6.3 for ARM with ``-Os -marm -march=armv2a
|
||||||
successfully executed the program shown in :numref:`sieve` in the test-bench.
|
-mno-thumb-interwork -ffreestanding``, linked with ``--fix-v4bx``
|
||||||
|
set and booted with a custom setup routine written in ARM assembler.
|
||||||
For simulation the BLIF file was converted back to Verilog using `ABC`_. So this
|
:name: sieve
|
||||||
test includes the successful transformation of the BLIF file into ABC's internal
|
|
||||||
format as well.
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
.. _ABC: https://github.com/berkeley-abc/abc
|
|
||||||
|
#define BITMAP_SIZE 64
|
||||||
The only thing left to write about the simulation itself is that it probably was
|
#define OUTPORT 0x10000000
|
||||||
one of the most energy inefficient and time consuming ways of successfully
|
|
||||||
calculating the first 31 primes the author has ever conducted.
|
static uint32_t bitmap[BITMAP_SIZE/32];
|
||||||
|
|
||||||
Limitations
|
static void bitmap_set(uint32_t idx) { bitmap[idx/32] |= 1 << (idx % 32); }
|
||||||
===========
|
static bool bitmap_get(uint32_t idx) { return (bitmap[idx/32] & (1 << (idx % 32))) != 0; }
|
||||||
|
static void output(uint32_t val) { *((volatile uint32_t*)OUTPORT) = val; }
|
||||||
At the time of this writing Yosys does not support multi-dimensional memories,
|
|
||||||
does not support writing to individual bits of array elements, does not support
|
int main() {
|
||||||
initialization of arrays with ``$readmemb`` and ``$readmemh``, and has only
|
uint32_t i, j, k;
|
||||||
limited support for tristate logic, to name just a few limitations.
|
output(2);
|
||||||
|
for (i = 0; i < BITMAP_SIZE; i++) {
|
||||||
That being said, Yosys can synthesize an overwhelming majority of real-world
|
if (bitmap_get(i)) continue;
|
||||||
Verilog RTL code. The remaining cases can usually be modified to be compatible
|
output(3+2*i);
|
||||||
with Yosys quite easily.
|
for (j = 2*(3+2*i);; j += 3+2*i) {
|
||||||
|
if (j%2 == 0) continue;
|
||||||
The various designs in yosys-bigsim are a good place to look for examples of
|
k = (j-3)/2;
|
||||||
what is within the capabilities of Yosys.
|
if (k >= BITMAP_SIZE) break;
|
||||||
|
bitmap_set(k);
|
||||||
Conclusion
|
}
|
||||||
==========
|
}
|
||||||
|
output(0);
|
||||||
Yosys is a feature-rich Verilog-2005 synthesis tool. It has many uses, but one
|
return 0;
|
||||||
is to provide an easy gateway from high-level Verilog code to low-level logic
|
}
|
||||||
circuits.
|
|
||||||
|
Verification of the Amber23 CPU
|
||||||
The command line option ``-S`` can be used to quickly synthesize Verilog code to
|
===============================
|
||||||
BLIF files without a hassle.
|
|
||||||
|
The BLIF file for the Amber23 core, generated using :numref:`amber23.ys` and
|
||||||
With custom synthesis scripts it becomes possible to easily perform high-level
|
:numref:`adff2dff.v` and the version of the Amber23 RTL source that is bundled
|
||||||
optimizations, such as re-encoding FSMs. In some extreme cases, such as the
|
with yosys-bigsim, was verified using the test-bench from yosys-bigsim. It
|
||||||
Amber23 ARMv2 CPU, the more advanced Yosys features can be used to change a
|
successfully executed the program shown in :numref:`sieve` in the test-bench.
|
||||||
design to fit a certain need without actually touching the RTL code.
|
|
||||||
|
For simulation the BLIF file was converted back to Verilog using `ABC`_. So this
|
||||||
|
test includes the successful transformation of the BLIF file into ABC's internal
|
||||||
|
format as well.
|
||||||
|
|
||||||
|
.. _ABC: https://github.com/berkeley-abc/abc
|
||||||
|
|
||||||
|
The only thing left to write about the simulation itself is that it probably was
|
||||||
|
one of the most energy inefficient and time consuming ways of successfully
|
||||||
|
calculating the first 31 primes the author has ever conducted.
|
||||||
|
|
||||||
|
Limitations
|
||||||
|
===========
|
||||||
|
|
||||||
|
At the time of this writing Yosys does not support multi-dimensional memories,
|
||||||
|
does not support writing to individual bits of array elements, does not support
|
||||||
|
initialization of arrays with ``$readmemb`` and ``$readmemh``, and has only
|
||||||
|
limited support for tristate logic, to name just a few limitations.
|
||||||
|
|
||||||
|
That being said, Yosys can synthesize an overwhelming majority of real-world
|
||||||
|
Verilog RTL code. The remaining cases can usually be modified to be compatible
|
||||||
|
with Yosys quite easily.
|
||||||
|
|
||||||
|
The various designs in yosys-bigsim are a good place to look for examples of
|
||||||
|
what is within the capabilities of Yosys.
|
||||||
|
|
||||||
|
Conclusion
|
||||||
|
==========
|
||||||
|
|
||||||
|
Yosys is a feature-rich Verilog-2005 synthesis tool. It has many uses, but one
|
||||||
|
is to provide an easy gateway from high-level Verilog code to low-level logic
|
||||||
|
circuits.
|
||||||
|
|
||||||
|
The command line option ``-S`` can be used to quickly synthesize Verilog code to
|
||||||
|
BLIF files without a hassle.
|
||||||
|
|
||||||
|
With custom synthesis scripts it becomes possible to easily perform high-level
|
||||||
|
optimizations, such as re-encoding FSMs. In some extreme cases, such as the
|
||||||
|
Amber23 ARMv2 CPU, the more advanced Yosys features can be used to change a
|
||||||
|
design to fit a certain need without actually touching the RTL code.
|
||||||
|
|
|
@ -1,333 +1,353 @@
|
||||||
|
:orphan:
|
||||||
|
|
||||||
====================================
|
====================================
|
||||||
012: Converting Verilog to BTOR page
|
012: Converting Verilog to BTOR page
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
Installation
|
Abstract
|
||||||
============
|
========
|
||||||
|
|
||||||
Yosys written in C++ (using features from C++11) and is tested on modern Linux.
|
Verilog-2005 is a powerful Hardware Description Language (HDL) that can be used
|
||||||
It should compile fine on most UNIX systems with a C++11 compiler. The README
|
to easily create complex designs from small HDL code. BTOR is a bit-precise
|
||||||
file contains useful information on building Yosys and its prerequisites.
|
word-level format for model checking. It is a simple format and easy to parse.
|
||||||
|
It allows to model the model checking problem over the theory of bit-vectors
|
||||||
|
with one-dimensional arrays, thus enabling to model Verilog designs with
|
||||||
|
registers and memories. Yosys is an Open-Source Verilog synthesis tool that can
|
||||||
|
be used to convert Verilog designs with simple assertions to BTOR format.
|
||||||
|
|
||||||
Yosys is a large and feature-rich program with some dependencies. For this work,
|
Download
|
||||||
we may deactivate other extra features such as TCL and ABC support in the
|
========
|
||||||
Makefile.
|
|
||||||
|
|
||||||
This Application Note is based on `Yosys GIT`_ `Rev. 082550f` from 2015-04-04.
|
This document was originally published in November 2013:
|
||||||
|
:download:`Converting Verilog to BTOR PDF</_downloads/APPNOTE_012_Verilog_to_BTOR.pdf>`
|
||||||
|
|
||||||
.. _Yosys GIT: https://github.com/YosysHQ/yosys
|
..
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
.. _Rev. 082550f: https://github.com/YosysHQ/yosys/tree/082550f
|
Yosys written in C++ (using features from C++11) and is tested on modern Linux.
|
||||||
|
It should compile fine on most UNIX systems with a C++11 compiler. The README
|
||||||
|
file contains useful information on building Yosys and its prerequisites.
|
||||||
|
|
||||||
Quick start
|
Yosys is a large and feature-rich program with some dependencies. For this work,
|
||||||
===========
|
we may deactivate other extra features such as TCL and ABC support in the
|
||||||
|
Makefile.
|
||||||
|
|
||||||
We assume that the Verilog design is synthesizable and we also assume that the
|
This Application Note is based on `Yosys GIT`_ `Rev. 082550f` from 2015-04-04.
|
||||||
design does not have multi-dimensional memories. As BTOR implicitly initializes
|
|
||||||
registers to zero value and memories stay uninitialized, we assume that the
|
|
||||||
Verilog design does not contain initial blocks. For more details about the BTOR
|
|
||||||
format, please refer to :cite:p:`btor`.
|
|
||||||
|
|
||||||
We provide a shell script ``verilog2btor.sh`` which can be used to convert a
|
.. _Yosys GIT: https://github.com/YosysHQ/yosys
|
||||||
Verilog design to BTOR. The script can be found in the ``backends/btor``
|
|
||||||
directory. The following example shows its usage:
|
|
||||||
|
|
||||||
.. code:: sh
|
.. _Rev. 082550f: https://github.com/YosysHQ/yosys/tree/082550f
|
||||||
|
|
||||||
verilog2btor.sh fsm.v fsm.btor test
|
Quick start
|
||||||
|
===========
|
||||||
|
|
||||||
The script ``verilog2btor.sh`` takes three parameters. In the above example, the
|
We assume that the Verilog design is synthesizable and we also assume that the
|
||||||
first parameter ``fsm.v`` is the input design, the second parameter ``fsm.btor``
|
design does not have multi-dimensional memories. As BTOR implicitly initializes
|
||||||
is the file name of BTOR output, and the third parameter ``test`` is the name of
|
registers to zero value and memories stay uninitialized, we assume that the
|
||||||
top module in the design.
|
Verilog design does not contain initial blocks. For more details about the BTOR
|
||||||
|
format, please refer to :cite:p:`btor`.
|
||||||
|
|
||||||
To specify the properties (that need to be checked), we have two
|
We provide a shell script ``verilog2btor.sh`` which can be used to convert a
|
||||||
options:
|
Verilog design to BTOR. The script can be found in the ``backends/btor``
|
||||||
|
directory. The following example shows its usage:
|
||||||
|
|
||||||
- We can use the Verilog ``assert`` statement in the procedural block or module
|
.. code:: sh
|
||||||
body of the Verilog design, as shown in :numref:`specifying_property_assert`.
|
|
||||||
This is the preferred option.
|
|
||||||
|
|
||||||
- We can use a single-bit output wire, whose name starts with ``safety``. The
|
verilog2btor.sh fsm.v fsm.btor test
|
||||||
value of this output wire needs to be driven low when the property is met,
|
|
||||||
i.e. the solver will try to find a model that makes the safety pin go high.
|
|
||||||
This is demonstrated in :numref:`specifying_property_output`.
|
|
||||||
|
|
||||||
.. code-block:: verilog
|
The script ``verilog2btor.sh`` takes three parameters. In the above example, the
|
||||||
:caption: Specifying property in Verilog design with ``assert``
|
first parameter ``fsm.v`` is the input design, the second parameter ``fsm.btor``
|
||||||
:name: specifying_property_assert
|
is the file name of BTOR output, and the third parameter ``test`` is the name of
|
||||||
|
top module in the design.
|
||||||
|
|
||||||
module test(input clk, input rst, output y);
|
To specify the properties (that need to be checked), we have two
|
||||||
|
options:
|
||||||
|
|
||||||
reg [2:0] state;
|
- We can use the Verilog ``assert`` statement in the procedural block or module
|
||||||
|
body of the Verilog design, as shown in :numref:`specifying_property_assert`.
|
||||||
|
This is the preferred option.
|
||||||
|
|
||||||
always @(posedge clk) begin
|
- We can use a single-bit output wire, whose name starts with ``safety``. The
|
||||||
if (rst || state == 3) begin
|
value of this output wire needs to be driven low when the property is met,
|
||||||
state <= 0;
|
i.e. the solver will try to find a model that makes the safety pin go high.
|
||||||
end else begin
|
This is demonstrated in :numref:`specifying_property_output`.
|
||||||
assert(state < 3);
|
|
||||||
state <= state + 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign y = state[2];
|
.. code-block:: verilog
|
||||||
|
:caption: Specifying property in Verilog design with ``assert``
|
||||||
|
:name: specifying_property_assert
|
||||||
|
|
||||||
assert property (y !== 1'b1);
|
module test(input clk, input rst, output y);
|
||||||
|
|
||||||
endmodule
|
reg [2:0] state;
|
||||||
|
|
||||||
.. code-block:: verilog
|
always @(posedge clk) begin
|
||||||
:caption: Specifying property in Verilog design with output wire
|
if (rst || state == 3) begin
|
||||||
:name: specifying_property_output
|
state <= 0;
|
||||||
|
end else begin
|
||||||
|
assert(state < 3);
|
||||||
|
state <= state + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
module test(input clk, input rst,
|
assign y = state[2];
|
||||||
output y, output safety1);
|
|
||||||
|
|
||||||
reg [2:0] state;
|
assert property (y !== 1'b1);
|
||||||
|
|
||||||
always @(posedge clk) begin
|
endmodule
|
||||||
if (rst || state == 3)
|
|
||||||
state <= 0;
|
|
||||||
else
|
|
||||||
state <= state + 1;
|
|
||||||
end
|
|
||||||
|
|
||||||
assign y = state[2];
|
.. code-block:: verilog
|
||||||
|
:caption: Specifying property in Verilog design with output wire
|
||||||
|
:name: specifying_property_output
|
||||||
|
|
||||||
assign safety1 = !(y !== 1'b1);
|
module test(input clk, input rst,
|
||||||
|
output y, output safety1);
|
||||||
|
|
||||||
endmodule
|
reg [2:0] state;
|
||||||
|
|
||||||
We can run `Boolector`_ ``1.4.1`` [1]_ on the generated BTOR file:
|
always @(posedge clk) begin
|
||||||
|
if (rst || state == 3)
|
||||||
|
state <= 0;
|
||||||
|
else
|
||||||
|
state <= state + 1;
|
||||||
|
end
|
||||||
|
|
||||||
.. _Boolector: http://fmv.jku.at/boolector/
|
assign y = state[2];
|
||||||
|
|
||||||
.. code:: sh
|
assign safety1 = !(y !== 1'b1);
|
||||||
|
|
||||||
$ boolector fsm.btor
|
endmodule
|
||||||
unsat
|
|
||||||
|
|
||||||
We can also use `nuXmv`_, but on BTOR designs it does not support memories yet.
|
We can run `Boolector`_ ``1.4.1`` [1]_ on the generated BTOR file:
|
||||||
With the next release of nuXmv, we will be also able to verify designs with
|
|
||||||
memories.
|
|
||||||
|
|
||||||
.. _nuXmv: https://es-static.fbk.eu/tools/nuxmv/index.php
|
.. _Boolector: http://fmv.jku.at/boolector/
|
||||||
|
|
||||||
Detailed flow
|
.. code:: sh
|
||||||
=============
|
|
||||||
|
|
||||||
Yosys is able to synthesize Verilog designs up to the gate level. We are
|
$ boolector fsm.btor
|
||||||
interested in keeping registers and memories when synthesizing the design. For
|
unsat
|
||||||
this purpose, we describe a customized Yosys synthesis flow, that is also
|
|
||||||
provided by the ``verilog2btor.sh`` script. :numref:`btor_script_memory` shows
|
|
||||||
the Yosys commands that are executed by ``verilog2btor.sh``.
|
|
||||||
|
|
||||||
.. code-block:: yoscrypt
|
We can also use `nuXmv`_, but on BTOR designs it does not support memories yet.
|
||||||
:caption: Synthesis Flow for BTOR with memories
|
With the next release of nuXmv, we will be also able to verify designs with
|
||||||
:name: btor_script_memory
|
memories.
|
||||||
|
|
||||||
read_verilog -sv $1;
|
.. _nuXmv: https://es-static.fbk.eu/tools/nuxmv/index.php
|
||||||
hierarchy -top $3; hierarchy -libdir $DIR;
|
|
||||||
hierarchy -check;
|
|
||||||
proc; opt;
|
|
||||||
opt_expr -mux_undef; opt;
|
|
||||||
rename -hide;;;
|
|
||||||
splice; opt;
|
|
||||||
memory_dff -wr_only; memory_collect;;
|
|
||||||
flatten;;
|
|
||||||
memory_unpack;
|
|
||||||
splitnets -driver;
|
|
||||||
setundef -zero -undriven;
|
|
||||||
opt;;;
|
|
||||||
write_btor $2;
|
|
||||||
|
|
||||||
Here is short description of what is happening in the script line by
|
Detailed flow
|
||||||
line:
|
=============
|
||||||
|
|
||||||
#. Reading the input file.
|
Yosys is able to synthesize Verilog designs up to the gate level. We are
|
||||||
|
interested in keeping registers and memories when synthesizing the design. For
|
||||||
|
this purpose, we describe a customized Yosys synthesis flow, that is also
|
||||||
|
provided by the ``verilog2btor.sh`` script. :numref:`btor_script_memory` shows
|
||||||
|
the Yosys commands that are executed by ``verilog2btor.sh``.
|
||||||
|
|
||||||
#. Setting the top module in the hierarchy and trying to read automatically the
|
.. code-block:: yoscrypt
|
||||||
files which are given as ``include`` in the file read in first line.
|
:caption: Synthesis Flow for BTOR with memories
|
||||||
|
:name: btor_script_memory
|
||||||
|
|
||||||
#. Checking the design hierarchy.
|
read_verilog -sv $1;
|
||||||
|
hierarchy -top $3; hierarchy -libdir $DIR;
|
||||||
|
hierarchy -check;
|
||||||
|
proc; opt;
|
||||||
|
opt_expr -mux_undef; opt;
|
||||||
|
rename -hide;;;
|
||||||
|
splice; opt;
|
||||||
|
memory_dff -wr_only; memory_collect;;
|
||||||
|
flatten;;
|
||||||
|
memory_unpack;
|
||||||
|
splitnets -driver;
|
||||||
|
setundef -zero -undriven;
|
||||||
|
opt;;;
|
||||||
|
write_btor $2;
|
||||||
|
|
||||||
#. Converting processes to multiplexers (muxs) and flip-flops.
|
Here is short description of what is happening in the script line by
|
||||||
|
line:
|
||||||
|
|
||||||
#. Removing undef signals from muxs.
|
#. Reading the input file.
|
||||||
|
|
||||||
#. Hiding all signal names that are not used as module ports.
|
#. Setting the top module in the hierarchy and trying to read automatically the
|
||||||
|
files which are given as ``include`` in the file read in first line.
|
||||||
|
|
||||||
#. Explicit type conversion, by introducing slice and concat cells in the
|
#. Checking the design hierarchy.
|
||||||
circuit.
|
|
||||||
|
|
||||||
#. Converting write memories to synchronous memories, and collecting the
|
#. Converting processes to multiplexers (muxs) and flip-flops.
|
||||||
memories to multi-port memories.
|
|
||||||
|
|
||||||
#. Flattening the design to get only one module.
|
#. Removing undef signals from muxs.
|
||||||
|
|
||||||
#. Separating read and write memories.
|
#. Hiding all signal names that are not used as module ports.
|
||||||
|
|
||||||
#. Splitting the signals that are partially assigned
|
#. Explicit type conversion, by introducing slice and concat cells in the
|
||||||
|
circuit.
|
||||||
|
|
||||||
#. Setting undef to zero value.
|
#. Converting write memories to synchronous memories, and collecting the
|
||||||
|
memories to multi-port memories.
|
||||||
|
|
||||||
#. Final optimization pass.
|
#. Flattening the design to get only one module.
|
||||||
|
|
||||||
#. Writing BTOR file.
|
#. Separating read and write memories.
|
||||||
|
|
||||||
For detailed description of the commands mentioned above, please refer
|
#. Splitting the signals that are partially assigned
|
||||||
to the Yosys documentation, or run ``yosys -h <command_name>``.
|
|
||||||
|
#. Setting undef to zero value.
|
||||||
The script presented earlier can be easily modified to have a BTOR file that
|
|
||||||
does not contain memories. This is done by removing the line number 8 and 10,
|
#. Final optimization pass.
|
||||||
and introduces a new command :cmd:ref:`memory` at line number 8.
|
|
||||||
:numref:`btor_script_without_memory` shows the modified Yosys script file:
|
#. Writing BTOR file.
|
||||||
|
|
||||||
.. code-block:: sh
|
For detailed description of the commands mentioned above, please refer
|
||||||
:caption: Synthesis Flow for BTOR without memories
|
to the Yosys documentation, or run ``yosys -h <command_name>``.
|
||||||
:name: btor_script_without_memory
|
|
||||||
|
The script presented earlier can be easily modified to have a BTOR file that
|
||||||
read_verilog -sv $1;
|
does not contain memories. This is done by removing the line number 8 and 10,
|
||||||
hierarchy -top $3; hierarchy -libdir $DIR;
|
and introduces a new command :cmd:ref:`memory` at line number 8.
|
||||||
hierarchy -check;
|
:numref:`btor_script_without_memory` shows the modified Yosys script file:
|
||||||
proc; opt;
|
|
||||||
opt_expr -mux_undef; opt;
|
.. code-block:: sh
|
||||||
rename -hide;;;
|
:caption: Synthesis Flow for BTOR without memories
|
||||||
splice; opt;
|
:name: btor_script_without_memory
|
||||||
memory;;
|
|
||||||
flatten;;
|
read_verilog -sv $1;
|
||||||
splitnets -driver;
|
hierarchy -top $3; hierarchy -libdir $DIR;
|
||||||
setundef -zero -undriven;
|
hierarchy -check;
|
||||||
opt;;;
|
proc; opt;
|
||||||
write_btor $2;
|
opt_expr -mux_undef; opt;
|
||||||
|
rename -hide;;;
|
||||||
Example
|
splice; opt;
|
||||||
=======
|
memory;;
|
||||||
|
flatten;;
|
||||||
Here is an example Verilog design that we want to convert to BTOR:
|
splitnets -driver;
|
||||||
|
setundef -zero -undriven;
|
||||||
.. code-block:: verilog
|
opt;;;
|
||||||
:caption: Example - Verilog Design
|
write_btor $2;
|
||||||
:name: example_verilog
|
|
||||||
|
Example
|
||||||
module array(input clk);
|
=======
|
||||||
|
|
||||||
reg [7:0] counter;
|
Here is an example Verilog design that we want to convert to BTOR:
|
||||||
reg [7:0] mem [7:0];
|
|
||||||
|
.. code-block:: verilog
|
||||||
always @(posedge clk) begin
|
:caption: Example - Verilog Design
|
||||||
counter <= counter + 8'd1;
|
:name: example_verilog
|
||||||
mem[counter] <= counter;
|
|
||||||
end
|
module array(input clk);
|
||||||
|
|
||||||
assert property (!(counter > 8'd0) ||
|
reg [7:0] counter;
|
||||||
mem[counter - 8'd1] == counter - 8'd1);
|
reg [7:0] mem [7:0];
|
||||||
|
|
||||||
endmodule
|
always @(posedge clk) begin
|
||||||
|
counter <= counter + 8'd1;
|
||||||
The generated BTOR file that contain memories, using the script shown in
|
mem[counter] <= counter;
|
||||||
:numref:`btor_memory`:
|
end
|
||||||
|
|
||||||
.. code-block::
|
assert property (!(counter > 8'd0) ||
|
||||||
:caption: Example - Converted BTOR with memory
|
mem[counter - 8'd1] == counter - 8'd1);
|
||||||
:name: btor_memory
|
|
||||||
|
endmodule
|
||||||
1 var 1 clk
|
|
||||||
2 array 8 3
|
The generated BTOR file that contain memories, using the script shown in
|
||||||
3 var 8 $auto$rename.cc:150:execute$20
|
:numref:`btor_memory`:
|
||||||
4 const 8 00000001
|
|
||||||
5 sub 8 3 4
|
.. code-block::
|
||||||
6 slice 3 5 2 0
|
:caption: Example - Converted BTOR with memory
|
||||||
7 read 8 2 6
|
:name: btor_memory
|
||||||
8 slice 3 3 2 0
|
|
||||||
9 add 8 3 4
|
1 var 1 clk
|
||||||
10 const 8 00000000
|
2 array 8 3
|
||||||
11 ugt 1 3 10
|
3 var 8 $auto$rename.cc:150:execute$20
|
||||||
12 not 1 11
|
4 const 8 00000001
|
||||||
13 const 8 11111111
|
5 sub 8 3 4
|
||||||
14 slice 1 13 0 0
|
6 slice 3 5 2 0
|
||||||
15 one 1
|
7 read 8 2 6
|
||||||
16 eq 1 1 15
|
8 slice 3 3 2 0
|
||||||
17 and 1 16 14
|
9 add 8 3 4
|
||||||
18 write 8 3 2 8 3
|
10 const 8 00000000
|
||||||
19 acond 8 3 17 18 2
|
11 ugt 1 3 10
|
||||||
20 anext 8 3 2 19
|
12 not 1 11
|
||||||
21 eq 1 7 5
|
13 const 8 11111111
|
||||||
22 or 1 12 21
|
14 slice 1 13 0 0
|
||||||
23 const 1 1
|
15 one 1
|
||||||
24 one 1
|
16 eq 1 1 15
|
||||||
25 eq 1 23 24
|
17 and 1 16 14
|
||||||
26 cond 1 25 22 24
|
18 write 8 3 2 8 3
|
||||||
27 root 1 -26
|
19 acond 8 3 17 18 2
|
||||||
28 cond 8 1 9 3
|
20 anext 8 3 2 19
|
||||||
29 next 8 3 28
|
21 eq 1 7 5
|
||||||
|
22 or 1 12 21
|
||||||
And the BTOR file obtained by the script shown in
|
23 const 1 1
|
||||||
:numref:`btor_without_memory`, which expands the memory into individual
|
24 one 1
|
||||||
elements:
|
25 eq 1 23 24
|
||||||
|
26 cond 1 25 22 24
|
||||||
.. code-block::
|
27 root 1 -26
|
||||||
:caption: Example - Converted BTOR with memory
|
28 cond 8 1 9 3
|
||||||
:name: btor_without_memory
|
29 next 8 3 28
|
||||||
|
|
||||||
1 var 1 clk
|
And the BTOR file obtained by the script shown in
|
||||||
2 var 8 mem[0]
|
:numref:`btor_without_memory`, which expands the memory into individual
|
||||||
3 var 8 $auto$rename.cc:150:execute$20
|
elements:
|
||||||
4 slice 3 3 2 0
|
|
||||||
5 slice 1 4 0 0
|
.. code-block::
|
||||||
6 not 1 5
|
:caption: Example - Converted BTOR with memory
|
||||||
7 slice 1 4 1 1
|
:name: btor_without_memory
|
||||||
8 not 1 7
|
|
||||||
9 slice 1 4 2 2
|
1 var 1 clk
|
||||||
10 not 1 9
|
2 var 8 mem[0]
|
||||||
11 and 1 8 10
|
3 var 8 $auto$rename.cc:150:execute$20
|
||||||
12 and 1 6 11
|
4 slice 3 3 2 0
|
||||||
13 cond 8 12 3 2
|
5 slice 1 4 0 0
|
||||||
14 cond 8 1 13 2
|
6 not 1 5
|
||||||
15 next 8 2 14
|
7 slice 1 4 1 1
|
||||||
16 const 8 00000001
|
8 not 1 7
|
||||||
17 add 8 3 16
|
9 slice 1 4 2 2
|
||||||
18 const 8 00000000
|
10 not 1 9
|
||||||
19 ugt 1 3 18
|
11 and 1 8 10
|
||||||
20 not 1 19
|
12 and 1 6 11
|
||||||
21 var 8 mem[2]
|
13 cond 8 12 3 2
|
||||||
22 and 1 7 10
|
14 cond 8 1 13 2
|
||||||
23 and 1 6 22
|
15 next 8 2 14
|
||||||
24 cond 8 23 3 21
|
16 const 8 00000001
|
||||||
25 cond 8 1 24 21
|
17 add 8 3 16
|
||||||
26 next 8 21 25
|
18 const 8 00000000
|
||||||
27 sub 8 3 16
|
19 ugt 1 3 18
|
||||||
|
20 not 1 19
|
||||||
...
|
21 var 8 mem[2]
|
||||||
|
22 and 1 7 10
|
||||||
54 cond 1 53 50 52
|
23 and 1 6 22
|
||||||
55 root 1 -54
|
24 cond 8 23 3 21
|
||||||
|
25 cond 8 1 24 21
|
||||||
...
|
26 next 8 21 25
|
||||||
|
27 sub 8 3 16
|
||||||
77 cond 8 76 3 44
|
|
||||||
78 cond 8 1 77 44
|
...
|
||||||
79 next 8 44 78
|
|
||||||
|
54 cond 1 53 50 52
|
||||||
Limitations
|
55 root 1 -54
|
||||||
===========
|
|
||||||
|
...
|
||||||
BTOR does not support initialization of memories and registers, i.e. they are
|
|
||||||
implicitly initialized to value zero, so the initial block for memories need to
|
77 cond 8 76 3 44
|
||||||
be removed when converting to BTOR. It should also be kept in consideration that
|
78 cond 8 1 77 44
|
||||||
BTOR does not support the ``x`` or ``z`` values of Verilog.
|
79 next 8 44 78
|
||||||
|
|
||||||
Another thing to bear in mind is that Yosys will convert multi-dimensional
|
Limitations
|
||||||
memories to one-dimensional memories and address decoders. Therefore
|
===========
|
||||||
out-of-bounds memory accesses can yield unexpected results.
|
|
||||||
|
BTOR does not support initialization of memories and registers, i.e. they are
|
||||||
Conclusion
|
implicitly initialized to value zero, so the initial block for memories need to
|
||||||
==========
|
be removed when converting to BTOR. It should also be kept in consideration that
|
||||||
|
BTOR does not support the ``x`` or ``z`` values of Verilog.
|
||||||
Using the described flow, we can use Yosys to generate word-level verification
|
|
||||||
benchmarks with or without memories from Verilog designs.
|
Another thing to bear in mind is that Yosys will convert multi-dimensional
|
||||||
|
memories to one-dimensional memories and address decoders. Therefore
|
||||||
.. [1]
|
out-of-bounds memory accesses can yield unexpected results.
|
||||||
Newer version of Boolector do not support sequential models.
|
|
||||||
Boolector 1.4.1 can be built with picosat-951. Newer versions of
|
Conclusion
|
||||||
picosat have an incompatible API.
|
==========
|
||||||
|
|
||||||
|
Using the described flow, we can use Yosys to generate word-level verification
|
||||||
|
benchmarks with or without memories from Verilog designs.
|
||||||
|
|
||||||
|
.. [1]
|
||||||
|
Newer version of Boolector do not support sequential models.
|
||||||
|
Boolector 1.4.1 can be built with picosat-951. Newer versions of
|
||||||
|
picosat have an incompatible API.
|
||||||
|
|
Loading…
Reference in New Issue