top of page

SPV – establish in 2002 and start with supplying a strong and flexible verification environment, native using C++ MATLAB and Python as a part of the environment.

We use the best tools for editing compiling linking debugging and running.

Many companies have used our verification environment to develop hundreds of FPGA and dozens of chips.

Simulator - 3 years ago we started to develop a new simulator. We concentrated on excellent performance. and began marketing the product, that work with our or other verification environment that supports PLI.

Our simulator is faster X5 than any other simulator. And we continue to develop it vigorously.

What in future:
we are looking for investment, but continue to develop the simulator and all other peripheral tools, compiler, wave viewer and the verification environment.

What we have today? 

Our complier compile almost of the Verilog keyword.  while our simulator could run them as well. 

Below you can see an example of a small project that tries to contain as many Verilog keyword as possible, and later we will also detail the verification environment for the same code. Within the code there is a simple generation environment in the Verilog language, but when working with our verification environments we disable the Verilog generation (we set 0 to 1 register - 'use_SpvTb' ) and we inject data and check the design, through three different verification environments that SPV supply: 
1. SPV C++.
2. SPV with pure python.
3. MATLAB -- m files that implement calculator.

The basic code contains modules for all mathematical operations, each one has a module that performs the operations in the small module, with the main module providing them with inputs and receiving the outputs that are the answer to the operation. There are also other commands in the main module such as case, assign, signal bit, signal slice, and Curly bracket operation.
in simulation time we create binary file for waves.
with our wave viewer we upload the file for debug process.

Verilog code:

module top_calc - top_calc.v


module TopCalc #(parameter MAX_SIZE=32);


///////   Add memory support ////////////////////////////////
reg [127:0]    mem1[15:0];


integer MarkIfWriteAllReady[0:9];
initial begin
   for(int i=0;i<10;i=i+1)
        MarkIfWriteAllReady[i]=0;
end

function integer add_two_numbers (input integer a, input integer b);
    // The return value is assigned to the function's name
    add_two_numbers = a + b;
endfunction

//function declaration
function automatic integer factorial(integer i);
   integer result;
   begin
       if (i > 1) begin
           result = i * factorial(i - 1);  // Recursive call        
       end else
           result = 1;  // Base case for recursion

        if (MarkIfWriteAllReady[i] == 0) begin 
           $display("factorial of %0d ==%0d\n", i, result);
           MarkIfWriteAllReady[i] = 1;
       end
   end 

   return result;
endfunction

reg            clk_factorial;
always        #100000 clk_factorial = ~ clk_factorial;

function [7:0] sum;
   input [7:0] x, y;
   begin
       sum = x + y; // Return the sum
   end
endfunction

reg         use_SpvTb;

reg         clk_or;
always #15    clk_or = ~clk_or;
reg     [MAX_SIZE-1:0]    or_a;
reg     [MAX_SIZE-1:0]  or_b;
wire    [MAX_SIZE-1:0]    or_res;

Or   or1(
   .clk_or      (clk_or),
   .or_a          (or_a),
   .or_b         (or_b),
   .or_res      (or_res)
);

 

reg         clk_add;
always #20    clk_add = ~clk_add;
reg        [MAX_SIZE-1:0]    add_a;
reg     [MAX_SIZE-1:0]  add_b;
wire     [MAX_SIZE-1:0]    add_res;

Add   add1(
   .clk_add      (clk_add),
   .add_a      (add_a),
   .add_b         (add_b),
   .add_res      (add_res)
);
               


reg         clk_sub;
always #25    clk_sub = ~clk_sub;
reg    [MAX_SIZE-1:0]    sub_a;
reg [MAX_SIZE-1:0]  sub_b;
wire [MAX_SIZE-1:0]    sub_res;

Sub   sub1(
   .clk_sub      (clk_sub),
   .sub_a      (sub_a),
   .sub_b         (sub_b),
   .sub_res      (sub_res)
);

