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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [rocketlib/] [tilelink/] [axibridge.vhd] - Rev 5

Compare with Previous | Blame | View Log

-----------------------------------------------------------------------------
--! @file
--! @copyright Copyright 2015 GNSS Sensor Ltd. All right reserved.
--! @author    Sergey Khabarov - sergeykhbr@gmail.com
--! @brief     TileLink-to-AXI4 bridge implementation.
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
library commonlib;
use commonlib.types_common.all;
--! AMBA system bus specific library.
library ambalib;
--! AXI4 configuration constants.
use ambalib.types_amba4.all;
library rocketlib;
use rocketlib.types_rocket.all;
 
entity AxiBridge is
  port (
    clk   : in  std_logic;
    nrst  : in  std_logic;
 
    --! Tile-to-AXI direction
    tloi : in tile_out_type;
    msto : out nasti_master_out_type;
    --! AXI-to-Tile direction
    msti : in nasti_master_in_type;
    tlio : out tile_in_type
  );
end; 
 
architecture arch_AxiBridge of AxiBridge is
 
  type tile_rstatetype is (rwait_acq, reading);
  type tile_wstatetype is (wwait_acq, writting);
 
  type registers is record
    rstate : tile_rstatetype;
    rd_addr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
    rd_addr_incr : integer;
    rd_beat_cnt : integer;
    rd_xsize : std_logic_vector(2 downto 0); -- encoded AXI4 bytes size
    rd_xact_id : std_logic_vector(2 downto 0);
    rd_g_type : std_logic_vector(3 downto 0);
 
    wstate : tile_wstatetype;
    wr_addr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
    wr_addr_incr : integer;
    wr_beat_cnt : integer;
    wr_xsize : std_logic_vector(2 downto 0); -- encoded AXI4 bytes size
    wr_xact_id : std_logic_vector(2 downto 0);
    wr_g_type : std_logic_vector(3 downto 0);
    wmask : std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
    wdata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
  end record;
 
 
signal r, rin : registers;
 
 
  function functionAxi4MetaData(
    a   : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
    len : integer;
    sz  : std_logic_vector(2 downto 0)
  ) return nasti_metadata_type is
    variable        ret : nasti_metadata_type;
  begin
        ret.addr    := a;
        ret.len     := conv_std_logic_vector(len,8);
        ret.size    := sz;
        ret.burst   := NASTI_BURST_INCR;
        ret.lock    := '0';
        ret.cache   := (others => '0');
        ret.prot    := (others => '0');
        ret.qos     := (others => '0');
        ret.region  := (others => '0');
        return (ret);
  end function;
 
