1. use Matlab to gen. a fix-point sin pcm code.
2. in verilog sim test bench. use $readmemh to put the pcm code to a Bus.
3. use waveform viewer to show the Bus data as "Analog".
From Cordic literature, it's obvious that the "more traditional" symmetrical form you're asking for would actually require an additional factor to achieve convergence.
See e.g.: CORDIC - Wikipedia, the free encyclopedia
It's not that obvious in my opinion, why the modification in the present algorithm achieves the required correction. But I assume, that the equivalence can be shown.
Another not obvious property of the fixed point implementation is, that it's apparently stable (with a small superimposed limit cycle) for different divider ratios, not only 8.
I finally found an explanation for the correction in the algorithm for generating the sine wave. This is a modified cordic algorithm called the "Goertzel Algorithm". For a good explanation, see paragraph 5 in the accompanying link.
**broken link removed**
Additional information on this algorithm can be found on wikipedia at
Can you provide a reference for your algorithm? It seems very stable, but I would like some mathematical verifaction to make me feel comfortable using it.
thank you for the code but m not getting the answer ..
for cos = 120 i got sine = 15 and for cos = 30 i got sine = 3 ..
so please clarify your answer..
i am waiting for your reply...
The operation principle of the code presented in post #5 has been explained by nand_gates and thoroughly discussed in this thread. If you don't get it, please refer to general CORDIC literature, e.g. https://en.wikipedia.org/wiki/CORDIC.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.sine_package.all;
entity sine_wave is
port( clock, reset, enable: in std_logic;
wave_out: out sine_vector_type);
end;
architecture arch1 of sine_wave is
type state_type is ( counting_up, change_down, counting_down, change_up );
signal state, next_state: state_type;
signal table_index: table_index_type;
signal positive_cycle: boolean;
begin
process( clock, reset )
begin
if reset = '1' then
state <= counting_up;
elsif rising_edge( clock ) then
if enable = '1' then
state <= next_state;
end if;
end if;
end process;
process( state, table_index )
begin
next_state <= state;
case state is
when counting_up =>
if table_index = max_table_index then
next_state <= change_down;
end if;
when change_down =>
next_state <= counting_down;
when counting_down =>
if table_index = 0 then
next_state <= change_up;
end if;
when others => -- change_up
next_state <= counting_up;
end case;
end process;
process( clock, reset )
begin
if reset = '1' then
table_index <= 0;
positive_cycle <= true;
elsif rising_edge( clock ) then
if enable = '1' then
case next_state is
when counting_up =>
table_index <= table_index + 1;
when counting_down =>
table_index <= table_index - 1;
when change_up =>
positive_cycle <= not positive_cycle;
when others =>
-- nothing to do
end case;
end if;
end if;
end process;
process( table_index, positive_cycle )
variable table_value: table_value_type;
begin
table_value := get_table_value( table_index );
if positive_cycle then
wave_out <= std_logic_vector(to_signed(table_value,sine_vector_type'length));
else
wave_out <= std_logic_vector(to_signed(-table_value,sine_vector_type'length));
end if;
end process;