reg         clk_mult;
always #30    clk_mult = ~clk_mult;
reg    [MAX_SIZE-1:0]    mult_a;
reg [MAX_SIZE-1:0]  mult_b;
wire [MAX_SIZE-1:0]    mult_res;

Mult   mult1(
   .clk_mult      (clk_mult),
   .mult_a      (mult_a),
   .mult_b     (mult_b),
   .mult_res      (mult_res)
);

reg         clk_and;
always #35    clk_and = ~clk_and;
reg    [MAX_SIZE-1:0]    and_a;
reg [MAX_SIZE-1:0]  and_b;
wire [MAX_SIZE-1:0]    and_res;

And   and1(
   .clk_and      (clk_and),
   .and_a      (and_a),
   .and_b         (and_b),
   .and_res      (and_res)
);

reg         clk_mode;
always #40    clk_mode = ~clk_mode;
reg    [MAX_SIZE-1:0]    mode_a;
reg [MAX_SIZE-1:0]  mode_b;
wire [MAX_SIZE-1:0]    mode_res;

Mode   mode1(
   .clk_mode      (clk_mode),
   .mode_a      (mode_a),
   .mode_b     (mode_b),
   .mode_res      (mode_res)
);

reg     clk_xor;
always #45   clk_xor = ~clk_xor;
reg    [MAX_SIZE-1:0]    xor_a;
reg [MAX_SIZE-1:0]  xor_b;
wire [MAX_SIZE-1:0]    xor_res;

Xor   xor1(
   .clk_xor      (clk_xor),
   .xor_a      (xor_a),
   .xor_b         (xor_b),
   .xor_res      (xor_res)
);

reg     clk_div;
always #45   clk_div = ~clk_div;
reg    [MAX_SIZE-1:0]    div_a;
reg [MAX_SIZE-1:0]  div_b;
wire [MAX_SIZE-1:0]    div_res;

Div   div1(
   .clk_div      (clk_div),
   .div_a      (div_a),
   .div_b         (div_b),
   .div_res      (div_res)
);

reg     clk_shiftL;
always #50   clk_shiftL = ~clk_shiftL;
reg    [MAX_SIZE-1:0]    shiftL_a;
reg [MAX_SIZE-1:0]  shiftL_b;
wire [MAX_SIZE-1:0]    shiftL_res;

ShiftL   shiftL1(
   .clk_shiftL      (clk_shiftL),
   .shiftL_a          (shiftL_a),
   .shiftL_b         (shiftL_b),
   .shiftL_res      (shiftL_res)
);

reg     clk_shiftR;
always #55   clk_shiftR = ~clk_shiftR;
reg     [MAX_SIZE-1:0]    shiftR_a;
reg  [MAX_SIZE-1:0] shiftR_b;
wire [MAX_SIZE-1:0]    shiftR_res;

ShiftR   shiftR1(
   .clk_shiftR      (clk_shiftR),
   .shiftR_a          (shiftR_a),
   .shiftR_b         (shiftR_b),
   .shiftR_res      (shiftR_res)
);

 

 

/////////////   Start motion ////////////////////////////
initial begin
   use_SpvTb     = 0;
   clk_factorial=0;    
   clk_or        = 0;
   clk_add        = 0;
   clk_and        = 0;
   clk_mode    = 0;
   #30;
   clk_mult    = 0;
   clk_shiftL    = 0;
   clk_shiftR    = 0;
   clk_sub        = 0;
   clk_xor        = 0;
   clk_div        = 0;
   for (int i = 0; i < 128; i = i + 1) begin
       mem1[i]        = 127-i;
       if (i == 50 || i == 127) $display("mem1[%d] == %d\n", i,mem1[i]);
    end
end

always @(posedge clk_factorial) begin
   factorial($random %7);
end


always @(negedge clk_or) begin
   if (!use_SpvTb) begin
       or_a = $random;
       or_b = $random;
   end 
end


