-- Internal memory signals
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_s : std_logic_vector(3 downto 0);
signal dmem_we_s : std_logic_vector(3 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
--
-- 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)
+ 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_s = '1' then
dmem_we_s <= "0000";
end if;
- if imem_en_s = '1' then
+ if imem_en_r = '1' then
data_o <= imem_data_o_s;
- elsif dmem_en_s = '1' then
+ elsif dmem_en_r = '1' then
data_o <= dmem_data_o_s;
- elsif ce_i = '1' and address_i(11 downto 10) = "11" then
- if address_i(9 downto 0) = "0000000000" 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 address_i(9 downto 0) = "0000000010" then
- data_o <= tumbl_state_s.pc;
- elsif address_i(9 downto 0) = "0000000011" then
- data_o(4 downto 0) <= tumbl_state_s.halt_code;
- data_o(31 downto 5) <= (others => '0');
- else
- data_o <= (others => 'X');
- end if;
+ 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_o <= (others => 'X');
end if;
-- Update
wait until clk_i'event and clk_i = '1';
+ imem_en_r <= imem_en_s;
+ dmem_en_r <= dmem_en_s;
+
+ tumbl_reg_en_control_r <= '0';
+ tumbl_reg_en_pc_r <= '0';
+ tumbl_reg_en_halt_code_r <= '0';
+
tumbl_input_s.trace_kick <= '0';
if reset_i = '1' then
end if;
end if;
end if;
+
+
+ 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;
end if;
-- Master to Tumbl DMEM / IMEM (Master)
signal tumbl_out_s : std_logic_vector(31 downto 0);
signal tumbl_ce_s : std_logic;
+ signal tumbl_ce_r : std_logic;
-- Measurement (Master)
signal meas_out_s : std_logic_vector(31 downto 0);
signal meas_ce_s : std_logic;
+ signal meas_ce_r : std_logic;
-- Master to Tumbl XMEM
signal master_tumbl_xmem_out_s : std_logic_vector(31 downto 0);
signal master_tumbl_xmem_ce_s : std_logic;
+ signal master_tumbl_xmem_ce_r : std_logic;
signal master_tumbl_xmem_lock_s : std_logic;
-- IRC (Tumbl)
- signal irc_proc_out_s : std_logic_vector(31 downto 0);
- signal irc_proc_ce_s : std_logic;
- signal irc_proc_next_ce_s : std_logic;
+ signal irc_proc_out_s : std_logic_vector(31 downto 0);
+ signal irc_proc_ce_s : std_logic;
+ signal irc_proc_ce_r : std_logic;
-- LX Master (Tumbl)
signal lxmaster_out_s : std_logic_vector(15 downto 0);
signal lxmaster_ce_s : std_logic;
- signal lxmaster_next_ce_s : std_logic;
+ signal lxmaster_ce_r : std_logic;
-- LX function approximation
signal lxfncapprox_out_s : std_logic_vector(31 downto 0);
signal lxfncapprox_ce_s : std_logic;
- signal lxfncapprox_next_ce_s : std_logic;
+ signal lxfncapprox_ce_r : std_logic;
-- Signals for external bus transmission
signal data_i_s : std_logic_vector(31 downto 0);
signal data_o_s : std_logic_vector(31 downto 0);
signal cs0_xc_f_s : std_logic;
signal rd_f_s : std_logic; -- Filtered RD
signal i_rd_s : std_logic; -- Internal bus RD (active 1)
- -- signal next_i_rd_s : std_logic;
- signal last_i_rd_s : std_logic; -- Delayed RD bus, used for latching
signal next_last_i_rd_s : std_logic;
- signal i_rd_cycle2_s : std_logic; -- Some internal subsystems provide
- signal next_i_rd_cycle2_s : std_logic; -- data only after 2 cycles
+ signal last_i_rd_s : std_logic; -- Delayed RD bus, used for latching
--
signal address_f_s : std_logic_vector(15 downto 0); -- Filtered address
--
--
clk_i => clk_50m,
address_i => tumbl_address_s(4 downto 0),
- next_ce_i => irc_proc_next_ce_s,
+ next_ce_i => irc_proc_ce_s,
data_i => tumbl_data_i_s,
data_o => irc_proc_out_s,
bls_i => tumbl_bls_s,
--
clk_i => clk_50m,
address_i => tumbl_address_s(10 downto 0),
- next_ce_i => lxmaster_next_ce_s,
+ next_ce_i => lxmaster_ce_s,
data_i => tumbl_data_i_s(15 downto 0),
data_o => lxmaster_out_s,
bls_i => tumbl_bls_s(1 downto 0),
clk_i => clk_50m,
-- Data bus
address_i => tumbl_address_s(4 downto 0),
- next_ce_i => lxfncapprox_next_ce_s,
+ next_ce_i => lxfncapprox_ce_s,
data_i => tumbl_data_i_s,
data_o => lxfncapprox_out_s,
bls_i => tumbl_bls_s
-- Bus update
memory_bus_logic:
- process(cs0_xc_f_s, rd_f_s, last_rd_s, i_rd_cycle2_s, last_i_rd_s,
+ process(cs0_xc_f_s, rd_f_s, last_rd_s, last_i_rd_s,
bls_f_s, last_bls_s, data_f_s, data_write_s,
data_o_s, data_read_s, last_address_s, address_f_s)
begin
-- Defaults
- next_i_rd_cycle2_s <= '0';
next_address_hold_s <= '0';
-- Check if we have chip select
-- Internal read
if last_rd_s = '0' or (last_address_s /= address_f_s) then
i_rd_s <= '1';
- next_i_rd_cycle2_s <= '1';
- next_last_i_rd_s <= '1';
- elsif i_rd_cycle2_s = '1' then -- FIXME it seems that some internal
- i_rd_s <= '1'; -- peripherals demands 2 cycles to read
next_last_i_rd_s <= '1';
else
i_rd_s <= '0';
last_bls_s <= next_last_bls_s;
last_rd_s <= next_last_rd_s;
i_bls_s <= next_i_bls_s;
- -- i_rd_s <= next_i_rd_s;
- i_rd_cycle2_s <= next_i_rd_cycle2_s;
last_i_rd_s <= next_last_i_rd_s;
data_write_s <= next_data_write_s;
last_address_s <= next_last_address_s;
data_read_s <= next_data_read_s;
+
+ -- Internal bus chipselects
+ tumbl_ce_r <= tumbl_ce_s;
+ meas_ce_r <= meas_ce_s;
+ master_tumbl_xmem_ce_r <= master_tumbl_xmem_ce_s;
--
-- ======================================================
-- TUMBL BUS
-- ======================================================
-- Just copy these to their desired next state
- irc_proc_ce_s <= irc_proc_next_ce_s;
- lxmaster_ce_s <= lxmaster_next_ce_s;
- lxfncapprox_ce_s <= lxfncapprox_next_ce_s;
+ irc_proc_ce_r <= irc_proc_ce_s;
+ lxmaster_ce_r <= lxmaster_ce_s;
+ lxfncapprox_ce_r <= lxfncapprox_ce_s;
end process;
-- Do the actual wiring here
memory_bus_wiring:
- process(cs0_xc_f_s, i_bls_s, address_f_s, tumbl_out_s, meas_out_s, master_tumbl_xmem_out_s)
+ process(i_rd_s, i_bls_s, address_f_s, tumbl_out_s, meas_out_s, master_tumbl_xmem_out_s,
+ tumbl_ce_r, meas_ce_r, master_tumbl_xmem_ce_r, last_i_rd_s)
begin
-- Inactive by default
tumbl_ce_s <= '0';
meas_ce_s <= '0';
master_tumbl_xmem_ce_s <= '0';
- data_o_s <= (others => '0');
+ data_o_s <= (others => 'X');
- if cs0_xc_f_s = '1' or i_bls_s /= "0000" then
+ if i_rd_s = '1' or i_bls_s /= "0000" then
-- Memory Map (16-bit address @ 32-bit each)
if address_f_s < "0001000000000000" then -- Tumbl
tumbl_ce_s <= '1';
- data_o_s <= tumbl_out_s;
elsif address_f_s(15 downto 2) = "00011111111111" then -- Measurement
meas_ce_s <= '1';
- data_o_s <= meas_out_s;
elsif address_f_s(15) = '1' then -- Tumbl External BUS
master_tumbl_xmem_ce_s <= '1';
- data_o_s <= master_tumbl_xmem_out_s;
end if;
end if;
+ if tumbl_ce_r = '1' then -- Tumbl
+ data_o_s <= tumbl_out_s;
+ elsif meas_ce_r = '1' then -- Measurement
+ data_o_s <= meas_out_s;
+ elsif master_tumbl_xmem_ce_r = '1' then -- Tumbl External BUS
+ data_o_s <= master_tumbl_xmem_out_s;
+ end if;
+
end process;
-- If RD and BLS is not high, we must keep DATA at high impedance
begin
-- Defaults
- irc_proc_next_ce_s <= '0';
- lxmaster_next_ce_s <= '0';
- lxfncapprox_next_ce_s <= '0';
+ irc_proc_ce_s <= '0';
+ lxmaster_ce_s <= '0';
+ lxfncapprox_ce_s <= '0';
master_tumbl_xmem_lock_s <= '0';
--
addr_v := (others => '0');
-- LX FNC AP: 0x0C00 - 0x0C1F (32-bit address)
-- LX MASTER: 0x1000 - 0x17FF (32-bit address)
if addr_v(14 downto 5) = "0001000000" then
- irc_proc_next_ce_s <= '1';
+ irc_proc_ce_s <= '1';
elsif addr_v(14 downto 5) = "0001100000" then
- lxfncapprox_next_ce_s <= '1';
+ lxfncapprox_ce_s <= '1';
elsif addr_v(14 downto 11) = "0010" then
- lxmaster_next_ce_s <= '1';
+ lxmaster_ce_s <= '1';
end if;
end if;
-- Inputs to Tumbl (enabling and address muxing)
tumbl_bus_i:
- process(irc_proc_ce_s, irc_proc_out_s, lxmaster_ce_s, lxmaster_out_s,
- lxfncapprox_ce_s, lxfncapprox_out_s, tumbl_xmemb_i_s)
+ process(irc_proc_ce_r, irc_proc_out_s, lxmaster_ce_r, lxmaster_out_s,
+ lxfncapprox_ce_r, lxfncapprox_out_s, tumbl_xmemb_i_s)
begin
tumbl_xmemb_i_s.data <= (others => 'X');
-- NOTE: This is input to Tumbl EXEQ - with MUL instruction for input > 18-bit,
-- (i.e. more DSPs in a sequence), this already has tough timing constraints
-- and SmartXplorer has to be used with XiSE or use Synplify.
- if irc_proc_ce_s = '1' then
+ if irc_proc_ce_r = '1' then
tumbl_xmemb_i_s.data <= irc_proc_out_s;
- elsif lxmaster_ce_s = '1' then
+ elsif lxmaster_ce_r = '1' then
tumbl_xmemb_i_s.data(15 downto 0) <= lxmaster_out_s;
tumbl_xmemb_i_s.data(31 downto 16) <= (others => '0');
- elsif lxfncapprox_ce_s = '1' then
+ elsif lxfncapprox_ce_r = '1' then
tumbl_xmemb_i_s.data <= lxfncapprox_out_s;
end if;