ferrandi / PandA-bambu

PandA-bambu public repository

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue when compiling code with static and volatile keywords

ymherklotz opened this issue · comments

I seem to be having an issue when trying to compile the following C file. Below is a working directory with the bambu log file, and I'm using the following version:

Version: PandA 0.9.7-dev - Revision 6f2d6eb92cb1507af12248a503ef39990d3d9c23-SROA_TCAD_release

The following C code should output 0x100 as b is just shifted to the right by 8. However, in bambu it seems to output 0. I have tried to create a minimal example, meaning everything in the test-case seems to be necessary to show the failure, including the static keywords, volatile keyword and unused a++.

static int b = 0x10000;
static volatile short a = 0;

int result() {
  a++;
  b = (b >> 8) & 0x100;
  return b;
}

Overview of running the test-case

I have uploaded the working directory.

Assuming the test-case is in main.c, we can then generate two different files to run the test-case with gcc and bambu respectively.

./main_gcc.c

#include "main.c"
#include <stdio.h>

int main () {
    int res = result();
    printf("checksum = %08X\n", res);
    return 0;
}

./main_bambu.c

#include "main.c"

int main () { return result(); }

For bambu we also need a test bench in verilog to execute the code:

./tb.v

module testbench;
   reg clock, reset, start_port;
   wire done_port;
   wire [31:0] return_port;

   main m(.clock(clock), .reset(reset), .start_port(start_port), .done_port(done_port), .return_port(return_port));

   always #10 clock = ~clock;

   initial begin
      clock = 0;
      reset = 0;
      start_port = 0;
      @(posedge clock) reset = 0;
      @(posedge clock) reset = 1; start_port = 1;
      @(posedge clock) start_port = 0;
   end

   always @(posedge clock)
     if (done_port) begin
        $display("checksum = %h", return_port);
        $finish;
     end

endmodule

Finally, to reproduce the failing test-case, one can run the following commands. It was reproduced using Icarus Verilog as the simulator, as shown below, or using Questasim as the simulator.

gcc main_gcc.c -o main_gcc
./main_gcc | tee out.gold.txt

output:

checksum = 00000100

running bambu:

bambu main_bambu.c >bambu.log 2>&1
iverilog top.v tb.v -o main_bambu
./main_bambu | tee out.bambu.txt

output:

checksum = 00000000

Using Questasim can be done using the following commands:

vlib work >/dev/null 2>&1
vlog -work work +acc=blnr -noincr -timescale 1ns/1ps tb.v top.v >/dev/null 2>&1
vopt -work work testbench -o work_opt >/dev/null 2>&1
vsim work_opt -batch -do run.do 2>/dev/null | grep -E "checksum = [a-fA-F0-9]{8}"

output:

checksum = 00000000

Hi,

I would say that this code is triggering an implementation-dependent difference between what is done by bambu and what it is done on other systems:
int main () { return result(); }

This is mainly related to the fact that on many Linux systems the main returns 8 bits values. A similar issue is discussed here.

Now this test:

#include "main.c"
#include <stdio.h>

int main () {
    int res = result();
    printf("checksum = %08X\n", res);
    return 0;
}

It simply says that res is equal to 0x100 but it does not say anything about what is returned by main in the previous test.

Now, I tested the code with the current release and I saw that the Verilog return 256 on many bambu supported compilers.
In case CLANG4 is used as the front-end compiler bambu return 0 which is different from what I expect.
Looking at the compiler steps it seems that during the Clang to bambu IR translation the returned value becomes 0. Since the error does not come out when the step is applied on main.c, including only the function result, and since this translation step does some LLVM IR optimizations, I'm expecting that somewhere LLVM takes advantage of this constraint on the 8 bit returned. Not sure this is the true reason.

Cheers,
Fabrizio

Hmm that's interesting, I didn't know that that was an implementation dependent difference, I mostly assumed that it had just to do with an operating system limitation, but that a C compiler would never really truncate it.

And yes, the main is written in this way to print the result when compiled with a C compiler, which I did because of the 8-bit restriction in Linux.

So are you saying that if Bambu is applied only one result, the output is correct? That would be great, so I'll do that instead of using a separate main function.

Thanks,
Yann

I confirm.
Passing only the top function without main and adding --top-fname=result, the testcase works.
Cheers,
Fabrizio

Hi, sorry to comment on this again, I was just wondering if this problem was fixed explicitly somewhere, as it doesn't seem to be an issue anymore on the Bambu 0.9.7-dev branch, which I compiled. Otherwise I just wanted to report that on the dev branch everything works as intended even when using main. It could just be a front end difference as well though.

It actually seems to still happen with the 0.9.7 AppImage version, even when --top-fname=result is added using the following testcase as main.c:

static int b = 0x10000;
static volatile short a = 0;
int result() {
  a++;
  b = (b >> 8) & 0x100;
  return b;
}

Running:

bambu --top-fname=result main.c && iverilog tb.v result.v -o top && ./top

Outputs the following on the current 0.9.7-dev branch:

checksum = 00000100

And outputs the following on the Appimage release on 0.9.7-dev:

checksum = 00000000