always @(negedge clk_add) begin
   if (!use_SpvTb) begin
       add_a = $random;
       add_b = $random;
   end 
end    

always @(negedge clk_sub) begin
   if (!use_SpvTb) begin
       sub_a = $random;
       sub_b = $random % sub_a;
   end 
end    

always @(negedge clk_and) begin
   if (!use_SpvTb) begin
       and_a = $random;
       and_b = $random;
   end 
end    

always @(negedge clk_mode) begin
   if (!use_SpvTb) begin
       mode_a = $random;
       mode_b = $random;
   end 
end    

always @(negedge clk_mult) begin
   if (!use_SpvTb) begin
       mult_a = $random;
       mult_b = $random;
   end 
end    

always @(negedge clk_shiftL) begin
   if (!use_SpvTb) begin
       shiftL_a = $random;
       shiftL_b = ($random % 31) + 1;
   end 
end    

always @(negedge clk_shiftR) begin
   if (!use_SpvTb) begin
       shiftR_a = $random;
       shiftR_b = ($random % 31) + 1;
   end 
end    

always @(negedge clk_xor) begin
   if (!use_SpvTb) begin
       xor_a = $random;
       xor_b = $random;
   end 
end    


always @(negedge clk_div) begin
   if (!use_SpvTb) begin
       div_a = $random;
       div_b = $random;
   end 
end    


/////   Some assign code ////////////////////////////////////////////
reg        assign_clk;
always    #50            assign_clk = ~assign_clk;
//reg        [31:0]        bus32;
reg        [31:0]        fifo_size;
reg        [31:0]        fifo_count;//How much data wrote to fifo.
reg                    have_2_write;//I have something to write.
wire                wire_2_write;
wire                wire_2_read;
wire                fifo_full;
wire                fifo_empty;
///wire    [31:0]        wire_xor;


always @(posedge assign_clk) begin
   if (!have_2_write && !fifo_full)
       have_2_write <= ($random % 6) > 1;//66% to write
end

always @(negedge assign_clk) begin
   if (wire_2_write) begin
       fifo_count     = fifo_count + 1;
       have_2_write = 0;
   end
end

always @(negedge assign_clk) begin
   if (wire_2_read)
       fifo_count     = fifo_count - 1;
end


assign    wire_2_write    = !fifo_full && have_2_write;
assign    wire_2_read        = !wire_2_write && !fifo_empty;
assign    fifo_full        = fifo_count >= fifo_size;
assign    fifo_empty        = fifo_count == 0;

initial begin 
   assign_clk    = 0;
   fifo_size    = ($random % 100 > 50) ?  100 : 150;
   fifo_count    = 0;
   have_2_write= 0;
   fifo_full   = 0;
   fifo_empty    = 1;
end


reg       [31:0]   Data1;
reg       [31:0]   Data2;
reg                crc_clock;
always #200 crc_clock = ~crc_clock;
wire   [31:0]   xorData1;
wire   [31:0]    Data2Slice;
//wire   [63:0]    Data3Slice;

initial crc_clock = 0;

always @(posedge crc_clock)
   if (!use_SpvTb) begin
       Data1        = $random;        
       Data2        <= $random;        
   end

assign Data2Slice[15:0]        = Data2[31:16];
assign Data2Slice[31:16]    = Data2[15:0];
//assign Data3Slice[16:50]    = Data2[1:30];//Other => 0 

