--------------------------------------------------------------------------------- -- -- Package: mbl_Pkg -- Filename: mbl_Pkg.vhd -- Description: Package for the TUD MB-Lite implementation -- -- Author: Huib Lincklaen Arriens -- Delft University of Technology -- Faculty EEMCS, Department ME&CE, Circuits and Systems -- Date: September, 2010 -- -- Modified: September, 2013: Removed FSL -- June, 2011: ALU_ACTION_Type extended to incorporate -- MUL and BS instructions (Huib) -- Adapted to work with separate fsl_M- -- and fsl_S selectors and automatic -- tumbl<_jtag><_fsl>.vhd generation (Huib) -- July, 2011: function ef_nbits added (Huib) -- Remarks: -- -------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_unsigned.all; USE IEEE.numeric_std.all; -------------------------------------------------------------------------------- PACKAGE mbl_Pkg IS -------------------------------------------------------------------------------- CONSTANT C_8_ZEROS : STD_LOGIC_VECTOR ( 7 DOWNTO 0) := X"00"; CONSTANT C_16_ZEROS : STD_LOGIC_VECTOR (15 DOWNTO 0) := X"0000"; CONSTANT C_24_ZEROS : STD_LOGIC_VECTOR (23 DOWNTO 0) := X"000000"; CONSTANT C_32_ZEROS : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000"; CONSTANT C_16_ONES : STD_LOGIC_VECTOR (15 DOWNTO 0) := X"FFFF"; CONSTANT C_24_ONES : STD_LOGIC_VECTOR (23 DOWNTO 0) := X"FFFFFF"; ---------------------------------------------------------------------------------------------- -- TYPE DEFINITIONS ---------------------------------------------------------------------------------------------- TYPE ALU_ACTION_Type IS (A_NOP, A_ADD, A_CMP, A_CMPU, A_OR, A_AND, A_XOR, A_SHIFT, A_SEXT8, A_SEXT16, A_MFS, A_MTS, A_MUL, A_BSLL, A_BSRL, A_BSRA, A_HALT); TYPE ALU_IN1_Type IS (ALU_IN_REGA, ALU_IN_NOT_REGA, ALU_IN_PC, ALU_IN_ZERO); TYPE ALU_IN2_Type IS (ALU_IN_REGB, ALU_IN_NOT_REGB, ALU_IN_IMM, ALU_IN_NOT_IMM); TYPE ALU_CIN_Type IS (CIN_ZERO, CIN_ONE, FROM_MSR, FROM_IN1); TYPE MSR_ACTION_Type IS (UPDATE_CARRY, KEEP_CARRY); TYPE BRANCH_ACTION_Type IS (NO_BR, BR, BRL, BEQ, BNE, BLT, BLE, BGT, BGE); TYPE WRB_ACTION_Type IS (NO_WRB, WRB_EX, WRB_MEM); TYPE MEM_ACTION_Type IS (NO_MEM, WR_MEM, RD_MEM); TYPE TRANSFER_SIZE_Type IS (WORD, HALFWORD, BYTE); TYPE SAVE_REG_Type IS (NO_SAVE, SAVE_RA, SAVE_RB); -- TYPE IF2ID_Type IS RECORD program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0); END RECORD; TYPE ID2EX_Type IS RECORD program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0); rdix_rA : STD_LOGIC_VECTOR ( 4 DOWNTO 0); rdix_rB : STD_LOGIC_VECTOR ( 4 DOWNTO 0); curr_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0); alu_Action : ALU_ACTION_Type; alu_Op1 : ALU_IN1_Type; alu_Op2 : ALU_IN2_Type; alu_Cin : ALU_CIN_Type; IMM16 : STD_LOGIC_VECTOR (15 DOWNTO 0); IMM_Lock : STD_LOGIC; msr_Action : MSR_ACTION_Type; branch_Action : BRANCH_ACTION_Type; mem_Action : MEM_ACTION_Type; -- rd_mem implies writeback transfer_Size : TRANSFER_SIZE_Type; wrb_Action : WRB_ACTION_Type; END RECORD; TYPE ID2GPRF_Type IS RECORD rdix_rA : STD_LOGIC_VECTOR ( 4 DOWNTO 0); rdix_rB : STD_LOGIC_VECTOR ( 4 DOWNTO 0); rdix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0); END RECORD; TYPE INT_CTRL_Type IS RECORD setup_int : STD_LOGIC; rti_target : STD_LOGIC_VECTOR (31 DOWNTO 0); int_busy : STD_LOGIC; END RECORD; TYPE ID2CTRL_Type IS RECORD delayBit : STD_LOGIC; int_busy : STD_LOGIC; END RECORD; TYPE GPRF2EX_Type IS RECORD data_rA : STD_LOGIC_VECTOR (31 DOWNTO 0); data_rB : STD_LOGIC_VECTOR (31 DOWNTO 0); data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0); END RECORD; TYPE IMM_LOCK_Type IS RECORD locked : STD_LOGIC; IMM_hi16 : STD_LOGIC_VECTOR (15 DOWNTO 0); END RECORD; TYPE MSR_Type IS RECORD IE : STD_LOGIC; -- MSR[VHDL b1] = [MicroBlaze b30] C : STD_LOGIC; -- MSR[VHDL b2 and b31] = [MicroBlaze b29 and b0] END RECORD; TYPE EX2IF_Type IS RECORD take_branch : STD_LOGIC; branch_target : STD_LOGIC_VECTOR (31 DOWNTO 0); END RECORD; TYPE HALT_Type IS RECORD halt : STD_LOGIC; halt_code : STD_LOGIC_VECTOR ( 4 DOWNTO 0); END RECORD; TYPE EX2MEM_Type IS RECORD mem_Action : MEM_ACTION_Type; -- RD_MEM implies writeback wrb_Action : WRB_ACTION_Type; exeq_result : STD_LOGIC_VECTOR (31 DOWNTO 0); data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0); byte_Enable : STD_LOGIC_VECTOR ( 3 DOWNTO 0); wrix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0); END RECORD; TYPE WRB_Type IS RECORD wrb_Action : WRB_ACTION_Type; wrix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0); data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0); END RECORD; TYPE HAZARD_WRB_Type IS RECORD hazard : STD_LOGIC; save_rX : SAVE_REG_Type; data_rX : STD_LOGIC_VECTOR (31 DOWNTO 0); data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0); END RECORD; TYPE MEM_REG_Type IS RECORD wrb_Action : WRB_ACTION_Type; exeq_result : STD_LOGIC_VECTOR (31 DOWNTO 0); byte_Enable : STD_LOGIC_VECTOR ( 3 DOWNTO 0); wrix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0); END RECORD; TYPE MEM2CTRL_Type IS RECORD clken : STD_LOGIC; int : STD_LOGIC; END RECORD; TYPE CORE2DMEMB_Type IS RECORD ena : STD_LOGIC; addr : STD_LOGIC_VECTOR (31 DOWNTO 0); bSel : STD_LOGIC_VECTOR ( 3 DOWNTO 0); wre : STD_LOGIC; data : STD_LOGIC_VECTOR (31 DOWNTO 0); END RECORD; TYPE DMEMB2CORE_Type IS RECORD clken : STD_LOGIC; data : STD_LOGIC_VECTOR (31 DOWNTO 0); int : STD_LOGIC; END RECORD; TYPE MEMORY_MAP_Type IS ARRAY(NATURAL RANGE <>) OF STD_LOGIC_VECTOR (31 DOWNTO 0); -- NOTE: Use the named association format xxxx := ( 0 => X"A0010000" ); -- in case the array has to contain only one element !! ---------------------------------------------------------------------------------------------- -- COMPONENTS ---------------------------------------------------------------------------------------------- COMPONENT fetch IS PORT ( prog_cntr_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0); inc_pc_i : IN STD_LOGIC; EX2IF_i : IN EX2IF_Type; IF2ID_o : OUT IF2ID_Type ); END COMPONENT; COMPONENT decode IS GENERIC ( USE_HW_MUL_g : BOOLEAN := TRUE; USE_BARREL_g : BOOLEAN := TRUE; COMPATIBILITY_MODE_g : BOOLEAN := FALSE ); PORT ( IF2ID_i : IN IF2ID_Type; imem_data_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0); -- ID2GPRF_o : OUT ID2GPRF_Type; ID2EX_o : OUT ID2EX_Type; -- INT_CTRL_i : IN INT_CTRL_Type; ID2CTRL_o : OUT ID2CTRL_Type; -- noLiteOpc_o : OUT STD_LOGIC ); END COMPONENT; COMPONENT adder IS GENERIC ( DW_g : POSITIVE := 32; LW_g : POSITIVE := 15 ); PORT ( in1 : IN STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0); in2 : IN STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0); cin : IN STD_LOGIC; sum : OUT STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0); cout : OUT STD_LOGIC ); END COMPONENT; COMPONENT exeq IS GENERIC ( USE_HW_MUL_g : BOOLEAN := FALSE; USE_BARREL_g : BOOLEAN := FALSE ); PORT ( ID2EX_i : IN ID2EX_Type; GPRF2EX_i : IN GPRF2EX_Type; EX2IF_o : OUT EX2IF_Type; HALT_o : OUT HALT_Type; -- EX_WRB_i : IN WRB_Type; EX_WRB_o : OUT WRB_Type; MEM_WRB_i : IN WRB_Type; -- HAZARD_WRB_i : IN HAZARD_WRB_Type; HAZARD_WRB_o : OUT HAZARD_WRB_Type; -- IMM_LOCK_i : IN IMM_LOCK_Type; IMM_LOCK_o : OUT IMM_LOCK_Type; -- MSR_i : IN MSR_Type; MSR_o : OUT MSR_Type; -- EX2MEM_o : OUT EX2MEM_Type ); END COMPONENT; COMPONENT mem IS PORT ( EX2MEM_i : IN EX2MEM_Type; -- DMEMB_i : IN DMEMB2CORE_Type; DMEMB_o : OUT CORE2DMEMB_Type; -- MEM_REG_i : IN MEM_REG_Type; MEM_REG_o : OUT MEM_REG_Type; -- MEM_WRB_o : OUT WRB_Type; MEM2CTRL_o : OUT MEM2CTRL_Type ); END COMPONENT; COMPONENT core_ctrl IS GENERIC ( COMPATIBILITY_MODE_g : BOOLEAN := FALSE ); PORT ( clk_i : IN STD_LOGIC; rst_i : IN STD_LOGIC; halt_i : IN STD_LOGIC; bad_op_i : IN STD_LOGIC; int_i : IN STD_LOGIC; trace_i : IN STD_LOGIC; trace_kick_i : IN STD_LOGIC; core_clken_o : OUT STD_LOGIC; -- specific fetch i/o imem_addr_o : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); imem_clken_o : OUT STD_LOGIC; pc_ctrl_o : OUT STD_LOGIC; -- fetch to decode pipeline registers IF2ID_REG_i : IN IF2ID_Type; IF2ID_REG_o : OUT IF2ID_Type; -- decode to exeq pipeline registers ID2EX_REG_i : IN ID2EX_Type; ID2EX_REG_o : OUT ID2EX_Type; -- GPRF control gprf_clken_o : OUT STD_LOGIC; -- exeq to fetch feedback registers EX2IF_REG_i : IN EX2IF_Type; EX2IF_REG_o : OUT EX2IF_Type; -- exeq to core (halting) exeq_halt_i : IN STD_LOGIC; -- exeq to mem pipeline registers EX2MEM_REG_i : IN EX2MEM_Type; EX2MEM_REG_o : OUT EX2MEM_Type; -- mem pipeline register MEM_REG_i : IN MEM_REG_Type; MEM_REG_o : OUT MEM_REG_Type; -- decode control i/o ID2CTRL_i : IN ID2CTRL_Type; INT_CTRL_o : OUT INT_CTRL_Type; -- exeq control i/o EX_WRB_i : IN WRB_Type; EX_WRB_o : OUT WRB_Type; -- data hazard i/o HAZARD_WRB_i : IN HAZARD_WRB_Type; HAZARD_WRB_o : OUT HAZARD_WRB_Type; -- for handling the 'IMM' instruction IMM_LOCK_i : IN IMM_LOCK_Type; IMM_LOCK_o : OUT IMM_LOCK_Type; -- for handling the Machine Status Register MSR_i : IN MSR_Type; MSR_o : OUT MSR_Type; -- miscellaneous MEM2CTRL_i : IN MEM2CTRL_Type ); END COMPONENT; ---------------------------------------------------------------------------------------------- -- FUNCTION, PROCEDURE DECLARATIONS ---------------------------------------------------------------------------------------------- PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0); ci : IN STD_LOGIC; VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); VARIABLE co : OUT STD_LOGIC ); PROCEDURE ep_add32nc ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0); ci : IN STD_LOGIC; VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)); -- PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR; ci : IN STD_LOGIC; -- VARIABLE s : OUT STD_LOGIC_VECTOR; -- VARIABLE co : OUT STD_LOGIC ); FUNCTION ef_nbits ( value : NATURAL ) RETURN POSITIVE; END PACKAGE mbl_Pkg; ---------------------------------------------------------- PACKAGE BODY mbl_Pkg IS ---------------------------------------------------------- PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0); ci : IN STD_LOGIC; VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); VARIABLE co : OUT STD_LOGIC ) IS CONSTANT NBITS_LO_c : POSITIVE := 17; CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c; VARIABLE tmp_lo_v : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0); VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0); VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0); BEGIN tmp_lo_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO 0) & '1' ) + UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO 0) & ci )); tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') + UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0')); tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') + UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1')); IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN s := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1); co := tmp_hi0_v(NBITS_HI_c +1); ELSE s := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1); co := tmp_hi1_v(NBITS_HI_c +1); END IF; END PROCEDURE; PROCEDURE ep_add32nc ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0); ci : IN STD_LOGIC; VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) ) IS CONSTANT NBITS_LO_c : POSITIVE := 17; CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c; VARIABLE tmp_lo_v : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0); VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0); VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0); BEGIN tmp_lo_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO 0) & '1' ) + UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO 0) & ci )); tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') + UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0')); tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') + UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1')); IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN s := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1); ELSE s := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1); END IF; END PROCEDURE; -- PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR; ci : IN STD_LOGIC; -- VARIABLE s : OUT STD_LOGIC_VECTOR; -- VARIABLE co : OUT STD_LOGIC ) IS -- VARIABLE tmp_lo_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0); -- VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0); -- VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0); -- BEGIN -- tmp_lo_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH/2 -1 DOWNTO 0) & '1' ) + -- UNSIGNED( '0' & b(a'LENGTH/2 -1 DOWNTO 0) & ci )); -- tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1') + -- UNSIGNED( '0' & b(a'LENGTH -1 DOWNTO a'LENGTH/2) & '0')); -- tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1') + -- UNSIGNED( '0' & b(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1')); -- IF (tmp_lo_v(a'LENGTH/2 +1) = '0') THEN -- s := tmp_hi0_v(a'LENGTH/2 DOWNTO 1) & tmp_lo_v(a'LENGTH/2 DOWNTO 1); -- co := tmp_hi0_v(a'LENGTH/2 +1); -- ELSE -- s := tmp_hi1_v(a'LENGTH/2 DOWNTO 1) & tmp_lo_v(a'LENGTH/2 DOWNTO 1); -- co := tmp_hi1_v(a'LENGTH/2 +1); -- END IF; -- END PROCEDURE; -- Function ef_nbits returns the minimum number of binary bits to represent -- a value N with: -- so N = 0,1 NBITS = 1 -- N = 2,3 NBITS = 2 -- N = 4,5,6,7 NBITS = 3 -- N = 8..15 NBITS = 4 -- N = 16..31 NBITS = 5 -- etc. FUNCTION ef_nbits( value : NATURAL ) RETURN POSITIVE IS VARIABLE temp_v : POSITIVE; BEGIN temp_v := 1; FOR i IN 1 TO INTEGER'HIGH LOOP temp_v := 2*temp_v; IF (temp_v > value) THEN RETURN i; END IF; END LOOP; RETURN 32; END FUNCTION; END PACKAGE BODY mbl_Pkg;