Question

I'm not so great with VHDL and I can't really see why my code won't work. I needed an NCO, found a working program and re-worked it to fit my needs, but just noticed a bug: every full cycle there is one blank cycle.

The program takes step for argument (jump between next samples) and clock as trigger.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;  --try to use this library as much as possible.

entity sinwave_new_01 is
port (clk :in std_logic;
     step :in integer range 0 to 1000;
 dataout : out integer range 0 to 1024
 );
end sinwave_new_01;

architecture Behavioral of sinwave_new_01 is
signal i : integer range 0 to 1999:=0;
type memory_type is array (0 to 999) of integer range 0 to 1024; 
--ROM for storing the sine values generated by MATLAB.
signal sine : memory_type :=(long and boring array of 1000 samples here);

begin

process(clk)
begin
  --to check the rising edge of the clock signal
if(rising_edge(clk)) then     
dataout <= sine(i);
i <= i+ step;
if(i > 999) then
    i <= i-1000;
end if;
end if;
end process;

end Behavioral;

What do I do to get rid of that zero? It appears every full cycle - every (1000/step) pulses. It's not supposed to be there and it messes up my PWM... From what I understand the whole block (dataout changes, it is increased, and if i>999 then i<=i-1000) executes when there is a positive edge of clock applied on the entrance...

BUT it looks like it requires one additional edge to, I don't know, reload it? Does the code execute sequentially, or are all conditions tested when the clock arrives? Am I reaching outside the table, and that's why I'm getting zeroes in that particular pulse? Program /shouldn't/ do that, as far as I understand if statement, or is it VHDL being VHDL and doing its weird stuff again.

How do I fix this bug? Guess I could add one extra clock tick every 1k/step pulses, but that's a work around and not a real solution. Thanks in advance for help.

Was it helpful?

Solution

It looks like your problem is that your variable 'i' exceeds 999 before you reset it. Remember, you're in a sequential process. 'i' doesn't get the assigned value until the next clock tick AFTER you assign it.

I think if you change this code

i <= i + step;
if (i > 999) then
  i <= i-1000;

to

if ((i + step) > 999) then
  i <= (i + step) - 1000;
else
  i <= i + step;

you should get the behavior you're looking for.

OTHER TIPS

One more thing... Does the declaration of sine (sample array) actually creates combinatory circuit (bad) or allocates those samples in ROM memory ('good')?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top