

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
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 ]

There are 3 testbench environment to this design.
1. SPV testbench - by C++ library-The most faster environment.
2. Python testbench - Pure python on top of SPV-Verification.