aquaxis / synverll

MIT License
14 stars 0 forks source link

An execution result of C and an execution result of the simulator don't agree about the program which purchases Fibonacci. #2

Closed ikwzm closed 8 years ago

ikwzm commented 8 years ago

I wrote fib.c

int fib(int n)
{
  int curr = 0;
  int next = 1;
  int i;
  for(i = 0; i < n; i++) {
    int prev = curr;
    curr = next;
    next += prev;
  }
  return curr;
}

and I wrote fib_test.c(test program for fib.c)

#include <stdio.h>
void main()
{
  int i;
  for(i = 0; i < 7; ++i) {
    printf("%d => %d\n", i, fib(i));
  }
}

compile and execute.

shell% gcc -o fib_test fib_test.c fib.c
shell% ./fib_test
0 => 0
1 => 1
2 => 1
3 => 2
4 => 3
5 => 5
6 => 8

generate fib.v from fib.c use synverll

shell% synverll
Synverll Rev 0.03
 Synthesis for Verilog HDL using LLVM
 C Source to Verilog-HDL Convertor
 Hidemi Ishihara <hidemi(at)aquaxis.com>

Usage:
 synverll [-d] C_SOURCE_FILENAME
  -d: Debug Mode(output a debug file)

shell% synverll fib.c
topname: fib_top
[Parser Start]
Open Filename: fib.c
 -> Parser for C Source
 -> create process source
 -> create header source
 -> Function Count: 1
[LLVM Compile Start]
[LLVM-IR function parser start]
[Parsing struct type for LLCM-IR]
 -> Create Stage for LLVM-IR
 -> Parser Memory Tree
 -> deploy_array_type
 -> Create Verilog HDL for Proc Tree
 -> Output Verilog HDL: module = fib
 -> Output Memory Map
[Create top Module]

generated fib.v

/*
 * Copyright (C)2005-2015 AQUAXIS TECHNOLOGY.
 *  Don't remove this header.
 * When you use this source, there is a need to inherit this header.
 *
 * This software is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * For further information please contact.
 *  URI:    http://www.aquaxis.com/
 *  E-Mail: info(at)aquaxis.com
 */
module fib(
    input __func_clock,
    input __func_reset,
    input __func_start,
    output reg __func_done,
    output reg __func_ready,

    // Memory Singal
    input [31:0] __args_n,
    // Call Singal
    // Result Singal
    output reg [31:0] __func_result

);

reg [0:0] __sig_1;
reg [31:0] __sig_2;
reg [31:0] __sig_curr_03;
reg [31:0] __sig_i_02;
reg [31:0] __sig_next_01;
reg [31:0] __sig_4;
reg [31:0] __sig_5;
reg [0:0] __sig_exitcond;
reg [31:0] __sig_next_01_lcssa;
reg [31:0] __sig_curr_0_lcssa;
    reg [31:0] __sig_n;
localparam __state_fin_exec = 0;
localparam __state_start_req = 1;
localparam __state_start_wait = 2;
localparam __state_start_exec = 3;
localparam __state_1_exec = 4;
localparam __state_2_exec = 5;
localparam __state_3_exec = 6;
localparam __state_4_exec = 7;
localparam __state_5_exec = 8;
localparam __state_6_exec = 9;
localparam __state_7_exec = 10;
localparam __state_8_exec = 11;
localparam __state_9_exec = 12;
localparam __state_10_exec = 13;
localparam __state_11_exec = 14;
localparam __state_12_exec = 15;
localparam __state_13_exec = 16;
localparam __state_14_exec = 17;
localparam __state_15_exec = 18;
integer __state;
localparam __label_0 = 0;
localparam __label__lr_ph = 4;
localparam __label_3 = 6;
localparam __label___crit_edge_loopexit = 10;
localparam __label___crit_edge = 12;
integer __label;
always @(posedge __func_clock or negedge __func_reset) begin
    if(!__func_reset) begin
        __state <= __state_start_req;
        __func_ready <= 1;
        __func_done <= 0;
    end else begin
    case(__state)
        __state_start_req: begin
            __state <= __state_start_wait;
        end
        __state_start_wait: begin
            if(__func_start) begin
                __state <= __state_start_exec;
                __func_ready <= 0;
                __func_done <= 0;
            __sig_n <= __args_n;
            end
        end
        __state_start_exec: begin
            __state <= __state_1_exec;
        end
        __state_1_exec: begin
            __state <= __state_2_exec;
        end
        __state_2_exec: begin
            __state <= __state_3_exec;
            __sig_1 <= ( $signed(__sig_n) > $signed((0)) );
            __sig_2 <= $signed(__sig_n) + $signed((-1));
        end
        __state_3_exec: begin
            __state <= (__sig_1)?__state_4_exec:__state_12_exec;
        end
        __state_4_exec: begin
            __state <= __state_5_exec;
            __label <= __label__lr_ph;
        end
        __state_5_exec: begin
            __state <= __state_6_exec;
        end
        __state_6_exec: begin
            __state <= __state_7_exec;
            __label <= __label_3;
        end
        __state_7_exec: begin
            __state <= __state_8_exec;
            case(__label)
                __label__lr_ph: __sig_curr_03 <= (0);
                __label_3: __sig_curr_03 <= __sig_next_01;
            endcase
            case(__label)
                __label__lr_ph: __sig_i_02 <= (0);
                __label_3: __sig_i_02 <= __sig_5;
            endcase
            case(__label)
                __label__lr_ph: __sig_next_01 <= (1);
                __label_3: __sig_next_01 <= __sig_4;
            endcase
        end
        __state_8_exec: begin
            __state <= __state_9_exec;
            __sig_4 <= $signed(__sig_curr_03) + $signed(__sig_next_01);
            __sig_5 <= $signed(__sig_i_02) + $signed((1));
            __sig_exitcond <= ( __sig_i_02 == __sig_2 );
        end
        __state_9_exec: begin
            __state <= (__sig_exitcond)?__state_10_exec:__state_6_exec;
        end
        __state_10_exec: begin
            __state <= __state_11_exec;
            __label <= __label___crit_edge_loopexit;
        end
        __state_11_exec: begin
            __state <= __state_12_exec;
            case(__label)
                __label_3: __sig_next_01_lcssa <= __sig_next_01;
            endcase
        end
        __state_12_exec: begin
            __state <= __state_13_exec;
            __label <= __label___crit_edge;
        end
        __state_13_exec: begin
            __state <= __state_14_exec;
            case(__label)
                __label_0: __sig_curr_0_lcssa <= (0);
                __label___crit_edge_loopexit: __sig_curr_0_lcssa <= __sig_next_01_lcssa;
            endcase
        end
        __state_14_exec: begin
            __state <= __state_fin_exec;
            __func_result <= $signed(__sig_curr_0_lcssa);
        end
        __state_15_exec: begin
            __state <= __state_fin_exec;
        end
        __state_fin_exec: begin
            __state <= __state_start_req;
            __func_ready <= 1;
            __func_done <= 1;
        end
    endcase
    end
