forked from cores/microwatt
				
			uart: Add a simulation model for the 16550 compatible UART
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>jtag-port
							parent
							
								
									4eae29801b
								
							
						
					
					
						commit
						cc10f6b289
					
				@ -0,0 +1,421 @@
 | 
			
		||||
library ieee;
 | 
			
		||||
use ieee.std_logic_1164.all;
 | 
			
		||||
use ieee.numeric_std.all;
 | 
			
		||||
 | 
			
		||||
library work;
 | 
			
		||||
use work.sim_console.all;
 | 
			
		||||
 | 
			
		||||
entity uart_top is
 | 
			
		||||
    port(
 | 
			
		||||
        wb_clk_i    : in std_ulogic;
 | 
			
		||||
        wb_rst_i    : in std_ulogic;
 | 
			
		||||
        wb_adr_i    : in std_ulogic_vector(2 downto 0);
 | 
			
		||||
        wb_dat_i    : in std_ulogic_vector(7 downto 0);
 | 
			
		||||
        wb_dat_o    : out std_ulogic_vector(7 downto 0);
 | 
			
		||||
        wb_we_i     : in std_ulogic;
 | 
			
		||||
        wb_stb_i    : in std_ulogic;
 | 
			
		||||
        wb_cyc_i    : in std_ulogic;
 | 
			
		||||
        wb_ack_o    : out std_ulogic;
 | 
			
		||||
        int_o       : out std_ulogic;
 | 
			
		||||
        stx_pad_o   : out std_ulogic;
 | 
			
		||||
        srx_pad_i   : in std_ulogic;
 | 
			
		||||
        rts_pad_o   : out std_ulogic;
 | 
			
		||||
        cts_pad_i   : in std_ulogic;
 | 
			
		||||
        dtr_pad_o   : out std_ulogic;
 | 
			
		||||
        dsr_pad_i   : in std_ulogic;
 | 
			
		||||
        ri_pad_i    : in std_ulogic;
 | 
			
		||||
        dcd_pad_i   : in std_ulogic
 | 
			
		||||
	);
 | 
			
		||||
end entity uart_top;
 | 
			
		||||
 | 
			
		||||
