summaryrefslogtreecommitdiffstats
path: root/gaisler
diff options
context:
space:
mode:
authorBert Lange <b.lange@fzd.de>2011-01-07 14:55:05 +0100
committerBert Lange <b.lange@fzd.de>2011-01-07 14:55:05 +0100
commit09acf7f43a4fff055599637122b73febf2dd2f1b (patch)
tree66d58c7be6ce5b422975c3c80ce45c6a6c723a46 /gaisler
parent72fa0c4b8d3a07ea4cff4265c9b27685178ae74e (diff)
downloadzpu-09acf7f43a4fff055599637122b73febf2dd2f1b.zip
zpu-09acf7f43a4fff055599637122b73febf2dd2f1b.tar.gz
add: UART with debug functionalitiy
Diffstat (limited to 'gaisler')
-rw-r--r--gaisler/rtl/ahbmst.vhd167
-rw-r--r--gaisler/rtl/ahbuart.vhd81
-rw-r--r--gaisler/rtl/dcom.vhd149
-rw-r--r--gaisler/rtl/dcom_uart.vhd325
-rw-r--r--gaisler/rtl/libdcom.vhd171
5 files changed, 893 insertions, 0 deletions
diff --git a/gaisler/rtl/ahbmst.vhd b/gaisler/rtl/ahbmst.vhd
new file mode 100644
index 0000000..de2b144
--- /dev/null
+++ b/gaisler/rtl/ahbmst.vhd
@@ -0,0 +1,167 @@
+------------------------------------------------------------------------------
+-- This file is a part of the GRLIB VHDL IP LIBRARY
+-- Copyright (C) 2003 - 2008, Gaisler Research
+-- Copyright (C) 2008 - 2010, Aeroflex Gaisler
+--
+-- 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: ahbmst
+-- File: ahbmst.vhd
+-- Author: Jiri Gaisler - Gaisler Research
+-- Description: Generic AHB master interface
+------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+library grlib;
+use grlib.amba.all;
+use grlib.stdlib.all;
+use grlib.devices.all;
+library gaisler;
+use gaisler.misc.all;
+
+entity ahbmst is
+ generic (
+ hindex : integer := 0;
+ hirq : integer := 0;
+ venid : integer := VENDOR_GAISLER;
+ devid : integer := 0;
+ version : integer := 0;
+ chprot : integer := 3;
+ incaddr : integer := 0);
+ port (
+ rst : in std_ulogic;
+ clk : in std_ulogic;
+ dmai : in ahb_dma_in_type;
+ dmao : out ahb_dma_out_type;
+ ahbi : in ahb_mst_in_type;
+ ahbo : out ahb_mst_out_type
+ );
+end;
+
+architecture rtl of ahbmst is
+
+constant hconfig : ahb_config_type := (
+ 0 => ahb_device_reg ( venid, devid, 0, version, 0),
+ others => zero32);
+
+type reg_type is record
+ start : std_ulogic;
+ retry : std_ulogic;
+ grant : std_ulogic;
+ active : std_ulogic;
+end record;
+
+signal r, rin : reg_type;
+
+begin
+
+ comb : process(ahbi, dmai, rst, r)
+ variable v : reg_type;
+ variable ready : std_ulogic;
+ variable retry : std_ulogic;
+ variable mexc : std_ulogic;
+ variable inc : std_logic_vector(3 downto 0); -- address increment
+
+ variable haddr : std_logic_vector(31 downto 0); -- AHB address
+ variable hwdata : std_logic_vector(31 downto 0); -- AHB write data
+ variable htrans : std_logic_vector(1 downto 0); -- transfer type
+ variable hwrite : std_ulogic; -- read/write
+ variable hburst : std_logic_vector(2 downto 0); -- burst type
+ variable newaddr : std_logic_vector(9 downto 0); -- next sequential address
+ variable hbusreq : std_ulogic; -- bus request
+ variable hprot : std_logic_vector(3 downto 0); -- transfer type
+ variable xhirq : std_logic_vector(NAHBIRQ-1 downto 0);
+ begin
+
+ v := r; ready := '0'; mexc := '0'; retry := '0'; inc := (others => '0');
+ hprot := conv_std_logic_vector(chprot, 4); -- non-cached supervisor data
+ xhirq := (others => '0'); xhirq(hirq) := dmai.irq;
+
+ haddr := dmai.address; hbusreq := dmai.start; hwdata := dmai.wdata;
+ newaddr := dmai.address(9 downto 0);
+
+ if INCADDR > 0 then
+ inc(conv_integer(dmai.size)) := '1';
+ newaddr := haddr(9 downto 0) + inc;
+ end if;
+
+ if dmai.burst = '0' then hburst := HBURST_SINGLE;
+ else hburst := HBURST_INCR; end if;
+ if dmai.start = '1' then
+ if (r.active and dmai.burst and not r.retry) = '1' then
+ haddr(9 downto 0) := newaddr;
+ if dmai.busy = '1' then htrans := HTRANS_BUSY;
+ else htrans := HTRANS_SEQ; end if;
+ hburst := HBURST_INCR;
+ else htrans := HTRANS_NONSEQ; end if;
+ else htrans := HTRANS_IDLE; end if;
+
+ if r.active = '1' then
+ if ahbi.hready = '1' then
+ case ahbi.hresp is
+ when HRESP_OKAY => ready := '1';
+ when HRESP_RETRY | HRESP_SPLIT=> retry := '1';
+ when others => ready := '1'; mexc := '1';
+ end case;
+ end if;
+ if ((ahbi.hresp = HRESP_RETRY) or (ahbi.hresp = HRESP_SPLIT)) then
+ v.retry := not ahbi.hready;
+ else v.retry := '0'; end if;
+ end if;
+
+ if r.retry = '1' then htrans := HTRANS_IDLE; end if;
+
+ v.start := '0';
+ if ahbi.hready = '1' then
+ v.grant := ahbi.hgrant(hindex);
+ if (htrans = HTRANS_NONSEQ) or (htrans = HTRANS_SEQ) or (htrans = HTRANS_BUSY) then
+ v.active := r.grant; v.start := r.grant;
+ else
+ v.active := '0';
+ end if;
+ end if;
+
+ if rst = '0' then v.retry := '0'; v.active := '0'; end if;
+
+ rin <= v;
+
+ ahbo.haddr <= haddr;
+ ahbo.htrans <= htrans;
+ ahbo.hbusreq <= hbusreq;
+ ahbo.hwdata <= dmai.wdata;
+ ahbo.hconfig <= hconfig;
+ ahbo.hlock <= '0';
+ ahbo.hwrite <= dmai.write;
+ ahbo.hsize <= '0' & dmai.size;
+ ahbo.hburst <= hburst;
+ ahbo.hprot <= hprot;
+ ahbo.hirq <= xhirq;
+ ahbo.hindex <= hindex;
+
+ dmao.start <= r.start;
+ dmao.active <= r.active;
+ dmao.ready <= ready;
+ dmao.mexc <= mexc;
+ dmao.retry <= retry;
+ dmao.haddr <= newaddr;
+ dmao.rdata <= ahbi.hrdata;
+
+ end process;
+
+ regs : process(clk)
+ begin if rising_edge(clk) then r <= rin; end if; end process;
+
+end;
diff --git a/gaisler/rtl/ahbuart.vhd b/gaisler/rtl/ahbuart.vhd
new file mode 100644
index 0000000..3f72b26
--- /dev/null
+++ b/gaisler/rtl/ahbuart.vhd
@@ -0,0 +1,81 @@
+------------------------------------------------------------------------------
+-- This file is a part of the GRLIB VHDL IP LIBRARY
+-- Copyright (C) 2003 - 2008, Gaisler Research
+-- Copyright (C) 2008 - 2010, Aeroflex Gaisler
+--
+-- 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: ahbuart
+-- File: ahbuart.vhd
+-- Author: Jiri Gaisler - Gaisler Research
+-- Description: UART with AHB master interface
+------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+library grlib;
+use grlib.amba.all;
+use grlib.stdlib.all;
+use grlib.devices.all;
+library gaisler;
+use gaisler.misc.all;
+use gaisler.uart.all;
+use gaisler.libdcom.all;
+
+entity ahbuart is
+ generic (
+ hindex : integer := 0;
+ pindex : integer := 0;
+ paddr : integer := 0;
+ pmask : integer := 16#fff#
+ );
+ port (
+ rst : in std_ulogic;
+ clk : in std_ulogic;
+ uarti : in uart_in_type;
+ uarto : out uart_out_type;
+ apbi : in apb_slv_in_type;
+ apbo : out apb_slv_out_type;
+ ahbi : in ahb_mst_in_type;
+ ahbo : out ahb_mst_out_type );
+end;
+
+architecture struct of ahbuart is
+
+constant REVISION : integer := 0;
+
+signal dmai : ahb_dma_in_type;
+signal dmao : ahb_dma_out_type;
+signal duarti : dcom_uart_in_type;
+signal duarto : dcom_uart_out_type;
+
+begin
+
+ ahbmst0 : ahbmst
+ generic map (hindex => hindex, venid => VENDOR_GAISLER, devid => GAISLER_AHBUART)
+ port map (rst, clk, dmai, dmao, ahbi, ahbo);
+
+ dcom_uart0 : dcom_uart generic map (pindex, paddr, pmask)
+ port map (rst, clk, uarti, uarto, apbi, apbo, duarti, duarto);
+
+ dcom0 : dcom port map (rst, clk, dmai, dmao, duarti, duarto, ahbi);
+
+-- pragma translate_off
+ bootmsg : report_version
+ generic map ("ahbuart" & tost(pindex) &
+ ": AHB Debug UART rev " & tost(REVISION));
+-- pragma translate_on
+
+end;
diff --git a/gaisler/rtl/dcom.vhd b/gaisler/rtl/dcom.vhd
new file mode 100644
index 0000000..12e46f8
--- /dev/null
+++ b/gaisler/rtl/dcom.vhd
@@ -0,0 +1,149 @@
+------------------------------------------------------------------------------
+-- This file is a part of the GRLIB VHDL IP LIBRARY
+-- Copyright (C) 2003 - 2008, Gaisler Research
+-- Copyright (C) 2008 - 2010, Aeroflex Gaisler
+--
+-- 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;
diff --git a/gaisler/rtl/dcom_uart.vhd b/gaisler/rtl/dcom_uart.vhd
new file mode 100644
index 0000000..7df6a78
--- /dev/null
+++ b/gaisler/rtl/dcom_uart.vhd
@@ -0,0 +1,325 @@
+------------------------------------------------------------------------------
+-- This file is a part of the GRLIB VHDL IP LIBRARY
+-- Copyright (C) 2003 - 2008, Gaisler Research
+-- Copyright (C) 2008 - 2010, Aeroflex Gaisler
+--
+-- 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_uart
+-- File: dcom_uart.vhd
+-- Author: Jiri Gaisler - Gaisler Research
+-- Description: Asynchronous UART with baud-rate detection.
+------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+library grlib;
+use grlib.amba.all;
+use grlib.stdlib.all;
+use grlib.devices.all;
+library gaisler;
+use gaisler.libdcom.all;
+use gaisler.uart.all;
+--pragma translate_off
+use std.textio.all;
+--pragma translate_on
+
+entity dcom_uart is
+ generic (
+ pindex : integer := 0;
+ paddr : integer := 0;
+ pmask : integer := 16#fff#
+ );
+ port (
+ rst : in std_ulogic;
+ clk : in std_ulogic;
+ ui : in uart_in_type;
+ uo : out uart_out_type;
+ apbi : in apb_slv_in_type;
+ apbo : out apb_slv_out_type;
+ uarti : in dcom_uart_in_type;
+ uarto : out dcom_uart_out_type
+ );
+end;
+
+architecture rtl of dcom_uart is
+
+constant REVISION : integer := 0;
+
+constant pconfig : apb_config_type := (
+ 0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_AHBUART, 0, REVISION, 0),
+ 1 => apb_iobar(paddr, pmask));
+
+type rxfsmtype is (idle, startbit, data, stopbit);
+type txfsmtype is (idle, data, stopbit);
+
+type uartregs is record
+ rxen : std_ulogic; -- receiver enabled
+ dready : std_ulogic; -- data ready
+ rsempty : std_ulogic; -- receiver shift register empty (internal)
+ tsempty : std_ulogic; -- transmitter shift register empty
+ thempty : std_ulogic; -- transmitter hold register empty
+ break : std_ulogic; -- break detected
+ ovf : std_ulogic; -- receiver overflow
+ frame : std_ulogic; -- framing error
+ rhold : std_logic_vector(7 downto 0);
+ rshift : std_logic_vector(7 downto 0);
+ tshift : std_logic_vector(10 downto 0);
+ thold : std_logic_vector(7 downto 0);
+ txstate : txfsmtype;
+ txclk : std_logic_vector(2 downto 0); -- tx clock divider
+ txtick : std_ulogic; -- tx clock (internal)
+ rxstate : rxfsmtype;
+ rxclk : std_logic_vector(2 downto 0); -- rx clock divider
+ rxdb : std_logic_vector(1 downto 0); -- rx data filtering buffer
+ rxtick : std_ulogic; -- rx clock (internal)
+ tick : std_ulogic; -- rx clock (internal)
+ scaler : std_logic_vector(17 downto 0);
+ brate : std_logic_vector(17 downto 0);
+ tcnt : std_logic_vector(1 downto 0); -- autobaud counter
+ rxf : std_logic_vector(4 downto 0); -- rx data filtering buffer
+ fedge : std_ulogic; -- rx falling edge
+end record;
+
+signal r, rin : uartregs;
+
+begin
+
+ uartop : process(rst, r, apbi, uarti, ui )
+ variable rdata : std_logic_vector(31 downto 0);
+ variable scaler : std_logic_vector(17 downto 0);
+ variable rxclk, txclk : std_logic_vector(2 downto 0);
+ variable irxd : std_ulogic;
+ variable v : uartregs;
+
+ begin
+
+ v := r;
+ v.txtick := '0'; v.rxtick := '0'; v.tick := '0'; rdata := (others => '0');
+ v.rxdb(1) := r.rxdb(0);
+
+-- scaler
+
+ if r.tcnt = "11" then scaler := r.scaler - 1;
+ else scaler := r.scaler + 1; end if;
+
+ if r.tcnt /= "11" then
+ if (r.rxdb(1) and not r.rxdb(0)) = '1' then v.fedge := '1'; end if;
+ if (r.fedge) = '1' then
+ v.scaler := scaler;
+ if (v.scaler(17) and not r.scaler(16)) = '1' then
+ v.scaler := "111111111111111011";
+ v.fedge := '0'; v.tcnt := "00";
+ end if;
+ end if;
+ if (r.rxdb(1) and r.fedge and not r.rxdb(0)) = '1' then
+ if (r.brate(17 downto 4)> r.scaler(17 downto 4)) then
+ v.brate := r.scaler; v.tcnt := "00";
+ end if;
+ v.scaler := "111111111111111011";
+ if (r.brate(17 downto 4) = r.scaler(17 downto 4)) then
+ v.tcnt := r.tcnt + 1;
+ if r.tcnt = "10" then
+ v.brate := "0000" & r.scaler(17 downto 4);
+ v.scaler := v.brate; v.rxen := '1';
+ end if;
+ end if;
+ end if;
+ else
+ if (r.break and r.rxdb(1)) = '1' then
+ v.scaler := "111111111111111011";
+ v.brate := (others => '1'); v.tcnt := "00";
+ v.break := '0'; v.rxen := '0';
+ end if;
+ end if;
+
+ if r.rxen = '1' then
+ v.scaler := scaler;
+ v.tick := scaler(15) and not r.scaler(15);
+ if v.tick = '1' then v.scaler := r.brate; end if;
+ end if;
+
+-- read/write registers
+
+ if uarti.read = '1' then v.dready := '0'; end if;
+
+ case apbi.paddr(3 downto 2) is
+ when "01" =>
+ rdata(9 downto 0) := r.tcnt & r.rxdb(0) & r.frame & '0' & r.ovf &
+ r.break & r.thempty & r.tsempty & r.dready;
+ when "10" =>
+ rdata(1 downto 0) := (r.tcnt(1) or r.tcnt(0)) & r.rxen;
+ when others =>
+ rdata(17 downto 0) := r.brate;
+ end case;
+
+ if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
+ case apbi.paddr(3 downto 2) is
+ when "01" =>
+ v.frame := apbi.pwdata(6);
+ v.ovf := apbi.pwdata(4);
+ v.break := apbi.pwdata(3);
+ when "10" =>
+ v.tcnt := apbi.pwdata(1) & apbi.pwdata(1);
+ v.rxen := apbi.pwdata(0);
+ when "11" =>
+ v.brate := apbi.pwdata(17 downto 0);
+ v.scaler := apbi.pwdata(17 downto 0);
+ when others =>
+ end case;
+ end if;
+
+-- tx clock
+
+ txclk := r.txclk + 1;
+ if r.tick = '1' then
+ v.txclk := txclk; v.txtick := r.txclk(2) and not txclk(2);
+ end if;
+
+-- rx clock
+
+ rxclk := r.rxclk + 1;
+ if r.tick = '1' then
+ v.rxclk := rxclk; v.rxtick := r.rxclk(2) and not rxclk(2);
+ end if;
+
+-- filter rx data
+
+ v.rxf(1 downto 0) := r.rxf(0) & ui.rxd; -- meta-stability filter
+ if ((r.tcnt /= "11") and (r.scaler(0 downto 0) = "1")) or
+ ((r.tcnt = "11") and (r.tick = '1'))
+ then v.rxf(4 downto 2) := r.rxf(3 downto 1); end if;
+ v.rxdb(0) := (r.rxf(4) and r.rxf(3)) or (r.rxf(4) and r.rxf(2)) or
+ (r.rxf(3) and r.rxf(2));
+ irxd := r.rxdb(0);
+
+-- transmitter operation
+
+ case r.txstate is
+ when idle => -- idle state
+ if (r.txtick = '1') then v.tsempty := '1'; end if;
+ if (r.rxen and (not r.thempty) and r.txtick) = '1' then
+ v.tshift := "10" & r.thold & '0'; v.txstate := data;
+ v.thempty := '1';
+ v.tsempty := '0'; v.txclk := "00" & r.tick; v.txtick := '0';
+ end if;
+ when data => -- transmitt data frame
+ if r.txtick = '1' then
+ v.tshift := '1' & r.tshift(10 downto 1);
+ if r.tshift(10 downto 1) = "1111111110" then
+ v.tshift(0) := '1'; v.txstate := stopbit;
+ end if;
+ end if;
+ when stopbit => -- transmitt stop bit
+ if r.txtick = '1' then
+ v.tshift := '1' & r.tshift(10 downto 1); v.txstate := idle;
+ end if;
+
+ end case;
+
+-- writing of tx data register must be done after tx fsm to get correct
+-- operation of thempty flag
+
+ if uarti.write = '1' then
+ v.thold := uarti.data(7 downto 0); v.thempty := '0';
+ end if;
+
+-- receiver operation
+
+ case r.rxstate is
+ when idle => -- wait for start bit
+ if ((not r.rsempty) and not r.dready) = '1' then
+ v.rhold := r.rshift; v.rsempty := '1'; v.dready := '1';
+ end if;
+ if (r.rxen and r.rxdb(1) and (not irxd)) = '1' then
+ v.rxstate := startbit; v.rshift := (others => '1'); v.rxclk := "100";
+ if v.rsempty = '0' then v.ovf := '1'; end if;
+ v.rsempty := '0'; v.rxtick := '0';
+ end if;
+ when startbit => -- check validity of start bit
+ if r.rxtick = '1' then
+ if irxd = '0' then
+ v.rshift := irxd & r.rshift(7 downto 1); v.rxstate := data;
+ else
+ v.rxstate := idle;
+ end if;
+ end if;
+ when data => -- receive data frame
+ if r.rxtick = '1' then
+ v.rshift := irxd & r.rshift(7 downto 1);
+ if r.rshift(0) = '0' then
+ v.rxstate := stopbit;
+ end if;
+ end if;
+ when stopbit => -- receive stop bit
+ if r.rxtick = '1' then
+ if irxd = '1' then
+ v.rsempty := '0';
+ if v.dready = '0' then
+ v.rhold := r.rshift; v.rsempty := '1'; v.dready := '1';
+ end if;
+ else
+ if r.rshift = "00000000" then
+ v.break := '1'; -- break
+ else
+ v.frame := '1'; -- framing error
+ end if;
+ v.rsempty := '1';
+ end if;
+ v.rxstate := idle;
+ end if;
+
+ end case;
+
+-- reset operation
+
+ if rst = '0' then
+ v.frame := '0'; v.rsempty := '1';
+ v.ovf := '0'; v.break := '0'; v.thempty := '1';
+ v.tsempty := '1'; v.dready := '0'; v.fedge := '0';
+ v.txstate := idle; v.rxstate := idle; v.tshift(0) := '1';
+ v.scaler := "111111111111111011"; v.brate := (others => '1');
+ v.rxen := '0'; v.tcnt := "00";
+ v.txclk := (others => '0'); v.rxclk := (others => '0');
+ end if;
+
+-- update registers
+
+ rin <= v;
+
+-- drive outputs
+ uo.txd <= r.tshift(0);
+ uo.scaler <= r.brate;
+ uo.rtsn <= '0';
+ uo.rxen <= andv(r.tcnt);
+ uarto.dready <= r.dready;
+ uarto.tsempty <= r.tsempty;
+ uarto.thempty <= r.thempty;
+ uarto.lock <= r.tcnt(1) and r.tcnt(0);
+ uarto.enable <= r.rxen;
+ uarto.data <= r.rhold;
+
+ apbo.prdata <= rdata;
+
+ end process;
+
+ apbo.pirq <= (others => '0');
+ apbo.pconfig <= pconfig;
+ apbo.pindex <= pindex;
+
+ regs : process(clk)
+ begin if rising_edge(clk) then r <= rin; end if; end process;
+
+end;
diff --git a/gaisler/rtl/libdcom.vhd b/gaisler/rtl/libdcom.vhd
new file mode 100644
index 0000000..64838ba
--- /dev/null
+++ b/gaisler/rtl/libdcom.vhd
@@ -0,0 +1,171 @@
+------------------------------------------------------------------------------
+-- This file is a part of the GRLIB VHDL IP LIBRARY
+-- Copyright (C) 2003 - 2008, Gaisler Research
+-- Copyright (C) 2008 - 2010, Aeroflex Gaisler
+--
+-- 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
+-----------------------------------------------------------------------------
+-- Package: libdcom
+-- File: libdcom.vhd
+-- Author: Jiri Gaisler - Gaisler Research
+-- Description: Types, functions and components for DSU uart
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+library grlib;
+use grlib.amba.all;
+use grlib.stdlib.all;
+library gaisler;
+use gaisler.uart.all;
+use gaisler.misc.all;
+
+package libdcom is
+
+type dcom_uart_in_type is record
+ read : std_ulogic;
+ write : std_ulogic;
+ data : std_logic_vector(7 downto 0);
+end record;
+
+type dcom_uart_out_type is record
+ dready : std_ulogic;
+ tsempty : std_ulogic;
+ thempty : std_ulogic;
+ lock : std_ulogic;
+ enable : std_ulogic;
+ data : std_logic_vector(7 downto 0);
+end record;
+
+component dcom_uart
+ generic (
+ pindex : integer := 0;
+ paddr : integer := 0;
+ pmask : integer := 16#fff#
+ );
+ port (
+ rst : in std_ulogic;
+ clk : in std_ulogic;
+ ui : in uart_in_type;
+ uo : out uart_out_type;
+ apbi : in apb_slv_in_type;
+ apbo : out apb_slv_out_type;
+ uarti : in dcom_uart_in_type;
+ uarto : out dcom_uart_out_type
+ );
+end component;
+
+component dcom
+ 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 component;
+
+
+-- pragma translate_off
+
+ procedure rxc(signal rxd : in std_logic; d: out std_logic_vector;
+ txperiod : time);
+
+ procedure rxi(signal rxd : in std_logic; d: out std_logic_vector;
+ txperiod : time; lresp : boolean);
+
+ procedure txc(signal txd : out std_logic; td : integer;
+ txperiod : time);
+
+ procedure txa(signal txd : out std_logic; td1, td2, td3, td4 : integer;
+ txperiod : time);
+
+ procedure txi(signal rxd : in std_logic; signal txd : out std_logic;
+ td1, td2, td3, td4 : integer; txperiod : time;
+ lresp : boolean);
+
+-- pragma translate_on
+
+end;
+
+-- pragma translate_off
+
+package body libdcom is
+
+ procedure rxc(signal rxd : in std_logic; d: out std_logic_vector;
+ txperiod : time) is
+ variable rxdata : std_logic_vector(7 downto 0);
+ begin
+ wait until rxd = '0'; wait for TXPERIOD/2;
+ for i in 0 to 7 loop wait for TXPERIOD; rxdata(i):= rxd; end loop;
+ wait for TXPERIOD ;
+ d := rxdata;
+ end;
+
+ procedure rxi(signal rxd : in std_logic; d: out std_logic_vector;
+ txperiod : time; lresp : boolean) is
+ variable rxdata : std_logic_vector(31 downto 0);
+ variable resp : std_logic_vector(7 downto 0);
+ begin
+ for i in 3 downto 0 loop
+ rxc(rxd, rxdata((i*8 +7) downto i*8), txperiod);
+ end loop;
+ d := rxdata;
+ if LRESP then
+ rxc(rxd, resp, txperiod);
+-- print("RESP : 0x" & tosth(resp));
+ end if;
+ end;
+
+ procedure txc(signal txd : out std_logic; td : integer;
+ txperiod : time) is
+ variable txdata : std_logic_vector(10 downto 0);
+ begin
+ txdata := "11" & conv_std_logic_vector(td, 8) & '0';
+ for i in 0 to 10 loop wait for TXPERIOD ; txd <= txdata(i); end loop;
+ end;
+
+ procedure txa(signal txd : out std_logic; td1, td2, td3, td4 : integer;
+ txperiod : time) is
+ variable txdata : std_logic_vector(43 downto 0);
+ begin
+ txdata := "11" & conv_std_logic_vector(td4, 8) & '0'
+ & "11" & conv_std_logic_vector(td3, 8) & '0'
+ & "11" & conv_std_logic_vector(td2, 8) & '0'
+ & "11" & conv_std_logic_vector(td1, 8) & '0';
+ for i in 0 to 43 loop wait for TXPERIOD ; txd <= txdata(i); end loop;
+ end;
+
+ procedure txi(signal rxd : in std_logic; signal txd : out std_logic;
+ td1, td2, td3, td4 : integer; txperiod : time;
+ lresp : boolean) is
+ variable txdata : std_logic_vector(43 downto 0);
+ begin
+ txdata := "11" & conv_std_logic_vector(td4, 8) & '0'
+ & "11" & conv_std_logic_vector(td3, 8) & '0'
+ & "11" & conv_std_logic_vector(td2, 8) & '0'
+ & "11" & conv_std_logic_vector(td1, 8) & '0';
+ for i in 0 to 43 loop wait for TXPERIOD ; txd <= txdata(i); end loop;
+ if LRESP then
+ rxc(rxd, txdata(7 downto 0), txperiod);
+-- print("RESP : 0x" & tosth(txdata(7 downto 0)));
+ end if;
+ end;
+
+end;
+
+-- pragma translate_on
OpenPOWER on IntegriCloud