X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=cpu%2Fsrc%2Ffetch_stage_b.vhd;h=59e5d9980c391138743a7e812940af2752cf6c2a;hb=1968f329b10681b760faec9369aa893cd2af8d44;hp=e774901a01dc6b93b514d15d9d6e707886ccc8fb;hpb=5356e3e07b4c3f16d4f2494100e2c4e937cb0e5b;p=calu.git diff --git a/cpu/src/fetch_stage_b.vhd b/cpu/src/fetch_stage_b.vhd index e774901..59e5d99 100644 --- a/cpu/src/fetch_stage_b.vhd +++ b/cpu/src/fetch_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; use IEEE.numeric_std.all; @@ -13,11 +34,12 @@ signal instr_r_addr : instruction_addr_t; signal instr_r_addr_nxt : instruction_addr_t; signal instr_we : std_logic; signal instr_wr_data : instruction_word_t; -signal instr_rd_data : instruction_word_t; +signal instr_rd_data_rom, instr_rd_data : instruction_word_t; +signal rom_ram, rom_ram_nxt : std_logic; begin - instruction_ram : r_w_ram + instruction_ram : r_w_ram --rom generic map ( PHYS_INSTR_ADDR_WIDTH, WORD_WIDTH @@ -25,12 +47,25 @@ begin port map ( clk, - instr_w_addr(PHYS_INSTR_ADDR_WIDTH-1 downto 0), + im_addr(PHYS_INSTR_ADDR_WIDTH-1 downto 0), instr_r_addr_nxt(PHYS_INSTR_ADDR_WIDTH-1 downto 0), - instr_we, - instr_wr_data, + new_im_data_in, + im_data, instr_rd_data ); + + instruction_rom : rom + generic map ( + ROM_INSTR_ADDR_WIDTH, + WORD_WIDTH + ) + + port map ( + clk, + instr_r_addr_nxt(ROM_INSTR_ADDR_WIDTH-1 downto 0), + instr_rd_data_rom + ); + syn: process(clk, reset) @@ -38,26 +73,80 @@ begin if (reset = RESET_VALUE) then instr_r_addr <= (others => '0'); + rom_ram <= ROM_USE; + led2 <= '0'; elsif rising_edge(clk) then instr_r_addr <= instr_r_addr_nxt; + rom_ram <= rom_ram_nxt; + led2 <= rom_ram; --rom_ram_nxt; end if; end process; -asyn: process(instr_r_addr, jump_result, prediction_result, branch_prediction_bit, alu_jump_bit, instr_rd_data) - +asyn: process(reset, s_reset, instr_r_addr, jump_result, prediction_result, branch_prediction_bit, alu_jump_bit, instr_rd_data, rom_ram, instr_rd_data_rom, int_req) +variable instr_pc : instruction_addr_t; begin + rom_ram_nxt <= rom_ram; + + case rom_ram is + when ROM_USE => + instruction <= instr_rd_data_rom; + when RAM_USE => + instruction <= instr_rd_data; + when others => + instruction <= x"F0000000"; + end case; + instr_pc := std_logic_vector(unsigned(instr_r_addr) + 1); + instr_r_addr_nxt <= instr_pc; + + if (instr_pc = x"0000007f" and rom_ram = ROM_USE) then + rom_ram_nxt <= RAM_USE; + instr_r_addr_nxt <= (others => '0'); + end if; - instruction <= instr_rd_data; - instr_r_addr_nxt <= std_logic_vector(unsigned(instr_r_addr) + 1); + if (reset = RESET_VALUE) then + instr_r_addr_nxt <= (others => '0'); + end if; - if (alu_jump_bit = LOGIC_ACT) then - instr_r_addr_nxt <= jump_result; + if (alu_jump_bit = LOGIC_ACT and int_req = IDLE) then + instr_r_addr_nxt <= jump_result; + instruction(31 downto 28) <= "1111"; elsif (branch_prediction_bit = LOGIC_ACT) then instr_r_addr_nxt <= prediction_result; end if; + case int_req is + when UART => + instruction(31 downto 0) <= (others => '0'); + instruction(31 downto 28) <= "1110"; + instruction(27 downto 23) <= "10110"; + instruction(PHYS_INSTR_ADDR_WIDTH + 7 - 1 downto 7) <= UART_INT_VECTOR; + instruction(6 downto 4) <= "001"; + instruction(3 downto 2) <= "01"; + instruction(1 downto 0) <= "10"; + +-- instr_r_addr_nxt <= instr_r_addr; + when others => null; + end case; + + if (s_reset = RESET_VALUE) then + rom_ram_nxt <= RAM_USE; + instr_r_addr_nxt <= (others => '0'); + end if; + +end process; + +out_logic : process (instr_r_addr, alu_jump_bit, int_req, jump_result) + +begin + prog_cnt(PHYS_INSTR_ADDR_WIDTH-1 downto 0) <= std_logic_vector(unsigned(instr_r_addr(PHYS_INSTR_ADDR_WIDTH-1 downto 0))); + prog_cnt(INSTR_ADDR_WIDTH-1 downto PHYS_INSTR_ADDR_WIDTH) <= (others => '0'); + + if (int_req /= IDLE and alu_jump_bit = LOGIC_ACT ) then + prog_cnt(PHYS_INSTR_ADDR_WIDTH-1 downto 0) <= jump_result(PHYS_INSTR_ADDR_WIDTH-1 downto 0); + end if; + end process; end behav;