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;