architecture behaviour of uart_top is
 | 
			
		||||
 | 
			
		||||
    -- Call POLL every N clocks to generate interrupts
 | 
			
		||||
    constant POLL_DELAY       : natural   := 100;
 | 
			
		||||
 | 
			
		||||
    -- Register definitions
 | 
			
		||||
    subtype reg_adr_t is std_ulogic_vector(2 downto 0);
 | 
			
		||||
 | 
			
		||||
    constant REG_IDX_RXTX     : reg_adr_t := "000";
 | 
			
		||||
    constant REG_IDX_IER      : reg_adr_t := "001";
 | 
			
		||||
    constant REG_IDX_IIR_FCR  : reg_adr_t := "010";
 | 
			
		||||
    constant REG_IDX_LCR      : reg_adr_t := "011";
 | 
			
		||||
    constant REG_IDX_MCR      : reg_adr_t := "100";
 | 
			
		||||
    constant REG_IDX_LSR      : reg_adr_t := "101";
 | 
			
		||||
    constant REG_IDX_MSR      : reg_adr_t := "110";
 | 
			
		||||
    constant REG_IDX_SCR      : reg_adr_t := "111";
 | 
			
		||||
 | 
			
		||||
    -- IER bits
 | 
			
		||||
    constant REG_IER_RDI_BIT    : natural := 0;
 | 
			
		||||
    constant REG_IER_THRI_BIT   : natural := 1;
 | 
			
		||||
    constant REG_IER_RLSI_BIT   : natural := 2;
 | 
			
		||||
    constant REG_IER_MSI_BIT    : natural := 3;
 | 
			
		||||
 | 
			
		||||
    -- IIR bit
 | 
			
		||||
    constant REG_IIR_NO_INT     : natural := 0;
 | 
			
		||||
    -- IIR values for bit 3 downto 0
 | 
			
		||||
    constant REG_IIR_RDI        : std_ulogic_vector(3 downto 1) := "010";
 | 
			
		||||
    constant REG_IIR_THRI       : std_ulogic_vector(3 downto 1) := "001";
 | 
			
		||||
    constant REG_IIR_RLSI       : std_ulogic_vector(3 downto 1) := "011";
 | 
			
		||||
    constant REG_IIR_MSI        : std_ulogic_vector(3 downto 1) := "000";
 | 
			
		||||
 | 
			
		||||
    -- FCR bits
 | 
			
		||||
    constant REG_FCR_EN_FIFO_BIT  : natural := 0;  -- Always 1
 | 
			
		||||
    constant REG_FCR_CLR_RCVR_BIT : natural := 1;
 | 
			
		||||
    constant REG_FCR_CLR_XMIT_BIT : natural := 2;
 | 
			
		||||
    constant REG_FCR_DMA_SEL_BIT  : natural := 3;  -- Not implemented
 | 
			
		||||
    -- FCR values for FIFO threshold in bits 7 downto 6
 | 
			
		||||
    constant REG_FCR_FIFO_TRIG1   : std_ulogic_vector(7 downto 6) := "00";
 | 
			
		||||
    constant REG_FCR_FIFO_TRIG4   : std_ulogic_vector(7 downto 6) := "01";
 | 
			
		||||
    constant REG_FCR_FIFO_TRIG8   : std_ulogic_vector(7 downto 6) := "10";
 | 
			
		||||
    constant REG_FCR_FIFO_TRIG14  : std_ulogic_vector(7 downto 6) := "11";
 | 
			
		||||
 | 
			
		||||
    -- LCR bits
 | 
			
		||||
    constant REG_LCR_STOP_BIT     : natural := 2;
 | 
			
		||||
    constant REG_LCR_PARITY_BIT   : natural := 3;
 | 
			
		||||
    constant REG_LCR_EPAR_BIT     : natural := 4;
 | 
			
		||||
    constant REG_LCR_SPAR_BIT     : natural := 5;
 | 
			
		||||
    constant REG_LCR_SBC_BIT      : natural := 6;
 | 
			
		||||
    constant REG_LCR_DLAB_BIT     : natural := 7;
 | 
			
		||||
    -- LCR values for data length (bits 1 downto 0)
 | 
			
		||||
    constant REG_LCR_WLEN5       : std_ulogic_vector(1 downto 0) := "00";
 | 
			
		||||
    constant REG_LCR_WLEN6       : std_ulogic_vector(1 downto 0) := "01";
 | 
			
		||||
    constant REG_LCR_WLEN7       : std_ulogic_vector(1 downto 0) := "10";
 | 
			
		||||
    constant REG_LCR_WLEN8       : std_ulogic_vector(1 downto 0) := "11";
 | 
			
		||||
 | 
			
		||||
    -- MCR bits
 | 
			
		||||
    constant REG_MCR_DTR_BIT     : natural := 0;
 | 
			
		||||
    constant REG_MCR_RTS_BIT     : natural := 1;
 | 
			
		||||
    constant REG_MCR_OUT1_BIT    : natural := 2;
 | 
			
		||||
    constant REG_MCR_OUT2_BIT    : natural := 3;
 | 
			
		||||
    constant REG_MCR_LOOP_BIT    : natural := 4;
 | 
			
		||||
 | 
			
		||||
    -- LSR bits
 | 
			
		||||
    constant REG_LSR_DR_BIT     : natural := 0;
 | 
			
		||||
    constant REG_LSR_OE_BIT     : natural := 1;
 | 
			
		||||
    constant REG_LSR_PE_BIT     : natural := 2;
 | 
			
		||||
    constant REG_LSR_FE_BIT     : natural := 3;
 | 
			
		||||
    constant REG_LSR_BI_BIT     : natural := 4;
 | 
			
		||||
    constant REG_LSR_THRE_BIT   : natural := 5;
 | 
			
		||||
    constant REG_LSR_TEMT_BIT   : natural := 6;
 | 
			
		||||
    constant REG_LSR_FIFOE_BIT  : natural := 7;
 | 
			
		||||
 | 
			
		||||
    -- MSR bits
 | 
			
		||||
    constant REG_MSR_DCTS_BIT    : natural := 0;
 | 
			
		||||
    constant REG_MSR_DDSR_BIT    : natural := 1;
 | 
			
		||||
    constant REG_MSR_TERI_BIT    : natural := 2;
 | 
			
		||||
    constant REG_MSR_DDCD_BIT    : natural := 3;
 | 
			
		||||
    constant REG_MSR_CTS_BIT     : natural := 4;
 | 
			
		||||
    constant REG_MSR_DSR_BIT     : natural := 5;
 | 
			
		||||
    constant REG_MSR_RI_BIT      : natural := 6;
 | 
			
		||||
    constant REG_MSR_DCD_BIT     : natural := 7;
 | 
			
		||||
 | 
			
		||||
    -- Wishbone signals decode:
 | 
			
		||||
    signal reg_idx               : reg_adr_t;
 | 
			
		||||
    signal wb_phase              : std_ulogic;
 | 
			
		||||
    signal reg_write             : std_ulogic;
 | 
			
		||||
    signal reg_read              : std_ulogic;
 | 
			
		||||
 | 
			
		||||
    -- Register storage
 | 
			
		||||
    signal reg_ier  : std_ulogic_vector(3 downto 0);
 | 
			
		||||
    signal reg_iir  : std_ulogic_vector(3 downto 0);
 | 
			
		||||
    signal reg_fcr  : std_ulogic_vector(7 downto 6);
 | 
			
		||||
    signal reg_lcr  : std_ulogic_vector(7 downto 0);
 | 
			
		||||
    signal reg_mcr  : std_ulogic_vector(4 downto 0);
 | 
			
		||||
    signal reg_lsr  : std_ulogic_vector(7 downto 0);
 | 
			
		||||
    signal reg_msr  : std_ulogic_vector(7 downto 0);
 | 
			
		||||
    signal reg_scr  : std_ulogic_vector(7 downto 0);
 | 
			
		||||
 | 
			
		||||
    signal reg_div  : std_ulogic_vector(15 downto 0);
 | 
			
		||||
 | 
			
		||||
    -- Control signals
 | 
			
		||||
    signal rx_fifo_clr : std_ulogic;
 | 
			
		||||
    signal tx_fifo_clr : std_ulogic;
 | 
			
		||||
 | 
			
		||||
    -- Pending interrupts
 | 
			
		||||
    signal int_rdi_pending  : std_ulogic;
 | 
			
		||||
    signal int_thri_pending : std_ulogic;
 | 
			
		||||
    signal int_rlsi_pending : std_ulogic;
 | 
			
		||||
    signal int_msi_pending  : std_ulogic;
 | 
			
		||||
 | 
			
		||||
    -- Actual data output
 | 
			
		||||
    signal data_out : std_ulogic_vector(7 downto 0) := x"00";
 | 
			
		||||
 | 
			
		||||
    -- Incoming data pending signal
 | 
			
		||||
    signal data_in_pending : std_ulogic := '0';
 | 
			
		||||
 | 
			
		||||
    -- Useful aliases
 | 
			
		||||
    alias dlab      : std_ulogic is reg_lcr(REG_LCR_DLAB_BIT);
 | 
			
		||||
 | 
			
		||||
    alias clk       : std_ulogic is wb_clk_i;
 | 
			
		||||
    alias rst       : std_ulogic is wb_rst_i;
 | 
			
		||||
    alias cyc       : std_ulogic is wb_cyc_i;
 | 
			
		||||
    alias stb       : std_ulogic is wb_stb_i;
 | 
			
		||||
    alias we        : std_ulogic is wb_we_i;
 | 
			
		||||
