diff --git a/SOUND/OPLL/VM2413/attacktable.vhd b/SOUND/OPLL/VM2413/attacktable.vhd new file mode 100644 index 0000000..e144caf --- /dev/null +++ b/SOUND/OPLL/VM2413/attacktable.vhd @@ -0,0 +1,159 @@ +-- +-- AttackTable.vhd +-- Envelope attack shaping table for VM2413 +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- + +-- +-- modified by t.hara +-- + +------------------------------------------------------------------------------- +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_signed.all; + +entity attack_table_mul is + port( + i0 : in std_logic_vector( 7 downto 0 ); -- 符号無し 8bit (整数部 0bit, 小数部 8bit) + i1 : in std_logic_vector( 7 downto 0 ); -- 符号付き 8bit (整数部 8bit) + o : out std_logic_vector( 13 downto 0 ) -- 符号付き14bit (整数部 8bit, 小数部 6bit) + ); +end attack_table_mul; + +architecture rtl of attack_table_mul is + signal w_mul : std_logic_vector( 16 downto 0 ); +begin + + w_mul <= ('0' & i0) * i1; + o <= w_mul( 15 downto 2 ); -- bit16 は bit15 と同じなのでカット。bit1〜0 (小数部) は切り捨て。 +end rtl; + +------------------------------------------------------------------------------- +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + use ieee.std_logic_arith; + +entity AttackTable is + port( + clk : in std_logic; + clkena : in std_logic; + addr : in std_logic_vector( 21 downto 0 ); -- 小数部 15bit + data : out std_logic_vector( 12 downto 0 ) -- 小数部 6bit + ); +end AttackTable; + +architecture rtl of attacktable is + + component attack_table_mul + port( + i0 : in std_logic_vector( 7 downto 0 ); -- 符号無し 8bit (整数部 0bit, 小数部 8bit) + i1 : in std_logic_vector( 7 downto 0 ); -- 符号付き 8bit (整数部 8bit) + o : out std_logic_vector( 13 downto 0 ) -- 符号付き 8bit (整数部 8bit, 小数部 6bit) + ); + end component; + + type ar_adjust_array is array ( 0 to 127 ) of std_logic_vector( 6 downto 0 ); + constant ar_adjust : ar_adjust_array :=( + "0000000", "0000000", "0000000", "0000000", "0000000", "0000001", "0000001", "0000001", + "0000001", "0000001", "0000010", "0000010", "0000010", "0000010", "0000011", "0000011", + "0000011", "0000011", "0000100", "0000100", "0000100", "0000100", "0000100", "0000101", + "0000101", "0000101", "0000110", "0000110", "0000110", "0000110", "0000111", "0000111", + "0000111", "0000111", "0001000", "0001000", "0001000", "0001001", "0001001", "0001001", + "0001001", "0001010", "0001010", "0001010", "0001011", "0001011", "0001011", "0001100", + "0001100", "0001100", "0001101", "0001101", "0001101", "0001110", "0001110", "0001110", + "0001111", "0001111", "0001111", "0010000", "0010000", "0010001", "0010001", "0010001", + "0010010", "0010010", "0010011", "0010011", "0010100", "0010100", "0010101", "0010101", + "0010101", "0010110", "0010110", "0010111", "0010111", "0011000", "0011000", "0011001", + "0011010", "0011010", "0011011", "0011011", "0011100", "0011101", "0011101", "0011110", + "0011110", "0011111", "0100000", "0100001", "0100001", "0100010", "0100011", "0100100", + "0100100", "0100101", "0100110", "0100111", "0101000", "0101001", "0101010", "0101011", + "0101100", "0101101", "0101111", "0110000", "0110001", "0110011", "0110100", "0110110", + "0111000", "0111001", "0111011", "0111101", "1000000", "1000010", "1000101", "1001000", + "1001011", "1010000", "1010100", "1011010", "1100010", "1101100", "1110101", "1111111" + ); + + signal ff_w : std_logic_vector( 7 downto 0 ); + signal ff_d1 : std_logic_vector( 6 downto 0 ); + signal ff_d2 : std_logic_vector( 6 downto 0 ); + + signal w_addr1 : std_logic_vector( 6 downto 0 ); + signal w_addr2 : std_logic_vector( 6 downto 0 ); + signal w_sub : std_logic_vector( 7 downto 0 ); -- 符号付き + signal w_mul : std_logic_vector( 13 downto 0 ); -- 符号付き + signal w_inter : std_logic_vector( 13 downto 0 ); +begin + + w_addr1 <= addr( 21 downto 15 ); + w_addr2 <= (others => '1') when( addr( 21 downto 15 ) = "1111111" )else + w_addr1 + 1; + + process( clk ) + begin + if( clk'event and clk = '1' )then + if( clkena = '1' )then + ff_d1 <= ar_adjust( conv_integer( w_addr1 ) ); + ff_d2 <= ar_adjust( conv_integer( w_addr2 ) ); + end if; + end if; + end process; + + process( clk ) + begin + if( clk'event and clk = '1' )then + if( clkena = '1' )then + ff_w <= addr( 14 downto 7 ); -- データ自体のビット数が 7bit なので 8bit で十分 + end if; + end if; + end process; + + -- 補間 (※符号をまたがる場所では 0 になるから ff_sign は気にしない) + -- o = i1 * (1 - k) + i2 * w = i1 - w * i1 + w * i2 = i1 + w * (i2 - i1) + w_sub <= ('0' & ff_d2) - ('0' & ff_d1); + + u_attack_table_mul: attack_table_mul + port map ( + i0 => ff_w, + i1 => w_sub, + o => w_mul + ); + + w_inter <= ('0' & ff_d1 & "000000") + w_mul; + + process( clk ) + begin + if( clk'event and clk = '1' )then + if( clkena = '1' )then + data <=w_inter( 12 downto 0 ); -- MSB は必ず 0 + end if; + end if; + end process; + +end rtl; diff --git a/SOUND/OPLL/VM2413/controller.vhd b/SOUND/OPLL/VM2413/controller.vhd new file mode 100644 index 0000000..13cc92d --- /dev/null +++ b/SOUND/OPLL/VM2413/controller.vhd @@ -0,0 +1,513 @@ +-- +-- Controller.vhd +-- The core controller module of VM2413 +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- +-- [Description] +-- +-- The Controller is the beginning module of the OPLL slot calculation. +-- It manages register accesses from I/O and sends proper voice parameters +-- to the succeding PhaseGenerator and EnvelopeGenerator modules. +-- The one cycle of the Controller consists of 4 stages as follows. +-- +-- 1st stage: +-- * Prepare to read the register value for the current slot from RegisterMemory. +-- * Prepare to read the voice parameter for the current slot from VoiceMemory. +-- * Prepare to read the user-voice data from VoiceMemory. +-- +-- 2nd stage: +-- * Wait for RegisterMemory and VoiceMemory +-- +-- 3rd clock stage: +-- * Update register value if wr='1' and addr points the current OPLL channel. +-- * Update voice parameter if wr='1' and addr points the voice parameter area. +-- * Write register value to RegisterMemory. +-- * Write voice parameter to VoiceMemory. +-- +-- 4th stage: +-- * Send voice and register parameters to PhaseGenerator and EnvelopeGenerator. +-- * Increment the number of the current slot. +-- +-- Each stage is completed in one clock. Thus the Controller traverses all 18 opll +-- slots in 72 clocks. +-- + +-- +-- modified by t.hara +-- + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + use work.vm2413.all; + +entity controller is port ( + + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : in std_logic_vector( 4 downto 0 ); + stage : in std_logic_vector( 1 downto 0 ); + + wr : in std_logic; + addr : in std_logic_vector( 7 downto 0 ); + data : in std_logic_vector( 7 downto 0 ); + + -- output parameters for phasegenerator and envelopegenerator + am : out am_type; + pm : out pm_type; + wf : out wf_type; + ml : out ml_type; + tl : out db_type; + fb : out fb_type; + ar : out ar_type; + dr : out dr_type; + sl : out sl_type; + rr : out rr_type; + + blk : out blk_type; + fnum : out fnum_type; + rks : out rks_type; + + key : out std_logic; + rhythm : out std_logic + + -- slot_out : out slot_id +); +end controller; + +architecture rtl of controller is + + component registermemory + port ( + clk : in std_logic; + reset : in std_logic; + addr : in std_logic_vector( 3 downto 0 ); + wr : in std_logic; + idata : in std_logic_vector( 23 downto 0 ); + odata : out std_logic_vector( 23 downto 0 ) + ); + end component; + + component voicememory port ( + clk : in std_logic; + reset : in std_logic; + idata : in voice_type; + wr : in std_logic; + rwaddr : in voice_id_type; + roaddr : in voice_id_type; + odata : out voice_type; + rodata : out voice_type ); + end component; + + -- the array which caches instrument number of each channel. + type inst_array is array (ch_type'range) of integer range 0 to 15; + signal inst_cache : inst_array; + + type kl_array is array (0 to 15) of std_logic_vector(5 downto 0); + constant kl_table : kl_array := ( + "000000", "011000", "100000", "100101", + "101000", "101011", "101101", "101111", + "110000", "110010", "110011", "110100", + "110101", "110110", "110111", "111000" + ); -- 0.75db/step, 6db/oct + + -- signals for the read-only access ports of voicememory module. + signal slot_voice_addr : voice_id_type; + signal slot_voice_data : voice_type; + + -- signals for the read-write access ports of voicememory module. + signal user_voice_wr : std_logic; + signal user_voice_addr : voice_id_type; + signal user_voice_rdata : voice_type; + signal user_voice_wdata : voice_type; + + -- signals for the registermemory module. + signal regs_wr : std_logic; + signal regs_addr : std_logic_vector( 3 downto 0 ); + signal regs_rdata : std_logic_vector( 23 downto 0 ); + signal regs_wdata : std_logic_vector( 23 downto 0 ); + + signal rflag : std_logic_vector( 7 downto 0 ); + signal w_channel : std_logic_vector( 3 downto 0 ); +-- signal w_is_carrier : std_logic; + +begin -- rtl + + -- レジスタ設定値を保持するためのメモリ + u_register_memory : RegisterMemory + port map ( + clk => clk, + reset => reset, + addr => regs_addr, + wr => regs_wr, + idata => regs_wdata, + odata => regs_rdata + ); + + vmem : voicememory port map ( + clk, reset, user_voice_wdata, user_voice_wr, user_voice_addr, slot_voice_addr, + user_voice_rdata, slot_voice_data ); + + -- レジスタアドレスラッチ (第1ステージ) + process( reset, clk ) + begin + if( reset = '1' )then + regs_addr <= (others => '0'); + elsif( clk'event and clk = '1' )then + if clkena='1' then + if( stage = "00" )then + regs_addr <= slot( 4 downto 1 ); + else + -- hold + end if; + end if; + end if; + end process; + + -- 現在のスロットの音色データ読み出しアドレスラッチ (第1ステージ) + process( reset, clk ) + begin + if( reset = '1' )then + slot_voice_addr <= 0; + elsif( clk'event and clk = '1' )then + if clkena='1' then + if( stage = "00" )then + if( rflag(5) = '1' and w_channel >= "0110" )then + -- リズムモードで ch6 以降 + slot_voice_addr <= conv_integer(slot) - 12 + 32; + else + slot_voice_addr <= inst_cache(conv_integer(slot)/2) * 2 + conv_integer(slot) mod 2; + end if; + else + -- hold + end if; + end if; + end if; + end process; + + w_channel <= slot( 4 downto 1 ); +-- w_is_carrier <= slot( 0 ); + + process (clk, reset) + + variable kflag : std_logic; + variable tll : std_logic_vector(db_type'high+1 downto 0); + variable kll : std_logic_vector(db_type'high+1 downto 0); + + variable regs_tmp : std_logic_vector(23 downto 0); + variable user_voice_tmp : voice_type; + + variable fb_buf : fb_type; + variable wf_buf : wf_type; + + variable extra_mode : std_logic; + variable vindex : voice_id_type; + + begin -- process + + if(reset = '1') then + + key <= '0'; + rhythm <= '0'; + tll := (others=>'0'); + kll := (others=>'0'); + kflag := '0'; + rflag <= (others=>'0'); + user_voice_wr <= '0'; + user_voice_addr <= 0; + regs_wr <='0'; + ar <= (others=>'0'); + dr <= (others=>'0'); + sl <= (others=>'0'); + rr <= (others=>'0'); + tl <= (others=>'0'); + fb <= (others=>'0'); + wf <= '0'; + ml <= (others=>'0'); + fnum <= (others=>'0'); + blk <= (others=>'0'); + key <= '0'; + rks <= (others=>'0'); + rhythm <= '0'; + extra_mode := '0'; + vindex := 0; + + elsif clk'event and clk='1' then if clkena='1' then + + case stage is + -------------------------------------------------------------------------- + -- 1st stage (setting up a read request for register and voice memories.) + -------------------------------------------------------------------------- + when "00" => + +-- if extra_mode = '0' then + -- alternately read modulator or carrior. + vindex := conv_integer(slot) mod 2; +-- else +-- if vindex = voice_id_type'high then +-- vindex:= 0; +-- else +-- vindex:= vindex + 1; +-- end if; +-- end if; + + user_voice_addr <= vindex; + regs_wr <= '0'; + user_voice_wr <='0'; + + -------------------------------------------------------------------------- + -- 2nd stage (just a wait for register and voice memories.) + -------------------------------------------------------------------------- + when "01" => + null; + + -------------------------------------------------------------------------- + -- 3rd stage (updating a register and voice parameters.) + -------------------------------------------------------------------------- + when "10" => + + if wr='1' then + +-- if ( extra_mode = '0' and conv_integer(addr) < 8 ) or +-- ( extra_mode = '1' and ( conv_integer(addr) - 64 ) / 8 = vindex / 2 ) then + if( extra_mode = '0' and conv_integer(addr) < 8 )then + + -- update user voice parameter. + user_voice_tmp := user_voice_rdata; + + case addr(2 downto 1) is + when "00" => + if conv_integer(addr(0 downto 0)) = (vindex mod 2) then + user_voice_tmp.am := data(7); + user_voice_tmp.pm := data(6); + user_voice_tmp.eg := data(5); + user_voice_tmp.kr := data(4); + user_voice_tmp.ml := data(3 downto 0); + user_voice_wr <= '1'; + end if; + + when "01" => + if addr(0)='0' and (vindex mod 2 = 0) then + user_voice_tmp.kl := data(7 downto 6); + user_voice_tmp.tl := data(5 downto 0); + user_voice_wr <= '1'; + elsif addr(0)='1' and (vindex mod 2 = 0) then + user_voice_tmp.wf := data(3); + user_voice_tmp.fb := data(2 downto 0); + user_voice_wr <= '1'; + elsif addr(0)='1' and (vindex mod 2 = 1) then + user_voice_tmp.kl := data(7 downto 6); + user_voice_tmp.wf := data(4); + user_voice_wr <= '1'; + end if; + + when "10" => + if conv_integer(addr(0 downto 0)) = (vindex mod 2) then + user_voice_tmp.ar := data(7 downto 4); + user_voice_tmp.dr := data(3 downto 0); + user_voice_wr <= '1'; + end if; + + when "11" => + if conv_integer(addr(0 downto 0)) = (vindex mod 2) then + user_voice_tmp.sl := data(7 downto 4); + user_voice_tmp.rr := data(3 downto 0); + user_voice_wr <= '1'; + end if; + end case; + + user_voice_wdata <= user_voice_tmp; + + elsif conv_integer(addr) = 14 then + + rflag <= data; + + elsif conv_integer(addr) < 16 then + + null; + + elsif conv_integer(addr) <= 63 then + + if( conv_integer(addr(3 downto 0) ) = conv_integer(slot) / 2 ) then + regs_tmp := regs_rdata; + case addr( 5 downto 4 ) is + when "01" => -- 10h〜18h の場合(下位 F-Number) + regs_tmp(7 downto 0) := data; -- F-Number + regs_wr <= '1'; + when "10" => -- 20h〜28h の場合(Sus, Key, Block, F-Number MSB) + regs_tmp(13) := data(5); -- Sus + regs_tmp(12) := data(4); -- Key + regs_tmp(11 downto 9) := data(3 downto 1); -- Block + regs_tmp(8) := data(0); -- F-Number + regs_wr <= '1'; + when "11" => -- 30h〜38h の場合(Inst, Vol) + regs_tmp(23 downto 20) := data(7 downto 4); -- Inst + regs_tmp(19 downto 16) := data(3 downto 0); -- Vol + regs_wr <='1'; + when others => + null; + end case; + regs_wdata <= regs_tmp; + end if; + + elsif conv_integer(addr) = 240 then + + if data(7 downto 0) = "10000000" then + extra_mode := '1'; + else + extra_mode := '0'; + end if; + + end if; + + end if; + + -------------------------------------------------------------------------- + -- 4th stage (updating a register and voice parameters.) + -------------------------------------------------------------------------- + when "11" => + + -- output slot number (for explicit synchonization with other units). + -- slot_out <= slot; + + -- updating insturument cache + inst_cache(conv_integer(slot)/2) <= conv_integer(regs_rdata(23 downto 20)); + + rhythm <= rflag(5); + + -- updating rhythm status and key flag + if rflag(5) = '1' and 12 <= slot then + case slot is + when "01100" | "01101" => -- bd + kflag := rflag(4); + when "01110" => -- hh + kflag := rflag(0); + when "01111" => -- sd + kflag := rflag(3); + when "10000" => -- tom + kflag := rflag(2); + when "10001" => -- cym + kflag := rflag(1); + when others => null; + end case; + else + kflag := '0'; + end if; + + kflag := kflag or regs_rdata(12); + + -- calculate key-scale attenuation amount. + kll := (("0"&kl_table(conv_integer(regs_rdata(8 downto 5)))) + - ("0"&("111"-regs_rdata(11 downto 9))&"000")) & '0'; + + if kll(kll'high) ='1' or slot_voice_data.kl = "00" then + kll := (others=>'0'); + else + kll := shr(kll, "11" - slot_voice_data.kl ); + end if; + + -- calculate base total level from volume register value. + if rflag(5) = '1' and (slot = "01110" or slot = "10000") then -- hh and cym + tll := ('0' & regs_rdata(23 downto 20) & "000"); + elsif( slot(0) = '0' )then + tll := ('0' & slot_voice_data.tl & '0'); -- mod + else + tll := ('0' & regs_rdata(19 downto 16) & "000"); -- car + end if; + + tll := tll + kll; + + if tll(tll'high) ='1' then + tl <= (others=>'1'); + else + tl <= tll(tl'range); + end if; + + -- output rks, f-number, block and key-status. + fnum <= regs_rdata(8 downto 0); + blk <= regs_rdata(11 downto 9); + key <= kflag; + + if rflag(5) = '1' and 14 <= slot then + if slot_voice_data.kr = '1' then + rks <= "0101"; + else + rks <= "00" & regs_rdata(11 downto 10); + end if; + else + if slot_voice_data.kr = '1' then + rks <= regs_rdata(11 downto 9) & regs_rdata(8); + else + rks <= "00" & regs_rdata(11 downto 10); + end if; + end if; + + -- output voice parameters + -- note that wf and fb output must keep its value + -- at least 3 clocks since the operator module will fetch + -- the wf and fb 2 clocks later of this stage. + am <= slot_voice_data.am; + pm <= slot_voice_data.pm; + ml <= slot_voice_data.ml; + wf_buf := slot_voice_data.wf; + fb_buf := slot_voice_data.fb; + wf <= wf_buf; + fb <= fb_buf; + ar <= slot_voice_data.ar; + dr <= slot_voice_data.dr; + sl <= slot_voice_data.sl; + + -- output release rate (depends on the sustine and envelope type). + if( kflag = '1' ) then -- key on + if slot_voice_data.eg = '1' then + rr <= "0000"; + else + rr <= slot_voice_data.rr; + end if; + else -- key off + if (slot(0) = '0') and not ( rflag(5) = '1' and (7 <= conv_integer(slot)/2) ) then + rr <= "0000"; + elsif regs_rdata(13) = '1' then + rr <= "0101"; + elsif slot_voice_data.eg = '0' then + rr <= "0111"; + else + rr <= slot_voice_data.rr; + end if; + end if; + + end case; + + end if; end if; + + end process; + +end rtl; diff --git a/SOUND/OPLL/VM2413/envelopegenerator.vhd b/SOUND/OPLL/VM2413/envelopegenerator.vhd new file mode 100644 index 0000000..dfc2785 --- /dev/null +++ b/SOUND/OPLL/VM2413/envelopegenerator.vhd @@ -0,0 +1,280 @@ +-- +-- EnvelopeGenerator.vhd +-- The envelope generator module of VM2413 +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- + +-- +-- modified by t.hara +-- + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + use work.vm2413.all; + +entity envelopegenerator is + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : in slot_type; + stage : in stage_type; + rhythm : in std_logic; + + am : in am_type; + tl : in db_type; + ar : in ar_type; + dr : in dr_type; + sl : in sl_type; + rr : in rr_type; + rks : in rks_type; + key : in std_logic; + + egout : out std_logic_vector( 12 downto 0 ) -- 小数部 6bit + ); +end envelopegenerator; + +architecture rtl of envelopegenerator is + + component EnvelopeMemory + port ( + clk : in std_logic; + reset : in std_logic; + + waddr : in slot_type; + wr : in std_logic; + wdata : in egdata_type; + raddr : in slot_type; + rdata : out egdata_type + ); + end component; + + component AttackTable + port( + clk : in std_logic; + clkena : in std_logic; + addr : in std_logic_vector( 21 downto 0 ); -- 小数部 15bit + data : out std_logic_vector( 12 downto 0 ) + ); + end component; + + signal rslot : slot_type; + signal memin : egdata_type; + signal memout : egdata_type; + signal memwr : std_logic; + + signal aridx : std_logic_vector( 21 downto 0 ); + signal ardata : std_logic_vector( 12 downto 0 ); -- 小数部 6bit +begin + + -- Attack テーブル + u_attack_table: AttackTable + port map ( + clk => clk, + clkena => clkena, + addr => aridx, + data => ardata + ); + + u_envelope_memory: EnvelopeMemory + port map ( + clk => clk, + reset => reset, + waddr => slot, + wr => memwr, + wdata => memin, + raddr => rslot, + rdata => memout + ); + + -- EnvelopeMemory のプリフェッチ + process( reset, clk ) + begin + if( reset = '1' )then + rslot <= (others => '0'); + elsif( clk'event and clk='1' )then + if( clkena = '1' )then + if( stage = "10" )then + if( slot = "10001" )then + rslot <= (others => '0'); + else + rslot <= slot + 1; + end if; + end if; + end if; + end if; + end process; + + process( reset, clk ) + variable lastkey : std_logic_vector(18-1 downto 0); + variable rm : std_logic_vector(4 downto 0); + variable egtmp : std_logic_vector(db_type'high + 8 downto 0); -- 小数部 6bit + variable amphase : std_logic_vector(19 downto 0); + variable egphase : egphase_type; + variable egstate : egstate_type; + variable dphase : egphase_type; + variable ntable : std_logic_vector(17 downto 0); + begin + if( reset = '1' )then + rm := (others=>'0'); + lastkey := (others=>'0'); + memwr <= '0'; + egstate := Finish; + egphase := (others=>'0'); + ntable := (others => '1'); + amphase(amphase'high downto amphase'high-4) := "00001"; + amphase(amphase'high-5 downto 0) := (others=>'0'); + + elsif( clk'event and clk='1' )then + + aridx <= egphase( 22-1 downto 0 ); + + if( clkena = '1' )then + + ntable( 17 downto 1 ) := ntable( 16 downto 0 ); + ntable( 0 ) := ntable( 17 ) xor ntable( 14 ); + + -- Amplitude oscillator ( -4.8dB to 0dB , 3.7Hz ) + amphase := amphase + '1'; + if amphase(amphase'high downto amphase'high-4) = "11111" then + amphase(amphase'high downto amphase'high-4) := "00001"; + end if; + + if stage = 0 then + egstate := memout.state; + egphase := memout.phase; + + elsif stage = 1 then + -- Wait for AttackTable + + elsif stage = 2 then + case egstate is + when Attack => + rm := '0'&ar; + egtmp := ("00"&tl&"000000") + ("00"&ardata); -- カーブを描いて上昇する + when Decay => + rm := '0'&dr; + egtmp := ("00"&tl&"000000") + ("00"&egphase(22-1 downto 22-7-6)); + when Release=> + rm := '0'&rr; + egtmp := ("00"&tl&"000000") + ("00"&egphase(22-1 downto 22-7-6)); + when Finish => + egtmp(egtmp'high downto egtmp'high -1) := "00"; + egtmp(egtmp'high-2 downto 0) := (others=>'1'); + end case; + + -- SD and HH + if ntable(0)='1' and conv_integer(slot)/2 = 7 and rhythm = '1' then + egtmp := egtmp + "010000000000000"; + end if; + + -- Amplitude LFO + if am ='1' then + if (amphase(amphase'high) = '0') then + -- 上りの場合 + egtmp := egtmp + ("00000"&(amphase(amphase'high-1 downto amphase'high-4-6)-'1')); + else + -- 下りの場合 + egtmp := egtmp + ("00000"&("1111"-amphase(amphase'high-1 downto amphase'high-4-6))); + end if; + end if; + + -- Generate output + if egtmp(egtmp'high downto egtmp'high-1) = "00" then -- リミッタ + egout <= egtmp(egout'range); + else + egout <= (others=>'1'); + end if; + + if rm /= "00000" then + + rm := rm + rks(3 downto 2); + if rm(rm'high)='1' then + rm(3 downto 0):="1111"; + end if; + + case egstate is + when Attack => + dphase(dphase'high downto 5) := (others=>'0'); + dphase(5 downto 0) := "110" * ('1'&rks(1 downto 0)); + dphase := SHL( dphase, rm(3 downto 0) ); + egphase := egphase - dphase(egphase'range); + when Decay | Release => + dphase(dphase'high downto 3) := (others=>'0'); + dphase(2 downto 0) := '1'&rks(1 downto 0); + dphase := SHL(dphase, rm(3 downto 0) - '1'); + egphase := egphase + dphase(egphase'range); + when Finish => + null; + end case; + + end if; + + case egstate is + when Attack => + if egphase(egphase'high) = '1' then + egphase := (others=>'0'); + egstate := Decay; + end if; + when Decay => + if egphase(egphase'high downto egphase'high-4) >= '0'&sl then + egstate := Release; + end if; + when Release => + if( egphase(egphase'high downto egphase'high-4) >= "01111" ) then + egstate:= Finish; + end if; + when Finish => + egphase := (others => '1'); + end case; + + if lastkey(conv_integer(slot)) = '0' and key = '1' then + egphase(egphase'high):= '0'; + egphase(egphase'high-1 downto 0) := (others =>'1'); + egstate:= Attack; + elsif lastkey(conv_integer(slot)) = '1' and key = '0' and egstate /= Finish then + egstate:= Release; + end if; + lastkey(conv_integer(slot)) := key; + + -- update phase and state memory + memin <= ( state => egstate, phase => egphase ); + memwr <='1'; + elsif stage = 3 then + -- wait for phase memory + memwr <='0'; + end if; + end if; + end if; + end process; + +end rtl; + diff --git a/SOUND/OPLL/VM2413/envelopememory.vhd b/SOUND/OPLL/VM2413/envelopememory.vhd new file mode 100644 index 0000000..0ccf673 --- /dev/null +++ b/SOUND/OPLL/VM2413/envelopememory.vhd @@ -0,0 +1,79 @@ +-- +-- EnvelopeMemory.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use WORK.VM2413.ALL; + +entity EnvelopeMemory is port ( + clk : in std_logic; + reset : in std_logic; + + waddr : in SLOT_TYPE; + wr : in std_logic; + wdata : in EGDATA_TYPE; + raddr : in SLOT_TYPE; + rdata : out EGDATA_TYPE + ); +end EnvelopeMemory; + +architecture RTL of EnvelopeMemory is + + type EGDATA_ARRAY is array (0 to 18-1) of EGDATA_VECTOR_TYPE; + signal egdata_set : EGDATA_ARRAY; + +begin + + process (clk, reset) + + variable init_slot : integer range 0 to 18; + + begin + + if reset = '1' then + + init_slot := 0; + + elsif clk'event and clk = '1' then + + if init_slot /= 18 then + egdata_set(init_slot) <= (others=>'1'); + init_slot := init_slot + 1; + elsif wr = '1' then + egdata_set(conv_integer(waddr)) <= CONV_EGDATA_VECTOR(wdata); + end if; + rdata <= CONV_EGDATA(egdata_set(conv_integer(raddr))); + + end if; + +end process; + +end RTL; diff --git a/SOUND/OPLL/VM2413/feedbackmemory.vhd b/SOUND/OPLL/VM2413/feedbackmemory.vhd new file mode 100644 index 0000000..b81260d --- /dev/null +++ b/SOUND/OPLL/VM2413/feedbackmemory.vhd @@ -0,0 +1,88 @@ +-- +-- FeedbackMemory.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use WORK.VM2413.ALL; + +-- +-- This module represents a store for feedback data of all OPLL channels. The feedback +-- data is written by the OutputGenerator module. Then the value written is +-- read from the Operator module. +-- +entity FeedbackMemory is port ( + clk : in std_logic; + reset : in std_logic; + wr : in std_logic; + waddr : in CH_TYPE; + wdata : in SIGNED_LI_TYPE; + raddr : in CH_TYPE; + rdata : out SIGNED_LI_TYPE +); +end FeedbackMemory; + +architecture RTL of FeedbackMemory is + + type SIGNED_LI_ARRAY_TYPE is array (0 to 9-1) of SIGNED_LI_VECTOR_TYPE; + signal data_array : SIGNED_LI_ARRAY_TYPE; + +begin + + process(clk, reset) + + variable init_ch : integer range 0 to 9; + + begin + + if reset = '1' then + + init_ch := 0; + + elsif clk'event and clk='1' then + + if init_ch /= 9 then + + data_array(init_ch) <= (others=>'0'); + init_ch := init_ch + 1; + + elsif wr='1' then + + data_array(waddr) <= CONV_SIGNED_LI_VECTOR(wdata); + + end if; + + rdata <= CONV_SIGNED_LI(data_array(raddr)); + + end if; + + end process; + +end RTL; \ No newline at end of file diff --git a/SOUND/OPLL/VM2413/lineartable.vhd b/SOUND/OPLL/VM2413/lineartable.vhd new file mode 100644 index 0000000..4fc1273 --- /dev/null +++ b/SOUND/OPLL/VM2413/lineartable.vhd @@ -0,0 +1,171 @@ +-- +-- LinearTable.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- + +-- +-- modified by t.hara +-- + +-- ---------------------------------------------------------------------------- +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_signed.all; + +entity linear_table_mul is + port ( + i0 : in std_logic_vector( 5 downto 0 ); -- 符号無し 6bit (小数部 6bit) + i1 : in std_logic_vector( 9 downto 0 ); -- 符号付き10bit (整数部 10bit) + o : out std_logic_vector( 9 downto 0 ) -- 符号付き10bit (整数部 10bit) + ); +end linear_table_mul; + +architecture rtl of linear_table_mul is + signal w_mul : std_logic_vector( 16 downto 0 ); -- 符号付き17bit (整数部16bit) +begin + + w_mul <= ('0' & i0) * i1; + o <= w_mul( 15 downto 6 ); -- MSBカット, 小数部下位 6bitカット +end rtl; + +-- ---------------------------------------------------------------------------- +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + use work.vm2413.all; + +entity LinearTable is + port ( + clk : in std_logic; + reset : in std_logic; + addr : in std_logic_vector( 13 downto 0 ); -- 整数部 8bit, 小数部 6bit + data : out signed_li_type + ); +end LinearTable; + +architecture rtl of lineartable is + + component linear_table_mul + port ( + i0 : in std_logic_vector( 5 downto 0 ); + i1 : in std_logic_vector( 9 downto 0 ); + o : out std_logic_vector( 9 downto 0 ) + ); + end component; + + type log2lin_type is array ( 0 to 127 ) of std_logic_vector( 8 downto 0 ); + constant log2lin_data : log2lin_type := ( + "111111111","111101001","111010100","111000000", + "110101101","110011011","110001010","101111001", + "101101001","101011010","101001011","100111101", + "100110000","100100011","100010111","100001011", + "100000000","011110101","011101010","011100000", + "011010111","011001110","011000101","010111101", + "010110101","010101101","010100110","010011111", + "010011000","010010010","010001011","010000110", + "010000000","001111010","001110101","001110000", + "001101011","001100111","001100011","001011110", + "001011010","001010111","001010011","001001111", + "001001100","001001001","001000110","001000011", + "001000000","000111101","000111011","000111000", + "000110110","000110011","000110001","000101111", + "000101101","000101011","000101001","000101000", + "000100110","000100100","000100011","000100001", + "000100000","000011110","000011101","000011100", + "000011011","000011001","000011000","000010111", + "000010110","000010101","000010100","000010100", + "000010011","000010010","000010001","000010000", + "000010000","000001111","000001110","000001110", + "000001101","000001101","000001100","000001011", + "000001011","000001010","000001010","000001010", + "000001001","000001001","000001000","000001000", + "000001000","000000111","000000111","000000111", + "000000110","000000110","000000110","000000101", + "000000101","000000101","000000101","000000101", + "000000100","000000100","000000100","000000100", + "000000100","000000011","000000011","000000011", + "000000011","000000011","000000011","000000011", + "000000010","000000010","000000010","000000010", + "000000010","000000010","000000010","000000000" + ); + + signal ff_sign : std_logic; + signal ff_weight : std_logic_vector( 5 downto 0 ); + signal ff_data0 : std_logic_vector( 8 downto 0 ); + signal ff_data1 : std_logic_vector( 8 downto 0 ); + + signal w_addr1 : std_logic_vector( 12 downto 6 ); + signal w_data : std_logic_vector( 8 downto 0 ); + signal w_sub : std_logic_vector( 9 downto 0 ); -- 符号付き + signal w_mul : std_logic_vector( 9 downto 0 ); + signal w_inter : std_logic_vector( 9 downto 0 ); +begin + w_addr1 <= (addr( 12 downto 6 ) + 1) when( addr( 12 downto 6 ) /= "1111111" )else + "1111111"; + + process( clk ) + begin + if( clk'event and clk = '1' )then + -- アドレス指定された次のサイクルで対応する値が出てくる(1cycle delay) + ff_data0 <= log2lin_data( conv_integer( addr(12 downto 6) ) ); + ff_data1 <= log2lin_data( conv_integer( w_addr1 ) ); + end if; + end process; + + process( clk ) + begin + if( clk'event and clk = '1' )then + ff_sign <= addr( 13 ); + ff_weight <= addr( 5 downto 0 ); + end if; + end process; + + -- 補間 (※符号をまたがる場所では 0 になるから ff_sign は気にしない) + -- o = i0 * (1 - k) + i1 * w = i0 - w * i0 + w * i1 = i0 + w * (i1 - i0) + w_sub <= ('0' & ff_data1) - ('0' & ff_data0); + + u_linear_table_mul: linear_table_mul + port map ( + i0 => ff_weight, + i1 => w_sub, + o => w_mul + ); + + w_inter <= ('0' & ff_data0) + w_mul; + + process( clk ) + begin + if( clk'event and clk = '1' )then + data <= ( + sign => ff_sign, + value => w_inter( 8 downto 0 ) + ); + end if; + end process; +end rtl; diff --git a/SOUND/OPLL/VM2413/operator.vhd b/SOUND/OPLL/VM2413/operator.vhd new file mode 100644 index 0000000..972e261 --- /dev/null +++ b/SOUND/OPLL/VM2413/operator.vhd @@ -0,0 +1,160 @@ +-- +-- Operator.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- + +-- +-- modified by t.hara +-- + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + use work.vm2413.all; + +entity Operator is + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : in SLOT_TYPE; + stage : in STAGE_TYPE; + rhythm : in std_logic; + + WF : in WF_TYPE; + FB : in FB_TYPE; + + noise : in std_logic; + pgout : in std_logic_vector( 17 downto 0 ); -- 整数部 9bit, 小数部 9bit + egout : in std_logic_vector( 12 downto 0 ); + + faddr : out CH_TYPE; + fdata : in SIGNED_LI_TYPE; + + opout : out std_logic_vector( 13 downto 0 ) -- 整数部 8bit, 小数部 6bit + ); +end Operator; + +architecture rtl of Operator is + + component SineTable + port ( + clk : in std_logic; + clkena : in std_logic; + wf : in std_logic; + addr : in std_logic_vector( 17 downto 0 ); -- 整数部 9bit, 小数部 9bit + data : out std_logic_vector( 13 downto 0 ) -- 整数部 8bit, 小数部 6bit + ); + end component; + + signal addr : std_logic_vector( 17 downto 0 ); + signal data : std_logic_vector( 13 downto 0 ); + signal w_is_carrier : std_logic; + signal w_modula_m : std_logic_vector( LI_TYPE'high + 2 + 9 downto 0 ); + signal w_modula_c : std_logic_vector( LI_TYPE'high + 2 + 9 downto 0 ); + signal w_modula : std_logic_vector( LI_TYPE'high + 2 + 9 downto 0 ); + signal ff_egout : std_logic_vector( 12 downto 0 ); +begin + + -- サイン波(対数表現)-------------------------------------------------- + -- addr 指定した次々サイクルに data が出てくる + -- + -- stage X 00 X 01 X 10 X 11 X 00 + -- addr X 確定 + -- data X 確定 + -- opout X 確定 + -- + u_sine_table : SineTable + port map( + clk => clk, + clkena => clkena, + wf => wf, + addr => addr, + data => data + ); + + w_is_carrier <= slot(0); + w_modula_m <= (others => '0') when( fb = "000" )else + shr( '0' & fdata.value & '0' & "000000000", "111" xor fb ); + w_modula_c <= fdata.value & "00" & "000000000"; + w_modula <= w_modula_c when( w_is_carrier = '1' )else + w_modula_m; + + process( reset, clk ) + variable opout_buf : std_logic_vector( 13 downto 0 ); -- 整数部 8bit, 小数部 6bit + begin + if( reset = '1' )then + opout <= (others => '0'); + ff_egout <= (others => '0'); + elsif( clk'event and clk='1' )then + if( clkena = '1' )then + if( stage = "00" )then + -- サイン波の参照アドレス(位相)を決定するステージ + if( rhythm = '1' and ( slot = 14 or slot = 17 ))then -- HH or CYM + addr <= (not noise) & "01111111" & "000000000"; + elsif( rhythm = '1' and slot = 15 )then -- SD + addr <= (not pgout(pgout'high)) & "01111111" & "000000000"; + elsif( rhythm = '1' and slot = 16 )then -- TOM + addr <= pgout; + else + if( fdata.sign = '0' )then -- modula は fdata の絶対値をシフトした値だから、ここで符号処理してる + addr <= pgout + w_modula(pgout'range); + else + addr <= pgout - w_modula(pgout'range); + end if; + end if; + + elsif( stage = "01" )then + -- 決定された参照アドレスが u_sine_table へ供給されるステージ + elsif( stage = "10" )then + ff_egout <= egout; + + -- フィードバックメモリのアドレスを決めるステージ + if( slot(0) = '1' )then + if( conv_integer(slot)/2 = 8 )then + faddr <= 0; + else + faddr <= conv_integer(slot)/2 + 1; -- 次のモジュレータのアドレスなので +1 + end if; + end if; + elsif( stage = "11" )then + -- SineTable からデータが出てくるステージ + if ( ( '0' & ff_egout ) + ('0'& data(12 downto 0) ) ) < "10000000000000" then + opout_buf := data(13) & (ff_egout + data(12 downto 0) ); + else + opout_buf := data(13) & "1111111111111"; + end if; + opout <= opout_buf; + -- 決定されたフィードバックメモリアドレスが FeedBackMemory へ供給されるステージ + end if; + end if; + end if; + end process; +end rtl; diff --git a/SOUND/OPLL/VM2413/opll.vhd b/SOUND/OPLL/VM2413/opll.vhd new file mode 100644 index 0000000..6687dcf --- /dev/null +++ b/SOUND/OPLL/VM2413/opll.vhd @@ -0,0 +1,369 @@ +-- +-- Opll.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- + +-- +-- modified by t.hara +-- + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + use work.vm2413.all; + +entity opll is + port( + xin : in std_logic; + xout : out std_logic; + xena : in std_logic; + d : in std_logic_vector( 7 downto 0 ); + a : in std_logic; + cs_n : in std_logic; + we_n : in std_logic; + ic_n : in std_logic; + mixout : out std_logic_vector(13 downto 0 ) + ); +end opll; + +architecture rtl of opll is + component slotcounter + generic ( + delay : in integer + ); + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : out std_logic_vector( 4 downto 0 ); + stage : out std_logic_vector( 1 downto 0 ) + ); + end component; + + component controller port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : in slot_type; + stage : in stage_type; + + wr : in std_logic; + addr : in std_logic_vector( 7 downto 0 ); + data : in std_logic_vector( 7 downto 0 ); + + am : out am_type; + pm : out pm_type; + wf : out wf_type; + ml : out ml_type; + tl : out db_type; + fb : out fb_type; + ar : out ar_type; + dr : out dr_type; + sl : out sl_type; + rr : out rr_type; + blk : out blk_type; + fnum : out fnum_type; + rks : out rks_type; + key : out std_logic; + rhythm : out std_logic + ); + end component; + + component envelopegenerator + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : in slot_type; + stage : in stage_type; + rhythm : in std_logic; + + am : in am_type; + tl : in db_type; + ar : in ar_type; + dr : in dr_type; + sl : in sl_type; + rr : in rr_type; + rks : in rks_type; + key : in std_logic; + + egout : out std_logic_vector( 12 downto 0 ) + ); + end component; + + component phasegenerator + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : in slot_type; + stage : in stage_type; + rhythm : in std_logic; + + pm : in pm_type; + ml : in ml_type; + blk : in blk_type; + fnum : in fnum_type; + key : in std_logic; + + noise : out std_logic; + pgout : out std_logic_vector( 17 downto 0 ) + ); + end component; + + component operator + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + slot : in slot_type; + stage : in stage_type; + rhythm : in std_logic; + + wf : in wf_type; + fb : in fb_type; + + noise : in std_logic; + pgout : in std_logic_vector( 17 downto 0 ); + egout : in std_logic_vector( 12 downto 0 ); + + faddr : out ch_type; + fdata : in signed_li_type; + + opout : out std_logic_vector( 13 downto 0 ) + ); + end component; + + component outputgenerator + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + slot : in slot_type; + stage : in stage_type; + rhythm : in std_logic; + + opout : in std_logic_vector( 13 downto 0 ); + + faddr : in ch_type; + fdata : out signed_li_type; + + maddr : in slot_type; + mdata : out signed_li_type + ); + end component; + + component temporalmixer + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : in slot_type; + stage : in stage_type; + + rhythm : in std_logic; + + maddr : out slot_type; + mdata : in signed_li_type; + + mixout : out std_logic_vector(13 downto 0) + ); + end component; + + signal reset : std_logic; + + signal opllptr : std_logic_vector( 7 downto 0 ); + signal oplldat : std_logic_vector( 7 downto 0 ); + signal opllwr : std_logic; + + signal am : am_type; + signal pm : pm_type; + signal wf : wf_type; + signal tl : db_type; + signal fb : fb_type; + signal ar : ar_type; + signal dr : dr_type; + signal sl : sl_type; + signal rr : rr_type; + signal ml : ml_type; + signal fnum : fnum_type; + signal blk : blk_type; + signal rks : rks_type; + signal key : std_logic; + + signal rhythm : std_logic; + + signal noise : std_logic; + signal pgout : std_logic_vector( 17 downto 0 ); -- ソスソスソスソスソスソス 9bit, ソスソスソスソスソスソス 9bit + + signal egout : std_logic_vector( 12 downto 0 ); + + signal opout : std_logic_vector( 13 downto 0 ); + + + signal faddr : ch_type; + signal maddr : slot_type; + signal fdata : signed_li_type; + signal mdata : signed_li_type; + + signal state2 : std_logic_vector( 6 downto 0 ); + signal state5 : std_logic_vector( 6 downto 0 ); + signal state8 : std_logic_vector( 6 downto 0 ); + signal slot : slot_type; + signal slot2 : slot_type; + signal slot5 : slot_type; + signal slot8 : slot_type; + signal stage : stage_type; + signal stage2 : stage_type; + signal stage5 : stage_type; + signal stage8 : stage_type; + +begin + + xout <= xin; + reset <= not ic_n; + + -- CPUソスAソスNソスZソスXソスソスソスソス ------------------------------------------------------ + process( xin, reset ) + begin + if( reset ='1' )then + opllwr <= '0'; + opllptr <= (others =>'0'); + elsif( xin'event and xin = '1' )then + if( xena = '1' )then + if( cs_n = '0' and we_n = '0' and a = '0' )then + -- ソスソスソスソスソスWソスXソス^ソスAソスhソスソスソスXソスwソス閭鯉ソスWソスXソス^ ソスヨの擾ソスソスソスソスソスソスソス + opllptr <= d; + opllwr <= '0'; + elsif( cs_n = '0' and we_n = '0' and a = '1' )then + -- ソスソスソスソスソスWソスXソス^ ソスヨの擾ソスソスソスソスソスソスソス + oplldat <= d; + opllwr <= '1'; + end if; + end if; + end if; + end process; + + -- ソス^ソスCソス~ソスソスソスOソスWソスFソスlソスソスソス[ソス^ ----------------------------------------------- + s0: slotcounter + generic map( + delay => 0 + ) + port map( + clk => xin, + reset => reset, + clkena => xena, + slot => slot, + stage => stage + ); + + s2: slotcounter + generic map( + delay => 2 + ) + port map( + clk => xin, + reset => reset, + clkena => xena, + slot => slot2, + stage => stage2 + ); + + s5: slotcounter + generic map( + delay => 5 + ) + port map( + clk => xin, + reset => reset, + clkena => xena, + slot => slot5, + stage => stage5 + ); + + s8: slotcounter + generic map( + delay => 8 + ) + port map( + clk => xin, + reset => reset, + clkena => xena, + slot => slot8, + stage => stage8 + ); + + -- no delay + ct: controller port map ( + xin,reset,xena, slot, stage, opllwr,opllptr,oplldat, + am,pm,wf,ml,tl,fb,ar,dr,sl,rr,blk,fnum,rks,key,rhythm); + + -- 2 stages delay + eg: envelopegenerator port map ( + xin,reset,xena, + slot2, stage2, rhythm, + am, tl, ar, dr, sl, rr, rks, key, + egout + ); + + pg: phasegenerator port map ( + xin,reset,xena, + slot2, stage2, rhythm, + pm, ml, blk, fnum, key, + noise, pgout + ); + + -- 5 stages delay + op: operator port map ( + xin,reset,xena, + slot5, stage5, rhythm, + wf, fb, noise, pgout, egout, faddr, fdata, opout + ); + + -- 8 stages delay + og: outputgenerator port map ( + xin, reset, xena, slot8, stage8, rhythm, + opout, faddr, fdata, maddr, mdata + ); + + -- independent from delay + tm: temporalmixer port map ( + xin, reset, xena, + slot, stage, rhythm, + maddr, mdata, + mixout + ); + +end rtl; + diff --git a/SOUND/OPLL/VM2413/outputgenerator.vhd b/SOUND/OPLL/VM2413/outputgenerator.vhd new file mode 100644 index 0000000..d633e34 --- /dev/null +++ b/SOUND/OPLL/VM2413/outputgenerator.vhd @@ -0,0 +1,186 @@ +-- +-- OutputGenerator.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use WORK.VM2413.ALL; + +entity OutputGenerator is + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + slot : in SLOT_TYPE; + stage : in STAGE_TYPE; + + rhythm : in std_logic; + opout : in std_logic_vector( 13 downto 0 ); + + faddr : in CH_TYPE; + fdata : out SIGNED_LI_TYPE; + + maddr : in SLOT_TYPE; + mdata : out SIGNED_LI_TYPE + ); +end OutputGenerator; + +architecture RTL of OutputGenerator is + + component FeedbackMemory + port ( + clk : in std_logic; + reset : in std_logic; + wr : in std_logic; + waddr : in CH_TYPE; + wdata : in SIGNED_LI_TYPE; + raddr : in CH_TYPE; + rdata : out SIGNED_LI_TYPE + ); + end component; + + component OutputMemory + port ( + clk : in std_logic; + reset : in std_logic; + wr : in std_logic; + addr : in SLOT_TYPE; + wdata : in SIGNED_LI_TYPE; + rdata : out SIGNED_LI_TYPE; + addr2 : in SLOT_TYPE; + rdata2 : out SIGNED_LI_TYPE + ); + end component; + + component LinearTable + port ( + clk : in std_logic; + reset : in std_logic; + addr : in std_logic_vector( 13 downto 0 ); + data : out SIGNED_LI_TYPE + ); + end component; + + function AVERAGE ( L : SIGNED_LI_TYPE ; R : SIGNED_LI_TYPE ) return SIGNED_LI_TYPE is + variable vL, vR : std_logic_vector(LI_TYPE'high + 2 downto 0); + begin + + -- 符号+絶対値 → 2の補数 + if( L.sign = '0' )then + vL := "00" & L.value; + else + vL := not ( "00" & L.value ) + '1'; + end if; + if( R.sign = '0' )then + vR := "00" & R.value; + else + vR := not ( "00" & R.value ) + '1'; + end if; + + vL := vL + vR; + + -- 2の補数 → 符号+絶対値、ついでに 1/2 倍。ここで1ビット消失。 + if vL(vL'high) = '0' then -- positive + return ( sign => '0', value => vL(vL'high-1 downto 1) ); + else -- negative + vL := not ( vL - '1' ); + return ( sign => '1', value => vL(vL'high-1 downto 1) ); + end if; + + end; + + signal fb_wr, mo_wr : std_logic; + signal fb_addr : CH_TYPE; + signal mo_addr : SLOT_TYPE; + signal li_data, fb_wdata, mo_wdata, mo_rdata : SIGNED_LI_TYPE; +begin + + Fmem : FeedbackMemory port map( + clk => clk, + reset => reset, + wr => fb_wr, + waddr => fb_addr, + wdata => fb_wdata, + raddr => faddr, + rdata => fdata + ); + + Mmem : OutputMemory port map( + clk => clk, + reset => reset, + wr => mo_wr, + addr => mo_addr, + wdata => mo_wdata, + rdata => mo_rdata, + addr2 => maddr, + rdata2 => mdata + ); + + Ltbl : LinearTable port map ( + clk => clk, + reset => reset, + addr => opout, -- 0〜127 (opout は FF の出力だからダイレクトに入れても問題ない) + data => li_data -- 0〜511 + ); + + process( reset, clk ) + begin + if( reset = '1' )then + mo_wr <= '0'; + fb_wr <= '0'; + elsif( clk'event and clk = '1' )then + if( clkena = '1' )then + mo_addr <= slot; + + if( stage = 0 )then + mo_wr <= '0'; + fb_wr <= '0'; + + elsif( stage = 1 )then + -- opout に所望の値が入ってくるステージ + elsif( stage = 2 )then + -- 待ち + elsif( stage = 3 )then + -- LinerTable から opout で指定されたアドレスに対応する値が出てくるステージ + if( slot(0) = '0' )then + -- フィードバックメモリにはモジュレータのときしか書き込まない + fb_addr <= conv_integer(slot)/2; + fb_wdata<= AVERAGE(mo_rdata, li_data); + fb_wr <= '1'; + end if; + -- Store raw output + mo_wdata<= li_data; + mo_wr <= '1'; + end if; + end if; + end if; + end process; + +end RTL; diff --git a/SOUND/OPLL/VM2413/outputmemory.vhd b/SOUND/OPLL/VM2413/outputmemory.vhd new file mode 100644 index 0000000..d8f089a --- /dev/null +++ b/SOUND/OPLL/VM2413/outputmemory.vhd @@ -0,0 +1,85 @@ +-- +-- OutputMemory.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use WORK.VM2413.ALL; + +entity OutputMemory is port ( + clk : in std_logic; + reset : in std_logic; + wr : in std_logic; + addr : in SLOT_TYPE; + wdata : in SIGNED_LI_TYPE; + rdata : out SIGNED_LI_TYPE; + addr2 : in SLOT_TYPE; + rdata2 : out SIGNED_LI_TYPE +); +end OutputMemory; + +architecture RTL of OutputMemory is + + type SIGNED_LI_ARRAY_TYPE is array (0 to 18) of SIGNED_LI_VECTOR_TYPE; + signal data_array : SIGNED_LI_ARRAY_TYPE; + +begin + + process(clk, reset) + + variable init_ch : integer range 0 to 18; + + begin + + if (reset = '1') then + + init_ch := 0; + + elsif clk'event and clk='1' then + + if init_ch /= 18 then + + data_array(init_ch) <= (others=>'0'); + init_ch := init_ch + 1; + + elsif wr='1' then + + data_array(conv_integer(addr)) <= CONV_SIGNED_LI_VECTOR(wdata); + + end if; + + rdata <= CONV_SIGNED_LI(data_array(conv_integer(addr))); + rdata2 <= CONV_SIGNED_LI(data_array(conv_integer(addr2))); + + end if; + + end process; + +end RTL; \ No newline at end of file diff --git a/SOUND/OPLL/VM2413/phasegenerator.vhd b/SOUND/OPLL/VM2413/phasegenerator.vhd new file mode 100644 index 0000000..c977210 --- /dev/null +++ b/SOUND/OPLL/VM2413/phasegenerator.vhd @@ -0,0 +1,177 @@ +-- +-- PhaseGenerator.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- + +-- +-- modified by t.hara +-- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use WORK.VM2413.ALL; + +entity PhaseGenerator is port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : in SLOT_TYPE; + stage : in STAGE_TYPE; + + rhythm : in std_logic; + pm : in PM_TYPE; + ml : in ML_TYPE; + blk : in BLK_TYPE; + fnum : in FNUM_TYPE; + key : in std_logic; + + noise : out std_logic; + pgout : out std_logic_vector( 17 downto 0 ) + ); +end PhaseGenerator; + +architecture RTL of PhaseGenerator is + + component PhaseMemory is port ( + clk : in std_logic; + reset : in std_logic; + + slot : in SLOT_TYPE; + memwr : in std_logic; + + memout : out PHASE_TYPE; + memin : in PHASE_TYPE + ); + end component; + + type ML_TABLE is array (0 to 15) of std_logic_vector(4 downto 0); + + constant mltbl : ML_TABLE := ( + "00001","00010","00100","00110","01000","01010","01100","01110", + "10000","10010","10100","10100","11000","11000","11110","11110" + ); + + constant noise14_tbl : std_logic_vector(63 downto 0) := + "1000100010001000100010001000100100010001000100010001000100010000"; + constant noise17_tbl : std_logic_vector(7 downto 0) := + "00001010"; + + -- Signals connected to the phase memory. + signal memwr : std_logic; + signal memout, memin : PHASE_TYPE; + + -- Counter for pitch modulation; + signal pmcount : std_logic_vector(12 downto 0); + +begin + + process(clk, reset) + variable lastkey : std_logic_vector(18-1 downto 0); + variable dphase : PHASE_TYPE; + variable noise14 : std_logic; + variable noise17 : std_logic; + variable pgout_buf : std_logic_vector( 17 downto 0 ); -- 整数部 9bit, 小数部 9bit + begin + + if reset = '1' then + + pmcount <= (others=>'0'); + memwr <= '0'; + lastkey := (others=>'0'); + dphase := (others=>'0'); + noise14 := '0'; + noise17 := '0'; + + elsif clk'event and clk='1' then if clkena = '1' then + + noise <= noise14 xor noise17; + + if stage = 0 then + + memwr <= '0'; + + elsif stage = 1 then + + -- Wait for memory + + elsif stage = 2 then + + -- Update pitch LFO counter when slot = 0 and stage = 0 (i.e. increment per 72 clocks) + if slot = 0 then + pmcount <= pmcount + '1'; + end if; + + -- Delta phase + dphase := (SHL("00000000"&(fnum*mltbl(CONV_INTEGER(ml))),blk)(19 downto 2)); + + if pm ='1' then + case pmcount(pmcount'high downto pmcount'high-1) is + when "01" => + dphase := dphase + SHR(dphase,"111"); + when "11" => + dphase := dphase - SHR(dphase,"111"); + when others => null; + end case; + end if; + + -- Update Phase + if lastkey(conv_integer(slot)) = '0' and key = '1' and (rhythm = '0' or (slot /= "01110" and slot /= "10001")) then + memin <= (others=>'0'); + else + memin <= memout + dphase; + end if; + lastkey(conv_integer(slot)) := key; + + -- Update noise + if slot = "01110" then + noise14 := noise14_tbl(CONV_INTEGER(memout(15 downto 10))); + elsif slot = "10001" then + noise17 := noise17_tbl(CONV_INTEGER(memout(13 downto 11))); + end if; + + pgout_buf := memout; + pgout <= pgout_buf; + memwr <= '1'; + + elsif stage = 3 then + + memwr <= '0'; + + end if; + + end if; end if; + + end process; + + MEM : PhaseMemory port map(clk,reset,slot,memwr,memout,memin); + +end RTL; + diff --git a/SOUND/OPLL/VM2413/phasememory.vhd b/SOUND/OPLL/VM2413/phasememory.vhd new file mode 100644 index 0000000..3f0f7db --- /dev/null +++ b/SOUND/OPLL/VM2413/phasememory.vhd @@ -0,0 +1,83 @@ +-- +-- PhaseMemory.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use WORK.VM2413.ALL; + +entity PhaseMemory is + port ( + clk : in std_logic; + reset : in std_logic; + slot : in SLOT_TYPE; + memwr : in std_logic; + memout : out PHASE_TYPE; + memin : in PHASE_TYPE + ); +end PhaseMemory; + +architecture RTL of PhaseMemory is + + type PHASE_ARRAY_TYPE is array (0 to 18-1) of PHASE_TYPE; + signal phase_array : PHASE_ARRAY_TYPE; + +begin + + process (clk, reset) + + variable init_slot : integer range 0 to 18; + + begin + + if reset = '1' then + + init_slot := 0; + + elsif clk'event and clk = '1' then + + if init_slot /= 18 then + + phase_array(init_slot) <= (others=>'0'); + init_slot := init_slot + 1; + + elsif memwr = '1' then + + phase_array(conv_integer(slot)) <= memin; + + end if; + + memout <= phase_array(conv_integer(slot)); + + end if; + + end process; + +end RTL; \ No newline at end of file diff --git a/SOUND/OPLL/VM2413/registermemory.vhd b/SOUND/OPLL/VM2413/registermemory.vhd new file mode 100644 index 0000000..a50a48c --- /dev/null +++ b/SOUND/OPLL/VM2413/registermemory.vhd @@ -0,0 +1,75 @@ +-- +-- RegisterMemory.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- + +-- +-- modified by t.hara +-- + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + +entity RegisterMemory is + port ( + clk : in std_logic; + reset : in std_logic; + addr : in std_logic_vector( 3 downto 0 ); + wr : in std_logic; + idata : in std_logic_vector( 23 downto 0 ); + odata : out std_logic_vector( 23 downto 0 ) + ); +end RegisterMemory; + +architecture rtl of registermemory is + -- チャネル情報保持用 1read/1write の SRAM + type regs_array_type is array (0 to 8) of std_logic_vector( 23 downto 0 ); + signal regs_array : regs_array_type; + +begin + process( reset, clk ) + variable init_state : integer range 0 to 9; + begin + if( reset = '1' )then + init_state := 0; + elsif( clk'event and clk ='1' )then + if( init_state /= 9 )then + -- 起動してすぐに RAM の内容を初期化する + regs_array( init_state ) <= (others => '0'); + init_state := init_state + 1; + elsif( wr = '1' )then + -- 書き込みサイクル + regs_array( conv_integer(addr) ) <= idata; + end if; + -- 読み出しは常時 + odata <= regs_array( conv_integer(addr) ); + end if; + end process; +end rtl; diff --git a/SOUND/OPLL/VM2413/sinetable.vhd b/SOUND/OPLL/VM2413/sinetable.vhd new file mode 100644 index 0000000..1e6d4f8 --- /dev/null +++ b/SOUND/OPLL/VM2413/sinetable.vhd @@ -0,0 +1,214 @@ +-- +-- SineTable.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- + +-- +-- modified by t.hara +-- + +-- ---------------------------------------------------------------------------- +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_signed.all; + +entity interpolate_mul is + port ( + i0 : in std_logic_vector( 8 downto 0 ); -- 符号無し 9bit (整数部 0bit, 小数部 9bit) + i1 : in std_logic_vector( 11 downto 0 ); -- 符号付き12bit (整数部 8bit, 小数部 4bit) + o : out std_logic_vector( 13 downto 0 ) -- 符号付き 7bit (整数部 8bit, 小数部 6bit) + ); +end interpolate_mul; + +architecture rtl of interpolate_mul is + signal w_mul : std_logic_vector( 21 downto 0 ); -- 符号付き22bit (整数部 9bit, 小数部13bit) +begin + + w_mul <= ('0' & i0) * i1; + o <= w_mul( 20 downto 7 ); -- MSBカットで 21bit, 小数部下位 7bitカット +end rtl; + +-- ---------------------------------------------------------------------------- +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + use ieee.std_logic_arith.all; -- conv_integer() + +entity SineTable is + port ( + clk : in std_logic; + clkena : in std_logic; + wf : in std_logic; + addr : in std_logic_vector( 17 downto 0 ); -- 整数部 9bit, 小数部 9bit + data : out std_logic_vector( 13 downto 0 ) -- 整数部 8bit, 小数部 6bit + ); +end SineTable; + +architecture rtl of sinetable is + + component interpolate_mul + port ( + i0 : in std_logic_vector( 8 downto 0 ); -- 符号無し 9bit (整数部 0bit, 小数部 9bit) + i1 : in std_logic_vector( 11 downto 0 ); -- 符号付き 8bit (整数部 8bit) + o : out std_logic_vector( 13 downto 0 ) -- 符号無し 7bit (整数部 8bit) + ); + end component; + + type sin_type is array (0 to 127) of std_logic_vector( 10 downto 0 ); -- 整数部 7bit, 小数部 4bit + constant sin_data : sin_type := ( + "11111111111", "11001010000", "10101010001", "10010111100", + "10001010011", "10000000001", "01110111110", "01110000101", + "01101010101", "01100101001", "01100000011", "01011100000", + "01011000000", "01010100011", "01010001000", "01001101111", + "01001011000", "01001000010", "01000101101", "01000011010", + "01000000111", "00111110110", "00111100101", "00111010101", + "00111000110", "00110110111", "00110101001", "00110011100", + "00110001111", "00110000011", "00101110111", "00101101011", + "00101100000", "00101010110", "00101001011", "00101000001", + "00100111000", "00100101110", "00100100101", "00100011100", + "00100010100", "00100001011", "00100000011", "00011111011", + "00011110100", "00011101100", "00011100101", "00011011110", + "00011010111", "00011010001", "00011001010", "00011000100", + "00010111110", "00010111000", "00010110010", "00010101100", + "00010100111", "00010100001", "00010011100", "00010010111", + "00010010010", "00010001101", "00010001000", "00010000011", + "00001111111", "00001111010", "00001110110", "00001110010", + "00001101110", "00001101010", "00001100110", "00001100010", + "00001011110", "00001011010", "00001010111", "00001010011", + "00001010000", "00001001101", "00001001001", "00001000110", + "00001000011", "00001000000", "00000111101", "00000111011", + "00000111000", "00000110101", "00000110011", "00000110000", + "00000101110", "00000101011", "00000101001", "00000100111", + "00000100101", "00000100010", "00000100000", "00000011110", + "00000011101", "00000011011", "00000011001", "00000010111", + "00000010110", "00000010100", "00000010011", "00000010001", + "00000010000", "00000001110", "00000001101", "00000001100", + "00000001011", "00000001010", "00000001001", "00000001000", + "00000000111", "00000000110", "00000000101", "00000000100", + "00000000011", "00000000011", "00000000010", "00000000010", + "00000000001", "00000000001", "00000000000", "00000000000", + "00000000000", "00000000000", "00000000000", "00000000000" + ); + + signal ff_data0 : std_logic_vector( 10 downto 0 ); -- 符号ナシ整数部 7bit, 小数部 4bit + signal ff_data1 : std_logic_vector( 10 downto 0 ); -- 符号ナシ整数部 7bit, 小数部 4bit + signal w_wf : std_logic_vector( 13 downto 0 ); + signal w_xor : std_logic_vector( 6 downto 0 ); + signal w_addr0 : std_logic_vector( 6 downto 0 ); + signal w_addr1 : std_logic_vector( 6 downto 0 ); + signal w_xaddr : std_logic_vector( 6 downto 0 ); + signal ff_sign : std_logic; + signal ff_wf : std_logic; + signal ff_weight : std_logic_vector( 8 downto 0 ); + signal w_sub : std_logic_vector( 11 downto 0 ); -- 符号付き整数部 8bit, 小数部 4bit + signal w_mul : std_logic_vector( 13 downto 0 ); -- 符号付き整数部 8bit, 小数部 6bit + signal w_inter : std_logic_vector( 13 downto 0 ); + signal ff_data : std_logic_vector( 13 downto 0 ); +begin + + w_xor <= (others => addr(16)); + w_xaddr <= addr( 15 downto 9 ) xor w_xor; + w_addr0 <= w_xaddr; + w_addr1 <= "1111111" xor w_xor when(addr( 15 downto 9 ) = "1111111" )else -- 波形が循環する部分の対処 + (addr( 15 downto 9 ) + 1) xor w_xor; + + -- 波形メモリ + process( clk ) + begin + if( clk'event and clk = '1' )then + if( clkena = '1' )then + ff_data0 <= sin_data( conv_integer( w_addr0 ) ); + ff_data1 <= sin_data( conv_integer( w_addr1 ) ); + end if; + end if; + end process; + + -- 修飾情報の遅延(波形メモリの読み出し遅延にあわせる) + process( clk ) + begin + if( clk'event and clk = '1' )then + if( clkena = '1' )then + ff_sign <= addr(17); + ff_wf <= wf and addr(17); + ff_weight <= addr( 8 downto 0 ); + end if; + end if; + end process; + + -- 補間 (※符号をまたがる場所では 0 になるから ff_sign は気にしない) + -- o = i0 * (1 - k) + i1 * w = i0 - w * i0 + w * i1 = i0 + w * (i1 - i0) + w_sub <= ('0' & ff_data1) - ('0' & ff_data0); + + u_interpolate_mul: interpolate_mul + port map ( + i0 => ff_weight, + i1 => w_sub, + o => w_mul + ); + + -- 下位 6bit (小数部)を演算精度維持のために残す + w_inter <= (ff_data0 & "00") + w_mul; -- "00" は桁あわせ + w_wf <= (others => ff_wf); + + process( clk ) + begin + if( clk'event and clk = '1' )then + if( clkena = '1' )then + -- 補間演算の結果をいったん FF に入れて演算遅延を吸収 + ff_data <= (ff_sign & w_inter(12 downto 0)) or w_wf; + end if; + end if; + end process; + + data <= ff_data; + + -------------------------------------------------------------------------- + -- addr X addr入力 X + -- w_addr0 X 確定 X + -- w_addr1 X 確定 X + -- ff_data0 X 確定 X + -- ff_data1 X 確定 X + -- ff_sign X 確定 X + -- ff_wf X 確定 X + -- ff_weight X 確定 X + -- w_sub X 確定 X + -- w_mul X 確定 X + -- w_inter X 確定 X + -- w_wf X 確定 X + -- ff_data X 確定 X + -- data X 確定 X + -- Operator + -- stage X 01 X 10 X 11 X 00 X + -- + -- Operator は、stage = 01 のときに投入した入力値に基づく出力を得る場合に + -- stage = 11 で受け取らなければならない。 + -- + -- アドレス指定されてから、それに対応する値が得られるまで 2cycle の遅延 + -- +end rtl; diff --git a/SOUND/OPLL/VM2413/slotcounter.vhd b/SOUND/OPLL/VM2413/slotcounter.vhd new file mode 100644 index 0000000..8687834 --- /dev/null +++ b/SOUND/OPLL/VM2413/slotcounter.vhd @@ -0,0 +1,75 @@ +-- +-- SlotCounter.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- + +-- +-- modified by t.hara +-- + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + +entity SlotCounter is + generic ( + delay : integer + ); + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : out std_logic_vector( 4 downto 0 ); + stage : out std_logic_vector( 1 downto 0 ) + ); +end SlotCounter; + +architecture rtl of SlotCounter is + signal ff_count : std_logic_vector( 6 downto 0 ); +begin + + process( reset, clk ) + begin + if( reset = '1' )then + ff_count <= "1000111" - delay; + elsif( clk'event and clk='1' )then + if( clkena ='1' )then + if( ff_count = "1000111" )then -- 71 + ff_count <= (others => '0'); + else + ff_count <= ff_count + 1; + end if; + end if; + end if; + end process; + + stage <= ff_count( 1 downto 0 ); -- 0〜3 で循環 + slot <= ff_count( 6 downto 2 ); -- 0〜17 で循環 +end rtl; diff --git a/SOUND/OPLL/VM2413/temporalmixer.vhd b/SOUND/OPLL/VM2413/temporalmixer.vhd new file mode 100644 index 0000000..d82f895 --- /dev/null +++ b/SOUND/OPLL/VM2413/temporalmixer.vhd @@ -0,0 +1,148 @@ +-- +-- TemporalMixer.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use ieee.std_logic_arith.all; +use WORK.VM2413.ALL; + +entity TemporalMixer is + port ( + clk : in std_logic; + reset : in std_logic; + clkena : in std_logic; + + slot : in SLOT_TYPE; + stage : in STAGE_TYPE; + + rhythm : in std_logic; + + maddr : out SLOT_TYPE; + mdata : in SIGNED_LI_TYPE; + + mixout : out std_logic_vector(13 downto 0) + ); +end TemporalMixer; + +architecture RTL of TemporalMixer is + + signal mute : std_logic; + signal mix : std_logic_vector(13 downto 0); + +begin + + process (clk, reset) + begin + + if reset = '1' then + + maddr <= (others => '0'); + mute <= '1'; + mix <= (others =>'0'); + mixout <= (others =>'0'); + + elsif clk'event and clk = '1' then if clkena='1' then + + if stage = 0 then + + if rhythm = '0' then + + case slot is + when "00000" => maddr <= "00001"; mute <='0'; -- CH0 + when "00001" => maddr <= "00011"; mute <='0'; -- CH1 + when "00010" => maddr <= "00101"; mute <='0'; -- CH2 + when "00011" => mute <= '1'; + when "00100" => mute <= '1'; + when "00101" => mute <= '1'; + when "00110" => maddr <= "00111"; mute<='0'; -- CH3 + when "00111" => maddr <= "01001"; mute<='0'; -- CH4 + when "01000" => maddr <= "01011"; mute<='0'; -- CH5 + when "01001" => mute <= '1'; + when "01010" => mute <= '1'; + when "01011" => mute <= '1'; + when "01100" => maddr <= "01101"; mute<='0'; -- CH6 + when "01101" => maddr <= "01111"; mute<='0'; -- CH7 + when "01110" => maddr <= "10001"; mute<='0'; -- CH8 + when "01111" => mute <= '1'; + when "10000" => mute <= '1'; + when "10001" => mute <= '1'; + when others => mute <= '1'; + end case; + + else + + case slot is + when "00000" => maddr <= "00001"; mute <='0'; -- CH0 + when "00001" => maddr <= "00011"; mute <='0'; -- CH1 + when "00010" => maddr <= "00101"; mute <='0'; -- CH2 + when "00011" => maddr <= "01111"; mute <='0'; -- SD + when "00100" => maddr <= "10001"; mute <='0'; -- CYM + when "00101" => mute <='1'; + when "00110" => maddr <= "00111"; mute <='0'; -- CH3 + when "00111" => maddr <= "01001"; mute <='0'; -- CH4 + when "01000" => maddr <= "01011"; mute <='0'; -- CH5 + when "01001" => maddr <= "01110"; mute <='0'; -- HH + when "01010" => maddr <= "10000"; mute <='0'; -- TOM + when "01011" => maddr <= "01101"; mute <='0'; -- BD + when "01100" => maddr <= "01111"; mute <='0'; -- SD + when "01101" => maddr <= "10001"; mute <='0'; -- CYM + when "01110" => maddr <= "01110"; mute <='0'; -- HH + when "01111" => maddr <= "10000"; mute <='0'; -- TOM + when "10000" => maddr <= "01101"; mute <='0'; -- BD + when "10001" => mute <='1'; + when others => mute <='1'; + end case; + + end if; + + else + if stage = 2 then + if slot = "10001" then + mixout <= mix; + mix <= (others =>'0'); + else + if mute = '0' then + if mdata.sign = '0' then + mix <= mix + mdata.value; + else + mix <= mix - mdata.value; + end if; + end if; + end if; + end if; + + end if; + + end if; end if; + + end process; + +end RTL; \ No newline at end of file diff --git a/SOUND/OPLL/VM2413/vm2413.vhd b/SOUND/OPLL/VM2413/vm2413.vhd new file mode 100644 index 0000000..a3f780c --- /dev/null +++ b/SOUND/OPLL/VM2413/vm2413.vhd @@ -0,0 +1,215 @@ +-- +-- VM2413.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +package VM2413 is + + subtype CH_TYPE is integer range 0 to 9-1; + subtype SLOT_TYPE is std_logic_vector( 4 downto 0 ); + subtype STAGE_TYPE is std_logic_vector( 1 downto 0 ); + + subtype REGS_VECTOR_TYPE is std_logic_vector(23 downto 0); + + type REGS_TYPE is record + INST : std_logic_vector(3 downto 0); + VOL : std_logic_vector(3 downto 0); + SUS : std_logic; + KEY : std_logic; + BLK : std_logic_vector(2 downto 0); + FNUM : std_logic_vector(8 downto 0); + end record; + + function CONV_REGS_VECTOR ( regs : REGS_TYPE ) return REGS_VECTOR_TYPE; + function CONV_REGS ( vec : REGS_VECTOR_TYPE ) return REGS_TYPE; + + subtype VOICE_ID_TYPE is integer range 0 to 37; + subtype VOICE_VECTOR_TYPE is std_logic_vector(35 downto 0); + + type VOICE_TYPE is record + AM, PM, EG, KR : std_logic; + ML : std_logic_vector(3 downto 0); + KL : std_logic_vector(1 downto 0); + TL : std_logic_vector(5 downto 0); + WF : std_logic; + FB : std_logic_vector(2 downto 0); + AR, DR, SL, RR : std_logic_vector(3 downto 0); + end record; + + function CONV_VOICE_VECTOR ( inst : VOICE_TYPE ) return VOICE_VECTOR_TYPE; + function CONV_VOICE ( inst_vec : VOICE_VECTOR_TYPE ) return VOICE_TYPE; + + -- Voice Parameter Types + subtype AM_TYPE is std_logic; -- AM switch - '0':off '1':3.70Hz + subtype PM_TYPE is std_logic; -- PM switch - '0':stop '1':6.06Hz + subtype EG_TYPE is std_logic; -- Envelope type - '0':release '1':sustine + subtype KR_TYPE is std_logic; -- Keyscale Rate + subtype ML_TYPE is std_logic_vector(3 downto 0); -- Multiple + subtype WF_TYPE is std_logic; -- WaveForm - '0':sine '1':half-sine + subtype FB_TYPE is std_logic_vector(2 downto 0); -- Feedback + subtype AR_TYPE is std_logic_vector(3 downto 0); -- Attack Rate + subtype DR_TYPE is std_logic_vector(3 downto 0); -- Decay Rate + subtype SL_TYPE is std_logic_vector(3 downto 0); -- Sustine Level + subtype RR_TYPE is std_logic_vector(3 downto 0); -- Release Rate + + -- F-Number, Block and Rks(Rate and key-scale) types + subtype BLK_TYPE is std_logic_vector(2 downto 0); -- Block + subtype FNUM_TYPE is std_logic_vector(8 downto 0); -- F-Number + subtype RKS_TYPE is std_logic_vector(3 downto 0); -- Rate-KeyScale + + -- 18 bits phase counter + subtype PHASE_TYPE is std_logic_vector (17 downto 0); + -- Phage generator's output + subtype PGOUT_TYPE is std_logic_vector (8 downto 0); + -- Final linear output of opll + subtype LI_TYPE is std_logic_vector (8 downto 0); -- Wave in Linear + -- Total Level and Envelope output + subtype DB_TYPE is std_logic_vector(6 downto 0); -- Wave in dB, Reso: 0.375dB + + subtype SIGNED_LI_VECTOR_TYPE is std_logic_vector(LI_TYPE'high + 1 downto 0); + type SIGNED_LI_TYPE is record + sign : std_logic; + value : LI_TYPE; + end record; + function CONV_SIGNED_LI_VECTOR( li : SIGNED_LI_TYPE ) return SIGNED_LI_VECTOR_TYPE; + function CONV_SIGNED_LI( vec : SIGNED_LI_VECTOR_TYPE ) return SIGNED_LI_TYPE; + + subtype SIGNED_DB_VECTOR_TYPE is std_logic_vector(DB_TYPE'high + 1 downto 0); + type SIGNED_DB_TYPE is record + sign : std_logic; + value : DB_TYPE; + end record; + function CONV_SIGNED_DB_VECTOR( db : SIGNED_DB_TYPE ) return SIGNED_DB_VECTOR_TYPE; + function CONV_SIGNED_DB( vec : SIGNED_DB_VECTOR_TYPE ) return SIGNED_DB_TYPE; + + -- Envelope generator states + subtype EGSTATE_TYPE is std_logic_vector(1 downto 0); + + constant Attack : EGSTATE_TYPE := "01"; + constant Decay : EGSTATE_TYPE := "10"; + constant Release : EGSTATE_TYPE := "11"; + constant Finish : EGSTATE_TYPE := "00"; + + -- Envelope generator phase + subtype EGPHASE_TYPE is std_logic_vector(22 downto 0); + + -- Envelope data (state and phase) + type EGDATA_TYPE is record + state : EGSTATE_TYPE; + phase : EGPHASE_TYPE; + end record; + + subtype EGDATA_VECTOR_TYPE is std_logic_vector(EGSTATE_TYPE'high + EGPHASE_TYPE'high + 1 downto 0); + + function CONV_EGDATA_VECTOR( data : EGDATA_TYPE ) return EGDATA_VECTOR_TYPE; + function CONV_EGDATA( vec : EGDATA_VECTOR_TYPE ) return EGDATA_TYPE; + + component Opll port( + XIN : in std_logic; + XOUT : out std_logic; + XENA : in std_logic; + D : in std_logic_vector(7 downto 0); + A : in std_logic; + CS_n : in std_logic; + WE_n : in std_logic; + IC_n : in std_logic; + mixout : out std_logic_vector(13 downto 0) + ); + end component; + +end VM2413; + +package body VM2413 is + + function CONV_REGS_VECTOR ( regs : REGS_TYPE ) return REGS_VECTOR_TYPE is + begin + return regs.INST & regs.VOL & "00" & regs.SUS & regs.KEY & regs.BLK & regs.FNUM; + end CONV_REGS_VECTOR; + + function CONV_REGS ( vec : REGS_VECTOR_TYPE ) return REGS_TYPE is + begin + return ( + INST=>vec(23 downto 20), VOL=>vec(19 downto 16), + SUS=>vec(13), KEY=>vec(12), BLK=>vec(11 downto 9), FNUM=>vec(8 downto 0) + ); + end CONV_REGS; + + function CONV_VOICE_VECTOR ( inst : VOICE_TYPE ) return VOICE_VECTOR_TYPE is + begin + return inst.AM & inst.PM & inst.EG & inst.KR & + inst.ML & inst.KL & inst.TL & inst.WF & inst.FB & + inst.AR & inst.DR & inst.SL & inst.RR; + end CONV_VOICE_VECTOR; + + function CONV_VOICE ( inst_vec : VOICE_VECTOR_TYPE ) return VOICE_TYPE is + begin + return ( + AM=>inst_vec(35), PM=>inst_vec(34), EG=>inst_vec(33), KR=>inst_vec(32), + ML=>inst_vec(31 downto 28), KL=>inst_vec(27 downto 26), TL=>inst_vec(25 downto 20), + WF=>inst_vec(19), FB=>inst_vec(18 downto 16), + AR=>inst_vec(15 downto 12), DR=>inst_vec(11 downto 8), SL=>inst_vec(7 downto 4), RR=>inst_vec(3 downto 0) + ); + end CONV_VOICE; + + function CONV_SIGNED_LI_VECTOR( li : SIGNED_LI_TYPE ) return SIGNED_LI_VECTOR_TYPE is + begin + return li.sign & li.value; + end; + + function CONV_SIGNED_LI( vec : SIGNED_LI_VECTOR_TYPE ) return SIGNED_LI_TYPE is + begin + return ( sign => vec(vec'high), value=>vec(vec'high-1 downto 0) ); + end; + + function CONV_SIGNED_DB_VECTOR( db : SIGNED_DB_TYPE ) return SIGNED_DB_VECTOR_TYPE is + begin + return db.sign & db.value; + end; + + function CONV_SIGNED_DB( vec : SIGNED_DB_VECTOR_TYPE ) return SIGNED_DB_TYPE is + begin + return ( sign => vec(vec'high), value=>vec(vec'high-1 downto 0) ); + end; + + function CONV_EGDATA_VECTOR( data : EGDATA_TYPE ) return EGDATA_VECTOR_TYPE is + begin + return data.state & data.phase; + end; + + function CONV_EGDATA( vec : EGDATA_VECTOR_TYPE ) return EGDATA_TYPE is + begin + return ( state => vec(vec'high downto EGPHASE_TYPE'high + 1), + phase => vec(EGPHASE_TYPE'range) ); + end; + +end VM2413; diff --git a/SOUND/OPLL/VM2413/voicememory.vhd b/SOUND/OPLL/VM2413/voicememory.vhd new file mode 100644 index 0000000..3e3d37d --- /dev/null +++ b/SOUND/OPLL/VM2413/voicememory.vhd @@ -0,0 +1,110 @@ +-- +-- VoiceMemory.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use WORK.VM2413.ALL; + +entity VoiceMemory is + port ( + clk : in std_logic; + reset : in std_logic; + + idata : in VOICE_TYPE; + wr : in std_logic; + rwaddr : in VOICE_ID_TYPE; -- read/write address + roaddr : in VOICE_ID_TYPE; -- read only address + odata : out VOICE_TYPE; + rodata : out VOICE_TYPE + ); +end VoiceMemory; + +architecture RTL of VoiceMemory is + + -- The following array is mapped into a Single-Clock Synchronous RAM with two-read + -- addresses by Altera's QuartusII compiler. + type VOICE_ARRAY_TYPE is array (VOICE_ID_TYPE'range) of VOICE_VECTOR_TYPE; + signal voices : VOICE_ARRAY_TYPE; + + component VoiceRom port ( + clk : in std_logic; + addr : in VOICE_ID_TYPE; + data : out VOICE_TYPE + ); + end component; + + signal rom_addr : VOICE_ID_TYPE; + signal rom_data : VOICE_TYPE; + signal rstate : integer range 0 to 2; + +begin + + ROM2413 : VoiceRom port map(clk, rom_addr, rom_data); + + process (clk, reset) + + variable init_id : integer range 0 to VOICE_ID_TYPE'high+1; + + begin + + if reset = '1' then + + init_id := 0; + rstate <= 0; + + elsif clk'event and clk = '1' then + + if init_id /= VOICE_ID_TYPE'high+1 then + + case rstate is + when 0 => + rom_addr <= init_id; + rstate <= 1; + when 1 => + rstate <= 2; + when 2 => + voices(init_id) <= CONV_VOICE_VECTOR(rom_data); + rstate <= 0; + init_id := init_id + 1; + end case; + + elsif wr = '1' then + voices(rwaddr) <= CONV_VOICE_VECTOR(idata); + end if; + + odata <= CONV_VOICE(voices(rwaddr)); + rodata <= CONV_VOICE(voices(roaddr)); + + end if; + + end process; + +end RTL; \ No newline at end of file diff --git a/SOUND/OPLL/VM2413/voicerom.vhd b/SOUND/OPLL/VM2413/voicerom.vhd new file mode 100644 index 0000000..792e6d3 --- /dev/null +++ b/SOUND/OPLL/VM2413/voicerom.vhd @@ -0,0 +1,119 @@ +-- +-- VoiceRom.vhd +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use WORK.VM2413.ALL; + +entity VoiceRom is + port ( + clk : in std_logic; + addr : in VOICE_ID_TYPE; + data : out VOICE_TYPE + ); +end VoiceRom; + +architecture RTL of VoiceRom is + + type VOICE_ARRAY_TYPE is array (VOICE_ID_TYPE'range) of VOICE_VECTOR_TYPE; + constant voices : VOICE_ARRAY_TYPE := ( +-- APEKKL< TL >W + "000000000000000000000000000000000000", -- @0(M) + "000000000000000000000000000000000000", -- @0(C) +-- APEKKL< TL >W + "011000010001111001111111000000000000", -- @1(M) + "011000010000000010000111111100010111", -- @1(C) +-- APEKKL< TL >W + "000100110001011111101111111100100011", -- @2(M) + "010000010000000000001111111100010011", -- @2(C) +-- APEKKL< TL >W + "001000111001101001001010001111110000", -- @3(M) + "000000010000000000001111010000100011", -- @3(C) +-- APEKKL< TL >W + "000100010000111001111111101001110000", -- @4(M) + "011000010000000000000110010000010111", -- @4(C) +-- APEKKL< TL >W + "001000100001111001101111000000000000", -- @5(M) + "001000010000000000000111011000101000", -- @5(C) +-- APEKKL< TL >W + "001000010001011001011111000000000000", -- @6(M) + "001000100000000000000111000100011000", -- @6(C) +-- APEKKL< TL >W + "001000010001110101111000001000010000", -- @7(M) + "011000010000000000001000000000000111", -- @7(C) +-- APEKKL< TL >W + "001000110010110101101001000000000000", -- @8(M) + "001000010000000010001001000000000111", -- @8(C) +-- APEKKL< TL >W + "001000010001101101100110010000010000", -- @9(M) + "001000010000000000000110010100010111", -- @9(C) +-- APEKKL< TL >W + "001000010000101110101000010101110000", -- @10(M) + "001000010000000010001010000000000111", -- @10(C) +-- APEKKL< TL >W + "001000111000001100001111111100010000", -- @11(M) + "000000010000000010001011000000000100", -- @11(C) +-- APEKKL< TL >W + "100101110010000001111111111100100010", -- @12(M) + "110000010000000000001111111100010010", -- @12(C) +-- APEKKL< TL >W + "011000010000110001011101001001000000", -- @13(M) + "000000000000000000001111011001000011", -- @13(C) +-- APEKKL< TL >W + "000000010101011000111111010000000011", -- @14(M) + "000000010000000000001111000000000010", -- @14(C) +-- APEKKL< TL >W + "001000011000100100111111000111110000", -- @15(M) + "010000010000000000001111010000100011", -- @15(C) +-- APEKKL< TL >W + "000001110001011000001101111111111111", -- BD(M) + "001000010000000000001111100011111000", -- BD(C) +-- APEKKL< TL >W + "001100010000000000001111011111110111", -- HH + "001100100000000000001111011111110111", -- SD +-- APEKKL< TL >W + "001001010000000000001111100011111000", -- TOM + "000000010000000000001101110001010101" -- CYM +); + +begin + + process (clk) + + begin + + if clk'event and clk = '1' then + data <= CONV_VOICE(voices(addr)); + end if; + + end process; + +end RTL; \ No newline at end of file diff --git a/SOUND/OPLL/eseopll.vhd b/SOUND/OPLL/eseopll.vhd new file mode 100644 index 0000000..84acce7 --- /dev/null +++ b/SOUND/OPLL/eseopll.vhd @@ -0,0 +1,119 @@ +-- +-- eseopll.vhd +-- A simple wrapper module for fitting VM2413 to ESE-MSX SYSTEM +-- +-- Copyright (c) 2006 Mitsutaka Okazaki (brezza@pokipoki.org) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use WORK.VM2413.ALL; + +entity eseopll is + port( + clk21m : in std_logic; + reset : in std_logic; + clkena : in std_logic; + enawait : in std_logic; + req : in std_logic; + ack : out std_logic; + wrt : in std_logic; + adr : in std_logic_vector(15 downto 0); + dbo : in std_logic_vector(7 downto 0); + wav : out std_logic_vector(13 downto 0) + ); +end eseopll; + +architecture RTL of eseopll is + + signal XIN : std_logic; + signal D : std_logic_vector(7 downto 0); + signal A : std_logic; + signal CS_n : std_logic; + signal WE_n : std_logic; + signal IC_n : std_logic; + signal MO : std_logic_vector(9 downto 0); + signal RO : std_logic_vector(9 downto 0); + + signal counter : integer range 0 to 72*6; + + signal A_buf : std_logic; + signal dbo_buf : std_logic_vector(7 downto 0); + signal CS_n_buf : std_logic; + signal WE_n_buf : std_logic; + +begin + + IC_n <= not reset; + + process (clk21m, reset) + + begin + + if reset = '1' then + + counter <= 0; + + elsif clk21m'event and clk21m = '1' then + + if counter /= 0 then + counter <= counter - 1; + ack <= '0'; + else + if req = '1' then + if enawait = '1' then + if adr(0) = '0' then + counter <= 4*6; + else + counter <= 72*6; + end if; + end if; + A_buf <= adr(0); + dbo_buf <= dbo; + CS_n_buf <= not req; + WE_n_buf <= not wrt; + end if; + ack <= req; + end if; + + if (clkena = '1') then + + A <= A_buf; + D <= dbo_buf; + CS_n <= CS_n_buf; + WE_n <= WE_n_buf; + + end if; + + end if; + + end process; + + U1 : opll port map (clk21m, open, clkena, D, A, CS_n, WE_n, IC_n, wav); + +end RTL;