1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-04-14 07:29:37 +00:00

Ladybug HW: use common T80 and SN67489

This commit is contained in:
Gyorgy Szombathelyi
2020-08-01 16:31:20 +02:00
parent 005b15b5ef
commit 58e23d2405
86 changed files with 416 additions and 23158 deletions

View File

@@ -45,22 +45,24 @@
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sn76489_attenuator is
port (
attenuation_i : in std_logic_vector(0 to 3);
factor_i : in signed(0 to 1);
product_o : out signed(0 to 7)
factor_i : in std_logic;
product_o : out std_logic_vector(0 to 7)
);
end sn76489_attenuator;
architecture rtl of sn76489_attenuator is
type volume_t is array (natural range 0 to 15) of natural;
constant volume_c : volume_t := (31, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3, 2, 2, 2, 1, 0);
begin
-----------------------------------------------------------------------------
@@ -78,37 +80,8 @@ begin
-- v(0) = 31
-- v(n+1) = v(n) * 0.79432823
--
attenuate: process (attenuation_i,
factor_i)
type volume_t is array (natural range 0 to 15) of natural;
constant volume_c : volume_t :=
(31, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3, 2, 2, 2, 1, 0);
variable attenuation_v : unsigned(attenuation_i'range);
variable volume_v : signed(product_o'range);
begin
attenuation_v := unsigned(attenuation_i);
-- volume look-up table
volume_v := to_signed(volume_c(to_integer(attenuation_v)),
product_o'length);
-- this replaces a multiplier and consumes a bit fewer
-- resources
case to_integer(factor_i) is
when +1 =>
product_o <= volume_v;
when -1 =>
product_o <= -volume_v;
when others =>
product_o <= (others => '0');
end case;
end process attenuate;
--
-----------------------------------------------------------------------------
product_o <= conv_std_logic_vector(volume_c(conv_integer(attenuation_i)), product_o'length) when factor_i = '1'
else (others => '0');
end rtl;

View File

@@ -45,7 +45,9 @@
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sn76489_clock_div is
@@ -68,7 +70,7 @@ use ieee.numeric_std.all;
architecture rtl of sn76489_clock_div is
signal cnt_s,
cnt_q : unsigned(3 downto 0);
cnt_q : std_logic_vector(3 downto 0);
begin
@@ -109,9 +111,9 @@ begin
clk_en_o <= true;
if clock_div_16_g = 1 then
cnt_s <= to_unsigned(15, cnt_q'length);
cnt_s <= conv_std_logic_vector(15, cnt_q'length);
elsif clock_div_16_g = 0 then
cnt_s <= to_unsigned( 1, cnt_q'length);
cnt_s <= conv_std_logic_vector( 1, cnt_q'length);
else
-- pragma translate_off
assert false

View File

@@ -75,6 +75,7 @@ architecture rtl of sn76489_latch_ctrl is
signal reg_q : std_logic_vector(0 to 2);
signal we_q : boolean;
signal ready_q : std_logic;
signal we_n_d : std_logic;
begin
@@ -92,6 +93,12 @@ begin
ready_q <= '0';
elsif clock_i'event and clock_i = '1' then
if clk_en_i then
we_n_d <= we_n_i;
elsif we_n_i = '1' then
we_n_d <= '1';
end if;
-- READY Flag Output ----------------------------------------------------
if ready_q = '0' and we_q then
if clk_en_i then
@@ -104,15 +111,15 @@ begin
end if;
-- Register Selection ---------------------------------------------------
if ce_n_i = '0' and we_n_i = '0' then
if clk_en_i then
if clk_en_i then
if ce_n_i = '0' and we_n_d = '1' and we_n_i = '0' then
if d_i(0) = '1' then
reg_q <= d_i(1 to 3);
end if;
we_q <= true;
else
we_q <= false;
end if;
else
we_q <= false;
end if;
end if;

View File

@@ -45,8 +45,9 @@
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sn76489_noise is
@@ -58,26 +59,25 @@ entity sn76489_noise is
d_i : in std_logic_vector(0 to 7);
r2_i : in std_logic;
tone3_ff_i : in std_logic;
noise_o : out signed(0 to 7)
noise_o : out std_logic_vector(0 to 7)
);
end sn76489_noise;
architecture rtl of sn76489_noise is
signal nf_q : std_logic_vector(0 to 1);
signal fb_q : std_logic;
signal a_q : std_logic_vector(0 to 3);
signal freq_cnt_q : unsigned(0 to 6);
signal freq_cnt_q : std_logic_vector(0 to 6);
signal freq_ff_q : std_logic;
signal shift_source_s,
shift_source_q : std_logic;
signal shift_rise_edge_s : boolean;
signal lfsr_q : std_logic_vector(0 to 15);
signal freq_s : signed(0 to 1);
signal lfsr_q : std_logic_vector(0 to 14);
begin
@@ -133,11 +133,11 @@ begin
-- reload frequency counter according to NF setting
case nf_q is
when "00" =>
freq_cnt_q <= to_unsigned(16 * 2 - 1, freq_cnt_q'length);
freq_cnt_q <= conv_std_logic_vector(16 * 2 - 1, freq_cnt_q'length);
when "01" =>
freq_cnt_q <= to_unsigned(16 * 4 - 1, freq_cnt_q'length);
freq_cnt_q <= conv_std_logic_vector(16 * 4 - 1, freq_cnt_q'length);
when "10" =>
freq_cnt_q <= to_unsigned(16 * 8 - 1, freq_cnt_q'length);
freq_cnt_q <= conv_std_logic_vector(16 * 8 - 1, freq_cnt_q'length);
when others =>
null;
end case;
@@ -202,9 +202,9 @@ begin
lfsr: process (clock_i, res_n_i)
function lfsr_tapped_f(lfsr : in std_logic_vector) return std_logic is
constant tapped_bits_c : std_logic_vector(0 to 15)
constant tapped_bits_c : std_logic_vector(0 to 14)
-- tapped bits are 0, 2, 15
:= "1010000000000001";
:= "110000000000000";
variable parity_v : std_logic;
begin
parity_v := '0';
@@ -253,17 +253,6 @@ begin
end if;
end if;
end process lfsr;
--
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Map output of LFSR to signed value for attenuator.
-----------------------------------------------------------------------------
freq_s <= to_signed(+1, 2)
when lfsr_q(0) = '1' else
to_signed( 0, 2);
-----------------------------------------------------------------------------
-- The attenuator itself
@@ -271,7 +260,7 @@ begin
attenuator_b : entity work.sn76489_attenuator
port map (
attenuation_i => a_q,
factor_i => freq_s,
factor_i => lfsr_q(0),
product_o => noise_o
);

View File

@@ -45,8 +45,9 @@
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sn76489_tone is
@@ -58,7 +59,7 @@ entity sn76489_tone is
d_i : in std_logic_vector(0 to 7);
r2_i : in std_logic;
ff_o : out std_logic;
tone_o : out signed(0 to 7)
tone_o : out std_logic_vector(0 to 7)
);
end sn76489_tone;
@@ -67,10 +68,9 @@ architecture rtl of sn76489_tone is
signal f_q : std_logic_vector(0 to 9);
signal a_q : std_logic_vector(0 to 3);
signal freq_cnt_q : unsigned(0 to 9);
signal freq_cnt_q : std_logic_vector(0 to 9);
signal freq_ff_q : std_logic;
signal freq_s : signed(0 to 1);
signal output_ff : std_logic;
function all_zero(a : in std_logic_vector) return boolean is
variable result_v : boolean;
@@ -134,21 +134,25 @@ begin
if res_n_i = '0' then
freq_cnt_q <= (others => '0');
freq_ff_q <= '0';
output_ff <= '0';
elsif clock_i'event and clock_i = '1' then
if clk_en_i then
if freq_cnt_q = 0 then
if freq_cnt_q = 1 then
-- update counter from frequency register
freq_cnt_q <= unsigned(f_q);
freq_cnt_q <= f_q;
-- and toggle the frequency flip-flop if enabled
if not all_zero(f_q) then
if (f_q > 5) then
freq_ff_q <= not freq_ff_q;
else
-- if frequency setting is 0, then keep flip-flop at +1
freq_ff_q <= '1';
end if;
-- either way toggle the output_ff - this is used to clock noise
output_ff <= not output_ff;
else
-- decrement frequency counter
freq_cnt_q <= freq_cnt_q - 1;
@@ -157,16 +161,6 @@ begin
end if;
end if;
end process freq_gen;
--
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Map frequency flip-flop to signed value for attenuator.
-----------------------------------------------------------------------------
freq_s <= to_signed(+1, 2)
when freq_ff_q = '1' else
to_signed(-1, 2);
-----------------------------------------------------------------------------
@@ -175,7 +169,7 @@ begin
attenuator_b : entity work.sn76489_attenuator
port map (
attenuation_i => a_q,
factor_i => freq_s,
factor_i => freq_ff_q,
product_o => tone_o
);
@@ -183,6 +177,6 @@ begin
-----------------------------------------------------------------------------
-- Output mapping
-----------------------------------------------------------------------------
ff_o <= freq_ff_q;
ff_o <= output_ff;
end rtl;

View File

@@ -56,11 +56,9 @@
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library ieee;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sn76489_top is
@@ -75,11 +73,15 @@ entity sn76489_top is
we_n_i : in std_logic;
ready_o : out std_logic;
d_i : in std_logic_vector(0 to 7);
aout_o : out signed(0 to 7)
aout_o : out std_logic_vector(0 to 7)
);
end sn76489_top;
library ieee;
use ieee.numeric_std.all;
architecture struct of sn76489_top is
signal clk_en_s : boolean;
@@ -93,7 +95,7 @@ architecture struct of sn76489_top is
signal tone1_s,
tone2_s,
tone3_s,
noise_s : signed(0 to 7);
noise_s : std_logic_vector(0 to 7);
signal tone3_ff_s : std_logic;