zachjs / sv2v

SystemVerilog to Verilog conversion
BSD 3-Clause "New" or "Revised" License
546 stars 52 forks source link

Support line mapping #61

Closed Kuree closed 4 years ago

Kuree commented 4 years ago

Say we have the following SV file register.sv:

module register (
  input logic clk,
  input logic [15:0] in,
  output logic [15:0] out,
  input logic rst
);

always_ff @(posedge clk, posedge rst) begin
  if (rst) begin
    out <= 16'h0;
  end
  else out <= in;
end
endmodule

We'd like to map the converted Verilog file to the original SV file so that we can trace back back the logic errors to the original source code. The output might look something below (line mapping is in comments for each line if there is a mapping):

module register (
    clk,  // register.v:2
    in,  // register.v:3
    out,  // register.v:4
    rst  // register.v:5
);
    input wire clk;  // register.v:2
    input wire [15:0] in;  // register.v:3
    output reg [15:0] out;  // register.v:4
    input wire rst;  // register.v:5
    always @(posedge clk or posedge rst)  // register.v:8
        if (rst)  // register.v:9
            out <= 16'h0;  // register.v:10
        else  // register.v:12
            out <= in;  // register.v:12
endmodule

I'm not familiar with Haskell but please let me know if I can help in any way to implement this feature.

zachjs commented 4 years ago

Besides using comments, I've also considered using the line directive to communicate source positions to downstream tools. One complicating factor in providing such information (using comments or otherwise) is that one line of Verilog output may be derived from many different parts of the SystemVerilog source, considering type resolution, interface inlining, and indeed many of the other conversions sv2v provides.

I originally intended for sv2v to enable synthesis of SystemVerilog without commercial tools, rather than completely remove commercial tools from one's toolchain. How do you see sv2v fitting into your toolchain? For this instrumentation, what level of granularity would be necessary? Should certain conversions be extended to leave artifacts detailing what they've done?

Kuree commented 4 years ago

We are working on formal analysis tools to assist debugging and fault localization. One of our front-end, i.e. yosys, only takes limited SV syntax so we're planning to convert our SV files via sv2v before feeding them to yosys.

Currently we only need statement-level mapping, e.g. if and assignment, on a line level. We're less worried about conversion as long as the the output is logically equivalent to the original source code.

Please let me know if you have any additional questions. Thanks again for this amazing tool!

zachjs commented 4 years ago

I've pushed a first pass at adding some trace comments to https://github.com/zachjs/sv2v/tree/trace. While it's clearly incomplete, I'm curious how close this gets to fulfilling your needs.

Bellow is the output for the sample you gave. You must specify the -v flag to preserve the trace comments that are generated during parsing. Note that the filename is - because I converted from stdin.

module register (
    clk,
    in,
    out,
    rst
);
    input wire clk;
    input wire [15:0] in;
    output reg [15:0] out;
    input wire rst;
    // Trace: -:8:1
    always // Trace: -:8:11
    @(posedge clk or posedge rst) begin
        // Trace: -:8:39
        // Trace: -:9:3
        if (rst) begin
            // Trace: -:9:12
            // Trace: -:11:3
            out <= 16'h0;
        end
        else
            // Trace: -:12:8
            out <= in;
    end
endmodule
Kuree commented 4 years ago

Yes this is enough for our use cases. Thank you very much!

zachjs commented 4 years ago

I've made some upgrades to the trace implementation to cover more constructs and remove redundant comments. This is now merged onto master. Please let me know if you run into any issues!

Below is the result now produced for your given example:

module register (
    clk,
    in,
    out,
    rst
);
    // Trace: -:2:9
    input wire clk;
    // Trace: -:3:9
    input wire [15:0] in;
    // Trace: -:4:10
    output reg [15:0] out;
    // Trace: -:5:9
    input wire rst;
    // Trace: -:8:1
    always @(posedge clk or posedge rst)
        // Trace: -:9:3
        if (rst)
            // Trace: -:10:17
            out <= 16'h0;
        else
            // Trace: -:12:8
            out <= in;
endmodule