v2c - A Verilog to C Translator Tool
v2c is a Verilog to C translator tool. Given a 
Register Transfer Level (RTL) description of a hardware circuit in  
Verilog Hardware Description Language 
(HDL), v2c is used to automatically translate the Verilog RTL 
circuit into a software program which is expressed in C language. The 
software program is called software netlist. 
Contact  Rajdeep Mukherjee
or send an email here with questions 
about v2c or feedback.
We distribute pre-compiled static binary of v2c for Linux Systems
| 
 | 
We distribute several benchmarks in Verilog and ANSI-C for property verification, equivalence checking and simulation.
| 
 | 
Application of v2c
Description
v2c is primarily used in our hardware property verification 
tool flow for translating the hardware circuit given in Verilog RTL into 
the software program in C language.  The representation of RTL circuit in 
a software language allow us to leverage range of software verification 
techniques including abstract interpretation and path-wise symbolic execution 
which have never been applied to RTL verification. 
v2c can also be used for hardware/software co-verification, 
equivalence checking and for simulation of the generated C program. 
Tool Flow
 
Working Example using v2c Translator
The following example illustrates Verilog to C translation usingv2c tool. The design contains sequential
and combinatorial logic, procedural blocks, blocking and 
non-blocking assignments and multiple module hierarchy. The 
code snippet on the left gives the Verilog RTL design and the 
code snippet on the right gives the C program. 
              Verilog                          C 
------------------------------ 	 ------------------------------
module top(Din,En,CLK,Dout);       struct s_ff {
wire cs; reg ns;                   _Bool q;
input CLK, Din, En;                } sff;
output Dout;                       struct s_en { 
                                    _Bool ns; 
assign Dout = cs;                   struct s_ff sff;
always @(Din or cs or En)          } sen; 
begin                               
if (En)                            _Bool ff(_Bool CLK, _Bool Din, 
ns = Din;                                   _Bool *Dout) { 
else                                 _Bool qold;
ns = cs;                             qold = sen.sff.q; 
end                                  sen.sff.q = Din;
ff ff1(ns,CLK,cs);                   *Dout = qold;
endmodule                            return; 
                                   }
module ff(Din, CLK, Dout);         void top(_Bool CLK, _Bool Din,
input Din, CLK;                     _Bool En, _Bool *Dout) { 
output Dout;                         _Bool cs;
                                     if(En) sen.ns = Din;
reg q;                               else sen.ns = cs;
assign Dout = q;                     ff(CLK,sen.ns,&cs);
always @(posedge CLK)                *Dout = cs;
q <= Din;                          }
endmodule                          int main() {
                                    _Bool CLK,En,Din,Dout; 
                                    while(1) {  
                                     Din = nondet_bool();
                                     En = nondet_bool();
                                     top(CLK,Din,En,&Dout);
                                    }
                                    return;
                                   }
Handling Multiple Always Blocks
The following example illustrates the handling of multiple always blocks within a module. The procedural blocks contain non-blocking assignments. v2c translator finds the dependencies between different procedural blocks and translates each procedural blocks individually. For example, if every procedural block is driven by same clock event and an update to variable 'x' in procedural block A is read by another procedural block B, then block B must read the old value of the varaible 'x'. If there exist no dependencies between two procedural blocks, then they are translated individually.
         Verilog                                 C  
