Reputation: 31
module OB_Addr_Contr_B1(
input clk,
input rst_n,
input wire signed [3:0] o_00,
output reg [31:0] OB_Data_00,
output wire [7:0] addr_write_0,
output wire write_enable_0
);
reg [3:0] cnt_0;
reg [5:0] Data_cnt_00;
reg rom_enable_0;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_0 <= 0;
Data_cnt_00 <= 0;
end
else if(cnt_0 == 8) begin
cnt_0 <= 1 ;
Data_cnt_00 <= Data_cnt_00 + 1;
end
else begin
cnt_0 <= cnt_0 + 1;
end
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
rom_enable_0 <= 0;
end
else if(cnt_0 == 7)
rom_enable_0 <= 1;
else
rom_enable_0 <= 0;
end
always@(*)begin
if(cnt_0 == 0)
OB_Data_00 = 0;
else if(cnt_0<=8)begin
OB_Data_00[31 - ((cnt_0-1'b1)<<2) -: 4] = o_00;
end
else
OB_Data_00 = OB_Data_00;
end
endmodule
My cnt_0
loops between 1~8, the always@(*)
statement has covered all cases, but the hardware synthesized by Vivado will still generate "RTL_LATCH".
Changing "always@(*)" to "always@(posedge clk)" does generate registers instead of "RTL_LATCH", but this gives me problems with my waveforms because it delays the assignment by one clk, which makes me very distressed.
I uploaded 3 pictures. The first one above is the circuit diagram synthesized by the code I provided.
The first one below is the waveform diagram corresponding to the circuit diagram, the waveform is what I want, and it is correct when cnt_0 is 8 The output is "0xffffffff".
The waveform diagram below is a wrong waveform diagram. It is the waveform generated by changing "always@(*)" to "always@(posedge clk)". The delay of one cycle leads to the error of the result(0xfffffff0).
I changed "always@(*)" to "always@(posedge clk)" and it did generate the circuit without LATCH, but also caused the waveform result to go from correct to wrong.
always@(cnt_0)begin
case(cnt_0)
0: OB_Data_00 = 0;
1: OB_Data_00[31:28] = o_00;
2: OB_Data_00[27:24] = o_00;
3: OB_Data_00[23:20] = o_00;
4: OB_Data_00[19:16] = o_00;
5: OB_Data_00[15:12] = o_00;
6: OB_Data_00[11: 8] = o_00;
7: OB_Data_00[ 7: 4] = o_00;
8: OB_Data_00[ 3: 0] = o_00;
default:OB_Data_00 = 0;
endcase
end
I modified the codes as suggested above and they still generate LATCH.
Upvotes: 1
Views: 126
Reputation: 62236
This line might be a cause for the inferred latch because it retains the state of OB_Data_00
:
OB_Data_00 = OB_Data_00;
You can probably simplify the always
block as follows since cout_0
can never be greater than 8:
always @(*) begin
if (cnt_0 == 0)
OB_Data_00 = 0;
else
OB_Data_00[31 - ((cnt_0-1'b1)<<2) -: 4] = o_00;
end
the always@(*) statement has covered all cases
That statement is incorrect. This line is also a potential cause of inferred latches because it does not make an assignment to all 32 bits of OB_Data_00
:
OB_Data_00[31 - ((cnt_0-1'b1)<<2) -: 4] = o_00;
For example, when cnt_0=2, it resolves to:
OB_Data_00[27:24] = o_00;
This only assigns to 4 of the 32 bits of OB_Data_00
, leaving the other 28 bits to retain their state.
The case
version of your code infers latches for the same reason. The case
version has another problem: an incomplete sensitivity list. It should use always @*
Upvotes: 1