在接口中为RTL可读性分配语句会导致合成中的赋值或缓冲区

时间:2015-09-12 02:27:54

标签: interface system-verilog synthesis

我们有一个modports connectin gmodules接口,看起来像这样:

interface test_interface (clk, in1, out1);
    input logic in1;
    output logic out1;
    input logic clk;
    logic mid1;
    logic aliased_signal;

    modport a_to_b (
        input in1,
        input clk,
        output mid1,
        input aliased_signal
    );

    modport b_to_a (
        input clk,
        input mid1,
        output out1,
        output aliased_signal
    );

endinterface : test_interface

module top(clock, inpad, outpad);
    input logic clock;
    input logic inpad;
    output logic outpad;

    test_interface test_if(.clk(clock), .in1(inpad), .out1(outpad));

    a A0(.a2b(test_if));
    b B0(.b2a(test_if));

endmodule

module a ( test_interface.a_to_b a2b);

    always_ff @(posedge a2b.clk) begin
        a2b.mid1 <= a2b.in1 & a2b.aliased_signal;
    end

endmodule

module b (test_interface.b_to_a b2a);

    assign b2a.aliased_signal = b2a.out1;

    always_ff @(posedge b2a.clk) begin
        b2a.out1 <= ~b2a.mid1;
    end

endmodule

这是一个简单的例子,但证明了这个问题。在实际设计中,我们有例如32位输出和8位可以到一个地方,8位到另一个,等等。在目的地,他们想使用在目标模块中更有意义的名称,所以使用赋值在接口中创建这些名称,以便目标代码不仅仅使用接口中模糊总线名称的部分位。

虽然上面的模拟很好,但结果是合成期间的赋值语句(即使明显使用always_comb),虽然我们可以使用合成工具插入缓冲区来使APR满意,但是当这些信号只是方便使用时,这是不可取的。基本上是别名。

是否存在具有SV接口的RTL编码样式,允许这种“混叠”而不会在综合/ APR工具中产生下游复杂性?

以下是我正在尝试做的更接近的例子。 “obfuscated_name”信号是a模块的输出,因为某些模块直接从接口使用该名称(这可以被清理为仅执行a-&gt; b连接正在执行的操作),但是我得到了相同的错误如果我连接到mid2 a-&gt; c而不是直接使用obfuscated_name信号,则为IUS和DC。

interface test_interface(clk, in1, out1, out2);
    input logic [7:0] in1;
    output logic [3:0] out1;
    output logic [3:0] out2;
    input logic clk;
    logic [7:0] obfuscated_name;
    logic [3:0] mid1;
    logic [3:0] mid2;

    modport a_mp (
        input clk,
        input in1,
        output obfuscated_name
    );

    modport a_to_b (
        input clk,
        input .mid1(obfuscated_name[3:0]),
        output out1
    );

    modport a_to_c (
        input clk,
        input obfuscated_name,
        output out2
    );

endinterface : test_interface

module a ( test_interface.a_mp a_intf);

    always_ff @(posedge a_intf.clk) begin
        a_intf.obfuscated_name <= ~a_intf.in1;
    end

endmodule

module b (test_interface.a_to_b b_intf);

    always_ff @(posedge b_intf.clk) begin
        b_intf.out1 <= b_intf.mid1;
    end

endmodule


module c (test_interface.a_to_c c_intf);

    always_ff @(posedge c_intf.clk) begin
        c_intf.out2 <= ~c_intf.obfuscated_name[7:4];
    end

endmodule



module top( input logic clock,
            input logic [7:0] inpad,
            output logic [3:0] outpad1,
            output logic [3:0] outpad2 );


    test_interface test_if(.clk(clock), .in1(inpad), .out1(outpad1), .out2(outpad2));

    a A0(.a_intf(test_if));
    b B0(.b_intf(test_if));
    c C0(.c_intf(test_if));

endmodule

我从IUS得到的错误是:

  

ncvlog:* E,MODPXE(test_interface.sv,18 | 18):不支持的modport   端口标识符'mid1'的表达式。

和DC给出了这个错误:

  

错误:./ b.sv:1:在综合中不支持构造'b_intf.mid1(没有来自父级的modport的modport表达式)'。 (VER-700)

我希望我在这里做一些无知的事情,这是我可能做的事情。

1 个答案:

答案 0 :(得分:2)

Verilog中有一个名为端口表达式 .name_of_port(expression_to_be_connected_to_port)的功能,大多数人都认识到模块实例端口列表中他们没有意识到也可以在模块减速端口列表标题中使用。这声明了端口的名称,以及连接到端口的表达式。这样,较大的内部总线的较小部分选择可以被制成端口。

module DUT(input clk, inout .data(bus[7:0]) );
  wire [31:0] bus;
endmodule
module top;
  reg clock;
  wire [7:0] mydata;
  DUT d1(.data(mydata), .clk(clock) );
endmodule

在SystemVerilog中,您可以使用modport表达式执行相同的操作。

interface test_interface (clk, in1, out1);
    input logic in1;
    output logic out1;
    input logic clk;
    logic mid1;
    logic aliased_signal;

    modport a_to_b (
        input in1,
        input clk,
        output mid1,
        input .aliased_signal(out1) // modport expression
    );

    modport b_to_a (
        input clk,
        input mid1,
        output out1
    );

endinterface : test_interface

module top( input logic clock,
            input logic inpad,
            output logic outpad );


    test_interface test_if(.clk(clock), .in1(inpad), .out1(outpad));

    a A0(.a2b(test_if));
    b B0(.b2a(test_if));

endmodule

module a ( test_interface.a_to_b a2b);

    always_ff @(posedge a2b.clk) begin
        a2b.mid1 <= a2b.in1 & a2b.aliased_signal; // port reference to alias
    end

endmodule

module b (test_interface.b_to_a b2a);

    always_ff @(posedge b2a.clk) begin
        b2a.out1 <= ~b2a.mid1;
    end

endmodule