OpenCores
URL https://opencores.org/ocsvn/ion/ion/trunk

Subversion Repositories ion

[/] [ion/] [trunk/] [vhdl/] [mips_cache_stub.vhdl] - Diff between revs 64 and 72

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 64 Rev 72
Line 47... Line 47...
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- KNOWN TROUBLE:
-- KNOWN TROUBLE:
-- 
-- 
-- Apart from the very rough looks of the code, there's a few known problems:
-- Apart from the very rough looks of the code, there's a few known problems:
--
--
-- 1.- Access to unmapped areas wil crash the CPU
-- 1.- Write address setup and hold wrt. WE\ not guaranteed
 
--      WE\ needs to be asserted later and deasserted earlier. The easy way 
 
--      would be using two extra cycles. Must find some less cosly way.
 
--      So far, in my particular test conditions, this is not giving me trouble
 
--      so this will have to wait.
 
-- 
 
-- 2.- Access to unmapped areas will crash the CPU
--      A couple states are missing in the state machine for handling accesses 
--      A couple states are missing in the state machine for handling accesses 
--      to unmapped areas. I haven't yet decided how to handle that (return 
--      to unmapped areas. I haven't yet decided how to handle that (return 
--      zero, trigger trap, mirror another mapped area...)
--      zero, trigger trap, mirror another mapped area...).
-- 2.- Code refills from SRAM is unimplemented yet
--
 
-- 3.- Code refills from SRAM is unimplemented yet
--      To be done for sheer lack of time.
--      To be done for sheer lack of time.
-- 3.- Address decoding is hardcoded in mips_pkg
--
--      It should be done here using module generics and not package constants.
 
-- 4.- Does not work as a real 1-word cache yet
-- 4.- Does not work as a real 1-word cache yet
--      That functionality is still missing, all accesses 'miss'. It should be
--      That functionality is still missing, all accesses 'miss'. It should be
--      implemented, as a way to test the real cache logic on a small scale.
--      implemented, as a way to test the real cache logic on a small scale.
--
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Line 121... Line 127...
 
 
 
 
 
 
architecture stub of mips_cache_stub is
architecture stub of mips_cache_stub is
 
 
 
-- Wait state counter -- we're supporting static memory from 10 to >100 ns
 
subtype t_wait_state_counter is std_logic_vector(2 downto 0);
 
 
-- state machines: definition of states -----------------------------
-- state machines: definition of states -----------------------------
 
 
type t_code_cache_state is (
type t_code_cache_state is (
    code_normal,                -- 
    code_normal,                -- 
    code_wait_for_dcache,       -- wait for D-cache to stop using the buses
    code_wait_for_dcache,       -- wait for D-cache to stop using the buses
Line 140... Line 149...
    code_bug                    -- caught an error in the state machine
    code_bug                    -- caught an error in the state machine
   );
   );
 
 
-- I-cache state machine state register & next state
-- I-cache state machine state register & next state
signal cps, cns :           t_code_cache_state;
signal cps, cns :           t_code_cache_state;
 
-- Wait state counter, formally part of the state machine register
 
signal code_wait_ctr :      t_wait_state_counter;
 
 
 
 
type t_data_cache_state is (
type t_data_cache_state is (
    data_normal,
    data_normal,
 
 
Line 156... Line 167...
    data_read_io_0,             -- rd addr on io_rd_addr, io_vma active
    data_read_io_0,             -- rd addr on io_rd_addr, io_vma active
    data_read_io_1,             -- rd data on io_rd_data
    data_read_io_1,             -- rd data on io_rd_data
 
 
    data_write_io_0,            -- wr addr & data in io_wr_*, io_byte_we active
    data_write_io_0,            -- wr addr & data in io_wr_*, io_byte_we active
 
 
    data_writethrough_sram_0,   -- wr addr & data in SRAM buses (low hword)
    data_writethrough_sram_0a,  -- wr addr & data in SRAM buses (low hword)
    data_writethrough_sram_1,   -- wr addr & data in SRAM buses (high hword)
    data_writethrough_sram_0b,  -- WE asserted
 
    data_writethrough_sram_0c,  -- WE deasserted
 
    data_writethrough_sram_1a,  -- wr addr & data in SRAM buses (high hword)
 
    data_writethrough_sram_1b,  -- WE asserted
 
    data_writethrough_sram_1c,  -- WE deasserted
 
 
    data_ignore_write,          -- hook for raising error flag FIXME untested
    data_ignore_write,          -- hook for raising error flag FIXME untested
 
    data_ignore_read,           -- hook for raising error flag FIXME untested
 
 
    data_bug                    -- caught an error in the state machine
    data_bug                    -- caught an error in the state machine
   );
   );
 
 
 
 
