OpenCores
URL https://opencores.org/ocsvn/marca/marca/trunk

Subversion Repositories marca

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /marca/tags/INITIAL/vhdl
    from Rev 3 to Rev 8
    Reverse comparison

Rev 3 → Rev 8

/fetch_ent.vhd
0,0 → 1,51
-- This file is part of the marca processor.
-- Copyright (C) 2007 Wolfgang Puffitsch
 
-- This program is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Library General Public License as published
-- by the Free Software Foundation; either version 2, 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
-- Library General Public License for more details.
 
-- You should have received a copy of the GNU Library General Public
-- License along with this program; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 
-------------------------------------------------------------------------------
-- MARCA fetch stage
-------------------------------------------------------------------------------
-- entity definition for the instruction-fetch pipeline stage
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- Wolfgang Puffitsch
-- Computer Architecture Lab, Group 3
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
 
use work.marca_pkg.all;
 
entity fetch is
port (
clock : in std_logic;
reset : in std_logic;
 
hold : in std_logic;
pcena : in std_logic;
pc_in : in std_logic_vector(REG_WIDTH-1 downto 0);
pc_out : out std_logic_vector(REG_WIDTH-1 downto 0);
 
src1 : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
src2 : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
dest : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
instr : out std_logic_vector(PDATA_WIDTH-1 downto 0));
 
end fetch;
/data_memory.vhd
0,0 → 1,182
-- megafunction wizard: %RAM: 1-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
 
-- ============================================================
-- File Name: data_memory.vhd
-- Megafunction Name(s):
-- altsyncram
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 6.0 Build 202 06/20/2006 SP 1 SJ Web Edition
-- ************************************************************
 
 
--Copyright (C) 1991-2006 Altera Corporation
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, Altera MegaCore Function License
--Agreement, or other applicable license agreement, including,
--without limitation, that your use is for the sole purpose of
--programming logic devices manufactured by Altera and sold by
--Altera or its authorized distributors. Please refer to the
--applicable agreement for further details.
 
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
 
LIBRARY altera_mf;
USE altera_mf.all;
 
