在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中搜索了这个问题,并找到了可能出错的一些很好的解释,例如here或here。
我的理解如下:temp_buff <= {i_msb,q_msb,temp_buff[31:24]};
是一个冲突行,因为<=
运算符从i_msb
和q_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}}是否得到了我想要的效果?
如果需要其他信息,请告诉我。这是我想要为我的目的修改的更大项目的一部分。
答案 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 ... */