-- D-cache state machine state register & next state
-- D-cache state machine state register & next state
signal dps, dns :           t_data_cache_state;
signal dps, dns :           t_data_cache_state;
 
-- Wait state counter, formally part of the state machine register
 
signal dws_ctr, dws :       t_wait_state_counter;
 
signal load_dws_ctr :       std_logic;
 
signal dws_wait_done :      std_logic;
 
 
 
 
 
 
-- CPU interface registers ------------------------------------------
-- CPU interface registers ------------------------------------------
signal data_rd_addr_reg :   t_pc;
signal data_rd_addr_reg :   t_pc;
signal data_wr_addr_reg :   t_pc;
signal data_wr_addr_reg :   t_pc;
signal code_rd_addr_reg :   t_pc;
signal code_rd_addr_reg :   t_pc;
Line 224... Line 246...
signal code_rd_addr_mask :  t_addr_decode;
signal code_rd_addr_mask :  t_addr_decode;
signal data_rd_addr_mask :  t_addr_decode;
signal data_rd_addr_mask :  t_addr_decode;
signal data_wr_addr_mask :  t_addr_decode;
signal data_wr_addr_mask :  t_addr_decode;
 
 
-- Memory map area being accessed for each of the 3 buses:
-- Memory map area being accessed for each of the 3 buses:
-- 00 -> BRAM (read only)
 
-- 01 -> SRAM
 
-- 10 -> IO
 
-- 11 -> Unmapped
 
 
 
signal code_rd_attr :       t_range_attr;
signal code_rd_attr :       t_range_attr;
signal data_rd_attr :       t_range_attr;
signal data_rd_attr :       t_range_attr;
signal data_wr_attr :       t_range_attr;
signal data_wr_attr :       t_range_attr;
signal code_rd_type :       t_memory_type;
 
signal data_rd_type :       t_memory_type;
 
signal data_wr_type :       t_memory_type;
 
 
 
 
 
 
 
begin
begin
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Cache control state machines 
-- Cache control state machines 
Line 259... Line 271...
    end if;
    end if;
end process cache_state_machine_regs;
end process cache_state_machine_regs;
 
 
-- (The code state machine occasionally 'waits' for the D-cache)
-- (The code state machine occasionally 'waits' for the D-cache)
code_state_machine_transitions:
code_state_machine_transitions:
process(cps, dps, code_rd_vma, code_miss, code_rd_type,
process(cps, dps, code_rd_vma, code_miss, code_rd_attr,
        write_pending, read_pending)
        write_pending, read_pending)
begin
begin
    case cps is
    case cps is
    when code_normal =>
    when code_normal =>
        -- FIXME wrong logic, these signals are not active in the same cycle
        -- FIXME wrong logic, these signals are not active in the same cycle
Line 310... Line 322...
 
 
 
 
-- This state machine does not overlap IO/BRAM/SRAM accesses for simplicity.
-- This state machine does not overlap IO/BRAM/SRAM accesses for simplicity.
 
 
data_state_machine_transitions:
data_state_machine_transitions:
process(dps, write_pending, read_pending, data_rd_type, data_wr_type)
process(dps, write_pending, read_pending,
 
        data_rd_attr, data_wr_attr, dws_wait_done)
begin
begin
    case dps is
    case dps is
    when data_normal =>
    when data_normal =>
        if write_pending='1' then
        if write_pending='1' then
            case data_wr_type is
            case data_wr_attr.mem_type is
            when MT_BRAM        => dns <= data_ignore_write;
            when MT_BRAM        => dns <= data_ignore_write;
            when MT_SRAM_16B    => dns <= data_writethrough_sram_0;
            when MT_SRAM_16B    => dns <= data_writethrough_sram_0a;
            when MT_IO_SYNC     => dns <= data_write_io_0;
            when MT_IO_SYNC     => dns <= data_write_io_0;
            when others         => dns <= dps; -- ignore write to undecoded area
            -- FIXME ignore write to undecoded area (clear pending flag)                        
 
            when others         => dns <= dps;
            end case;
            end case;
 
 
        elsif read_pending='1' then
        elsif read_pending='1' then
            case data_rd_type is
            case data_rd_attr.mem_type is
            when MT_BRAM        => dns <= data_refill_bram_0;
            when MT_BRAM        => dns <= data_refill_bram_0;
            when MT_SRAM_16B    => dns <= data_refill_sram_0;
            when MT_SRAM_16B    => dns <= data_refill_sram_0;
            when MT_IO_SYNC     => dns <= data_read_io_0;
            when MT_IO_SYNC     => dns <= data_read_io_0;
            when others         => dns <= dps; -- ignore read from undec. area
            -- FIXME ignore read from undecoded area (clear pending flag) 
                           -- FIXME should raise debug flag 
            when others         => dns <= data_ignore_read;
            end case;
            end case;
        else
        else
            dns <= dps;
            dns <= dps;
        end if;
        end if;
 
 
