-------------------------------------------------------------------------- -- Project: JCPU, a portable 8-bit RISC CPU written in VHDL -- This file: On-Chip registers -- -- Copyright (C) 2007 J. Ahrensfeld -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -- -- For questions and ideas, please contact the author at jens@jayfield.org -- -------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.ALL; use work.cpu_pkg.all; entity chipreg is Port ( rst : in STD_LOGIC; clk : in STD_LOGIC; we : in STD_LOGIC; addr : in dmem_addr_t; din : in dmem_data_t; dout : out dmem_data_t; ctrl_in : in creg_ctrl_in_t; ctrl_out : out creg_ctrl_out_t ); end chipreg; architecture Behavioral of chipreg is signal reg_bank_sel : bank_sel_t; signal reg_int_ctrl : int_ctrl_in_t; signal reg_stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0); signal reg_cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0); begin proc_assign_ctrl_lines: process (clk) begin if rising_edge(clk) then ctrl_out.bank_sel <= reg_bank_sel; ctrl_out.int_ctrl <= reg_int_ctrl; ctrl_out.stk_high <= reg_stk_high; ctrl_out.cmem_high <= reg_cmem_high; end if; end process; proc_reg_write: process (rst, clk) begin if rst = '1' then reg_stk_high <= (others => '0'); reg_cmem_high <= (others => '0'); reg_bank_sel <= (others => '0'); reg_int_ctrl.enable <= '0'; elsif rising_edge(clk) then if we = '1' then case addr is when X"01" => reg_bank_sel(bank_sel_t'range) <= din(bank_sel_t'range); when X"03" => reg_int_ctrl.enable <= din(0); when X"04" => reg_cmem_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0); when X"05" => reg_stk_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0); when others => null; end case; end if; end if; end process; proc_reg_read: process (clk) begin if rising_edge(clk) then case addr is when X"00" => -- Revison dout <= to_unsigned(REVISION, dmem_data_t'length); when X"01" => -- Control 0 dout <= (7 downto bank_sel_t'length => '0') & reg_bank_sel; when X"02" => -- CPU status dout <= "000000" & ctrl_in.alu.carry & ctrl_in.alu.zero; when X"03" => -- Interrupt control dout <= "0000000" & reg_int_ctrl.enable; when X"04" => -- Upper stack bits out dout <= "0000" & reg_cmem_high; when X"05" => -- Upper cmem bits out dout <= "0000" & reg_stk_high; when others => if addr(0) = '0' then dout <= X"DE"; else dout <= X"AD"; end if; end case; end if; end process; end Behavioral;