如何用vhdl生成正弦波?

如何用vhdl生成正弦波?,vhdl,trigonometry,xilinx,hdl,Vhdl,Trigonometry,Xilinx,Hdl,我是vhdl的初学者,我试图生成频率为50MHz的正弦和方形信号,但首先我试图生成正弦波。我看过很多教程,但理解起来相当复杂。这是我写的代码。提前感谢您的帮助:) IEEE库; 使用IEEE.STD_LOGIC_1164.ALL; 使用IEEE.STD_LOGIC_UNSIGNED.ALL; 使用IEEE.STD_LOGIC_ARITH.ALL; 实体窦房结 端口(时钟:在标准逻辑中; 清除:在标准逻辑中; sel:标准逻辑向量(1到0); 数据输出:输出标准逻辑向量(7到0); 端窦; 窦的

我是vhdl的初学者,我试图生成频率为50MHz的正弦和方形信号,但首先我试图生成正弦波。我看过很多教程,但理解起来相当复杂。这是我写的代码。提前感谢您的帮助:)

IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.STD_LOGIC_UNSIGNED.ALL;
使用IEEE.STD_LOGIC_ARITH.ALL;
实体窦房结
端口(时钟:在标准逻辑中;
清除:在标准逻辑中;
sel:标准逻辑向量(1到0);
数据输出:输出标准逻辑向量(7到0);
端窦;
窦的结构是
信号输入数据:标准逻辑向量(数据输出范围);
信号i:整数范围0至77:=0;
类型mem_data是整数范围为-128到127的数组(0到255);
常数sin:mem_数据:=(
(   0),(   3),(   6),(   9),(  12),(  15),(  18),(  21),(  24),(  28),(  31),(  34),(  37),(  40),(  43),(  46),  (  48),(  51),(  54),(  57),(  60),(  63),(  65),(  68),(  71),(  73),(  76),(  78),(  81),(  83),(  85),(  88),  (  90),(  92),(  94),(  96),(  98),( 100),( 102),( 104),( 106),( 108),( 109),( 111),( 112),( 114),( 115),( 117),  ( 118),( 119),( 120),( 121),( 122),( 123),( 124),( 124),( 125),( 126),( 126),( 127),( 127),( 127),( 127),( 127),  ( 127),( 127),( 127),( 127),( 127),( 127),( 126),( 126),( 125),( 124),( 124),( 123),( 122),( 121),( 120),( 119),  ( 118),( 117),( 115),( 114),( 112),( 111),( 109),( 108),( 106),( 104),( 102),( 100),(  98),(  96),(  94),(  92),  (  90),(  88),(  85),(  83),(  81),(  78),(  76),(  73),(  71),(  68),(  65),(  63),(  60),(  57),(  54),(  51),  (  48),(  46),(  43),(  40),(  37),(  34),(  31),(  28),(  24),(  21),(  18),(  15),(  12),(   9),(   6),(   3),  (   0),(  -3),(  -6),(  -9),( -12),( -15),( -18),( -21),( -24),( -28),( -31),( -34),( -37),( -40),( -43),( -46),  ( -48),( -51),( -54),( -57),( -60),( -63),( -65),( -68),( -71),( -73),( -76),( -78),( -81),( -83),( -85),( -88),  ( -90),( -92),( -94),( -96),( -98),(-100),(-102),(-104),(-106),(-108),(-109),(-111),(-112),(-114),(-115),(-117),  (-118),(-119),(-120),(-121),(-122),(-123),(-124),(-124),(-125),(-126),(-126),(-127),(-127),(-127),(-127),(-127),  (-127),(-127),(-127),(-127),(-127),(-127),(-126),(-126),(-125),(-124),(-124),(-123),(-122),(-121),(-120),(-119),  (-118),(-117),(-115),(-114),(-112),(-111),(-109),(-108),(-106),(-104),(-102),(-100),( -98),( -96),( -94),( -92),  ( -90),( -88),( -85),( -83),( -81),( -78),( -76),( -73),( -71),( -68),( -65),( -63),( -60),( -57),( -54),( -51),  ( -48),( -46),( -43),( -40),( -37),( -34),( -31),( -28),( -24),( -21),( -18),( -15),( -12),(  -9),(  -6),(  -3)); 
开始
进程(clk,clear)开始
如果(clear='1'),则
in_数据“0”);
elsif(clk'事件和clk='1'),然后

由于VHDL是硬件描述语言,您应该问自己的问题是:我想实现什么?这个框图上的实体端口、内部信号在哪里

您面临的主要问题是,您的设计与插图之间没有真正的对应关系。此外,您的VHDL编码风格在VHDL语言本身以及如何实现方面都需要改进

从替换开始

use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

这是用于有符号和无符号类型的官方供应商不可知VHDL包。IEEE.STD_LOGIC_unsigned和STD_LOGIC_ARITH。所有这些都是过时的供应商依赖VHDL包,在供应商无法就通用定义达成一致的时候提供。这在使用不同供应商的工具进行设计流时导致了许多可移植性问题(Cadence,Mentor,Synopsys)。IEEE规范机构一次性解决了这个问题

如果您正在设计真正的硬件,以下代码可能会导致实现问题

process(clk, clear) begin
    if (clear='1') then
        in_data <= (others => '0');
    elsif (clk'event and clk='1') then
            in_data <= in_data +1; 
    end if;     
end process;

这里发生的事情会更加明显

你说你想产生一个50MHz的信号,但你没有说系统频率是多少(或者我应该反过来理解)。系统时钟频率/50MHz的比率将给出序列长度

无论如何,您需要声明一个自由运行的计数器作为信号,让我们称它为计数器(在您的原始代码中,您有两个信号,i和in_数据,用于相同的目的),并使用本地同步重置和时钟信号重置/增加它

如果是方形信号(假设sel='0'),输出将完全由计数器的值决定。低于给定的计数器值,您将有一个预定的数据输出值(“低”状态),而高于此值,您将有另一个预定的数据输出值(“高”状态)

对于正弦信号(假设sel='1'),计数器将表示相位,并将用作正弦查找表的输入(顺便说一句,您可以使用VHDL函数进行初始化,计算查找表内容,而不是提供预先计算的文字)。正弦查找表的输出是dataout输出


如果您需要更多帮助,请告诉我。

这不是一个真正的答案,但可能值得评论。当您有更多的声誉时,您可以发表评论。根据技术,异步清除不是问题。例如,所有Altera芯片都没有同步重置,只有异步重置。Xilinx还通过GSR提供异步清除。而
rising_edge(clk)
可能更可取,在大多数情况下,
clk'event和clk='1'
的工作原理完全相同(并推断出相同的硬件)。此外,虽然
std_logic_unsigned
可能不是标准,但它同样可以很好地编译并理想地适用于我所知道的所有工具。
numeric_std_unsigned
被添加到VHDL 2008中,其工作原理与此包几乎相同。有关同步与异步的内容,请参阅文档完整的白皮书WP272
use IEEE.NUMERIC_STD.ALL;
process(clk, clear) begin
    if (clear='1') then
        in_data <= (others => '0');
    elsif (clk'event and clk='1') then
            in_data <= in_data +1; 
    end if;     
end process;
if (p_reset_n = '0') then
    s_reset_on_clock <= (others => '1');
else if rising_edge(p_clock) then
         s_reset_on_clock <= '0' & s_reset_on_clock(3 downto 1);
     end if;
end if;
 elsif (clk'event and clk='1') then
 elsif rising_edge(clk) then