end
endmodule

I wrote fib_test.v (test_bench for fib.v)

module fib_test;
   reg         clk = 0;
   reg         rst = 1;
   reg         fib_start;
   reg  [31:0] fib_n;
   wire        fib_done;
   wire        fib_ready;
   wire [31:0] fib_result;

   always #10
      clk <= !clk;

   task test;
      input [31:0] n;
      input [31:0] expected_result;
      integer      timeout;
      begin
         repeat(10) @(posedge clk);
         fib_n     <= #1 n;
         fib_start <= #1 1;
         @(posedge clk);
         fib_start <= #1 0;
     timeout   = 1000;
     begin: loop
        forever begin
               @(posedge clk);
               if (fib_done) begin
                  if (fib_result !== expected_result)
                      $display("fib_return = %d expected but %d found.", expected_result, fib_result);
                  disable loop;
               end
               if (timeout == 0) begin
                  $display("fib_done is timeout.");
                  rst <= #1 0;
                  repeat(10) @(posedge clk);
                  rst <= #1 1;
                  disable loop;
               end
               timeout = timeout - 1;
            end
     end
      end
   endtask

   initial begin
      rst       <= 0;
      fib_n     <= 0;
      fib_start <= 0;
      repeat(10) @(posedge clk);
      rst <= #1 1;
      test(0, 0);
      test(1, 1);
      test(2, 1);
      test(3, 2);
      test(4, 3);
      test(5, 5);
      test(6, 8);
      $stop;
   end

   fib dut(
       .__func_clock (clk),
       .__func_reset (rst),
       .__func_start (fib_start ),
       .__func_done  (fib_done  ),
       .__func_ready (fib_ready ),
       .__args_n     (fib_n     ),
       .__func_result(fib_result)
    );
endmodule

simulation on Xilinx Vivado 2015.3

Vivado Simulator 2015.3
Copyright 1986-1999, 2001-2015 Xilinx, Inc. All Rights Reserved.
Running: E:/Xilinx/Vivado/2015.3/bin/unwrapped/win64.o/xelab.exe -wto b025135b906741e6a779a306912a6b47 --debug typical --relax --mt 2 -L xil_defaultlib -L unisims_ver -L unimacro_ver -L secureip --snapshot fib_test_behav xil_defaultlib.fib_test xil_defaultlib.glbl -log elaborate.log 
Using 2 slave threads.
Starting static elaboration
Completed static elaboration
Starting simulation data flow analysis
WARNING: [XSIM 43-4100] "H:/gist/msgpack-vhdl-examples/examples/fibonacci/sim/vivado/synverll/fib_test/fib_test.sim/sim_1/behav/glbl.v" Line 6. Module glbl has a timescale but at least one module in design doesn't have timescale.
WARNING: [XSIM 43-4100] "H:/gist/msgpack-vhdl-examples/examples/fibonacci/sim/vivado/synverll/fib_test/fib_test.sim/sim_1/behav/glbl.v" Line 6. Module glbl has a timescale but at least one module in design doesn't have timescale.
Completed simulation data flow analysis
Time Resolution for simulation is 1ps
Compiling module xil_defaultlib.fib
Compiling module xil_defaultlib.fib_test
Compiling module xil_defaultlib.glbl
Built simulation snapshot fib_test_behav
Vivado Simulator 2015.3
Time resolution is 1 ps
run all
fib_return =          0 expected but          x found.
fib_done is timeout.
fib_done is timeout.
fib_done is timeout.
fib_done is timeout.
fib_done is timeout.
fib_done is timeout.

not return fib_done when (n > 0) and return 'x' when (n==0)

Do I make a mistake in anything?

aquaxis commented 8 years ago

Hello,

Sorry, synverll mistake a create with label. Output RTL can't state with Branch of LLVM-IR.

I modify with V0.4.

Best regards,