begin
 
  comblogic : process(tloi, msti, r)
    variable v : registers;
    variable vmsto : nasti_master_out_type;
    variable vtlio  : tile_in_type;
 
 
    variable addr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
    variable write : std_logic;
    variable next_ena : std_logic;
 
    variable wWrite     : std_logic;
    variable wb_xsize : std_logic_vector(2 downto 0);    
    variable wbByteAddr : std_logic_vector(2 downto 0);    
 
  begin
 
    v := r;
    addr := (others => '0');
    write := '0';
 
    vmsto.aw_valid        := '0';
    vmsto.aw_bits         := META_NONE;
    vmsto.aw_id           := (others => '0');
    vmsto.w_valid         := '0';
    vmsto.w_data          := (others => '0');
    vmsto.w_last          := '0';
    vmsto.w_strb          := (others => '0');
    vmsto.ar_valid        := '0';
    vmsto.ar_bits         := META_NONE;
    vmsto.ar_id           := (others => '0');
    vmsto.r_ready         := '0';
    vmsto.ar_user         := '0';
    vmsto.aw_user         := '0';
    vmsto.w_user          := '0';
    vmsto.b_ready         := '1';
 
    vtlio.a_ready := '0';
    vtlio.b_valid := '0';
    vtlio.b_opcode := "000";
    vtlio.b_param := "00";
    vtlio.b_size := "0000";
    vtlio.b_source := "000";
    vtlio.b_address := (others => '0');
    vtlio.b_mask := (others => '0');
    vtlio.b_data := (others => '0');
    vtlio.c_ready := '0';
    vtlio.d_valid := '0';
    vtlio.d_opcode := "001";
    vtlio.d_param := "00";
    vtlio.d_size := "0000";
    vtlio.d_source := "000";
    vtlio.d_sink := "0000";
    vtlio.d_addr_lo := "000";
    vtlio.d_data := (others => '0');
    vtlio.d_error := '0';
    vtlio.e_ready := '1';
 
    wWrite := not tloi.a_opcode(2);
 
    if tloi.a_size(3 downto 2) /= "00" then
       wb_xsize     := "011";
    else
       wb_xsize     := '0' & tloi.a_size(1 downto 0);
    end if;
 
    vmsto.aw_valid        := tloi.a_valid and wWrite;
    vmsto.ar_valid        := tloi.a_valid and not wWrite;
 
    case r.wstate is
    when wwait_acq =>
        if vmsto.aw_valid = '1' and r.rstate = rwait_acq then
 
          v.wr_xsize     := wb_xsize;
          v.wr_addr      := tloi.a_address;
          v.wr_addr_incr := XSizeToBytes(conv_integer(wb_xsize));
          v.wr_beat_cnt  := conv_integer(tloi.a_size(3 downto 2));
          v.wr_xact_id   := tloi.a_source;
          v.wmask        := tloi.a_mask;
 
          if msti.aw_ready = '1' then
             v.wstate := writting;
             v.wdata := tloi.a_data;
          end if;
          vmsto.aw_bits         := functionAxi4MetaData(tloi.a_address, v.wr_beat_cnt, wb_xsize);
          vmsto.aw_id(2 downto 0) := tloi.a_source;
          vmsto.aw_id(CFG_ROCKET_ID_BITS-1 downto 3) := (others => '0');
 
          vtlio.a_ready := tloi.a_valid and msti.aw_ready;
        end if;
 
    when writting =>
          if r.wr_beat_cnt = 0 and msti.w_ready = '1' then
              vmsto.w_last := '1';
              v.wstate := wwait_acq;
          elsif msti.w_ready = '1' and tloi.a_valid = '1' then
             v.wr_beat_cnt := r.wr_beat_cnt - 1;
             v.wr_addr := r.wr_addr + r.wr_addr_incr;
             v.wdata := tloi.a_data;
          end if;
          vmsto.w_valid         := '1';
          vmsto.w_data          := r.wdata;
          vmsto.w_strb          := r.wmask;
    when others => 
    end case;
 
 
    case r.rstate is
    when rwait_acq =>
        if vmsto.ar_valid = '1' and r.wstate = wwait_acq then
 
          v.rd_addr := tloi.a_address;
          v.rd_addr_incr := XSizeToBytes(conv_integer(wb_xsize));
          v.rd_beat_cnt := conv_integer(tloi.a_size(3 downto 2));
          v.rd_xsize := wb_xsize;
          v.rd_xact_id := tloi.a_source;
 
          if msti.ar_ready = '1' then
            v.rstate := reading;
          end if;
          vmsto.ar_bits         := functionAxi4MetaData(tloi.a_address, v.rd_beat_cnt, wb_xsize);
          vmsto.ar_id(2 downto 0) := tloi.a_source;
          vmsto.ar_id(CFG_ROCKET_ID_BITS-1 downto 3) := (others => '0');
 
          vtlio.a_ready := tloi.a_valid and msti.ar_ready;
        end if;
 
    when reading =>
          next_ena := tloi.d_ready and msti.r_valid;
          if next_ena = '1' and r.rd_xact_id = msti.r_id(2 downto 0) then
              v.rd_beat_cnt := r.rd_beat_cnt - 1;
              v.rd_addr := r.rd_addr + r.rd_addr_incr;
              if r.rd_beat_cnt = 0 then
                 v.rstate := rwait_acq;
              end if;
          end if;
          vmsto.r_ready         := tloi.d_ready;
    when others => 
    end case;
 
    if r.rstate = reading then
        if r.rd_xact_id = msti.r_id(2 downto 0) then
          vtlio.d_valid                := msti.r_valid;
        else
          vtlio.d_valid                := '0';
        end if;
        vtlio.d_size := "0110";
        vtlio.d_addr_lo       := r.rd_addr(5 downto 3);--!!  depends on AXI_DATA_WIDTH
        vtlio.d_source  := r.rd_xact_id;
        --vtlio.grant_bits_g_type          := r.rd_g_type;
        vtlio.d_data            := msti.r_data;
    elsif r.wstate = writting then
        vtlio.d_valid               := msti.w_ready;
        vtlio.d_addr_lo      := r.wr_addr(5 downto 3);--!!  depends on AXI_DATA_WIDTH
        vtlio.d_source := r.wr_xact_id;
        --vtlio.grant_bits_g_type         := r.wr_g_type;
        --vtlio.grant_bits_data           := (others => '0');
    end if;
 
    rin <= v;
    tlio <= vtlio;
    msto  <= vmsto;
 
  end process;
 
 
  -- registers:
  regs : process(clk, nrst)
  begin 
     if nrst = '0' then
        r.rstate <= rwait_acq;
        r.wstate <= wwait_acq;
     elsif rising_edge(clk) then 
        r <= rin;
     end if; 
  end process;
 
end;
 

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.