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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gaisler/] [uart/] [dcom.vhd] - Rev 2

Compare with Previous | Blame | View Log

------------------------------------------------------------------------------
--  This file is a part of the GRLIB VHDL IP LIBRARY
--  Copyright (C) 2003, Gaisler Research
--
--  This program is free software; you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation; either version 2 of the License, or
--  (at your option) any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program; if not, write to the Free Software
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
-----------------------------------------------------------------------------   
-- Entity:      dcom
-- File:        dcom.vhd
-- Author:      Jiri Gaisler - Gaisler Research
-- Description: DSU Communications module
------------------------------------------------------------------------------  
 
library ieee;
use ieee.std_logic_1164.all;
library grlib;
use grlib.amba.all;
use grlib.stdlib.all;
library gaisler;
use gaisler.misc.all;
use gaisler.libdcom.all;
 
entity dcom is
   port (
      rst    : in  std_ulogic;
      clk    : in  std_ulogic;
      dmai   : out ahb_dma_in_type;
      dmao   : in  ahb_dma_out_type;
      uarti  : out dcom_uart_in_type;
      uarto  : in  dcom_uart_out_type;
      ahbi   : in  ahb_mst_in_type
      );
end;      
 
architecture struct of dcom is
 
type dcom_state_type is (idle, addr1, read1, read2, write1, write2);
 
type reg_type is record
  addr    : std_logic_vector(31 downto 0);
  data    : std_logic_vector(31 downto 0);
  len     : std_logic_vector(5 downto 0);
  write   : std_ulogic;
  clen    : std_logic_vector(1 downto 0);
  state   : dcom_state_type;
  hresp   : std_logic_vector(1 downto 0);
end record;
 
signal r, rin : reg_type;
 
begin
 
  comb : process(dmao, rst, uarto, ahbi, r)
  variable v : reg_type;
  variable enable : std_ulogic;
  variable newlen : std_logic_vector(5 downto 0);
  variable vuarti : dcom_uart_in_type;
  variable vdmai : ahb_dma_in_type;
  variable newaddr : std_logic_vector(31 downto 2);
 
  begin
 
    v := r;
    vuarti.read := '0'; vuarti.write := '0'; vuarti.data := r.data(31 downto 24);
    vdmai.start := '0'; vdmai.burst := '0'; vdmai.size := "10"; vdmai.busy := '0';
    vdmai.address := r.addr; vdmai.wdata := r.data;
    vdmai.write := r.write; vdmai.irq := '0';
 
    -- save hresp
    if dmao.ready = '1' then v.hresp := ahbi.hresp; end if;
 
    -- address incrementer
    newlen := r.len - 1;
    newaddr := r.addr(31 downto 2) + 1;
 
    case r.state is
    when idle =>		-- idle state
      v.clen := "00";
      if uarto.dready = '1' then
        if uarto.data(7) = '1' then v.state := addr1; end if;
	v.write := uarto.data(6); v.len := uarto.data(5 downto 0);  
	vuarti.read := '1';
      end if;
    when addr1 =>		-- receive address
      if uarto.dready = '1' then
	v.addr := r.addr(23 downto 0) & uarto.data;  
	vuarti.read := '1'; v.clen := r.clen + 1;
      end if;
      if (r.clen(1) and not v.clen(1)) = '1' then
	if r.write = '1' then v.state := write1; else v.state := read1; end if;
      end if;
    when read1 =>		-- read AHB
      if dmao.active = '1' then
	if dmao.ready = '1' then
	  v.data := dmao.rdata; v.state := read2;
        end if;
      else vdmai.start := '1'; end if;
      v.clen := "00";
    when read2 =>		-- send read-data on uart
      if uarto.thempty = '1' then
	v.data := r.data(23 downto 0) & uarto.data;  
	vuarti.write := '1'; v.clen := r.clen + 1; 
        if (r.clen(1) and not v.clen(1)) = '1' then
	  v.addr(31 downto 2) := newaddr; v.len := newlen;
          if (v.len(5) and not r.len(5)) = '1' then v.state := idle; 
	  else v.state := read1; end if;
        end if;
      end if;
    when write1 =>		-- receive write-data
      if uarto.dready = '1' then
	v.data := r.data(23 downto 0) & uarto.data;  
	vuarti.read := '1'; v.clen := r.clen + 1;
      end if;
      if (r.clen(1) and not v.clen(1)) = '1' then v.state := write2; end if;
    when write2 =>		-- write AHB
      if dmao.active = '1' then
	if dmao.ready = '1' then 
	  v.addr(31 downto 2) := newaddr; v.len := newlen;
          if (v.len(5) and not r.len(5)) = '1' then v.state := idle; 
	  else v.state := write1; end if;
        end if;
      else vdmai.start := '1'; end if;
      v.clen := "00";
    end case;
 
    if (uarto.lock and rst) = '0' then
      v.state := idle; v.write := '0';
    end if;
 
    rin <= v; dmai <= vdmai; uarti <= vuarti;
 
  end process;
 
  regs : process(clk)
  begin if 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.