From 1575d4f53805f177474b5bb96daebede9b2dfb73 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Feb 2021 23:45:58 +0000 Subject: base --- de1/fpga-bbc-pq/master/sn76489-fixes.patch | 634 +++++++++++++++++++++++++++++ 1 file changed, 634 insertions(+) create mode 100644 de1/fpga-bbc-pq/master/sn76489-fixes.patch (limited to 'de1/fpga-bbc-pq/master/sn76489-fixes.patch') diff --git a/de1/fpga-bbc-pq/master/sn76489-fixes.patch b/de1/fpga-bbc-pq/master/sn76489-fixes.patch new file mode 100644 index 0000000..6566582 --- /dev/null +++ b/de1/fpga-bbc-pq/master/sn76489-fixes.patch @@ -0,0 +1,634 @@ +diff --git a/sn76489-1.0/sn76489_comp_pack-p.vhd b/sn76489-1.0/sn76489_comp_pack-p.vhd +index 06b12c8..c5fcc90 100644 +--- a/sn76489-1.0/sn76489_comp_pack-p.vhd ++++ b/sn76489-1.0/sn76489_comp_pack-p.vhd +@@ -27,9 +27,11 @@ package sn76489_comp_pack is + clock_i : in std_logic; + clk_en_i : in boolean; + res_n_i : in std_logic; +- we_i : in boolean; ++ we_i : in std_logic; + d_i : in std_logic_vector(0 to 7); +- r2_i : in std_logic; ++ addr_i : in std_logic_vector(0 to 1); ++ rst_a_i : in std_logic_vector(0 to 3); ++ rst_cnt_i: in std_logic_vector(0 to 9); + ff_o : out std_logic; + tone_o : out signed(0 to 7) + ); +@@ -40,31 +42,14 @@ package sn76489_comp_pack is + clock_i : in std_logic; + clk_en_i : in boolean; + res_n_i : in std_logic; +- we_i : in boolean; ++ we_i : in std_logic; + d_i : in std_logic_vector(0 to 7); +- r2_i : in std_logic; ++ addr_i : in std_logic_vector(0 to 1); + tone3_ff_i : in std_logic; + noise_o : out signed(0 to 7) + ); + end component; + +- component sn76489_latch_ctrl +- port ( +- clock_i : in std_logic; +- clk_en_i : in boolean; +- res_n_i : in std_logic; +- ce_n_i : in std_logic; +- we_n_i : in std_logic; +- d_i : in std_logic_vector(0 to 7); +- ready_o : out std_logic; +- tone1_we_o : out boolean; +- tone2_we_o : out boolean; +- tone3_we_o : out boolean; +- noise_we_o : out boolean; +- r2_o : out std_logic +- ); +- end component; +- + component sn76489_clock_div + generic ( + clock_div_16_g : integer := 1 +diff --git a/sn76489-1.0/sn76489_latch_ctrl-c.vhd b/sn76489-1.0/sn76489_latch_ctrl-c.vhd +deleted file mode 100644 +index abc09e0..0000000 +--- a/sn76489-1.0/sn76489_latch_ctrl-c.vhd ++++ /dev/null +@@ -1,14 +0,0 @@ +-------------------------------------------------------------------------------- +--- +--- Synthesizable model of TI's SN76489AN. +--- +--- $Id: sn76489_latch_ctrl-c.vhd,v 1.2 2005/10/10 22:12:38 arnim Exp $ +--- +-------------------------------------------------------------------------------- +- +-configuration sn76489_latch_ctrl_rtl_c0 of sn76489_latch_ctrl is +- +- for rtl +- end for; +- +-end sn76489_latch_ctrl_rtl_c0; +diff --git a/sn76489-1.0/sn76489_latch_ctrl.vhd b/sn76489-1.0/sn76489_latch_ctrl.vhd +deleted file mode 100644 +index 789720c..0000000 +--- a/sn76489-1.0/sn76489_latch_ctrl.vhd ++++ /dev/null +@@ -1,138 +0,0 @@ +-------------------------------------------------------------------------------- +--- +--- Synthesizable model of TI's SN76489AN. +--- +--- $Id: sn76489_latch_ctrl.vhd,v 1.6 2006/02/27 20:30:10 arnim Exp $ +--- +--- Latch Control Unit +--- +-------------------------------------------------------------------------------- +--- +--- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +--- +--- All rights reserved +--- +--- Redistribution and use in source and synthezised forms, with or without +--- modification, are permitted provided that the following conditions are met: +--- +--- Redistributions of source code must retain the above copyright notice, +--- this list of conditions and the following disclaimer. +--- +--- Redistributions in synthesized 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. +--- +--- Neither the name of the author nor the names of other contributors may +--- be used to endorse or promote products derived from this software 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 AUTHOR 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. +--- +--- Please report bugs to the author, but before you do so, please +--- make sure that this is not a derivative work and that +--- you have the latest version of this file. +--- +-------------------------------------------------------------------------------- +- +-library ieee; +-use ieee.std_logic_1164.all; +- +-entity sn76489_latch_ctrl is +- +- port ( +- clock_i : in std_logic; +- clk_en_i : in boolean; +- res_n_i : in std_logic; +- ce_n_i : in std_logic; +- we_n_i : in std_logic; +- d_i : in std_logic_vector(0 to 7); +- ready_o : out std_logic; +- tone1_we_o : out boolean; +- tone2_we_o : out boolean; +- tone3_we_o : out boolean; +- noise_we_o : out boolean; +- r2_o : out std_logic +- ); +- +-end sn76489_latch_ctrl; +- +- +-library ieee; +-use ieee.numeric_std.all; +- +-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; +- +-begin +- +- ----------------------------------------------------------------------------- +- -- Process seq +- -- +- -- Purpose: +- -- Implements the sequential elements. +- -- +- seq: process (clock_i, res_n_i) +- begin +- if res_n_i = '0' then +- reg_q <= (others => '0'); +- we_q <= false; +- ready_q <= '0'; +- +- elsif clock_i'event and clock_i = '1' then +- -- READY Flag Output ---------------------------------------------------- +- if ready_q = '0' and we_q then +- if clk_en_i then +- -- assert READY when write access happened +- ready_q <= '1'; +- end if; +- elsif ce_n_i = '1' then +- -- deassert READY when access has finished +- ready_q <= '0'; +- end if; +- +- -- Register Selection --------------------------------------------------- +- if ce_n_i = '0' and we_n_i = '0' then +- if clk_en_i then +- if d_i(0) = '1' then +- reg_q <= d_i(1 to 3); +- end if; +- we_q <= true; +- end if; +- else +- we_q <= false; +- end if; +- +- end if; +- end process seq; +- -- +- ----------------------------------------------------------------------------- +- +- +- ----------------------------------------------------------------------------- +- -- Output mapping +- ----------------------------------------------------------------------------- +- tone1_we_o <= reg_q(0 to 1) = "00" and we_q; +- tone2_we_o <= reg_q(0 to 1) = "01" and we_q; +- tone3_we_o <= reg_q(0 to 1) = "10" and we_q; +- noise_we_o <= reg_q(0 to 1) = "11" and we_q; +- +- r2_o <= reg_q(2); +- +- ready_o <= ready_q +- when ce_n_i = '0' else +- '1'; +- +-end rtl; +diff --git a/sn76489-1.0/sn76489_noise.vhd b/sn76489-1.0/sn76489_noise.vhd +index 8b2ee0e..035adab 100644 +--- a/sn76489-1.0/sn76489_noise.vhd ++++ b/sn76489-1.0/sn76489_noise.vhd +@@ -54,9 +54,9 @@ entity sn76489_noise is + clock_i : in std_logic; + clk_en_i : in boolean; + res_n_i : in std_logic; +- we_i : in boolean; ++ we_i : in std_logic; + d_i : in std_logic_vector(0 to 7); +- r2_i : in std_logic; ++ addr_i : in std_logic_vector(0 to 1); + tone3_ff_i : in std_logic; + noise_o : out signed(0 to 7) + ); +@@ -68,6 +68,9 @@ use work.sn76489_comp_pack.sn76489_attenuator; + + architecture rtl of sn76489_noise is + ++ signal selected : std_logic; ++ signal write_cr : std_logic; ++ + signal nf_q : std_logic_vector(0 to 1); + signal fb_q : std_logic; + signal a_q : std_logic_vector(0 to 3); +@@ -78,12 +81,13 @@ architecture rtl of sn76489_noise is + shift_source_q : std_logic; + signal shift_rise_edge_s : boolean; + +- signal lfsr_q : std_logic_vector(0 to 15); ++ signal lfsr_q : std_logic_vector(0 to 7); + + signal freq_s : signed(0 to 1); + + begin + ++ + ----------------------------------------------------------------------------- + -- Process cpu_regs + -- +@@ -96,22 +100,25 @@ begin + nf_q <= (others => '0'); + fb_q <= '0'; + a_q <= (others => '1'); +- +- elsif clock_i'event and clock_i = '1' then +- if clk_en_i and we_i then +- if r2_i = '0' then +- -- access to control register +- -- both access types can write to the control register! +- nf_q <= d_i(6 to 7); +- fb_q <= d_i(5); +- +- else +- -- access to attenuator register +- -- both access types can write to the attenuator register! +- a_q <= d_i(4 to 7); +- ++ elsif rising_edge(clock_i) and we_i = '1' then ++ if d_i(0) = '1' then ++ if d_i(1 to 2) = addr_i then ++ if d_i(3) = '0' then ++ selected<='1'; ++ nf_q <= d_i(6 to 7); ++ fb_q <= d_i(5); ++ else ++ selected <='0'; ++ a_q <= d_i(4 to 7); ++ end if; ++ else ++ selected <='0'; ++ end if; ++ elsif selected = '1' then ++ selected<='0'; ++ nf_q <= d_i(6 to 7); ++ fb_q <= d_i(5); + end if; +- end if; + end if; + end process cpu_regs; + -- +@@ -130,8 +137,7 @@ begin + freq_cnt_q <= (others => '0'); + freq_ff_q <= '0'; + +- elsif clock_i'event and clock_i = '1' then +- if clk_en_i then ++ elsif rising_edge(clock_i) and clk_en_i then + if freq_cnt_q = 0 then + -- reload frequency counter according to NF setting + case nf_q is +@@ -152,8 +158,6 @@ begin + freq_cnt_q <= freq_cnt_q - 1; + + end if; +- +- end if; + end if; + end process freq_gen; + -- +@@ -191,6 +195,8 @@ begin + shift_rise_edge_s <= shift_source_q = '0' and shift_source_s = '1'; + + ++ write_cr <= '1' when ((we_i='1') and (((d_i(0) = '1') and (d_i(1 to 2) = addr_i) and (d_i(3) = '0')) or (selected='1'))) else '0'; ++ + ----------------------------------------------------------------------------- + -- Process lfsr + -- +@@ -219,15 +225,15 @@ begin + return parity_v; + end; + ++ + begin + if res_n_i = '0' then + -- reset LFSR to "0000000000000001" + lfsr_q <= (others => '0'); + lfsr_q(lfsr_q'right) <= '1'; + +- elsif clock_i'event and clock_i = '1' then +- if clk_en_i then +- if we_i and r2_i = '0' then ++ elsif rising_edge(clock_i) and clk_en_i then ++ if write_cr='1' then + -- write to noise register + -- -> reset LFSR + lfsr_q <= (others => '0'); +@@ -253,7 +259,6 @@ begin + + end if; + +- end if; + end if; + end process lfsr; + -- +diff --git a/sn76489-1.0/sn76489_tone.vhd b/sn76489-1.0/sn76489_tone.vhd +index b71af8b..f1b6885 100644 +--- a/sn76489-1.0/sn76489_tone.vhd ++++ b/sn76489-1.0/sn76489_tone.vhd +@@ -54,9 +54,11 @@ entity sn76489_tone is + clock_i : in std_logic; + clk_en_i : in boolean; + res_n_i : in std_logic; +- we_i : in boolean; ++ we_i : in std_logic; + d_i : in std_logic_vector(0 to 7); +- r2_i : in std_logic; ++ addr_i : in std_logic_vector(0 to 1); ++ rst_a_i : in std_logic_vector(0 to 3); ++ rst_cnt_i: in std_logic_vector(0 to 9); + ff_o : out std_logic; + tone_o : out signed(0 to 7) + ); +@@ -68,6 +70,7 @@ use work.sn76489_comp_pack.sn76489_attenuator; + + architecture rtl of sn76489_tone is + ++ signal selected : std_logic; + 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); +@@ -75,6 +78,7 @@ architecture rtl of sn76489_tone is + + signal freq_s : signed(0 to 1); + ++ + function all_zero(a : in std_logic_vector) return boolean is + variable result_v : boolean; + begin +@@ -91,6 +95,8 @@ architecture rtl of sn76489_tone is + + begin + ++ ++ + ----------------------------------------------------------------------------- + -- Process cpu_regs + -- +@@ -99,27 +105,28 @@ begin + -- + cpu_regs: process (clock_i, res_n_i) + begin +- if res_n_i = '0' then +- f_q <= (others => '0'); +- a_q <= (others => '1'); +- +- elsif clock_i'event and clock_i = '1' then +- if clk_en_i and we_i then +- if r2_i = '0' then +- -- access to frequency register +- if d_i(0) = '0' then +- f_q(0 to 5) <= d_i(2 to 7); +- else +- f_q(6 to 9) <= d_i(4 to 7); +- end if; +- +- else +- -- access to attenuator register +- -- both access types can write to the attenuator register! +- a_q <= d_i(4 to 7); + ++ if res_n_i = '0' then ++ f_q <= (others => '1'); ++ a_q <= rst_a_i; ++ selected <='0'; ++ elsif rising_edge(clock_i) and we_i = '1' then ++ if d_i(0) = '1' then ++ if d_i(1 to 2) = addr_i then ++ if d_i(3) = '0' then ++ selected<='1'; ++ f_q(6 to 9) <= d_i(4 to 7); ++ else ++ selected <='0'; ++ a_q <= d_i(4 to 7); ++ end if; ++ else ++ selected <='0'; ++ end if; ++ elsif selected = '1' then ++ selected<='0'; ++ f_q(0 to 5) <= d_i(2 to 7); + end if; +- end if; + end if; + end process cpu_regs; + -- +@@ -135,17 +142,19 @@ begin + freq_gen: process (clock_i, res_n_i) + begin + if res_n_i = '0' then +- freq_cnt_q <= (others => '0'); ++ freq_cnt_q <= unsigned(rst_cnt_i); + freq_ff_q <= '0'; + +- elsif clock_i'event and clock_i = '1' then +- if clk_en_i then +- if freq_cnt_q = 0 then ++ elsif rising_edge(clock_i) and clk_en_i then ++ if we_i='1' and selected = '1' then ++ freq_cnt_q <= (others => '0'); ++ freq_ff_q <= '1'; ++ elsif freq_cnt_q = 0 then + -- update counter from frequency register +- freq_cnt_q <= unsigned(f_q); ++ freq_cnt_q <= unsigned(f_q)-to_unsigned(1,10); + + -- and toggle the frequency flip-flop if enabled +- if not all_zero(f_q) then ++ if unsigned(f_q) > to_unsigned(1,10) then + freq_ff_q <= not freq_ff_q; + else + -- if frequency setting is 0, then keep flip-flop at +1 +@@ -157,7 +166,6 @@ begin + freq_cnt_q <= freq_cnt_q - 1; + + end if; +- end if; + end if; + end process freq_gen; + -- +diff --git a/sn76489-1.0/sn76489_top-c.vhd b/sn76489-1.0/sn76489_top-c.vhd +index 8f709b9..55f3dfb 100644 +--- a/sn76489-1.0/sn76489_top-c.vhd ++++ b/sn76489-1.0/sn76489_top-c.vhd +@@ -14,10 +14,6 @@ configuration sn76489_top_struct_c0 of sn76489_top is + use configuration work.sn76489_clock_div_rtl_c0; + end for; + +- for latch_ctrl_b : sn76489_latch_ctrl +- use configuration work.sn76489_latch_ctrl_rtl_c0; +- end for; +- + for all : sn76489_tone + use configuration work.sn76489_tone_rtl_c0; + end for; +diff --git a/sn76489-1.0/sn76489_top.vhd b/sn76489-1.0/sn76489_top.vhd +index deb8170..2f6a01c 100644 +--- a/sn76489-1.0/sn76489_top.vhd ++++ b/sn76489-1.0/sn76489_top.vhd +@@ -86,19 +86,17 @@ architecture struct of sn76489_top is + + signal clk_en_s : boolean; + +- signal tone1_we_s, +- tone2_we_s, +- tone3_we_s, +- noise_we_s : boolean; +- signal r2_s : std_logic; +- + signal tone1_s, + tone2_s, + tone3_s, +- noise_s : signed(0 to 7); ++ noise_s : signed(0 to 15); + + signal tone3_ff_s : std_logic; + ++ signal dl : std_logic_vector(0 to 9); ++ ++ signal we : std_logic; ++ + begin + + ----------------------------------------------------------------------------- +@@ -116,26 +114,6 @@ begin + ); + + +- ----------------------------------------------------------------------------- +- -- Latch Control = CPU Interface +- ----------------------------------------------------------------------------- +- latch_ctrl_b : sn76489_latch_ctrl +- port map ( +- clock_i => clock_i, +- clk_en_i => clk_en_s, +- res_n_i => res_n_i, +- ce_n_i => ce_n_i, +- we_n_i => we_n_i, +- d_i => d_i, +- ready_o => ready_o, +- tone1_we_o => tone1_we_s, +- tone2_we_o => tone2_we_s, +- tone3_we_o => tone3_we_s, +- noise_we_o => noise_we_s, +- r2_o => r2_s +- ); +- +- + ----------------------------------------------------------------------------- + -- Tone Channel 1 + ----------------------------------------------------------------------------- +@@ -144,9 +122,11 @@ begin + clock_i => clock_i, + clk_en_i => clk_en_s, + res_n_i => res_n_i, +- we_i => tone1_we_s, ++ we_i => we, + d_i => d_i, +- r2_i => r2_s, ++ addr_i => "00", ++ rst_a_i => "0000", ++ rst_cnt_i=> "0000000000", + ff_o => open, + tone_o => tone1_s + ); +@@ -159,9 +139,11 @@ begin + clock_i => clock_i, + clk_en_i => clk_en_s, + res_n_i => res_n_i, +- we_i => tone2_we_s, ++ we_i => we, + d_i => d_i, +- r2_i => r2_s, ++ addr_i => "01", ++ rst_a_i => "1000", ++ rst_cnt_i=> "0000110100", + ff_o => open, + tone_o => tone2_s + ); +@@ -174,9 +156,11 @@ begin + clock_i => clock_i, + clk_en_i => clk_en_s, + res_n_i => res_n_i, +- we_i => tone3_we_s, ++ we_i => we, + d_i => d_i, +- r2_i => r2_s, ++ addr_i => "10", ++ rst_a_i => "1000", ++ rst_cnt_i=> "1100110100", + ff_o => tone3_ff_s, + tone_o => tone3_s + ); +@@ -189,14 +173,16 @@ begin + clock_i => clock_i, + clk_en_i => clk_en_s, + res_n_i => res_n_i, +- we_i => noise_we_s, ++ we_i => we, + d_i => d_i, +- r2_i => r2_s, ++ addr_i => "11", + tone3_ff_i => tone3_ff_s, + noise_o => noise_s + ); + + ++ we<= not(ce_n_i or we_n_i) when clk_en_s else '0'; ++ + -- Register output + process(clock_i) + begin +@@ -207,4 +193,23 @@ begin + end if; + end process; + ++ process(clock_i) ++ begin ++ if res_n_i = '0' then ++ dl<=(others => '0'); ++ elsif rising_edge(clock_i) then ++ if ce_n_i = '0' and we_n_i = '0' then ++ if d_i(0)='1' then ++ if d_i(3)='0' then ++ dl(6 to 9) <= d_i(4 to 7); ++ end if; ++ else ++ dl(0 to 5) <= d_i(2 to 7); ++ end if; ++ end if; ++ end if; ++ end process; ++ ++ ++ ready_o <= '1'; + end struct; -- cgit v1.2.3