assign xorData1[0]  = Data1[0] ^ Data1[5]  ^ Data1[8]  ^ Data1[12] ^ Data1[15] ^ Data1[23] ^ Data1[26];
assign xorData1[1]  = Data1[1] ^ Data1[4]  ^ Data1[8]  ^ Data1[12] ^ Data1[14] ^ Data1[23] ^ Data1[26];
assign xorData1[2]  = Data1[2] ^ Data1[5]  ^ Data1[8]  ^ Data1[12] ^ Data1[13] ^ Data1[23] ^ Data1[26];
assign xorData1[3]  = Data1[3] ^ Data1[5]  ^ Data1[8]  ^ Data1[12] ^ Data1[14] ^ Data1[23] ^ Data1[26];
assign xorData1[4]  = Data1[4] ^ Data1[13] ^ Data1[14] ^ Data1[15] ^ Data1[21] ^ Data1[28] ^ Data1[29];
assign xorData1[5]  = Data1[5] ^ Data1[13] ^ Data1[15] ^ Data1[16] ^ Data1[22] ^ Data1[28] ^ Data1[29];
assign xorData1[6]  = Data1[6] ^ Data1[13] ^ Data1[16] ^ Data1[17] ^ Data1[23] ^ Data1[28] ^ Data1[29];
assign xorData1[7]  = Data1[7] ^ Data1[13] ^ Data1[17] ^ Data1[18] ^ Data1[25] ^ Data1[28] ^ Data1[29];
assign xorData1[8]  = Data1[8] ^ Data1[13] ^ Data1[18] ^ Data1[19] ^ Data1[20] ^ Data1[28] ^ Data1[29];
assign xorData1[9]  = Data1[3] ^ Data1[9]  ^ Data1[15] ^ Data1[20] ^ Data1[21] ^ Data1[23] ^ Data1[28];
assign xorData1[10] = Data1[4] ^ Data1[10]  ^ Data1[16] ^ Data1[21] ^ Data1[22] ^ Data1[23] ^ Data1[28];
assign xorData1[11] = Data1[5] ^ Data1[11]  ^ Data1[13] ^ Data1[22] ^ Data1[19] ^ Data1[23] ^ Data1[28];
assign xorData1[12] = Data1[6] ^ Data1[12]  ^ Data1[14] ^ Data1[16] ^ Data1[18] ^ Data1[23] ^ Data1[28];
assign xorData1[13] = Data1[7] ^ Data1[13]  ^ Data1[15] ^ Data1[16] ^ Data1[17] ^ Data1[23] ^ Data1[28];
assign xorData1[14] = Data1[8] ^ Data1[14] ^ Data1[13] ^ Data1[21] ^ Data1[24] ^ Data1[27] ^ Data1[31];
assign xorData1[15] = Data1[9] ^ Data1[15] ^ Data1[14] ^ Data1[22] ^ Data1[25] ^ Data1[27] ^ Data1[31];
assign xorData1[16] = Data1[10] ^ Data1[12] ^ Data1[15] ^ Data1[23] ^ Data1[23] ^ Data1[27] ^ Data1[31];
assign xorData1[17] = Data1[11] ^ Data1[12] ^ Data1[16] ^ Data1[21] ^ Data1[24] ^ Data1[27] ^ Data1[31];
assign xorData1[18] = Data1[11] ^ Data1[12] ^ Data1[17] ^ Data1[22] ^ Data1[22] ^ Data1[27] ^ Data1[31];
assign xorData1[19] = Data1[5] ^ Data1[12] ^ Data1[19] ^ Data1[23] ^ Data1[25] ^ Data1[27] ^ Data1[31];
assign xorData1[20] = Data1[6] ^ Data1[4]  ^ Data1[7]  ^ Data1[13] ^ Data1[14] ^ Data1[15] ^ Data1[29];
assign xorData1[21] = Data1[7] ^ Data1[4]  ^ Data1[7]  ^ Data1[13] ^ Data1[15] ^ Data1[16] ^ Data1[29];
assign xorData1[22] = Data1[8] ^ Data1[4]  ^ Data1[7]  ^ Data1[13] ^ Data1[16] ^ Data1[17] ^ Data1[29];
assign xorData1[23] = Data1[4] ^ Data1[4]  ^ Data1[7]  ^ Data1[13] ^ Data1[17] ^ Data1[18] ^ Data1[29];
assign xorData1[24] = Data1[4] ^ Data1[4]  ^ Data1[7]  ^ Data1[13] ^ Data1[18] ^ Data1[19] ^ Data1[29];
assign xorData1[25] = Data1[4] ^ Data1[8]  ^ Data1[7]  ^ Data1[13] ^ Data1[19] ^ Data1[20] ^ Data1[29];
assign xorData1[26] = Data1[4] ^ Data1[8]  ^ Data1[7]  ^ Data1[13] ^ Data1[20] ^ Data1[21] ^ Data1[29];
assign xorData1[27] = Data1[4] ^ Data1[8]  ^ Data1[10] ^ Data1[14] ^ Data1[21] ^ Data1[22] ^ Data1[30];
assign xorData1[28] = Data1[6] ^ Data1[8]  ^ Data1[10] ^ Data1[14] ^ Data1[22] ^ Data1[23] ^ Data1[31];
assign xorData1[29] = Data1[6] ^ Data1[8]  ^ Data1[10] ^ Data1[14] ^ Data1[23] ^ Data1[24] ^ Data1[30];
assign xorData1[30] = Data1[6] ^ Data1[8]  ^ Data1[10] ^ Data1[14] ^ Data1[24] ^ Data1[28] ^ Data1[31];
assign xorData1[31] = Data1[6] ^ Data1[8]  ^ Data1[10] ^ Data1[14] ^ Data1[19] ^ Data1[29] ^ Data1[30];