ENTITY data_memory IS
PORT
(
address : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
clken : IN STD_LOGIC ;
clock : IN STD_LOGIC ;
data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
wren : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END data_memory;
 
 
ARCHITECTURE SYN OF data_memory IS
 
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
 
 
 
COMPONENT altsyncram
GENERIC (
address_aclr_a : STRING;
indata_aclr_a : STRING;
intended_device_family : STRING;
lpm_hint : STRING;
lpm_type : STRING;
numwords_a : NATURAL;
operation_mode : STRING;
outdata_aclr_a : STRING;
outdata_reg_a : STRING;
power_up_uninitialized : STRING;
widthad_a : NATURAL;
width_a : NATURAL;
width_byteena_a : NATURAL;
wrcontrol_aclr_a : STRING
);
PORT (
clocken0 : IN STD_LOGIC ;
wren_a : IN STD_LOGIC ;
clock0 : IN STD_LOGIC ;
address_a : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END COMPONENT;
 
BEGIN
q <= sub_wire0(7 DOWNTO 0);
 
altsyncram_component : altsyncram
GENERIC MAP (
address_aclr_a => "NONE",
indata_aclr_a => "NONE",
intended_device_family => "Cyclone",
lpm_hint => "ENABLE_RUNTIME_MOD=NO",
lpm_type => "altsyncram",
numwords_a => 4096,
operation_mode => "SINGLE_PORT",
outdata_aclr_a => "NONE",
outdata_reg_a => "UNREGISTERED",
power_up_uninitialized => "FALSE",
widthad_a => 12,
width_a => 8,
width_byteena_a => 1,
wrcontrol_aclr_a => "NONE"
)
PORT MAP (
clocken0 => clken,
wren_a => wren,
clock0 => clock,
address_a => address,
data_a => data,
q_a => sub_wire0
);
 
 
 
END SYN;
 
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
-- Retrieval info: PRIVATE: AclrData NUMERIC "0"
-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clken NUMERIC "1"
-- Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING ""
-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "4096"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
-- Retrieval info: PRIVATE: RegData NUMERIC "1"
-- Retrieval info: PRIVATE: RegOutput NUMERIC "0"
-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "1"
-- Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0"
-- Retrieval info: PRIVATE: WidthAddr NUMERIC "12"
-- Retrieval info: PRIVATE: WidthData NUMERIC "8"
-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: INDATA_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "4096"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "12"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: CONSTANT: WRCONTROL_ACLR_A STRING "NONE"
-- Retrieval info: USED_PORT: address 0 0 12 0 INPUT NODEFVAL address[11..0]
-- Retrieval info: USED_PORT: clken 0 0 0 0 INPUT NODEFVAL clken
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
-- Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL data[7..0]
-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL wren
-- Retrieval info: CONNECT: @address_a 0 0 12 0 address 0 0 12 0
-- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: @clocken0 0 0 0 0 clken 0 0 0 0
-- Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: GEN_FILE: TYPE_NORMAL data_memory.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL data_memory.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL data_memory.cmp FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL data_memory.bsf TRUE FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL data_memory_inst.vhd FALSE
/code_memory.vhd
0,0 → 1,166
-- megafunction wizard: %ROM: 1-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
 
-- ============================================================
-- File Name: code_memory.vhd
-- Megafunction Name(s):
-- altsyncram
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 6.0 Build 202 06/20/2006 SP 1 SJ Web Edition
-- ************************************************************
 
 
--Copyright (C) 1991-2006 Altera Corporation
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, Altera MegaCore Function License
--Agreement, or other applicable license agreement, including,
--without limitation, that your use is for the sole purpose of
--programming logic devices manufactured by Altera and sold by
--Altera or its authorized distributors. Please refer to the
--applicable agreement for further details.
 
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
 
LIBRARY altera_mf;
USE altera_mf.all;
 
ENTITY code_memory IS
GENERIC
(
init_file : STRING
);
PORT
(
address : IN STD_LOGIC_VECTOR (12 DOWNTO 0);
clken : IN STD_LOGIC ;
clock : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
END code_memory;
 
 
ARCHITECTURE SYN OF code_memory IS
 
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (15 DOWNTO 0);
 
 
 
COMPONENT altsyncram
GENERIC (
address_aclr_a : STRING;
init_file : STRING;
intended_device_family : STRING;
lpm_hint : STRING;
lpm_type : STRING;
numwords_a : NATURAL;
operation_mode : STRING;
outdata_aclr_a : STRING;
outdata_reg_a : STRING;
widthad_a : NATURAL;
width_a : NATURAL;
width_byteena_a : NATURAL
);
PORT (
clocken0 : IN STD_LOGIC ;
clock0 : IN STD_LOGIC ;
address_a : IN STD_LOGIC_VECTOR (12 DOWNTO 0);
q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
END COMPONENT;
 
BEGIN
q <= sub_wire0(15 DOWNTO 0);
 
altsyncram_component : altsyncram
GENERIC MAP (
address_aclr_a => "NONE",
init_file => init_file,
intended_device_family => "Cyclone",
lpm_hint => "ENABLE_RUNTIME_MOD=NO",
lpm_type => "altsyncram",
numwords_a => 8192,
operation_mode => "ROM",
outdata_aclr_a => "NONE",
outdata_reg_a => "UNREGISTERED",
widthad_a => 13,
width_a => 16,
width_byteena_a => 1
)
PORT MAP (
clocken0 => clken,
clock0 => clock,
address_a => address,
q_a => sub_wire0
);
 
 
 
END SYN;
 
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "1"
-- Retrieval info: PRIVATE: Clken NUMERIC "1"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING "src/code.mif"
-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "8192"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
-- Retrieval info: PRIVATE: RegOutput NUMERIC "0"
-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0"
-- Retrieval info: PRIVATE: WidthAddr NUMERIC "13"
-- Retrieval info: PRIVATE: WidthData NUMERIC "16"
-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: INIT_FILE STRING "src/code.mif"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "8192"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "13"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "16"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: USED_PORT: address 0 0 12 0 INPUT NODEFVAL address[12..0]
-- Retrieval info: USED_PORT: clken 0 0 0 0 INPUT NODEFVAL clken
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
-- Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL q[15..0]
-- Retrieval info: CONNECT: @address_a 0 0 13 0 address 0 0 13 0
-- Retrieval info: CONNECT: q 0 0 16 0 @q_a 0 0 16 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: @clocken0 0 0 0 0 clken 0 0 0 0
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: GEN_FILE: TYPE_NORMAL code_memory.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL code_memory.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL code_memory.cmp FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL code_memory.bsf TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL code_memory_inst.vhd FALSE
/execute.vhd
0,0 → 1,291
-- This file is part of the marca processor.
-- Copyright (C) 2007 Wolfgang Puffitsch
 
-- This program is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Library General Public License as published
-- by the Free Software Foundation; either version 2, 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
-- Library General Public License for more details.
 
-- You should have received a copy of the GNU Library General Public
-- License along with this program; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 
-------------------------------------------------------------------------------
-- MARCA execution stage
-------------------------------------------------------------------------------
-- architecture of the execution pipeline stage
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- Wolfgang Puffitsch
-- Computer Architecture Lab, Group 3
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
use work.marca_pkg.all;
 
architecture behaviour of execute is
 
component alu is
port (
clock : in std_logic;
reset : in std_logic;
busy : out std_logic;
op : in ALU_OP;
a : in std_logic_vector(REG_WIDTH-1 downto 0);
b : in std_logic_vector(REG_WIDTH-1 downto 0);
i : in std_logic_vector(REG_WIDTH-1 downto 0);
pc : in std_logic_vector(REG_WIDTH-1 downto 0);
intr : in std_logic;
exc : out std_logic;
iena : out std_logic;
pcchg : out std_logic;
result : out std_logic_vector(REG_WIDTH-1 downto 0));
end component;
 
component mem is
port (
clock : in std_logic;
reset : in std_logic;
op : in MEM_OP;
address : in std_logic_vector(REG_WIDTH-1 downto 0);
data : in std_logic_vector(REG_WIDTH-1 downto 0);
exc : out std_logic;
busy : out std_logic;
result : out std_logic_vector(REG_WIDTH-1 downto 0);
intrs : out std_logic_vector(VEC_COUNT-1 downto 3);
ext_in : in std_logic_vector(IN_BITS-1 downto 0);
ext_out : out std_logic_vector(OUT_BITS-1 downto 0));
end component;
 
component intr is
port (
clock : in std_logic;
reset : in std_logic;
enable : in std_logic;
trigger : in std_logic_vector(VEC_COUNT-1 downto 1);
op : in INTR_OP;
a : in std_logic_vector(REG_WIDTH-1 downto 0);
i : in std_logic_vector(REG_WIDTH-1 downto 0);
pc : in std_logic_vector(REG_WIDTH-1 downto 0);
exc : out std_logic;
pcchg : out std_logic;
result : out std_logic_vector(REG_WIDTH-1 downto 0));
end component;
 
signal any_busy : std_logic;
 
signal alu_iena : std_logic;
signal alu_exc : std_logic;
signal alu_busy : std_logic;
signal alu_pcchg : std_logic;
signal alu_result : std_logic_vector(REG_WIDTH-1 downto 0);
 
signal mem_exc : std_logic;
signal mem_busy : std_logic;
signal mem_result : std_logic_vector(REG_WIDTH-1 downto 0);
signal mem_intrs : std_logic_vector(VEC_COUNT-1 downto 3);
 
signal intr_enable : std_logic;
signal intr_exc : std_logic;
signal intr_pcchg : std_logic;
signal intr_result : std_logic_vector(REG_WIDTH-1 downto 0);
 
signal pc_reg : std_logic_vector(REG_WIDTH-1 downto 0);
 
signal src1_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
signal src2_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
signal dest_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
 
signal op1_reg : std_logic_vector(REG_WIDTH-1 downto 0);
signal op2_reg : std_logic_vector(REG_WIDTH-1 downto 0);
signal imm_reg : std_logic_vector(REG_WIDTH-1 downto 0);
 
signal op1_fwed : std_logic_vector(REG_WIDTH-1 downto 0);
signal op2_fwed : std_logic_vector(REG_WIDTH-1 downto 0);
 
signal aop_reg : ALU_OP;
signal mop_reg : MEM_OP;
signal iop_reg : INTR_OP;
 
signal unit_reg : UNIT_SELECTOR;
signal target_reg : TARGET_SELECTOR;
 
signal stall_cnt : std_logic_vector(1 downto 0); -- prohibiting
signal next_stall_cnt : std_logic_vector(1 downto 0); -- interrupts during reti
 
begin -- behaviour
 
-- interrupts do not work while jumping
intr_enable <= alu_iena and zero(stall_cnt) and not any_busy;
alu_unit : alu
port map (
clock => clock,
reset => reset,
op => aop_reg,
a => op1_fwed,
b => op2_fwed,
i => imm_reg,
pc => pc_reg,
intr => intr_exc,
exc => alu_exc,
busy => alu_busy,
iena => alu_iena,
pcchg => alu_pcchg,
result => alu_result);
 
mem_unit : mem
port map (
clock => clock,
reset => reset,
op => mop_reg,
address => op2_fwed,
data => op1_fwed,
exc => mem_exc,
busy => mem_busy,
result => mem_result,
intrs => mem_intrs,
ext_in => ext_in,
ext_out => ext_out);
 
intr_unit : intr
port map (
clock => clock,
reset => reset,
enable => intr_enable,
trigger(EXC_ALU) => alu_exc,
trigger(EXC_MEM) => mem_exc,
trigger(VEC_COUNT-1 downto 3) => mem_intrs,
op => iop_reg,
a => op1_fwed,
i => imm_reg,
pc => pc_reg,
exc => intr_exc,
pcchg => intr_pcchg,
result => intr_result);
syn_proc: process (clock, reset)
begin -- process syn_proc
if reset = RESET_ACTIVE then -- asynchronous reset (active low)
stall_cnt <= (others => '0');
pc_reg <= (others => '0');
src1_reg <= (others => '0');
src2_reg <= (others => '0');
dest_reg <= (others => '0');
aop_reg <= ALU_NOP;
mop_reg <= MEM_NOP;
iop_reg <= INTR_NOP;
op1_reg <= (others => '0');
op2_reg <= (others => '0');
imm_reg <= (others => '0');
unit_reg <= UNIT_ALU;
target_reg <= TARGET_NONE;
elsif clock'event and clock = '1' then -- rising clock edge
if any_busy = '0' then
stall_cnt <= next_stall_cnt;
if stall = '1' then
pc_reg <= (others => '0');
src1_reg <= (others => '0');
src2_reg <= (others => '0');
dest_reg <= (others => '0');
aop_reg <= ALU_NOP;
mop_reg <= MEM_NOP;
iop_reg <= INTR_NOP;
op1_reg <= (others => '0');
op2_reg <= (others => '0');
imm_reg <= (others => '0');
unit_reg <= UNIT_ALU;
target_reg <= TARGET_NONE;
else
pc_reg <= pc_in;
dest_reg <= dest_in;
src1_reg <= src1;
src2_reg <= src2;
aop_reg <= aop;
mop_reg <= mop;
iop_reg <= iop;
op1_reg <= op1;
op2_reg <= op2;
imm_reg <= imm;
unit_reg <= unit;
target_reg <= target_in;
end if;
end if;
end if;
end process syn_proc;
 
stalling: process (stall, stall_cnt)
begin -- process hold_pc
next_stall_cnt <= std_logic_vector(unsigned(stall_cnt) - 1);
if zero(stall_cnt) = '1' then
next_stall_cnt <= "00";
end if;
if stall = '1' then
next_stall_cnt <= "11";
end if;
end process stalling;
business: process (any_busy, alu_busy, mem_busy)
begin -- process business
any_busy <= alu_busy or mem_busy;
busy <= any_busy;
end process business;
feedthrough: process (pc_reg, dest_reg, unit_reg, target_reg, op2_fwed, intr_exc)
begin -- process feedthrough
if unit_reg /= UNIT_CALL then
pc_out <= pc_reg;
else
pc_out <= op2_fwed;
end if;
dest_out <= dest_reg;
if intr_exc = '1' then
target_out <= TARGET_PC;
else
target_out <= target_reg;
end if;
end process feedthrough;
 
forward: process (src1_reg, src2_reg, op1_reg, op2_reg, fw_ena, fw_dest, fw_val)
begin -- process forward
op1_fwed <= op1_reg;
op2_fwed <= op2_reg;
if fw_ena = '1' then
if src1_reg = fw_dest then
op1_fwed <= fw_val;
end if;
if src2_reg = fw_dest then
op2_fwed <= fw_val;
end if;
end if;
end process forward;
select_result: process(unit_reg, alu_result, mem_result, intr_result, pc_reg,
alu_pcchg, intr_pcchg,
intr_exc)
begin -- process select_result
case unit_reg is
when UNIT_ALU => result <= alu_result;
when UNIT_MEM => result <= mem_result;
when UNIT_INTR => result <= intr_result;
when UNIT_CALL => result <= std_logic_vector(unsigned(pc_reg) + 1);
when others => null;
end case;
if intr_exc = '1' then
result <= intr_result;
end if;
pcchg <= alu_pcchg or intr_pcchg;
end process select_result;
end behaviour;
/marca.vht
0,0 → 1,492
-- Copyright (C) 1991-2006 Altera Corporation
-- Your use of Altera Corporation's design tools, logic functions
-- and other software and tools, and its AMPP partner logic
-- functions, and any output files any of the foregoing
-- (including device programming or simulation files), and any
-- associated documentation or information are expressly subject
-- to the terms and conditions of the Altera Program License
-- Subscription Agreement, Altera MegaCore Function License
-- Agreement, or other applicable license agreement, including,
-- without limitation, that your use is for the sole purpose of
-- programming logic devices manufactured by Altera and sold by
-- Altera or its authorized distributors. Please refer to the
-- applicable agreement for further details.
 
-- *****************************************************************************
-- This file contains a Vhdl test bench with test vectors .The test vectors
-- are exported from a vector file in the Quartus Waveform Editor and apply to
-- the top level entity of the current Quartus project .The user can use this
-- testbench to simulate his design using a third-party simulation tool .
-- *****************************************************************************
-- Generated on "12/14/2006 19:48:14"
-- Vhdl Self-Checking Test Bench (with test vectors) for design : marca
--
-- Simulation tool : 3rd Party
--
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
 
LIBRARY STD;
USE STD.textio.ALL;
 
PACKAGE marca_vhd_tb_types IS
-- input port types
SUBTYPE i1_type IS STD_LOGIC;
SUBTYPE i2_type IS STD_LOGIC_VECTOR(1 DOWNTO 0);
SUBTYPE i3_type IS STD_LOGIC;
-- output port types
SUBTYPE o1_type IS STD_LOGIC_VECTOR(1 DOWNTO 0);
-- output port names
CONSTANT o1_name : STRING (1 TO 7) := "ext_out";
-- n(outputs)
CONSTANT o_num : INTEGER := 1;
-- mismatches vector type
TYPE mmvec IS ARRAY (0 to (o_num - 1)) OF INTEGER;
-- exp o/ first change track vector type
TYPE trackvec IS ARRAY (1 to o_num) OF BIT;
-- sampler type
SUBTYPE sample_type IS STD_LOGIC;
-- utility functions
FUNCTION std_logic_to_char (a: STD_LOGIC) RETURN CHARACTER;
FUNCTION std_logic_vector_to_string (a: STD_LOGIC_VECTOR) RETURN STRING;
PROCEDURE write (l:INOUT LINE; value:IN STD_LOGIC; justified: IN SIDE:= RIGHT; field:IN WIDTH:=0);
PROCEDURE write (l:INOUT LINE; value:IN STD_LOGIC_VECTOR; justified: IN SIDE:= RIGHT; field:IN WIDTH:=0);
PROCEDURE throw_error(output_port_name: IN STRING; expected_value : IN STD_LOGIC; real_value : IN STD_LOGIC);
PROCEDURE throw_error(output_port_name: IN STRING; expected_value : IN STD_LOGIC_VECTOR; real_value : IN STD_LOGIC_VECTOR);
 
END marca_vhd_tb_types;
 
PACKAGE BODY marca_vhd_tb_types IS
FUNCTION std_logic_to_char (a: STD_LOGIC)
RETURN CHARACTER IS
BEGIN
CASE a IS
WHEN 'U' =>
RETURN 'U';
WHEN 'X' =>
RETURN 'X';
WHEN '0' =>
RETURN '0';
WHEN '1' =>
RETURN '1';
WHEN 'Z' =>
RETURN 'Z';
WHEN 'W' =>
RETURN 'W';
WHEN 'L' =>
RETURN 'L';
WHEN 'H' =>
RETURN 'H';
WHEN '-' =>
RETURN 'D';
END CASE;
END;
 
FUNCTION std_logic_vector_to_string (a: STD_LOGIC_VECTOR)
RETURN STRING IS
VARIABLE result : STRING(1 TO a'LENGTH);
VARIABLE j : NATURAL := 1;
BEGIN
FOR i IN a'RANGE LOOP
result(j) := std_logic_to_char(a(i));
j := j + 1;
END LOOP;
RETURN result;
END;
 
PROCEDURE write (l:INOUT LINE; value:IN STD_LOGIC; justified: IN SIDE:=RIGHT; field:IN WIDTH:=0) IS
BEGIN
write(L,std_logic_to_char(VALUE),JUSTIFIED,field);
END;
PROCEDURE write (l:INOUT LINE; value:IN STD_LOGIC_VECTOR; justified: IN SIDE:= RIGHT; field:IN WIDTH:=0) IS
BEGIN
write(L,std_logic_vector_to_string(VALUE),JUSTIFIED,field);
END;
 
PROCEDURE throw_error(output_port_name: IN STRING; expected_value : IN STD_LOGIC; real_value : IN STD_LOGIC) IS
VARIABLE txt : LINE;
BEGIN
write(txt,string'("ERROR! Vector Mismatch for output port "));
write(txt,output_port_name);
write(txt,string'(" :: @time = "));
write(txt,NOW);
write(txt,string'(", Expected value = "));
write(txt,expected_value);
write(txt,string'(", Real value = "));
write(txt,real_value);
writeline(output,txt);
END;
 
PROCEDURE throw_error(output_port_name: IN STRING; expected_value : IN STD_LOGIC_VECTOR; real_value : IN STD_LOGIC_VECTOR) IS
VARIABLE txt : LINE;
BEGIN
write(txt,string'("ERROR! Vector Mismatch for output port "));
write(txt,output_port_name);
write(txt,string'(" :: @time = "));
write(txt,NOW);
write(txt,string'(", Expected value = "));
write(txt,expected_value);
write(txt,string'(", Real value = "));
write(txt,real_value);
writeline(output,txt);
END;
 
END marca_vhd_tb_types;
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
 
USE WORK.marca_vhd_tb_types.ALL;
 
ENTITY marca_vhd_sample_tst IS
PORT (
s1 : IN i1_type;
s2 : IN i2_type;
s3 : IN i3_type;
sampler : OUT sample_type
);
END marca_vhd_sample_tst;
 
ARCHITECTURE sample_arch OF marca_vhd_sample_tst IS
SIGNAL clk : sample_type := '1';
BEGIN
t_prcs_sample : PROCESS ( s1 , s2 , s3 )
BEGIN
IF (NOW > 0 ps) AND (NOW < 850000000 ps) THEN
clk <= NOT clk ;
END IF;
END PROCESS t_prcs_sample;
sampler <= clk;
END sample_arch;
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
 
LIBRARY STD;
USE STD.textio.ALL;
 
USE WORK.marca_vhd_tb_types.ALL;
 
ENTITY marca_vhd_check_tst IS
GENERIC (
debug_tbench : BIT := '0'
);
PORT (
o1 : IN o1_type;
sampler : IN sample_type
);
END marca_vhd_check_tst;
ARCHITECTURE ovec_arch OF marca_vhd_check_tst IS
SIGNAL t_sig_o1_expected,t_sig_o1_expected_prev,t_sig_o1_prev : o1_type;
 
SIGNAL trigger : BIT := '0';
SIGNAL trigger_e : BIT := '0';
SIGNAL trigger_r : BIT := '0';
SIGNAL trigger_i : BIT := '0';
SIGNAL num_mismatches : mmvec := (OTHERS => 0);
 
BEGIN
 
-- Update history buffers expected /o
t_prcs_update_o_expected_hist : PROCESS (trigger)
BEGIN
t_sig_o1_expected_prev <= t_sig_o1_expected;
END PROCESS t_prcs_update_o_expected_hist;
 
 
-- Update history buffers real /o
t_prcs_update_o_real_hist : PROCESS (trigger)
BEGIN
t_sig_o1_prev <= o1;
END PROCESS t_prcs_update_o_real_hist;
 
 
-- expected ext_out[1]
t_prcs_ext_out_1: PROCESS
BEGIN
t_sig_o1_expected(1) <= '0';
WAIT FOR 93383521 ps;
t_sig_o1_expected(1) <= '1';
WAIT FOR 100000 ps;
t_sig_o1_expected(1) <= '0';
WAIT FOR 95600000 ps;
t_sig_o1_expected(1) <= '1';
WAIT FOR 100000 ps;
t_sig_o1_expected(1) <= '0';
WAIT FOR 95050000 ps;
t_sig_o1_expected(1) <= '1';
WAIT FOR 100000 ps;
t_sig_o1_expected(1) <= '0';
WAIT FOR 95600000 ps;
t_sig_o1_expected(1) <= '1';
WAIT FOR 100000 ps;
t_sig_o1_expected(1) <= '0';
WAIT;
END PROCESS t_prcs_ext_out_1;
-- expected ext_out[0]
t_prcs_ext_out_0: PROCESS
BEGIN
t_sig_o1_expected(0) <= '1';
WAIT FOR 387433530 ps;
t_sig_o1_expected(0) <= '0';
WAIT FOR 8800000 ps;
FOR i IN 1 TO 3
LOOP
t_sig_o1_expected(0) <= '1';
WAIT FOR 17600000 ps;
t_sig_o1_expected(0) <= '0';
WAIT FOR 17600000 ps;
END LOOP;
t_sig_o1_expected(0) <= '1';
WAIT FOR 8800000 ps;
FOR i IN 1 TO 2
LOOP
t_sig_o1_expected(0) <= '0';
WAIT FOR 17600000 ps;
t_sig_o1_expected(0) <= '1';
WAIT FOR 17600000 ps;
END LOOP;
t_sig_o1_expected(0) <= '0';
WAIT FOR 8800000 ps;
t_sig_o1_expected(0) <= '1';
WAIT FOR 8800000 ps;
t_sig_o1_expected(0) <= '0';
WAIT FOR 26400000 ps;
FOR i IN 1 TO 2
LOOP
t_sig_o1_expected(0) <= '1';
WAIT FOR 17600000 ps;
t_sig_o1_expected(0) <= '0';
WAIT FOR 17600000 ps;
END LOOP;
t_sig_o1_expected(0) <= '1';
WAIT FOR 8800000 ps;
t_sig_o1_expected(0) <= '0';
WAIT FOR 8800000 ps;
t_sig_o1_expected(0) <= '1';
WAIT FOR 8800000 ps;
t_sig_o1_expected(0) <= '0';
WAIT FOR 35200000 ps;
t_sig_o1_expected(0) <= '1';
WAIT;
END PROCESS t_prcs_ext_out_0;
 
-- Set trigger on real/expected o/ pattern changes
 
t_prcs_trigger_e : PROCESS(t_sig_o1_expected)
BEGIN
trigger_e <= NOT trigger_e;
END PROCESS t_prcs_trigger_e;
 
t_prcs_trigger_r : PROCESS(o1)
BEGIN
trigger_r <= NOT trigger_r;
END PROCESS t_prcs_trigger_r;
 
 
t_prcs_selfcheck : PROCESS
VARIABLE i : INTEGER := 1;
VARIABLE txt : LINE;
 
VARIABLE last_o1_exp : o1_type := (OTHERS => 'U');
 
VARIABLE on_first_change : trackvec := "1";
BEGIN
 
WAIT UNTIL (sampler'LAST_VALUE = '1'OR sampler'LAST_VALUE = '0')
AND sampler'EVENT;
IF (debug_tbench = '1') THEN
write(txt,string'("Scanning pattern "));
write(txt,i);
writeline(output,txt);
write(txt,string'("| expected "));write(txt,o1_name);write(txt,string'(" = "));write(txt,t_sig_o1_expected_prev);
writeline(output,txt);
write(txt,string'("| real "));write(txt,o1_name);write(txt,string'(" = "));write(txt,t_sig_o1_prev);
writeline(output,txt);
i := i + 1;
END IF;
IF ( t_sig_o1_expected_prev /= "XX" ) AND (t_sig_o1_expected_prev /= "UU" ) AND (t_sig_o1_prev /= t_sig_o1_expected_prev) AND (
(t_sig_o1_expected_prev /= last_o1_exp) OR
(on_first_change(1) = '1')
) THEN
throw_error("ext_out",t_sig_o1_expected_prev,t_sig_o1_prev);
num_mismatches(0) <= num_mismatches(0) + 1;
on_first_change(1) := '0';
last_o1_exp := t_sig_o1_expected_prev;
END IF;
trigger_i <= NOT trigger_i;
END PROCESS t_prcs_selfcheck;
 
 
t_prcs_trigger_res : PROCESS(trigger_e,trigger_i,trigger_r)
BEGIN
trigger <= trigger_i XOR trigger_e XOR trigger_r;
END PROCESS t_prcs_trigger_res;
 
t_prcs_endsim : PROCESS
VARIABLE txt : LINE;
VARIABLE total_mismatches : INTEGER := 0;
BEGIN
WAIT FOR 850000000 ps;
total_mismatches := num_mismatches(0);
IF (total_mismatches = 0) THEN
write(txt,string'("Simulation passed !"));
writeline(output,txt);
ELSE
write(txt,total_mismatches);
write(txt,string'(" mismatched vectors : Simulation failed !"));
writeline(output,txt);
END IF;
WAIT;
END PROCESS t_prcs_endsim;
 
END ovec_arch;
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
 
LIBRARY STD;
USE STD.textio.ALL;
 
USE WORK.marca_vhd_tb_types.ALL;
 
ENTITY marca_vhd_vec_tst IS
END marca_vhd_vec_tst;
ARCHITECTURE marca_arch OF marca_vhd_vec_tst IS
-- constants
-- signals
SIGNAL t_sig_clock : STD_LOGIC;
SIGNAL t_sig_ext_in : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL t_sig_ext_out : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL t_sig_ext_reset : STD_LOGIC;
SIGNAL t_sig_sampler : sample_type;
 
COMPONENT marca
PORT (
clock : IN STD_LOGIC;
ext_in : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
ext_out : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
ext_reset : IN STD_LOGIC
);
END COMPONENT;
COMPONENT marca_vhd_check_tst
PORT (
o1 : IN o1_type;
sampler : IN sample_type
);
END COMPONENT;
COMPONENT marca_vhd_sample_tst
PORT (
s1 : IN i1_type;
s2 : IN i2_type;
s3 : IN i3_type;
sampler : OUT sample_type
);
END COMPONENT;
BEGIN
i1 : marca
PORT MAP (
-- list connections between master ports and signals
clock => t_sig_clock,
ext_in => t_sig_ext_in,
ext_out => t_sig_ext_out,
ext_reset => t_sig_ext_reset
);
 
-- clock
t_prcs_clock: PROCESS
BEGIN
LOOP
t_sig_clock <= '0';
WAIT FOR 25000 ps;
t_sig_clock <= '1';
WAIT FOR 25000 ps;
IF (NOW >= 850000000 ps) THEN WAIT; END IF;
END LOOP;
END PROCESS t_prcs_clock;
 
-- ext_reset
t_prcs_ext_reset: PROCESS
BEGIN
t_sig_ext_reset <= '0';
WAIT FOR 100000 ps;
t_sig_ext_reset <= '1';
WAIT;
END PROCESS t_prcs_ext_reset;
-- ext_in[1]
t_prcs_ext_in_1: PROCESS
BEGIN
t_sig_ext_in(1) <= '0';
WAIT;
END PROCESS t_prcs_ext_in_1;
-- ext_in[0]
t_prcs_ext_in_0: PROCESS
BEGIN
t_sig_ext_in(0) <= '1';
WAIT FOR 8680000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 8680000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 8680000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 26040000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 8680000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 8680000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 17360000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 8680000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 8680000 ps;
t_sig_ext_in(0) <= '1';
WAIT FOR 8680000 ps;
t_sig_ext_in(0) <= '0';
WAIT FOR 34720000 ps;
t_sig_ext_in(0) <= '1';
WAIT;
END PROCESS t_prcs_ext_in_0;
tb_sample : marca_vhd_sample_tst
PORT MAP (
s1 => t_sig_clock,
s2 => t_sig_ext_in,
s3 => t_sig_ext_reset,
sampler => t_sig_sampler
);
 
tb_out : marca_vhd_check_tst
PORT MAP (
o1 => t_sig_ext_out,
sampler => t_sig_sampler
);
END marca_arch;
/code.mif Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
code.mif Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: sc_pkg.vhd =================================================================== --- sc_pkg.vhd (nonexistent) +++ sc_pkg.vhd (revision 8) @@ -0,0 +1,91 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- Package SC +------------------------------------------------------------------------------- +-- definitions for the SimpCon interface +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.marca_pkg.all; + +package sc_pkg is + + ----------------------------------------------------------------------------- + -- general configuration + ----------------------------------------------------------------------------- + constant SC_ADDR_WIDTH : integer := 2; + constant SC_REG_WIDTH : integer := 16; + + ----------------------------------------------------------------------------- + -- where to access SimCon modules + ----------------------------------------------------------------------------- + constant SC_MIN_ADDR : std_logic_vector := "1111111111111000"; + constant SC_MAX_ADDR : std_logic_vector := "1111111111111111"; + + ----------------------------------------------------------------------------- + -- records for simpler interfacing + ----------------------------------------------------------------------------- + type SC_IN is record + address : std_logic_vector(SC_ADDR_WIDTH-1 downto 0); + wr : std_logic; + wr_data : std_logic_vector(SC_REG_WIDTH-1 downto 0); + rd : std_logic; + end record; + + constant SC_IN_NULL : SC_IN := ((others => '0'), '0', (others => '0'), '0'); + + type SC_OUT is record + rd_data : std_logic_vector(SC_REG_WIDTH-1 downto 0); + rdy_cnt : unsigned(1 downto 0); + end record; + + constant SC_OUT_NULL : SC_OUT := ((others => '0'), "00"); + + ----------------------------------------------------------------------------- + -- output bits + ----------------------------------------------------------------------------- + constant UART_TXD : integer := 0; + constant UART_NRTS : integer := 1; + + ----------------------------------------------------------------------------- + -- input bits + ----------------------------------------------------------------------------- + constant UART_RXD : integer := 0; + constant UART_NCTS : integer := 1; + + ----------------------------------------------------------------------------- + -- interrupt numbers, >= 3 + ----------------------------------------------------------------------------- + constant UART_INTR : integer := 3; + + ----------------------------------------------------------------------------- + -- UART configuration + ----------------------------------------------------------------------------- + constant UART_BASE_ADDR : std_logic_vector(REG_WIDTH-1 downto SC_ADDR_WIDTH+1) := "1111111111111"; + constant UART_BAUD_RATE : integer := 115200; + +end sc_pkg; Index: execute_ent.vhd =================================================================== --- execute_ent.vhd (nonexistent) +++ execute_ent.vhd (revision 8) @@ -0,0 +1,74 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA execution stage +------------------------------------------------------------------------------- +-- entity for the execution pipeline stage +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +entity execute is + + port ( + clock : in std_logic; + reset : in std_logic; + + busy : out std_logic; + stall : in std_logic; + + pc_in : in std_logic_vector(REG_WIDTH-1 downto 0); + pcchg : out std_logic; + pc_out : out std_logic_vector(REG_WIDTH-1 downto 0); + + dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + + src1 : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + src2 : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + + aop : in ALU_OP; + mop : in MEM_OP; + iop : in INTR_OP; + + op1 : in std_logic_vector(REG_WIDTH-1 downto 0); + op2 : in std_logic_vector(REG_WIDTH-1 downto 0); + imm : in std_logic_vector(REG_WIDTH-1 downto 0); + + unit : in UNIT_SELECTOR; + target_in : in TARGET_SELECTOR; + target_out : out TARGET_SELECTOR; + + result : out std_logic_vector(REG_WIDTH-1 downto 0); + + fw_ena : in std_logic; + fw_dest : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + fw_val : in std_logic_vector(REG_WIDTH-1 downto 0); + + ext_in : in std_logic_vector(IN_BITS-1 downto 0); + ext_out : out std_logic_vector(OUT_BITS-1 downto 0)); + +end execute; Index: writeback.vhd =================================================================== --- writeback.vhd (nonexistent) +++ writeback.vhd (revision 8) @@ -0,0 +1,93 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA write-back stage +------------------------------------------------------------------------------- +-- architecture of the write-back pipeline stage +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +architecture behaviour of writeback is + +signal pcchg_reg : std_logic; +signal pc_reg : std_logic_vector(REG_WIDTH-1 downto 0); +signal dest_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal result_reg : std_logic_vector(REG_WIDTH-1 downto 0); +signal target_reg : TARGET_SELECTOR; + +begin -- behaviour + + syn_proc: process (clock, reset) + begin -- process syn_proc + if reset = RESET_ACTIVE then -- asynchronous reset (active low) + pcchg_reg <= '0'; + pc_reg <= (others => '0'); + dest_reg <= (others => '0'); + result_reg <= (others => '0'); + target_reg <= TARGET_NONE; + elsif clock'event and clock = '1' then -- rising clock edge + if hold = '0' then + pcchg_reg <= pcchg; + pc_reg <= pc_in; + dest_reg <= dest_in; + target_reg <= target; + result_reg <= result; + end if; + end if; + end process syn_proc; + + dispatch: process (target_reg, pcchg_reg, pc_reg, result_reg, dest_reg) + begin -- process dispatch + + pcena <= '0'; + pc_out <= pc_reg; + + ena <= '0'; + dest_out <= dest_reg; + val <= result_reg; + + case target_reg is + + when TARGET_REGISTER => + ena <= '1'; + + when TARGET_PC => + if pcchg_reg = '1' then + pcena <= '1'; + pc_out <= result_reg; + end if; + + when TARGET_BOTH => + pcena <= '1'; + ena <= '1'; + + when others => null; + end case; + + end process dispatch; + +end behaviour; Index: intr.vhd =================================================================== --- intr.vhd (nonexistent) +++ intr.vhd (revision 8) @@ -0,0 +1,105 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA interrupt unit +------------------------------------------------------------------------------- +-- architecture for the interrupt unit +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.marca_pkg.all; + +architecture behaviour of intr is + +type vectors is array (VEC_COUNT-1 downto 0) of std_logic_vector(REG_WIDTH-1 downto 0); +signal vecs, next_vecs : vectors; + +signal ira, next_ira : std_logic_vector(REG_WIDTH-1 downto 0); + +begin -- behaviour + + syn_proc: process (clock, reset) + begin -- process syn_proc + if reset = RESET_ACTIVE then -- asynchronous reset (active low) + vecs <= (others => (others => '0')); + ira <= (others => '0'); + elsif clock'event and clock = '1' then -- rising clock edge + vecs <= next_vecs; + ira <= next_ira; + end if; + end process syn_proc; + + compute: process (op, a, i, pc, vecs, ira, enable, trigger) + begin -- process compute + + next_vecs <= vecs; + next_ira <= ira; + + exc <= '0'; + pcchg <= '0'; + result <= (others => '0'); + + case op is + when INTR_INTR => + if enable = '1' then + pcchg <= '1'; + result <= vecs(to_integer(unsigned(i))); + next_ira <= std_logic_vector(unsigned(pc) + 1); + end if; + when INTR_RETI => + pcchg <= '1'; + result <= ira; + when INTR_SETIRA => + next_ira <= a; + when INTR_GETIRA => + result <= ira; + when INTR_STVEC => + next_vecs(to_integer(unsigned(i))) <= a; + when INTR_LDVEC => + result <= vecs(to_integer(unsigned(i))); + when others => null; + end case; + + if enable = '1' then + for v in VEC_COUNT-1 downto 1 loop + if trigger(v) = '1' then + exc <= '1'; + pcchg <= '1'; + result <= vecs(v); + if v = EXC_ALU or v = EXC_MEM then + -- don't repeat division by zero and ill memory access + next_ira <= std_logic_vector(unsigned(pc) + 1); + else + -- repeat the instruction if interrupted + next_ira <= pc; + end if; + end if; + end loop; + end if; + + end process compute; + +end behaviour; Index: mem.vhd =================================================================== --- mem.vhd (nonexistent) +++ mem.vhd (revision 8) @@ -0,0 +1,485 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA fetch stage +------------------------------------------------------------------------------- +-- architecture for the instruction-fetch pipeline stage +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.marca_pkg.all; +use work.sc_pkg.all; + +architecture behaviour of mem is + +type WAIT_STATE is (WAIT_LOAD_EVEN, WAIT_LOAD_ODD, + WAIT_LOADL_EVEN, WAIT_LOADL_ODD, + WAIT_LOADH_EVEN, WAIT_LOADH_ODD, + WAIT_LOADB_EVEN, WAIT_LOADB_ODD, + WAIT_STORE, + WAIT_NONE); + +signal state : WAIT_STATE; +signal next_state : WAIT_STATE; + +signal old_data : std_logic_vector(REG_WIDTH-1 downto 0); +signal next_data : std_logic_vector(REG_WIDTH-1 downto 0); + +component data_memory + port ( + clken : in std_logic; + clock : in std_logic; + wren : in std_logic; + address : in std_logic_vector (ADDR_WIDTH-2 downto 0); + data : in std_logic_vector (DATA_WIDTH-1 downto 0); + q : out std_logic_vector (DATA_WIDTH-1 downto 0)); +end component; + +signal ram_enable : std_logic; + +signal wren0 : std_logic; +signal a0 : std_logic_vector(ADDR_WIDTH-2 downto 0); +signal d0 : std_logic_vector(DATA_WIDTH-1 downto 0); +signal q0 : std_logic_vector(DATA_WIDTH-1 downto 0); + +signal wren1 : std_logic; +signal a1 : std_logic_vector(ADDR_WIDTH-2 downto 0); +signal d1 : std_logic_vector(DATA_WIDTH-1 downto 0); +signal q1 : std_logic_vector(DATA_WIDTH-1 downto 0); + +component data_rom + generic ( + init_file : string); + port ( + clken : in std_logic; + clock : in std_logic; + address : in std_logic_vector (RADDR_WIDTH-2 downto 0); + q : out std_logic_vector (RDATA_WIDTH-1 downto 0)); +end component; + +signal rom_enable : std_logic; + +signal ra0 : std_logic_vector(RADDR_WIDTH-2 downto 0); +signal rq0 : std_logic_vector(RDATA_WIDTH-1 downto 0); + +signal ra1 : std_logic_vector(RADDR_WIDTH-2 downto 0); +signal rq1 : std_logic_vector(RDATA_WIDTH-1 downto 0); + + +signal sc_input : SC_IN; +signal sc_output : SC_OUT; + +component sc_uart + generic ( + clock_freq : integer; + baud_rate : integer; + txf_depth : integer; txf_thres : integer; + rxf_depth : integer; rxf_thres : integer); + port ( + clock : in std_logic; + reset : in std_logic; + input : in SC_IN; + output : out SC_OUT; + intr : out std_logic; + txd : out std_logic; + rxd : in std_logic; + nrts : out std_logic; + ncts : in std_logic); +end component; + +signal uart_input : SC_IN; +signal uart_output : SC_OUT; + +begin -- behaviour + + intrs(VEC_COUNT-1 downto 4) <= (others => '0'); + + data_memory_0_unit : data_memory + port map ( + clken => ram_enable, + clock => clock, + wren => wren0, + address => a0, + data => d0, + q => q0); + + data_memory_1_unit : data_memory + port map ( + clken => ram_enable, + clock => clock, + wren => wren1, + address => a1, + data => d1, + q => q1); + + data_rom_0_unit : data_rom + generic map ( + init_file => "../vhdl/rom0.mif") + port map ( + clken => rom_enable, + clock => clock, + address => ra0, + q => rq0); + + data_rom_1_unit : data_rom + generic map ( + init_file => "../vhdl/rom1.mif") + port map ( + clken => rom_enable, + clock => clock, + address => ra1, + q => rq1); + + uart_unit : sc_uart + generic map ( + clock_freq => CLOCK_FREQ, + baud_rate => UART_BAUD_RATE, + txf_depth => 2, txf_thres => 1, + rxf_depth => 2, rxf_thres => 1) + port map ( + clock => clock, + reset => reset, + input => uart_input, + output => uart_output, + intr => intrs(UART_INTR), + txd => ext_out(UART_TXD), + rxd => ext_in(UART_RXD), + nrts => ext_out(UART_NRTS), + ncts => ext_in(UART_NCTS)); + + syn_proc: process (clock, reset) + begin -- process syn_proc + if reset = RESET_ACTIVE then -- asynchronous reset (active low) + state <= WAIT_NONE; + old_data <= (others => '0'); + elsif clock'event and clock = '1' then -- rising clock edge + state <= next_state; + old_data <= next_data; + end if; + end process syn_proc; + + business: process (next_state) + begin -- process business + if next_state /= WAIT_NONE then + busy <= '1'; + else + busy <= '0'; + end if; + end process business; + + sc_mux: process (address, sc_input, + uart_output) + begin -- process sc_mux + + uart_input <= SC_IN_NULL; + sc_output <= SC_OUT_NULL; + + case address(REG_WIDTH-1 downto SC_ADDR_WIDTH+1) is + when UART_BASE_ADDR => + uart_input <= sc_input; + sc_output <= uart_output; + when others => null; + end case; + + end process sc_mux; + + readwrite: process (state, op, address, data, old_data, q0, q1, rq0, rq1, sc_output) + begin -- process readwrite + exc <= '0'; + + ram_enable <= '0'; + + wren0 <= '0'; + wren1 <= '0'; + + a0 <= (others => '0'); + d0 <= (others => '0'); + + a1 <= (others => '0'); + d1 <= (others => '0'); + + rom_enable <= '0'; + + ra0 <= (others => '0'); + ra1 <= (others => '0'); + + sc_input <= SC_IN_NULL; + + result <= (others => '0'); + + next_state <= WAIT_NONE; + next_data <= data; + + if unsigned(address) >= unsigned(MEM_MIN_ADDR) + and unsigned(address) <= unsigned(MEM_MAX_ADDR) then + + -- regular memory access + if op /= MEM_NOP then + ram_enable <= '1'; + end if; + + case state is + when WAIT_LOAD_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q1; + result(REG_WIDTH/2-1 downto 0) <= q0; + next_state <= WAIT_NONE; + + when WAIT_LOAD_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q0; + result(REG_WIDTH/2-1 downto 0) <= q1; + next_state <= WAIT_NONE; + + when WAIT_LOADL_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2); + result(REG_WIDTH/2-1 downto 0) <= q0; + next_state <= WAIT_NONE; + + when WAIT_LOADL_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2); + result(REG_WIDTH/2-1 downto 0) <= q1; + next_state <= WAIT_NONE; + + when WAIT_LOADH_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q0; + result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0); + next_state <= WAIT_NONE; + + when WAIT_LOADH_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q1; + result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0); + next_state <= WAIT_NONE; + + when WAIT_LOADB_EVEN => result <= std_logic_vector(resize(signed(q0), REG_WIDTH)); + next_state <= WAIT_NONE; + + when WAIT_LOADB_ODD => result <= std_logic_vector(resize(signed(q1), REG_WIDTH)); + next_state <= WAIT_NONE; + + when WAIT_NONE => + case op is + when MEM_LOAD => if address(0) = '0' then + a0 <= address(ADDR_WIDTH-1 downto 1); + a1 <= address(ADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOAD_EVEN; + else + a1 <= address(ADDR_WIDTH-1 downto 1); + a0 <= std_logic_vector(unsigned(address(ADDR_WIDTH-1 downto 1)) + 1); + next_state <= WAIT_LOAD_ODD; + end if; + when MEM_LOADL => if address(0) = '0' then + a0 <= address(ADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADL_EVEN; + else + a1 <= address(ADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADL_ODD; + end if; + when MEM_LOADH => if address(0) = '0' then + a0 <= address(ADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADH_EVEN; + else + a1 <= address(ADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADH_ODD; + end if; + when MEM_LOADB => if address(0) = '0' then + a0 <= address(ADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADB_EVEN; + else + a1 <= address(ADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADB_ODD; + end if; + when MEM_STORE => if address(0) = '0' then + wren0 <= '1'; + wren1 <= '1'; + a0 <= address(ADDR_WIDTH-1 downto 1); + a1 <= address(ADDR_WIDTH-1 downto 1); + d0 <= data(REG_WIDTH/2-1 downto 0); + d1 <= data(REG_WIDTH-1 downto REG_WIDTH/2); + next_state <= WAIT_NONE; + else + wren0 <= '1'; + wren1 <= '1'; + a1 <= address(ADDR_WIDTH-1 downto 1); + a0 <= std_logic_vector(unsigned(address(ADDR_WIDTH-1 downto 1)) + 1); + d1 <= data(REG_WIDTH/2-1 downto 0); + d0 <= data(REG_WIDTH-1 downto REG_WIDTH/2); + next_state <= WAIT_NONE; + end if; + when MEM_STOREL => if address(0) = '0' then + wren0 <= '1'; + a0 <= address(ADDR_WIDTH-1 downto 1); + d0 <= data(REG_WIDTH/2-1 downto 0); + next_state <= WAIT_NONE; + else + wren1 <= '1'; + a1 <= address(ADDR_WIDTH-1 downto 1); + d1 <= data(REG_WIDTH/2-1 downto 0); + next_state <= WAIT_NONE; + end if; + when MEM_STOREH => if address(0) = '0' then + wren0 <= '1'; + a0 <= address(ADDR_WIDTH-1 downto 1); + d0 <= data(REG_WIDTH-1 downto REG_WIDTH/2); + next_state <= WAIT_NONE; + else + wren1 <= '1'; + a1 <= address(ADDR_WIDTH-1 downto 1); + d1 <= data(REG_WIDTH-1 downto REG_WIDTH/2); + next_state <= WAIT_NONE; + end if; + when MEM_NOP => next_state <= WAIT_NONE; + when others => null; + end case; + when others => null; + end case; + + elsif unsigned(address) >= unsigned(ROM_MIN_ADDR) + and unsigned(address) <= unsigned(ROM_MAX_ADDR) then + + -- accessing the ROM + if op /= MEM_NOP then + rom_enable <= '1'; + end if; + + case state is + when WAIT_LOAD_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq1; + result(REG_WIDTH/2-1 downto 0) <= rq0; + next_state <= WAIT_NONE; + + when WAIT_LOAD_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq0; + result(REG_WIDTH/2-1 downto 0) <= rq1; + next_state <= WAIT_NONE; + + when WAIT_LOADL_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2); + result(REG_WIDTH/2-1 downto 0) <= rq0; + next_state <= WAIT_NONE; + + when WAIT_LOADL_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2); + result(REG_WIDTH/2-1 downto 0) <= rq1; + next_state <= WAIT_NONE; + + when WAIT_LOADH_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq0; + result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0); + next_state <= WAIT_NONE; + + when WAIT_LOADH_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq1; + result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0); + next_state <= WAIT_NONE; + + when WAIT_LOADB_EVEN => result <= std_logic_vector(resize(signed(rq0), REG_WIDTH)); + next_state <= WAIT_NONE; + + when WAIT_LOADB_ODD => result <= std_logic_vector(resize(signed(rq1), REG_WIDTH)); + next_state <= WAIT_NONE; + + when WAIT_NONE => + case op is + when MEM_LOAD => if address(0) = '0' then + ra0 <= address(RADDR_WIDTH-1 downto 1); + ra1 <= address(RADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOAD_EVEN; + else + ra1 <= address(RADDR_WIDTH-1 downto 1); + ra0 <= std_logic_vector(unsigned(address(RADDR_WIDTH-1 downto 1)) + 1); + next_state <= WAIT_LOAD_ODD; + end if; + when MEM_LOADL => if address(0) = '0' then + ra0 <= address(RADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADL_EVEN; + else + ra1 <= address(RADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADL_ODD; + end if; + when MEM_LOADH => if address(0) = '0' then + ra0 <= address(RADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADH_EVEN; + else + ra1 <= address(RADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADH_ODD; + end if; + when MEM_LOADB => if address(0) = '0' then + ra0 <= address(RADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADB_EVEN; + else + ra1 <= address(RADDR_WIDTH-1 downto 1); + next_state <= WAIT_LOADB_ODD; + end if; + when MEM_NOP => next_state <= WAIT_NONE; + when others => exc <= '1'; -- inhibit invalid operations + end case; + when others => null; + end case; + + elsif unsigned(address) >= unsigned(SC_MIN_ADDR) + and unsigned(address) <= unsigned(SC_MAX_ADDR) + and address(0) = '0' then + + -- access via SimpCon interface + case state is + + when WAIT_LOAD_EVEN => + if sc_output.rdy_cnt /= "00" then + next_state <= WAIT_LOAD_EVEN; + else + result <= sc_output.rd_data; + next_state <= WAIT_NONE; + end if; + + when WAIT_STORE => + if sc_output.rdy_cnt /= "00" then + next_state <= WAIT_STORE; + else + next_state <= WAIT_NONE; + end if; + + when WAIT_NONE => + case op is + + when MEM_LOAD => + sc_input.address <= address(SC_ADDR_WIDTH downto 1); + sc_input.wr <= '0'; + sc_input.wr_data <= (others => '0'); + sc_input.rd <= '1'; + next_state <= WAIT_LOAD_EVEN; + + when MEM_STORE => + sc_input.address <= address(SC_ADDR_WIDTH downto 1); + sc_input.wr <= '1'; + sc_input.wr_data <= data; + sc_input.rd <= '0'; + next_state <= WAIT_STORE; + + when MEM_NOP => next_state <= WAIT_NONE; + + when others => exc <= '1'; -- inhibit invalid operations + + end case; + when others => null; + end case; + + else + -- invalid address and/or alignment + if op /= MEM_NOP then + exc <= '1'; + end if; + end if; + + end process readwrite; + +end behaviour; Index: data_rom.bsf =================================================================== --- data_rom.bsf (nonexistent) +++ data_rom.bsf (revision 8) @@ -0,0 +1,74 @@ +/* +WARNING: Do NOT edit the input and output ports in this file in a text +editor if you plan to continue editing the block that represents it in +the Block Editor! File corruption is VERY likely to occur. +*/ +/* +Copyright (C) 1991-2006 Altera Corporation +Your use of Altera Corporation's design tools, logic functions +and other software and tools, and its AMPP partner logic +functions, and any output files any of the foregoing +(including device programming or simulation files), and any +associated documentation or information are expressly subject +to the terms and conditions of the Altera Program License +Subscription Agreement, Altera MegaCore Function License +Agreement, or other applicable license agreement, including, +without limitation, that your use is for the sole purpose of +programming logic devices manufactured by Altera and sold by +Altera or its authorized distributors. Please refer to the +applicable agreement for further details. +*/ +(header "symbol" (version "1.1")) +(symbol + (rect 0 0 216 152) + (text "data_rom" (rect 81 1 144 17)(font "Arial" (font_size 10))) + (text "inst" (rect 8 136 25 148)(font "Arial" )) + (port + (pt 0 32) + (input) + (text "address[6..0]" (rect 0 0 75 14)(font "Arial" (font_size 8))) + (text "address[6..0]" (rect 4 19 63 32)(font "Arial" (font_size 8))) + (line (pt 0 32)(pt 88 32)(line_width 3)) + ) + (port + (pt 0 112) + (input) + (text "clock" (rect 0 0 29 14)(font "Arial" (font_size 8))) + (text "clock" (rect 4 99 29 112)(font "Arial" (font_size 8))) + (line (pt 0 112)(pt 80 112)(line_width 1)) + ) + (port + (pt 0 128) + (input) + (text "clken" (rect 0 0 29 14)(font "Arial" (font_size 8))) + (text "clken" (rect 4 115 29 128)(font "Arial" (font_size 8))) + (line (pt 0 128)(pt 16 128)(line_width 1)) + ) + (port + (pt 216 32) + (output) + (text "q[7..0]" (rect 0 0 35 14)(font "Arial" (font_size 8))) + (text "q[7..0]" (rect 183 19 213 32)(font "Arial" (font_size 8))) + (line (pt 216 32)(pt 136 32)(line_width 3)) + ) + (drawing + (text "8 bits" (rect 108 48 120 71)(font "Arial" )(vertical)) + (text "128 words" (rect 121 39 133 81)(font "Arial" )(vertical)) + (text "Block type: AUTO" (rect 41 132 117 144)(font "Arial" )) + (line (pt 104 24)(pt 136 24)(line_width 1)) + (line (pt 136 24)(pt 136 96)(line_width 1)) + (line (pt 136 96)(pt 104 96)(line_width 1)) + (line (pt 104 96)(pt 104 24)(line_width 1)) + (line (pt 118 58)(pt 123 63)(line_width 1)) + (line (pt 118 62)(pt 123 57)(line_width 1)) + (line (pt 88 27)(pt 96 27)(line_width 1)) + (line (pt 96 27)(pt 96 39)(line_width 1)) + (line (pt 96 39)(pt 88 39)(line_width 1)) + (line (pt 88 39)(pt 88 27)(line_width 1)) + (line (pt 88 34)(pt 90 36)(line_width 1)) + (line (pt 90 36)(pt 88 38)(line_width 1)) + (line (pt 80 36)(pt 88 36)(line_width 1)) + (line (pt 96 32)(pt 104 32)(line_width 3)) + (line (pt 80 112)(pt 80 36)(line_width 1)) + ) +) Index: writeback_ent.vhd =================================================================== --- writeback_ent.vhd (nonexistent) +++ writeback_ent.vhd (revision 8) @@ -0,0 +1,58 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA write-back stage +------------------------------------------------------------------------------- +-- entity for the write-back pipeline stage +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +entity writeback is + + port ( + clock : in std_logic; + reset : in std_logic; + + hold : in std_logic; + + pc_in : in std_logic_vector(REG_WIDTH-1 downto 0); + pcchg : in std_logic; + pc_out : out std_logic_vector(REG_WIDTH-1 downto 0); + + pcena : out std_logic; + + dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + + target : in TARGET_SELECTOR; + result : in std_logic_vector(REG_WIDTH-1 downto 0); + + ena : out std_logic; + val : out std_logic_vector(REG_WIDTH-1 downto 0) + ); + +end writeback; Index: intr_ent.vhd =================================================================== --- intr_ent.vhd (nonexistent) +++ intr_ent.vhd (revision 8) @@ -0,0 +1,52 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA interrupt unit +------------------------------------------------------------------------------- +-- entity for the interrupt unit +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +entity intr is + + port ( + clock : in std_logic; + reset : in std_logic; + enable : in std_logic; + + trigger : in std_logic_vector(VEC_COUNT-1 downto 1); + + op : in INTR_OP; + a : in std_logic_vector(REG_WIDTH-1 downto 0); + i : in std_logic_vector(REG_WIDTH-1 downto 0); + pc : in std_logic_vector(REG_WIDTH-1 downto 0); + + exc : out std_logic; + pcchg : out std_logic; + result : out std_logic_vector(REG_WIDTH-1 downto 0)); + +end intr; Index: fifo.vhd =================================================================== --- fifo.vhd (nonexistent) +++ fifo.vhd (revision 8) @@ -0,0 +1,155 @@ +-- +-- fifo.vhd +-- +-- simple fifo +-- +-- uses FF and every rd or wr has to 'bubble' through the hole fifo. +-- +-- Author: Martin Schoeberl martin.schoeberl@chello.at +-- +-- +-- resources on ACEX1K +-- +-- (width+2)*depth-1 LCs +-- +-- +-- 2002-01-06 first working version +-- 2002-11-03 a signal for reaching threshold +-- 2005-02-20 change entity order for modelsim vcom +-- + +library ieee; +use ieee.std_logic_1164.all; + +use work.marca_pkg.all; + +entity fifo_elem is + + generic (width : integer); + port ( + clk : in std_logic; + reset : in std_logic; + + din : in std_logic_vector(width-1 downto 0); + dout : out std_logic_vector(width-1 downto 0); + + rd : in std_logic; + wr : in std_logic; + + rd_prev : out std_logic; + full : out std_logic + ); +end fifo_elem; + +architecture rtl of fifo_elem is + + signal buf : std_logic_vector(width-1 downto 0); + signal f : std_logic; + +begin + + dout <= buf; + + process(clk, reset, f) + + begin + + full <= f; + + if reset = RESET_ACTIVE then + + buf <= (others => '0'); + f <= '0'; + rd_prev <= '0'; + + elsif rising_edge(clk) then + + rd_prev <= '0'; + if f='0' then + if wr='1' then + rd_prev <= '1'; + buf <= din; + f <= '1'; + end if; + else + if rd='1' then + f <= '0'; + end if; + end if; + + end if; + + end process; + +end rtl; + +library ieee; +use ieee.std_logic_1164.all; + +entity fifo is + + generic (width : integer := 8; depth : integer := 4; thres : integer := 2); + port ( + clk : in std_logic; + reset : in std_logic; + + din : in std_logic_vector(width-1 downto 0); + dout : out std_logic_vector(width-1 downto 0); + + rd : in std_logic; + wr : in std_logic; + + empty : out std_logic; + full : out std_logic; + half : out std_logic + ); +end fifo ; + +architecture rtl of fifo is + + component fifo_elem is + generic (width : integer); + port ( + clk : in std_logic; + reset : in std_logic; + + din : in std_logic_vector(width-1 downto 0); + dout : out std_logic_vector(width-1 downto 0); + + rd : in std_logic; + wr : in std_logic; + + rd_prev : out std_logic; + full : out std_logic); + end component; + + signal r, w, rp, f : std_logic_vector(depth-1 downto 0); + type d_array is array (0 to depth-1) of std_logic_vector(width-1 downto 0); + signal di, do : d_array; + +begin + + g1: for i in 0 to depth-1 generate + + f1: fifo_elem generic map (width) + port map (clk, reset, di(i), do(i), r(i), w(i), rp(i), f(i)); + + x: if i '0'); + reg_operand2 <= (others => '0'); + reg_product <= (others => '0'); + reg_hotbit <= (others => '0'); + reg_hotbit(0) <= '1'; + + elsif clock'event and clock = '1' then -- rising clock edge + + if trigger = '1' then + reg_operand1 <= operand1; + reg_operand2 <= operand2; + reg_product <= (others => '0'); + reg_hotbit(width-1) <= '1'; + reg_hotbit(width-2 downto 0) <= (others => '0'); + reg_busy <= '1'; + else + reg_operand1 <= next_operand1; + reg_operand2 <= next_operand2; + reg_product(width-1 downto 0) <= next_product(width-1 downto 0); + -- sticky "carry"-bit + reg_product(width) <= reg_product(width) or next_product(width); + reg_hotbit <= next_hotbit; + reg_busy <= next_busy; + end if; + + end if; + end process syn_proc; + + compute: process (reg_operand1, reg_operand2, reg_product, reg_hotbit) + begin -- process compute + + next_operand1 <= reg_operand1(width-2 downto 0) & '0'; + next_operand2 <= '0' & reg_operand2(width-1 downto 1); + next_hotbit <= '0' & reg_hotbit(width-1 downto 1); + + if reg_hotbit(0) = '1' then + next_hotbit <= reg_hotbit; + next_busy <= '0'; + else + next_busy <= '1'; + end if; + + if reg_operand2(0) = '1' then + next_product <= std_logic_vector(unsigned(reg_product) + unsigned(reg_operand1(width-1 downto 0))); + else + next_product <= reg_product; + end if; + + end process compute; + +end behaviour; Index: uart_reverse.s =================================================================== --- uart_reverse.s (nonexistent) +++ uart_reverse.s (revision 8) @@ -0,0 +1,79 @@ +.data + data 0x0A + data 0x0D +buffer: + +.text +;;; initialization + ldib r0, -8 ; config/status + ldib r1, -6 ; data + + ldil r2, lo(buffer) ; buffer address + ldih r2, hi(buffer) ; buffer address + + ldib r3, 0x0A ; newline character + ldib r4, 0x0D ; carriage return + + ldib r5, 0 ; mode + + ldib r7, isr ; register isr + stvec r7, 3 + + ldib r7, (1 << 3) ; enable receive interrupts + store r7, r0 + + sei ; enable interrupts + +;;; loop forever +loop: br loop + + +;;; ISR +isr: + cmpi r5, 0 ; check mode + brnz write_mode + +;;; reading +read_mode: + load r7, r1 ; read data + + cmp r7, r3 ; change mode upon newline + brnz read_CR + + ldib r7, (1 << 2) ; do the change + store r7, r0 + ldib r5, 1 + reti + +read_CR: + cmp r7, r4 ; ignore carriage return + brnz read_cont + reti + +read_cont: + storel r7, r2 ; store date + addi r2, 1 + reti + +;;; writing +write_mode: + addi r2, -1 + + cmpi r2, -1 ; change mode if there is no more data + brnz write_cont + + ldil r2, lo(buffer) ; correct pointer to buffer + ldih r2, hi(buffer) + + ldib r7, (1 << 3) ; do the change + store r7, r0 + ldib r5, 0 + reti + +write_cont: + loadl r7, r2 ; write data + store r7, r1 + reti + + + Index: data_memory.bsf =================================================================== --- data_memory.bsf (nonexistent) +++ data_memory.bsf (revision 8) @@ -0,0 +1,104 @@ +/* +WARNING: Do NOT edit the input and output ports in this file in a text +editor if you plan to continue editing the block that represents it in +the Block Editor! File corruption is VERY likely to occur. +*/ +/* +Copyright (C) 1991-2006 Altera Corporation +Your use of Altera Corporation's design tools, logic functions +and other software and tools, and its AMPP partner logic +functions, and any output files any of the foregoing +(including device programming or simulation files), and any +associated documentation or information are expressly subject +to the terms and conditions of the Altera Program License +Subscription Agreement, Altera MegaCore Function License +Agreement, or other applicable license agreement, including, +without limitation, that your use is for the sole purpose of +programming logic devices manufactured by Altera and sold by +Altera or its authorized distributors. Please refer to the +applicable agreement for further details. +*/ +(header "symbol" (version "1.1")) +(symbol + (rect 0 0 216 152) + (text "data_memory" (rect 69 1 162 17)(font "Arial" (font_size 10))) + (text "inst" (rect 8 136 25 148)(font "Arial" )) + (port + (pt 0 32) + (input) + (text "data[7..0]" (rect 0 0 53 14)(font "Arial" (font_size 8))) + (text "data[7..0]" (rect 4 19 49 32)(font "Arial" (font_size 8))) + (line (pt 0 32)(pt 88 32)(line_width 3)) + ) + (port + (pt 0 48) + (input) + (text "wren" (rect 0 0 30 14)(font "Arial" (font_size 8))) + (text "wren" (rect 4 35 26 48)(font "Arial" (font_size 8))) + (line (pt 0 48)(pt 88 48)(line_width 1)) + ) + (port + (pt 0 64) + (input) + (text "address[11..0]" (rect 0 0 82 14)(font "Arial" (font_size 8))) + (text "address[11..0]" (rect 4 51 69 64)(font "Arial" (font_size 8))) + (line (pt 0 64)(pt 88 64)(line_width 3)) + ) + (port + (pt 0 112) + (input) + (text "clock" (rect 0 0 29 14)(font "Arial" (font_size 8))) + (text "clock" (rect 4 99 29 112)(font "Arial" (font_size 8))) + (line (pt 0 112)(pt 80 112)(line_width 1)) + ) + (port + (pt 0 128) + (input) + (text "clken" (rect 0 0 29 14)(font "Arial" (font_size 8))) + (text "clken" (rect 4 115 29 128)(font "Arial" (font_size 8))) + (line (pt 0 128)(pt 16 128)(line_width 1)) + ) + (port + (pt 216 32) + (output) + (text "q[7..0]" (rect 0 0 35 14)(font "Arial" (font_size 8))) + (text "q[7..0]" (rect 183 19 213 32)(font "Arial" (font_size 8))) + (line (pt 216 32)(pt 136 32)(line_width 3)) + ) + (drawing + (text "8 bits" (rect 108 48 120 71)(font "Arial" )(vertical)) + (text "4096 words" (rect 121 36 133 83)(font "Arial" )(vertical)) + (text "Block type: AUTO" (rect 41 132 117 144)(font "Arial" )) + (line (pt 104 24)(pt 136 24)(line_width 1)) + (line (pt 136 24)(pt 136 96)(line_width 1)) + (line (pt 136 96)(pt 104 96)(line_width 1)) + (line (pt 104 96)(pt 104 24)(line_width 1)) + (line (pt 118 58)(pt 123 63)(line_width 1)) + (line (pt 118 62)(pt 123 57)(line_width 1)) + (line (pt 88 27)(pt 96 27)(line_width 1)) + (line (pt 96 27)(pt 96 39)(line_width 1)) + (line (pt 96 39)(pt 88 39)(line_width 1)) + (line (pt 88 39)(pt 88 27)(line_width 1)) + (line (pt 88 34)(pt 90 36)(line_width 1)) + (line (pt 90 36)(pt 88 38)(line_width 1)) + (line (pt 80 36)(pt 88 36)(line_width 1)) + (line (pt 96 32)(pt 104 32)(line_width 3)) + (line (pt 88 43)(pt 96 43)(line_width 1)) + (line (pt 96 43)(pt 96 55)(line_width 1)) + (line (pt 96 55)(pt 88 55)(line_width 1)) + (line (pt 88 55)(pt 88 43)(line_width 1)) + (line (pt 88 50)(pt 90 52)(line_width 1)) + (line (pt 90 52)(pt 88 54)(line_width 1)) + (line (pt 80 52)(pt 88 52)(line_width 1)) + (line (pt 96 48)(pt 104 48)(line_width 1)) + (line (pt 88 59)(pt 96 59)(line_width 1)) + (line (pt 96 59)(pt 96 71)(line_width 1)) + (line (pt 96 71)(pt 88 71)(line_width 1)) + (line (pt 88 71)(pt 88 59)(line_width 1)) + (line (pt 88 66)(pt 90 68)(line_width 1)) + (line (pt 90 68)(pt 88 70)(line_width 1)) + (line (pt 80 68)(pt 88 68)(line_width 1)) + (line (pt 96 64)(pt 104 64)(line_width 3)) + (line (pt 80 112)(pt 80 36)(line_width 1)) + ) +) Index: code_memory.bsf =================================================================== --- code_memory.bsf (nonexistent) +++ code_memory.bsf (revision 8) @@ -0,0 +1,74 @@ +/* +WARNING: Do NOT edit the input and output ports in this file in a text +editor if you plan to continue editing the block that represents it in +the Block Editor! File corruption is VERY likely to occur. +*/ +/* +Copyright (C) 1991-2006 Altera Corporation +Your use of Altera Corporation's design tools, logic functions +and other software and tools, and its AMPP partner logic +functions, and any output files any of the foregoing +(including device programming or simulation files), and any +associated documentation or information are expressly subject +to the terms and conditions of the Altera Program License +Subscription Agreement, Altera MegaCore Function License +Agreement, or other applicable license agreement, including, +without limitation, that your use is for the sole purpose of +programming logic devices manufactured by Altera and sold by +Altera or its authorized distributors. Please refer to the +applicable agreement for further details. +*/ +(header "symbol" (version "1.1")) +(symbol + (rect 0 0 216 152) + (text "code_memory" (rect 67 1 163 17)(font "Arial" (font_size 10))) + (text "inst" (rect 8 136 25 148)(font "Arial" )) + (port + (pt 0 32) + (input) + (text "address[11..0]" (rect 0 0 82 14)(font "Arial" (font_size 8))) + (text "address[11..0]" (rect 4 19 69 32)(font "Arial" (font_size 8))) + (line (pt 0 32)(pt 88 32)(line_width 3)) + ) + (port + (pt 0 112) + (input) + (text "clock" (rect 0 0 29 14)(font "Arial" (font_size 8))) + (text "clock" (rect 4 99 29 112)(font "Arial" (font_size 8))) + (line (pt 0 112)(pt 80 112)(line_width 1)) + ) + (port + (pt 0 128) + (input) + (text "clken" (rect 0 0 29 14)(font "Arial" (font_size 8))) + (text "clken" (rect 4 115 29 128)(font "Arial" (font_size 8))) + (line (pt 0 128)(pt 16 128)(line_width 1)) + ) + (port + (pt 216 32) + (output) + (text "q[15..0]" (rect 0 0 42 14)(font "Arial" (font_size 8))) + (text "q[15..0]" (rect 177 19 213 32)(font "Arial" (font_size 8))) + (line (pt 216 32)(pt 136 32)(line_width 3)) + ) + (drawing + (text "16 bits" (rect 108 46 120 74)(font "Arial" )(vertical)) + (text "4096 words" (rect 121 36 133 83)(font "Arial" )(vertical)) + (text "Block type: AUTO" (rect 41 132 117 144)(font "Arial" )) + (line (pt 104 24)(pt 136 24)(line_width 1)) + (line (pt 136 24)(pt 136 96)(line_width 1)) + (line (pt 136 96)(pt 104 96)(line_width 1)) + (line (pt 104 96)(pt 104 24)(line_width 1)) + (line (pt 118 58)(pt 123 63)(line_width 1)) + (line (pt 118 62)(pt 123 57)(line_width 1)) + (line (pt 88 27)(pt 96 27)(line_width 1)) + (line (pt 96 27)(pt 96 39)(line_width 1)) + (line (pt 96 39)(pt 88 39)(line_width 1)) + (line (pt 88 39)(pt 88 27)(line_width 1)) + (line (pt 88 34)(pt 90 36)(line_width 1)) + (line (pt 90 36)(pt 88 38)(line_width 1)) + (line (pt 80 36)(pt 88 36)(line_width 1)) + (line (pt 96 32)(pt 104 32)(line_width 3)) + (line (pt 80 112)(pt 80 36)(line_width 1)) + ) +) Index: multiplier_ent.vhd =================================================================== --- multiplier_ent.vhd (nonexistent) +++ multiplier_ent.vhd (revision 8) @@ -0,0 +1,48 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA multiplier +------------------------------------------------------------------------------- +-- entity of a bit-serial multiplier +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +entity multiplier is + + generic ( + width : integer := REG_WIDTH); + + port ( + clock : in std_logic; + reset : in std_logic; + trigger : in std_logic; + operand1 : in std_logic_vector(width-1 downto 0); + operand2 : in std_logic_vector(width-1 downto 0); + busy : out std_logic; + product : out std_logic_vector(width downto 0)); + +end multiplier; Index: Makefile =================================================================== --- Makefile (nonexistent) +++ Makefile (revision 8) @@ -0,0 +1,2 @@ +program: factorial.s + ../../spar/as1 --output=code.mif --rom0file=rom0.mif --rom1file=rom1.mif factorial.s Index: sc_uart.vhd =================================================================== --- sc_uart.vhd (nonexistent) +++ sc_uart.vhd (revision 8) @@ -0,0 +1,367 @@ +-- +-- sc_uart.vhd +-- +-- 8-N-1 serial interface +-- +-- wr, rd should be one cycle long => trde, rdrf goes 0 one cycle later +-- +-- Author: Martin Schoeberl martin@jopdesign.com +-- +-- +-- resources on ACEX1K30-3 +-- +-- 100 LCs, max 90 MHz +-- +-- resetting rts with fifo_full-1 works with C program on pc +-- but not with javax.comm: sends some more bytes after deassert +-- of rts (16 byte blocks regardless of rts). +-- Try to stop with half full fifo. +-- +-- todo: +-- +-- +-- 2000-12-02 first working version +-- 2002-01-06 changed tdr and rdr to fifos. +-- 2002-05-15 changed clkdiv calculation +-- 2002-11-01 don't wait if read fifo is full, just drop the byte +-- 2002-11-03 use threshold in fifo to reset rts +-- don't send if cts is '0' +-- 2002-11-08 rx fifo to 20 characters and stop after 4 +-- 2003-07-05 new IO standard, change cts/rts to neg logic +-- 2003-09-19 sync ncts in! +-- 2004-03-23 two stop bits +-- 2005-11-30 change interface to SimpCon +-- 2006-08-07 rxd input register with clk to avoid Quartus tsu violation +-- 2006-08-13 use 3 FFs for the rxd input at clk +-- + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.marca_pkg.all; +use work.sc_pkg.all; + +entity sc_uart is + + generic (clock_freq : integer; + baud_rate : integer; + txf_depth : integer; txf_thres : integer; + rxf_depth : integer; rxf_thres : integer); + + port (clock : in std_logic; + reset : in std_logic; + +-- SimpCon interface + input : in SC_IN; + output : out SC_OUT; + + intr : out std_logic; + + txd : out std_logic; + rxd : in std_logic; + ncts : in std_logic; + nrts : out std_logic); + +end sc_uart; + +architecture rtl of sc_uart is + + component fifo is + + generic (width : integer; + depth : integer; + thres : integer); + + port (clk : in std_logic; + reset : in std_logic; + + din : in std_logic_vector(width-1 downto 0); + dout : out std_logic_vector(width-1 downto 0); + + rd : in std_logic; + wr : in std_logic; + + empty : out std_logic; + full : out std_logic; + half : out std_logic); + end component; + +-- +-- signals for uart connection +-- + signal ua_dout : std_logic_vector(7 downto 0); + signal ua_wr, tdre : std_logic; + signal ua_rd, rdrf : std_logic; + + type uart_tx_state_type is (s0, s1); + signal uart_tx_state : uart_tx_state_type; + + signal tf_dout : std_logic_vector(7 downto 0); -- fifo out + signal tf_rd : std_logic; + signal tf_empty : std_logic; + signal tf_full : std_logic; + signal tf_half : std_logic; + + signal ncts_buf : std_logic_vector(2 downto 0); -- sync in + signal tsr : std_logic_vector(9 downto 0); -- tx shift register + signal tx_clk : std_logic; + + type uart_rx_state_type is (s0, s1, s2); + signal uart_rx_state : uart_rx_state_type; + + signal rf_wr : std_logic; + signal rf_empty : std_logic; + signal rf_full : std_logic; + signal rf_half : std_logic; + + signal rxd_reg : std_logic_vector(2 downto 0); + signal rx_buf : std_logic_vector(2 downto 0); -- sync in, filter + signal rx_d : std_logic; -- rx serial data + signal rsr : std_logic_vector(9 downto 0); -- rx shift register + signal rx_clk : std_logic; + signal rx_clk_ena : std_logic; + + signal rdrf_iena : std_logic; + signal tdre_iena : std_logic; + + constant clk16_cnt : integer := (clock_freq/baud_rate+8)/16-1; + +begin + + output.rdy_cnt <= "00"; -- no wait states + output.rd_data(SC_REG_WIDTH-1 downto 8) <= std_logic_vector(to_unsigned(0, SC_REG_WIDTH-8)); + +-- +-- The registered MUX is all we need for a SimpCon read. +-- The read data is stored in registered rd_data. +-- + process(clock, reset) + begin + + if reset = RESET_ACTIVE then + output.rd_data(7 downto 0) <= (others => '0'); + elsif rising_edge(clock) then + + ua_rd <= '0'; + if input.rd='1' then + -- that's our very simple address decoder + if input.address(0)='0' then + output.rd_data(7 downto 0) <= "0000" & rdrf_iena & tdre_iena & rdrf & tdre; + else + output.rd_data(7 downto 0) <= ua_dout; + ua_rd <= input.rd; + end if; + end if; + + if input.wr='1' then + if input.address(0)='0' then + rdrf_iena <= input.wr_data(3); + tdre_iena <= input.wr_data(2); + end if; + end if; + + end if; + + end process; + + ua_wr <= input.wr and input.address(0); + + intr <= (rdrf and rdrf_iena) or (tdre and tdre_iena); + +-- +-- serial clock +-- + process(clock, reset) + + variable clk16 : integer range 0 to clk16_cnt; + variable clktx : unsigned(3 downto 0); + variable clkrx : unsigned(3 downto 0); + + begin + if reset = RESET_ACTIVE then + clk16 := 0; + clktx := "0000"; + clkrx := "0000"; + tx_clk <= '0'; + rx_clk <= '0'; + rx_buf <= "111"; + + elsif rising_edge(clock) then + + rxd_reg(0) <= rxd; -- to avoid setup timing error in Quartus + rxd_reg(1) <= rxd_reg(0); + rxd_reg(2) <= rxd_reg(1); + + if (clk16=clk16_cnt) then -- 16 x serial clock + clk16 := 0; +-- +-- tx clock +-- + clktx := clktx + 1; + if (clktx="0000") then + tx_clk <= '1'; + else + tx_clk <= '0'; + end if; +-- +-- rx clock +-- + if (rx_clk_ena='1') then + clkrx := clkrx + 1; + if (clkrx="1000") then + rx_clk <= '1'; + else + rx_clk <= '0'; + end if; + else + clkrx := "0000"; + end if; +-- +-- sync in filter buffer +-- + rx_buf(0) <= rxd_reg(2); + rx_buf(2 downto 1) <= rx_buf(1 downto 0); + else + clk16 := clk16 + 1; + tx_clk <= '0'; + rx_clk <= '0'; + end if; + + end if; + + end process; + +-- +-- transmit fifo +-- + cmp_tf: fifo generic map (8, txf_depth, txf_thres) + port map (clock, reset, input.wr_data(7 downto 0), tf_dout, tf_rd, ua_wr, tf_empty, tf_full, tf_half); + + txd <= tsr(0); + tdre <= not tf_full; + +-- +-- state machine for actual shift out +-- + process(clock, reset) + + variable i : integer range 0 to 11; + + begin + + if reset = RESET_ACTIVE then + uart_tx_state <= s0; + tsr <= "1111111111"; + tf_rd <= '0'; + ncts_buf <= "111"; + + elsif rising_edge(clock) then + + ncts_buf(0) <= ncts; + ncts_buf(2 downto 1) <= ncts_buf(1 downto 0); + + case uart_tx_state is + + when s0 => + i := 0; + if (tf_empty='0' and ncts_buf(2)='0') then + uart_tx_state <= s1; + tsr <= tf_dout & '0' & '1'; + tf_rd <= '1'; + end if; + + when s1 => + tf_rd <= '0'; + if (tx_clk='1') then + tsr(9) <= '1'; + tsr(8 downto 0) <= tsr(9 downto 1); + i := i+1; + if (i=11) then -- two stop bits + uart_tx_state <= s0; + end if; + end if; + + end case; + end if; + + end process; + +-- +-- receive fifo +-- + cmp_rf: fifo generic map (8, rxf_depth, rxf_thres) + port map (clock, reset, rsr(8 downto 1), ua_dout, ua_rd, rf_wr, rf_empty, rf_full, rf_half); + + rdrf <= not rf_empty; + nrts <= rf_half; -- glitches even on empty fifo! + +-- +-- filter rxd +-- + with rx_buf select + rx_d <= '0' when "000", + '0' when "001", + '0' when "010", + '1' when "011", + '0' when "100", + '1' when "101", + '1' when "110", + '1' when "111", + 'X' when others; + +-- +-- state machine for actual shift in +-- + process(clock, reset) + + variable i : integer range 0 to 10; + + begin + + if reset = RESET_ACTIVE then + uart_rx_state <= s0; + rsr <= "0000000000"; + rf_wr <= '0'; + rx_clk_ena <= '0'; + + elsif rising_edge(clock) then + + case uart_rx_state is + + when s0 => + i := 0; + rf_wr <= '0'; + if (rx_d='0') then + rx_clk_ena <= '1'; + uart_rx_state <= s1; + else + rx_clk_ena <= '0'; + end if; + + when s1 => + if (rx_clk='1') then + rsr(9) <= rx_d; + rsr(8 downto 0) <= rsr(9 downto 1); + i := i+1; + if (i=10) then + uart_rx_state <= s2; + end if; + end if; + + when s2 => + rx_clk_ena <= '0'; + if rsr(0)='0' and rsr(9)='1' then + if rf_full='0' then -- if full just drop it + rf_wr <= '1'; + end if; + end if; + uart_rx_state <= s0; + + end case; + end if; + + end process; + +end rtl; Index: rom0.mif =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: rom0.mif =================================================================== --- rom0.mif (nonexistent) +++ rom0.mif (revision 8)
rom0.mif Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: ChangeLog =================================================================== --- ChangeLog (nonexistent) +++ ChangeLog (revision 8) @@ -0,0 +1,47 @@ +2007-02-02 Wolfgang Puffitsch + + Version to be published on opencores.org ``Cement and aluminium.'' + +2007-01-31 Wolfgang Puffitsch + + * decode.vhd: restuctured decoder, saving a few LCs + +2007-01-29 Wolfgang Puffitsch + + * alu.vhd: simplified logic to use only one adder/subtractor + + * mem.vhd: removed extra state for SimpCon access + +2007-01-28 Wolfgang Puffitsch + + * mem.vhd: introduced enable-signals for the memories to reduce + power consumption + +2007-01-20 Wolfgang Puffitsch + + * mem.vhd: fixed condition for raising memory interrupt + +2006-12-31 Wolfgang Puffitsch + + * multiplier.vhd: "predicting" unconditional branches now + + * execute.vhd: fixing a bug with calls + + * mem.vhd: fixing a bug with stores to odd addresses + +2006-12-29 Wolfgang Puffitsch + + * intr.vhd: EXC_ERR is triggered by an instruction itself, so it's + wire is left out in the "trigger" signal + + * decode.vhd: now triggering interrupt upon invalid instructions + + * marca_pkg.vhd: introduced constant RESET_ACTIVE for easy + adaption to low-active reset buttons + + * fetch.vhd: reorganized this stage to fix an off-by-one flaw with + the program counter + +2006-12-14 Wolfgang Puffitsch + + First working version ``Starving hysterical naked.'' \ No newline at end of file Index: rom1.mif =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: rom1.mif =================================================================== --- rom1.mif (nonexistent) +++ rom1.mif (revision 8)
rom1.mif Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: regfile.vhd =================================================================== --- regfile.vhd (nonexistent) +++ regfile.vhd (revision 8) @@ -0,0 +1,77 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA decode stage +------------------------------------------------------------------------------- +-- architecture for the instruction-decode pipeline stage +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.marca_pkg.all; + +architecture behaviour of regfile is + +type registers is array (REG_COUNT-1 downto 0) of std_logic_vector(REG_WIDTH-1 downto 0); + +signal regs, next_regs : registers; + +begin -- behaviour + + syn_proc: process (clock, reset) + begin -- process syn_proc + if reset = RESET_ACTIVE then -- asynchronous reset (active low) + regs <= (others => (others => '0')); + elsif clock'event and clock = '1' then -- rising clock edge + if hold = '0' then + regs <= next_regs; + end if; + end if; + end process syn_proc; + + forward: process(rd1_addr, rd2_addr, wr_ena, wr_addr, wr_val, regs) + begin -- process forward + + next_regs <= regs; + + if wr_ena = '1' then + next_regs(to_integer(unsigned(wr_addr))) <= wr_val; + end if; + + if rd1_addr /= wr_addr or wr_ena = '0' then + rd1_val <= regs(to_integer(unsigned(rd1_addr))); + else + rd1_val <= wr_val; + end if; + + if rd2_addr /= wr_addr or wr_ena = '0' then + rd2_val <= regs(to_integer(unsigned(rd2_addr))); + else + rd2_val <= wr_val; + end if; + + end process forward; + +end behaviour; Index: alu.vhd =================================================================== --- alu.vhd (nonexistent) +++ alu.vhd (revision 8) @@ -0,0 +1,613 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA ALU +------------------------------------------------------------------------------- +-- architecture for the ALU +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.marca_pkg.all; + +architecture behaviour of alu is + + type WAIT_STATE is (WAIT_NONE, WAIT_MULT, WAIT_DIV, WAIT_UDIV, WAIT_MOD, WAIT_UMOD); + signal state : WAIT_STATE; + signal next_state : WAIT_STATE; + + signal flags : std_logic_vector(REG_WIDTH-1 downto 0); + signal next_flags : std_logic_vector(REG_WIDTH-1 downto 0); + + signal shflags : std_logic_vector(REG_WIDTH-1 downto 0); + signal next_shflags : std_logic_vector(REG_WIDTH-1 downto 0); + + signal old_sgna, old_sgnb : std_logic; + signal sgna, sgnb : std_logic; + + component multiplier is + generic ( + width : integer := REG_WIDTH); + port ( + clock : in std_logic; + reset : in std_logic; + trigger : in std_logic; + operand1 : in std_logic_vector(width-1 downto 0); + operand2 : in std_logic_vector(width-1 downto 0); + busy : out std_logic; + product : out std_logic_vector(width downto 0)); + end component; + + signal mult_op1 : std_logic_vector(REG_WIDTH-1 downto 0); + signal mult_op2 : std_logic_vector(REG_WIDTH-1 downto 0); + signal mult_trigger : std_logic; + signal mult_busy : std_logic; + signal mult_result : std_logic_vector(REG_WIDTH downto 0); + + + component divider is + generic ( + width : integer := REG_WIDTH); + port ( + clock : in std_logic; + reset : in std_logic; + trigger : in std_logic; + denom : in std_logic_vector(width-1 downto 0); + numer : in std_logic_vector(width-1 downto 0); + exc : out std_logic; + busy : out std_logic; + quotient : out std_logic_vector(width-1 downto 0); + remain : out std_logic_vector(width-1 downto 0)); + end component; + + signal udiv_op1 : std_logic_vector(REG_WIDTH-1 downto 0); + signal udiv_op2 : std_logic_vector(REG_WIDTH-1 downto 0); + signal udiv_trigger : std_logic; + signal udiv_exc : std_logic; + signal udiv_busy : std_logic; + signal udiv_result : std_logic_vector(REG_WIDTH-1 downto 0); + signal umod_result : std_logic_vector(REG_WIDTH-1 downto 0); + + + signal adder_op1 : std_logic_vector(REG_WIDTH downto 0); + signal adder_op2 : std_logic_vector(REG_WIDTH downto 0); + signal adder_op3 : std_logic; + signal adder_result : std_logic_vector(REG_WIDTH downto 0); + + + function shift_left (a : std_logic_vector; + b : std_logic_vector) + return std_logic_vector is + variable result : std_logic_vector(a'length-1 downto 0); + variable i : integer; + begin + for i in 0 to a'length-1 loop + if i < to_integer(unsigned(b)) then + result(i) := '0'; + else + result(i) := a(i - to_integer(unsigned(b))); + end if; + end loop; + return result; + end; + + function shift_right (a : std_logic_vector; + b : std_logic_vector) + return std_logic_vector is + variable result : std_logic_vector(a'length-1 downto 0); + variable i : integer; + begin + for i in 0 to a'length-1 loop + if i < to_integer(unsigned(b)) then + result(i) := a(i + to_integer(unsigned(b))); + elsif i < a'length-1 then + result(i) := '0'; + else + result(i) := a(to_integer(unsigned(b)) - 1); + end if; + end loop; + return result; + end; + + function shift_aright (a : std_logic_vector; + b : std_logic_vector) + return std_logic_vector is + variable result : std_logic_vector(a'length-1 downto 0); + variable i : integer; + begin + for i in 0 to a'length-1 loop + if i < to_integer(unsigned(b)) then + result(i) := a(i + to_integer(unsigned(b))); + elsif i < a'length-1 then + result(i) := a(a'length-1); + else + result(i) := a(to_integer(unsigned(b)) - 1); + end if; + end loop; + return result; + end; + + function rotate_left (a : std_logic_vector; + b : std_logic_vector; + c : std_logic) + return std_logic_vector is + variable result : std_logic_vector(a'length-1 downto 0); + variable i : integer; + begin + for i in 0 to a'length-1 loop + if i < to_integer(unsigned(b)) - 1 then + result(i) := a(a'length - to_integer(unsigned(b)) + i); + elsif i = to_integer(unsigned(b)) - 1 then + result(i) := c; + else + result(i) := a(i - to_integer(unsigned(b))); + end if; + end loop; + return result; + end; + + function rotate_right(a : std_logic_vector; + b : std_logic_vector; + c : std_logic) + return std_logic_vector is + variable result : std_logic_vector(a'length-1 downto 0); + variable i : integer; + begin + for i in 0 to a'length-1 loop + if i < a'length - to_integer(unsigned(b)) then + result(i) := a(to_integer(unsigned(b)) + i); + elsif i = a'length - to_integer(unsigned(b)) - 1 then + result(i) := c; + else + result(i) := a(i - a'length - to_integer(unsigned(b))); + end if; + end loop; + return result; + end; + + function to_unsigned(a : std_logic) + return unsigned is + variable result : unsigned(0 downto 0); + begin -- to_unsigned + if a = '1' then + result := "1"; + else + result := "0"; + end if; + return result; + end to_unsigned; + + function parity(a : std_logic_vector) + return std_logic is + variable result : std_logic; + variable i : integer; + begin + result := '1'; + for i in a'low to a'high loop + result := result xor a(i); + end loop; + return result; + end; + +begin -- behaviour + + -- hardwire the interrupt enable flag + iena <= flags(FLAG_I); + -- and the exception signal to the divider + exc <= udiv_exc; + + mult_unit : multiplier + port map ( + clock => clock, + reset => reset, + trigger => mult_trigger, + operand1 => mult_op1, + operand2 => mult_op2, + busy => mult_busy, + product => mult_result); + + udiv_unit : divider + port map ( + clock => clock, + reset => reset, + trigger => udiv_trigger, + numer => udiv_op1, + denom => udiv_op2, + exc => udiv_exc, + busy => udiv_busy, + quotient => udiv_result, + remain => umod_result); + + syn_proc: process (clock, reset) + begin -- process syn_proc + if reset = RESET_ACTIVE then -- asynchronous reset (active low) + flags <= (others => '0'); + shflags <= (others => '0'); + state <= WAIT_NONE; + old_sgna <= '0'; + old_sgnb <= '0'; + elsif clock'event and clock = '1' then -- rising clock edge + flags <= next_flags; + shflags <= next_shflags; + state <= next_state; + old_sgna <= sgna; + old_sgnb <= sgnb; + end if; + end process syn_proc; + + business: process(next_state) + begin -- process business + if next_state /= WAIT_NONE then + busy <= '1'; + else + busy <= '0'; + end if; + end process business; + + adder: process (adder_op1, adder_op2, adder_op3) + begin -- process adder + adder_result <= std_logic_vector(unsigned(adder_op1) + unsigned(adder_op2) + + to_unsigned(adder_op3)); + end process adder; + + compute: process (state, op, a, b, i, pc, flags, shflags, + intr, + sgna, sgnb, old_sgna, old_sgnb, + mult_busy, mult_result, + udiv_busy, udiv_result, umod_result, + adder_result) + + variable wr_flags : std_logic; + variable tmp : std_logic_vector(REG_WIDTH downto 0); + + begin + wr_flags := '1'; + tmp := (others => '0'); + + next_flags <= flags; + next_shflags <= shflags; + next_state <= state; + + sgna <= a(REG_WIDTH-1); + sgnb <= b(REG_WIDTH-1); + + mult_op1 <= (others => '0'); + mult_op2 <= (others => '0'); + mult_trigger <= '0'; + + udiv_op1 <= (others => '0'); + udiv_op2 <= (others => '0'); + udiv_trigger <= '0'; + + adder_op1 <= (others => '0'); + adder_op2 <= (others => '0'); + adder_op3 <= '0'; + + pcchg <= '0'; + + case state is + when WAIT_MULT => + sgna <= old_sgna; + sgnb <= old_sgnb; + tmp := mult_result; + if mult_busy = '0' then + next_state <= WAIT_NONE; + end if; + when WAIT_DIV => + sgna <= old_sgna; + sgnb <= old_sgnb; + if sgna = sgnb then + tmp(REG_WIDTH-1 downto 0) := udiv_result; + else + tmp(REG_WIDTH-1 downto 0) := std_logic_vector(-signed(udiv_result)); + end if; + if udiv_busy = '0' then + next_state <= WAIT_NONE; + end if; + when WAIT_UDIV => + sgna <= old_sgna; + sgnb <= old_sgnb; + tmp(REG_WIDTH-1 downto 0) := udiv_result; + if udiv_busy = '0' then + next_state <= WAIT_NONE; + end if; + when WAIT_MOD => + sgna <= old_sgna; + sgnb <= old_sgnb; + if sgna = sgnb then + tmp(REG_WIDTH-1 downto 0) := umod_result; + else + tmp(REG_WIDTH-1 downto 0) := std_logic_vector(-signed(umod_result)); + end if; + if udiv_busy = '0' then + next_state <= WAIT_NONE; + end if; + when WAIT_UMOD => + sgna <= old_sgna; + sgnb <= old_sgnb; + tmp(REG_WIDTH-1 downto 0) := umod_result; + if udiv_busy = '0' then + next_state <= WAIT_NONE; + end if; + when WAIT_NONE => + case op is + when ALU_ADD => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1)); + adder_op2 <= std_logic_vector(resize(unsigned(b), REG_WIDTH+1)); + tmp := adder_result; + when ALU_SUB => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1)); + adder_op2 <= not std_logic_vector(resize(unsigned(b), REG_WIDTH+1)); + adder_op3 <= '1'; + tmp := adder_result; + when ALU_ADDC => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1)); + adder_op2 <= std_logic_vector(resize(unsigned(b), REG_WIDTH+1)); + adder_op3 <= flags(FLAG_C); + tmp := adder_result; + when ALU_SUBC => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1)); + adder_op2 <= not std_logic_vector(resize(unsigned(b), REG_WIDTH+1)); + adder_op3 <= not flags(FLAG_C); + tmp := adder_result; + when ALU_AND => tmp(REG_WIDTH-1 downto 0) := a and b; + when ALU_OR => tmp(REG_WIDTH-1 downto 0) := a or b; + when ALU_XOR => tmp(REG_WIDTH-1 downto 0) := a xor b; +------------------------------------------------------------------------------- + when ALU_MUL => mult_trigger <= '1'; + mult_op1 <= a; + mult_op2 <= b; + next_state <= WAIT_MULT; + when ALU_DIV => udiv_trigger <= '1'; + udiv_op1 <= std_logic_vector(abs(signed(a))); + udiv_op2 <= std_logic_vector(abs(signed(b))); + next_state <= WAIT_DIV; + when ALU_UDIV => udiv_trigger <= '1'; + udiv_op1 <= a; + udiv_op2 <= b; + next_state <= WAIT_UDIV; + when ALU_MOD => udiv_trigger <= '1'; + udiv_op1 <= std_logic_vector(abs(signed(a))); + udiv_op2 <= std_logic_vector(abs(signed(b))); + next_state <= WAIT_MOD; + when ALU_UMOD => udiv_trigger <= '1'; + udiv_op1 <= a; + udiv_op2 <= b; + next_state <= WAIT_UMOD; +------------------------------------------------------------------------------- + when ALU_LDIL => tmp(REG_WIDTH-1 downto 0) := a(REG_WIDTH-1 downto REG_WIDTH/2) & i(REG_WIDTH/2-1 downto 0); + when ALU_LDIH => tmp(REG_WIDTH-1 downto 0) := i(REG_WIDTH/2-1 downto 0) & a(REG_WIDTH/2-1 downto 0); + when ALU_LDIB => tmp(REG_WIDTH-1 downto 0) := i; +------------------------------------------------------------------------------- + when ALU_MOV => tmp(REG_WIDTH-1 downto 0) := b; + when ALU_NOT => tmp(REG_WIDTH-1 downto 0) := not b; + when ALU_NEG => adder_op1 <= (others => '0'); + adder_op2 <= not std_logic_vector(resize(unsigned(b), REG_WIDTH+1)); + adder_op3 <= '1'; + tmp := adder_result; + when ALU_ADDI => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1)); + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + tmp := adder_result; + sgnb <= i(REG_WIDTH-1); + when ALU_CMPI => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1)); + adder_op2 <= not std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + adder_op3 <= '1'; + tmp := adder_result; + sgnb <= i(REG_WIDTH-1); + when ALU_SHL => tmp := shift_left (std_logic_vector(resize(unsigned(a), REG_WIDTH+1)), b); + when ALU_SHR => tmp := shift_right (std_logic_vector(resize(unsigned(a), REG_WIDTH+1)), b); + when ALU_SAR => tmp := shift_aright (std_logic_vector(resize( signed(a), REG_WIDTH+1)), b); + when ALU_ROLC => tmp := rotate_left (std_logic_vector(resize(unsigned(a), REG_WIDTH+1)), b(REG_WIDTH_LOG-1 downto 0), flags(FLAG_C)); + when ALU_RORC => tmp := rotate_right (std_logic_vector(resize(unsigned(a), REG_WIDTH+1)), b(REG_WIDTH_LOG-1 downto 0), flags(FLAG_C)); + when ALU_BSET => tmp(REG_WIDTH-1 downto 0) := a; tmp(to_integer(unsigned(i))) := '1'; + when ALU_BCLR => tmp(REG_WIDTH-1 downto 0) := a; tmp(to_integer(unsigned(i))) := '0'; + when ALU_BTEST => tmp := (others => '0'); tmp(0) := a(to_integer(unsigned(i))); + when ALU_SEXT => tmp(REG_WIDTH-1 downto 0) := std_logic_vector(resize(signed(a(REG_WIDTH/2-1 downto 0)), REG_WIDTH)); +------------------------------------------------------------------------------- + when ALU_BRZ => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1)); + if flags(FLAG_Z) = '1' then + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + pcchg <= '1'; + end if; + tmp := adder_result; + wr_flags := '0'; + when ALU_BRNZ => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1)); + if flags(FLAG_Z) = '0' then + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + pcchg <= '1'; + end if; + tmp := adder_result; + wr_flags := '0'; + when ALU_BRLE => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1)); + if flags(FLAG_Z) = '1' or flags(FLAG_N) /= flags(FLAG_V) then + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + pcchg <= '1'; + end if; + tmp := adder_result; + wr_flags := '0'; + when ALU_BRLT => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1)); + if flags(FLAG_Z) = '0' and flags(FLAG_N) /= flags(FLAG_V) then + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + pcchg <= '1'; + end if; + tmp := adder_result; + wr_flags := '0'; + when ALU_BRGE => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1)); + if flags(FLAG_Z) = '1' or flags(FLAG_N) = flags(FLAG_V) then + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + pcchg <= '1'; + end if; + tmp := adder_result; + wr_flags := '0'; + when ALU_BRGT => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1)); + if flags(FLAG_Z) = '0' and flags(FLAG_N) = flags(FLAG_V) then + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + pcchg <= '1'; + end if; + tmp := adder_result; + wr_flags := '0'; + when ALU_BRULE => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1)); + if flags(FLAG_Z) = '1' or flags(FLAG_C) = '1' then + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + pcchg <= '1'; + end if; + tmp := adder_result; + wr_flags := '0'; + when ALU_BRULT => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1)); + if flags(FLAG_Z) = '0' and flags(FLAG_C) = '1' then + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + pcchg <= '1'; + end if; + tmp := adder_result; + wr_flags := '0'; + when ALU_BRUGE => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1)); + if flags(FLAG_Z) = '1' or flags(FLAG_C) = '0' then + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + pcchg <= '1'; + end if; + tmp := adder_result; + wr_flags := '0'; + when ALU_BRUGT => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1)); + if flags(FLAG_Z) = '0' and flags(FLAG_C) = '0' then + adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1)); + pcchg <= '1'; + end if; + tmp := adder_result; + wr_flags := '0'; +------------------------------------------------------------------------------- + when ALU_JMP => tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + wr_flags := '0'; + when ALU_JMPZ => if flags(FLAG_Z) = '1' then + tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + else + tmp(REG_WIDTH-1 downto 0) := pc; + end if; + wr_flags := '0'; + when ALU_JMPNZ => if flags(FLAG_Z) = '0' then + tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + else + tmp(REG_WIDTH-1 downto 0) := pc; + end if; + wr_flags := '0'; + when ALU_JMPLE => if flags(FLAG_Z) = '1' or flags(FLAG_N) /= flags(FLAG_V) then + tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + else + tmp(REG_WIDTH-1 downto 0) := pc; + end if; + wr_flags := '0'; + when ALU_JMPLT => if flags(FLAG_Z) = '0' and flags(FLAG_N) /= flags(FLAG_V) then + tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + else + tmp(REG_WIDTH-1 downto 0) := pc; + end if; + wr_flags := '0'; + when ALU_JMPGE => if flags(FLAG_Z) = '1' or flags(FLAG_N) = flags(FLAG_V) then + tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + else + tmp(REG_WIDTH-1 downto 0) := pc; + end if; + wr_flags := '0'; + when ALU_JMPGT => if flags(FLAG_Z) = '0' and flags(FLAG_N) = flags(FLAG_V) then + tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + else + tmp(REG_WIDTH-1 downto 0) := pc; + end if; + wr_flags := '0'; + when ALU_JMPULE => if flags(FLAG_Z) = '1' or flags(FLAG_C) = '1' then + tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + else + tmp(REG_WIDTH-1 downto 0) := pc; + end if; + wr_flags := '0'; + when ALU_JMPULT => if flags(FLAG_Z) = '0' and flags(FLAG_C) = '1' then + tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + else + tmp(REG_WIDTH-1 downto 0) := pc; + end if; + wr_flags := '0'; + when ALU_JMPUGE => if flags(FLAG_Z) = '1' or flags(FLAG_C) = '0' then + tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + else + tmp(REG_WIDTH-1 downto 0) := pc; + end if; + wr_flags := '0'; + when ALU_JMPUGT => if flags(FLAG_Z) = '0' and flags(FLAG_C) = '0' then + tmp(REG_WIDTH-1 downto 0) := a; + pcchg <= '1'; + else + tmp(REG_WIDTH-1 downto 0) := pc; + end if; + wr_flags := '0'; +------------------------------------------------------------------------------- + when ALU_GETFL => tmp(REG_WIDTH-1 downto 0) := flags; + wr_flags := '0'; + when ALU_SETFL => next_flags <= a; + wr_flags := '0'; + when ALU_GETSHFL => tmp(REG_WIDTH-1 downto 0) := shflags; + wr_flags := '0'; + when ALU_SETSHFL => next_shflags <= a; + wr_flags := '0'; + when ALU_INTR => next_shflags <= flags; + next_flags(FLAG_I) <= '0'; + wr_flags := '0'; + when ALU_RETI => next_flags <= shflags; + wr_flags := '0'; + when ALU_SEI => next_flags(FLAG_I) <= '1'; + wr_flags := '0'; + when ALU_CLI => next_flags(FLAG_I) <= '0'; + wr_flags := '0'; +------------------------------------------------------------------------------- + when ALU_NOP => wr_flags := '0'; + when others => null; + end case; + when others => null; + end case; + + -- if the result is to be ignored, it will be ignored in the write-back stage + result <= tmp(REG_WIDTH-1 downto 0); + + -- the flags do not make sense with all instructions yet + if wr_flags = '1' then + next_flags(FLAG_C) <= tmp(REG_WIDTH); + next_flags(FLAG_N) <= tmp(REG_WIDTH-1); + next_flags(FLAG_Z) <= zero(tmp(REG_WIDTH-1 downto 0)); + next_flags(FLAG_V) <= sgna xor sgnb xor tmp(REG_WIDTH) xor tmp(REG_WIDTH-1); + next_flags(FLAG_P) <= parity(tmp(REG_WIDTH-1 downto 0)); + end if; + + if intr = '1' then + next_shflags <= flags; + next_flags(FLAG_I) <= '0'; + end if; + + end process compute; + +end behaviour; Index: decode.vhd =================================================================== --- decode.vhd (nonexistent) +++ decode.vhd (revision 8) @@ -0,0 +1,690 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA decode stage +------------------------------------------------------------------------------- +-- architecture for the instruction-decode pipeline stage +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.marca_pkg.all; + +architecture behaviour of decode is + +signal pc_reg : std_logic_vector(REG_WIDTH-1 downto 0); +signal dest_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal instr_reg : std_logic_vector(PDATA_WIDTH-1 downto 0); + +signal src1_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal src2_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0); + +component regfile is + port ( + clock : in std_logic; + reset : in std_logic; + hold : in std_logic; + rd1_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + rd2_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + rd1_val : out std_logic_vector(REG_WIDTH-1 downto 0); + rd2_val : out std_logic_vector(REG_WIDTH-1 downto 0); + wr_ena : in std_logic; + wr_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + wr_val : in std_logic_vector(REG_WIDTH-1 downto 0)); +end component; + +begin -- behaviour + + regfile_unit : regfile + port map ( + clock => clock, + reset => reset, + hold => hold, + rd1_addr => src1_reg, + rd2_addr => src2_reg, + rd1_val => op1, + rd2_val => op2, + wr_ena => wr_ena, + wr_addr => wr_dest, + wr_val => wr_val); + + syn_proc: process (clock, reset) + begin -- process syn_proc + if reset = RESET_ACTIVE then -- asynchronous reset (active low) + pc_reg <= (others => '0'); + dest_reg <= (others => '0'); + instr_reg <= OPC_PFX_C & OPC_PFX_C2 & OPC_PFX_C2a & OPC_NOP; + src1_reg <= (others => '0'); + src2_reg <= (others => '0'); + elsif clock'event and clock = '1' then -- rising clock edge + if hold = '0' then + if stall = '1' then + pc_reg <= (others => '0'); + dest_reg <= (others => '0'); + instr_reg <= OPC_PFX_C & OPC_PFX_C2 & OPC_PFX_C2a & OPC_NOP; + src1_reg <= (others => '0'); + src2_reg <= (others => '0'); + else + pc_reg <= pc_in; + dest_reg <= dest_in; + instr_reg <= instr; + src1_reg <= src1_in; + src2_reg <= src2_in; + end if; + end if; + end if; + end process syn_proc; + + feedthrough: process (pc_reg, src1_reg, src2_reg) + begin -- process feedthrough + pc_out <= pc_reg; + src1_out <= src1_reg; + src2_out <= src2_reg; + end process feedthrough; + + do_decode: process (instr_reg, src1_reg, src2_reg, dest_reg) + begin -- process + + -- all unknown opcodes trigger interrupt EXC_ERR + imm <= std_logic_vector(to_unsigned(EXC_ERR, REG_WIDTH)); + dest_out <= dest_reg; + aop <= ALU_INTR; + mop <= MEM_NOP; + iop <= INTR_INTR; + unit <= UNIT_INTR; + target <= TARGET_PC; + + case instr_reg(PDATA_WIDTH-1 downto PDATA_WIDTH-4) is + when + OPC_ADD => aop <= ALU_ADD; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= dest_reg; + when + OPC_SUB => aop <= ALU_SUB; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= dest_reg; + when + OPC_ADDC => aop <= ALU_ADDC; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= dest_reg; + when + OPC_SUBC => aop <= ALU_SUBC; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= dest_reg; + when + OPC_AND => aop <= ALU_AND; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= dest_reg; + when + OPC_OR => aop <= ALU_OR; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= dest_reg; + when + OPC_XOR => aop <= ALU_XOR; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= dest_reg; + when + OPC_MUL => aop <= ALU_MUL; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= dest_reg; + when + OPC_DIV => aop <= ALU_DIV; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= dest_reg; + when + OPC_UDIV => aop <= ALU_UDIV; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= dest_reg; + when + OPC_LDIL => imm <= std_logic_vector(resize(signed(dest_reg & src2_reg), REG_WIDTH)); + aop <= ALU_LDIL; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_LDIH => imm <= std_logic_vector(resize(signed(dest_reg & src2_reg), REG_WIDTH)); + aop <= ALU_LDIH; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_LDIB => imm <= std_logic_vector(resize(signed(dest_reg & src2_reg), REG_WIDTH)); + aop <= ALU_LDIB; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + + when + OPC_PFX_A => + case instr_reg(PDATA_WIDTH-5 downto PDATA_WIDTH-8) is + when + OPC_MOV => aop <= ALU_MOV; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_MOD => aop <= ALU_MOD; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_UMOD => aop <= ALU_UMOD; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_NOT => aop <= ALU_NOT; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_NEG => aop <= ALU_NEG; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_CMP => aop <= ALU_SUB; -- it's the same + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_ADDI => imm <= std_logic_vector(resize(signed(src2_reg), REG_WIDTH)); + aop <= ALU_ADDI; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_CMPI => imm <= std_logic_vector(resize(signed(src2_reg), REG_WIDTH)); + aop <= ALU_CMPI; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_SHL => aop <= ALU_SHL; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_SHR => aop <= ALU_SHR; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_SAR => aop <= ALU_SAR; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_ROLC => aop <= ALU_ROLC; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_RORC => aop <= ALU_RORC; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_BSET => imm <= std_logic_vector(resize(unsigned(src2_reg), REG_WIDTH)); + aop <= ALU_BSET; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_BCLR => imm <= std_logic_vector(resize(unsigned(src2_reg), REG_WIDTH)); + aop <= ALU_BCLR; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_BTEST => imm <= std_logic_vector(resize(unsigned(src2_reg), REG_WIDTH)); + aop <= ALU_BTEST; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_NONE; + dest_out <= src1_reg; + when others => null; + end case; + + when OPC_PFX_B => + case instr_reg(PDATA_WIDTH-5 downto PDATA_WIDTH-8) is + when + OPC_LOAD => mop <= MEM_LOAD; + aop <= ALU_NOP; + iop <= INTR_NOP; + unit <= UNIT_MEM; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_LOADL => mop <= MEM_LOADL; + aop <= ALU_NOP; + iop <= INTR_NOP; + unit <= UNIT_MEM; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_LOADH => mop <= MEM_LOADH; + aop <= ALU_NOP; + iop <= INTR_NOP; + unit <= UNIT_MEM; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_LOADB => mop <= MEM_LOADB; + aop <= ALU_NOP; + iop <= INTR_NOP; + unit <= UNIT_MEM; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_STORE => mop <= MEM_STORE; + aop <= ALU_NOP; + iop <= INTR_NOP; + unit <= UNIT_MEM; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_STOREL => mop <= MEM_STOREL; + aop <= ALU_NOP; + iop <= INTR_NOP; + unit <= UNIT_MEM; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_STOREH => mop <= MEM_STOREH; + aop <= ALU_NOP; + iop <= INTR_NOP; + unit <= UNIT_MEM; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_CALL => aop <= ALU_JMP; -- force alu_pcchg + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_CALL; + target <= TARGET_BOTH; + dest_out <= src1_reg; + when others => null; + end case; + + when OPC_PFX_C => + case instr_reg(PDATA_WIDTH-5 downto PDATA_WIDTH-8) is + when + OPC_BR => aop <= ALU_NOP; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_BRZ => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH)); + aop <= ALU_BRZ; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_BRNZ => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH)); + aop <= ALU_BRNZ; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_BRLE => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH)); + aop <= ALU_BRLE; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_BRLT => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH)); + aop <= ALU_BRLT; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_BRGE => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH)); + aop <= ALU_BRGE; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_BRGT => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH)); + aop <= ALU_BRGT; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_BRULE => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH)); + aop <= ALU_BRULE; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_BRULT => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH)); + aop <= ALU_BRULT; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_BRUGE => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH)); + aop <= ALU_BRUGE; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_BRUGT => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH)); + aop <= ALU_BRUGT; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_SEXT => aop <= ALU_SEXT; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_LDVEC => imm <= std_logic_vector(resize(unsigned(src2_reg), REG_WIDTH)); + iop <= INTR_LDVEC; + aop <= ALU_NOP; + mop <= MEM_NOP; + unit <= UNIT_INTR; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_STVEC => imm <= std_logic_vector(resize(unsigned(src2_reg), REG_WIDTH)); + iop <= INTR_STVEC; + aop <= ALU_NOP; + mop <= MEM_NOP; + unit <= UNIT_INTR; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_PFX_C1 => + case instr_reg(PDATA_WIDTH-9 downto PDATA_WIDTH-12) is + when + OPC_JMP => aop <= ALU_JMP; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_JMPZ => aop <= ALU_JMPZ; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_JMPNZ => aop <= ALU_JMPNZ; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_JMPLE => aop <= ALU_JMPLE; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_JMPLT => aop <= ALU_JMPLT; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_JMPGE => aop <= ALU_JMPGE; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_JMPGT => aop <= ALU_JMPGT; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_JMPULE => aop <= ALU_JMPULE; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_JMPULT => aop <= ALU_JMPULT; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_JMPUGE => aop <= ALU_JMPUGE; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_JMPUGT => aop <= ALU_JMPUGT; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_INTR => imm <= std_logic_vector(resize(unsigned(src1_reg), REG_WIDTH)); + aop <= ALU_INTR; + iop <= INTR_INTR; + mop <= MEM_NOP; + unit <= UNIT_INTR; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_GETFL => aop <= ALU_GETFL; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_SETFL => aop <= ALU_SETFL; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_GETIRA => iop <= INTR_GETIRA; + aop <= ALU_NOP; + mop <= MEM_NOP; + unit <= UNIT_INTR; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + + when + OPC_SETIRA => iop <= INTR_SETIRA; + aop <= ALU_NOP; + mop <= MEM_NOP; + unit <= UNIT_INTR; + target <= TARGET_NONE; + dest_out <= src1_reg; + when others => null; + end case; + + when + OPC_PFX_C2 => + case instr_reg(PDATA_WIDTH-9 downto PDATA_WIDTH-12) is + when + OPC_GETSHFL => aop <= ALU_GETSHFL; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_REGISTER; + dest_out <= src1_reg; + when + OPC_SETSHFL => aop <= ALU_SETSHFL; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_PFX_C2a => + case instr_reg(PDATA_WIDTH-13 downto PDATA_WIDTH-16) is + when + OPC_RETI => aop <= ALU_RETI; + iop <= INTR_RETI; + mop <= MEM_NOP; + unit <= UNIT_INTR; + target <= TARGET_PC; + dest_out <= src1_reg; + when + OPC_NOP => aop <= ALU_NOP; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_SEI => aop <= ALU_SEI; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_NONE; + dest_out <= src1_reg; + when + OPC_CLI => aop <= ALU_CLI; + mop <= MEM_NOP; + iop <= INTR_NOP; + unit <= UNIT_ALU; + target <= TARGET_NONE; + dest_out <= src1_reg; + when others => null; + end case; + when others => null; + end case; + when others => null; + end case; + when others => null; + end case; + + end process; + +end behaviour; Index: marca.vhd =================================================================== --- marca.vhd (nonexistent) +++ marca.vhd (revision 8) @@ -0,0 +1,288 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA top level architecture +------------------------------------------------------------------------------- +-- architecture of the processor itself +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +architecture behaviour of marca is + +component fetch + port ( + clock : in std_logic; + reset : in std_logic; + + hold : in std_logic; + + pcena : in std_logic; + pc_in : in std_logic_vector(REG_WIDTH-1 downto 0); + pc_out : out std_logic_vector(REG_WIDTH-1 downto 0); + + src1 : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + src2 : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + dest : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + instr : out std_logic_vector(PDATA_WIDTH-1 downto 0)); +end component; + +signal fetch_pc : std_logic_vector(REG_WIDTH-1 downto 0); +signal fetch_src1 : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal fetch_src2 : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal fetch_dest : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal fetch_instr : std_logic_vector(PDATA_WIDTH-1 downto 0); + +component decode + port ( + clock : in std_logic; + reset : in std_logic; + + hold : in std_logic; + stall : in std_logic; + + pc_in : in std_logic_vector(REG_WIDTH-1 downto 0); + pc_out : out std_logic_vector(REG_WIDTH-1 downto 0); + + instr : in std_logic_vector(PDATA_WIDTH-1 downto 0); + + src1_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + src1_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + src2_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + src2_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + + dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + + aop : out ALU_OP; + mop : out MEM_OP; + iop : out INTR_OP; + + op1 : out std_logic_vector(REG_WIDTH-1 downto 0); + op2 : out std_logic_vector(REG_WIDTH-1 downto 0); + imm : out std_logic_vector(REG_WIDTH-1 downto 0); + + unit : out UNIT_SELECTOR; + target : out TARGET_SELECTOR; + + wr_ena : in std_logic; + wr_dest : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + wr_val : in std_logic_vector(REG_WIDTH-1 downto 0)); +end component; + +signal decode_pc : std_logic_vector(REG_WIDTH-1 downto 0); +signal decode_op1 : std_logic_vector(REG_WIDTH-1 downto 0); +signal decode_op2 : std_logic_vector(REG_WIDTH-1 downto 0); +signal decode_imm : std_logic_vector(REG_WIDTH-1 downto 0); +signal decode_src1 : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal decode_src2 : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal decode_dest : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal decode_aop : ALU_OP; +signal decode_mop : MEM_OP; +signal decode_iop : INTR_OP; +signal decode_unit : UNIT_SELECTOR; +signal decode_target : TARGET_SELECTOR; +signal decode_instr : std_logic_vector(PDATA_WIDTH-1 downto 0); + +component execute is + port ( + clock : in std_logic; + reset : in std_logic; + + busy : out std_logic; + stall : in std_logic; + + pc_in : in std_logic_vector(REG_WIDTH-1 downto 0); + pcchg : out std_logic; + pc_out : out std_logic_vector(REG_WIDTH-1 downto 0); + + dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + + src1 : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + src2 : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + + aop : in ALU_OP; + mop : in MEM_OP; + iop : in INTR_OP; + + op1 : in std_logic_vector(REG_WIDTH-1 downto 0); + op2 : in std_logic_vector(REG_WIDTH-1 downto 0); + imm : in std_logic_vector(REG_WIDTH-1 downto 0); + + unit : in UNIT_SELECTOR; + target_in : in TARGET_SELECTOR; + target_out : out TARGET_SELECTOR; + + result : out std_logic_vector(REG_WIDTH-1 downto 0); + + fw_ena : in std_logic; + fw_dest : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + fw_val : in std_logic_vector(REG_WIDTH-1 downto 0); + + ext_in : in std_logic_vector(IN_BITS-1 downto 0); + ext_out : out std_logic_vector(OUT_BITS-1 downto 0)); +end component; + +signal exec_busy : std_logic; +signal exec_pcchg : std_logic; +signal exec_pc : std_logic_vector(REG_WIDTH-1 downto 0); +signal exec_dest : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal exec_target : TARGET_SELECTOR; +signal exec_result : std_logic_vector(REG_WIDTH-1 downto 0); + +component writeback is + port ( + clock : in std_logic; + reset : in std_logic; + + hold : in std_logic; + + pc_in : in std_logic_vector(REG_WIDTH-1 downto 0); + pcchg : in std_logic; + pc_out : out std_logic_vector(REG_WIDTH-1 downto 0); + pcena : out std_logic; + + dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + + target : in TARGET_SELECTOR; + result : in std_logic_vector(REG_WIDTH-1 downto 0); + + ena : out std_logic; + val : out std_logic_vector(REG_WIDTH-1 downto 0)); +end component; + +signal wb_pc : std_logic_vector(REG_WIDTH-1 downto 0); +signal wb_pcena : std_logic; +signal wb_dest : std_logic_vector(REG_COUNT_LOG-1 downto 0); +signal wb_ena : std_logic; +signal wb_val : std_logic_vector(REG_WIDTH-1 downto 0); + +signal decode_stall : std_logic; + +signal reset : std_logic; +signal meta_reset : std_logic; + +begin -- behaviour + + -- in the decode and execution stage we need to stall a little earlier + decode_stall <= exec_pcchg or wb_pcena; + + fetch_stage : fetch + port map ( + clock => clock, + reset => reset, + hold => exec_busy, + pcena => wb_pcena, + pc_in => wb_pc, + pc_out => fetch_pc, + src1 => fetch_src1, + src2 => fetch_src2, + dest => fetch_dest, + instr => fetch_instr); + + decode_stage : decode + port map ( + clock => clock, + reset => reset, + hold => exec_busy, + stall => decode_stall, + pc_in => fetch_pc, + pc_out => decode_pc, + instr => fetch_instr, + src1_in => fetch_src1, + src1_out => decode_src1, + src2_in => fetch_src2, + src2_out => decode_src2, + dest_in => fetch_dest, + dest_out => decode_dest, + aop => decode_aop, + mop => decode_mop, + iop => decode_iop, + op1 => decode_op1, + op2 => decode_op2, + imm => decode_imm, + unit => decode_unit, + target => decode_target, + wr_ena => wb_ena, + wr_dest => wb_dest, + wr_val => wb_val); + + execution_stage : execute + port map ( + clock => clock, + reset => reset, + busy => exec_busy, + stall => exec_pcchg, + pc_in => decode_pc, + pcchg => exec_pcchg, + pc_out => exec_pc, + dest_in => decode_dest, + dest_out => exec_dest, + src1 => decode_src1, + src2 => decode_src2, + aop => decode_aop, + mop => decode_mop, + iop => decode_iop, + op1 => decode_op1, + op2 => decode_op2, + imm => decode_imm, + unit => decode_unit, + target_in => decode_target, + target_out => exec_target, + result => exec_result, + fw_ena => wb_ena, + fw_dest => wb_dest, + fw_val => wb_val, + ext_in => ext_in, + ext_out => ext_out); + + writeback_stage : writeback + port map ( + clock => clock, + reset => reset, + hold => exec_busy, + pc_in => exec_pc, + pcchg => exec_pcchg, + pc_out => wb_pc, + pcena => wb_pcena, + dest_in => exec_dest, + dest_out => wb_dest, + target => exec_target, + result => exec_result, + ena => wb_ena, + val => wb_val); + + synchronize: process (clock, ext_reset, meta_reset) + begin + if clock'event and clock = '1' then + meta_reset <= ext_reset; + reset <= meta_reset; + end if; + end process synchronize; + +end behaviour; Index: regfile_ent.vhd =================================================================== --- regfile_ent.vhd (nonexistent) +++ regfile_ent.vhd (revision 8) @@ -0,0 +1,48 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA decode stage +------------------------------------------------------------------------------- +-- entity of the instruction-decode pipeline stage +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +entity regfile is + + port ( + clock : in std_logic; + reset : in std_logic; + hold : in std_logic; + rd1_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + rd2_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + rd1_val : out std_logic_vector(REG_WIDTH-1 downto 0); + rd2_val : out std_logic_vector(REG_WIDTH-1 downto 0); + wr_ena : in std_logic; + wr_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + wr_val : in std_logic_vector(REG_WIDTH-1 downto 0)); + +end regfile; Index: data_rom.vhd =================================================================== --- data_rom.vhd (nonexistent) +++ data_rom.vhd (revision 8) @@ -0,0 +1,166 @@ +-- megafunction wizard: %ROM: 1-PORT% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altsyncram + +-- ============================================================ +-- File Name: data_rom.vhd +-- Megafunction Name(s): +-- altsyncram +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 6.0 Build 202 06/20/2006 SP 1 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2006 Altera Corporation +--Your use of Altera Corporation's design tools, logic functions +--and other software and tools, and its AMPP partner logic +--functions, and any output files any of the foregoing +--(including device programming or simulation files), and any +--associated documentation or information are expressly subject +--to the terms and conditions of the Altera Program License +--Subscription Agreement, Altera MegaCore Function License +--Agreement, or other applicable license agreement, including, +--without limitation, that your use is for the sole purpose of +--programming logic devices manufactured by Altera and sold by +--Altera or its authorized distributors. Please refer to the +--applicable agreement for further details. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY data_rom IS + GENERIC + ( + init_file : STRING + ); + PORT + ( + address : IN STD_LOGIC_VECTOR (6 DOWNTO 0); + clken : IN STD_LOGIC ; + clock : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) + ); +END data_rom; + + +ARCHITECTURE SYN OF data_rom IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0); + + + + COMPONENT altsyncram + GENERIC ( + address_aclr_a : STRING; + init_file : STRING; + intended_device_family : STRING; + lpm_hint : STRING; + lpm_type : STRING; + numwords_a : NATURAL; + operation_mode : STRING; + outdata_aclr_a : STRING; + outdata_reg_a : STRING; + widthad_a : NATURAL; + width_a : NATURAL; + width_byteena_a : NATURAL + ); + PORT ( + clocken0 : IN STD_LOGIC ; + clock0 : IN STD_LOGIC ; + address_a : IN STD_LOGIC_VECTOR (6 DOWNTO 0); + q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + q <= sub_wire0(7 DOWNTO 0); + + altsyncram_component : altsyncram + GENERIC MAP ( + address_aclr_a => "NONE", + init_file => init_file, + intended_device_family => "Cyclone", + lpm_hint => "ENABLE_RUNTIME_MOD=NO", + lpm_type => "altsyncram", + numwords_a => 128, + operation_mode => "ROM", + outdata_aclr_a => "NONE", + outdata_reg_a => "UNREGISTERED", + widthad_a => 7, + width_a => 8, + width_byteena_a => 1 + ) + PORT MAP ( + clocken0 => clken, + clock0 => clock, + address_a => address, + q_a => sub_wire0 + ); + + + +END SYN; + +-- ============================================================ +-- CNX file retrieval info +-- ============================================================ +-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0" +-- Retrieval info: PRIVATE: AclrByte NUMERIC "0" +-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0" +-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" +-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +-- Retrieval info: PRIVATE: Clken NUMERIC "1" +-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" +-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone" +-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +-- Retrieval info: PRIVATE: MIFfilename STRING "src/rom.mif" +-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "128" +-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +-- Retrieval info: PRIVATE: RegAddr NUMERIC "1" +-- Retrieval info: PRIVATE: RegOutput NUMERIC "0" +-- Retrieval info: PRIVATE: SingleClock NUMERIC "1" +-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0" +-- Retrieval info: PRIVATE: WidthAddr NUMERIC "7" +-- Retrieval info: PRIVATE: WidthData NUMERIC "8" +-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE" +-- Retrieval info: CONSTANT: INIT_FILE STRING "src/rom.mif" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone" +-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "128" +-- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM" +-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" +-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED" +-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "7" +-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8" +-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +-- Retrieval info: USED_PORT: address 0 0 7 0 INPUT NODEFVAL address[6..0] +-- Retrieval info: USED_PORT: clken 0 0 0 0 INPUT NODEFVAL clken +-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock +-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0] +-- Retrieval info: CONNECT: @address_a 0 0 7 0 address 0 0 7 0 +-- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0 +-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +-- Retrieval info: CONNECT: @clocken0 0 0 0 0 clken 0 0 0 0 +-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +-- Retrieval info: GEN_FILE: TYPE_NORMAL data_rom.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL data_rom.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL data_rom.cmp FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL data_rom.bsf TRUE FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL data_rom_inst.vhd FALSE Index: divider.vhd =================================================================== --- divider.vhd (nonexistent) +++ divider.vhd (revision 8) @@ -0,0 +1,119 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA divider +------------------------------------------------------------------------------- +-- architecture for a bit-serial divider +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.marca_pkg.all; + +architecture behaviour of divider is + +signal reg_busy : std_logic; +signal reg_denom : std_logic_vector(2*width-2 downto 0); +signal reg_remain : std_logic_vector(width-1 downto 0); +signal reg_quotient : std_logic_vector(width-1 downto 0); +signal reg_hotbit : std_logic_vector(width-1 downto 0); + +signal next_busy : std_logic; +signal next_denom : std_logic_vector(2*width-2 downto 0); +signal next_remain : std_logic_vector(width-1 downto 0); +signal next_quotient : std_logic_vector(width-1 downto 0); +signal next_hotbit : std_logic_vector(width-1 downto 0); + +begin -- behaviour + + busy <= reg_busy; + quotient <= reg_quotient; + remain <= reg_remain; + + syn_proc: process (clock, reset) + begin -- process sync + + if reset = RESET_ACTIVE then -- asynchronous reset (active low) + + reg_busy <= '0'; + reg_denom <= (others => '0'); + reg_remain <= (others => '0'); + reg_quotient <= (others => '0'); + reg_hotbit <= (others => '0'); + reg_hotbit(0) <= '1'; + + elsif clock'event and clock = '1' then -- rising clock edge + + if trigger = '1' then + reg_denom(2*width-2 downto width-1) <= denom; + reg_denom(width-2 downto 0) <= (others => '0'); + reg_remain <= numer; + reg_quotient <= (others => '0'); + reg_hotbit(width-1) <= '1'; + reg_hotbit(width-2 downto 0) <= (others => '0'); + if zero(denom) = '1' then + exc <= '1'; + reg_busy <= '0'; + else + exc <= '0'; + reg_busy <= '1'; + end if; + else + reg_denom <= next_denom; + reg_remain <= next_remain; + reg_quotient <= next_quotient; + reg_hotbit <= next_hotbit; + reg_busy <= next_busy; + exc <= '0'; + end if; + + end if; + end process syn_proc; + + compute: process (reg_denom, reg_remain, reg_quotient, reg_hotbit) + variable tmp_remain : std_logic_vector(2*width-2 downto 0); + begin -- process compute + + next_denom <= '0' & reg_denom(2*width-2 downto 1); + next_remain <= reg_remain; + next_quotient <= reg_quotient; + next_hotbit <= '0' & reg_hotbit(width-1 downto 1); + + if reg_hotbit(0) = '1' then + next_hotbit <= reg_hotbit; + next_busy <= '0'; + else + next_busy <= '1'; + end if; + + tmp_remain := std_logic_vector(resize(unsigned(reg_remain), 2*width-1) - unsigned(reg_denom)); + if tmp_remain(2*width-2) = '0' then + next_remain <= tmp_remain(width-1 downto 0); + next_quotient <= reg_quotient or reg_hotbit; + end if; + + end process compute; + +end behaviour; Index: alu_ent.vhd =================================================================== --- alu_ent.vhd (nonexistent) +++ alu_ent.vhd (revision 8) @@ -0,0 +1,56 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA ALU +------------------------------------------------------------------------------- +-- entity for the ALU +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +entity alu is + + port ( + clock : in std_logic; + reset : in std_logic; + + op : in ALU_OP; + + a : in std_logic_vector(REG_WIDTH-1 downto 0); + b : in std_logic_vector(REG_WIDTH-1 downto 0); + i : in std_logic_vector(REG_WIDTH-1 downto 0); + pc : in std_logic_vector(REG_WIDTH-1 downto 0); + + intr : in std_logic; + + exc : out std_logic; + + iena : out std_logic; + pcchg : out std_logic; + busy : out std_logic; + result : out std_logic_vector(REG_WIDTH-1 downto 0)); + +end alu; Index: marca_ent.vhd =================================================================== --- marca_ent.vhd (nonexistent) +++ marca_ent.vhd (revision 8) @@ -0,0 +1,42 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA top level entity +------------------------------------------------------------------------------- +-- entity definition for the processor itself +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +entity marca is + + port ( + clock : in std_logic; + ext_reset : in std_logic; + ext_in : in std_logic_vector(IN_BITS-1 downto 0); + ext_out : out std_logic_vector(OUT_BITS-1 downto 0)); + +end marca; Index: fetch.vhd =================================================================== --- fetch.vhd (nonexistent) +++ fetch.vhd (revision 8) @@ -0,0 +1,121 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA fetch stage +------------------------------------------------------------------------------- +-- architecture for the instruction-fetch pipeline stage +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.marca_pkg.all; + +architecture behaviour of fetch is + +component code_memory + generic ( + init_file : string); + port ( + clken : in std_logic; + clock : in std_logic; + address : in std_logic_vector (PADDR_WIDTH-1 downto 0); + q : out std_logic_vector (PDATA_WIDTH-1 downto 0)); +end component; + +signal enable : std_logic; + +signal address : std_logic_vector(PADDR_WIDTH-1 downto 0); +signal data : std_logic_vector(PDATA_WIDTH-1 downto 0); + +signal pc_reg : std_logic_vector(REG_WIDTH-1 downto 0); +signal next_pc : std_logic_vector(REG_WIDTH-1 downto 0); + +signal next_pc_out : std_logic_vector(REG_WIDTH-1 downto 0); + +begin -- behaviour + + enable <= not hold; + pc_out <= pc_reg; + + code_memory_unit : code_memory + generic map ( + init_file => "../vhdl/code.mif") + port map ( + address => address(PADDR_WIDTH-1 downto 0), + clken => enable, + clock => clock, + q => data); + + syn_proc: process (clock, reset) + begin -- process syn_proc + if reset = RESET_ACTIVE then -- asynchronous reset (active low) + pc_reg <= (others => '0'); + elsif clock'event and clock = '1' then -- rising clock edge + if hold = '0' then + pc_reg <= next_pc; + end if; + end if; + end process syn_proc; + + increment: process (pc_reg, pc_in, pcena, data) + begin -- process increment + if pcena = '1' then + next_pc <= pc_in; + else + -- "predict" hard branches + if data(PDATA_WIDTH-1 downto PDATA_WIDTH-8) = OPC_PFX_C & OPC_BR then + next_pc <= std_logic_vector(signed(pc_reg) + signed(data(7 downto 0))); + else + next_pc <= std_logic_vector(unsigned(pc_reg) + 1); + end if; + end if; + end process increment; + + forward: process (pc_reg, pc_in, pcena, data, reset) + begin -- process forward + if reset = RESET_ACTIVE then + address <= (others => '0'); + else + if pcena = '1' then + address <= pc_in(PADDR_WIDTH-1 downto 0); + else + if data(PDATA_WIDTH-1 downto PDATA_WIDTH-8) = OPC_PFX_C & OPC_BR then + address <= std_logic_vector(signed(pc_reg) + signed(data(7 downto 0)))(PADDR_WIDTH-1 downto 0); + else + address <= std_logic_vector(unsigned(pc_reg) + 1)(PADDR_WIDTH-1 downto 0); + end if; + end if; + end if; + end process forward; + + spread: process (data) + begin -- process spread + src1 <= data(3 downto 0); + src2 <= data(7 downto 4); + dest <= data(11 downto 8); + instr <= data; + end process spread; + +end behaviour; Index: decode_ent.vhd =================================================================== --- decode_ent.vhd (nonexistent) +++ decode_ent.vhd (revision 8) @@ -0,0 +1,71 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA decode stage +------------------------------------------------------------------------------- +-- entity definition for the instruction-decode pipeline stage +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +entity decode is + + port ( + clock : in std_logic; + reset : in std_logic; + + hold : in std_logic; + stall : in std_logic; + + pc_in : in std_logic_vector(REG_WIDTH-1 downto 0); + pc_out : out std_logic_vector(REG_WIDTH-1 downto 0); + + instr : in std_logic_vector(PDATA_WIDTH-1 downto 0); + + src1_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + src1_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + src2_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + src2_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + + dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0); + + aop : out ALU_OP; + mop : out MEM_OP; + iop : out INTR_OP; + + op1 : out std_logic_vector(REG_WIDTH-1 downto 0); + op2 : out std_logic_vector(REG_WIDTH-1 downto 0); + imm : out std_logic_vector(REG_WIDTH-1 downto 0); + + unit : out UNIT_SELECTOR; + target : out TARGET_SELECTOR; + + wr_ena : in std_logic; + wr_dest : in std_logic_vector(REG_COUNT_LOG-1 downto 0); + wr_val : in std_logic_vector(REG_WIDTH-1 downto 0)); + +end decode; Index: divider_ent.vhd =================================================================== --- divider_ent.vhd (nonexistent) +++ divider_ent.vhd (revision 8) @@ -0,0 +1,50 @@ +-- This file is part of the marca processor. +-- Copyright (C) 2007 Wolfgang Puffitsch + +-- This program is free software; you can redistribute it and/or modify it +-- under the terms of the GNU Library General Public License as published +-- by the Free Software Foundation; either version 2, 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 +-- Library General Public License for more details. + +-- You should have received a copy of the GNU Library General Public +-- License along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +------------------------------------------------------------------------------- +-- MARCA divider +------------------------------------------------------------------------------- +-- entity of a bit-serial divider +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Wolfgang Puffitsch +-- Computer Architecture Lab, Group 3 +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +use work.marca_pkg.all; + +entity divider is + + generic ( + width : integer := REG_WIDTH); + + port ( + clock : in std_logic; + reset : in std_logic; + trigger : in std_logic; + denom : in std_logic_vector(width-1 downto 0); + numer : in std_logic_vector(width-1 downto 0); + exc : out std_logic; + busy : out std_logic; + quotient : out std_logic_vector(width-1 downto 0); + remain : out std_logic_vector(width-1 downto 0)); + +end divider;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.