Line 88... |
Line 88... |
-- UART_WRITE / UART_READ 0xf00000e0
|
-- UART_WRITE / UART_READ 0xf00000e0
|
-- UART_DIVISOR 0xf00000f0
|
-- UART_DIVISOR 0xf00000f0
|
--
|
--
|
-- Interrupt masks:
|
-- Interrupt masks:
|
--
|
--
|
-- IRQ_COUNTER 0x0001 (bit 18 of the counter is set)
|
-- IRQ_COUNTER 0x00000001 (bit 18 of the counter is set)
|
-- IRQ_COUNTER_NOT 0x0002 (bit 18 of the counter is clear)
|
-- IRQ_COUNTER_NOT 0x00000002 (bit 18 of the counter is clear)
|
-- IRQ_COUNTER2 0x0004 (bit 16 of the counter is set)
|
-- IRQ_COUNTER2 0x00000004 (bit 16 of the counter is set)
|
-- IRQ_COUNTER2_NOT 0x0008 (bit 16 of the counter is clear)
|
-- IRQ_COUNTER2_NOT 0x00000008 (bit 16 of the counter is clear)
|
-- IRQ_COMPARE 0x0010 (counter is equal to compare, clears irq when updated)
|
-- IRQ_COMPARE 0x00000010 (counter is equal to compare, clears irq when updated)
|
-- IRQ_COMPARE2 0x0020 (counter bits 23 to 0 are equal to compare2, clears irq when updated)
|
-- IRQ_COMPARE2 0x00000020 (counter bits 23 to 0 are equal to compare2, clears irq when updated)
|
-- IRQ_UART_READ_AVAILABLE 0x0040 (there is data available for reading on the UART)
|
-- IRQ_UART_READ_AVAILABLE 0x00000040 (there is data available for reading on the UART)
|
-- IRQ_UART_WRITE_AVAILABLE 0x0080 (UART is not busy)
|
-- IRQ_UART_WRITE_AVAILABLE 0x00000080 (UART is not busy)
|
-- EXT_IRQ0 0x0100 (external interrupts on extio_in, 'high' level triggered)
|
-- EXT_IRQ0 0x00010000 (external interrupts on extio_in, high level triggered)
|
-- EXT_IRQ1 0x0200
|
-- EXT_IRQ1 0x00020000
|
-- EXT_IRQ2 0x0400
|
-- EXT_IRQ2 0x00040000
|
-- EXT_IRQ3 0x0800
|
-- EXT_IRQ3 0x00080000
|
-- EXT_IRQ4 0x1000
|
-- EXT_IRQ4 0x00100000
|
-- EXT_IRQ5 0x2000
|
-- EXT_IRQ5 0x00200000
|
-- EXT_IRQ6 0x4000
|
-- EXT_IRQ6 0x00400000
|
-- EXT_IRQ7 0x8000
|
-- EXT_IRQ7 0x00800000
|
|
-- EXT_IRQ0_NOT 0x01000000 (external interrupts on extio_in, low level triggered)
|
|
-- EXT_IRQ1_NOT 0x02000000
|
|
-- EXT_IRQ2_NOT 0x04000000
|
|
-- EXT_IRQ3_NOT 0x08000000
|
|
-- EXT_IRQ4_NOT 0x10000000
|
|
-- EXT_IRQ5_NOT 0x20000000
|
|
-- EXT_IRQ6_NOT 0x40000000
|
|
-- EXT_IRQ7_NOT 0x80000000
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
Line 144... |
Line 152... |
);
|
);
|
end busmux;
|
end busmux;
|
|
|
architecture arch of busmux is
|
architecture arch of busmux is
|
signal write_enable: std_logic;
|
signal write_enable: std_logic;
|
signal irq_cause, irq_mask_reg, uart_divisor: std_logic_vector(15 downto 0);
|
signal uart_divisor: std_logic_vector(15 downto 0);
|
signal irq_status_reg, extio_out_reg: std_logic_vector(7 downto 0);
|
signal irq_status_reg, extio_out_reg: std_logic_vector(7 downto 0);
|
signal periph_data, irq_vector_reg, irq_epc_reg, compare_reg, counter_reg: std_logic_vector(31 downto 0);
|
signal periph_data, irq_vector_reg, irq_cause, irq_mask_reg, irq_epc_reg, compare_reg, counter_reg: std_logic_vector(31 downto 0);
|
signal compare2_reg: std_logic_vector(23 downto 0);
|
signal compare2_reg: std_logic_vector(23 downto 0);
|
signal interrupt, irq, irq_counter, irq_counter_not, irq_counter2, irq_counter2_not, irq_compare, irq_compare2, compare_trig, compare2_trig: std_logic;
|
signal interrupt, irq, irq_counter, irq_counter_not, irq_counter2, irq_counter2_not, irq_compare, irq_compare2, compare_trig, compare2_trig: std_logic;
|
signal data_read_uart, data_write_uart: std_logic_vector(7 downto 0);
|
signal data_read_uart, data_write_uart: std_logic_vector(7 downto 0);
|
signal enable_uart, enable_uart_read, enable_uart_write, uart_write_busy, uart_data_avail: std_logic;
|
signal enable_uart, enable_uart_read, enable_uart_write, uart_write_busy, uart_data_avail: std_logic;
|
|
|
Line 171... |
Line 179... |
if periph_access = '1' then
|
if periph_access = '1' then
|
case address_cpu(7 downto 4) is
|
case address_cpu(7 downto 4) is
|
when "0000" => -- IRQ_VECTOR (RW)
|
when "0000" => -- IRQ_VECTOR (RW)
|
periph_data <= irq_vector_reg;
|
periph_data <= irq_vector_reg;
|
when "0001" => -- IRQ_CAUSE (RO)
|
when "0001" => -- IRQ_CAUSE (RO)
|
periph_data <= x"0000" & irq_cause;
|
periph_data <= irq_cause;
|
when "0010" => -- IRQ_MASK (RW)
|
when "0010" => -- IRQ_MASK (RW)
|
periph_data <= x"0000" & irq_mask_reg;
|
periph_data <= irq_mask_reg;
|
when "0011" => -- IRQ_STATUS (RW)
|
when "0011" => -- IRQ_STATUS (RW)
|
periph_data <= x"000000" & irq_status_reg;
|
periph_data <= x"000000" & irq_status_reg;
|
when "0100" => -- IRQ_EPC (RO)
|
when "0100" => -- IRQ_EPC (RO)
|
periph_data <= irq_epc_reg;
|
periph_data <= irq_epc_reg;
|
when "0101" => -- COUNTER (RO)
|
when "0101" => -- COUNTER (RO)
|
Line 205... |
Line 213... |
|
|
-- peripheral register logic, write to peripheral registers
|
-- peripheral register logic, write to peripheral registers
|
process(clock, reset, counter_reg, address_cpu, data_out_cpu, periph_access, periph_access_we, irq_ack_cpu)
|
process(clock, reset, counter_reg, address_cpu, data_out_cpu, periph_access, periph_access_we, irq_ack_cpu)
|
begin
|
begin
|
if reset = '1' then
|
if reset = '1' then
|
irq_vector_reg <= x"00000000";
|
irq_vector_reg <= (others => '0');
|
irq_mask_reg <= x"0000";
|
irq_mask_reg <= (others => '0');
|
irq_status_reg <= x"00";
|
irq_status_reg <= (others => '0');
|
counter_reg <= x"00000000";
|
counter_reg <= (others => '0');
|
compare_reg <= x"00000000";
|
compare_reg <= (others => '0');
|
compare_trig <= '0';
|
compare_trig <= '0';
|
compare2_reg <= x"000000";
|
compare2_reg <= (others => '0');
|
compare2_trig <= '0';
|
compare2_trig <= '0';
|
extio_out_reg <= x"00";
|
extio_out_reg <= (others => '0');
|
uart_divisor <= x"0000";
|
uart_divisor <= (others => '0');
|
elsif clock'event and clock = '1' then
|
elsif clock'event and clock = '1' then
|
counter_reg <= counter_reg + 1;
|
counter_reg <= counter_reg + 1;
|
if compare_reg = counter_reg then
|
if compare_reg = counter_reg then
|
compare_trig <= '1';
|
compare_trig <= '1';
|
end if;
|
end if;
|
Line 228... |
Line 236... |
if periph_access = '1' and periph_access_we = '1' then
|
if periph_access = '1' and periph_access_we = '1' then
|
case address_cpu(7 downto 4) is
|
case address_cpu(7 downto 4) is
|
when "0000" => -- IRQ_VECTOR
|
when "0000" => -- IRQ_VECTOR
|
irq_vector_reg <= data_out_cpu;
|
irq_vector_reg <= data_out_cpu;
|
when "0010" => -- IRQ_MASK
|
when "0010" => -- IRQ_MASK
|
irq_mask_reg <= data_out_cpu(15 downto 0);
|
irq_mask_reg <= data_out_cpu;
|
when "0011" => -- IRQ_STATUS
|
when "0011" => -- IRQ_STATUS
|
irq_status_reg <= data_out_cpu(7 downto 0);
|
irq_status_reg <= data_out_cpu(7 downto 0);
|
when "0110" => -- IRQ_COMPARE
|
when "0110" => -- IRQ_COMPARE
|
compare_reg <= data_out_cpu;
|
compare_reg <= data_out_cpu;
|
compare_trig <= '0';
|
compare_trig <= '0';
|
Line 323... |
Line 331... |
|
|
stall_cpu <= stall;
|
stall_cpu <= stall;
|
|
|
-- interrupts and peripherals
|
-- interrupts and peripherals
|
interrupt <= '0' when (irq_cause and irq_mask_reg) = x"0000" else '1';
|
interrupt <= '0' when (irq_cause and irq_mask_reg) = x"0000" else '1';
|
irq_cause <= extio_in & not uart_write_busy & uart_data_avail & irq_compare2 & irq_compare & irq_counter2_not & irq_counter2 & irq_counter_not & irq_counter;
|
irq_cause <= not extio_in & extio_in & x"00" & not uart_write_busy & uart_data_avail & irq_compare2 & irq_compare & irq_counter2_not & irq_counter2 & irq_counter_not & irq_counter;
|
|
|
irq_cpu <= irq;
|
irq_cpu <= irq;
|
irq_vector_cpu <= irq_vector_reg;
|
irq_vector_cpu <= irq_vector_reg;
|
irq_counter <= counter_reg(18);
|
irq_counter <= counter_reg(18);
|
irq_counter_not <= not counter_reg(18);
|
irq_counter_not <= not counter_reg(18);
|