VH2SCVHDL to SystemC Converter
web:www.ht-lab.com |
|
VH2SC is a free basic VHDL to SystemC converter. The converter handles a small subset of Synthesisable VHDL 87/93 language constructs. The current version translates all VHDL IEEE types to sc_int/sc_uint/integers and booleans this in order to maximise performance. The aim of the converter is to produce a cycle accurate model of synthesisable VHDL code. The converter runs on Windows.
Some wording of advice, don't try to convert the Leon core with it, it is simply too complex to handle. VH2SC is not a compiler, it is a language construct translator and as such the VHDL constructs it can handle are rather limited. If you are serious about translating your VHDL to SystemC and need the fastest available converter with all the guarantees of cycle accuracy etc, than I can highly recommended the VSP compiler from Carbon Design Systems in the US. I used this product for a while and I can tell you this is some impressive piece of technology!
Let me know if this utility is helpful in anyway. If you want anything changed
or added just send me an email. If I have the time and the update is not that
difficult I might add it :-) This utility is no longer maintained. This is mainly due to the parser which is hacked so much that fixing one bug will result in 10 new ones.
- License Agreement
- Download Software
- Installation
- Example Usage
- Performance
- Limitations
- VH2SC Command-line options
- FAQ
- Links
1. License Agreement
The VH2SC converter is licensed under the Aladdin Free Public license (AFPL). This means it can be freely used for non-commercial purposes.
2. Download software
Make sure your run a virus checker on the executable files before executing them!
- Windows Version 0.26 [zipped, 800KByte, tested on Win2K/XP]
- Code Beautifier, for example GreatCode
or Artistic Style
(included in the zip file).
Alpha Version 0.23 release on the web 10/03/07
First version that can translate some of my cores (see examples directory in the download file). This version is quite limited but might be useful to some
Alpha Version 0.24 release on the web 17/03/07
Added support for slicing constants. Added support for "with select" VHDL constructs. Preliminary support for functions and concurrent generate statements. This version is still quite limited but might be useful to some. Note for some reason vh2sc.exe fails to run under Linux wine, it returns with a segment failure.
Alpha Version 0.26 release on the web 20/07/08
Corrected build, it now works again in a DOS box rather than only under Cygwin. You need to make sure that vh2sc.exe can find the libpcre-0.dll which is in the installation directory.
3. Installation
Unzip the file to a suitable directory. Look in the example directory for some working models.
4. Example Usage
|
Before you run vh2sc on your VHDL code make sure that: |
|
4.1 Example1: Simple counter
- Convert the counter.vhd file to SystemC,
c:\VHDL2SystemC\example1>vh2sc -v -mti count.vhd
VH2SC -> VHDL to SystemC Converter
Ver 0.21
** Alpha Release ** (c)HT-Lab 2007
SQLite Version
: 3.3.13
Parsing File
: count.vhd
Line
9 ** Info : library ieee ignored
Line
28 ** Info : VH2SC Translation Disabled
Line
32 ** Info : VH2SC Translation Re-Enabled
Line
37 ** Info : process() translated to process_line37
Writing
Header File : cnt.h
Writing C++ File :
cnt.cpp
**
Info : Modelsim SC_MODULE_EXPORT(cnt) macro added
- The -v is a verbose flag and -mti is required only if the module is going to be used in Modelsim.
- Note the generated output filenames are cnt.cpp and cnt.h. This is the name of the entity and not the input VHDL filename. This can be changed using the -oh and -oc command line arguments.
- All processes in SystemC are translated to function calls and as such a function name is required. If the process is not labeled vh2sc will use "process_" plus the line number were the process was declared.
- All combinatorial assignments are written to a single SystemC process called comb_assignments(), all input signals are added to its sensitivity list.
- The generated code has no formatting and therefore it is strongly recommended to run the header and cpp files through a code beautifier. There are several on the web. For this example I use the AStyle beautifier which is freely available and included in the download zip file.
c:\example1>AStyle --style=kr -n cnt.cpp cnt.h
Artistic Style 1.20.2
formatting cnt.cpp
formatting
cnt.h
total time 0.015 seconds
4.1.1 Simulation using Modelsim
If you have access to Modelsim (PE/SE+SystemC option) than the simulation/validation step is simple, just compile the cnt.cpp module instead of the count.vhd file. I would advice to clean the work library (vdel -all; vdel -allsystemc, or rm -Rf work, or del /Q/S work) before compiling the code (it seems that the _opt file from a previous VHDL simulation can result in an error during elaboration).
rmdir /S /Q work
vlib work
sccom
-O2 cnt.cpp
Model Technology ModelSim SE sccom 6.2f compiler
2007.01 Jan 12 2007
Exported modules:
cnt
sccom
-link
vcom count_tb.vhd
vsim work.count_tb
add wave *
run 1
ms
# ** Warning: (vsim-6599) Counter Overflow
# In process: /count_tb/dut/process_line25
@ 2800 ns
# ** Fatal: Fatal SystemC error detected, exiting...
# Time:
2800 ns Iteration: 2 Process: /count_tb/dut/process_line25 File:
cnt.h

