]> git.the-white-hart.net Git - vhdl/commitdiff
Add host regs with SRL clock divider
authorrs <>
Fri, 19 Sep 2025 04:27:51 +0000 (23:27 -0500)
committerrs <>
Fri, 19 Sep 2025 04:27:51 +0000 (23:27 -0500)
libraries/nexys2/host_regs_opt.vhd [new file with mode: 0644]

diff --git a/libraries/nexys2/host_regs_opt.vhd b/libraries/nexys2/host_regs_opt.vhd
new file mode 100644 (file)
index 0000000..bd4059e
--- /dev/null
@@ -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;