From d15d5f1bc65729081bd076a057634f8adfe1d5fb Mon Sep 17 00:00:00 2001 From: rs <> Date: Thu, 18 Sep 2025 23:27:51 -0500 Subject: [PATCH] Add host regs with SRL clock divider --- libraries/nexys2/host_regs_opt.vhd | 242 +++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 libraries/nexys2/host_regs_opt.vhd diff --git a/libraries/nexys2/host_regs_opt.vhd b/libraries/nexys2/host_regs_opt.vhd new file mode 100644 index 0000000..bd4059e --- /dev/null +++ b/libraries/nexys2/host_regs_opt.vhd @@ -0,0 +1,242 @@ +-------------------------------------------------------------------------------- +-- host_regs - host control register file for Nexys2 +-- +-- Intended to be used by "host_ctrl" entity +-------------------------------------------------------------------------------- +-- WISHBONE DATASHEET (Host-side) +-- +-- Wishbone specification used: Rev B.3 +-- Interface type: device +-- Port size: 8-bit +-- Operand sizes: 8-bit +-- Endianness: undefined (port size same as granularity) +-- Data transfer sequence: undefined +-- Clock constraints: none +-- Signals: +-- * rst_i +-- * clk_i +-- * h_cyc_i (CYC_I) +-- * h_stb_i (STB_I) +-- * h_we_i (WE_I) +-- * h_ack_o (ACK_O) +-- * h_adr_i (ADR_I, 3-bit) +-- * h_dat_i (DAT_I, 8-bit) +-- * h_dat_o (DAT_O, 8-bit) +-------------------------------------------------------------------------------- +-- WISHBONE DATASHEET (Device-side) +-- +-- Wishbone specification used: Rev B.3 +-- Interface type: device +-- Port size: 8-bit +-- Operand sizes: 8-bit +-- Endianness: undefined (port size same as granularity) +-- Data transfer sequence: undefined +-- Clock constraints: none +-- Signals: +-- * rst_i +-- * clk_i +-- * d_cyc_i (CYC_I) +-- * d_stb_i (STB_I) +-- * d_we_i (WE_I) +-- * d_ack_o (ACK_O) +-- * d_adr_i (ADR_I, 3-bit) +-- * d_dat_i (DAT_I, 8-bit) +-- * d_dat_o (DAT_O, 8-bit) +-------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library unisim; +use unisim.vcomponents.all; + +library work; + + +entity host_regs_opt is + port ( + rst_i: in std_logic; + clk_i: in std_logic; + + h_cyc_i: in std_logic; + h_stb_i: in std_logic; + h_we_i: in std_logic; + h_ack_o: out std_logic; + h_adr_i: in std_logic_vector(2 downto 0); + h_dat_i: in std_logic_vector(7 downto 0); + h_dat_o: out std_logic_vector(7 downto 0); + + d_cyc_i: in std_logic; + d_stb_i: in std_logic; + d_we_i: in std_logic; + d_ack_o: out std_logic; + d_adr_i: in std_logic_vector(2 downto 0); + d_dat_i: in std_logic_vector(7 downto 0); + d_dat_o: out std_logic_vector(7 downto 0); + + ctrl: out std_logic_vector(7 downto 0); + flags: out std_logic_vector(7 downto 0); + seg: out std_logic_vector(6 downto 0); + dp: out std_logic; + an: out std_logic_vector(3 downto 0); + Led: out std_logic_vector(7 downto 0); + sw: in std_logic_vector(7 downto 0) + ); +end host_regs_opt; + + +architecture behavioral of host_regs_opt is + + type byte_array is array(natural range <>) of std_logic_vector(7 downto 0); + + signal regs: byte_array(7 downto 0); + + --signal clk_div: unsigned(15 downto 0); + signal clk_div_0: std_logic; + signal clk_div_1: std_logic; + signal clk_div_2: std_logic; + signal clk_div_3: std_logic; + signal clk_div_1_ce: std_logic; + signal clk_div_2_ce: std_logic; + signal clk_div_3_ce: std_logic; + signal clk_div_tick: std_logic; + signal temp_an: std_logic_vector(3 downto 0); + +begin + + h_ack_o <= '1'; + h_dat_o <= sw when h_adr_i = "011" + else regs(to_integer(unsigned(h_adr_i))); + + d_ack_o <= '0' when h_cyc_i = '1' and h_we_i = '1' else '1'; + d_dat_o <= sw when d_adr_i = "011" + else regs(to_integer(unsigned(d_adr_i))); + + process (clk_i, rst_i, + h_cyc_i, h_stb_i, h_we_i, h_adr_i, h_dat_i, + d_cyc_i, d_stb_i, d_we_i, d_adr_i, d_dat_i, + sw) + begin + if rising_edge(clk_i) then + if rst_i = '1' then + -- Reset + regs(0) <= (7 => '1', others => '0'); + regs(1) <= (others => '0'); + regs(2) <= (others => '0'); + regs(3) <= (others => '0'); + regs(4) <= (others => '1'); + regs(5) <= (others => '1'); + regs(6) <= (others => '1'); + regs(7) <= (others => '1'); + else + if h_cyc_i = '1' and h_stb_i = '1' then + if h_we_i = '1' then + -- Host write + case h_adr_i is + when "001" => regs(1) <= regs(1) or h_dat_i; -- Register 1 is write-one-set + when others => regs(to_integer(unsigned(h_adr_i))) <= h_dat_i; + end case; + end if; + elsif d_cyc_i = '1' and d_stb_i = '1' then + if d_we_i = '1' then + -- Device write + case d_adr_i(2 downto 0) is + when "000" => null; -- Register 0 is read-only + when "001" => regs(1) <= regs(1) and not d_dat_i; -- Register 1 is write-one-clear + when others => regs(to_integer(unsigned(d_adr_i))) <= d_dat_i; + end case; + end if; + end if; + end if; + end if; + end process; + + ctrl <= regs(0); + flags <= regs(1); + + -- LEDs + Led <= regs(3); + + e_clk_div_0: srl16 + generic map (INIT => x"0001") + port map ( + clk => clk_i, + a0 => '1', + a1 => '1', + a2 => '1', + a3 => '1', + d => clk_div_0, + q => clk_div_0 + ); + + clk_div_1_ce <= clk_div_0; + e_clk_div_1: srl16e + generic map (INIT => x"0001") + port map ( + clk => clk_i, + ce => clk_div_1_ce, + a0 => '1', + a1 => '1', + a2 => '1', + a3 => '1', + d => clk_div_1, + q => clk_div_1 + ); + + clk_div_2_ce <= clk_div_1 and clk_div_0; + e_clk_div_2: srl16e + generic map (INIT => x"0001") + port map ( + clk => clk_i, + ce => clk_div_2_ce, + a0 => '1', + a1 => '1', + a2 => '1', + a3 => '1', + d => clk_div_2, + q => clk_div_2 + ); + + clk_div_3_ce <= clk_div_2 and clk_div_1 and clk_div_0; + e_clk_div_3: srl16e + generic map (INIT => x"0001") + port map ( + clk => clk_i, + ce => clk_div_3_ce, + a0 => '1', + a1 => '1', + a2 => '1', + a3 => '1', + d => clk_div_3, + q => clk_div_3 + ); + + clk_div_tick <= clk_div_3 and clk_div_2 and clk_div_1 and clk_div_0;--clk_div_3_ce; + + --process (clk_i, clk_div) + --begin + -- if rising_edge(clk_i) then + -- clk_div <= clk_div + 1; + -- end if; + --end process; + + temp_an <= regs(7)(7) & regs(6)(7) & regs(5)(7) & regs(4)(7); + + e_seven_seg_mux: entity work.seven_seg_mux + port map ( + clk_in => clk_i, + clk_en => clk_div_tick, + + seg_0_in => regs(4)(6 downto 0), + seg_1_in => regs(5)(6 downto 0), + seg_2_in => regs(6)(6 downto 0), + seg_3_in => regs(7)(6 downto 0), + dps_in => temp_an, + + seg_out => seg, + dp_out => dp, + an_out => an + ); + +end behavioral; -- 2.43.0