Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Vivado Mitigations to be ifdef-guarded #8310

Open
seldridge opened this issue Mar 10, 2025 · 0 comments
Open

Move Vivado Mitigations to be ifdef-guarded #8310

seldridge opened this issue Mar 10, 2025 · 0 comments

Comments

@seldridge
Copy link
Member

seldridge commented Mar 10, 2025

We currently have two Vivado-centric mitigations to address pretty egregious bugs in Vivado tooling. One of these is mitigated with a Vivado-specific SystemVerilog attribute.

Change the SystemVerilog attribute to be ifdef guarded with a macro that is only defined for Vivado. (I don't know what this is, but it's probably XILINX.)

E.g., consider the following FIRRTL circuit:

FIRRTL version 4.2.0
circuit Foo:
  public module Foo:
    input clock: Clock
    input r: {addr: UInt<3>, en: UInt<1>, flip data: UInt<8>}
    input w: {addr: UInt<3>, en: UInt<1>, data: UInt<8>, mask: UInt<1>}

    mem memory:
      data-type => UInt<8>
      depth => 16
      reader => r
      writer => w
      read-latency => 0
      write-latency => 1
      read-under-write => undefined

    connect memory.r.addr, r.addr
    connect memory.r.en, r.en
    connect memory.r.clk, clock
    connect r.data, memory.r.data

    connect memory.w.addr, w.addr
    connect memory.w.en, w.en
    connect memory.w.clk, clock
    connect memory.w.data, w.data
    connect memory.w.mask, w.mask

Change this so that, when compiled it produces:

// Generated by CIRCT firtool-1.108.0-23-g231dea049
// VCS coverage exclude_file
module memory_16x8(
  input  [3:0] R0_addr,
  input        R0_en,
               R0_clk,
  output [7:0] R0_data,
  input  [3:0] W0_addr,
  input        W0_en,
               W0_clk,
  input  [7:0] W0_data
);

  `ifdef XILINX
  (* ram_style = "distributed" *)
  `endif
  reg [7:0] Memory[0:15];
  reg       _R0_en_d0;
  reg [3:0] _R0_addr_d0;
  always @(posedge R0_clk) begin
    _R0_en_d0 <= R0_en;
    _R0_addr_d0 <= R0_addr;
  end // always @(posedge)
  always @(posedge W0_clk) begin
    if (W0_en & 1'h1)
      Memory[W0_addr] <= W0_data;
  end // always @(posedge)
  assign R0_data = _R0_en_d0 ? Memory[_R0_addr_d0] : 8'bx;
endmodule

module Foo(
  input        clock,
  input  [2:0] r_addr,
  input        r_en,
  output [7:0] r_data,
  input  [2:0] w_addr,
  input        w_en,
  input  [7:0] w_data,
  input        w_mask
);

  memory_16x8 memory_ext (
    .R0_addr ({1'h0, r_addr}),
    .R0_en   (r_en),
    .R0_clk  (clock),
    .R0_data (r_data),
    .W0_addr ({1'h0, w_addr}),
    .W0_en   (w_en & w_mask),
    .W0_clk  (clock),
    .W0_data (w_data)
  );
endmodule

As part of this, investigate if there are Vivado-specific macros that it defines, e.g., if XILNIX is actually defined. If no such define exists, then we may need to define one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant