----------------------------------------------------------------- -- -- ----------------------------------------------------------------- -- -- constants.vhd - -- -- Copyright(c) SEND GmbH 2000 -- -- Author: KLAUS SCHLEISIEK -- Created on: 16.06.2009 15:48:50 -- Last change: KS 16.06.2009 16:41:13 -- -- Do not use this file except in compliance with the License. You may -- obtain a copy of the License at http://www.microcore.org/License/ -- Software distributed under the License is distributed on an "AS IS" basis, -- WITHOUT WARRANTY OF ANY KIND, either express or implied. -- See the License for the specific language governing rights and limitations -- under the License. -- -- The Original Code is: MicroCore constants.vhd 1.40 -- -- The Initial Developer of the Original Code is Klaus.Schleisiek AT microcore.org. -- -- Introduction see: information/uCore_Introduction.pdf -- Tools see: information/uCore_Implementation.pdf -- Versions see: uCore_Versions.txt -- License see: information/uCore_License.pdf -- Conventions see: information/uCore_Conventions.pdf -- Contributors see: information/uCore_Contributors.pdf -- -- Defining all MicroCore bus-widths and records, as well as the -- opcode fields. LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE work.functions.ALL; PACKAGE constants IS CONSTANT version : NATURAL := 142; CONSTANT simulation : STD_LOGIC := '1'; -- will increase the frequency of timers to make them observable in simulation CONSTANT tri_state : STD_LOGIC := '1'; -- '1' uses tri-stated bus, '0' uses multiplexers CONSTANT keeper : STD_LOGIC := '0'; -- '1' uses bus keepers on outputs instead of latches CONSTANT syn_stackram : STD_LOGIC := '1'; -- '1' when stack ram will be realised by block ram CONSTANT with_mult : STD_LOGIC := '0'; -- '1' when FPGA has hardware multiply resources CONSTANT with_locals : STD_LOGIC := '1'; -- '1' when RSP+TOS addressing mode CONSTANT with_tasks : STD_LOGIC := '1'; -- '1' when TASK+TOS addressing mode CONSTANT sys_frequency : NATURAL := 12288000; -- Hz CONSTANT phase_1 : NATURAL := 1; -- number of cycles for address computation phase CONSTANT phase_2 : NATURAL := 1; -- number of cycles for memory access & execution phase CONSTANT baudrate : NATURAL := 512000; -------------------------------------------------------------------------- -- microcore busses -------------------------------------------------------------------------- CONSTANT data_width : NATURAL := 16; -- data bus width CONSTANT data_nibbles : NATURAL := ceiling(data_width, 8); --CONSTANT inst_width : NATURAL := 16; -- instruction width CONSTANT prog_addr_width : NATURAL := 12; -- program memory address width CONSTANT boot_addr_width : NATURAL := 12; -- size of the internal boot program memory CONSTANT pcache_addr_width : NATURAL := 8; -- prog. cache memory address width CONSTANT prog_ram_width : NATURAL := 8; -- writeable program memory address width, at most data_addr_width-2 -- 0 => canonical Harvard Architecture CONSTANT ds_addr_width : NATURAL := 5; -- data stack pointer width CONSTANT tasks_addr_width : NATURAL := 3; -- 2**tasks_addr_width copies of the stack areas will be provided -- data memory parameters ****** data_addr_width > tasks_addr_width+rs_addr_width CONSTANT data_addr_width : NATURAL := 12; -- data memory address width, at most data_width-1 because of I/O space CONSTANT dcache_addr_width : NATURAL := 8; -- data cache memory address width, at most see "data_addr_width" CONSTANT rs_base_width : NATURAL := 12; -- return stack base address width - data_width-rs_base_width = number of leading '0's of rstack address; data_width must be at least 1 larger than rs_base_width CONSTANT rs_addr_width : NATURAL := 5; -- return stack pointer width CONSTANT usr_vect_width : NATURAL := 3; -- each vector has room for 2**usr_vec_width instructions CONSTANT reg_addr_width : NATURAL := 5; -- number of address bits reserved for internal registers at the top data space SUBTYPE byte IS STD_LOGIC_VECTOR(7 DOWNTO 0); SUBTYPE data_bus IS STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); SUBTYPE inst_bus IS STD_LOGIC_VECTOR(15 DOWNTO 0); SUBTYPE inst_stack IS STD_LOGIC_VECTOR( 1 DOWNTO 0); SUBTYPE inst_group IS STD_LOGIC_VECTOR( 7 DOWNTO 0); -- some synthesizers do not support SIGNALS in a package. Therefore, the INST-register -- has to be routed into each entity explicitly as well as the field specific SIGNALs SUBTYPE data_addr IS STD_LOGIC_VECTOR(data_addr_width-1 DOWNTO 0); SUBTYPE program_addr IS STD_LOGIC_VECTOR(prog_addr_width-1 DOWNTO 0); SUBTYPE boot_addr IS STD_LOGIC_VECTOR(boot_addr_width-1 DOWNTO 0); SUBTYPE reg_addr IS STD_LOGIC_VECTOR(reg_addr_width-1 DOWNTO 0); SUBTYPE ds_addr IS STD_LOGIC_VECTOR(ds_addr_width+tasks_addr_width-1 DOWNTO 0); SUBTYPE rs_addr IS STD_LOGIC_VECTOR(rs_addr_width+tasks_addr_width-1 DOWNTO 0); -------------------------------------------------------------------------- -- status register -------------------------------------------------------------------------- CONSTANT s_c_bit : NATURAL := 0; -- carry bit CONSTANT s_ovl_bit : NATURAL := 1; -- Overflow-bit of UDIVS instruction CONSTANT s_ie_bit : NATURAL := 2; -- Interrupt Enable bit CONSTANT s_iis_bit : NATURAL := 3; -- InterruptInService bit CONSTANT s_lit_bit : NATURAL := 4; -- LIT bit of the previous instruction CONSTANT s_n_bit : NATURAL := 5; -- Sign-bit of top data element (TOS or sometimes NOS) CONSTANT s_z_bit : NATURAL := 6; -- Zero-bit of top data element (TOS or sometimes NOS) CONSTANT s_times : NATURAL := 7; CONSTANT times_width : NATURAL := 5; CONSTANT status_width : NATURAL := s_times+times_width; -------------------------------------------------------------------------- -- microcore physical addresses and memory mapped registers -------------------------------------------------------------------------- CONSTANT addr_reset : program_addr := to_vec(0, prog_addr_width); CONSTANT vect_isr : NATURAL := 1; CONSTANT addr_isr : program_addr := to_vec(vect_isr*2**usr_vect_width, prog_addr_width); CONSTANT vect_esr : NATURAL := 2; CONSTANT addr_esr : program_addr := to_vec(vect_esr*2**usr_vect_width, prog_addr_width); CONSTANT vect_ovfl : NATURAL := 3; CONSTANT addr_ovfl : program_addr := to_vec(vect_ovfl*2**usr_vect_width, prog_addr_width); CONSTANT max_registers : INTEGER := 9; CONSTANT STATUS_REGISTER : INTEGER := 9; CONSTANT DATA_RAM : INTEGER := 8; CONSTANT PROGRAM_RAM : INTEGER := 7; CONSTANT PC_REGISTER : INTEGER := 6; CONSTANT NOS_REGISTER : INTEGER := 5; CONSTANT DSP_REGISTER : INTEGER := 4; CONSTANT TOR_REGISTER : INTEGER := 3; CONSTANT RSP_REGISTER : INTEGER := 2; CONSTANT TOS_REGISTER : INTEGER := 1; CONSTANT ALU_TERM : INTEGER := 0; CONSTANT INT_REGISTER : INTEGER := -1; -- ints@ and ie! CONSTANT FLAG_REGISTER : INTEGER := -2; -- flags@ CONSTANT TASK_REGISTER : INTEGER := -3; -- base register for +tld and +tst instructions CONSTANT SEMA_REGISTER : INTEGER := -4; CONSTANT VERSION_REGISTER : INTEGER := -5; CONSTANT DEBUG_REGISTER : INTEGER := -6; -- umbilical interface CONSTANT CTRL_REGISTER : INTEGER := -7; CONSTANT TIME_REGISTER : INTEGER := -8; CONSTANT min_registers : INTEGER := -8; --(2**reg_addr_width)+DATA_RAM+1; TYPE data_sources IS ARRAY (max_registers DOWNTO min_registers) OF data_bus; TYPE data_select IS ARRAY (max_registers DOWNTO min_registers) OF STD_LOGIC; CONSTANT set_reset : NATURAL := 0; -- bit 0 is used as value field in bit wise writeable registers CONSTANT IS_INT : reg_addr := to_vec(INT_REGISTER, reg_addr_width); CONSTANT IS_FLAG : reg_addr := to_vec(FLAG_REGISTER, reg_addr_width); CONSTANT f_dtr : NATURAL := 0; CONSTANT i_ext : NATURAL := 1; CONSTANT interrupts : NATURAL := 1; -- maskable interrupt sources CONSTANT flag_width : NATURAL := 2; CONSTANT IS_TASK : reg_addr := to_vec(TASK_REGISTER, reg_addr_width); CONSTANT IS_SEMAPHOR : reg_addr := to_vec(SEMA_REGISTER, reg_addr_width); CONSTANT sema0 : NATURAL := 0; CONSTANT sema_width : NATURAL := 1; CONSTANT green : STD_LOGIC := '0'; CONSTANT red : STD_LOGIC := '1'; CONSTANT IS_DEBUG : reg_addr := to_vec(DEBUG_REGISTER, reg_addr_width); CONSTANT mark_start : byte := "00110011"; -- umbilical CONSTANT mark_reset : byte := "11001100"; -- control CONSTANT mark_debug : byte := "10101010"; -- codes CONSTANT mark_ack : byte := "11111111"; CONSTANT mark_nack : byte := "00000000"; CONSTANT IS_CTRL : reg_addr := to_vec(CTRL_REGISTER, reg_addr_width); CONSTANT c_sema0 : NATURAL := 1; CONSTANT ctrl_width : NATURAL := 1; CONSTANT IS_TIME : reg_addr := to_vec(TIME_REGISTER, reg_addr_width); CONSTANT ticks_per_ms: NATURAL := 4; CONSTANT max_delay : NATURAL := 5000; -- ms CONSTANT delay_width : NATURAL := log2(2*max_delay*ticks_per_ms); -- 2* because sign bit is used for > function -- please note that DELAY_WIDTH can not be wider than DATA_WIDTH -------------------------------------------------------------------------- -- microcore record definitions -------------------------------------------------------------------------- TYPE uBus_port IS RECORD en : STD_LOGIC; -- bus_en for tri-state implementation sel_io : STD_LOGIC; -- RAM & IO address space, includes Returnstack write : STD_LOGIC; -- 1 => write, 0 => read wr_status : STD_LOGIC; -- status register write enable wr_sema : STD_LOGIC; -- semaphor register write enable registers : reg_addr; -- register select address sources : data_sources; -- array of most register outputs addr : data_bus; -- address on uBus data : data_bus; -- data on uBus END RECORD; -- Control lines for Programm Memory TYPE progmem_port IS RECORD write : STD_LOGIC; addr : program_addr; din : inst_bus; dout : inst_bus; END RECORD; -- umbilical interface TYPE umbilical_port IS RECORD rx_data : byte; -- input data buffer OUT rx_read : STD_LOGIC; -- read and clear data buffer IN rx_full : STD_LOGIC; -- data buffer full OUT tx_data : byte; -- output data IN tx_write : STD_LOGIC; -- write into data buffer IN tx_empty : STD_LOGIC; -- data buffer empty OUT tx_busy : STD_LOGIC; -- transmission under way OUT END RECORD; -------------------------------------------------------------------------- -- op codes -------------------------------------------------------------------------- FUNCTION is_CALL (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN; FUNCTION is_LIT (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN; FUNCTION is_QBRANCH(i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN; FUNCTION is_BRANCH (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN; FUNCTION is_MEM (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN; FUNCTION is_ZPAGE (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN; FUNCTION is_RSP (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN; FUNCTION is_TASK (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN; FUNCTION is_REG (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN; FUNCTION is_ALU (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN; -------------------------------------------------------------------------- -- STACK -------------------------------------------------------------------------- -- Code Name Action -- 00 NONE Type dependent -- 01 POP Stack->NOS->TOS -- 10 PUSH TOS->NOS->Stack -------------------------------------------------------------------------- CONSTANT op_NONE : inst_stack := "00"; CONSTANT op_POP : inst_stack := "10"; CONSTANT op_PUSH : inst_stack := "01"; -------------------------------------------------------------------------- -- REG -------------------------------------------------------------------------- -- stack CONSTANT op_TOS : inst_group := X"00"; CONSTANT op_NOS : inst_group := X"01"; CONSTANT op_SWAP : inst_group := X"02"; CONSTANT op_TUCK : inst_group := X"03"; CONSTANT op_UNDER : inst_group := X"04"; -- flags CONSTANT op_CS : inst_group := X"10"; CONSTANT op_CS_N : inst_group := X"11"; CONSTANT op_OVFL : inst_group := X"12"; CONSTANT op_OVFL_N : inst_group := X"13"; CONSTANT op_COMPC : inst_group := X"14"; -- registers -------------------------------------------------------------------------- -- ALU -------------------------------------------------------------------------- -- ALU POP and ALU PUSH CONSTANT op_ADD : inst_group := "000"; CONSTANT op_ADC : inst_group := "001"; CONSTANT op_SUB : inst_group := "010"; CONSTANT op_SSUB : inst_group := "011"; CONSTANT op_AND : inst_group := "100"; CONSTANT op_OR : inst_group := "101"; CONSTANT op_XOR : inst_group := "110"; -- Unary-Operators -- ALU BOTH CONSTANT op_NOT : inst_group := "000"; CONSTANT op_SL : inst_group := "001"; CONSTANT op_ASR : inst_group := "010"; CONSTANT op_LSR : inst_group := "011"; CONSTANT op_ROR : inst_group := "100"; CONSTANT op_ROL : inst_group := "101"; CONSTANT op_ZEQU : inst_group := "110"; CONSTANT op_CC : inst_group := "111"; -- evtl. hier 0< realisieren -- Mathstep-Operators -- ALU NONE CONSTANT op_MULTS : inst_group := "000"; CONSTANT op_0DIVS : inst_group := "001"; CONSTANT op_UDIVS : inst_group := "010"; CONSTANT op_LDIVS : inst_group := "011"; CONSTANT op_CRC : inst_group := "100"; CONSTANT op_PACK : inst_group := "101"; CONSTANT op_UNPACK : inst_group := "110"; -- Conditions -- BRA POP CONSTANT op_NEVER : inst_group := "000"; CONSTANT op_ALWAYS : inst_group := "001"; CONSTANT op_ZERO : inst_group := "010"; CONSTANT op_NZERO : inst_group := "011"; CONSTANT op_SIGN : inst_group := "100"; CONSTANT op_NSIGN : inst_group := "101"; CONSTANT op_NOVL : inst_group := "110"; CONSTANT op_NCARRY : inst_group := "111"; -- Special Branches -- BRA PUSH CONSTANT op_DUP : inst_group := "000"; --CONSTANT : inst_group := "001"; --CONSTANT op_QDUP : inst_group := "010"; --CONSTANT : inst_group := "011"; CONSTANT op_NEXT : inst_group := "100"; CONSTANT op_IRET : inst_group := "101"; CONSTANT op_TIMES : inst_group := "110"; CONSTANT op_EVENT : inst_group := "111"; -- Registers -- MEM NONE and MEM BOTH CONSTANT op_STATUS : inst_group := "000"; CONSTANT op_TOR : inst_group := "001"; CONSTANT op_RSTACK : inst_group := "010"; CONSTANT op_LOCAL : inst_group := "011"; CONSTANT op_RSP : inst_group := "100"; CONSTANT op_DSP : inst_group := "101"; CONSTANT op_TASK : inst_group := "110"; CONSTANT op_INTFL : inst_group := "111"; -- User instructions CONSTANT op_INT : inst_usr := "00001"; --to_vec(vect_isr, 5); CONSTANT op_EXC : inst_usr := "00010"; --to_vec(vect_esr, 5); CONSTANT op_QOVL : inst_usr := "00011"; --to_vec(vect_ovfl, 5); -- Concatenated instructions END constants; PACKAGE BODY constants IS FUNCTION is_CALL (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN IS VARIABLE temp : BOOLEAN; BEGIN IF i(i'high)='1' THEN temp := true; ELSE temp := false; END IF; RETURN temp; END; FUNCTION is_LIT (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN IS VARIABLE temp : BOOLEAN; BEGIN IF i(i'high DOWNTO i'high-1)="01" THEN temp := true; ELSE temp := false; END IF; RETURN temp; END; FUNCTION is_QBRANCH(i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN IS VARIABLE temp : BOOLEAN; BEGIN IF i(i'high DOWNTO i'high-3)="0011" THEN temp := true; ELSE temp := false; END IF; RETURN temp; END; FUNCTION is_BRANCH (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN IS VARIABLE temp : BOOLEAN; BEGIN IF i(i'high DOWNTO i'high-3)="0010" THEN temp := true; ELSE temp := false; END IF; RETURN temp; END; FUNCTION is_MEM (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN IS VARIABLE temp : BOOLEAN; BEGIN IF i(i'high DOWNTO i'high-4)="00011" THEN temp := true; ELSE temp := false; END IF; RETURN temp; END; FUNCTION is_ZPAGE (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN IS VARIABLE temp : BOOLEAN; BEGIN IF i(i'high DOWNTO i'high-4)="00010" AND i(i'high-7)='1' THEN temp := true; ELSE temp := false; END IF; RETURN temp; END; FUNCTION is_RSP (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN IS VARIABLE temp : BOOLEAN; BEGIN IF i(i'high DOWNTO i'high-4)="00010" AND i(i'high-7 DOWNTO i'high-8)="01" THEN temp := true; ELSE temp := false; END IF; RETURN temp; END; FUNCTION is_TASK (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN IS VARIABLE temp : BOOLEAN; BEGIN IF i(i'high DOWNTO i'high-4)="00010" AND i(i'high-7 DOWNTO i'high-8)="00" THEN temp := true; ELSE temp := false; END IF; RETURN temp; END; FUNCTION is_REG (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN IS VARIABLE temp : BOOLEAN; BEGIN IF i(i'high DOWNTO i'high-4)="00001" THEN temp := true; ELSE temp := false; END IF; RETURN temp; END; FUNCTION is_ALU (i : IN STD_LOGIC_VECTOR) RETURN BOOLEAN IS VARIABLE temp : BOOLEAN; BEGIN IF i(i'high DOWNTO i'high-4)="00000" THEN temp := true; ELSE temp := false; END IF; RETURN temp; END; END constants;