-1

I did a counter like i normally do on VHDL (Modelsim) and when i simulate my code with my testbench all the counters do not work at all. They stay at 0. Here is the code for the counter:

process(CLK)
begin
if (CLK'event AND CLK='1') then
    if (RST='1') then
        cont_presc_spi_clk <=  "0000000000000";
    elsif (RST='0') then
        if presc_spi_cs = '1' then
            cont_presc_spi_clk <= cont_presc_spi_clk;
        elsif presc_spi_cs = '0' then
            if (cont_presc_spi_clk = "1001110000111") then 
                cont_presc_spi_clk <= "0000000000000";
            else
                cont_presc_spi_clk <= cont_presc_spi_clk + "0000000000001";
            end if;
        end if;
    end if;
end if;
end process;

Q_spi_clk <= cont_presc_spi_clk;
presc_spi_clk <= Not presc_spi_clk when (cont_presc_spi_clk = "1001110000111"); 

And here is the warning the programe gives: Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).

I've read multiple webs on the warning message but all the things they say about it are fine on my code. I have all the signals initialized in my testbench. Is there something wrong with my code or is it a common warning in modelsim and the code might work on a fpga?

  • Please provide a [MCVE](https://stackoverflow.com/help/minimal-reproducible-example). You do not show library and use clauses. The error shown is thrown from `numeric_std` library when arithmatic is performed on objects that have meta-values. Likely that `cont_presc_spi_clk` has meta values either from lack of initialisation or reset or it has multiple drivers. – Tricky Nov 30 '22 at 11:55

1 Answers1

0
presc_spi_clk <= Not presc_spi_clk when (cont_presc_spi_clk = "1001110000111"); 

This is a sequential statement that you are putting in a concurrent context. That will create problem, where as long as cont_presc_spi_clk = "1001110000111" presc_spi_clk will toggle voilently.

You want such statement inside the clocked part (in the if (CLK'event AND CLK='1') body).

(something like

process(CLK)
begin
if rising_edge(CLK) then
    if RST = '1' then
        cont_presc_spi_clk <=  "0000000000000";
    elsif presc_spi_cs = '0' then
        if (cont_presc_spi_clk = "1001110000111") then 
            cont_presc_spi_clk <= "0000000000000";
            presc_spi_clk <= not presc_spi_clk;
        else
            cont_presc_spi_clk <= cont_presc_spi_clk + "0000000000001";
        end if;
    end if;
end if;
end process;

I actually don't see where "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).", so that's in code you aren't showing. Maybe you are not assigning "0000000000000" to cont_presc_spi_clk on declaration? Same for presc_spi_clk?

p.s. I would just use integer for cont_presc_spi_clk. And count down to zero.

JHBonarius
  • 10,824
  • 3
  • 22
  • 41