use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
use work.lx_rocon_pkg.all;
-- Connects tumbl to the Master CPU
port
(
-- Clock
- clk_100m : in std_logic;
- clk_50m : in std_logic;
-
+ clk_i : in std_logic;
-- Chip enable
- ce : in std_logic;
-
+ ce_i : in std_logic;
-- Global Reset
- reset : in std_logic;
-
+ reset_i : in std_logic;
-- Master CPU bus for the memory
- rd : in std_logic;
- bls : in std_logic_vector(3 downto 0);
- address : in std_logic_vector(11 downto 0);
- data_in : in std_logic_vector(31 downto 0);
- data_out : out std_logic_vector(31 downto 0);
- ta : out std_logic;
-
+ bls_i : in std_logic_vector(3 downto 0);
+ address_i : in std_logic_vector(11 downto 0);
+ data_i : in std_logic_vector(31 downto 0);
+ data_o : out std_logic_vector(31 downto 0);
-- Tumbl extrenal memory bus
- XMEMB_sel_o : out std_logic;
- XMEMB_i : in DMEMB2CORE_Type;
- XMEMB_o : out CORE2DMEMB_Type
+ xmemb_sel_o : out std_logic;
+ xmemb_i : in DMEMB2CORE_Type;
+ xmemb_o : out CORE2DMEMB_Type
);
end bus_tumbl;
architecture Behavioral of bus_tumbl is
-
- -- Internal state
- signal tumbl_reset : std_logic;
- signal tumbl_halt : std_logic;
- signal tumbl_int : std_logic;
- signal tumbl_trace : std_logic;
- signal tumbl_trace_kick : std_logic; -- driven by 50M clock
- signal tumbl_trace_kick_ack : std_logic; -- driven by 50M clock
- signal tumbl_trace_kick_req : std_logic; -- driven by 100M clock
- signal tumbl_bad_op : std_logic; -- driven by 50M clock
-
- -- Tumbl PC (copy it with cpu clock and then wire further)
- signal tumbl_pc : std_logic_vector(31 downto 0); -- driven by 50M clock
-
- -- Halting using halt instruction
- signal tumbl_halted : std_logic;
- signal tumbl_halt_code : std_logic_vector(4 downto 0);
+ -- Types
+ type TUMBL_Input_Type is record
+ halt : std_logic;
+ int : std_logic;
+ trace : std_logic;
+ trace_kick : std_logic;
+ end record;
+
+ type TUMBL_State_Type is record
+ pc : std_logic_vector(31 downto 0);
+ halted : std_logic;
+ halt_code : std_logic_vector(4 downto 0);
+ end record;
+
+ -- Reset
+ signal tumbl_reset_s : std_logic;
+ -- Internals
+ signal tumbl_input_s : TUMBL_Input_Type;
+ signal tumbl_state_s : TUMBL_State_Type;
-- Internal memory signals
- signal imem_en : std_logic;
- signal dmem_en : std_logic;
+ signal imem_en_s : std_logic;
+ signal imem_en_r : std_logic;
+ signal dmem_en_s : std_logic;
+ signal dmem_en_r : std_logic;
- signal imem_we : std_logic_vector(3 downto 0);
- signal dmem_we : std_logic_vector(3 downto 0);
+ signal imem_we_s : std_logic_vector(3 downto 0);
+ signal dmem_we_s : std_logic_vector(3 downto 0);
- signal imem_dout : std_logic_vector(31 downto 0);
- signal dmem_dout : std_logic_vector(31 downto 0);
+ signal imem_data_o_s : std_logic_vector(31 downto 0);
+ signal dmem_data_o_s : std_logic_vector(31 downto 0);
+
+ -- Control registers read access
+ signal tumbl_reg_en_control_r : std_logic;
+ signal tumbl_reg_en_pc_r : std_logic;
+ signal tumbl_reg_en_halt_code_r : std_logic;
-- Internal bus structure
-- 12 address bits: 2 bits for selection, 10 bits for address
-- Registers
-- 0x000
--
- -- Bit 0: R/W - Reset
- -- Bit 1: R/W - Interrupt
- -- Bit 2: R/W - Halt
- -- Bit 3: R/W - Trace
- -- Bit 4: R - Halted
- -- Bit 5: R - Done
- -- Bit 6: R - Bad Op (halts the core until reset)
+ -- Bit 0: RW - Reset
+ -- Bit 1: RW - Interrupt
+ -- Bit 2: RW - Halt
+ -- Bit 3: RW - Trace
+ -- Bit 4: R - Halted
-- 0x001
- -- Bit 0: W - Write 1 for trace kick, R - Read internal signals
+ -- Bit 0: W - Write 1 for trace kick
-- 0x002
-- Tumbl program counter (R)
I_TUMBL: lx_rocon_tumbl
generic map
(
- IMEM_ABITS_g => 11,
- DMEM_ABITS_g => 12,
+ IMEM_ABITS_g => 9,
+ DMEM_ABITS_g => 10,
--
- USE_HW_MUL_g => true,
- USE_BARREL_g => true,
+ USE_HW_MUL_g => true,
+ USE_BARREL_g => true,
COMPATIBILITY_MODE_g => false
)
port map
(
- clk_i => clk_50m,
- rst_i => tumbl_reset,
- halt_i => tumbl_halt,
- int_i => tumbl_int,
- trace_i => tumbl_trace,
- trace_kick_i => tumbl_trace_kick,
+ clk_i => clk_i,
+ rst_i => tumbl_reset_s,
+ halt_i => tumbl_input_s.halt,
+ int_i => tumbl_input_s.int,
+ trace_i => tumbl_input_s.trace,
+ trace_kick_i => tumbl_input_s.trace_kick,
- pc_o => tumbl_pc,
- halted_o => tumbl_halted,
- halt_code_o => tumbl_halt_code,
+ pc_o => tumbl_state_s.pc,
+ halted_o => tumbl_state_s.halted,
+ halt_code_o => tumbl_state_s.halt_code,
-- Internal memory (instruction)
- imem_clk => clk_100m,
- imem_en => imem_en,
- imem_we => imem_we,
- imem_addr => address(8 downto 0),
- imem_din => data_in,
- imem_dout => imem_dout,
+ imem_clk_i => clk_i,
+ imem_en_i => imem_en_s,
+ imem_we_i => imem_we_s,
+ imem_addr_i => address_i(8 downto 0),
+ imem_data_i => data_i,
+ imem_data_o => imem_data_o_s,
-- Internal memory (data)
- dmem_clk => clk_100m,
- dmem_en => dmem_en,
- dmem_we => dmem_we,
- dmem_addr => address(9 downto 0),
- dmem_din => data_in,
- dmem_dout => dmem_dout,
+ dmem_clk_i => clk_i,
+ dmem_en_i => dmem_en_s,
+ dmem_we_i => dmem_we_s,
+ dmem_addr_i => address_i(9 downto 0),
+ dmem_data_i => data_i,
+ dmem_data_o => dmem_data_o_s,
-- External memory bus
- XMEMB_sel_o => XMEMB_sel_o,
- XMEMB_i => XMEMB_i,
- XMEMB_o => XMEMB_o,
- --
- bad_op_o => tumbl_bad_op
+ xmemb_sel_o => xmemb_sel_o,
+ xmemb_i => xmemb_i,
+ xmemb_o => xmemb_o
);
- -- Enabling
- enabling: process(ce, address)
+-- Enabling
+enabling: process(ce_i, address_i)
begin
- if ce = '0' and address(11 downto 10) = "00" then
- imem_en <= '1';
+ if ce_i = '1' and address_i(11 downto 10) = "00" then
+ imem_en_s <= '1';
else
- imem_en <= '0';
+ imem_en_s <= '0';
end if;
- if ce = '0' and address(11 downto 10) = "01" then
- dmem_en <= '1';
+ if ce_i = '1' and address_i(11 downto 10) = "01" then
+ dmem_en_s <= '1';
else
- dmem_en <= '0';
+ dmem_en_s <= '0';
end if;
end process;
- -- Wiring
- wiring: process(ce, rd, bls, address, imem_en, imem_dout, dmem_en, dmem_dout,
- tumbl_reset, tumbl_int, tumbl_halt, tumbl_trace,
- tumbl_halted, tumbl_halt_code, tumbl_bad_op, tumbl_pc)
+-- Wiring
+wiring:
+ process(ce_i, bls_i, address_i, imem_en_s, imem_data_o_s, dmem_en_s,
+ dmem_data_o_s, tumbl_reset_s, tumbl_input_s, tumbl_state_s,
+ imem_en_r, dmem_en_r, tumbl_reg_en_control_r, tumbl_reg_en_pc_r,
+ tumbl_reg_en_halt_code_r)
begin
- if imem_en = '1' and tumbl_reset = '1' then
- imem_we <= not bls;
+ if imem_en_s = '1' then
+ imem_we_s <= bls_i;
else
- imem_we <= "0000";
+ imem_we_s <= "0000";
end if;
- if dmem_en = '1' and tumbl_reset = '1' then
- dmem_we <= not bls;
+ if dmem_en_s = '1' then
+ dmem_we_s <= bls_i;
else
- dmem_we <= "0000";
+ dmem_we_s <= "0000";
end if;
- if imem_en = '1' then
- data_out <= imem_dout;
- elsif dmem_en = '1' then
- data_out <= dmem_dout;
- elsif ce = '0' and rd = '0' and address(11 downto 10) = "11" then
- if address(9 downto 0) = "0000000000" then
- data_out(0) <= tumbl_reset;
- data_out(1) <= tumbl_int;
- data_out(2) <= tumbl_halt;
- data_out(3) <= tumbl_trace;
- data_out(4) <= tumbl_halted;
- data_out(5) <= tumbl_bad_op;
- data_out(31 downto 6) <= (others => '0');
- elsif address(9 downto 0) = "0000000010" then
- data_out <= tumbl_pc;
- elsif address(9 downto 0) = "0000000011" then
- data_out(4 downto 0) <= tumbl_halt_code;
- data_out(31 downto 5) <= (others => '0');
- else
- data_out <= (others => 'X');
- end if;
+ if imem_en_r = '1' then
+ data_o <= imem_data_o_s;
+ elsif dmem_en_r = '1' then
+ data_o <= dmem_data_o_s;
+ elsif tumbl_reg_en_control_r = '1' then
+ data_o(0) <= tumbl_reset_s;
+ data_o(1) <= tumbl_input_s.int;
+ data_o(2) <= tumbl_input_s.halt;
+ data_o(3) <= tumbl_input_s.trace;
+ data_o(4) <= tumbl_state_s.halted;
+ data_o(31 downto 5) <= (others => '0');
+ elsif tumbl_reg_en_pc_r = '1' then
+ data_o <= tumbl_state_s.pc;
+ elsif tumbl_reg_en_halt_code_r = '1' then
+ data_o(4 downto 0) <= tumbl_state_s.halt_code;
+ data_o(31 downto 5) <= (others => '0');
else
- data_out <= (others => 'X');
+ data_o <= (others => 'X');
end if;
end process;
- -- Transaction acknowledge and writing to registers
- -- The clock are synchronous!
- update: process(clk_100m)
+-- Transaction acknowledge and writing to registers
+update:
+ process
begin
- -- Update on the 100 MHz clock
- if clk_100m = '1' and clk_100m'event then
- ta <= '1';
+ -- Update
+ wait until clk_i'event and clk_i = '1';
- if imem_en = '1' or dmem_en = '1' then
- ta <= '0';
- end if;
+ imem_en_r <= imem_en_s;
+ dmem_en_r <= dmem_en_s;
- if reset = '1' then
- tumbl_reset <= '1';
- tumbl_int <= '0';
- tumbl_halt <= '0';
- tumbl_trace <= '0';
- tumbl_trace_kick_req <= '0';
- else
+ tumbl_reg_en_control_r <= '0';
+ tumbl_reg_en_pc_r <= '0';
+ tumbl_reg_en_halt_code_r <= '0';
- if tumbl_trace_kick_ack = '1' then
- tumbl_trace_kick_req <= '0';
- end if;
+ tumbl_input_s.trace_kick <= '0';
- if ce = '0' and address(11 downto 10) = "11" then
- if bls(0) = '0' then
- if address(9 downto 0) = "0000000000" then
- tumbl_reset <= data_in(0);
- tumbl_int <= data_in(1);
- tumbl_halt <= data_in(2);
- tumbl_trace <= data_in(3);
- elsif address(9 downto 0) = "0000000001" then
- if data_in(0) = '1' and tumbl_trace_kick = '0' then
- tumbl_trace_kick_req <= '1';
- end if;
- end if;
- end if;
+ if reset_i = '1' then
+ tumbl_reset_s <= '1';
+ tumbl_input_s.int <= '0';
+ tumbl_input_s.halt <= '0';
+ tumbl_input_s.trace <= '0';
+
+ else
- if rd = '0' then
- ta <= '0';
+ if ce_i = '1' and address_i(11 downto 10) = "11" then
+ if bls_i(0) = '1' then
+ if address_i(9 downto 0) = "0000000000" then
+ tumbl_reset_s <= data_i(0);
+ tumbl_input_s.int <= data_i(1);
+ tumbl_input_s.halt <= data_i(2);
+ tumbl_input_s.trace <= data_i(3);
+ elsif address_i(9 downto 0) = "0000000001" then
+ if data_i(0) = '1' then
+ tumbl_input_s.trace_kick <= '1';
+ end if;
end if;
end if;
- end if;
- end if;
- end process;
- -- Update tracing
- tumbl: process(clk_50m)
- begin
-
- -- Update on the 50 MHz clock
- if clk_50m = '1' and clk_50m'event then
-
- if reset = '1' then
- tumbl_trace_kick <= '0';
- tumbl_trace_kick_ack <= '0';
- else
- if tumbl_trace_kick = '0' and tumbl_trace_kick_req = '1' then
- tumbl_trace_kick <= '1';
- tumbl_trace_kick_ack <= '1';
- else
- tumbl_trace_kick <= '0';
+ if address_i(9 downto 0) = "0000000000" then
+ tumbl_reg_en_control_r <= '1';
+ elsif address_i(9 downto 0) = "0000000010" then
+ tumbl_reg_en_pc_r <= '1';
+ elsif address_i(9 downto 0) = "0000000011" then
+ tumbl_reg_en_halt_code_r <= '1';
end if;
end if;
-
- if tumbl_trace_kick_req <= '0' then
- tumbl_trace_kick_ack <= '0';
- end if;
-
end if;
end process;
end Behavioral;
-