In this other question I asked I got some general advice regarding my module. Now I seek advice here since I noted that the Verilog community has more users.
I am trying to implement into an existing framework a Most Significant Bit (MSB) operation.
The idea is as follows: I am getting 32 bit complex samples in from ddc_out_strobe
, which are 16 bit I and 16 bit Q.
My idea is to combine 4 "cutted" samples into a new sample to feed to the output bb_sample
. This is done by getting the 4 MSB out of I0,Q0,I1,Q1,I2,Q2,I3,Q3 (4*8 = 32 bit total) and wiring them every 4th bb_strobe
to bb_sample
.
Here you can see my implementation:
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) When trying to build the FPGA images I get the following warning (I just show you the one for 23
, but it is the same for other ones):
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
I have searched this problem in SE and found some good explanations on what might be going wrong, here or here for example.
What I understand is the following: temp_buff <= {i_msb,q_msb,temp_buff[31:24]};
is a conflictive line since the <=
operator is getting the old values from i_msb
and q_msb
, and not the ones from the MSB operation.
(2) I tried avoiding if-else
conditions to allow me to declare some things out of the always @*
block (this way I avoid having a wire on the LHS of an always
block, which is not allowed).
Are my conditionals correct?
As I explained before, I want only every 4th bb_sample
to be assigned.
Is assign bb_strobe = (count==2'd3) ? 1'b1 : 1'b0;
getting the effect I want despite not being in the always @(posedge clock)
block?
If other infos are needed, please let me know. This is part of a much bigger project that I am trying to modify for my purposes.
(1) The trimmed FF/Latch warning is not due to non-blocking assignments. It is from 24 bits of the
temp_buff
register always being assigned to zeros. The RHS is 16bits;i_msb
(4 bits),q_msb
(4 bits), andtemp_buff[31:24]
(8 bits). And you are assigning it to a 32bit value. The assignment:Is equivalent to:
This means
temp_buff[31:16]
will always be zero can can be optimized out.temp_buff[7:0]
can also be optimized out to constant zeros because it is assigned totemp_buff[31:24]
which is a constant 0. Perhaps you meant you shift right 8 bits like so:(2) You are correct that wires should not be assigned with any always block (or initial block). However you could have turned the
wire
to areg
. It is a miss conception thatreg
is for registers only (FF/Latches).reg
in a properly coded combinational block will create combinational logic (no FF or Latches). Property meaning thereg
is assigned within every branching condition withing the always block, else it infers a latch. Example