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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [mem/] [cache/] [genic.vhd] - Rev 6

Go to most recent revision | Compare with Previous | Blame | View Log

-- $(lic)
-- $(help_generic)
-- $(help_local)
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_unsigned.conv_integer;
use IEEE.std_logic_arith.conv_unsigned;
use work.config.all;
use work.int.all;
use work.memdef.all;
use work.corelib.all;
use work.cache_comp.all;
use work.cache_config.all;
use work.genic_lib.all;
use work.gencmem_lib.all;
use work.bus_comp.all;
 
entity genic is
  port ( 
    rst     : in  std_logic; 
    clk     : in  std_logic;
    hold : in cli_hold;
    i    : in  genic_type_in;
    o    : out genic_type_out;
    ctrl : in gicl_ctrl;
    icmo : in gencmem_type_ic_out;
    icmi : out gencmem_type_ic_in;
    mcio : in ahbmst_mp_out;
    mcii : out ahbmst_mp_in
    );
end genic;
 
architecture rtl of genic is
 
  type genic_datasrc is (genic_mem,genic_cmem);
  type genic_tmp_type is record
    hit ,valid  : std_logic;
    set  : integer;
    pos  : integer;
    setrep : integer;
    sethit  : std_logic_vector(CFG_IC_SETS-1 downto 0);
    setvalid   : std_logic_vector(CFG_IC_SETS-1 downto 0);
    icmi      : gencmem_type_ic_in;
    o  : genic_type_out;
    datasrc  : genic_datasrc;
    ehold, reqinsn, branch : std_logic;
    twrite, dwrite : std_logic;
    newvalid : std_logic_vector(CFG_IC_TLINE_SZ-1 downto 0);
    mcii  : ahbmst_mp_in;
  end record;
  type genic_state is (genic_hit,genic_pempty,genic_stream,genic_pfull,genic_waitwrite);
  type genic_reg_type is record
    setrep : std_logic_vector(lin_log2x(CFG_IC_SETS)-1 downto 0);
    state : genic_state;
    hold : std_logic;
    hit : std_logic;
    mcii  : ahbmst_mp_in;
    faddr : std_logic_vector(GCML_IC_TADDR_BSZ-1 downto 0);
    ready_addr  : std_logic_vector(31 downto 0);
    --flush, fluship : std_logic;
  end record;
  type genic_dbg_type is record
     dummy : std_logic;
     -- pragma translate_off
     dbg : genic_tmp_type;
     -- pragma translate_on
  end record;
  signal r, c       : genic_reg_type;
  signal rdbg, cdbg : genic_dbg_type;
 