begin
 | 
			
		||||
 | 
			
		||||
    -- Register index shortcut
 | 
			
		||||
    reg_idx <= wb_adr_i(2 downto 0);
 | 
			
		||||
 | 
			
		||||
    -- 2 phases WB process.
 | 
			
		||||
    --
 | 
			
		||||
    -- Among others, this gives us a "free" cycle for the
 | 
			
		||||
    -- side effects of some accesses percolate in the form
 | 
			
		||||
    -- of status bit changes in other registers.
 | 
			
		||||
    wb_cycle: process(clk)
 | 
			
		||||
        variable phase : std_ulogic := '0';
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if wb_phase = '0' then
 | 
			
		||||
                if cyc = '1' and stb = '1' then
 | 
			
		||||
                    wb_ack_o <= '1';
 | 
			
		||||
                    wb_phase <= '1';
 | 
			
		||||
                end if;
 | 
			
		||||
            else
 | 
			
		||||
                wb_ack_o <= '0';
 | 
			
		||||
                wb_phase <= '0';
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- Reg read/write signals
 | 
			
		||||
    reg_write <= cyc and stb and we and not wb_phase;
 | 
			
		||||
    reg_read  <= cyc and stb and not we and not wb_phase;
 | 
			
		||||
 | 
			
		||||
    -- Register read is synchronous to avoid collisions with
 | 
			
		||||
    -- read-clear side effects
 | 
			
		||||
    do_reg_read: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            wb_dat_o <= x"00";
 | 
			
		||||
            if reg_read = '1' then
 | 
			
		||||
                case reg_idx is
 | 
			
		||||
                when REG_IDX_RXTX =>
 | 
			
		||||
                    if dlab = '1' then
 | 
			
		||||
                        wb_dat_o <= reg_div(7 downto 0);
 | 
			
		||||
                    else
 | 
			
		||||
                        wb_dat_o <= data_out;
 | 
			
		||||
                    end if;
 | 
			
		||||
                when REG_IDX_IER =>
 | 
			
		||||
                    if dlab = '1' then
 | 
			
		||||
                        wb_dat_o <= reg_div(15 downto 8);
 | 
			
		||||
                    else
 | 
			
		||||
                        wb_dat_o <= "0000" & reg_ier;
 | 
			
		||||
                    end if;
 | 
			
		||||
                when REG_IDX_IIR_FCR =>
 | 
			
		||||
                    -- Top bits always set as FIFO is always enabled
 | 
			
		||||
                    wb_dat_o <= "1100" & reg_iir;
 | 
			
		||||
                when REG_IDX_LCR =>
 | 
			
		||||
                    wb_dat_o <= reg_lcr;
 | 
			
		||||
                when REG_IDX_LSR =>
 | 
			
		||||
                    wb_dat_o <= reg_lsr;
 | 
			
		||||
                when REG_IDX_MSR =>
 | 
			
		||||
                    wb_dat_o <= reg_msr;
 | 
			
		||||
                when REG_IDX_SCR =>
 | 
			
		||||
                    wb_dat_o <= reg_scr;
 | 
			
		||||
                when others =>
 | 
			
		||||
                end case;
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- Receive/send synchronous process
 | 
			
		||||
    rxtx: process(clk)
 | 
			
		||||
        variable dp       : std_ulogic;
 | 
			
		||||
        variable poll_cnt : natural;
 | 
			
		||||
        variable sim_tmp  : std_ulogic_vector(63 downto 0);
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if rst = '0' then
 | 
			
		||||
                dp := data_in_pending;
 | 
			
		||||
                if dlab = '0' and reg_idx = REG_IDX_RXTX then
 | 
			
		||||
                    if reg_write = '1' then
 | 
			
		||||
                        -- FIFO write
 | 
			
		||||
                        -- XXX Simulate the FIFO and delays for more
 | 
			
		||||
                        -- accurate behaviour & interrupts
 | 
			
		||||
                        sim_console_write(x"00000000000000" & wb_dat_i);
 | 
			
		||||
                    end if;
 | 
			
		||||
                    if reg_read = '1' then
 | 
			
		||||
                        dp := '0';
 | 
			
		||||
                        data_out <= x"00";
 | 
			
		||||
                    end if;
 | 
			
		||||
                end if;
 | 
			
		||||
 | 
			
		||||
                -- Poll for incoming data
 | 
			
		||||
                if poll_cnt = 0 or (reg_read = '1' and reg_idx = REG_IDX_LSR) then
 | 
			
		||||
                    sim_console_poll(sim_tmp);
 | 
			
		||||
                    poll_cnt := POLL_DELAY;
 | 
			
		||||
                    if dp = '0' and sim_tmp(0) = '1' then
 | 
			
		||||
                        dp := '1';
 | 
			
		||||
                        sim_console_read(sim_tmp);
 | 
			
		||||
                        data_out <= sim_tmp(7 downto 0);
 | 
			
		||||
                    end if;
 | 
			
		||||
                    poll_cnt := poll_cnt - 1;
 | 
			
		||||
                end if;
 | 
			
		||||
                data_in_pending <= dp;
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- Interrupt pending bits
 | 
			
		||||
    int_rdi_pending  <= data_in_pending;
 | 
			
		||||
    int_thri_pending <= '1';
 | 
			
		||||
    int_rlsi_pending <= reg_lsr(REG_LSR_OE_BIT) or
 | 
			
		||||
                        reg_lsr(REG_LSR_PE_BIT) or
 | 
			
		||||
                        reg_lsr(REG_LSR_FE_BIT) or
 | 
			
		||||
                        reg_lsr(REG_LSR_BI_BIT);
 | 
			
		||||
    int_msi_pending  <= reg_msr(REG_MSR_DCTS_BIT) or
 | 
			
		||||
                        reg_msr(REG_MSR_DDSR_BIT) or
 | 
			
		||||
                        reg_msr(REG_MSR_TERI_BIT) or
 | 
			
		||||
                        reg_msr(REG_MSR_DDCD_BIT);
 | 
			
		||||
 | 
			
		||||
    -- Derive interrupt output from IIR
 | 
			
		||||
    int_o <= not reg_iir(REG_IIR_NO_INT);
 | 
			
		||||
 | 
			
		||||
    -- Divisor register
 | 
			
		||||
    div_reg_w: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if rst = '1' then
 | 
			
		||||
                reg_div <= (others => '0');
 | 
			
		||||
            elsif reg_write = '1' and dlab = '1' then
 | 
			
		||||
                if reg_idx = REG_IDX_RXTX then
 | 
			
		||||
                    reg_div(7 downto 0) <= wb_dat_i;
 | 
			
		||||
                elsif reg_idx = REG_IDX_IER then
 | 
			
		||||
                    reg_div(15 downto 8) <= wb_dat_i;
 | 
			
		||||
                end if;
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- IER register
 | 
			
		||||
    ier_reg_w: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if rst = '1' then
 | 
			
		||||
                reg_ier <= "0000";
 | 
			
		||||
            else
 | 
			
		||||
                if reg_write = '1' and dlab = '0' and reg_idx = REG_IDX_IER then
 | 
			
		||||
                    reg_ier <= wb_dat_i(3 downto 0);
 | 
			
		||||
                end if;
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- IIR (read only) generation
 | 
			
		||||
    iir_reg_w: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            reg_iir <= "0001";
 | 
			
		||||
            if int_rlsi_pending = '1' and reg_ier(REG_IER_RLSI_BIT) = '1' then
 | 
			
		||||
                reg_iir <= REG_IIR_RLSI & "0";
 | 
			
		||||
            elsif int_rdi_pending = '1' and reg_ier(REG_IER_RDI_BIT) = '1' then
 | 
			
		||||
                reg_iir <= REG_IIR_RDI & "0";
 | 
			
		||||
            elsif int_thri_pending = '1' and reg_ier(REG_IER_THRI_BIT) = '1' then
 | 
			
		||||
                reg_iir <= REG_IIR_THRI & "0";
 | 
			
		||||
            elsif int_msi_pending = '1' and reg_ier(REG_IER_MSI_BIT) = '1' then
 | 
			
		||||
                reg_iir <= REG_IIR_MSI & "0";
 | 
			
		||||
            end if;
 | 
			
		||||
 | 
			
		||||
            -- It *seems* like reading IIR should clear THRI for
 | 
			
		||||
            -- some amount of time until it gets set again  a few
 | 
			
		||||
            -- clocks later if the transmitter is still empty. We
 | 
			
		||||
            -- don't do that at this point.
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- FCR (write only) register
 | 
			
		||||
    fcr_reg_w: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if rst = '1' then
 | 
			
		||||
                reg_fcr <= "11";
 | 
			
		||||
                rx_fifo_clr <= '1';
 | 
			
		||||
                tx_fifo_clr <= '1';
 | 
			
		||||
            elsif reg_write = '1' and reg_idx = REG_IDX_IIR_FCR then
 | 
			
		||||
                reg_fcr <= wb_dat_i(7 downto 6);
 | 
			
		||||
                rx_fifo_clr <= wb_dat_i(REG_FCR_CLR_RCVR_BIT);
 | 
			
		||||
                tx_fifo_clr <= wb_dat_i(REG_FCR_CLR_XMIT_BIT);
 | 
			
		||||
            else
 | 
			
		||||
                rx_fifo_clr <= '0';
 | 
			
		||||
                tx_fifo_clr <= '0';
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- LCR register
 | 
			
		||||
    lcr_reg_w: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if rst = '1' then
 | 
			
		||||
                reg_lcr <= "00000011";
 | 
			
		||||
            elsif reg_write = '1' and reg_idx = REG_IDX_LCR then
 | 
			
		||||
                reg_lcr <= wb_dat_i;
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- MCR register
 | 
			
		||||
    mcr_reg_w: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if rst = '1' then
 | 
			
		||||
                reg_mcr <= "00000";
 | 
			
		||||
            elsif reg_write = '1' and reg_idx = REG_IDX_MCR then
 | 
			
		||||
                reg_mcr <= wb_dat_i(4 downto 0);
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- LSR register
 | 
			
		||||
    lsr_reg_w: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if rst = '1' then
 | 
			
		||||
                reg_lsr <= "00000000";
 | 
			
		||||
            else
 | 
			
		||||
                reg_lsr(REG_LSR_DR_BIT) <= data_in_pending;
 | 
			
		||||
 | 
			
		||||
                -- Clear error bits on read. Those bits are
 | 
			
		||||
                -- always 0 in sim for now.
 | 
			
		||||
                -- if reg_read = '1' and reg_idx = REG_IDX_LSR then
 | 
			
		||||
                --     reg_lsr(REG_LSR_OE_BIT)    <= '0';
 | 
			
		||||
                --     reg_lsr(REG_LSR_PE_BIT)    <= '0';
 | 
			
		||||
                --     reg_lsr(REG_LSR_FE_BIT)    <= '0';
 | 
			
		||||
                --     reg_lsr(REG_LSR_BI_BIT)    <= '0';
 | 
			
		||||
                --     reg_lsr(REG_LSR_FIFOE_BIT) <= '0';
 | 
			
		||||
                -- end if;
 | 
			
		||||
 | 
			
		||||
                -- Tx FIFO empty indicators. Always empty in sim
 | 
			
		||||
                reg_lsr(REG_LSR_THRE_BIT) <= '1';
 | 
			
		||||
                reg_lsr(REG_LSR_TEMT_BIT) <= '1';
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- MSR register
 | 
			
		||||
    msr_reg_w: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if rst = '1' then
 | 
			
		||||
                reg_msr <= "00000000";
 | 
			
		||||
            elsif reg_read = '1' and reg_idx = REG_IDX_MSR then
 | 
			
		||||
                reg_msr <= "00000000";
 | 
			
		||||
                -- XXX TODO bit setting machine...
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
    -- SCR register
 | 
			
		||||
    scr_reg_w: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if rst = '1' then
 | 
			
		||||
                reg_scr <= "00000000";
 | 
			
		||||
            elsif reg_write = '1' and reg_idx = REG_IDX_SCR then
 | 
			
		||||
                reg_scr <= wb_dat_i;
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
 | 
			
		||||
end architecture behaviour;
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue