Search code examples
verilogregister-transfer-level

How to resolve synthesis warnings in Verilog code for I2S?


When synthesizing using vivado and design compiler, the following warnings appear respectively. How should I change the code?

vivado

[Synth 8-3332] Sequential element (\i2s_rx/rx_right_reg[15] ) is unused and will be removed from module i2s_top.

[Synth 8-3332] Sequential element (\i2s_rx/rx_right_reg[15] ) is unused and will be removed from module i2s_top.

design compiler

line# 255: Warning: Verilog 'assign' or 'tran' statements are written out. (VO-4)

i2s_top

module i2s_top #(
    parameter AUDIO_DW = 16
)(
    input i_tx_sclk,
    input i_rst_n,
    input [AUDIO_DW-1:0] i_tx_prescaler,
    input [AUDIO_DW-1:0] i_tx_left_chan,
    input [AUDIO_DW-1:0] i_tx_right_chan,

    output [AUDIO_DW-1:0] o_rx_left_chan,
    output [AUDIO_DW-1:0] o_rx_right_chan
);

wire w_sclk;
wire w_lrclk;
wire w_sdata;

i2s_tx #(
    .AUDIO_DW(AUDIO_DW)
) i2s_tx (
    .i_tx_sclk(i_tx_sclk),
    .i_tx_rst_n(i_rst_n),
    .i_tx_prescaler(i_tx_prescaler),
    
    .o_tx_sclk(w_sclk),
    .o_tx_lrclk(w_lrclk),
    .o_tx_sdata(w_sdata),
    
    .i_tx_left_chan(i_tx_left_chan),
    .i_tx_right_chan(i_tx_right_chan)
);

i2s_rx #(
    .AUDIO_DW(AUDIO_DW)
) i2s_rx (
    .i_rx_sclk(w_sclk),
    .i_rx_rst_n(i_rst_n),
    .i_rx_lrclk(w_lrclk),
    .i_rx_sdata(w_sdata),
    .o_rx_left_chan(o_rx_left_chan),
    .o_rx_right_chan(o_rx_right_chan)
);

endmodule

i2s_tx

`timescale 1ns / 1ns

module i2s_tx #(
    parameter AUDIO_DW = 16
)(
    input i_tx_sclk,
    input [AUDIO_DW-1:0] i_tx_prescaler,
    input i_tx_rst_n,
    
    output wire o_tx_sclk,
    output reg o_tx_lrclk,
    output reg o_tx_sdata,

    input [AUDIO_DW-1:0] i_tx_left_chan,
    input [AUDIO_DW-1:0] i_tx_raight_chan
);

reg [AUDIO_DW-1:0] tx_bit_cnt;
reg [AUDIO_DW-1:0] tx_left;
reg [AUDIO_DW-1:0] tx_right;

assign o_tx_sclk = i_tx_sclk;

always @(negedge i_tx_sclk or negedge i_tx_rst_n) begin
    if (!i_tx_rst_n) begin
        tx_bit_cnt <= 1;
        tx_left <= 0;
        tx_right <= 0;
        o_tx_lrclk <= 0;
        o_tx_sdata <= 0;
        
    end else begin
        if (tx_bit_cnt >= i_tx_prescaler) begin
            tx_bit_cnt <= 1;
        end else begin
            tx_bit_cnt <= tx_bit_cnt + 1;
        end
        
        if (tx_bit_cnt == i_tx_prescaler && o_tx_lrclk) begin
            tx_left <= i_tx_left_chan;
            tx_right <= i_tx_right_chan;
        end
                
        o_tx_lrclk <= (tx_bit_cnt == i_tx_prescaler) ? ~o_tx_lrclk : o_tx_lrclk;
    
        o_tx_sdata <= o_tx_lrclk ? tx_right[AUDIO_DW - tx_bit_cnt] : tx_left[AUDIO_DW - tx_bit_cnt];
    end
end

endmodule

i2s_rx

`timescale 1ns / 1ns

module i2s_rx #(
    parameter AUDIO_DW = 16
)(
    input i_rx_sclk,
    input i_rx_rst_n,
    input i_rx_lrclk,
    input i_rx_sdata,

    output reg [AUDIO_DW-1:0] o_rx_left_chan,
    output reg [AUDIO_DW-1:0] o_rx_right_chan
);

reg [AUDIO_DW-1:0] rx_left;
reg [AUDIO_DW-1:0] rx_right;
reg rx_lrclk_r;
wire rx_lrclk_nedge;

assign rx_lrclk_nedge = !i_rx_lrclk & rx_lrclk_r;

always @(posedge i_rx_sclk or negedge i_rx_rst_n)
    if (!i_rx_rst_n) begin
        rx_lrclk_r <= 0;
        rx_left <= 0;
        rx_right <= 0;
    end else begin
        rx_lrclk_r <= i_rx_lrclk;
        if (rx_lrclk_r) begin
            rx_right <= {rx_right[AUDIO_DW-2:0], i_rx_sdata};
        end else 
            rx_left <= {rx_left[AUDIO_DW-2:0], i_rx_sdata};
    end

always @(posedge i_rx_sclk or negedge i_rx_rst_n)
    if (!i_rx_rst_n) begin
        o_rx_left_chan <= 0;
        o_rx_right_chan <= 0;
    end else if (rx_lrclk_nedge) begin
        o_rx_left_chan <= rx_left;
        o_rx_right_chan <= {rx_right[AUDIO_DW-2:0], i_rx_sdata};
    end

endmodule


Solution

    1. rx_right[15] doesn't affect the outputs of the module i2x_rx. So you may change its declaration to reg [AUDIO_DW-2:0] rx_right.

    2. Add "set_multiple_port_nets -all -buffer_constants" before compile/compile_ultra to add buffers to replace "assign" statements in output netlist.

    Here are some lines of the modified module i2s_rx:

    module i2s_rx #(
    ...
    );
    ...
    reg [AUDIO_DW-1:0] rx_left;
    reg [AUDIO_DW-2:0] rx_right;  // <-- After modified
    reg rx_lrclk_r;
    ...
    

    The "assign" statement in output netlist may be casued by the following line in module i2s_tx:

    assign o_tx_sclk = i_tx_sclk;
    

    If you don't want it, you may remove the above line and o_tx_sclk output port of i2s_tx, then connect i_tx_sclk to i2s_rx in module i2s_top:

    i2s_rx #(
        .AUDIO_DW(AUDIO_DW)
    ) i2s_rx (
        .i_rx_sclk(i_tx_sclk),  // <-- After modified
        .i_rx_rst_n(i_rst_n),
        .i_rx_lrclk(w_lrclk),
        .i_rx_sdata(w_sdata),
        .o_rx_left_chan(o_rx_left_chan),
        .o_rx_right_chan(o_rx_right_chan)
    );