-----------------------------------    -------------------------
module top(out, enable ,clk, reset);   struct state_top {
output [7:0] out;                       _Bool set;
input enable, clk, reset;               unsigned char tout; 
reg [7:0] out;                          _Bool setfound;
reg set, a,b,c;                        };
reg [7:0] tout;                        struct state__top stop;
wire found;                            void top(unsigned char *out,
always @(posedge clk)                  _Bool enable, _Bool clk, 
                                       _Bool reset) { 
if (reset) begin                       _Bool found;
  tout <= 8'b0;                        unsigned char tout_old;
end else if (enable) begin             tout_old = stop.out;
  tout <= tout + 1;                    if(reset) stop.tout = 0;
end                                    else if(enable) 
                                        stop.tout = tout_old+1;
always @(posedge clk) begin            if(stop.out == 2) 
                                          stop.set = 1;
 if(out==8'h02)                        else stop.set = 0;
  set <= 1'b1;
 else                                  if(found == 1) 
  set <= 1'b0;                          stop.setfound = 1; 
end                                    else 
                                        stop.setfound = 0; 
                                       
always @(posedge clk) begin           void main() {
 if(found==1'b1) begin                unsigned char out;
  setfound <= 1'b1;                   _Bool enable, clk, reset;
end                                   while(1) 
 else begin                           top(&out,enable,clk,reset);
  setfound <= 1'b0;                   }
 end
end
endmodule 
            
Handling Inter-modular Dependencies
The following example demonstrates the handling of inter-modular dependencies between the continuous assignments and the procedural blocks containing non-blocking assignments.
         Verilog                                C  
---------------------------        -------------------------------
module M1(Din, CLK, Dout);         struct s_M1 {
input Din, CLK;                    unsigned int q1,q2;
output Dout;                       } sM1;                      
reg q1,q2;                             
wire t;                            _Bool M1(_Bool CLK, _Bool Din,  
assign Dout = q1;                           _Bool *Dout)   
always @(posedge CLK)              {
q1 <= Din;                         _Bool q1_old, q2_old;  
if(q1)                             q1_old = sM1.q1;q2_old = sM1.q2;
q2 <= q1;                          sM1.q1 = Din;
endmodule                          if(sM1.q1)
                                     sM1.q2 = q1_old;   
                                   *Dout = sM1.q1;
                                   }
            
Bit-accurate Software netlist
The following example illustrates generation of bit accurate C program from Verilog usingv2c.  Verilog support extraction operators,
concatenation operator, reduction operators which are not available in C. 
The following code snippet shows some examples of bit-accurate translation.
      Verilog                           C 
---------------------     ----------------------------------
reg [7:0] in,out;         unsigned char in, out;
out[7:5] = in[4:2];       out = out & 0xff1f | 
                          (((in & 0x001c) >> 2) << 5) ;
out[6] = in[4];           out = (out & 0xffbf) | 
                          (((in  & 0x0010) >> 4) << 6);
 
x = { y[5:2], z[6:1] };   x = (((y >> 2) & oxF) << 6)
                              | ((z >> 1) & 0x3F);
            
Combinatorial feedback loop between module
The code snippet below demonstrates handling of combinatorial feedback loop between modules. The output C program shown on the right is generated manually. The global structure of the C program namedtop gives access to all the module elements as well 
as instantiates the structure for the submodule foo. The 
structure for foo is not shown below but it contains all 
the input, output and state-holding elements of foo.  
Note that the module hierarchy is lost during translation. However, 
the translated program is structurally similar to the synthesized netlist.  
We use __CPROVER_assume statements
to assume the generated constraints. 
         Verilog                        C Model 
---------------------------  -------------------------------
module foo(c,a,z,y);          struct module_top {
 input c;                      _u32 loopback;
 input [31:0] a;               _u32 y; 
 output [31:0] z;              _Bool data;
 reg [31:0] y;                 struct module_foo f;
 output [31:0] y;             };
                              struct module_top top; 
 assign z[0] = c;             void main() { 
 assign z[31:1] = a[30:0];    __CPROVER_assume(top.f.z == 
                              (top.f.z & 0xfffffffe) 
always@(posedge clk)          | (top.f.c & 0x1));    
   y <= z;                    __CPROVER_assume(top.f.z == 
                              (top.f.z & 0x00000001) 
                              | ((top.f.a & 0x7fffffff) << 1)); 
endmodule                 __CPROVER_assume(top.f.c==top.data);
module top();             __CPROVER_assume(top.f.a==top.loopback); 
 wire [31:0] loopback;    __CPROVER_assume(top.f.z==top.loopback);
 wire [31:0] y;           __CPROVER_assume(top.f.y==top.f.z);
 wire data;               } //end main
 foo f(.c(data),.
 a(loopback),.z(loopback),.y());
endmodule
            
Combinatorial feedback between module preserving module hierarchy
We also demonstrate the translation of the above example where the module hierarchy is retained. This requires determining the stability condition for the combinational exchanges between modules. The combinational part of the design is invoked until the stability condition is reached, which in this case depends on the stability of the values ofa and z.  Note that the C program below is 
generated manually. 
         Verilog                            C 
---------------------------   -------------------------------
module foo(c,a,z,y);          struct state_elements_foo
input c;                      {
input [31:0] a;                 unsigned int y;  
output [31:0] z;              };
reg [31:0] y;                 struct state_elements_foo sfoo;  
output [31:0] y;              void foo_out(_Bool c,unsigned int a, 
                              unsigned int *z, unsigned int *y) {
assign z[0] = c;              *z=(*z & 0xfffffffe) 
                              | (c & 0x1);           
assign z[31:1] = a[30:0];     *z=(*z & 0x00000001) 
                              | ((a & 0x7fffffff)<<1);
                              }                     
always@(posedge clk)
y <= z;                       void foo_ns(_Bool,unsigned int a,
                              unsigned int *z, unsigned int *y){  
endmodule                       unsigned int z_old;     
                                z_old = *z;
module top();                   sfoo.y = z_old;
wire [31:0] loopback;         }
wire [31:0] y;                 
foo f(.c(1),.a(loopback),     int main() {
.z(loopback),.y());           unsigned int y, loopback;
endmodule                     for(i=1;i<33;i++)  
                              foo_out(1, loopback, &loopback, &y);
                              foo_ns(1, loopback, &loopback, &y);
                              }
            
Limitation of v2c
v2c assumes that the designer has included all the dependent 
files in the top level design with the construct `include.
v2c does not support the following design constructs:
Multi-clock designs
Transparent latches
Combinatorial feedback loop
Synthesizable Subset of Verilog
v2c supports the IEEE 1364-2005 Verilog synthesizable standard.
| Construct | Keywords | Notes | Supported? | 
|---|---|---|---|
| ports | input, output, inout | Use inout port only at IO level | ✔ | 
| parameters | parameter | Allows more generic design style | ✔ | 
| module definition | module | Used to define Verilog module structure | ✔ | 
| signals and variables | wire, reg, tri | different signal types, allows vector type | ✔ | 
| instantiation | module instance/primitive gate level instances | Used to instantiate one module inside another | ✔ | 
| function and tasks | function, task | reduces repeated code, doesnot allow timing | ✔ | 
| procedural constructs | always, if, else, case, casex, casez | synthesizable set except initial block | ✔ | 
| precedural block | begin, end, named blocks, disable | Allows disabling of named blocks | ✔ | 
| precedural assignments | blocking, non-blocking | allows assignments to registers in blocking or non-blocking fashion | ✔ | 
| Assignment | assign | continuous assignment to wires in combinatorial block | ✔ | 
| loops | for, while, forever | looping constructs used in Verilog | ✔ | 
| named blocks | disable | Supports disabling of named blocks | ✘ | 
Non-synthesizable Subset of Verilog
| Construct | Notes | Supported? | 
|---|---|---|
| initial | Used only in test benches | ✔ | 
| events | Used in test benches for syncing test bench components | ✘ | 
| real | Real data type not supported | ✘ | 
| force and release | Force and Release data-types not supported | ✘ | 
| assign and deassign | assign and deassign on reg type data not supported, but assign supported on wire data type | ✔ | 
| fork join | Not supported. Can be simulated using nonblocking assignments | ✘ | 
| primitives | only gate level primitives supported | ✔ | 
| UDP and Tables | Not supported | ✘ | 
Co-verification and Equivalence Checking Tool
If you are interested in hardware/software co-verification or C-RTL equivalence checking, please use our tool HW-CBMC.
Bounded Model Checking Tool for Verilog RTL
If you are interested in bounded model checking for Verilog designs, please use our tool EBMC.
Path-based Symbolic Execution Tool
If you are interested in path-based symbolic execution tool for the cycle-accurate C models generated from Verilog or any software (in C) in general, please use our tool VerifOx.