用于MSB下采样的Xilinx警告(FF / Latch微调)在Verilog中

时间:2014-04-16 13:13:38

标签: debugging warnings verilog sampling

this其他问题中,我问我对我的模块有一些一般性的建议。 现在我在这里寻求建议,因为我注意到Verilog社区有更多的用户。

我试图在现有框架中实现最高有效位(MSB)操作。 这个想法如下:我从ddc_out_strobe得到32位复数样本,它们是16位I和16位Q. 我的想法是将4个“切割”样本组合成一个新样本,以输入到输出bb_sample。这是通过将4 MSB从I0,Q0,I1,Q1,I2,Q2,I3,Q3(4 * 8 =总共32位)中取出并将它们每隔4 bb_strobe连接到bb_sample来完成的

在这里你可以看到我的实现:

module my_rx_dsp0_custom
#(
    //frontend bus width
    parameter WIDTH = 24
)
(
    //control signals
    input clock, //dsp clock
    input reset, //active high synchronous reset
    input clear, //active high on packet control init
    input enable, //active high when streaming enabled

    //user settings bus, controlled through user setting regs API
    input set_stb, input [7:0] set_addr, input [31:0] set_data,

    //full rate inputs directly from the RX frontend
    input [WIDTH-1:0] frontend_i,
    input [WIDTH-1:0] frontend_q,

    //full rate outputs directly to the DDC chain
    output [WIDTH-1:0] ddc_in_i,
    output [WIDTH-1:0] ddc_in_q,

    //strobed samples {I16,Q16} from the RX DDC chain
    input [31:0] ddc_out_sample,
    input ddc_out_strobe, //high on valid sample
    output ddc_out_enable, //enables DDC module

    //strobbed baseband samples {I16,Q16} from this module
    output [31:0] bb_sample,
    output bb_strobe //high on valid sample
);

    reg [3:0] i_msb;
    reg [3:0] q_msb;

    reg [31:0]temp_buff = 0;
    reg [31:0]my_zeros = 0;
    reg [1:0] count = 0;

    always @(posedge clock) 
        if(ddc_out_strobe) begin
            i_msb <= ddc_out_sample[31:28];
            q_msb <= ddc_out_sample[15:12];
            temp_buff <= {i_msb,q_msb,temp_buff[31:24]};
            // to avoid if-else conditions
            count <= (count==2'd3) ? 2'd0 : (count+1);
        end

    // to avoid if-else conditions
    assign bb_strobe = (count==2'd3) ? 1'b1 : 1'b0; 

    assign bb_sample = (count==2'd3) ? temp_buff : my_zeros;    
    assign ddc_out_enable = enable;
    assign ddc_in_i = frontend_i;
    assign ddc_in_q = frontend_q;   

endmodule //my_rx_dsp0_custom

(1)在尝试构建FPGA映像时,我收到以下警告(我只是向您显示23的警告,但对于其他情况则相同):< / p>

WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch <temp_buff_23> has a constant value of 0 in block <my_rx_dsp0_custom>. This FF/Latch will be trimmed during the optimization process

我在SE中搜索了这个问题,并找到了可能出错的一些很好的解释,例如herehere。 我的理解如下:temp_buff <= {i_msb,q_msb,temp_buff[31:24]};是一个冲突行,因为<=运算符从i_msbq_msb获取值,并且不是来自MSB操作的那些。

(2)我试图避免if-else条件允许我从always @*块中声明一些东西(这样我避免在LHS上有一条线路always块,不允许使用。)

我的条件是否正确? 正如我之前解释过的,我只希望每隔4 bb_sample分配一次assign bb_strobe = (count==2'd3) ? 1'b1 : 1'b0;。 尽管不在always @(posedge clock)区块内,{{1}}是否得到了我想要的效果?

如果需要其他信息,请告诉我。这是我想要为我的目的修改的更大项目的一部分。

1 个答案:

答案 0 :(得分:3)

(1)修剪的FF / Latch警告不是由于非阻塞分配造成的。始终将temp_buff寄存器的24位分配给零。 RHS是16位; i_msb(4位),q_msb(4位)和temp_buff[31:24](8位)。并且您将其分配给32位值。作业:

temp_buff <= {i_msb,q_msb,temp_buff[31:24]};

相当于:

temp_buff <= {16'h0000, i_msb,q_msb,temp_buff[31:24]};

这意味着temp_buff[31:16]将始终为零,可以优化出来。 temp_buff[7:0]也可以优化为常量零,因为它被赋值为temp_buff[31:24],这是一个常数0.也许你的意思是你向右移8位:

temp_buff <= {i_msb,q_msb,temp_buff[31: 8 ]};

(2)您是正确的,不应为任何始终块(或初始块)分配电线。但是,您可以将wire变为reg。这是reg仅用于寄存器(FF / Latches)的错误概念。 正确编码的组合块中的reg将创建组合逻辑(无FF或锁存器)。 属性意味着reg在每个分支条件下都使用always块分配,否则它会推断出一个锁存器。实施例

module my_rx_dsp0_custom
/* ... your original code ... */
    output reg [31:0] bb_sample,
    output reg bb_strobe //high on valid sample
);
/* ... your original code ... */
    always @(posedge clock) 
        if(ddc_out_strobe) begin
            temp_buff <= {i_msb,q_msb,temp_buff[31:8]};
            count <= (count==2'd3) ? 2'd0 : (count+1);
        end

    always @*
        begin
            i_msb = ddc_out_sample[31:28];
            q_msb = ddc_out_sample[15:12];
            bb_strobe = (count==2'd3); 
            bb_sample = bb_strobe ? temp_buff : 32'd0;  
        end

    assign ddc_out_enable = enable;
/* ... your original code ... */