///////////////    case code ///////////////////
reg        case_clk;
initial case_clk = 0;
always  #200 case_clk = ~case_clk;
reg     [2:0]    case_data;
reg     [7:0]    case_value;

always @(posedge case_clk)
   if (!use_SpvTb) begin
       case_data    = $random;                
   end

always @(posedge case_clk)    begin
   case (case_data)
      0 : case_value = 0*0;
     1 : case_value = 1*1;
     2 : case_value = 2*2;
     3 : case_value = 3*3;
     4 : case_value = 4*4;
     5 : case_value = 5*5;
     6 ,7 :    begin
       case_value = (case_data[2]) ? 36 : 49;
     end
     default : case_value[7:6] = (case_data[2]) ? case_data[1:0] : case_data[2:1];
   endcase
end

//////////     Cruled code ///////////////
reg        curled_clk;
initial curled_clk = 0;
always  #500    curled_clk = ~curled_clk;
wire    [33:0]    wireA;
wire    [19:0]    wireB;
wire    [9:0]    wireC;
reg        [8:0]    regA;//9
reg        [3:0]    regB;//4
reg        [6:0]    regC;//7 -- Total reg 24 bits 
reg        [3:0]    regD;

always @(posedge curled_clk)
   if (!use_SpvTb) begin
       regA    = $random;    
       regB    = $random;    
       regC    = $random;    
       regD    = $random;    
   end

