Quartus is telling me that I have inferred latches for input_val, ii, output_val, delayed, and addr_to_rom. I have looked at previous posts and made changes so that all my if statements have an else component and that my case statement has a default option.
What else could be causing all of these inferred latches? (updated code below)
module simple_fir(clk, reset_n, output_val);
parameter data_width = 8;
parameter size = 1024;
input wire clk;
input wire reset_n;
//input reg [(data_width):0] input_val;
reg [(data_width):0] input_val;
output reg [data_width:0] output_val;
reg [(data_width):0] delayed;
reg [data_width:0] to_avg;
reg [9:0] ii ;
reg [9:0] i ;
reg [data_width:0] val;
reg [data_width:0] output_arr [(size-1):0];
logic [(data_width):0] data_from_rom; //precalculated 1 Hz sine wave
logic [9:0] addr_to_rom;
initial delayed = 0;
initial i = 0;
initial ii = 0;
//port map to ROM
rom_data input_data(
.clk(clk),
.addr(addr_to_rom), //text file?
.data(data_from_rom)
);
//Moore FSM
localparam [3:0]
s0=0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6;
reg [3:0] state_reg, state_next;
initial state_next = 0;
always @(posedge clk, negedge reset_n) begin //posedge clk, reset_n
if (reset_n == 'b0) begin //reset is active low
state_reg <= s0;
end else begin
state_reg <= state_next;
end
end
always @* begin
state_next = state_reg; // default state_next
case (state_reg)
s0 : begin //initial state, reset state
if (!reset_n) begin
output_val = 0;
delayed = 0;
to_avg= 0;
i = 0;
ii = 0;
end else begin
state_next = s1;
end
end
s1 : begin
if (ii>(size-2)) begin
ii = 0;
end else begin
addr_to_rom = ii;
end
input_val = input_val;
delayed = delayed;
state_next = s2;
end
s2 : begin
input_val = data_from_rom;
ii = ii+1;
delayed = delayed;
state_next = s3;
end
s3 : begin
delayed = input_val;
state_next = s4;
end
s4 : begin
addr_to_rom = ii;
input_val = input_val;
delayed = delayed;
state_next = s5;
end
s5 : begin
input_val = data_from_rom;
delayed = delayed;
//i=i+1;
//ii <= ii+1;
state_next = s6;
end
s6 : begin
to_avg = input_val + delayed; //summing two values
val = (to_avg >> 1); //taking the average
output_arr[ii-1] = val; //indexing starts on [2]
output_val = val;
state_next = s0;
input_val = input_val;
end
default: begin
addr_to_rom = addr_to_rom;
data_from_rom = data_from_rom;
delayed = delayed;
input_val = input_val;
to_avg = to_avg;
val = val;
output_val = output_val;
ii = ii;
end
endcase
end
endmodule
you have to look at the ways state machines are programmed. Usually states are calculated using flop and the final assignment is a combinatorial. You have it vice versa. Therefore you have issues. Something like the following should work for you. Sorry, i did not test it. The code needs to use non-blocking assignments except in the place where you caculate an intermediate value.
always @*
state_reg = state_next;
always @(posedge clk, negedge reset_n) begin //posedge clk, reset_n
if (reset_n == 'b0) begin //reset is active low
state_next <= s0;
end
else begin
case (state_reg)
S0: begin
output_val <= 0;
delayed <= 0;
i <= 0;
ii <= 0;
end
s1 : begin
if (ii>(size-2)) begin
ii <= 0;
end else begin
addr_to_rom <= ii;
end
input_val <= input_val;
delayed <= delayed;
state_next <= s2;
end
s2 : begin
input_val <= data_from_rom;
ii <= ii+1;
state_next <= s3;
end
s3 : begin
delayed <= input_val;
state_next <= s4;
end
s4 : begin
addr_to_rom <= ii;
state_next <= s5;
end
s5 : begin
input_val <= data_from_rom;
state_next <= s6;
end
s6 : begin
// calculating intermediate value, need blocking assignments here
to_avg = input_val + delayed; //need blocking here
val = (to_avg >> 1); //need blocking here
output_arr[ii-1] <= val; //indexing starts on [2]
output_val <= val;
state_next <= s0;
end
endcase
end // else
end // always