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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [bus/] [ahbmst_mp.vhd] - Rev 5

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."+";
use IEEE.std_logic_arith.conv_unsigned;
use work.amba.all;
use work.memdef.all;
use work.int.all;
use work.bus_comp.all;
 
entity ahbmst_mp is
  generic ( AHBMST_PORTS : integer := 4 );
  port (
    rst   : in  std_logic;
    clk   : in  std_logic;
    i     : in  ahbmst_mp_in_a(AHBMST_PORTS-1 downto 0);
    o     : out ahbmst_mp_out_a(AHBMST_PORTS-1 downto 0);
    ahbi  : in  ahb_mst_in_type;
    ahbo  : out ahb_mst_out_type
  );
end;
 
architecture rtl of ahbmst_mp is
 
  constant AHBMST_PORTS_BITSZ : integer := lin_log2x(AHBMST_PORTS);
  constant NBO_ZERO : std_logic_vector(AHBMST_PORTS-1 downto 0) := (others => '0');
 
  type ahbmst_mp_tmp_type is record
    ahbo   : ahb_mst_out_type;
    bo_i,nbo_i   : integer;
    o_ready, o_grant, o_mexc : std_logic_vector(AHBMST_PORTS-1 downto 0);   
    o_retry, o_cache, hold, nboreq : std_logic_vector(AHBMST_PORTS-1 downto 0);   
    nbo : std_logic_vector(AHBMST_PORTS_BITSZ-1 downto 0);
    num : std_logic_vector(AHBMST_PORTS_BITSZ-1 downto 0);
  end record;
  type ahbmst_mp_reg_type is record
     retry, cache : std_logic;
     bo    : std_logic_vector(AHBMST_PORTS_BITSZ-1 downto 0);
     ba, bg : std_logic;
  end record;
  type ahbmst_mp_dbg_type is record
     dummy : std_logic;
     -- pragma translate_off
     dbg : ahbmst_mp_tmp_type;
     -- pragma translate_on
  end record;
  signal r, c       : ahbmst_mp_reg_type;
  signal rdbg, cdbg : ahbmst_mp_dbg_type;
 
begin
 
  p0 : process(ahbi, r, rst, i)
    variable v    : ahbmst_mp_reg_type;
    variable t    : ahbmst_mp_tmp_type;
    variable vdbg : ahbmst_mp_dbg_type;
  begin
 
    -- $(init(t:ahbmst_mp_tmp_type))
 
    v := r;
 
    t.o_ready := (others => '0');
    t.o_grant := (others => '0');
    t.o_retry := (others => '0');
    t.o_cache := (others => '0');
    t.o_mexc := (others => '0'); 
 
    -- owner hold 
    t.num := (others => '0');
    t.hold := (others => '0');
    for j in AHBMST_PORTS-1 downto 0 loop
      t.num := std_logic_vector(conv_unsigned(j, AHBMST_PORTS_BITSZ));
      if (r.ba = '1') and
         (i(j).req = '1') and
         (r.bo = t.num) then
        t.hold(j) := '1';
      end if;
    end loop;  -- i
 
    -- next bus owner req
    for k in AHBMST_PORTS-1 downto 0 loop
      t.nboreq(k) := i(k).req;
      for j in AHBMST_PORTS-1 downto 0 loop
        if k /= j then
          if t.hold(j) = '1' then
            t.nboreq(k) := '0';
          end if;
        end if;
      end loop;
    end loop;
 
    -- priority 
    t.nbo_i := 0;
l1: for j in AHBMST_PORTS-1 downto 0 loop
      if t.nboreq(j) = '1' then
        t.nbo_i := j;
        exit l1;
      end if;
    end loop;
 
    -- lock (only per ahb)
    t.ahbo.hlock := '0';
    for j in AHBMST_PORTS-1 downto 0 loop
      if i(j).lock = '1' then
        t.ahbo.hlock := '1';
      end if;
    end loop;
 
    -- ahb signals
    t.ahbo.hbusreq := '0';
    t.ahbo.htrans  := HTRANS_IDLE;
    t.ahbo.haddr   := i(0).address;
 
    if not (t.nboreq = NBO_ZERO) then
 
      t.nbo := std_logic_vector(conv_unsigned(t.nbo_i, AHBMST_PORTS_BITSZ));
      t.ahbo.hbusreq := i(t.nbo_i).req;
      t.ahbo.haddr   := i(t.nbo_i).address;
      t.ahbo.htrans  := HTRANS_NONSEQ;
      t.ahbo.hwrite  := not i(t.nbo_i).read;
      t.ahbo.hsize   := lmd_toamba(i(t.nbo_i).size);
      t.ahbo.hburst := HBURST_SINGLE;
      if i(t.nbo_i).burst = '1' then
        t.ahbo.hburst := HBURST_INCR; 
      end if;
 
      -- burst
      if (r.bo = t.nbo) then
        if (i(t.nbo_i).req = '1') and (r.ba = '1')  then
          if ((not r.retry) = '1') then
            if i(t.nbo_i).burst = '1' then
              t.ahbo.htrans := HTRANS_SEQ;
              -- todo: 1k boundary check
              t.ahbo.hburst := HBURST_INCR; 
            end if;
          end if;
        end if;
      end if;
 
      -- grant
      if (r.bg = '1') then
        if (ahbi.hready = '1') and (i(t.nbo_i).req = '1') then
          if ((not r.retry) = '1') then
            t.o_grant(t.nbo_i) := '1';
          end if;
        end if;
      end if;
 
    end if;
 
    -- retry
    v.retry := '0';
    if (r.ba = '1') and 
       ((ahbi.hresp = HRESP_RETRY) or
        (ahbi.hresp = HRESP_SPLIT))
    then
      v.retry := not ahbi.hready;
    end if;
    if r.retry = '1' then
      t.ahbo.htrans := HTRANS_IDLE;
    end if;
 
    -- ahb return
    t.bo_i := lin_convint(r.bo);
    t.ahbo.hwdata := i(t.bo_i).data;
    if r.ba = '1' then
      t.o_cache(t.bo_i) := r.cache;
      if ahbi.hready = '1' then
        case ahbi.hresp is
	  when HRESP_OKAY => t.o_ready(t.bo_i) := '1'; 
	  when HRESP_RETRY | HRESP_SPLIT=> t.o_retry(t.bo_i) := '1'; 
	  when others => t.o_ready(t.bo_i) := '1'; t.o_mexc(t.bo_i) := '1'; 
        end case;
      end if;
    end if;
 
    -- next
    if ahbi.hready = '1' then
      v.bo := t.nbo;
      v.bg := ahbi.hgrant;
      v.ba := '0';
      if (t.ahbo.htrans = HTRANS_NONSEQ) or (t.ahbo.htrans = HTRANS_SEQ) then
	v.ba := r.bg;
      end if;
    end if;
 
    -- reset
    if rst = '0' then
      v.retry := '0';
      v.cache := '0';
      v.bo := (others => '0');
      v.ba := '0';
      v.bg := '0';
    end if;
 
    c <= v;
 
    for i in AHBMST_PORTS-1 downto 0 loop
      o(i).grant <= t.o_grant(i);
      o(i).ready <= t.o_ready(i);
      o(i).mexc <=  t.o_mexc(i);
      o(i).retry <= t.o_retry(i);
      o(i).data  <= ahbi.hrdata;
    end loop;
 
    ahbo   <= t.ahbo;
 
    -- 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;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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

powered by: WebSVN 2.1.0

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