Line 344... Line 358...
 
 
    when data_read_io_1 =>
    when data_read_io_1 =>
        dns <= data_normal;
        dns <= data_normal;
 
 
    when data_refill_sram_0 =>
    when data_refill_sram_0 =>
 
        if dws_wait_done='1' then
        dns <= data_refill_sram_1;
        dns <= data_refill_sram_1;
 
        else
 
            dns <= dps;
 
        end if;
 
 
    when data_refill_sram_1 =>
    when data_refill_sram_1 =>
 
        if dws_wait_done='1' then
        dns <= data_normal;
        dns <= data_normal;
 
        else
 
            dns <= dps;
 
        end if;
 
 
    when data_refill_bram_0 =>
    when data_refill_bram_0 =>
        dns <= data_refill_bram_1;
        dns <= data_refill_bram_1;
 
 
    when data_refill_bram_1 =>
    when data_refill_bram_1 =>
        dns <= data_normal;
        dns <= data_normal;
 
 
    when data_writethrough_sram_0 =>
    when data_writethrough_sram_0a =>
        dns <= data_writethrough_sram_1;
        dns <= data_writethrough_sram_0b;
 
 
    when data_writethrough_sram_1 =>
    when data_writethrough_sram_0b =>
 
        if dws_wait_done='1' then
 
            dns <= data_writethrough_sram_0c;
 
        else
 
            dns <= dps;
 
        end if;
 
 
 
    when data_writethrough_sram_0c =>
 
        dns <= data_writethrough_sram_1a;
 
 
 
    when data_writethrough_sram_1a =>
 
        dns <= data_writethrough_sram_1b;
 
 
 
    when data_writethrough_sram_1b =>
 
        if dws_wait_done='1' then
 
            dns <= data_writethrough_sram_1c;
 
        else
 
            dns <= dps;
 
        end if;
 
 
 
    when data_writethrough_sram_1c =>
        dns <= data_normal;
        dns <= data_normal;
 
 
 
 
    when data_ignore_write =>
    when data_ignore_write =>
        dns <= data_normal;
        dns <= data_normal;
 
 
 
    when data_ignore_read =>
 
        dns <= data_normal;
 
 
    when data_bug =>
    when data_bug =>
        -- Something weird happened, we have 1 cycle to do something like raise
        -- Something weird happened, we have 1 cycle to do something like raise
        -- an error flag, etc. After 1 cycle, back to normal.    
        -- an error flag, etc. After 1 cycle, back to normal.    
        dns <= data_normal;
        dns <= data_normal;
 
 
Line 375... Line 421...
        -- Should never arrive here. If we do, we handle it in state data_bug.
        -- Should never arrive here. If we do, we handle it in state data_bug.
        dns <= data_bug;
        dns <= data_bug;
    end case;
    end case;
end process data_state_machine_transitions;
end process data_state_machine_transitions;
 
 
 
load_dws_ctr <= '1' when
 
    (dns=data_refill_sram_0 and dps/=data_refill_sram_0) or
 
    (dns=data_refill_sram_1 and dps/=data_refill_sram_1) or
 
    (dns=data_writethrough_sram_0a) or
 
    (dns=data_writethrough_sram_1a)
 
    else '0';
 
 
 
with dns select dws <=
 
    data_rd_attr.wait_states    when data_refill_sram_0,
 
    data_wr_attr.wait_states    when data_writethrough_sram_0a,
 
    data_wr_attr.wait_states    when data_writethrough_sram_1a,
 
    data_wr_attr.wait_states    when others;
 
 
 
data_wait_state_counter:
 
process(clk)
 
