mirror of
https://github.com/MiSTer-devel/SMS_MiSTer.git
synced 2026-05-17 03:04:32 +00:00
Technically, `Clk’event and clk = ‘1’` can result in non-`0` triggers (e.g. `1`, `U`, `H`, `X`, `Z`, `W`, etc...), whereas `rising_edge(clk)` does not.
215 lines
9.2 KiB
VHDL
215 lines
9.2 KiB
VHDL
--
|
|
-- 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 rising_edge(clk) 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 rising_edge(clk) 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 rising_edge(clk) 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;
|