-- `Deep Thought', a softcore CPU implemented on a FPGA -- -- Copyright (C) 2010 Markus Hofstaetter -- Copyright (C) 2010 Martin Perner -- Copyright (C) 2010 Stefan Rebernig -- Copyright (C) 2010 Manfred Schwarz -- Copyright (C) 2010 Bernhard Urban -- -- 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 . library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use work.common_pkg.all; use work.alu_pkg.all; --use work.gpm_pkg.all; use work.extension_pkg.all; architecture behav of execute_stage is signal condition : condition_t; signal op_group : op_info_t; signal op_detail : op_opt_t; signal left_operand, right_operand : gp_register_t; signal alu_state, alu_nxt : alu_result_rec; signal psw : status_rec; -- extension signals signal ext_gpmp : extmod_rec; signal data_out : gp_register_t; signal pval, pval_nxt : gp_register_t; signal paddr : paddr_t; signal pinc, pwr_en : std_logic; type exec_internal is record result : gp_register_t; res_addr : gp_addr_t; alu_jump : std_logic; brpr : std_logic; wr_en : std_logic; end record; signal reg, reg_nxt : exec_internal; begin alu_inst : alu port map(clk, reset, condition, op_group, left_operand, right_operand, dec_instr.displacement, dec_instr.prog_cnt, dec_instr.brpr, op_detail, alu_state, pval, pval_nxt, alu_nxt,addr,data, pinc, pwr_en, paddr); gpmp_inst : extension_gpm generic map (RESET_VALUE) port map ( clk, reset, ext_gpmp, ext_data_out, alu_nxt.status, paddr, pinc, pwr_en, psw, pval, pval_nxt ); syn: process(clk, reset) begin if reset = RESET_VALUE then reg.alu_jump <= '0'; reg.brpr <= '0'; reg.wr_en <= '0'; reg.result <= (others =>'0'); reg.res_addr <= (others => '0'); elsif rising_edge(clk) then reg <= reg_nxt; end if; end process; asyn: process(reset,dec_instr, alu_nxt, psw, reg,left_operand,right_operand) begin condition <= dec_instr.condition; op_group <= dec_instr.op_group; op_detail <= dec_instr.op_detail; alu_state <= (reg.result,dec_instr.daddr,psw,reg.alu_jump,reg.brpr,'0','0','0','0','0','0'); if reset = RESET_VALUE then condition <= COND_NEVER; else end if; reg_nxt.brpr <= alu_nxt.brpr; reg_nxt.alu_jump <= alu_nxt.alu_jump; reg_nxt.wr_en <= alu_nxt.reg_op; reg_nxt.result <= alu_nxt.result; reg_nxt.res_addr <= alu_nxt.result_addr; end process asyn; forward: process(regfile_val, reg_we, reg_addr, dec_instr) begin left_operand <= dec_instr.src1; right_operand <= dec_instr.src2; if reg_we = '1' then if dec_instr.saddr1 = reg_addr then left_operand <= regfile_val; end if; if (dec_instr.saddr2 = reg_addr) and (dec_instr.op_detail(IMM_OPT) = '0') then right_operand <= regfile_val; end if; end if; end process forward; result <= reg.result; result_addr <= reg.res_addr; alu_jump <= reg.alu_jump; brpr <= reg.brpr; wr_en <= reg.wr_en; dmem <= alu_nxt.mem_op; --dmem <= reg.result(4); dmem_write_en <= alu_nxt.mem_en; --dmem_write_en <= reg.result(0); --dmem_write_en <= '1'; hword <= alu_nxt.hw_op; --hword <= reg.result(1); byte_s <= alu_nxt.byte_op; --addr <= alu_nxt.result; --data <= right_operand; --byte_s <= reg.result(2); end behav;