begin
 
    if clk'event and clk='1' then
 
        if reset='1' then
 
            dws_ctr <= (others => '0');
 
        else
 
            if load_dws_ctr='1' then
 
                dws_ctr <= dws;
 
            elsif dws_wait_done='0' then
 
                dws_ctr <= dws_ctr - 1;
 
            end if;
 
        end if;
 
    end if;
 
end process data_wait_state_counter;
 
 
 
dws_wait_done <= '1' when dws_ctr="000" else '0';
 
 
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- CPU interface registers and address decoding --------------------------------
-- CPU interface registers and address decoding --------------------------------
 
 
 
 
Line 400... Line 477...
            if data_rd_vma='1' then
            if data_rd_vma='1' then
                read_pending <= '1';
                read_pending <= '1';
                data_rd_addr_reg <= data_rd_addr(31 downto 2);
                data_rd_addr_reg <= data_rd_addr(31 downto 2);
            elsif dps=data_refill_sram_1 or
            elsif dps=data_refill_sram_1 or
                  dps=data_refill_bram_1 or
                  dps=data_refill_bram_1 or
                  dps=data_read_io_0 then
                  dps=data_read_io_0 or
 
                  dps=data_ignore_read then
                read_pending <= '0';
                read_pending <= '0';
            end if;
            end if;
 
 
            -- Raise 'write_pending' at the 1st cycle of a read, clear it when
            -- Raise 'write_pending' at the 1st cycle of a read, clear it when
            -- the write (writethrough actually) operation has been done.
            -- the write (writethrough actually) operation has been done.
Line 412... Line 490...
            if byte_we/="0000" and dps=data_normal then
            if byte_we/="0000" and dps=data_normal then
                byte_we_reg <= byte_we;
                byte_we_reg <= byte_we;
                data_wr_reg <= data_wr;
                data_wr_reg <= data_wr;
                data_wr_addr_reg <= data_wr_addr;
                data_wr_addr_reg <= data_wr_addr;
                write_pending <= '1';
                write_pending <= '1';
            elsif dps=data_writethrough_sram_1 or
            elsif dps=data_writethrough_sram_1b or
                  dps=data_write_io_0 or
                  dps=data_write_io_0 or
                  dps=data_ignore_write then
                  dps=data_ignore_write then
                write_pending <= '0';
                write_pending <= '0';
                byte_we_reg <= "0000";
                byte_we_reg <= "0000";
            end if;
            end if;
