X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=cpu%2Fsrc%2Fdecode_stage_b.vhd;h=4f6990148e2ba524e847b8435b519cfd8c50f9d7;hb=1968f329b10681b760faec9369aa893cd2af8d44;hp=28c04c35aaf5aa0353af073505d90f28ffba4476;hpb=5356e3e07b4c3f16d4f2494100e2c4e937cb0e5b;p=calu.git diff --git a/cpu/src/decode_stage_b.vhd b/cpu/src/decode_stage_b.vhd index 28c04c3..4f69901 100644 --- a/cpu/src/decode_stage_b.vhd +++ b/cpu/src/decode_stage_b.vhd @@ -1,3 +1,24 @@ +-- `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; @@ -8,13 +29,14 @@ use work.core_pkg.all; use work.common_pkg.all; - architecture behav of decode_stage is signal instr_spl : instruction_rec; signal rtw_rec, rtw_rec_nxt : read_through_write_rec; -signal reg1_mem_data, reg2_mem_data : gp_register_t; +signal reg1_mem_data, reg2_mem_data, reg1_rd_data, reg2_rd_data : gp_register_t; +signal dec_op_inst, dec_op_inst_nxt : dec_op; + begin @@ -53,53 +75,133 @@ begin rtw_rec.rtw_reg <= (others => '0'); rtw_rec.rtw_reg1 <= '0'; rtw_rec.rtw_reg2 <= '0'; + rtw_rec.immediate <= (others => '0'); + rtw_rec.imm_set <= '0'; + + dec_op_inst.condition <= (others => '1'); + dec_op_inst.op_detail <= (others => '0'); + dec_op_inst.op_group <= ADDSUB_OP; + dec_op_inst.brpr <= '0'; --branch_prediction_bit; + dec_op_inst.src1 <= (others => '0'); + dec_op_inst.src2 <= (others => '0'); + dec_op_inst.saddr1 <= (others => '0'); + dec_op_inst.saddr2 <= (others => '0'); + dec_op_inst.daddr <= (others => '0'); + dec_op_inst.displacement <= (others => '0'); + dec_op_inst.prog_cnt <= (others => '0'); + elsif rising_edge(clk) then rtw_rec <= rtw_rec_nxt; + dec_op_inst <= dec_op_inst_nxt; end if; end process; +-- type dec_op is record +-- condition : condition_t; +-- op_group : op_info_t; +-- op_detail : op_opt_t; +-- brpr : std_logic; +-- +-- src1 : gp_register_t; +-- src2 : gp_register_t; +-- +-- saddr1 : gp_addr_t; +-- saddr2 : gp_addr_t; +-- +-- daddr : gp_addr_t; +-- +-- end record; + +-- output logic incl. bypassing reg-file +output_next_stage: process(dec_op_inst, reg1_rd_data, reg2_rd_data, nop) + +begin + + to_next_stage <= dec_op_inst; + to_next_stage.src1 <= reg1_rd_data; + to_next_stage.src2 <= reg2_rd_data; + + if (nop = '1') then + to_next_stage.condition <= "1111"; + end if; + +end process; + + +-- fills output register +to_next: process(instr_spl, prog_cnt) + +begin + dec_op_inst_nxt.condition <= instr_spl.predicates; + dec_op_inst_nxt.op_detail <= instr_spl.op_detail; + dec_op_inst_nxt.brpr <= instr_spl.bp; --branch_prediction_bit; + dec_op_inst_nxt.src1 <= (others => '0'); + dec_op_inst_nxt.src2 <= (others => '0'); + dec_op_inst_nxt.saddr1 <= instr_spl.reg_src1_addr; + dec_op_inst_nxt.saddr2 <= instr_spl.reg_src2_addr; + dec_op_inst_nxt.daddr <= instr_spl.reg_dest_addr; --(others => '0'); + dec_op_inst_nxt.op_group <= instr_spl.op_group; + dec_op_inst_nxt.displacement <= instr_spl.displacement; + dec_op_inst_nxt.prog_cnt <= prog_cnt; + +end process; -- async process: decides between memory and read-through-write buffer on output -output: process(rtw_rec, reg1_mem_data, reg2_mem_data) +output: process(rtw_rec, rtw_rec_nxt, reg1_mem_data, reg2_mem_data) begin - if (rtw_rec.rtw_reg1 = '1') then + if ((rtw_rec.rtw_reg1) = '1') then reg1_rd_data <= rtw_rec.rtw_reg; else reg1_rd_data <= reg1_mem_data; end if; - if (rtw_rec.rtw_reg2 = '1') then + if ((rtw_rec.rtw_reg2) = '1') then reg2_rd_data <= rtw_rec.rtw_reg; else reg2_rd_data <= reg2_mem_data; end if; + + if (rtw_rec.imm_set = '1') then + reg2_rd_data <= rtw_rec.immediate; + end if; + end process; -- async process: checks forward condition -forward: process(instr_spl, reg_w_addr, reg_wr_data) +forward: process(instr_spl, reg_w_addr, reg_wr_data, reg_we) begin rtw_rec_nxt.rtw_reg <= reg_wr_data; rtw_rec_nxt.rtw_reg1 <= '0'; rtw_rec_nxt.rtw_reg2 <= '0'; + rtw_rec_nxt.immediate <= (others => '0'); + rtw_rec_nxt.imm_set <= '0'; +--- ???? wieso + rtw_rec_nxt.reg1_addr <= instr_spl.reg_src1_addr; + rtw_rec_nxt.reg2_addr <= instr_spl.reg_src2_addr; + + if (instr_spl.op_detail(IMM_OPT) = '1') then -- or instr_spl.op_group = LDST_OP + rtw_rec_nxt.immediate <= instr_spl.immediate; + rtw_rec_nxt.imm_set <= '1'; + end if; if (reg_w_addr = instr_spl.reg_src1_addr) then - rtw_rec_nxt.rtw_reg1 <= '1'; + rtw_rec_nxt.rtw_reg1 <= ('1' and reg_we); end if; if (reg_w_addr = instr_spl.reg_src2_addr) then - rtw_rec_nxt.rtw_reg2 <= '1'; + rtw_rec_nxt.rtw_reg2 <= ('1' and reg_we); end if; end process; -- async process: calculates branch prediction -br_pred: process(instr_spl) +br_pred: process(instr_spl, prog_cnt, reset) begin @@ -107,10 +209,18 @@ begin branch_prediction_bit <= '0'; if ((instr_spl.opcode = "10110" or instr_spl.opcode = "10111") and instr_spl.bp = '1') then - branch_prediction_res <= instr_spl.immediate; --both 32 bit + if instr_spl.int = '0' then + branch_prediction_res <= std_logic_vector(unsigned(instr_spl.immediate) + unsigned(prog_cnt)); --both 32 bit + else + branch_prediction_res <= instr_spl.immediate; + end if; branch_prediction_bit <= '1'; end if; + if reset = RESET_VALUE then + branch_prediction_bit <= '0'; + end if; + end process; end behav;