Debugging Verilog中针对MSB下采样的Xilinx警告(FF/闩锁修剪)

Debugging Verilog中针对MSB下采样的Xilinx警告(FF/闩锁修剪),debugging,warnings,verilog,sampling,Debugging,Warnings,Verilog,Sampling,在另一个问题中,我问了一些关于我的模块的一般性建议。 现在我在这里寻求建议,因为我注意到Verilog社区有更多的用户 我试图在现有框架中实现最高有效位(MSB)操作。 其思想如下:我从ddc\u out\u选通获取32位复杂样本,它们是16位I和16位Q。 我的想法是将4个“切割”的样本组合成一个新样本,以馈送到输出bb_样本。这是通过从I0、Q0、I1、Q1、I2、Q2、I3、Q3中取出4个MSB(总共4*8=32位)并每隔4次将它们连接到bb_选通到bb_sample 在这里您可以看到我的

在另一个问题中,我问了一些关于我的模块的一般性建议。 现在我在这里寻求建议,因为我注意到Verilog社区有更多的用户

我试图在现有框架中实现最高有效位(MSB)操作。 其思想如下:我从
ddc\u out\u选通
获取32位复杂样本,它们是16位I和16位Q。 我的想法是将4个“切割”的样本组合成一个新样本,以馈送到输出
bb_样本
。这是通过从I0、Q0、I1、Q1、I2、Q2、I3、Q3中取出4个MSB(总共4*8=32位)并每隔4次将它们连接到
bb_选通
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
我在SE中搜索了这个问题,并找到了一些很好的解释,说明了可能出现的问题,例如。 我的理解如下:
temp\u buff(1)修剪的FF/闩锁警告不是由于非阻塞分配。它来自始终分配给零的
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]};
(2)不应为导线指定任何always块(或初始块),这是正确的。但是,您可以将
导线
转到
reg
reg
仅用于寄存器(FF/LATCH),这是一个错误的概念<正确编码的组合块中的code>reg
将创建组合逻辑(无FF或锁存)。属性,表示在每个分支条件中使用always块分配
reg
,否则它将推断闩锁。范例

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 ... */
模块my\u rx\u dsp0\u自定义
/* ... 您的原始代码*/
输出寄存器[31:0]bb_样本,
有效样本上的输出寄存器bb_选通//高
);
/* ... 您的原始代码*/
始终@(posedge时钟)
如果(ddc输出选通)开始
temp\u buff(1)修剪的FF/闩锁警告不是由于非阻塞分配。它来自始终分配给零的
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]};
(2)不应为导线指定任何always块(或初始块),这是正确的。但是,您可以将
导线
转到
reg
reg
仅用于寄存器(FF/LATCH),这是一个错误的概念<正确编码的组合块中的code>reg
将创建组合逻辑(无FF或锁存)。属性,表示在每个分支条件中使用always块分配
reg
,否则它将推断闩锁。范例

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 ... */
模块my\u rx\u dsp0\u自定义
/* ... 您的原始代码*/
输出寄存器[31:0]bb_样本,
有效样本上的输出寄存器bb_选通//高
);
/* ... 您的原始代码*/
始终@(posedge时钟)
如果(ddc输出选通)开始
temp\u buff(1)修剪的FF/闩锁警告不是由于非阻塞分配。它来自始终分配给零的
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]};
(2)不应为导线指定任何always块(或初始块),这是正确的。但是,您可以将
导线
转到
reg
reg
仅用于寄存器(FF/LATCH),这是一个错误的概念<正确编码的组合块中的code>reg
将创建组合逻辑(无FF或锁存)。属性,表示在每个分支条件中使用always块分配
reg
,否则它将推断闩锁。范例

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 ... */
模块my\u rx\u dsp0\u自定义
/* ... 您的原始代码*/
输出寄存器[31:0]bb_样本,
有效样本上的输出寄存器bb_选通//高
);
/* ... 您的原始代码*/
始终@(posedge时钟)
如果(ddc输出选通)开始
temp\u buff(1)修剪的FF/闩锁警告不是由于非阻塞分配。它来自始终分配给零的
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]};
(2)不应为导线指定任何always块(或初始块),这是正确的。但是,您可以将
导线
转到
reg
reg
仅用于寄存器(FF/LATCH),这是一个错误的概念<正确编码的组合块中的code>reg
将创建组合逻辑(无FF或锁存)。属性,表示在每个分支条件中使用always块分配
reg
,否则它将推断闩锁。范例

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 ... */
模块my\u rx\u dsp0\u自定义
/* ... 您的原始代码*/
输出寄存器[31:0]bb_样本,
有效样本上的输出寄存器bb_选通//高
);
/* ... 您的原始代码*/
始终@(posedge时钟)
如果(ddc输出选通)开始

谢谢你的回复,真的很有帮助!(2) 允许我将
bb_sample
bb_strobe
声明为
reg
,即使在调用此示例的其他模块中,它们被定义为
wire
s?@user17247,是的
reg
wire
不是继承的类型,它们仅适用于当前模块<代码>输出寄存器a
,必须在n处驱动导线(连接)