Line 449... Line 527...
data_rd_addr_mask <= data_rd_addr_reg(31 downto t_addr_decode'low);
data_rd_addr_mask <= data_rd_addr_reg(31 downto t_addr_decode'low);
data_wr_addr_mask <= data_wr_addr_reg(31 downto t_addr_decode'low);
data_wr_addr_mask <= data_wr_addr_reg(31 downto t_addr_decode'low);
 
 
 
 
code_rd_attr <= decode_addr(code_rd_addr_mask);
code_rd_attr <= decode_addr(code_rd_addr_mask);
code_rd_type <= code_rd_attr(6 downto 4);
 
 
 
data_rd_attr <= decode_addr(data_rd_addr_mask);
data_rd_attr <= decode_addr(data_rd_addr_mask);
data_rd_type <= data_rd_attr(6 downto 4);
 
 
 
data_wr_attr <= decode_addr(data_wr_addr_mask);
data_wr_attr <= decode_addr(data_wr_addr_mask);
data_wr_type <= data_wr_attr(6 downto 4);
 
 
 
 
 
--with code_rd_addr_mask select code_rd_type <=
 
--    "000"   when ADDR_BOOT,
 
--    "001"   when ADDR_XRAM,
 
--    "011"   when others;
 
--
 
--with data_rd_addr_mask select data_rd_type <=
 
--    "000"   when ADDR_BOOT,
 
--    "001"   when ADDR_XRAM,
 
--    "010"   when ADDR_IO,
 
--    "011"   when others;
 
--
 
--with data_wr_addr_mask select data_wr_type <=
 
--    "001"   when ADDR_XRAM,
 
--    "010"   when ADDR_IO,
 
--    "011"   when others;
 
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- BRAM interface
-- BRAM interface
 
 
 
 
-- BRAMm address can come from code or data buses
-- BRAMm address can come from code or data buses
Line 585... Line 642...
    data_wr_addr_reg(sram_address'high downto 2)    when others;
    data_wr_addr_reg(sram_address'high downto 2)    when others;
 
 
-- SRAM addr bus LSB depends on the D-cache state because we read/write the
-- SRAM addr bus LSB depends on the D-cache state because we read/write the
-- halfwords sequentially in successive cycles.
-- halfwords sequentially in successive cycles.
with dps select sram_address(1) <=
with dps select sram_address(1) <=
    '0'     when data_writethrough_sram_0,
    '0'     when data_writethrough_sram_0a,
    '1'     when data_writethrough_sram_1,
    '0'     when data_writethrough_sram_0b,
 
    '0'     when data_writethrough_sram_0c,
 
    '1'     when data_writethrough_sram_1a,
 
    '1'     when data_writethrough_sram_1b,
 
    '1'     when data_writethrough_sram_1c,
    '0'     when data_refill_sram_0,
    '0'     when data_refill_sram_0,
    '1'     when data_refill_sram_1,
    '1'     when data_refill_sram_1,
    '0'     when others;
    '0'     when others;
 
 
-- SRAM databus i(when used for output) comes from either hword of the data
-- SRAM databus i(when used for output) comes from either hword of the data
-- write register.
-- write register.
with dps select sram_databus <=
with dps select sram_databus <=
    data_wr_reg(31 downto 16)   when data_writethrough_sram_0,
    data_wr_reg(31 downto 16)   when data_writethrough_sram_0a,
    data_wr_reg(15 downto  0)   when data_writethrough_sram_1,
    data_wr_reg(31 downto 16)   when data_writethrough_sram_0b,
 
    data_wr_reg(31 downto 16)   when data_writethrough_sram_0c,
 
    data_wr_reg(15 downto  0)   when data_writethrough_sram_1a,
 
    data_wr_reg(15 downto  0)   when data_writethrough_sram_1b,
 
    data_wr_reg(15 downto  0)   when data_writethrough_sram_1c,
    (others => 'Z')             when others;
    (others => 'Z')             when others;
 
 
-- The byte_we is split in two similarly.
-- The byte_we is split in two similarly.
with dps select sram_byte_we_n <=
with dps select sram_byte_we_n <=
    not byte_we_reg(3 downto 2) when data_writethrough_sram_0,
    not byte_we_reg(3 downto 2) when data_writethrough_sram_0b,
    not byte_we_reg(1 downto 0) when data_writethrough_sram_1,
    not byte_we_reg(1 downto 0) when data_writethrough_sram_1b,
    "11"                        when others;
    "11"                        when others;
 
 
-- SRAM OE\ is only asserted low for read cycles
-- SRAM OE\ is only asserted low for read cycles
with dps select sram_oe_n <=
with dps select sram_oe_n <=
    '0' when data_refill_sram_0,
    '0' when data_refill_sram_0,
Line 618... Line 683...
 
 
sram_input_halfword_register:
sram_input_halfword_register:
process(clk)
process(clk)
begin
begin
    if clk'event and clk='1' then
    if clk'event and clk='1' then
 
        if dps=data_refill_sram_0 then
        sram_rd_data_reg <= sram_databus;
        sram_rd_data_reg <= sram_databus;
    end if;
    end if;
 
    end if;
end process sram_input_halfword_register;
end process sram_input_halfword_register;
 
 
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- I/O interface -- IO is assumed to behave like synchronous memory
-- I/O interface -- IO is assumed to behave like synchronous memory
Line 651... Line 718...
    '0' when others;
    '0' when others;
 
 
-- Assert code_wait until the cycle where the CPU has valid data word on its
-- Assert code_wait until the cycle where the CPU has valid data word on its
-- code bus AND no other operations are ongoing that may use the external buses.
-- code bus AND no other operations are ongoing that may use the external buses.
with dps select data_wait <=
with dps select data_wait <=
    '1' when data_writethrough_sram_0,
    '1' when data_writethrough_sram_0a,
    '1' when data_writethrough_sram_1,
    '1' when data_writethrough_sram_0b,
 
    '1' when data_writethrough_sram_0c,
 
    '1' when data_writethrough_sram_1a,
 
    '1' when data_writethrough_sram_1b,
 
    '1' when data_writethrough_sram_1c,
    '1' when data_refill_sram_0,
    '1' when data_refill_sram_0,
    '1' when data_refill_sram_1,
    '1' when data_refill_sram_1,
    '1' when data_refill_bram_0,
    '1' when data_refill_bram_0,
    '1' when data_refill_bram_1,
    '1' when data_refill_bram_1,
    '1' when data_read_io_0,
    '1' when data_read_io_0,

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.