2014-12-22 43 views
0

我正在做一个音乐盒与VHDL。我第一次玩A4,而且我很成功。For循环和rom在vhdl

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.NUMERIC_STD.ALL; 


library UNISIM; 

use UNISIM.VComponents.all; 


entity Basic is 

    Port( clk : in STD_LOGIC; 
     note : out STD_LOGIC; 
     ); 
end Basic; 

architecture Behavioral of Basic is 

    signal count : unsigned (15 downto 0) := (others => '0'); 
begin 

    note <= std_logic(count(15)); 
    process (clk) 
    begin 
     if rising_edge(clk) then 
      if (count=56817) then 
       count <= "0000000000000000"; 
      else 
       count <= count + 1; 
      end if; 
      end if; 
    end process; 
end Behavioral; 

我未完成的代码是这样的

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 

library UNISIM; 
use UNISIM.VComponents.all; 

entity Basic is 

    Port( clk : in STD_LOGIC; 
      note : out STD_LOGIC; 
      address: in integer range 0 to 31 
     ); 
end Basic; 

architecture Behavioral of Basic is 

    signal count : unsigned (15 downto 0) := (others => '0'); 
    signal reg_address : integer range 0 to 31 ; 
    type rom_array is array (0 to 31) of integer (4 downto 0); 
    constant rom: rom_array := ( "11011", "11011", 
        "11011", "11011","11011", "11011", 
        "11011", "11011", "11011", "11011", 
        "11011", "11011","11011", "11011", 
        "11011", "11011","11011", "11011", 
        "11011", "11011","11011", "11011", 
        "11011", "11011","11011", "11011", 
        "11011", "11011","11011", "11011", 
        "11011", "11011"); 
begin 

    note <= std_logic(count(15)); 
    process (clk) 
    begin 
      if rising_edge(clk) then 
       reg_address <= address; 
       if (reg_address < 32) then 
        if (count = rom(reg_address)) then 
         count <= "0000000000000000"; 
        else 
         count <= count + 1; 
        end if; 
       else 
        reg_address <= "00000"; 
       end if; 
      end if; 
      reg_address <= reg_address + 1; 
    end process; 
end Behavioral; 

的ROM值要改变。 我试图通过分时钟来产生声音。就像25mhz/56818 = 440一样。要想播放一首歌曲,我想创建一个充满数字的ROM来划分时钟,然后做一个for循环播放歌曲。但我不能因为循环不类似于java/C所以我想我需要绕过它。

我的错误是:

ERROR:HDLParsers:526 - "C:/Users/user/DigitalProje/Basic.vhd" Line 18. Non array type integer can not have a index constraint.

ERROR:HDLParsers:3312 - "C:/Users/user/DigitalProje/Basic.vhd" Line 19. Undefined symbol 'rom_array'.

ERROR:HDLParsers:1209 - "C:/Users/user/DigitalProje/Basic.vhd" Line 19. rom_array: Undefined symbol (last report in this block)

ERROR:HDLParsers:3285 - "C:/Users/user/DigitalProje/Basic.vhd" Line 19. No array or record type can be found that has elements of types matching the aggregate.

ERROR:HDLParsers:532 - "C:/Users/user/DigitalProje/Basic.vhd" Line 19. Deferred constant are allowed only in packages.

ERROR:HDLParsers:808 - "C:/Users/user/DigitalProje/Basic.vhd" Line 35. = can not have such operands in this context.

ERROR:HDLParsers:800 - "C:/Users/user/DigitalProje/Basic.vhd" Line 41. Type of reg_address is incompatible with type of 00000.

+0

熊,如果你迭代尽管每个一旦前一个完成,你只会在每个频率上产生一个单独的转换。为了按顺序播放“音符”,您需要基于(慢得多)稳定的时钟遍历音符列表,以便能够听到每个不同的音调。您也无法使用此方法覆盖色调。这就是为什么音乐音频文件(未压缩时)每秒存储24,000次以上的幅度测量结果以复制可能由许多单独音调组成的实际波形。 – QuantumRipple

+0

对不起,打扰你进一步,但我是一个初学者,我不知道如何使用嵌入式以外的时钟。你能详细说明吗? – Strider

+0

有几种方法可以从现有时钟生成较慢的时钟。大多数FPGA都有专用的时钟操作模块,可以通过各种方式对时钟进行倍增或分频,但您也可以像使用音频发生器一样使用计数器生成分频时钟。当计数器翻转而不是实际的单独时钟时,我可能会在25MHz(主时钟)域上进行处理,以增加笔记ROM的地址。这使用时钟启用来获得所需的减速而不必处理多个时钟域。 – QuantumRipple

回答

0

VHDL是强类型语言,所以你必须严格要求的类型。

两个问题,rom_arrayinteger型的元件,但它看起来像的意图可能已经使用基于恒定分配到rom无符号(或另一种载体类型);所以也许这样做:

type rom_array is array (0 to 31) of unsigned (4 downto 0); 

reg_address是整数,因此不能用绳子像reg_address <= "00000";分配,所以认为这更改为:记

reg_address <= 0; 
+0

但是当我这样做时,我不能添加数字像56000 65000到数组 – Strider

+0

其实你可以,你只需要将它们转换为无符号('to_unsigned(整数,宽度)'),并使用足够宽的无符号来处理您想要使用的最大值。 – QuantumRipple