begin  
 
  p0: process (clk, rst, r, hold, i, icmo, mcio, ctrl )
    variable v    : genic_reg_type;
    variable t    : genic_tmp_type;
    variable vdbg : genic_dbg_type;
  begin 
 
    -- $(init(t:genic_tmp_type))
 
    v := r;
 
    -- todo: use part of with mcii.address
    -- lin_incdec(t.ahbo.haddr(4 downto 2),t.ahbo.haddr(4 downto 2),'1','1');
    t.icmi.addr := r.ready_addr;
 
    t.datasrc := genic_mem;
    t.ehold :=  hold.dhold;
    t.reqinsn := not (t.ehold or i.annul);
    t.branch := i.bra_v;
    t.twrite := '0';
    t.dwrite := '0';
 
    t.o.mstrobe := '0';
 
    -- cmp
    t.hit := '0';
    t.set := 0;
    for j in CFG_IC_SETS-1 downto 0 loop
      if gicl_is_taghit(i.pc_r,icmo.tag_line(j)) then
        t.hit := '1';
        t.sethit(j) := '1';
        t.set := j;
      end if;
    end loop; 
 
    t.valid := '0';
    if gicl_is_linevalid(i.pc_r,icmo.tag_line(t.set)) then
      t.valid := '1';
    end if;
 
    -- next addr
    if mcio.ready = '1' then
      v.ready_addr := r.mcii.address;
    end if;
 
    -- state
    case r.state is
      when genic_hit =>
 
        t.icmi.addr := i.pc_v;
        t.datasrc := genic_cmem;
        v.hold := '0';
 
        -- remove: 
        v.mcii.burst := ctrl.burst;
        if gicl_is_onetogo(i.pc_r) then
          v.mcii.burst := '0';
        end if;
        v.hit := t.hit;
 
        if t.reqinsn = '1' then
          if (not (t.hit and t.valid)) = '1' then
            v.hold := '1';
            v.state := genic_pempty;
            v.mcii.req := '1';
          end if;
          v.mcii.address := i.pc_r;
          -- todo: use part of with mcii.address
          v.ready_addr := i.pc_r;
        end if;
 
        v.setrep := std_logic_vector(conv_unsigned(t.set, lin_log2x(CFG_IC_SETS)));
 
      when genic_pempty =>
 
        if mcio.ready = '1' then
          t.o.mstrobe := '1';
          if i.bra_r = '1' then
            v.state := genic_pfull;
          else
            v.state := genic_stream;
            v.hold := '0';
          end if;
        end if;
 
        t.branch := i.bra_r;
 
      when genic_stream =>
 
        if t.reqinsn = '1' then
          if mcio.ready = '0' then
            v.hold := '1';
            v.state := genic_pempty;
          else
            if i.bra_v = '1' then
              v.hold := '1';
              v.state := genic_pfull;
            end if;
          end if;
        else
          if mcio.ready = '1' then
            v.hold := '1';
            v.state := genic_pfull;
          end if;
        end if;
 
      when genic_pfull =>
 
      when genic_waitwrite =>
 
        v.state := genic_hit;
        t.icmi.addr := i.pc_r;
        v.hold := '0';
 
      when others => 
    end case;
 
    -- next req
    if mcio.grant = '1' then 
      v.mcii.burst := ctrl.burst;
      v.mcii.req := r.mcii.burst;
      lin_incdec(r.mcii.address(31 downto 2), v.mcii.address(31 downto 2),'1','1');
      if gicl_is_onetogo(r.mcii.address) then
        v.mcii.burst := '0';
        if mcio.ready = '1' then
          v.mcii.req := '0';
        end if;
      end if;
      if (t.branch   = '1') then
        v.mcii.burst := '0';
        v.mcii.req := '0';
      end if;
    end if;
 
    -- finish
    if (mcio.ready = '1') and (r.mcii.req = '0') then
      --v.flush := r.fluship;
      v.state := genic_waitwrite;
      v.hold := '1';
    end if;
 
    -- memdata returned
    if mcio.ready = '1' then
      t.twrite := '1';
      t.dwrite := '1';
    end if;
 
    -- retry
    if mcio.retry = '1' then
      v.mcii.req := '1';
      v.mcii.address := r.ready_addr;
    end if;
 
    -- mexc
    if (mcio.mexc or not mcio.cache) = '1' then 
      t.twrite := '0';
      t.dwrite := '0';
    else
      t.dwrite := t.twrite;
    end if;
 
    -- return data
    t.o.dat_line_v := icmo.dat_line(t.set);
    if CFG_IC_DLINE_SZ = 1 then
      t.pos := 0;
    else
      t.pos := lin_convint(r.ready_addr(GICL_TLINE_U downto GICL_TLINE_D));
    end if;
    case t.datasrc is
      when genic_mem    => t.o.dat_line_v.data(t.pos) := mcio.data;
      when genic_cmem   => t.o.dat_line_v := icmo.dat_line(t.set);
      when others => 
    end case;
 
    -- assemble input tag line
    t.setrep := lin_convint(r.setrep);
    t.icmi.tag_line := icmo.tag_line(t.setrep);
    t.newvalid := lin_decode(r.ready_addr(GICL_TLINE_U downto GICL_TLINE_D));
    if r.hit = '1' then
      t.icmi.tag_line.valid := t.icmi.tag_line.valid or t.newvalid;
    else
      t.icmi.tag_line.valid := t.newvalid;
    end if;
    t.icmi.tag_line.tag := r.ready_addr(GICL_TTAG_U downto GICL_TTAG_D);
    t.icmi.tag_write(t.setrep) := t.twrite;
 
    -- assemble input data line
    t.icmi.dat_line := icmo.dat_line(t.setrep);
    t.icmi.dat_line.data(t.pos) := mcio.data;
    t.icmi.dat_write(t.setrep) := t.dwrite;
 
    -- flush
    --if r.fluship = '1' then
    --  t.icmi.tag_write := (others => '1');
    --  t.icmi.addr(GICL_TADDR_U downto GICL_TADDR_D) := r.faddr;
    --  t.icmi.tag_line.tag := (others => '0');
    --  t.icmi.tag_line.valid := (others => '0');
    --  lin_incdec(r.faddr, v.faddr,'1','1');
    --  if (r.faddr(GICL_TADDR_U) and not v.faddr(GICL_TADDR_U)) = '1' then
    --	v.fluship := '0';
    --  end if;
    --end if;
 
    -- reset
    if ( rst = '0' ) then
      v.state := genic_hit;
      v.hold := '0';
      v.mcii.req := '0';
      --v.flush := '0';
      --v.fluship := '0';
    end if;
 
    t.o.hold := r.hold;
    t.mcii := r.mcii;
    t.mcii.read := '1';
    t.mcii.lock := '0';
    v.mcii.size := lmd_word;
    t.mcii.data := (others => '0');
 
    c <= v;
 
    icmi <= t.icmi;
    o  <= t.o;
    mcii <= t.mcii;
 
    -- pragma translate_off
    vdbg := rdbg;
    vdbg.dbg := t;
    cdbg <= vdbg;
    -- pragma translate_on  end process p0;
 
  end process p0;
 
  pregs : process (clk, c)
  begin
    if rising_edge(clk) then
      r <= c;
      -- pragma translate_off
      rdbg <= cdbg;
      -- pragma translate_on
    end if;
  end process;
 
end rtl;
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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