UPDATE: I'm editing this question to change the Equation to a more simple one, although the issues are about the same, with the difference that this time, I actually could it make it gives the correct answer to the calculation, yet I keep having a problem of "latches".(my original equation is also working fine, but same warning latches issues).
I want to do a simple Equation step by Step which is as follows:
c = 50 / (|a - 2|^2 + |b - 5|^2)
Data is unsigned binary 32 bits values, subtraction result is also unsigned (absolute values), What I want to do is to perform this in several steps using a clock,
|a - 2| , // First this subtraction
|b - 5| AND |a - 2|^2, // then a subtraction and a square of before
|a - 2|^2 + |b - 5|^2 // then the another square plus the before square
c = 50 / |a - 2|^2 + |b - 5|^2 /// finally a division of 50
What I'm expecting is that synthesis tool generates only in 1 Subtraction, 1 Squaring and 1 Division for the whole process, in the this simplified version that situation only happen at the Squaring and Subtraction since there is only 1 division operation. First question: am I really doing what intended? is Quartus II generating a "datapath"? is hardware/energy being actually saved?
I'm new in verilog and digital design in general and teaching myself this, please correct me if my conceptions are wrong.
I have created the modules of division, subtraction and Squaring separately because I plan to implement them later instead of relying on the /,-,* operators. Reason is because I may guess, by programming more efficient algorithm (available by authors in internet for example) I could substitute the operators-inferred algorithms of Quartus II. But again I'm not sure.
This program runs correctly, output is the expected, However, I'm receiving a lot of warnings from Quartus-II like this
Warning (10240): Verilog HDL Always Construct warning at FCM_EQ.v(88): inferring latch(es) for variable "SU_in_a", which holds its previous value in one or more paths through the always construct
Warning (13012): Latch SQ_in_a[18] has unsafe behavior Warning (13013): Ports D and ENA on the latch are fed by the same signal state.S2
I barely knows what a latch is, I read one have to avoid the latches, is that registers keep its values in different clocks? the whole program is exactly about that, so I'm not sure how would I fix that. Any advices or alternative solutions?
The top-module is this:
module FCM_EQ (a, b, c, clk, enable, rst_n, all_finish, OBS);
input [31:0] a, b;
input clk, enable, rst_n;
output [31:0] c;
output [63:0] OBS;
output all_finish;
reg [31:0] SU_in_a, SU_in_b;
wire [31:0] SU_out_r;
reg [31:0] SQ_in_a;
wire [63:0] SQ_out_r;
reg [63:0] DIV_in_b;
reg [63:0] DIV_in_a;
wire [63:0] DIV_out_r;
reg [31:00] botA, botB, c;
reg [63:00] SQ_botA, SQ_botB, N_C;
reg [63:0] den_total;
reg all_finish;
reg [4:0] state, nextstate;
reg [63:0] OBS;
parameter FIFTY = 64'b0000000000000000_0000000000110010_0000000000000000_0000000000000000;
parameter FIVE = 32'b0000000000000101_0000000000000000;
parameter TWO = 32'b0000000000000010_0000000000000000;
parameter reset = 0;
parameter S0 = 1;
parameter S1 = 2;
parameter S2 = 3;
parameter S3 = 4;
SUB_VAL SU_inst1(.a (SU_in_a),.b (SU_in_b),.r (SU_out_r) );
SQ_VAL SQ_inst1 (.a (SQ_in_a),.r (SQ_out_r) );
DIV_VAL DIV_inst1 (.a (DIV_in_a),.b (DIV_in_b),.r (DIV_out_r) );
always @ (posedge clk or negedge rst_n)
if (~rst_n)
state <= reset ;
else
state <= nextstate;
always @*
begin
case (state)
reset:
begin
if (enable == 1)
nextstate = S0;
else
nextstate = reset;
end
S0:
begin
SU_in_a = a;
SU_in_b = TWO;
botA = SU_out_r;
nextstate = S1;
end
S1:
begin
SU_in_a = b;
SU_in_b = FIVE;
botB = SU_out_r;
SQ_in_a = botA;
SQ_botA = SQ_out_r;
nextstate = S2;
end
S2:
begin
SQ_in_a = botB;
SQ_botB = SQ_out_r; // SQ_botB is 64 bits (32_32)
den_total = SQ_botA + SQ_botB;
den_total = den_total >> 24;
nextstate = S3;
end
S3:
begin
DIV_in_a = FIFTY;
DIV_in_b = den_total;
N_C = DIV_out_r;
OBS = N_C;
c = N_C [31:0]; // Extract 32 bits en total (16_24)
all_finish = 1;
nextstate = reset;
end
default:
begin
nextstate = reset;
end
endcase
end
endmodule
OBS register is just my noob way to check for a value of a register in the Modelsim since I ignore if there is a better way to watch over this.
The Testbench and the full code can be seen here
Not a full answer just quick observations:
always @ (posedge clk)
state <= nextstate; //Use Non blocking
always @* // Auto sensitivity list
begin
case (state)
I would also recommend reseting your state:
always @ (posedge clk or negedge rst_n)
if (~rst_n)
state <= 'b0 ;
else
state <= nextstate; //Non blocking