LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
-USE WORK.mbl_Pkg.all;
+USE WORK.mbl_pkg.all;
--------------------------------------------------------------------------------
ENTITY core_ctrl IS
--------------------------------------------------------------------------------
GENERIC
(
+ IMEM_ABITS_g : positive := 9;
COMPATIBILITY_MODE_g : BOOLEAN := FALSE
);
PORT
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_addr_o : OUT STD_LOGIC_VECTOR ((IMEM_ABITS_g-1) DOWNTO 0);
imem_clken_o : OUT STD_LOGIC;
pc_ctrl_o : OUT STD_LOGIC;
-- fetch to decode pipeline registers
-- static connections
reset_s <= rst_i OR rst_r;
pc_ctrl_o <= NOT rst_r;
- imem_addr_o <= IF2ID_REG_i.program_counter;
+ -- Addressing is 32-bit, so omit two lowest bytes from PC
+ imem_addr_o <= IF2ID_REG_i.program_counter((IMEM_ABITS_g+1) DOWNTO 2);
-- Tracing
-- Reset_s is 1 when rst_i is one and then gets deactivated
core_clken_s <= reset_s OR (((NOT trace_i) AND (NOT exeq_halt_i)) OR trace_kick_i);
INT_CTRL_o.int_busy <= int_busy_r;
regd_proc:
- PROCESS ( clk_i, rst_i, halt_i, core_clken_s,
- -- complete sensitivity list for synthesizer
- reset_s, MEM2CTRL_i, clken_pipe_s, IF2ID_REG_i,
- flush_ID2EX_s, flush_EX2MEM_s, HAZARD_WRB_i,
- MEM_REG_i, ID2CTRL_i, int_i, MSR_i,
- int_busy_r, IMM_LOCK_i, ID2EX_REG_i, ID2EX_REG_r,
- EX2IF_REG_i, EX2CTRL_REG_i, EX_WRB_i, EX2MEM_REG_i )
+ PROCESS
-- some local procedures
PROCEDURE lp_rst_IF2ID_REG IS
BEGIN
- IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' AND
- core_clken_s = '1' THEN
+ WAIT UNTIL clk_i'event AND clk_i = '1';
+
+ IF MEM2CTRL_i.clken = '1' AND halt_i = '0' AND core_clken_s = '1' THEN
rst_r <= rst_i;
IF (reset_s = '1') THEN -- synchronous reset ...
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
-USE WORK.mbl_Pkg.all;
+USE WORK.mbl_pkg.all;
--------------------------------------------------------------------------------
ENTITY decode IS
IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
CASE code_x26_v IS
+ WHEN "000" => -- CLZ
+ alu_Action_v := A_CLZ;
WHEN "001" | "011" | "101" =>
CASE code_x26_v(2 DOWNTO 1) IS
WHEN "00" => -- SRA
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
-USE WORK.mbl_Pkg.all;
-
+USE WORK.mbl_pkg.all;
----------------------------------------------------------
ENTITY exeq IS
END IF;
WHEN A_MFS =>
- result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
+ if (COMPATIBILITY_MODE_g = FALSE) THEN
+ result_v := C_24_ZEROS & "00000" & MSR_i.C & MSR_i.IE & '0';
+ ELSE
+ result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
+ END IF;
WHEN A_MTS =>
MSR_o.IE <= data_Ra_v(1);
END IF;
END IF; -- (USE_BARREL_g = TRUE)
+ WHEN A_CLZ =>
+ tmp64_v := (OTHERS => '0');
+ leading_zeroes32 ( in1_v, UNSIGNED(tmp64_v(31 DOWNTO 0)), result_v );
+
WHEN OTHERS =>
NULL;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
-USE WORK.mbl_Pkg.all;
+USE WORK.mbl_pkg.all;
--------------------------------------------------------------------------------
ENTITY fetch IS
USE IEEE.numeric_std.all;
--------------------------------------------------------------------------------
-PACKAGE mbl_Pkg IS
+PACKAGE mbl_pkg IS
--------------------------------------------------------------------------------
CONSTANT C_8_ZEROS : STD_LOGIC_VECTOR ( 7 DOWNTO 0) := X"00";
----------------------------------------------------------------------------------------------
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_SHIFT, A_SEXT8, A_SEXT16, A_MFS, A_MTS, A_MUL,
+ A_BSLL, A_BSRL, A_BSRA, A_CLZ);
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);
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;
+ rd : STD_LOGIC;
+ addr : STD_LOGIC_VECTOR (14 DOWNTO 0); -- 64 kB space is more than enough
+ bls : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
data : STD_LOGIC_VECTOR (31 DOWNTO 0);
END RECORD;
COMPONENT core_ctrl IS
GENERIC
(
+ IMEM_ABITS_g : positive := 9;
COMPATIBILITY_MODE_g : BOOLEAN := FALSE
);
PORT
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_addr_o : OUT STD_LOGIC_VECTOR ((IMEM_ABITS_g-1) DOWNTO 0);
imem_clken_o : OUT STD_LOGIC;
pc_ctrl_o : OUT STD_LOGIC;
-- fetch to decode pipeline registers
ci : IN STD_LOGIC;
VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0));
+ PROCEDURE leading_zeroes32( m : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+ n : IN UNSIGNED;
+ VARIABLE r : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) );
+
FUNCTION ef_nbits ( value : NATURAL ) RETURN POSITIVE;
-END PACKAGE mbl_Pkg;
+END PACKAGE mbl_pkg;
----------------------------------------------------------
-PACKAGE BODY mbl_Pkg IS
+PACKAGE BODY mbl_pkg IS
----------------------------------------------------------
PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
END IF;
END PROCEDURE;
+ PROCEDURE leading_zeroes32( m : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+ n : IN UNSIGNED;
+ VARIABLE r : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) ) IS
+ BEGIN
+ -- It would be easier if it could be generated, but it's a sequence
+ IF ( m(31) = '1' ) THEN
+ r := STD_LOGIC_VECTOR ( n );
+ ELSE
+ leading_zeroes32 ( m (30 DOWNTO 0) & '1', UNSIGNED (n + 1), r);
+ END IF;
+
+ END PROCEDURE leading_zeroes32;
- FUNCTION ef_nbits( value : NATURAL ) RETURN POSITIVE IS
+ FUNCTION ef_nbits ( value : NATURAL ) RETURN POSITIVE IS
VARIABLE temp_v : POSITIVE;
BEGIN
temp_v := 1;
RETURN 32;
END FUNCTION;
-END PACKAGE BODY mbl_Pkg;
+END PACKAGE BODY mbl_pkg;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
-USE work.mbl_Pkg.all;
+USE WORK.mbl_pkg.all;
--------------------------------------------------------------------------------
ENTITY mem IS
-- also signal 'slow memory decices' and interrupts from devices
MEM2CTRL_o.clken <= DMEMB_i.clken;
MEM2CTRL_o.int <= DMEMB_i.int;
- -- pass byte_select signal (NOTE: BIG ENDIAN)
- DMEMB_o.bSel <= EX2MEM_i.byte_Enable;
p_mem:
PROCESS (EX2MEM_i, DMEMB_i, MEM_REG_i)
WHEN WR_MEM =>
-- write (or forward) to data memory bus
- DMEMB_o.addr <= EX2MEM_i.exeq_result;
- DMEMB_o.ena <= '1';
- DMEMB_o.wre <= '1';
+ DMEMB_o.addr <= EX2MEM_i.exeq_result(16 downto 2);
+ DMEMB_o.rd <= '0';
+ DMEMB_o.bls <= EX2MEM_i.byte_Enable;
-- Note: use MEM_REG_i here, since MEM_WRB_o (output) cannot be read
IF ((MEM_REG_i.wrb_Action /= NO_WRB) AND
(EX2MEM_i.wrix_rD = MEM_REG_i.wrix_rD)) THEN
WHEN RD_MEM =>
-- read from data memory bus
- DMEMB_o.addr <= EX2MEM_i.exeq_result;
- DMEMB_o.ena <= '1';
- DMEMB_o.wre <= '0';
+ DMEMB_o.addr <= EX2MEM_i.exeq_result(16 downto 2);
+ DMEMB_o.rd <= '1';
+ DMEMB_o.bls <= (others => '0');
DMEMB_o.data <= EX2MEM_i.data_rD; -- (OTHERS => 'Z');
WHEN OTHERS => -- NO_MEM
- DMEMB_o.addr <= C_32_ZEROS;
- DMEMB_o.ena <= '0';
- DMEMB_o.wre <= '0';
+ DMEMB_o.addr <= (others => '0');
+ DMEMB_o.rd <= '0';
+ DMEMB_o.bls <= (others => '0');
DMEMB_o.data <= EX2MEM_i.data_rD; -- (OTHERS => 'Z');
END CASE;