Visually comparing the waveforms from a VHDL and SystemC simulation is obvious not the way to confirm that the generated model is cycle accurate. Modelsim SE supports a very handy waveform compare option which is one of the methods I use in my regression test. A better method is to write a self checking testbench that confirms the result after simulation. Calypto makes equivalent checkers for RTL and SystemC, this is obvious the best solution but you might need a serious EDA budget for that :-).
Note: the fatal SystemC error is generated by the SC_REPORT_FATAL macro and is used to stop the simulation. This is just an example to show how vh2sc translates assert statements and should not be consider good coding practice.
4.2 Example2: AES Core
The second example is the modified 128bits AES86 core which you can find here. This design has a self checking testbench so is easy to validate. To convert the design to SystemC use the following sequence:
- Navigate to the Modelsim directory and confirm the
core is working by executing run.bat. Note how fast Modelsim compiles
the design! The testbench has been set to a quick test (see
AES86 description), so only 40 AES Encrypt
keys are generated. This test takes about 14 minutes to run
on my AMD3500+.
# Key=B2F123944C43DEC9FD36EB0FB83ECEFF
# PT =8A79CE45F030B91B53D1591D10FF1B02
# CT =BE20190BAE15162F43E93F67A580192B
# I=39
# Key=0CD13A9FE256C8E6BEDFD4681DBED7D4
# PT =BE20190BAE15162F43E93F67A580192B
# CT =0107D3E3511F91545D02B498A9E3C318
# ** Failure: ************** End of Test **************
- Next navigate to the SystemC directory and execute the DOS run.bat batch file. Observe some of the warnings like:
Line 99 ** Warning : 'X' converted to 0
vh2sc translates all 'X'/'Z'/'-'/'H'/'L' to either a '0' or '1'. This can potentially lead to simulation differences and invalid C++ code. Consider the next VHDL code snippet from a case statement:
WHEN '1'|'H' => rtaddr <= fsbout;
which is translated to:
case 1 :
case 1 : rtaddr.write(fsbout.read());
<-- Compile error, duplicate case
- Watch out for any SystemC keywords, the AES86 design uses the "int" keyword for the interrupt line. This was changed to intx to avoid a compile error. You can also not have the same name for an entity as for a signal declaration, the code below is valid in VHDL but will result in illegal C++ code;
architecture rtl of regfile
is
type regfile
is array (8 to 31) of std_logic_vector(7 downto
0); -- Using the entity name regfile is valid in VHDL
which is translated to:
SC_MODULE(regfile) {
typedef
sc_uint<8> regfile; //
Error: ISO C++ forbids nested type `regfile' with same name as the enclosing
class
sc_signal<regfile
> gpr_s[32];
- Note the compile time! also the total runtime on my AMD3500+ was 44 minutes which is more than 3x slower than VHDL!
4.3 Example3: Simple Cordic Core
The third example shows how vh2sc handles packages and sliced signals. When a package is converter vh2sc will automatically write an SQLite(tm) database file. This file is then read whenever the package is referenced.
# ** Note: *** Start of Test ***
# Time:
200 ns Iteration: 0 Instance: /cordic_tb
# Angle x=08EFA351
SIN(x)=08E83643 [08E88573] COS(x)=3F608D0E [3F6081F1]
# Angle x=9ED1EFEE
SIN(x)=C0167464 [C0166DF5] COS(x)=035978EC [0358FE0D]
# Angle x=612E1012
SIN(x)=3FE98B9B [3FE9920A] COS(x)=035978E8 [0358FE0D]
# Angle x=37D9BCBB
SIN(x)=3106DF14 [3106F086] COS(x)=29236E7D [292359B4]
# ** Failure:
*** End of Test ***
When you execute the run.bat file you will see the following Info line :
Line 93 ** Info : variable xreg_s_sliced added to generated source
This informs the user that an extra variable has been added to the generated source. This variable is required if the VHDL contains sliced assignments, for example:
xreg_s(31 downto 0) <= xinit_c;
xreg_s is translated into sc_signal, unfortunately there is no part select method for sc_signals so in order to support constructs like this the signal is read into a variable at the beginning of the process, modified as per the VHDL and then written back to the signal at the end of the process,
void cordic::process_line90() {
sc_uint<32>
xreg_s_sliced; --
Declare local variable same size as sc_signal
xreg_s_sliced=xreg_s.read();
-- Read signal into local variable
xreg_s_sliced(31,0)=xinit_c ; --
Perform slicing/part select
xreg_s.write(xreg_s_sliced);
-- Write variable value
back to sc_signal
}
5. Performance
The simulation speed of the generated code is generally much slower than the equivalent VHDL. This might come as a surprise and disappointment to some. SystemC can run much faster than VHDL/Verilog but only when used at a higher level of abstraction. The generated SystemC code is at the RTL level which means that communication between the modules is at the so called pin level. This type of communication is very demanding in terms of events and this is what is slowing down the performance. In most cases when you write a SystemC model you are not interested in the way that subblocks communicate. For example, using a function call (transactor) to write data into a memory block is much faster than simulating all the signals that are associated with say a DDR3 hardware model.
In addition to the above vh2sc generates inefficient code. To start with, all the combinatorial logic is written to the same process. This means that if you have large amount of combinatorial logic a high-frequency signal will trigger and execute all that combinatorial logic even when this is not required for most of it. This is not the way that VHDL/Verilog simulation operates. In this case only the logic associated with the high-frequency signal is schedules and executed.
The second problem is that the translated code follows the VHDL coding style, for example a rising_edge(clk) process is translated as:
|
VHDL |
SystemC |
|
process (clk) |
void process_linex() { SC_METHOD(process_linex); |
The above code will result in the process_linex to be triggered on both edges of the clock. A better solution is to change the sensitivity list such that the process is only triggered on the rising edge of the clk (sensitive << clk.pos();).
6. Limitations
The following constructs are not (yet?) supported :
- functions/procedures/generate/configurations/loop/alias/guarded blocks/...
- sll/srl/sla/sra/rol/ror/shift_left/shift_right.
When vh2sc finds these functions it will write out the function in C (e.g. sll(identifier,3) ) and add the vh2sc.h include file. The code for these function is not available and needs to be added by the user. - inout and buffer entity ports, this is because all I/O ports are translated
to sc_uint/sc_int types.
A warning is issues when vh2sc encounters these port types.
- Signal initialisation values (non synthesisable anyway). Signals are translated to sc_signal for which there is no init constructor.
vector : in std_logic_vector(7 downto 0):="01110010"; -- 01110010 is ignored by vh2sc!
- Exponential functions in entity declarations, for example;
generic (WIDTH : integer
:= 3);
vector : in std_logic_vector((2**WIDTH)-1
downto 0); -- Note
due to some coding constraints
vh2sc reports the ** operator as #
- bit slicing in port maps, for example:
signal carrychain: std_logic_vector(15
downto 0);
alu: singlebit port
map (
Cout => carrychain(0) --
Error
- Declaration ranges which do not start or end at 0. The reason for this is that SystemC doesn't support ranges in sc_signal and sc_in/sc_out/sc_inout types. Thus the following will result in a compile error due to size mismatches;
signal regdn :
std_logic_vector(15 downto 2); --
14 bits vector, vh2sc defaults to (15 downto 0) and issues a warning
signal
regup : std_logic_vector(4
to 89); --
86 bits vector, vh2sc default to (0 to 89) and issues a warning
sc_signal<sc_uint<16> > regdn;
// 16 bits vector!
sc_signal<sc_biguint<90>
> regup; //
90 bits vector!
Line 16 ** Warning : lower bounds of
range is not 0, "15 downto 2"
Line 17 ** Warning
: lower bounds of range is not 0, "4 to 89"
- And lots more.....
To re-iterate, the current build is Alpha Status, vh2sc was "tweaked" for the supplied examples.
7. VH2SC Command-Line options
NAME
vh2sc - VHDL 2 SystemC converter
SYNOPSIS
vh2sc [-q] [-options] filename
DESCRIPTION
vh2sc is a basic VHDL 2 SystemC converter. The input to the converter must be error free synthesisable VHDL and should contain 1 entity and 1 architecture declaration or 1 package header and 1 package body per file. The output of the converter is a SystemC .cpp file and an associated header .h file.
OPTIONS
| -q | quiet mode, suppress all warnigs and info messages |
| -v | verbose mode, show all info messages |
| filename | VHDL input filename |
| -c2h | Write all generated code to header file |
| -oh <filename> | Specify output header filename (default:entity_name.h) |
| -oc <filename> | Specify output cpp filename (default: entity_name.cpp) |
| -ip | Ignore synthesis/translate/vh2sc pragmas |
| -mti | Add SC_MODULE_EXPORT(modulename) to cpp file |
| -ncsim | Add NCSC_MODULE_EXPORT(modulename) to cpp file |
| -sql | Force an SQLite datebase file |
8. FAQ
- Are you planning to support language construct .....?
If it can be synthesised then perhaps, it is just a question of available "free" time :-). - You generate incorrect or inefficient code for language construct ...?
Great, this is the kind of info I need. please send me an example and I will try to fix it. - Are you planning to support Verilog?
No, however there is an excellent Verilog to C++/SystemC converter called Verilator. - I get a compile error on the SC_MODULE_EXPORT
macro in modelsim, why is this?
Check that you don't have any VHDL generic(s) in your top level since Modelsim does not support templates on the top exported module.
For any other questions or comments please use the feedback form
9. Useful Links
- Open SystemC Initiative (OSCI), main site for downloading the SystemC library and reference manual.
- European SystemC users group.
- VHDL to SystemC converter developed by the University of Tubingen.
- Verilator, Verilog to C++ or SystemC converter.
- Fastest HDL to SystemC/C++ converter (commercial product).
- SC2V, a SystemC to Verilog translator.
- Opencore's SystemC ARM core.
- GTKWave, free VCD viewer for Linux and Windows.
- Dinotrace, another free VCD viewer.
- SystemC Parser developed by FZI research organisation.
- Great GUI for Code Beautifiers
- Basic VHDL SystemC Code Comparison sheet
- Excellent comprehensive SystemC course from Doulos, guess which SystemC course I attended :-)
- SystemC course specific for VHDL engineers.
- ArchC language, architecture language on top of SystemC


