0
votes

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

http://www.edaplayground.com/x/RTC

1
@sujeto1 The code on EDA Playground doesn't seems to be different code. Do you post the correct URL? - Matthew Taylor
@sujeto1 With Verilog in EDA Playground you need to include any other files. This is a little clunky. I would like to change it, but have not thought of a way of doing it that would not break existing saved code (I didn't create EDA Playground, but I'm now the guy who looks after it). I have modified your code to do this at - see edaplayground.com/x/WhA . It now compiles. - Matthew Taylor
Inputs to you submodules should always be defined, you are only defining them in the states that you want to use them. this will imply latches. Also you have lines like NSQ_botA = NSQ_botA >> 24; which looks like you want combinatorial logic to retain state, or your reusing regs to calculate temp values it would be better if you did not do this. - Morgan
@sujeto1 The reason why you're getting latches is because you have incomplete assignment. With combinational logic, all outputs (is all regs assigned in the always block) must be assigned whatever path is taken through the code. That certainty is not the case in your code. This link is about VHDL, but the principle is exactly the same: doulos.com/knowhow/vhdl_designers_guide/synthesising_latches . - Matthew Taylor
Another thing, I see although my program deliver the correct answer, should I still have to fix this problem of latches or can I leave them like this? - sujeto1

1 Answers

2
votes

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