Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Using a macro gives errors, but putting macro text in explicitly does work

I am using the open source pulp_platform_common_cells which has been implemented for Xilinx FPGAs, and I want to convert it so it also works in Quartus. In Vivado, the project synthesizes fine, but in Quartus, I get the following errors for the stream_throttle.sv file:

  • Verilog HDL syntax error at stream_throttle.sv(90) near text: "("; expecting "endmodule"
  • Verilog HDL syntax error at stream_throttle.sv(90) near text: ")"; expecting ";"
  • Verilog HDL Declaration error at stream_throttle.sv(90): identifier "credit_d" is already declared in the present scope
  • Verilog HDL syntax error at stream_throttle.sv(90) near text: "’0"; expecting an identifier

This error happens at the FF(credit_q, credit_d, '0, clk_i, rst_ni) part where `FF is a macro.
If I put the contents of the macro there instead, everything synthesizes just fine. What could be the issue with this macro?

The error happens near the end of the code. I marked what does work and what doesn’t with comments. For simplicity, I put the macro its complaining about at the top.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

`define FF (__q, __d, __reset_value, __clk , __arst_n ) \
  always_ff @(posedge (__clk) or negedge (__arst_n)) begin                           \
    if (!__arst_n) begin                                                             \
      __q <= (__reset_value);                                                        \
    end else begin                                                                   \
      __q <= (__d);                                                                  \
    end                                                                              \
  end

/// Throttles a ready valid handshaked bus. The maximum number of outstanding transfers have to
/// be set as a compile-time parameter, whereas the number of outstanding transfers can be set
/// during runtime. This module assumes either in-order processing of the requests or
/// indistinguishability of the request/responses.

module stream_throttle (clk_i, rst_ni, req_valid_i, req_valid_o, req_ready_i, req_ready_o, rsp_valid_i, rsp_ready_i, credit_i);

    /// The maximum amount of allowable outstanding requests
    parameter MaxNumPending = 1,
    /// The width of the credit counter (*DO NOT OVERWRITE*)
    CntWidth = cf_math_pkg::idx_width(MaxNumPending);
    /// The type of the credit counter (*DO NOT OVERWRITE*)
    typedef logic [cf_math_pkg::idx_width(MaxNumPending)-1:0] credit_t;

    /// Clock
    input  logic clk_i;
    /// Asynchronous reset, active low
    input  logic rst_ni;

    /// Request valid in
    input  logic    req_valid_i;
    /// Request valid out
    output logic    req_valid_o;
    /// Request ready in
    input  logic    req_ready_i;
    /// Request ready out
    output logic    req_ready_o;

    /// Response valid in
    input  logic    rsp_valid_i;
    /// Response ready in
    input  logic    rsp_ready_i;

    /// Amount of credit (number of outstanding transfers)
    input  credit_t credit_i;

    // we use a credit counter to keep track of how many transfers are pending at any point in
    // time. Valid is passed-through if there is credit.
    credit_t credit_d;
    credit_t credit_q;

    // we have credit available
    logic credit_available;

    // implement the counter. If credit is available let the valid pass, else block it. Increment
    // the counter once a request happens, decrement once a response arrives. Assumes in-order
    // responses.
    always_comb begin : proc_credit_counter

        // default: keep state
        credit_d = credit_q;

        // on valid outgoing request: count up
        if (req_ready_o & req_valid_o) begin
            credit_d = credit_d + 'd1;
        end

        // on valid response: count down
        if (rsp_valid_i & rsp_ready_i) begin
            credit_d = credit_d - 'd1;
        end
    end

    // credit is available
    assign credit_available = credit_q <= (credit_i - 'd1);

    // a request id passed on as valid if the input is valid and we have credit.
    assign req_valid_o = req_valid_i & credit_available;

    // a request id passed on as ready if the input is ready and we have credit.
    assign req_ready_o = req_ready_i & credit_available;
    // state
    `FF(credit_q, credit_d, '0, clk_i, rst_ni) // THIS DOES NOT WORK
    // always_ff @(posedge (clk_i) or negedge (rst_ni)) begin // THIS DOES WORK                          
    //     if (!rst_ni) begin                                                             
    //     credit_q <= ('0);                                                        
    //     end else begin                                                                   
    //     credit_q <= (credit_d);                                                                  
    //     end                                                                              
    // end

endmodule : stream_throttle

>Solution :

The probelm is the whitespace between FF and ( in the macro declaration. Change:

`define FF (__q, __d, __reset_value, __clk , __arst_n ) \

to:

`define FF(__q, __d, __reset_value, __clk , __arst_n ) \

Refer to IEEE Std 1800-2017, section 22.5.1 `define:

The left parenthesis shall follow the text macro name immediately,
with no space in between.

Since Vivado accepted your syntax, Vivado does not comply with the Std in this case.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading