--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The datapath controller
--
-- 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 <http://www.gnu.org/licenses/>.
--
-- 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 dpath_ctrl is
	Generic (
		use_rom		: boolean := true
	);
	Port (
		inst_in		: in  inst_t;
		iphase_in	: in  iphase_t;
		status_in	: in  cpu_status_t;
		ctrl_out	: out dpath_ctrl_out_t;
		idout		: out inst_addr_t;
		ddout		: out dmem_data_t
	);
end dpath_ctrl;

architecture Behavioral of dpath_ctrl is

	signal opcode : opcode_t;
	signal ctrl_lines : ctrl_lines_t;
	signal dbg_iname : instr_name_t;
	
begin

	idout <= inst_in(IMEM_ADDR_WIDTH-1 downto 0);
	ddout <= inst_in(REG_SIZE_BITS+DMEM_DATA_WIDTH-1 downto REG_SIZE_BITS);
	opcode <= inst_in(IMEM_DATA_WIDTH-1 downto IMEM_DATA_WIDTH-INST_OPCODE_WIDTH);

	ctrl_out.reg_a_ptr <= inst_in(reg_ptr_t'length-1 downto 0);
	ctrl_out.reg_b_ptr <= inst_in(2*(reg_ptr_t'length)-1 downto reg_ptr_t'length);
	ctrl_out.lines <= ctrl_lines;

	-- pragma translate_off
	dbg_iname <= instr_name_array(to_integer(opcode));
	-- pragma translate_on

gen_ctrl_rom:
if use_rom = true generate

	i_dec:
		process(opcode, iphase_in, status_in)
		constant rom_data : murom_t := gen_murom;
		variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
		begin
			addr := get_muromaddr(opcode, iphase_in, status_in);
			ctrl_lines <= rom_data(to_integer(addr));
		end process;
end generate;

gen_ctrl:
if use_rom = false generate
	i_dec:
		process (opcode, iphase_in, status_in)
		begin
			ctrl_lines <= idecoder(opcode, iphase_in, status_in);
		end process;
end generate;

end Behavioral;