assign {wireA, wireB, wireC} = {regA,0xAbCdEf01,8'b1100XxZz,regB,regC,regD[0:2],regD[3]};

endmodule // end module TopCalc

Other module:

Module Add - add.v

module Add(
   clk_add,
   add_a,
   add_b,
   add_res
);

input     wire clk_add;
input     wire [31:0] add_a,add_b;
output    reg  [31:0] add_res;

always @(posedge clk_add)
   add_res = add_a + add_b;
SubAdd    AddSubInst(
   .SubAdd_clk      (clk_add),
   .SubAdd_a          (add_a),
   .SubAdd_Res     (add_res)    
);

endmodule

 

        Module And - and.v

 

module And(
   clk_and,
   and_a,
   and_b,
   and_res
);

input     wire clk_and;
input     wire [31:0] and_a,and_b;
output    reg  [31:0] and_res;

always @(posedge clk_and)
   and_res = and_a & and_b;

 


endmodule
 

 

        Module Div - div.v

 

module Div(
   clk_div,
   div_a,
   div_b,
   div_res
);

input     wire clk_div;
input     wire [31:0] div_a,div_b;
output    reg  [31:0] div_res;

always @(posedge clk_div)
   div_res = div_a / div_b;

endmodule
 

 

        Module Mode - mode.v

 

module Mode(
   clk_mode,
   mode_a,
   mode_b,
   mode_res
);

input     wire clk_mode;
input     wire [31:0] mode_a,mode_b;
output    reg  [31:0] mode_res;

always @(posedge clk_mode)
   mode_res = mode_a % mode_b;


endmodule
 

SPV_ADVANTAGES

 

        

        Module Mult - mult.v

 

module Mult(
   clk_mult,
   mult_a,
   mult_b,
   mult_res
);

input     wire clk_mult;
input     wire [31:0] mult_a,mult_b;
output    reg  [31:0] mult_res;

always @(posedge clk_mult)
   mult_res = mult_a * mult_b;


endmodule

 

        Module Or - or.v

module Or(
   clk_or,
   or_a,
   or_b,
   or_res
);

input     wire clk_or;
input     wire [31:0] or_a,or_b;
output    reg  [31:0] or_res;

always @(posedge clk_or)
   or_res = or_a | or_b;


endmodule

 

        Module ShiftL - shiftl.v

module ShiftL(
   clk_shiftL,
   shiftL_a,
   shiftL_b,
   shiftL_res
);

input   wire clk_shiftL;
input   wire [31:0] shiftL_a,shiftL_b;
output  reg  [31:0] shiftL_res;

always @(posedge clk_shiftL)
   shiftL_res = shiftL_a << shiftL_b;
endmodule

 

        Module ShiftR - shiftr.v

module ShiftR(
   clk_shiftR,
   shiftR_a,
   shiftR_b,
   shiftR_res
);

input     wire  clk_shiftR;
input     wire  [31:0] shiftR_a,shiftR_b;
output    reg   [31:0] shiftR_res;

always @(posedge clk_shiftR)
   shiftR_res = shiftR_a >> shiftR_b;


endmodule
 

 

        Module Sub - sub.v

module Sub(
   clk_sub,
   sub_a,
   sub_b,
   sub_res
);

input     wire clk_sub;
input     wire [31:0] sub_a,sub_b;
output    reg  [31:0] sub_res;

always @(posedge clk_sub)
   sub_res = sub_a - sub_b;

AddSub    AddSubInst(
   .AddSub_clk      (clk_sub),
   .AddSub_b          (sub_b),
   .AddSub_res     (sub_res)    
);

endmodule

module AddSub(
   AddSub_clk,
   AddSub_b,
   AddSub_res
);

input     wire            AddSub_clk;
input     wire    [31:0]    AddSub_b,AddSub_res;
reg                [31:0]    AddSub_a;

always @(negedge AddSub_clk)    
   AddSub_a    = AddSub_res + AddSub_b;

endmodule

 

        Module Xor - xor.v

module Xor(
   clk_xor,
   xor_a,
   xor_b,
   xor_res
);

input     wire clk_xor;
input     wire [31:0] xor_a,xor_b;
output    reg  [31:0] xor_res;

always @(posedge clk_xor)
   xor_res = xor_a ^ xor_b;


endmodule
 

 

        FileList   - FileList.txt

./HDL/Or.v
./HDL/Add.v
./HDL/Sub.v
./HDL/Mode.v
./HDL/Mult.v
./HDL/assign.v
./HDL/TopCalc.v
./HDL/And.v
./HDL/Xor.v
./HDL/Div.v
./HDL/ShiftL.v
./HDL/ShiftR.v

 

       Compiler command:

       spc -f FileList.txt  -o calcDesign =>  Result is exe name calcDesign

 

       Run Simulation (with testbench [-pli dllName or without it]

       $(SPV_SIM)\CalcDesign\RunDesign.exe   [ -pli  CalcTb.dll   The test bench C++/Matlab/Python ]

bottom of page