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

Subversion Repositories w11

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /w11/tags/w11a_V0.7/rtl/vlib/rlink
    from Rev 30 to Rev 33
    Reverse comparison

Rev 30 → Rev 33

/rlink_sp1c.vhd
0,0 → 1,178
-- $Id: rlink_sp1c.vhd 672 2015-05-02 21:58:28Z mueller $
--
-- Copyright 2011-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: rlink_sp1c - syn
-- Description: rlink_core8 + serport_1clock combo
--
-- Dependencies: rlink_core8
-- serport/serport_1clock
-- rbus/rbd_rbmon
-- rbus/rb_sres_or_2
--
-- Test bench: -
--
-- Target Devices: generic
-- Tool versions: ise 13.1-14.7; viv 2014.4; ghdl 0.29-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri ifa ofa
-- 2015-05-02 672 14.7 131013 xc6slx16-2 495 671 56 255 s 8.8 - -
-- 2011-12-09 437 13.1 O40d xc3s1000-4 337 733 64 469 s 9.8 - -
--
-- Revision History:
-- Date Rev Version Comment
-- 2015-05-02 672 4.2 add rbd_rbmon (optional via generics)
-- 2015-04-11 666 4.1 rename ENAESC->ESCFILL, rearrange XON handling
-- 2014-08-28 588 4.0 use rlink v4 iface, 4 bit STAT
-- 2011-12-09 437 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.rblib.all;
use work.rbdlib.all;
use work.rlinklib.all;
use work.serportlib.all;
 
entity rlink_sp1c is -- rlink_core8+serport_1clock combo
generic (
BTOWIDTH : positive := 5; -- rbus timeout counter width
RTAWIDTH : positive := 12; -- retransmit buffer address width
SYSID : slv32 := (others=>'0'); -- rlink system id
IFAWIDTH : natural := 5; -- input fifo address width (0=none)
OFAWIDTH : natural := 5; -- output fifo address width (0=none)
ENAPIN_RLMON : integer := -1; -- SB_CNTL for rlmon (-1=none)
ENAPIN_RLBMON: integer := -1; -- SB_CNTL for rlbmon (-1=none)
ENAPIN_RBMON : integer := -1; -- SB_CNTL for rbmon (-1=none)
CDWIDTH : positive := 13; -- clk divider width
CDINIT : natural := 15; -- clk divider initial/reset setting
RBMON_AWIDTH : natural := 0; -- rbmon: buffer size, (0=none)
RBMON_RBADDR : slv16 := slv(to_unsigned(16#ffe8#,16))); -- rbmon: base addr
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- 1 usec clock enable
CE_MSEC : in slbit; -- 1 msec clock enable
CE_INT : in slbit := '0'; -- rri ato time unit clock enable
RESET : in slbit; -- reset
ENAXON : in slbit; -- enable xon/xoff handling
ESCFILL : in slbit; -- enable fill escaping
RXSD : in slbit; -- receive serial data (board view)
TXSD : out slbit; -- transmit serial data (board view)
CTS_N : in slbit := '0'; -- clear to send (act.low, board view)
RTS_N : out slbit; -- request to send (act.low, board view)
RB_MREQ : out rb_mreq_type; -- rbus: request
RB_SRES : in rb_sres_type; -- rbus: response
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4; -- rbus: status flags
RL_MONI : out rl_moni_type; -- rlink_core: monitor port
SER_MONI : out serport_moni_type -- serport: monitor port
);
end entity rlink_sp1c;
 
 
architecture syn of rlink_sp1c is
 
signal RLB_DI : slv8 := (others=>'0');
signal RLB_ENA : slbit := '0';
signal RLB_BUSY : slbit := '0';
signal RLB_DO : slv8 := (others=>'0');
signal RLB_VAL : slbit := '0';
signal RLB_HOLD : slbit := '0';
 
signal RB_MREQ_M : rb_mreq_type := rb_mreq_init;
signal RB_SRES_M : rb_sres_type := rb_sres_init;
signal RB_SRES_RBMON : rb_sres_type := rb_sres_init;
 
begin
CORE : rlink_core8 -- rlink master ----------------------
generic map (
BTOWIDTH => BTOWIDTH,
RTAWIDTH => RTAWIDTH,
SYSID => SYSID,
ENAPIN_RLMON => ENAPIN_RLMON,
ENAPIN_RLBMON=> ENAPIN_RLBMON,
ENAPIN_RBMON => ENAPIN_RBMON)
port map (
CLK => CLK,
CE_INT => CE_INT,
RESET => RESET,
ESCXON => ENAXON,
ESCFILL => ESCFILL,
RLB_DI => RLB_DI,
RLB_ENA => RLB_ENA,
RLB_BUSY => RLB_BUSY,
RLB_DO => RLB_DO,
RLB_VAL => RLB_VAL,
RLB_HOLD => RLB_HOLD,
RL_MONI => RL_MONI,
RB_MREQ => RB_MREQ_M,
RB_SRES => RB_SRES_M,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT
);
SERPORT : serport_1clock -- serport interface -----------------
generic map (
CDWIDTH => CDWIDTH,
CDINIT => CDINIT,
RXFAWIDTH => IFAWIDTH,
TXFAWIDTH => OFAWIDTH)
port map (
CLK => CLK,
CE_MSEC => CE_MSEC,
RESET => RESET,
ENAXON => ENAXON,
ENAESC => '0', -- escaping now in rlink_core8
RXDATA => RLB_DI,
RXVAL => RLB_ENA,
RXHOLD => RLB_BUSY,
TXDATA => RLB_DO,
TXENA => RLB_VAL,
TXBUSY => RLB_HOLD,
MONI => SER_MONI,
RXSD => RXSD,
TXSD => TXSD,
RXRTS_N => RTS_N,
TXCTS_N => CTS_N
);
RBMON : if RBMON_AWIDTH > 0 generate -- rbus monitor --------------
begin
I0 : rbd_rbmon
generic map (
RB_ADDR => RBMON_RBADDR,
AWIDTH => RBMON_AWIDTH)
port map (
CLK => CLK,
RESET => RESET,
RB_MREQ => RB_MREQ_M,
RB_SRES => RB_SRES_RBMON,
RB_SRES_SUM => RB_SRES_M
);
end generate RBMON;
 
RB_SRES_OR : rb_sres_or_2 -- rbus or ---------------------------
port map (
RB_SRES_1 => RB_SRES,
RB_SRES_2 => RB_SRES_RBMON,
RB_SRES_OR => RB_SRES_M
);
 
RB_MREQ <= RB_MREQ_M; -- setup output signals
 
end syn;
/rlinklib.vhd
0,0 → 1,301
-- $Id: rlinklib.vhd 672 2015-05-02 21:58:28Z mueller $
--
-- Copyright 2007-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Package Name: rlinklib
-- Description: Definitions for rlink interface and bus entities
--
-- Dependencies: -
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Revision History:
-- Date Rev Version Comment
--
-- 2015-04-11 666 4.1.2 rlink_core8: add ESC(XON|FILL);
-- rlink_sp1c: rename ENAESC->ESCFILL
-- 2015-02-21 649 4.1.1 add ioleds_sp1c
-- 2014-12-21 617 4.1 use stat(2) to signal rbus timeout
-- 2014-10-12 596 4.0 now rlink v4.0 iface, 4 bit STAT
-- 2014-08-15 583 3.5 rb_mreq addr now 16 bit
-- 2013-04-21 509 3.3.2 add rlb_moni record definition
-- 2012-12-29 466 3.3.1 add rlink_rlbmux
-- 2011-12-23 444 3.3 CLK_CYCLE now integer
-- 2011-12-21 442 3.2.1 retire old, deprecated interfaces
-- 2011-12-09 437 3.2 add rlink_core8
-- 2011-11-18 427 3.1.3 now numeric_std clean
-- 2010-12-25 348 3.1.2 drop RL_FLUSH support, add RL_MONI for rlink_core;
-- new rlink_serport interface;
-- rename rlink_core_serport->rlink_base_serport
-- 2010-12-24 347 3.1.1 rename: CP_*->RL->*
-- 2010-12-22 346 3.1 rename: [cd]crc->[cd]err, ioto->rbnak, ioerr->rberr
-- 2010-12-04 343 3.0 move rbus components to rbus/rblib; renames
-- rri_ -> rlink and c_rri -> c_rlink;
-- 2010-06-18 306 2.5.1 rename rbus data fields to _rbf_
-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining
-- 2010-06-03 300 2.1.5 use FAWIDTH=5 for rri_serport
-- 2010-05-02 287 2.1.4 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM
-- drop RP_IINT from interfaces; drop RTSFLUSH generic
-- 2010-05-01 285 2.1.3 remove rri_rb_rpcompat, now obsolete
-- 2010-04-18 279 2.1.2 rri_core_serport: drop RTSFBUF generic
-- 2010-04-10 275 2.1.1 add rri_core_serport
-- 2010-04-03 274 2.1 add CP_FLUSH for rri_core, rri_serport;
-- CE_USEC, RTSFLUSH, CTS_N, RTS_N for rri_serport
-- 2008-08-24 162 2.0 all with new rb_mreq/rb_sres interface
-- 2008-08-22 161 1.3 renamed rri_rbres_ -> rb_sres_; drop rri_[24]rp
-- 2008-02-16 116 1.2.1 added rri_wreg(rw|w|r)_3
-- 2008-01-20 113 1.2 added rb_[mreq|sres]; _rbres_or_*; _rb_rpcompat
-- 2007-11-24 98 1.1 added RP_IINT for rri_core.
-- 2007-09-09 81 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.rblib.all;
use work.serportlib.all;
 
package rlinklib is
 
constant c_rlink_dat_sop : slv9 := "100000000";
constant c_rlink_dat_eop : slv9 := "100000001";
constant c_rlink_dat_nak : slv9 := "100000010";
constant c_rlink_dat_attn : slv9 := "100000011";
 
constant c_rlink_cmd_rreg : slv3 := "000";
constant c_rlink_cmd_rblk : slv3 := "001";
constant c_rlink_cmd_wreg : slv3 := "010";
constant c_rlink_cmd_wblk : slv3 := "011";
constant c_rlink_cmd_labo : slv3 := "100";
constant c_rlink_cmd_attn : slv3 := "101";
constant c_rlink_cmd_init : slv3 := "110";
 
subtype c_rlink_cmd_rbf_seq is integer range 7 downto 3; -- sequence number
subtype c_rlink_cmd_rbf_code is integer range 2 downto 0; -- command code
 
subtype c_rlink_stat_rbf_stat is integer range 7 downto 4; -- ext status bits
constant c_rlink_stat_rbf_attn: integer := 3; -- attention flags set
constant c_rlink_stat_rbf_rbtout: integer := 2; -- rbus timeout
constant c_rlink_stat_rbf_rbnak: integer := 1; -- rbus no ack
constant c_rlink_stat_rbf_rberr: integer := 0; -- rbus err bit set
 
constant c_rlink_nakcode_ccrc : slv3 := "000"; -- cmd crc error
constant c_rlink_nakcode_dcrc : slv3 := "001"; -- data crc error
constant c_rlink_nakcode_frame : slv3 := "010"; -- framing error
constant c_rlink_nakcode_unused : slv3 := "011"; -- <unused code>
constant c_rlink_nakcode_cmd : slv3 := "100"; -- bad cmd
constant c_rlink_nakcode_cnt : slv3 := "101"; -- bad cnt
constant c_rlink_nakcode_rtovfl : slv3 := "110"; -- rtbuf ovfl
constant c_rlink_nakcode_rtwblk : slv3 := "111"; -- rtbuf ovfl in wblk
 
type rl_moni_type is record -- rlink_core monitor port
eop : slbit; -- eop send in last cycle
attn : slbit; -- attn send in last cycle
lamp : slbit; -- attn (lam) pending
end record rl_moni_type;
 
constant rl_moni_init : rl_moni_type :=
('0','0','0'); -- eop,attn,lamp
 
type rlb_moni_type is record -- rlink 8b monitor port
rxval : slbit; -- data in valid
rxhold : slbit; -- data in hold
txena : slbit; -- data out enable
txbusy : slbit; -- data out busy
end record rlb_moni_type;
 
constant rlb_moni_init : rlb_moni_type :=
('0','0','0','0'); -- rxval,rxhold,txena,txbusy
 
-- these definitions logically belongs into the 'for test benches' section'
-- it is here for convenience to simplify instantiations.
constant sbcntl_sbf_rlmon : integer := 15;
constant sbcntl_sbf_rlbmon : integer := 14;
 
component rlink_core is -- rlink core with 9bit iface
generic (
BTOWIDTH : positive := 5; -- rbus timeout counter width
RTAWIDTH : positive := 12; -- retransmit buffer address width
SYSID : slv32 := (others=>'0'); -- rlink system id
ENAPIN_RLMON : integer := -1; -- SB_CNTL for rlmon (-1=none)
ENAPIN_RBMON : integer := -1); -- SB_CNTL for rbmon (-1=none)
port (
CLK : in slbit; -- clock
CE_INT : in slbit := '0'; -- rlink ato time unit clock enable
RESET : in slbit; -- reset
RL_DI : in slv9; -- rlink 9b: data in
RL_ENA : in slbit; -- rlink 9b: data enable
RL_BUSY : out slbit; -- rlink 9b: data busy
RL_DO : out slv9; -- rlink 9b: data out
RL_VAL : out slbit; -- rlink 9b: data valid
RL_HOLD : in slbit; -- rlink 9b: data hold
RL_MONI : out rl_moni_type; -- rlink: monitor port
RB_MREQ : out rb_mreq_type; -- rbus: request
RB_SRES : in rb_sres_type; -- rbus: response
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4 -- rbus: status flags
);
end component;
 
component rlink_aif is -- rlink, abstract interface
port (
CLK : in slbit; -- clock
CE_INT : in slbit := '0'; -- rlink ato time unit clock enable
RESET : in slbit :='0'; -- reset
RL_DI : in slv9; -- rlink 9b: data in
RL_ENA : in slbit; -- rlink 9b: data enable
RL_BUSY : out slbit; -- rlink 9b: data busy
RL_DO : out slv9; -- rlink 9b: data out
RL_VAL : out slbit; -- rlink 9b: data valid
RL_HOLD : in slbit := '0' -- rlink 9b: data hold
);
end component;
 
component rlink_core8 is -- rlink core with 8bit iface
generic (
BTOWIDTH : positive := 5; -- rbus timeout counter width
RTAWIDTH : positive := 12; -- retransmit buffer address width
SYSID : slv32 := (others=>'0'); -- rlink system id
ENAPIN_RLMON : integer := -1; -- SB_CNTL for rlmon (-1=none)
ENAPIN_RLBMON: integer := -1; -- SB_CNTL for rlbmon (-1=none)
ENAPIN_RBMON : integer := -1); -- SB_CNTL for rbmon (-1=none)
port (
CLK : in slbit; -- clock
CE_INT : in slbit := '0'; -- rlink ato time unit clock enable
RESET : in slbit; -- reset
ESCXON : in slbit := '0'; -- enable xon/xoff escaping
ESCFILL : in slbit := '0'; -- enable fill escaping
RLB_DI : in slv8; -- rlink 8b: data in
RLB_ENA : in slbit; -- rlink 8b: data enable
RLB_BUSY : out slbit; -- rlink 8b: data busy
RLB_DO : out slv8; -- rlink 8b: data out
RLB_VAL : out slbit; -- rlink 8b: data valid
RLB_HOLD : in slbit; -- rlink 8b: data hold
RL_MONI : out rl_moni_type; -- rlink: monitor port
RB_MREQ : out rb_mreq_type; -- rbus: request
RB_SRES : in rb_sres_type; -- rbus: response
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4 -- rbus: status flags
);
end component;
 
component rlink_rlbmux is -- rlink rlb multiplexer
port (
SEL : in slbit; -- port select (0:RLB<->P0; 1:RLB<->P1)
RLB_DI : out slv8; -- rlb: data in
RLB_ENA : out slbit; -- rlb: data enable
RLB_BUSY : in slbit; -- rlb: data busy
RLB_DO : in slv8; -- rlb: data out
RLB_VAL : in slbit; -- rlb: data valid
RLB_HOLD : out slbit; -- rlb: data hold
P0_RXDATA : in slv8; -- p0: rx data
P0_RXVAL : in slbit; -- p0: rx valid
P0_RXHOLD : out slbit; -- p0: rx hold
P0_TXDATA : out slv8; -- p0: tx data
P0_TXENA : out slbit; -- p0: tx enable
P0_TXBUSY : in slbit; -- p0: tx busy
P1_RXDATA : in slv8; -- p1: rx data
P1_RXVAL : in slbit; -- p1: rx valid
P1_RXHOLD : out slbit; -- p1: rx hold
P1_TXDATA : out slv8; -- p1: tx data
P1_TXENA : out slbit; -- p1: tx enable
P1_TXBUSY : in slbit -- p1: tx busy
);
end component;
 
--
-- core + concrete_interface combo's
--
 
component rlink_sp1c is -- rlink_core8+serport_1clock combo
generic (
BTOWIDTH : positive := 5; -- rbus timeout counter width
RTAWIDTH : positive := 12; -- retransmit buffer address width
SYSID : slv32 := (others=>'0'); -- rlink system id
IFAWIDTH : natural := 5; -- input fifo address width (0=none)
OFAWIDTH : natural := 5; -- output fifo address width (0=none)
ENAPIN_RLMON : integer := -1; -- SB_CNTL for rlmon (-1=none)
ENAPIN_RLBMON: integer := -1; -- SB_CNTL for rlbmon (-1=none)
ENAPIN_RBMON : integer := -1; -- SB_CNTL for rbmon (-1=none)
CDWIDTH : positive := 13; -- clk divider width
CDINIT : natural := 15; -- clk divider initial/reset setting
RBMON_AWIDTH : natural := 0; -- rbmon: buffer size, (0=none)
RBMON_RBADDR : slv16 := slv(to_unsigned(16#ffe8#,16))); -- rbmon: base addr
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- 1 usec clock enable
CE_MSEC : in slbit; -- 1 msec clock enable
CE_INT : in slbit := '0'; -- rri ato time unit clock enable
RESET : in slbit; -- reset
ENAXON : in slbit := '0'; -- enable xon/xoff handling
ESCFILL : in slbit := '0'; -- enable fill escaping
RXSD : in slbit; -- receive serial data (board view)
TXSD : out slbit; -- transmit serial data (board view)
CTS_N : in slbit := '0'; -- clear to send (act.low, board view)
RTS_N : out slbit; -- request to send (act.low, board view)
RB_MREQ : out rb_mreq_type; -- rbus: request
RB_SRES : in rb_sres_type; -- rbus: response
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4; -- rbus: status flags
RL_MONI : out rl_moni_type; -- rlink_core: monitor port
SER_MONI : out serport_moni_type -- serport: monitor port
);
end component;
 
--
-- io activity leds
--
component ioleds_sp1c -- io activity leds for rlink_sp1c
port (
SER_MONI : in serport_moni_type; -- ser: monitor port
IOLEDS : out slv4 -- 4 bit IO monitor (e.g. for DSP_DP)
);
end component;
 
--
-- components for use in test benches (not synthesizable)
--
 
component rlink_mon is -- rlink monitor
generic (
DWIDTH : positive := 9); -- data port width (8 or 9)
port (
CLK : in slbit; -- clock
CLK_CYCLE : in integer := 0; -- clock cycle number
ENA : in slbit := '1'; -- enable monitor output
RL_DI : in slv(DWIDTH-1 downto 0); -- rlink: data in
RL_ENA : in slbit; -- rlink: data enable
RL_BUSY : in slbit; -- rlink: data busy
RL_DO : in slv(DWIDTH-1 downto 0); -- rlink: data out
RL_VAL : in slbit; -- rlink: data valid
RL_HOLD : in slbit -- rlink: data hold
);
end component;
 
component rlink_mon_sb is -- simbus wrap for rlink monitor
generic (
DWIDTH : positive := 9; -- data port width (8 or 9)
ENAPIN : integer := sbcntl_sbf_rlmon); -- SB_CNTL signal to use for enable
port (
CLK : in slbit; -- clock
RL_DI : in slv(DWIDTH-1 downto 0); -- rlink: data in
RL_ENA : in slbit; -- rlink: data enable
RL_BUSY : in slbit; -- rlink: data busy
RL_DO : in slv(DWIDTH-1 downto 0); -- rlink: data out
RL_VAL : in slbit; -- rlink: data valid
RL_HOLD : in slbit -- rlink: data hold
);
end component;
 
end package rlinklib;
/rlink_core8.vhd
0,0 → 1,169
-- $Id: rlink_core8.vhd 666 2015-04-12 21:17:54Z mueller $
--
-- Copyright 2011-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: rlink_core8 - syn
-- Description: rlink core with 8bit interface (core+b2c/c2b+rlmon+rbmon)
--
-- Dependencies: rlink_core
-- comlib/byte2cdata
-- comlib/cdata2byte
-- rlink_mon_sb [sim only, for 8bit level]
--
-- Test bench: -
--
-- Target Devices: generic
-- Tool versions: ise 13.1-14.7; viv 2014.4; ghdl 0.29-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2014-12-05 596 14.7 131013 xc6slx16-2 352 492 24 176 s 7.0 ver 4.0
-- 2011-12-09 437 13.1 O40d xc3s1000-4 184 403 0 244 s 9.1
--
-- Revision History:
-- Date Rev Version Comment
-- 2015-04-11 666 4.1 add ESCXON,ESCFILL in signals, for cdata2byte
-- 2014-10-12 596 4.0 now rlink v4 iface, 4 bit STAT
-- 2011-12-09 437 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.comlib.all;
use work.rblib.all;
use work.rlinklib.all;
 
entity rlink_core8 is -- rlink core with 8bit interface
generic (
BTOWIDTH : positive := 5; -- rbus timeout counter width
RTAWIDTH : positive := 12; -- retransmit buffer address width
SYSID : slv32 := (others=>'0'); -- rlink system id
ENAPIN_RLMON : integer := -1; -- SB_CNTL for rlmon (-1=none)
ENAPIN_RLBMON: integer := -1; -- SB_CNTL for rlbmon (-1=none)
ENAPIN_RBMON : integer := -1); -- SB_CNTL for rbmon (-1=none)
port (
CLK : in slbit; -- clock
CE_INT : in slbit := '0'; -- rlink ato time unit clock enable
RESET : in slbit; -- reset
ESCXON : in slbit; -- enable xon/xoff escaping
ESCFILL : in slbit; -- enable fill escaping
RLB_DI : in slv8; -- rlink 8b: data in
RLB_ENA : in slbit; -- rlink 8b: data enable
RLB_BUSY : out slbit; -- rlink 8b: data busy
RLB_DO : out slv8; -- rlink 8b: data out
RLB_VAL : out slbit; -- rlink 8b: data valid
RLB_HOLD : in slbit; -- rlink 8b: data hold
RL_MONI : out rl_moni_type; -- rlink: monitor port
RB_MREQ : out rb_mreq_type; -- rbus: request
RB_SRES : in rb_sres_type; -- rbus: response
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4 -- rbus: status flags
);
end entity rlink_core8;
 
 
architecture syn of rlink_core8 is
 
signal RL_DI : slv9 := (others=>'0');
signal RL_ENA : slbit := '0';
signal RL_BUSY : slbit := '0';
signal RL_DO : slv9 := (others=>'0');
signal RL_VAL : slbit := '0';
signal RL_HOLD : slbit := '0';
signal RLB_BUSY_L : slbit := '0';
signal RLB_DO_L : slv8 := (others=>'0');
signal RLB_VAL_L : slbit := '0';
 
begin
 
RL : rlink_core
generic map (
BTOWIDTH => BTOWIDTH,
RTAWIDTH => RTAWIDTH,
SYSID => SYSID,
ENAPIN_RLMON => ENAPIN_RLMON,
ENAPIN_RBMON => ENAPIN_RBMON)
port map (
CLK => CLK,
CE_INT => CE_INT,
RESET => RESET,
RL_DI => RL_DI,
RL_ENA => RL_ENA,
RL_BUSY => RL_BUSY,
RL_DO => RL_DO,
RL_VAL => RL_VAL,
RL_HOLD => RL_HOLD,
RL_MONI => RL_MONI,
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT
);
 
-- RLB -> RL converter (DI handling) -------------
B2CD : byte2cdata -- byte stream -> 9bit comma,data
port map (
CLK => CLK,
RESET => RESET,
DI => RLB_DI,
ENA => RLB_ENA,
ERR => '0',
BUSY => RLB_BUSY_L,
DO => RL_DI,
VAL => RL_ENA,
HOLD => RL_BUSY
);
 
-- RL -> RLB converter (DO handling) -------------
CD2B : cdata2byte -- 9bit comma,data -> byte stream
port map (
CLK => CLK,
RESET => RESET,
ESCXON => ESCXON,
ESCFILL => ESCFILL,
DI => RL_DO,
ENA => RL_VAL,
BUSY => RL_HOLD,
DO => RLB_DO_L,
VAL => RLB_VAL_L,
HOLD => RLB_HOLD
);
 
RLB_BUSY <= RLB_BUSY_L;
RLB_DO <= RLB_DO_L;
RLB_VAL <= RLB_VAL_L;
-- synthesis translate_off
 
RLBMON: if ENAPIN_RLBMON >= 0 generate
MON : rlink_mon_sb
generic map (
DWIDTH => RLB_DI'length,
ENAPIN => ENAPIN_RLBMON)
port map (
CLK => CLK,
RL_DI => RLB_DI,
RL_ENA => RLB_ENA,
RL_BUSY => RLB_BUSY_L,
RL_DO => RLB_DO_L,
RL_VAL => RLB_VAL_L,
RL_HOLD => RLB_HOLD
);
end generate RLBMON;
 
-- synthesis translate_on
 
end syn;
/tb/tbu_rlink_sp1c.vhd
0,0 → 1,155
-- $Id: tbu_rlink_sp1c.vhd 666 2015-04-12 21:17:54Z mueller $
--
-- Copyright 2007-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: tbu_rlink_sp1c - syn
-- Description: Wrapper for rlink_sp1c to avoid records.
-- It has a port interface which will not be modified by xst
-- synthesis (no records, no generic port).
--
-- Dependencies: rlink_sp1c
--
-- To test: rlink_sp1c
--
-- Target Devices: generic
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2011-12-22 442 13.1 O40d xc3s1000-4 348 704 64 473 s 9.08
-- 2010-04-03 274 11.4 L68 xc3s1000-4 278 588 18 366 s 9.83
-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 273 547 18 - t 9.65
-- 2007-10-27 92 9.1 J30 xc3s1000-4 273 545 18 - t 9.65
-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 283 594 18 323 s 10.3
-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 285 596 18 - s 9.32
--
-- Tool versions: xst 8.2-14.7; ghdl 0.18-0.31
--
-- Revision History:
-- Date Rev Version Comment
-- 2015-04-11 666 4.1 rename ENAESC->ESCFILL
-- 2014-08-31 590 4.0 now full rlink v4 iface, 4 bit STAT
-- 2014-08-15 583 3.5 rb_mreq addr now 16 bit
-- 2011-12-22 442 3.2 renamed and retargeted to test rlink_sp1c
-- 2011-11-19 427 3.1.2 now numeric_std clean
-- 2010-12-28 350 3.1.1 use CLKDIV/CDINIT=0;
-- 2010-12-26 348 3.1 use rlink_base now; add RTS/CTS ports
-- 2010-12-24 347 3.0.1 rename: CP_*->RL->*
-- 2010-12-05 343 3.0 rri->rlink renames; port to rbus V3 protocol;
-- 2010-06-03 300 2.2.3 use default FAWIDTH for rri_core_serport
-- 2010-05-02 287 2.2.2 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM
-- drop RP_IINT from interfaces; drop RTSFLUSH generic
-- 2010-04-18 279 2.2.1 drop RTSFBUF generic for rri_serport
-- 2010-04-03 274 2.2 add CP_FLUSH, add rri_serport handshake logic
-- 2009-03-14 197 2.1 remove records in interface to allow _ssim usage
-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface
-- 2007-11-24 98 1.1 added RP_IINT support
-- 2007-07-02 63 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.rblib.all;
use work.rlinklib.all;
 
entity tbu_rlink_sp1c is -- rlink core+serport combo
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rlink ito time unit clock enable
CE_USEC : in slbit; -- 1 usec clock enable
CE_MSEC : in slbit; -- 1 msec clock enable
RESET : in slbit; -- reset
RXSD : in slbit; -- receive serial data (board view)
TXSD : out slbit; -- transmit serial data (board view)
CTS_N : in slbit; -- clear to send (act.low, board view)
RTS_N : out slbit; -- request to send (act.low, board view)
RB_MREQ_aval : out slbit; -- rbus: request - aval
RB_MREQ_re : out slbit; -- rbus: request - re
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt: out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv16; -- rbus: request - addr
RB_MREQ_din : out slv16; -- rbus: request - din
RB_SRES_ack : in slbit; -- rbus: response - ack
RB_SRES_busy : in slbit; -- rbus: response - busy
RB_SRES_err : in slbit; -- rbus: response - err
RB_SRES_dout : in slv16; -- rbus: response - dout
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4 -- rbus: status flags
);
end entity tbu_rlink_sp1c;
 
 
architecture syn of tbu_rlink_sp1c is
 
constant CDWIDTH : positive := 13;
constant c_cdinit : natural := 0; -- NOTE: change in tbd_rlink_sp1c !!
 
signal RB_MREQ : rb_mreq_type := rb_mreq_init;
signal RB_SRES : rb_sres_type := rb_sres_init;
 
signal RLB_DI : slv8 := (others=>'0');
signal RLB_ENA : slbit := '0';
signal RLB_BUSY : slbit := '0';
signal RLB_DO : slv8 := (others=>'0');
signal RLB_VAL : slbit := '0';
signal RLB_HOLD : slbit := '0';
begin
 
RB_MREQ_aval <= RB_MREQ.aval;
RB_MREQ_re <= RB_MREQ.re;
RB_MREQ_we <= RB_MREQ.we;
RB_MREQ_initt<= RB_MREQ.init;
RB_MREQ_addr <= RB_MREQ.addr;
RB_MREQ_din <= RB_MREQ.din;
 
RB_SRES.ack <= RB_SRES_ack;
RB_SRES.busy <= RB_SRES_busy;
RB_SRES.err <= RB_SRES_err;
RB_SRES.dout <= RB_SRES_dout;
 
RLINK : rlink_sp1c
generic map (
BTOWIDTH => 5,
RTAWIDTH => 11,
SYSID => x"76543210",
IFAWIDTH => 5,
OFAWIDTH => 5,
ENAPIN_RLMON => sbcntl_sbf_rlmon,
ENAPIN_RLBMON=> sbcntl_sbf_rlbmon,
ENAPIN_RBMON => sbcntl_sbf_rbmon,
CDWIDTH => 15,
CDINIT => c_cdinit)
port map (
CLK => CLK,
CE_USEC => CE_USEC,
CE_MSEC => CE_MSEC,
CE_INT => CE_INT,
RESET => RESET,
ENAXON => '0',
ESCFILL => '0',
RXSD => RXSD,
TXSD => TXSD,
CTS_N => CTS_N,
RTS_N => RTS_N,
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT,
RL_MONI => open
-- SER_MONI => open -- ISE 13.1 err's when a second record is mapped open
);
 
end syn;
/tb/tbcore_rlink.vhd
0,0 → 1,271
-- $Id: tbcore_rlink.vhd 649 2015-02-21 21:10:16Z mueller $
--
-- Copyright 2010-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: tbcore_rlink - sim
-- Description: Core for a rlink_cext based test bench
--
-- Dependencies: simlib/simclkcnt
--
-- To test: generic, any rlink_cext based target
--
-- Target Devices: generic
-- Tool versions: xst 11.4-14.7; ghdl 0.26-0.31
-- Revision History:
-- Date Rev Version Comment
-- 2013-01-04 469 3.1.2 use 1ns wait for .sinit to allow simbus debugging
-- 2011-12-25 445 3.1.1 add SB_ init drivers to avoid SB_VAL='U' at start
-- 2011-12-23 444 3.1 redo clock handling, remove simclk, CLK now input
-- 2011-11-19 427 3.0.1 now numeric_std clean
-- 2010-12-29 351 3.0 rename rritb_core->tbcore_rlink; use rbv3 naming
-- 2010-06-05 301 1.1.2 rename .rpmon -> .rbmon
-- 2010-05-02 287 1.1.1 rename config command .sdata -> .sinit;
-- use sbcntl_sbf_(cp|rp)mon defs, use rritblib;
-- 2010-04-25 283 1.1 new clk handling in proc_stim, wait period-setup
-- 2010-04-24 282 1.0 Initial version (from vlib/s3board/tb/tb_s3board)
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.simlib.all;
use work.simbus.all;
use work.rblib.all;
use work.rlinklib.all;
use work.rlinktblib.all;
use work.rlink_cext_vhpi.all;
 
entity tbcore_rlink is -- core of rlink_cext based test bench
port (
CLK : in slbit; -- control interface clock
CLK_STOP : out slbit; -- clock stop trigger
RX_DATA : out slv8; -- read data (data ext->tb)
RX_VAL : out slbit; -- read data valid (data ext->tb)
RX_HOLD : in slbit; -- read data hold (data ext->tb)
TX_DATA : in slv8; -- write data (data tb->ext)
TX_ENA : in slbit -- write data enable (data tb->ext)
);
end tbcore_rlink;
 
architecture sim of tbcore_rlink is
signal CLK_CYCLE : integer := 0;
 
begin
CLKCNT : simclkcnt port map (CLK => CLK, CLK_CYCLE => CLK_CYCLE);
 
proc_conf: process
file fconf : text open read_mode is "rlink_cext_conf";
variable iline : line;
variable oline : line;
variable ok : boolean;
variable dname : string(1 to 6) := (others=>' ');
variable ien : slbit := '0';
variable ibit : integer := 0;
variable iaddr : slv8 := (others=>'0');
variable idata : slv16 := (others=>'0');
begin
SB_CNTL <= (others=>'L');
SB_VAL <= 'L';
SB_ADDR <= (others=>'L');
SB_DATA <= (others=>'L');
file_loop: while not endfile(fconf) loop
readline (fconf, iline);
readcomment(iline, ok);
next file_loop when ok;
readword(iline, dname, ok);
if ok then
case dname is
 
when ".scntl" => -- .scntl
read_ea(iline, ibit);
read_ea(iline, ien);
assert (ibit>=SB_CNTL'low and ibit<=SB_CNTL'high)
report "assert bit number in range of SB_CNTL"
severity failure;
if ien = '1' then
SB_CNTL(ibit) <= 'H';
else
SB_CNTL(ibit) <= 'L';
end if;
 
when ".rlmon" => -- .rlmon
read_ea(iline, ien);
if ien = '1' then
SB_CNTL(sbcntl_sbf_rlmon) <= 'H';
else
SB_CNTL(sbcntl_sbf_rlmon) <= 'L';
end if;
 
when ".rbmon" => -- .rbmon
read_ea(iline, ien);
if ien = '1' then
SB_CNTL(sbcntl_sbf_rbmon) <= 'H';
else
SB_CNTL(sbcntl_sbf_rbmon) <= 'L';
end if;
 
when ".sinit" => -- .sinit
readgen_ea(iline, iaddr, 8);
readgen_ea(iline, idata, 8);
SB_ADDR <= iaddr;
SB_DATA <= idata;
SB_VAL <= 'H';
wait for 1 ns;
SB_VAL <= 'L';
SB_ADDR <= (others=>'L');
SB_DATA <= (others=>'L');
wait for 1 ns;
 
when others => -- bad command
write(oline, string'("?? unknown command: "));
write(oline, dname);
writeline(output, oline);
report "aborting" severity failure;
end case;
else
report "failed to find command" severity failure;
end if;
 
testempty_ea(iline);
end loop; -- file_loop:
 
SB_VAL <= 'L';
SB_ADDR <= (others=>'L');
SB_DATA <= (others=>'L');
 
wait; -- halt process here
end process proc_conf;
proc_stim: process
variable irxint : integer := 0;
variable irxslv : slv24 := (others=>'0');
variable ibit : integer := 0;
variable oline : line;
variable r_sb_cntl : slv16 := (others=>'Z');
variable iaddr : slv8 := (others=>'0');
variable idata : slv16 := (others=>'0');
begin
 
-- setup init values for all output ports
CLK_STOP <= '0';
RX_DATA <= (others=>'0');
RX_VAL <= '0';
 
SB_VAL <= 'Z';
SB_ADDR <= (others=>'Z');
SB_DATA <= (others=>'Z');
 
-- wait for 10 clock cycles (design run up)
for i in 0 to 9 loop
wait until rising_edge(CLK);
end loop; -- i
stim_loop: loop
 
wait until falling_edge(CLK);
 
SB_ADDR <= (others=>'Z');
SB_DATA <= (others=>'Z');
 
RX_VAL <= '0';
 
if RX_HOLD = '0' then
irxint := rlink_cext_getbyte(CLK_CYCLE);
if irxint >= 0 then
if irxint <= 16#ff# then -- normal data byte
RX_DATA <= slv(to_unsigned(irxint, 8));
RX_VAL <= '1';
elsif irxint >= 16#1000000# then -- out-of-band message
irxslv := slv(to_unsigned(irxint mod 16#1000000#, 24));
iaddr := irxslv(23 downto 16);
idata := irxslv(15 downto 0);
writetimestamp(oline, CLK_CYCLE, ": OOB-MSG");
write(oline, irxslv(23 downto 16), right, 9);
write(oline, irxslv(15 downto 8), right, 9);
write(oline, irxslv( 7 downto 0), right, 9);
write(oline, string'(" : "));
writeoct(oline, iaddr, right, 3);
writeoct(oline, idata, right, 7);
writeline(output, oline);
if unsigned(iaddr) = 0 then
ibit := to_integer(unsigned(idata(15 downto 8)));
r_sb_cntl(ibit) := idata(0);
else
SB_ADDR <= iaddr;
SB_DATA <= idata;
SB_VAL <= '1';
wait for 0 ns;
SB_VAL <= 'Z';
wait for 0 ns;
end if;
end if;
elsif irxint = -1 then -- end-of-file seen
exit stim_loop;
else
report "rlink_cext_getbyte error: " & integer'image(-irxint)
severity failure;
end if;
end if;
SB_CNTL <= r_sb_cntl;
end loop;
-- wait for 50 clock cycles (design run down)
for i in 0 to 49 loop
wait until rising_edge(CLK);
end loop; -- i
CLK_STOP <= '1';
writetimestamp(oline, CLK_CYCLE, ": DONE ");
writeline(output, oline);
 
wait; -- suspend proc_stim forever
-- clock is stopped, sim will end
 
end process proc_stim;
 
proc_moni: process
variable itxdata : integer := 0;
variable itxrc : integer := 0;
variable oline : line;
begin
loop
wait until rising_edge(CLK);
if TX_ENA = '1' then
itxdata := to_integer(unsigned(TX_DATA));
itxrc := rlink_cext_putbyte(itxdata);
assert itxrc=0
report "rlink_cext_putbyte error: " & integer'image(itxrc)
severity failure;
end if;
 
end loop;
end process proc_moni;
 
end sim;
/tb/rlink_cext_vhpi.vhd
0,0 → 1,58
-- $Id: rlink_cext_vhpi.vhd 649 2015-02-21 21:10:16Z mueller $
--
-- Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Package Name: rlink_cext_vhpi
-- Description: VHDL procedural interface: VHDL declaration side
--
-- Dependencies: -
-- Tool versions: xst 8.1-14.7; ghdl 0.18-0.31
-- Revision History:
-- Date Rev Version Comment
-- 2010-12-29 351 1.1 rename vhpi_rriext->rlink_cext_vhpi; new rbv3 names
-- 2007-08-26 76 1.0 Initial version
------------------------------------------------------------------------------
 
package rlink_cext_vhpi is
 
impure function rlink_cext_getbyte (
clk : integer) -- clock cycle
return integer;
attribute foreign of rlink_cext_getbyte :
function is "VHPIDIRECT rlink_cext_getbyte";
impure function rlink_cext_putbyte (
dat : integer) -- data byte
return integer;
attribute foreign of rlink_cext_putbyte :
function is "VHPIDIRECT rlink_cext_putbyte";
 
end package rlink_cext_vhpi;
 
package body rlink_cext_vhpi is
 
impure function rlink_cext_getbyte (
clk : integer) -- clock cycle
return integer is
begin
report "rlink_cext_getbyte not vhpi'ed" severity failure;
end rlink_cext_getbyte;
 
impure function rlink_cext_putbyte (
dat : integer) -- data byte
return integer is
begin
report "rlink_cext_getbyte not vhpi'ed" severity failure;
end rlink_cext_putbyte;
 
end package body rlink_cext_vhpi;
/tb/Makefile
0,0 → 1,45
# $Id: Makefile 639 2015-01-30 18:12:19Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2014-07-27 545 1.4.1 make reference board configurable via XTW_BOARD
# 2011-08-13 405 1.4 use includes from rtl/make
# 2010-12-05 343 1.3 rri->rlink renames
# 2009-11-21 252 1.2 add ISim support
# 2007-11-03 95 1.1.2 use .log rather .dat output in check_dsim
# 2007-09-16 83 1.1.1 add include *.o.dep_ghdl
# 2007-06-29 61 1.1 add clean and all
# 2007-06-10 51 1.0 Initial version
#
EXE_all = tb_rlink_direct
EXE_all += tb_rlink_sp1c
#
# reference board for test synthesis is Spartan-6 based Nexys3
ifndef XTW_BOARD
XTW_BOARD=nexys3
endif
include $(RETROBASE)/rtl/make_ise/xflow_default_$(XTW_BOARD).mk
#
.PHONY : all all_ssim all_tsim clean
#
all : $(EXE_all)
all_ssim : $(EXE_all:=_ssim)
all_tsim : $(EXE_all:=_tsim)
#
clean : ise_clean ghdl_clean isim_clean
#
#-----
#
include $(RETROBASE)/rtl/make_ise/generic_ghdl.mk
include $(RETROBASE)/rtl/make_ise/generic_isim.mk
include $(RETROBASE)/rtl/make_ise/generic_xflow.mk
#
VBOM_all = $(wildcard *.vbom)
#
ifndef DONTINCDEP
include $(VBOM_all:.vbom=.dep_xst)
include $(VBOM_all:.vbom=.dep_ghdl)
include $(VBOM_all:.vbom=.dep_isim)
include $(wildcard *.o.dep_ghdl)
endif
#
/tb/tb_rlink_stim.dat
0,0 → 1,647
# $Id: tb_rlink_stim.dat 617 2014-12-21 14:18:53Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2014-12-21 617 4.0.1 rlink signals now tout and nak on separate stat bits
# 2014-10-12 596 4.0 rewritten for rlink v4
# ... all history v1->v3 droped
# 2007-06-17 58 1.0 Initial version
#
#---------------------------------------
# rbus address mapping
# ffe0 rbd_tester cntl
# ffe1 rbd_tester stat
# ffe2 rbd_tester attn
# ffe3 rbd_tester ncyc
# ffe4 rbd_tester data
# ffe5 rbd_tester dinc
# ffe6 rbd_tester fifo
# ffe7 rbd_tester lnak
#
.rlmon 0
.rlbmo 0
.rbmon 1
#
C =============================================================================
C Section A1: Basic framing
C -----------------------------------------------------------------------------
C Test A1.1: empty frame
C tx: sop - eop
C rx: sop - eop
rxsop
rxeop
#
txsop
txeop
#
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A1.2: discard extra eop's
C tx: eop - eop - sop - eop
C rx: sop - eop
rxsop
rxeop
#
txeop
txeop
txsop
txeop
#
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A1.3: discard extra data
C tx: <4 byte data> - sop - eop
C rx: sop - eop
rxsop
rxeop
#
tx8 00000000
tx8 00000001
tx8 00000010
tx8 00000011
txsop
txeop
#
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A1.4: frame error nak abort: sop in active frame
C tx: sop - sop - eop
C rx: sop - nak nakcode(010) - eop
rxsop
rxnak
rx8 10101010 -- 10 101 010
rxeop
#
txsop
txsop
txeop
#
.iowt 10
#
C =============================================================================
C Section A2: Basic commands: attn, wreg, rreg
C -----------------------------------------------------------------------------
C Test A2.1: test attn (simplest cmd, no rbus access)
C .attn 1000000000000000
C attn: tx: sop - cmd(attn,1) ccrc
C attn: tx: - cmd(attn,2) ccrc - eop
C rx: sop - cmd(attn,1) dl dh stat crc
C rx: - cmd(attn,2) dl dh stat crc - eop
#
.attn 1000000000000000
rxsop
rxcds attn,1 1000000000000000 00000000
rxcds attn,2 0000000000000000 00000000
rxeop
txsop
txc attn,1
txc attn,2
txeop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A2.2: wreg(data) -> shows that rlink can write a register
C data := x"1111"
C wreg: tx: sop - cmd(wreg,3) addr(00f1) dl dh ccrc - eop
C rx: sop - cmd(wreg,3) stat crc - eop
#
rxsop
rxcs wreg,3 00000000
rxeop
#
txsop
txcad wreg,3 x"ffe4" x"1111"
txeop
#
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A2.3: rreg(data) -> shows that rlink can read back a register
C data -> x"1111"
C rreg: tx: sop - cmd(rreg,4) addr(00f1) ccrc - eop
C rx: sop - cmd(rreg,4) dl dh stat crc - eop
#
rxsop
rxcds rreg,4 x"1111" 00000000
rxeop
#
txsop
txca rreg,4 x"ffe4"
txeop
#
.iowt 10
#
C =============================================================================
C Section A3: Check-out rbd_tester basics with wreg,rreg
C from now use lists and high level commands
C -----------------------------------------------------------------------------
C Test A3.1: wreg(data) + rreg(data) list
#
sop
wreg 0 x"ffe4" x"f0f0" 00000000 -- data := f0f0
rreg 1 x"ffe4" x"f0f0" 00000000 -- data >? f0f0
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A3.2: check cntl write/read
#
sop
wreg 2 x"ffe0" x"ffff" 00000000 -- cntl := ffff
rreg 3 x"ffe0" x"83ff" 00000000 -- cntl >? (wchk=1,nbusy=3ff)
wreg 4 x"ffe0" x"0000" 00000000 -- cntl := ffff
rreg 5 x"ffe0" x"0000" 00000000 -- cntl >? (wchk=0,nbusy=0)
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A3.3: check stat write/read (and that RB_STAT is retured)
#
sop
wreg 2 x"ffe1" x"ffff" 00000000 -- stat := ffff
rreg 3 x"ffe1" x"000f" 11110000 -- stat >? 000f {stat=1111}
wreg 4 x"ffe1" x"0000" 11110000 -- stat := 0000 {stat=1111}
rreg 5 x"ffe1" x"0000" 00000000 -- stat >? 0000
eop
.iowt 10
C -----------------------------------------------------------------------------
C Test A3.4: check attn write/read (also RB_LAM is driven; also rberr in rreg)
#
sop
wreg 6 x"ffe2" x"beaf" 00001000 -- attn := 5555 {attn=1}
rreg 7 x"ffe2" x"5555" 00001001 -- attn >? 5555 {attn=1,err=1}
attn 8 x"beaf" 00000000 -- >? beaf (attn pattern)
attn 8 x"0000" 00000000 -- >? 0000 (cleared on reread)
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A3.5: check ncyc write/read (also rberr in wreg)
#
sop
wreg 9 x"ffe4" x"beaf" 00000000 -- data := beaf
rreg 10 x"ffe3" x"0001" 00000000 -- ncyc >? 0001 (nbusy is 0!)
wreg 11 x"ffe3" x"dead" 00000001 -- ncyc := dead {err=1}
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A3.6: check dinc read
#
sop
wreg 12 x"ffe4" x"1100" 00000000 -- data := 1100
rreg 13 x"ffe5" x"1100" 00000000 -- dinc >? 1100
rreg 14 x"ffe5" x"1101" 00000000 -- dinc >? 1101
rreg 15 x"ffe5" x"1102" 00000000 -- dinc >? 1102
rreg 16 x"ffe4" x"1103" 00000000 -- data >? 1103
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A3.7: check dinc write (and wchk)
#
sop
wreg 17 x"ffe4" x"1200" 00000000 -- data := 1200
wreg 18 x"ffe5" x"1200" 00000000 -- dinc := 1200
wreg 19 x"ffe5" x"1201" 00000000 -- dinc := 1201
wreg 20 x"ffe5" x"1202" 00000000 -- dinc := 1202
rreg 21 x"ffe4" x"1203" 00000000 -- data >? 1203
rreg 22 x"ffe0" x"0000" 00000000 -- cntl >? (wchk=0)
eop
.iowt 10
#
sop
wreg 23 x"ffe5" x"f203" 00000000 -- dinc := f203 (should be 1203!)
wreg 24 x"ffe5" x"1204" 00000000 -- dinc := 1204 (ok again)
rreg 25 x"ffe0" x"8000" 00000000 -- cntl >? (wchk=1)
rreg 26 x"ffe4" x"1205" 00000000 -- data >? 1205
wreg 27 x"ffe4" x"1300" 00000000 -- data := 1300 (clears wchk)
rreg 28 x"ffe0" x"0000" 00000000 -- cntl >? (wchk=0)
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A3.8: check fifo write/read (and rberr for rreg)
#
sop
rreg 0 x"ffe6" x"5555" 00000001 -- fifo >? 5555 {err=1} (fifo empty)
wreg 1 x"ffe6" x"1400" 00000000 -- fifo := 1400
wreg 2 x"ffe6" x"1401" 00000000 -- fifo := 1401
wreg 3 x"ffe6" x"1402" 00000000 -- fifo := 1402
rreg 4 x"ffe6" x"1400" 00000000 -- fifo >? 1400
rreg 5 x"ffe6" x"1401" 00000000 -- fifo >? 1400
rreg 6 x"ffe6" x"1402" 00000000 -- fifo >? 1400
rreg 7 x"ffe6" x"5555" 00000001 -- fifo >? 5555 {err=1} (fifo empty)
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A3.9: check lnak write/read (and rbnak for rreg and wreg)
#
sop
wreg 0 x"ffe7" x"aaaa" 00000010 -- lnak >? aaaa {nak=1}
rreg 1 x"ffe7" x"5555" 00000010 -- lnak >? 5555 {nak=1}
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A3.10: check nbusy (use nbusy=4)
#
C with data
sop
wreg 0 x"ffe0" x"0004" 00000000 -- cntl := (nbusy=4)
wreg 1 x"ffe4" x"1234" 00000000 -- data := 1234
rreg 2 x"ffe3" x"0005" 00000000 -- ncyc >? 0005 (ncyc=nbusy+1)
rreg 3 x"ffe4" x"1234" 00000000 -- data >? 1234
rreg 4 x"ffe3" x"0005" 00000000 -- ncyc >? 0005 (ncyc=nbusy+1)
eop
.iowt 10
#
C with dinc
sop
wreg 0 x"ffe5" x"1234" 00000000 -- dinc := 1234
rreg 1 x"ffe3" x"0005" 00000000 -- ncyc >? 0005 (ncyc=nbusy+1)
rreg 2 x"ffe5" x"1235" 00000000 -- dinc >? 1235
rreg 3 x"ffe3" x"0005" 00000000 -- ncyc >? 0005 (ncyc=nbusy+1)
eop
.iowt 10
#
C with fifo
sop
wreg 0 x"ffe6" x"3300" 00000000 -- fifo := 3300
rreg 1 x"ffe3" x"0005" 00000000 -- ncyc >? 0005 (ncyc=nbusy+1)
rreg 2 x"ffe6" x"3300" 00000000 -- fifo >? 3300
rreg 3 x"ffe3" x"0005" 00000000 -- ncyc >? 0005 (ncyc=nbusy+1)
eop
.iowt 10
#
C with lnak
sop
wreg 0 x"ffe7" x"aaaa" 00000010 -- lnak := aaaa {nak=1}
rreg 1 x"ffe3" x"0005" 00000000 -- ncyc >? 0005 (ncyc=nbusy+1)
rreg 2 x"ffe7" x"5555" 00000010 -- lnak >? 5555 {nak=1}
rreg 3 x"ffe3" x"0005" 00000000 -- ncyc >? 0005 (ncyc=nbusy+1)
eop
.iowt 10
#
C with stat (should not assert busy!)
sop
wreg 0 x"ffe1" x"0000" 00000000 -- stat := 0000
rreg 1 x"ffe3" x"0001" 00000000 -- ncyc >? 0001 (after wreg stat)
rreg 2 x"ffe1" x"0000" 00000000 -- stat >? 0000
rreg 3 x"ffe3" x"0001" 00000000 -- ncyc >? 0001 (after rreg stat)
eop
.iowt 10
#
C with ncyc (should not assert busy!)
sop
rreg 0 x"ffe3" x"0001" 00000000 -- ncyc >? 0001 (after rreg ncyc)
eop
.iowt 10
#
C with cntl (should not assert busy!)
sop
rreg 0 x"ffe0" x"0004" 00000000 -- cntl >? 0004
rreg 1 x"ffe3" x"0001" 00000000 -- ncyc >? 0001 (after rreg cntl)
wreg 2 x"ffe0" x"0000" 00000000 -- cntl := 0000
rreg 3 x"ffe3" x"0001" 00000000 -- ncyc >? 0001 (after wreg cntl)
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A3.11: check nbusy (use nbusy=3ff -> will cause time out)
#
C with data
sop
wreg 0 x"ffe0" x"03ff" 00000000 -- cntl := (nbusy=1023)
wreg 1 x"ffe4" x"1234" 00000100 -- data := 1234
rreg 2 x"ffe3" x"0020" 00000000 -- ncyc >? 0020 (ncyc=TO(32))
rreg 3 x"ffe4" x"5555" 00000100 -- data >? 5555
rreg 4 x"ffe3" x"0020" 00000000 -- ncyc >? 0020 (ncyc=TO(32))
eop
.iowt 10
#
C with dinc
sop
wreg 0 x"ffe5" x"1234" 00000100 -- dinc := 1234
rreg 1 x"ffe3" x"0020" 00000000 -- ncyc >? 0020 (ncyc=TO(32))
rreg 2 x"ffe5" x"5555" 00000100 -- dinc >? 5555
rreg 3 x"ffe3" x"0020" 00000000 -- ncyc >? 0020 (ncyc=TO(32))
eop
.iowt 10
#
C with fifo
sop
wreg 0 x"ffe6" x"3300" 00000100 -- fifo := 3300
rreg 1 x"ffe3" x"0020" 00000000 -- ncyc >? 0020 (ncyc=TO(32))
rreg 2 x"ffe6" x"5555" 00000100 -- fifo >? 5555
rreg 3 x"ffe3" x"0020" 00000000 -- ncyc >? 0020 (ncyc=TO(32))
eop
.iowt 10
#
C with lnak
sop
wreg 0 x"ffe7" x"aaaa" 00000100 -- lnak := aaaa {nak=1}
rreg 1 x"ffe3" x"0020" 00000000 -- ncyc >? 0020 (ncyc=TO(32))
rreg 2 x"ffe7" x"5555" 00000100 -- lnak >? 5555 {nak=1}
rreg 3 x"ffe3" x"0020" 00000000 -- ncyc >? 0020 (ncyc=TO(32))
eop
.iowt 10
#
C reset to nbusy=0
sop
wreg 0 x"ffe0" x"0000" 00000000 -- cntl := (nbusy=0)
eop
.iowt 10
#
C =============================================================================
C Section A4: Basic commands: wblk, rblk
C -----------------------------------------------------------------------------
C Test A4.1: wblk, rblk (with fifo, no errors)
#
sop
wblks 0 x"ffe6" 8 x"0100" 00000000 -- fifo := seq(8,0100)
rblks 1 x"ffe6" 8 x"0100" 00000000 -- fifo >? seq(8,0100)
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A4.2: wblk, rblk (with dinc, no errors)
#
sop
wreg 0 x"ffe4" x"2200" 00000000 -- data := 2200
rblks 1 x"ffe5" 8 x"2200" 00000000 -- dinc >? seq(8,2200)
wblks 2 x"ffe5" 8 x"2208" 00000000 -- dinc := seq(8,2208)
rreg 3 x"ffe4" x"2210" 00000000 -- data >? 2210
rreg 4 x"ffe0" x"0000" 00000000 -- cntl >? (wchk=0)
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A4.3: wblk, rblk (with lnak, -> rbnak response)
#
sop
.dclr
.dseq 4 x"3300" -- seq( 4,3300)
wblkd 0 x"ffe7" 0 00000010 -- lnak := .... {nak=1,dc=0}
.dclr
.dwrd x"0055" -- 1st lsb from rbus
.dwrd x"0000" -- rest will be 0 from abort states
.dwrd x"0000"
.dwrd x"0000"
rblkd 1 x"ffe7" 0 00000010 -- lnak >? .... {nak=1,dc=0)
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A4.4: wblk, rblk (with fifo, -> rberr response when fifo full)
#
sop
.dclr
.dseq 18 x"4400" -- seq(18,4400)
wblkd 0 x"ffe6" 16 00000001 -- fifo := .... {err=1,dc=16}
.dclr
.dseq 16 x"4400" -- seq(16,4400)
.dwrd x"0055" -- 1st lsb from rbus
.dwrd x"0000" -- rest will be 0 from abort states
rblkd 1 x"ffe6" 16 00000001 -- lnak >? .... {err=1,dc=16)
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A4.5: wblk, rblk (with dinc, zero length request)
#
sop
wreg 0 x"ffe4" x"5500" 00000000 -- data := 5500
rblks 1 x"ffe5" 0 x"5500" 00000000 -- dinc >? seq(0,5500)
wblks 2 x"ffe5" 0 x"5500" 00000000 -- dinc := seq(0,5500)
rreg 3 x"ffe4" x"5500" 00000000 -- data >? 5500
rreg 4 x"ffe0" x"0000" 00000000 -- cntl >? (wchk=0)
eop
.iowt 10
#
C =============================================================================
C Section A5: Basic commands: init
C -----------------------------------------------------------------------------
C Test A5.1: init (test with tester data reg)
#
C setup cntl, data, fifo
sop
wreg 0 x"ffe0" x"0002" 00000000 -- cntl := 0002
wreg 1 x"ffe4" x"3210" 00000000 -- data := 3210
wreg 2 x"ffe6" x"6600" 00000000 -- fifo := 6600
wreg 3 x"ffe6" x"6601" 00000000 -- fifo := 6601
wreg 4 x"ffe6" x"6602" 00000000 -- fifo := 6602
wreg 5 x"ffe6" x"6603" 00000000 -- fifo := 6603
eop
.iowt 10
#
C init(0000) -> noop
sop
init 0 x"ffe0" x"0000" 00000000
rreg 1 x"ffe0" x"0002" 00000000 -- cntl >? 0002
rreg 2 x"ffe4" x"3210" 00000000 -- data >? 3210
rreg 3 x"ffe6" x"6600" 00000000 -- fifo >? 6600
eop
.iowt 10
#
C init(0001) -> clear cntl
sop
init 0 x"ffe0" x"0001" 00000000
rreg 1 x"ffe0" x"0000" 00000000 -- cntl >? 0000
rreg 2 x"ffe4" x"3210" 00000000 -- data >? 3210
rreg 3 x"ffe6" x"6601" 00000000 -- fifo >? 6601
eop
.iowt 10
#
C init(0002) -> clear data
sop
init 0 x"ffe0" x"0002" 00000000
rreg 1 x"ffe0" x"0000" 00000000 -- cntl >? 0000
rreg 2 x"ffe4" x"0000" 00000000 -- data >? 0000
rreg 3 x"ffe6" x"6602" 00000000 -- fifo >? 6602
eop
.iowt 10
#
C init(0004) -> clear fifo
sop
init 0 x"ffe0" x"0004" 00000000
rreg 1 x"ffe0" x"0000" 00000000 -- cntl >? 0000
rreg 2 x"ffe4" x"0000" 00000000 -- data >? 0000
rreg 3 x"ffe6" x"5555" 00000001 -- fifo >? 5555 {err=1}
eop
.iowt 10
#
C =============================================================================
C Section A6: rlink core rbus registers (needed for labo and attn tests)
C -----------------------------------------------------------------------------
C Test A6.1: read all regs
# for stat expect: lcmd = 00001 000 (seq=1,cmd=000) from previous rreg,1
# babo = 0 (last wblk/rblk was ok)
# size = 001 (size=RTAWIDTH-10, and tb has RTAWIDTH=11)
# --> stat= 00001 000 0 0000 001 -> 0801
#
sop
rreg 1 x"ffff" x"0000" 00000000 -- cntl >? 0000
rreg 2 x"fffe" x"0801" 00000000 -- stat >? 0801 (see above)
rreg 3 x"fffd" x"7654" 00000000 -- sysh >? 7654
rreg 4 x"fffc" x"3210" 00000000 -- sysl >? 3210
eop
.iowt 10
#
C =============================================================================
C Section A7: Basic commands: labo
C -----------------------------------------------------------------------------
C Test A7.1: labo after successful rblk,wblk (essentially a noop)
#
sop
init 0 x"ffe0" x"0007" 00000000 -- clear all
wblks 1 x"ffe6" 4 x"0200" 00000000 -- fifo := seq(4,0200)
labo 2 x"00" 00000000
rblks 3 x"ffe6" 4 x"0200" 00000000 -- fifo >? seq(4,0200)
labo 4 x"00" 00000000
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test A7.2: labo after aborted wblk,rblk
#
# for stat expect: lcmd = 00001 011 (seq=1,cmd=011) from previous wblk,1
# lcmd = 00001 001 (seq=1,cmd=001) from previous rblk,1
# babo = 1 (last wblk/rblk was aborted)
# size = 001 (size=RTAWIDTH-10, and tb has RTAWIDTH=11)
# --> stat= 00001 011 1 0000 001 -> 0b81
# --> stat= 00001 001 1 0000 001 -> 0981
#
C aborted wblk, labo, wreg(data),rreg(dinc)
sop
.dclr
.dseq 18 x"4400" -- seq(18,4400)
init 0 x"ffe0" x"0007" 00000000 -- clear all
wblkd 1 x"ffe6" 16 00000001 -- fifo := .... {err=1,dc=16}
rreg 2 x"fffe" x"0b81" 00000000 -- stat >? 0b81 (see above)
labo 3 x"01" 00000000
wreg 4 x"ffe4" x"0101" 00000000 -- data := 0101
rreg 5 x"ffe5" x"0102" 00000000 -- dinc := 0102
eop
.iowt 20 -- 20 needed for sp1c
#
C check that wreg(data) and rreg(dinc) wasn't done
sop
rreg 0 x"ffe4" x"0000" 00000000 -- data >? 0000
eop
.iowt 10
#
C aborted rblk, labo, wreg(data),rreg(dinc)
sop
.dclr
.dseq 16 x"4400" -- seq(16,4400)
.dwrd x"0055" -- 1st lsb from rbus
.dwrd x"0000" -- rest will be 0 from abort states
rblkd 1 x"ffe6" 16 00000001 -- lnak >? .... {err=1,dc=16)
rreg 2 x"fffe" x"0981" 00000000 -- stat >? 0981 (see above)
labo 3 x"01" 00000000
wreg 4 x"ffe4" x"0101" 00000000 -- data := 0101
rreg 5 x"ffe5" x"0102" 00000000 -- dinc := 0102
eop
.iowt 10
#
C check that wreg(data) and rreg(dinc) wasn't done
sop
rreg 0 x"ffe4" x"0000" 00000000 -- data >? 0000
eop
.iowt 10
 
 
C =============================================================================
C Section A8: attn notification
C -----------------------------------------------------------------------------
C Test A8.1: test response on attn polls
#
C send attn, expect attn notify message (with all 0)
anmsg 0000000000000000
txattn
.iowt 20
#
C trigger LAM, send attn, expect attn notify message
.attn 0000000000000001
.iowt 10
anmsg 0000000000000001
txattn
.iowt 20
#
C harvest attn, send attn, expect attn notify message (all 0 again)
sop
attn 1 x"0001" 00000000 -- attn >? 0001
attn 2 x"0000" 00000000 -- attn >? 0000
eop
.iowt 10
anmsg 0000000000000000
txattn
.iowt 20
#
C -----------------------------------------------------------------------------
C Test A8.2: test attn notification
#
C enable attn notification
sop
wreg 1 x"ffff" x"8000" 00000000 -- cntl := (anena=1)
rreg 2 x"ffff" x"8000" 00000000 -- cntl >? (anena=1)
eop
.iowt 10
#
C trigger LAM, expect attn notify message
anmsg 0000000000000010
.attn 0000000000000010
.iowt 10
#
C send attn, expect attn notify message
anmsg 0000000000000010
txattn
.iowt 20
#
C harvest attn pattern
sop
rreg 1 x"ffff" x"8000" 00001000 -- cntl >? (anena=1) {attn=1}
attn 2 x"0002" 00000000 -- attn >? 0002
rreg 3 x"ffff" x"8000" 00000000 -- cntl >? (anena=1)
attn 4 x"0000" 00000000 -- attn >? 0000 (nothing !)
eop
.iowt 10
#
C send attn, expect attn notify message (all 0)
anmsg 0000000000000000
txattn
.iowt 20
#
C disable attn notification
sop
wreg 1 x"ffff" x"0000" 00000000 -- cntl := (anena=1)
rreg 2 x"ffff" x"0000" 00000000 -- cntl >? (anena=1)
eop
.iowt 10
C trigger LAM, no attn comma now
.attn 0000000000000100
.iowt 10
#
C send attn, expect attn notify message
anmsg 0000000000000100
txattn
.iowt 20
#
C harvest attn pattern
sop
rreg 1 x"ffff" x"0000" 00001000 -- cntl >? (anena=1) {attn=1}
attn 2 x"0004" 00000000 -- attn >? 0004
eop
.iowt 10
#
#==============================================================================
#
C -----------------------------------------------------------------------------
C Run down and Finish
.iowt 10
.wait 10
/tb/tbd_rlink_direct.vhd
0,0 → 1,140
-- $Id: tbd_rlink_direct.vhd 594 2014-09-21 12:29:33Z mueller $
--
-- Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: tbd_rlink_direct - syn
-- Description: Wrapper for rlink_core to avoid records. It has a port
-- interface which will not be modified by xst synthesis
-- (no records, no generic port).
--
-- Dependencies: rlink_core
-- rbus/rb_mon
-- rlink/rlink_mon
--
-- To test: rlink_core
--
-- Target Devices: generic
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2007-11-24 92 8.1.03 I27 xc3s1000-4 143 309 0 166 s 7.64
-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 148 320 0 - t 8.34
-- 2007-10-27 92 9.1 J30 xc3s1000-4 148 315 0 - t 8.34
-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 153 302 0 162 s 7.65
-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 138 306 0 - s 7.64
--
-- Tool versions: xst 8.1-14.7; ghdl 0.18-0.31
--
-- Revision History:
-- Date Rev Version Comment
-- 2014-09-19 594 4.0 now rlink v4.0 iface, 4 bit STAT
-- 2014-08-15 583 3.5 rb_mreq addr now 16 bit
-- 2010-12-25 348 3.0.2 drop RL_FLUSH, add RL_MONI for rlink_core
-- 2010-12-24 347 3.0.1 rename: CP_*->RL->*
-- 2010-12-05 343 3.0 rri->rlink renames; port to rbus V3 protocol;
-- 2010-05-02 287 2.2.1 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM
-- drop RP_IINT signal from interfaces
-- 2010-04-03 274 2.2 add CP_FLUSH for rri_core, add CE_USEC
-- 2009-03-14 197 2.1 remove records in interface to allow _ssim usage
-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface
-- 2007-11-25 98 1.1 added RP_IINT support; use entity rather arch
-- name to switch core/serport
-- 2007-07-02 63 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.rblib.all;
use work.rlinklib.all;
 
entity tbd_rlink_direct is -- rlink_core only tb design
-- generic: ATOWIDTH=5; ITOWIDTH=6
-- implements tbd_rlink_gen
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rlink ito time unit clock enable
CE_USEC : in slbit; -- 1 usec clock enable
RESET : in slbit; -- reset
RL_DI : in slv9; -- rlink: data in
RL_ENA : in slbit; -- rlink: data enable
RL_BUSY : out slbit; -- rlink: data busy
RL_DO : out slv9; -- rlink: data out
RL_VAL : out slbit; -- rlink: data valid
RL_HOLD : in slbit; -- rlink: data hold
RB_MREQ_aval : out slbit; -- rbus: request - aval
RB_MREQ_re : out slbit; -- rbus: request - re
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt : out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv16; -- rbus: request - addr
RB_MREQ_din : out slv16; -- rbus: request - din
RB_SRES_ack : in slbit; -- rbus: response - ack
RB_SRES_busy : in slbit; -- rbus: response - busy
RB_SRES_err : in slbit; -- rbus: response - err
RB_SRES_dout : in slv16; -- rbus: response - dout
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4; -- rbus: status flags
TXRXACT : out slbit -- txrx active flag
);
end entity tbd_rlink_direct;
 
 
architecture syn of tbd_rlink_direct is
 
signal RL_MONI : rl_moni_type := rl_moni_init;
signal RB_MREQ : rb_mreq_type := rb_mreq_init;
signal RB_SRES : rb_sres_type := rb_sres_init;
 
begin
 
RB_MREQ_aval <= RB_MREQ.aval;
RB_MREQ_re <= RB_MREQ.re;
RB_MREQ_we <= RB_MREQ.we;
RB_MREQ_initt<= RB_MREQ.init;
RB_MREQ_addr <= RB_MREQ.addr;
RB_MREQ_din <= RB_MREQ.din;
 
RB_SRES.ack <= RB_SRES_ack;
RB_SRES.busy <= RB_SRES_busy;
RB_SRES.err <= RB_SRES_err;
RB_SRES.dout <= RB_SRES_dout;
 
UUT : rlink_core
generic map (
BTOWIDTH => 5,
RTAWIDTH => 11,
SYSID => x"76543210",
ENAPIN_RLMON => sbcntl_sbf_rlmon,
ENAPIN_RBMON => sbcntl_sbf_rbmon)
port map (
CLK => CLK,
CE_INT => CE_INT,
RESET => RESET,
RL_DI => RL_DI,
RL_ENA => RL_ENA,
RL_BUSY => RL_BUSY,
RL_DO => RL_DO,
RL_VAL => RL_VAL,
RL_HOLD => RL_HOLD,
RL_MONI => RL_MONI,
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT
);
 
TXRXACT <= '0';
end syn;
/tb/rlink_cext.c
0,0 → 1,276
/* $Id: rlink_cext.c 602 2014-11-08 21:42:47Z mueller $
*
* Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
*
* This program is free software; you may redistribute and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 2, 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 complete details.
*
* Revision History:
* Date Rev Vers Comment
* 2014-11-02 602 2.0 sideband handling for rlink v4; count EAGAINs
* 2014-07-27 575 1.3.2 add ssize_t -> int casts to avoid warnings
* add fflush(stdout) after standart open/close msgs
* 2011-03-05 366 1.3.1 add RLINK_CEXT_TRACE=2 trace level
* 2010-12-29 351 1.3 rename cext_rriext -> rlink_cext; rename functions
* cext_* -> rlink_cext_* and fifo file names
* tb_cext_* -> rlink_cext_*
* 2007-11-18 96 1.2 add 'read before write' logic to avoid deadlocks
* under cygwin broken fifo (size=1 !) implementation
* 2007-10-19 90 1.1 add trace option, controlled by setting an
* the environment variable CEXT_RRIEXT_TRACE=1
* 2007-09-23 84 1.0 Initial version
*/
 
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sched.h>
#include <stdlib.h>
#include <string.h>
 
/* kSymEsc = 0xCA = 1100 1010 (bin) */
#define CESC (0xCA)
#define QRBUFSIZE 1024
 
static int fd_rx = -1;
static int fd_tx = -1;
 
static int io_trace = 0;
 
static char qr_buf[QRBUFSIZE];
static int qr_pr = 0;
static int qr_pw = 0;
static int qr_nb = 0;
static int qr_eof = 0;
static int qr_err = EAGAIN;
 
static void rlink_cext_dotrace(const char *text, int dat)
{
int i;
int mask = 0x80;
printf("rlink_cext-I: %s ", text);
for (i=0; i<8; i++) {
printf("%c", (dat&mask)?'1':'0' );
mask >>= 1;
}
printf("\n");
}
 
static void rlink_cext_doread()
{
static int neagain = 0;
char buf[1];
ssize_t nbyte;
nbyte = read(fd_rx, buf, 1);
if (io_trace > 1) {
if (nbyte < 0 && errno == EAGAIN) {
neagain += 1;
} else {
if (neagain) {
printf("rlink_cext-I: reads with EAGAIN: %d seen\n", neagain);
neagain = 0;
}
printf("rlink_cext-I: read rc=%d", (int)nbyte);
if (nbyte < 0) printf(" errno=%d %s", errno, strerror(errno));
printf("\n");
}
}
 
if (nbyte < 0) {
qr_err = errno;
} else if (nbyte == 0) {
qr_err = EAGAIN;
qr_eof = 1;
} else {
qr_err = EAGAIN;
if (qr_nb < QRBUFSIZE) {
if (io_trace) rlink_cext_dotrace("rcv8", (unsigned char) buf[0]);
qr_buf[qr_pw++] = buf[0];
if (qr_pw >= QRBUFSIZE) qr_pw = 0;
qr_nb += 1;
} else {
printf("Buffer overflow\n"); /* FIXME: better error handling */
}
}
}
 
/* returns:
* <0 if error
* >=0 <=0xff normal data
* == 0x100 idle
* 0x01aahhll if side band message seen
*
*/
 
int rlink_cext_getbyte(int clk)
{
char buf[1];
ssize_t nbyte;
int irc;
int tdat;
char* env_val;
 
static int odat;
static int nidle = 0;
static int ncesc = 0;
static int nside = -1;
 
if (fd_rx < 0) { /* fifo's not yet opened */
fd_rx = open("rlink_cext_fifo_rx", O_RDONLY|O_NONBLOCK);
if (fd_rx <= 0) {
perror("rlink_cext-E: failed to open rlink_cext_fifo_rx");
return -2;
}
printf("rlink_cext-I: connected to rlink_cext_fifo_rx\n");
fflush(stdout);
fd_tx = open("rlink_cext_fifo_tx", O_WRONLY);
if (fd_tx <= 0) {
perror("rlink_cext-E: failed to open rlink_cext_fifo_tx");
return -2;
}
printf("rlink_cext-I: connected to rlink_cext_fifo_tx\n");
fflush(stdout);
 
nidle = 0;
ncesc = 0;
nside = -1;
 
/* determine trace level from RLINK_CEXT_TRACE: */
/* "1" trace bytes read and written */
/* "2" trace also read() and write() calls */
io_trace = 0;
env_val = getenv("RLINK_CEXT_TRACE");
if (env_val) {
printf("rlink_cext-I: seen RLINK_CEXT_TRACE=%s\n", env_val);
if (strcmp(env_val, "0") == 0) {
printf("rlink_cext-I: set trace level to 0 (off)\n");
} else if (strcmp(env_val, "1") == 0) {
printf("rlink_cext-I: set trace level to 1 (bytes)\n");
io_trace = 1;
} else if (strcmp(env_val, "2") == 0) {
printf("rlink_cext-I: set trace level to 2 (bytes + calls)\n");
io_trace = 2;
} else {
printf("rlink_cext-E: invalid RLINK_CEXT_TRACE value; ignored\n");
}
}
}
 
rlink_cext_doread();
 
if (qr_nb == 0) { /* no character to be processed */
if (qr_eof != 0) { /* EOF seen */
if (ncesc >= 2) { /* two+ CESC seen ? */
printf("rlink_cext-I: seen EOF, wait for reconnect\n");
fflush(stdout);
close(fd_rx);
close(fd_tx);
fd_rx = -1;
fd_tx = -1;
usleep(500000); /* wait 0.5 sec */
return 0x100; /* return idle, will reconnect */
}
printf("rlink_cext-I: seen EOF, schedule clock stop and exit\n");
fflush(stdout);
return -1; /* signal EOF seen */
 
} else if (qr_err == EAGAIN) { /* nothing read, return idle */
if (nidle < 8 || (nidle%1024)==0) {
irc = sched_yield();
if (irc < 0) perror("rlink_cext-W: sched_yield failed");
}
nidle += 1;
return 0x100;
} else { /* must be a read error */
errno = qr_err;
perror("rlink_cext-E: read error on rlink_cext_fifo_rx");
return -3;
}
}
 
nidle = 0;
tdat = (unsigned char) qr_buf[qr_pr++];
if (qr_pr >= QRBUFSIZE) qr_pr = 0;
qr_nb -= 1;
if (tdat == CESC) {
ncesc += 1;
if (ncesc == 2) nside = 0;
} else {
ncesc = 0;
}
 
switch (nside) {
case -1: /* normal data */
return tdat;
case 0: /* 2nd CESC, return it */
nside += 1;
odat = 0x01000000; /* init odat */
return tdat;
 
/* decode oob data as formated by RlinkPacketBufSnd::SndOob() */
/* odat format: 0x01aadddd */
case 1: /* get ADDR(3:0) */
nside += 1;
odat |= (tdat&0x0f)<<16;
return 0x100;
case 2: /* get ADDR(7:4) */
nside += 1;
odat |= (tdat&0x0f)<<20;
return 0x100;
case 3: /* get data( 3: 0) */
nside += 1;
odat |= (tdat&0x0f);
return 0x100;
case 4: /* get data( 7: 4) */
nside += 1;
odat |= (tdat&0x0f)<<4;
return 0x100;
case 5: /* get data(11: 8) */
nside += 1;
odat |= (tdat&0x0f)<<8;
return 0x100;
case 6: /* get data(15:12) */
nside = -1;
odat |= (tdat&0x0f)<<12;
return odat;
}
}
 
int rlink_cext_putbyte(int dat)
{
char buf[1];
ssize_t nbyte;
 
rlink_cext_doread();
 
if (io_trace) rlink_cext_dotrace("snd8", dat);
 
buf[0] = (unsigned char) dat;
nbyte = write(fd_tx, buf, 1);
if (io_trace > 1) {
printf("rlink_cext-I: write rc=%d", (int)nbyte);
if (nbyte < 0) printf(" errno=%d %s", errno, strerror(errno));
printf("\n");
}
 
if (nbyte < 0) {
perror("rlink_cext-E: write error on rlink_cext_fifo_tx");
return -3;
}
 
return 0;
}
/tb/tb_rlink.vhd
0,0 → 1,991
-- $Id: tb_rlink.vhd 596 2014-10-17 19:50:07Z mueller $
--
-- Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: tb_rlink - sim
-- Description: Test bench for rlink_core
--
-- Dependencies: simlib/simclk
-- simlib/simclkcnt
-- genlib/clkdivce
-- rbus/tbd_tester
-- tbd_rlink_gen [UUT]
--
-- To test: rlink_core (via tbd_rlink_direct)
-- rlink_base (via tbd_rlink_serport)
-- rlink_serport (via tbd_rlink_serport)
--
-- Target Devices: generic
-- Tool versions: xst 8.2-14.7; ghdl 0.18-0.31
--
-- Revision History:
-- Date Rev Version Comment
-- 2014-10-12 596 4.1 use readgen_ea; add get_cmd_ea; labo instead of stat
-- add txblk,rxblk,rxrbeg,rxrend,rxcbs,anmsg commands
-- 2014-08-28 588 4.0 now rlink v4 iface -> txcac has 16 bit; 4 bit STAT
-- 2014-08-15 583 3.5 rb_mreq addr now 16 bit; adopt txca,txcad,txcac
-- 2011-12-23 444 3.1 use new simclk/simclkcnt
-- 2011-11-19 427 3.0.7 fix crc8_update_tbl usage; now numeric_std clean
-- 2010-12-29 351 3.0.6 use new rbd_tester addr 111100xx (from 111101xx)
-- 2010-12-26 348 3.0.5 use simbus to export clkcycle (for tbd_..serport)
-- 2010-12-23 347 3.0.4 use rb_mon, rlink_mon directly; rename CP_*->RL_*
-- 2010-12-22 346 3.0.3 add .rlmon and .rbmon commands
-- 2010-12-21 345 3.0.2 rename commands .[rt]x... to [rt]x...;
-- add .[rt]x(idle|attn) cmds; remove 'bbbbbbbb' cmd
-- 2010-12-12 344 3.0.1 add .attn again; add .txbad, .txoof; ren oob->oof
-- 2010-12-05 343 3.0 rri->rlink renames; port to rbus V3 protocol;
-- use rbd_tester instead of sim target;
-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining
-- 2010-06-03 299 2.2.2 new init encoding (WE=0/1 int/ext);use sv_ prefix
-- for shared variables
-- 2010-05-02 287 2.2.1 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM
-- drop RP_IINT signal from interfaces
-- 2010-04-03 274 2.2 add CE_USEC in tbd_rri_gen interface
-- 2009-03-14 197 2.1 remove records in interface to allow _ssim usage
-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface
-- 2008-03-24 129 1.1.2 CLK_CYCLE now 31 bits
-- 2008-01-20 112 1.1.1 rename clkgen->clkdivce
-- 2007-11-24 98 1.1 add RP_IINT support, add checkmiss_tx to test
-- for missing responses
-- 2007-10-26 92 1.0.2 add DONE timestamp at end of execution
-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned
-- 2007-09-09 81 1.0 Initial version
------------------------------------------------------------------------------
-- command set:
-- .reset assert RESET for 1 clk
-- .rlmon ien enable rlink monitor (9 bit)
-- .rlbmo ien enable rlink monitor (8 bit)
-- .rbmon ien enable rbus monitor
-- .wait n wait n clks
-- .iowt n wait n clks for rlink i/o; auto-extend
-- .attn dat(16) pulse attn lines with dat
--
-- - high level ---
-- anmsg apat attn notify message
-- sop start packet
-- eop end packet
-- rreg seq addr data stat rreg cmd
-- wreg seq addr data stat wreg cmd
-- init seq addr data stat init cmd
-- attn seq data stat attn cmd
-- labo seq data stat labo cmd
-- rblks seq addr nblk data stat rblk cmd (with seq)
-- wblks seq addr nblk data stat wblk cmd (with seq)
-- rblkd seq addr ndone stat rblk cmd (with data list)
-- wblkd seq addr ndone stat wblk cmd (with data list)
-- .dclr clear data list
-- .dwrd data add word to data list
-- .dseq nblk data add sequence to data list
--
-- - low level ---
-- txcrc send crc
-- txbad send bad (inverted) crc
-- txc cmd(8) send cmd - crc
-- txca cmd(8) addr(16) send cmd - al ah - crcl crch
-- txcad cmd(8) addr(16) dat(16) send cmd - al ah - dl dh - crcl crch
-- txcac cmd(8) addr(16) cnt(16) send cmd - al ah - cl ch - crcl crch
-- txoof dat(9) send out-of-frame symbol
-- rxcrc expect crc
-- rxcs cmd(8) stat(8) expect cmd - stat - crcl crch
-- rxcds cmd(8) dat(16) stat(8) expect cmd - dl dh - stat - crcl crch
-- rxcbs cmd(8) dat(8) stat(8) expect cmd - dl - stat - crcl crch
-- rxrbeg cmd(8) cnt(16) expect cmd - cl ch
-- rxrend dcnt(16) expect dcl dch - stat - crcl crch
-- rxoof dat(9) expect out-of-frame symbol
--
-- - raw level ---
-- txsop send <sop>
-- txeop send <eop>
-- txnak send <nak>
-- txattn send <attn>
-- tx8 dat(8) send 8 bit value
-- tx16 dat(16) send 16 bit value
-- txblk n start send n 16 values
-- rxsop reset rx list; expect sop
-- rxeop expect <eop>
-- rxnak expect <nak>
-- rxattn expect <attn>
-- rx8 dat(8) expect 8 bit value
-- rx16 dat(16) expect 16 bit value
-- rxblk n start expect n 16 values
--
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.genlib.all;
use work.comlib.all;
use work.rblib.all;
use work.rbdlib.all;
use work.rlinklib.all;
use work.simlib.all;
use work.simbus.all;
 
entity tb_rlink is
end tb_rlink;
 
architecture sim of tb_rlink is
constant d_f_cflag : integer := 8; -- d9: comma flag
subtype d_f_data is integer range 7 downto 0; -- d9: data field
 
subtype f_byte1 is integer range 15 downto 8;
subtype f_byte0 is integer range 7 downto 0;
 
signal CLK : slbit := '0';
signal CE_USEC : slbit := '0';
signal CE_MSEC : slbit := '0';
signal RESET : slbit := '0';
signal RL_DI : slv9 := (others=>'0');
signal RL_ENA : slbit := '0';
signal RL_BUSY : slbit := '0';
signal RL_DO : slv9 := (others=>'0');
signal RL_VAL : slbit := '0';
signal RL_HOLD : slbit := '0';
signal RB_MREQ_aval : slbit := '0';
signal RB_MREQ_re : slbit := '0';
signal RB_MREQ_we : slbit := '0';
signal RB_MREQ_initt: slbit := '0';
signal RB_MREQ_addr : slv16 := (others=>'0');
signal RB_MREQ_din : slv16 := (others=>'0');
signal RB_SRES_ack : slbit := '0';
signal RB_SRES_busy : slbit := '0';
signal RB_SRES_err : slbit := '0';
signal RB_SRES_dout : slv16 := (others=>'0');
signal RB_LAM_TBENCH : slv16 := (others=>'0');
signal RB_LAM_TESTER : slv16 := (others=>'0');
signal RB_LAM : slv16 := (others=>'0');
signal RB_STAT : slv4 := (others=>'0');
signal TXRXACT : slbit := '0';
 
signal RB_MREQ : rb_mreq_type := rb_mreq_init;
signal RB_SRES : rb_sres_type := rb_sres_init;
signal CLK_STOP : slbit := '0';
signal CLK_CYCLE : integer := 0;
 
constant rxlist_size : positive := 4096; -- size of rxlist
constant txlist_size : positive := 4096; -- size of txlist
constant datlist_size : positive := 2048; -- size of datlist
 
constant slv9_zero : slv9 := (others=>'0');
constant slv16_zero : slv16 := (others=>'0');
 
type rxlist_array_type is array (0 to rxlist_size-1) of slv9;
type txlist_array_type is array (0 to txlist_size-1) of slv9;
type datlist_array_type is array (0 to datlist_size-1) of slv16;
 
shared variable sv_rxlist : rxlist_array_type := (others=>slv9_zero);
shared variable sv_nrxlist : natural := 0;
shared variable sv_rxind : natural := 0;
 
constant clock_period : time := 20 ns;
constant clock_offset : time := 200 ns;
constant setup_time : time := 5 ns;
constant c2out_time : time := 10 ns;
 
component tbd_rlink_gen is -- rlink, generic tb design interface
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rlink ito time unit clock enable
CE_USEC : in slbit; -- 1 usec clock enable
RESET : in slbit; -- reset
RL_DI : in slv9; -- rlink: data in
RL_ENA : in slbit; -- rlink: data enable
RL_BUSY : out slbit; -- rlink: data busy
RL_DO : out slv9; -- rlink: data out
RL_VAL : out slbit; -- rlink: data valid
RL_HOLD : in slbit; -- rlink: data hold
RB_MREQ_aval : out slbit; -- rbus: request - aval
RB_MREQ_re : out slbit; -- rbus: request - re
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt: out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv16; -- rbus: request - addr
RB_MREQ_din : out slv16; -- rbus: request - din
RB_SRES_ack : in slbit; -- rbus: response - ack
RB_SRES_busy : in slbit; -- rbus: response - busy
RB_SRES_err : in slbit; -- rbus: response - err
RB_SRES_dout : in slv16; -- rbus: response - dout
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4; -- rbus: status flags
TXRXACT : out slbit -- txrx active flag
);
end component;
 
begin
 
CLKGEN : simclk
generic map (
PERIOD => clock_period,
OFFSET => clock_offset)
port map (
CLK => CLK,
CLK_STOP => CLK_STOP
);
 
CLKCNT : simclkcnt port map (CLK => CLK, CLK_CYCLE => CLK_CYCLE);
 
CLKDIV : clkdivce
generic map (
CDUWIDTH => 6,
USECDIV => 4,
MSECDIV => 5)
port map (
CLK => CLK,
CE_USEC => CE_USEC,
CE_MSEC => CE_MSEC
);
 
RB_MREQ.aval <= RB_MREQ_aval;
RB_MREQ.re <= RB_MREQ_re;
RB_MREQ.we <= RB_MREQ_we;
RB_MREQ.init <= RB_MREQ_initt;
RB_MREQ.addr <= RB_MREQ_addr;
RB_MREQ.din <= RB_MREQ_din;
 
RB_SRES_ack <= RB_SRES.ack;
RB_SRES_busy <= RB_SRES.busy;
RB_SRES_err <= RB_SRES.err;
RB_SRES_dout <= RB_SRES.dout;
 
RBTEST : rbd_tester
generic map (
RB_ADDR => slv(to_unsigned(16#ffe0#,16)))
port map (
CLK => CLK,
RESET => '0',
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES,
RB_LAM => RB_LAM_TESTER,
RB_STAT => RB_STAT
);
 
RB_LAM <= RB_LAM_TESTER or RB_LAM_TBENCH;
UUT : tbd_rlink_gen
port map (
CLK => CLK,
CE_INT => CE_MSEC,
CE_USEC => CE_USEC,
RESET => RESET,
RL_DI => RL_DI,
RL_ENA => RL_ENA,
RL_BUSY => RL_BUSY,
RL_DO => RL_DO,
RL_VAL => RL_VAL,
RL_HOLD => RL_HOLD,
RB_MREQ_aval => RB_MREQ_aval,
RB_MREQ_re => RB_MREQ_re,
RB_MREQ_we => RB_MREQ_we,
RB_MREQ_initt=> RB_MREQ_initt,
RB_MREQ_addr => RB_MREQ_addr,
RB_MREQ_din => RB_MREQ_din,
RB_SRES_ack => RB_SRES_ack,
RB_SRES_busy => RB_SRES_busy,
RB_SRES_err => RB_SRES_err,
RB_SRES_dout => RB_SRES_dout,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT,
TXRXACT => TXRXACT
);
 
proc_stim: process
file fstim : text open read_mode is "tb_rlink_stim";
variable iline : line;
variable oline : line;
variable ien : slbit := '0';
variable icmd : slv8 := (others=>'0');
variable iaddr : slv16 := (others=>'0');
variable icnt : slv16 := (others=>'0');
variable ibabo : slv8 := (others=>'0');
variable istat : slv8 := (others=>'0');
variable iattn : slv16 := (others=>'0');
variable idata : slv16 := (others=>'0');
variable idat8 : slv8 := (others=>'0');
variable ioof : slv9 := (others=>'0');
variable iblkval : slv16 := (others=>'0');
variable iblkmsk : slv16 := (others=>'0');
variable nblk : natural := 1;
variable ndone : natural := 1;
variable rxlabo : boolean := false;
variable ok : boolean;
variable dname : string(1 to 6) := (others=>' ');
variable idelta : integer := 0;
variable iowait : integer := 0;
variable txcrc,rxcrc : slv16 := (others=>'0');
variable txlist : txlist_array_type := (others=>slv9_zero);
variable ntxlist : natural := 0;
variable datlist : datlist_array_type := (others=>slv16_zero);
variable ndatlist : natural := 0;
-- read command line helpers ------------------------------------
procedure get_cmd_ea ( -- ---- get_cmd_ea -----------
L : inout line;
icmd : out slv8) is
variable cname : string(1 to 4) := (others=>' ');
variable ival : natural;
variable ok : boolean;
variable cmd : slv3;
variable dat : slv8;
begin
readword_ea(L, cname);
ival := 0;
readoptchar(L, ',', ok);
if ok then
readint_ea(L, ival, 0, 31);
end if;
case cname is
when "rreg" => cmd := c_rlink_cmd_rreg;
when "rblk" => cmd := c_rlink_cmd_rblk;
when "wreg" => cmd := c_rlink_cmd_wreg;
when "wblk" => cmd := c_rlink_cmd_wblk;
when "labo" => cmd := c_rlink_cmd_labo;
when "attn" => cmd := c_rlink_cmd_attn;
when "init" => cmd := c_rlink_cmd_init;
when others =>
report "unknown cmd code" severity failure;
end case;
dat := (others=>'0');
dat(c_rlink_cmd_rbf_seq) := slv(to_unsigned(ival,5));
dat(c_rlink_cmd_rbf_code) := cmd;
icmd := dat;
end procedure get_cmd_ea;
procedure get_seq_ea ( -- ---- get_seq_ea -----------
L : inout line;
code : in slv3;
icmd : out slv8) is
variable ival : natural;
variable dat : slv8;
begin
readint_ea(L, ival, 0, 31);
dat := (others=>'0');
dat(c_rlink_cmd_rbf_seq) := slv(to_unsigned(ival,5));
dat(c_rlink_cmd_rbf_code) := code;
icmd := dat;
end procedure get_seq_ea;
-- tx helpers ----------------------------------------------------
procedure do_tx9 (data : in slv9) is -- ---- do_tx9 -------------
begin
txlist(ntxlist) := data;
ntxlist := ntxlist + 1;
end procedure do_tx9;
procedure do_tx8 (data : in slv8) is -- ---- do_tx8 -------------
begin
do_tx9('0' & data);
txcrc := crc16_update_tbl(txcrc, data);
end procedure do_tx8;
procedure do_tx16 (data : in slv16) is -- ---- do_tx16 ----------
begin
do_tx8(data( f_byte0));
do_tx8(data(f_byte1));
end procedure do_tx16;
 
procedure do_txcrc is -- ---- do_txcrc -------------
begin
do_tx9('0' & txcrc(f_byte0));
do_tx9('0' & txcrc(f_byte1));
end procedure do_txcrc;
procedure do_txsop is -- ---- do_txsop -------------
begin
do_tx9(c_rlink_dat_sop);
txcrc := (others=>'0');
end procedure do_txsop;
 
procedure do_txeop is -- ---- do_txeop -------------
begin
do_tx9(c_rlink_dat_eop);
end procedure do_txeop;
procedure do_txc (icmd : in slv8) is -- ---- do_txc -------------
begin
do_tx8(icmd);
do_txcrc;
end procedure do_txc;
 
procedure do_txca ( -- ---- do_txca --------------
icmd : in slv8;
iaddr : in slv16) is
begin
do_tx8(icmd);
do_tx16(iaddr);
do_txcrc;
end procedure do_txca;
 
procedure do_txcad ( -- ---- do_txcad -------------
icmd : in slv8;
iaddr : in slv16;
idata : in slv16) is
begin
do_tx8(icmd);
do_tx16(iaddr);
do_tx16(idata);
do_txcrc;
end procedure do_txcad;
 
procedure do_txblks ( -- ---- do_txblks ------------
nblk : in natural;
start : in slv16) is
variable idata : slv16;
begin
idata := start;
for i in 1 to nblk loop
do_tx16(idata);
idata := slv(unsigned(idata) + 1);
end loop;
end procedure do_txblks;
 
-- rx helpers ----------------------------------------------------
procedure checkmiss_rx is -- ---- checkmiss_rx ---------
begin
if sv_rxind < sv_nrxlist then
for i in sv_rxind to sv_nrxlist-1 loop
writetimestamp(oline, CLK_CYCLE, ": moni ");
write(oline, string'(" FAIL MISSING DATA="));
write(oline, sv_rxlist(i)(d_f_cflag));
write(oline, string'(" "));
write(oline, sv_rxlist(i)(f_byte0));
writeline(output, oline);
end loop;
 
end if;
end procedure checkmiss_rx;
procedure do_rx9 (data : in slv9) is -- ---- do_rx9 -------------
begin
sv_rxlist(sv_nrxlist) := data;
sv_nrxlist := sv_nrxlist + 1;
end procedure do_rx9;
 
procedure do_rx8 (data : in slv8) is -- ---- do_rx8 -------------
begin
if not rxlabo then
do_rx9('0' & data);
rxcrc := crc16_update_tbl(rxcrc, data);
end if;
end procedure do_rx8;
 
procedure do_rx16 (data : in slv16) is -- ---- do_rx16 ----------
begin
do_rx8(data(f_byte0));
do_rx8(data(f_byte1));
end procedure do_rx16;
procedure do_rxattn is -- ---- do_rxattn ------------
begin
do_rx9(c_rlink_dat_attn);
rxcrc := (others=>'0');
end procedure do_rxattn;
 
procedure do_rxcrc is -- ---- do_rxcrc -------------
begin
if not rxlabo then
do_rx9('0' & rxcrc(f_byte0));
do_rx9('0' & rxcrc(f_byte1));
end if;
end procedure do_rxcrc;
procedure do_rxsop is -- ---- do_rxsop -------------
begin
checkmiss_rx;
sv_nrxlist := 0;
sv_rxind := 0;
rxcrc := (others=>'0');
do_rx9(c_rlink_dat_sop);
end procedure do_rxsop;
 
procedure do_rxeop is -- ---- do_rxeop -------------
begin
do_rx9(c_rlink_dat_eop);
end procedure do_rxeop;
 
procedure do_rxcs ( -- ---- do_rxcs ----------
icmd : in slv8;
istat : in slv8) is
begin
do_rx8(icmd);
do_rx8(istat);
do_rxcrc;
end procedure do_rxcs;
 
procedure do_rxcds ( -- ---- do_rxcds ----------
icmd : in slv8;
idata : in slv16;
istat : in slv8) is
begin
do_rx8(icmd);
do_rx16(idata);
do_rx8(istat);
do_rxcrc;
end procedure do_rxcds;
 
procedure do_rxcbs ( -- ---- do_rxcbs ----------
icmd : in slv8;
ibabo : in slv8;
istat : in slv8) is
begin
do_rx8(icmd);
do_rx8(ibabo);
do_rx8(istat);
do_rxcrc;
end procedure do_rxcbs;
 
procedure do_rxrbeg ( -- ---- do_rxrbeg -------------
icmd : in slv8;
nblk : in natural) is
begin
do_rx8(icmd);
do_rx16(slv(to_unsigned(nblk,16)));
end procedure do_rxrbeg;
 
procedure do_rxrend ( -- ---- do_rxrend -------------
nblk : in natural;
istat : in slv8) is
begin
do_rx16(slv(to_unsigned(nblk,16)));
do_rx8(istat);
do_rxcrc;
end procedure do_rxrend;
 
procedure do_rxblks ( -- ---- do_rxblks ------------
nblk : in natural;
start : in slv16) is
variable idata : slv16;
begin
idata := start;
for i in 1 to nblk loop
do_rx16(idata);
idata := slv(unsigned(idata) + 1);
end loop;
end procedure do_rxblks;
 
begin
 
SB_CNTL <= (others=>'0');
 
wait for clock_offset - setup_time;
 
file_loop: while not endfile(fstim) loop
 
readline (fstim, iline);
readcomment(iline, ok);
next file_loop when ok;
 
readword(iline, dname, ok);
if ok then
case dname is
when ".reset" => -- .reset
write(oline, string'(".reset"));
writeline(output, oline);
RESET <= '1';
wait for clock_period;
RESET <= '0';
wait for 9*clock_period;
 
when ".rlmon" => -- .rlmon
read_ea(iline, ien);
SB_CNTL(sbcntl_sbf_rlmon) <= ien;
wait for 2*clock_period; -- wait for monitor to start
 
when ".rlbmo" => -- .rlbmo
read_ea(iline, ien);
SB_CNTL(sbcntl_sbf_rlbmon) <= ien;
wait for 2*clock_period; -- wait for monitor to start
 
when ".rbmon" => -- .rbmon
read_ea(iline, ien);
SB_CNTL(sbcntl_sbf_rbmon) <= ien;
wait for 2*clock_period; -- wait for monitor to start
 
when ".wait " => -- .wait
read_ea(iline, idelta);
wait for idelta*clock_period;
when ".iowt " => -- .iowt
read_ea(iline, iowait);
idelta := iowait;
while idelta > 0 loop -- until time has expired
if TXRXACT = '1' then -- if any io activity
idelta := iowait; -- restart timer
else
idelta := idelta - 1; -- otherwise count down time
end if;
wait for clock_period;
end loop;
 
when ".attn " => -- .attn
read_ea(iline, iattn);
RB_LAM_TBENCH <= iattn; -- pulse attn lines
wait for clock_period; -- for 1 clock
RB_LAM_TBENCH <= (others=>'0');
 
when "txsop " => -- txsop send sop
do_txsop;
when "txeop " => -- txeop send eop
do_txeop;
 
when "txnak " => -- txnak send nak
do_tx9(c_rlink_dat_nak);
when "txattn" => -- txattn send attn
do_tx9(c_rlink_dat_attn);
 
when "tx8 " => -- tx8 send 8 bit value
readgen_ea(iline, idat8, 2);
do_tx8(idat8);
when "tx16 " => -- tx16 send 16 bit value
readgen_ea(iline, idata, 2);
do_tx16(idata);
 
when "txblk " => -- txblk send n 16 bit values
read_ea(iline, nblk);
readgen_ea(iline, idata, 2);
do_txblks(nblk, idata);
when "txcrc " => -- txcrc send crc
do_txcrc;
when "txbad " => -- txbad send bad crc
do_tx9('0' & (not txcrc(f_byte0)));
do_tx9('0' & (not txcrc(f_byte1)));
 
when "txc " => -- txc send: cmd crc
get_cmd_ea(iline, icmd);
do_txc(icmd);
 
when "txca " => -- txc send: cmd addr crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, iaddr, 2);
do_txca(icmd, iaddr);
 
when "txcad " => -- txc send: cmd addr data crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, iaddr, 2);
readgen_ea(iline, idata, 2);
do_txcad(icmd, iaddr, idata);
 
when "txcac " => -- txc send: cmd addr cnt crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, iaddr, 2);
readgen_ea(iline, icnt, 2);
do_txcad(icmd, iaddr, icnt);
 
when "txoof " => -- txoof send out-of-frame symbol
readgen_ea(iline, txlist(0), 2);
ntxlist := 1;
when "rxsop " => -- rxsop expect sop
do_rxsop;
when "rxeop " => -- rxeop expect eop
do_rxeop;
when "rxnak " => -- rxnak expect nak
do_rx9(c_rlink_dat_nak);
when "rxattn" => -- rxattn expect attn
do_rxattn;
 
when "rx8 " => -- rx8 expect 8 bit value
readgen_ea(iline, idat8, 2);
do_rx8(idat8);
when "rx16 " => -- rx16 expect 16 bit value
readgen_ea(iline, idata, 2);
do_rx16(idata);
 
when "rxblk " => -- rxblk expect n 16 bit values
read_ea(iline, nblk);
readgen_ea(iline, idata, 2);
do_rxblks(nblk, idata);
 
when "rxcrc " => -- rxcrc expect crc
do_rxcrc;
 
when "rxcs " => -- rxcs expect: cmd stat crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, istat, 2);
do_rxcs(icmd, istat);
 
when "rxcds " => -- rxcsd expect: cmd data stat crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, idata, 2);
readgen_ea(iline, istat, 2);
do_rxcds(icmd, idata, istat);
 
when "rxcbs " => -- rxcsd expect: cmd babo stat crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, ibabo, 2);
readgen_ea(iline, istat, 2);
do_rxcbs(icmd, ibabo, istat);
 
when "rxrbeg" => -- rxrbeg expect: cmd - cl ch
get_cmd_ea(iline, icmd);
read_ea(iline, nblk);
do_rxrbeg(icmd, nblk);
 
when "rxrend" => -- rxrend expect: dcl dch - stat - crc
read_ea(iline, nblk);
readgen_ea(iline, istat, 2);
do_rxrend(nblk, istat);
when "rxoof " => -- rxoof expect: out-of-frame symbol
readgen_ea(iline, ioof, 2);
sv_rxlist(sv_nrxlist) := ioof;
sv_nrxlist := sv_nrxlist + 1;
 
when "anmsg " => -- anmsg
readgen_ea(iline, idata, 2); -- apat
do_rxattn;
do_rx16(idata);
do_rxcrc;
do_rxeop;
when "sop " => -- sop
do_rxsop;
do_txsop;
rxlabo := false;
when "eop " => -- eop
do_rxeop;
do_txeop;
 
when "rreg " => -- rreg seq addr data stat
get_seq_ea(iline, c_rlink_cmd_rreg, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
readgen_ea(iline, idata, 2); -- data
readgen_ea(iline, istat, 2); -- stat
do_rxcds(icmd, idata, istat); -- rx: cmd dl sh stat ccsr
do_txca (icmd, iaddr); -- tx: cmd al ah ccsr
when "wreg " => -- wreg seq addr data stat
get_seq_ea(iline, c_rlink_cmd_wreg, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
readgen_ea(iline, idata, 2); -- data
readgen_ea(iline, istat, 2); -- stat
do_rxcs (icmd, istat); -- rx: cmd stat ccsr
do_txcad(icmd, iaddr, idata); -- tx: cmd al ah dl dh ccsr
 
when "init " => -- init seq addr data stat
get_seq_ea(iline, c_rlink_cmd_init, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
readgen_ea(iline, idata, 2); -- data
readgen_ea(iline, istat, 2); -- stat
do_rxcs (icmd, istat); -- rx: cmd stat ccsr
do_txcad(icmd, iaddr, idata); -- tx: cmd al ah dl dh ccsr
 
when "attn " => -- attn seq data stat
get_seq_ea(iline, c_rlink_cmd_attn, icmd); -- seq
readgen_ea(iline, idata, 2); -- data
readgen_ea(iline, istat, 2); -- stat
do_rxcds (icmd, idata, istat); -- rx: cmd dl dh stat ccsr
do_txc (icmd); -- tx: cmd ccsr
 
when "labo " => -- labo seq babo stat
get_seq_ea(iline, c_rlink_cmd_labo, icmd); -- seq
readgen_ea(iline, ibabo, 2); -- babo
readgen_ea(iline, istat, 2); -- stat
do_rxcbs (icmd, ibabo, istat); -- rx: cmd dl stat ccsr
do_txc (icmd); -- tx: cmd ccsr
rxlabo := ibabo /= x"00"; -- set rxlabo flag
when "rblks " => -- rblks seq addr nblk data stat
get_seq_ea(iline, c_rlink_cmd_rblk, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
read_ea(iline, nblk); -- nblk
readgen_ea(iline, idata, 2); -- start
readgen_ea(iline, istat, 2); -- stat
do_rxrbeg(icmd, nblk); --rx: cmd cl ch
do_rxblks(nblk, idata); -- nblk*(dl dh)
do_rxrend(nblk, istat); -- dcl dch stat ccrc
do_txcad(icmd, iaddr, -- tx: cmd al ah cl ch ccrc
slv(to_unsigned(nblk,16)));
when "wblks " => -- wblks seq addr nblk data stat
get_seq_ea(iline, c_rlink_cmd_wblk, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
read_ea(iline, nblk); -- nblk
readgen_ea(iline, idata, 2); -- start
readgen_ea(iline, istat, 2); -- stat
do_rxcds(icmd, -- rx: cmd dcl dch stat ccsr
slv(to_unsigned(nblk,16)),
istat);
do_txcad(icmd, iaddr, -- tx: cmd al ah cl ch ccrc
slv(to_unsigned(nblk,16)));
do_txblks(nblk, idata); -- nblk*(dl dh)
do_txcrc; -- dcrc
when "rblkd " => -- rblkd seq addr ndone stat
get_seq_ea(iline, c_rlink_cmd_rblk, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
read_ea(iline, ndone); -- ndone
readgen_ea(iline, istat, 2); -- stat
do_rxrbeg(icmd, ndatlist); --rx: cmd cl ch
for i in 0 to ndatlist-1 loop
do_rx16(datlist(i)); -- nblk*(dl dh)
end loop; -- i
do_rxrend(ndone, istat); -- dcl dch stat ccrc
do_txcad(icmd, iaddr, -- tx: cmd al ah cl ch ccrc
slv(to_unsigned(ndatlist,16)));
when "wblkd " => -- wblkd seq addr ndone stat
get_seq_ea(iline, c_rlink_cmd_wblk, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
read_ea(iline, ndone); -- ndone
readgen_ea(iline, istat, 2); -- stat
do_rxcds(icmd, -- rx: cmd dcl dch stat ccsr
slv(to_unsigned(ndone,16)),
istat);
do_txcad(icmd, iaddr, -- tx: cmd al ah cl ch ccrc
slv(to_unsigned(ndatlist,16)));
for i in 0 to ndatlist-1 loop
do_tx16(datlist(i)); -- nblk*(dl dh)
end loop; -- i
do_txcrc; -- dcrc
when ".dclr " => -- .dclr
ndatlist := 0;
 
when ".dwrd " => -- .dwrd data
readgen_ea(iline, idata, 2);
datlist(ndatlist) := idata;
ndatlist := ndatlist + 1;
 
when ".dseq " => -- .dseq nblk start
read_ea(iline, nblk);
readgen_ea(iline, idata, 2);
for i in 1 to nblk loop
datlist(ndatlist) := idata;
ndatlist := ndatlist + 1;
idata := slv(unsigned(idata) + 1);
end loop;
 
when others => -- bad command
write(oline, string'("?? unknown command: "));
write(oline, dname);
writeline(output, oline);
report "aborting" severity failure;
end case;
 
else
report "failed to find command" severity failure;
end if;
 
testempty_ea(iline);
next file_loop when ntxlist=0;
for i in 0 to ntxlist-1 loop
RL_DI <= txlist(i);
RL_ENA <= '1';
 
writetimestamp(oline, CLK_CYCLE, ": stim");
write(oline, txlist(i)(d_f_cflag), right, 3);
write(oline, txlist(i)(d_f_data), right, 9);
if txlist(i)(d_f_cflag) = '1' then
case txlist(i) is
when c_rlink_dat_sop =>
write(oline, string'(" (sop) "));
when c_rlink_dat_eop =>
write(oline, string'(" (eop) "));
when c_rlink_dat_nak =>
write(oline, string'(" (nak) "));
when c_rlink_dat_attn =>
write(oline, string'(" (attn)"));
when others =>
write(oline, string'(" (????)"));
end case;
end if;
writeline(output, oline);
wait for clock_period;
while RL_BUSY = '1' loop
wait for clock_period;
end loop;
RL_ENA <= '0';
end loop; -- i
 
ntxlist := 0;
end loop; -- file fstim
 
wait for 50*clock_period;
 
checkmiss_rx;
writetimestamp(oline, CLK_CYCLE, ": DONE ");
writeline(output, oline);
 
CLK_STOP <= '1';
 
wait; -- suspend proc_stim forever
-- clock is stopped, sim will end
 
end process proc_stim;
 
proc_moni: process
variable oline : line;
begin
 
loop
wait until rising_edge(CLK);
wait for c2out_time;
 
if RL_VAL = '1' then
writetimestamp(oline, CLK_CYCLE, ": moni");
write(oline, RL_DO(d_f_cflag), right, 3);
write(oline, RL_DO(d_f_data), right, 9);
if RL_DO(d_f_cflag) = '1' then
case RL_DO is
when c_rlink_dat_sop =>
write(oline, string'(" (sop) "));
when c_rlink_dat_eop =>
write(oline, string'(" (eop) "));
when c_rlink_dat_nak =>
write(oline, string'(" (nak) "));
when c_rlink_dat_attn =>
write(oline, string'(" (attn)"));
when others =>
write(oline, string'(" (????)"));
end case;
end if;
if sv_nrxlist > 0 then
write(oline, string'(" CHECK"));
if sv_rxind < sv_nrxlist then
if RL_DO = sv_rxlist(sv_rxind) then
write(oline, string'(" OK"));
else
write(oline, string'(" FAIL, exp="));
write(oline, sv_rxlist(sv_rxind)(d_f_cflag), right, 2);
write(oline, sv_rxlist(sv_rxind)(d_f_data), right, 9);
end if;
sv_rxind := sv_rxind + 1;
else
write(oline, string'(" FAIL, UNEXPECTED"));
end if;
end if;
writeline(output, oline);
end if;
end loop;
end process proc_moni;
 
end sim;
/tb/tb_rlink_sp1c_stim.dat
0,0 → 1,62
# $Id: tb_rlink_sp1c_stim.dat 593 2014-09-14 22:21:33Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2014-09-07 593 4.0 adopt for new comma encoding, use higl level cmds
# 2014-08-15 583 3.5 rb_mreq addr now 16 bit
# 2011-12-22 442 1.1 remove RTS tests (now obsolete)
# 2010-12-29 351 1.0.1 use new rbd_tester addr 111100xx (from 111101xx)
# 2010-12-26 348 1.0 Initial version (Test 3 from tb_rlink_stim.dat)
#
#---------------------------------------
# rbus address mapping
# ffe0 rbd_tester cntl
# ffe1 rbd_tester stat
# ffe2 rbd_tester attn
# ffe3 rbd_tester ncyc
# ffe4 rbd_tester data
# ffe5 rbd_tester dinc
# ffe6 rbd_tester fifo
# ffe7 rbd_tester lnak
#
.rlmon 1
.rlbmo 1
.rbmon 1
#
C -----------------------------------------------------------------------------
C Test 1: wreg,rreg to data
#
sop
wreg 0 x"ffe4" x"aaaa" 00000000 -- data := aaaa
rreg 1 x"ffe4" x"aaaa" 00000000 -- data >? aaaa
eop
.iowt 10
#
C -----------------------------------------------------------------------------
C Test 2: Test comma escapes with fifo
C Assumes c_cdata_escape = "11000011" = x"C3"
#
sop
wreg 0 x"ffe6" x"4321" 00000000 -- fifo := 4321
wreg 0 x"ffe6" x"c321" 00000000 -- fifo := c321
wreg 0 x"ffe6" x"43c3" 00000000 -- fifo := 43c3
wreg 0 x"ffe6" x"c3c3" 00000000 -- fifo := c3c3
wreg 0 x"ffe6" x"1234" 00000000 -- fifo := 1234
eop
.iowt 10
#
sop
rreg 1 x"ffe6" x"4321" 00000000 -- fifo >? 4321
rreg 1 x"ffe6" x"c321" 00000000 -- fifo >? c321
rreg 1 x"ffe6" x"43c3" 00000000 -- fifo >? 43c3
rreg 1 x"ffe6" x"c3c3" 00000000 -- fifo >? c3c3
rreg 1 x"ffe6" x"1234" 00000000 -- fifo >? 1234
eop
.iowt 10
#
#==============================================================================
#
C -----------------------------------------------------------------------------
C Run down and Finish
.iowt 10
.wait 100
/tb/tb_rlink.vbom
0,0 → 1,22
# Not meant for direct top level usage. Used with
# tb_rlink_(direct|serport|...)[_ssim].vbom and config
# lines to generate the different cases.
#
# libs
../../slvtypes.vhd
../../genlib/genlib.vhd
../../comlib/comlib.vhd
../../rbus/rblib.vhd
../../rbus/rbdlib.vhd
../rlinklib.vbom
../../simlib/simlib.vhd
../../simlib/simbus.vhd
# components
../../simlib/simclk.vbom
../../simlib/simclkcnt.vbom
../../genlib/clkdivce.vbom
../../rbus/rbd_tester.vbom
${tbd_rlink_gen := tbd_rlink_direct.vbom}
# design
tb_rlink.vhd
@top:tb_rlink
/tb/rlinktblib.vhd
0,0 → 1,164
-- $Id: rlinktblib.vhd 595 2014-09-28 08:47:45Z mueller $
--
-- Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Package Name: rlinktblib
-- Description: rlink test environment components
--
-- Dependencies: -
-- Tool versions: xst 8.2-14.7; ghdl 0.18-0.31
-- Revision History:
-- Date Rev Version Comment
-- 2014-08-28 588 4.0 now full rlink v4 iface and 4 bit STAT
-- 2014-08-15 583 3.5 rb_mreq addr now 16 bit
-- 2011-12-23 444 3.1 new clock iface for tbcore_rlink; drop .._dcm
-- 2010-12-29 351 3.0.1 add rbtba_aif;
-- 2010-12-24 347 3.0 rename rritblib->rlinktblib, CP_*->RL_*;
-- many rri->rlink renames; drop rbus parts;
-- 2010-11-13 338 2.5.2 add rritb_core_dcm
-- 2010-06-26 309 2.5.1 add rritb_sres_or_mon
-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining
-- 2010-06-05 301 2.1.2 renamed _rpmon -> _rbmon
-- 2010-05-02 287 2.1.1 rename CE_XSEC->CE_INT,RP_STAT->RB_STAT
-- drop RP_IINT signal from interfaces
-- add sbcntl_sbf_(cp|rp)mon defs
-- 2010-04-24 282 2.1 add rritb_core
-- 2008-08-24 162 2.0 all with new rb_mreq/rb_sres interface
-- 2008-03-24 129 1.1.5 CLK_CYCLE now 31 bits
-- 2007-12-23 105 1.1.4 add AP_LAM for rritb_rpmon(_sb)
-- 2007-11-24 98 1.1.3 add RP_IINT for rritb_rpmon(_sb)
-- 2007-09-01 78 1.1.2 add rricp_rp
-- 2007-08-25 75 1.1.1 add rritb_cpmon_sb, rritb_rpmon_sb
-- 2007-08-16 74 1.1 remove rritb_tt* component; some interface changes
-- 2007-08-03 71 1.0.2 use rrirp_acif; change generics for rritb_[cr]pmon
-- 2007-07-22 68 1.0.1 add rritb_cpmon rritb_rpmon monitors
-- 2007-07-15 66 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
use work.slvtypes.all;
use work.rlinklib.all;
 
package rlinktblib is
 
type rlink_tba_cntl_type is record -- rlink_tba control
cmd : slv3; -- command code
ena : slbit; -- command enable
addr : slv16; -- address
cnt : slv16; -- block size
eop : slbit; -- end packet after current command
end record rlink_tba_cntl_type;
 
constant rlink_tba_cntl_init : rlink_tba_cntl_type := (
(others=>'0'), -- cmd
'0', -- ena
(others=>'0'), -- addr
(others=>'0'), -- cnt
'0'); -- eop
type rlink_tba_stat_type is record -- rlink_tba status
busy : slbit; -- command busy
ack : slbit; -- command acknowledge
err : slbit; -- command error flag
stat : slv8; -- status flags
braddr : slv16; -- block read address (for wblk)
bre : slbit; -- block read enable (for wblk)
bwaddr : slv16; -- block write address (for rblk)
bwe : slbit; -- block write enable (for rblk)
dcnt : slv16; -- block done count
apend : slbit; -- attn pending (from stat)
ano : slbit; -- attn notify seen
apat : slv16; -- attn pattern
end record rlink_tba_stat_type;
 
constant rlink_tba_stat_init : rlink_tba_stat_type := (
'0','0','0', -- busy, ack, err
(others=>'0'), -- stat
(others=>'0'), -- braddr
'0', -- bre
(others=>'0'), -- bwaddr
'0', -- bwe
(others=>'0'), -- dcnt
'0','0', -- apend, ano
(others=>'0') -- apat
);
 
component rlink_tba is -- rlink test bench adapter
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
CNTL : in rlink_tba_cntl_type; -- control port
DI : in slv16; -- input data
STAT : out rlink_tba_stat_type; -- status port
DO : out slv16; -- output data
RL_DI : out slv9; -- rlink: data in
RL_ENA : out slbit; -- rlink: data enable
RL_BUSY : in slbit; -- rlink: data busy
RL_DO : in slv9; -- rlink: data out
RL_VAL : in slbit; -- rlink: data valid
RL_HOLD : out slbit -- rlink: data hold
);
end component;
 
component rbtba_aif is -- rbus tba, abstract interface
-- no generics, no records
port (
CLK : in slbit; -- clock
RESET : in slbit := '0'; -- reset
RB_MREQ_aval : in slbit; -- rbus: request - aval
RB_MREQ_re : in slbit; -- rbus: request - re
RB_MREQ_we : in slbit; -- rbus: request - we
RB_MREQ_initt : in slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : in slv16; -- rbus: request - addr
RB_MREQ_din : in slv16; -- rbus: request - din
RB_SRES_ack : out slbit; -- rbus: response - ack
RB_SRES_busy : out slbit; -- rbus: response - busy
RB_SRES_err : out slbit; -- rbus: response - err
RB_SRES_dout : out slv16; -- rbus: response - dout
RB_LAM : out slv16; -- rbus: look at me
RB_STAT : out slv4 -- rbus: status flags
);
end component;
 
component tbcore_rlink is -- core of vhpi_cext based test bench
port (
CLK : in slbit; -- control interface clock
CLK_STOP : out slbit; -- clock stop trigger
RX_DATA : out slv8; -- read data (data ext->tb)
RX_VAL : out slbit; -- read data valid (data ext->tb)
RX_HOLD : in slbit; -- read data hold (data ext->tb)
TX_DATA : in slv8; -- write data (data tb->ext)
TX_ENA : in slbit -- write data enable (data tb->ext)
);
end component;
 
-- FIXME after this point !!
 
component rricp_rp is -- rri comm->reg port aif forwarder
-- implements rricp_aif, uses rrirp_aif
port (
CLK : in slbit; -- clock
CE_INT : in slbit := '0'; -- rri ito time unit clock enable
RESET : in slbit :='0'; -- reset
RL_DI : in slv9; -- rlink: data in
RL_ENA : in slbit; -- rlink: data enable
RL_BUSY : out slbit; -- rlink: data busy
RL_DO : out slv9; -- rlink: data out
RL_VAL : out slbit; -- rlink: data valid
RL_HOLD : in slbit := '0' -- rlink: data hold
);
end component;
 
end package rlinktblib;
/tb/tbd_rlink_sp1c.vhd
0,0 → 1,253
-- $Id: tbd_rlink_sp1c.vhd 596 2014-10-17 19:50:07Z mueller $
--
-- Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: tbd_rlink_sp1c - syn
-- Description: Wrapper for rlink_core plus rlink_serport with an interface
-- compatible to the rlink_core only module.
-- NOTE: this implementation is a hack, should be redone
-- using configurations.
--
-- Dependencies: tbu_rlink_sp1c [UUT]
-- serport_uart_tx
-- serport_uart_rx
-- byte2cdata
-- cdata2byte
-- simlib/simclkcnt
--
-- To test: rlink_sp1c
--
-- Target Devices: generic
-- Tool versions: xst 8.2-14.7; ghdl 0.18-0.31
--
-- Revision History:
-- Date Rev Version Comment
-- 2014-08-28 588 4.0 use new rlink v4 iface and 4 bit STAT
-- 2011-12-23 444 3.2 use simclkcnt instead of simbus global
-- 2011-12-22 442 3.1 renamed and retargeted to tbu_rlink_sp1c
-- 2011-11-19 427 3.0.5 now numeric_std clean
-- 2010-12-28 350 3.0.4 use CLKDIV/CDINIT=0;
-- 2010-12-26 348 3.0.3 add RTS/CTS ports for tbu_;
-- 2010-12-24 347 3.0.2 rename: CP_*->RL->*
-- 2010-12-22 346 3.0.1 removed proc_moni, use .rlmon cmd in test bench
-- 2010-12-05 343 3.0 rri->rlink renames; port to rbus V3 protocol;
-- 2010-06-06 301 2.3 use NCOMM=4 (new eop,nak commas)
-- 2010-05-02 287 2.2.2 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM
-- drop RP_IINT signal from interfaces
-- 2010-04-24 281 2.2.1 use serport_uart_[tr]x directly again
-- 2010-04-03 274 2.2 add CE_USEC
-- 2009-03-14 197 2.1 remove records in interface to allow _ssim usage
-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface
-- 2007-11-25 98 1.1 added RP_IINT support; use entity rather arch
-- name to switch core/serport;
-- use serport_uart_[tr]x_tb to allow that UUT is a
-- [sft]sim model compiled with keep hierarchy
-- 2007-07-02 63 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.rlinklib.all;
use work.comlib.all;
use work.serportlib.all;
use work.simlib.all;
use work.simbus.all;
 
entity tbd_rlink_sp1c is -- rlink_sp1c tb design
-- implements tbd_rlink_gen
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rlink ito time unit clock enable
CE_USEC : in slbit; -- 1 usec clock enable
RESET : in slbit; -- reset
RL_DI : in slv9; -- rlink: data in
RL_ENA : in slbit; -- rlink: data enable
RL_BUSY : out slbit; -- rlink: data busy
RL_DO : out slv9; -- rlink: data out
RL_VAL : out slbit; -- rlink: data valid
RL_HOLD : in slbit; -- rlink: data hold
RB_MREQ_aval : out slbit; -- rbus: request - aval
RB_MREQ_re : out slbit; -- rbus: request - re
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt : out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv16; -- rbus: request - addr
RB_MREQ_din : out slv16; -- rbus: request - din
RB_SRES_ack : in slbit; -- rbus: response - ack
RB_SRES_busy : in slbit; -- rbus: response - busy
RB_SRES_err : in slbit; -- rbus: response - err
RB_SRES_dout : in slv16; -- rbus: response - dout
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4; -- rbus: status flags
TXRXACT : out slbit -- txrx active flag
);
end entity tbd_rlink_sp1c;
 
 
architecture syn of tbd_rlink_sp1c is
constant CDWIDTH : positive := 13;
constant c_cdinit : natural := 0; -- NOTE: change in tbu_rlink_sp1c !!
 
signal RRI_RXSD : slbit := '0';
signal RRI_TXSD : slbit := '0';
signal RTS_N : slbit := '0';
signal RXDATA : slv8 := (others=>'0');
signal RXVAL : slbit := '0';
signal RXACT : slbit := '0';
signal TXDATA : slv8 := (others=>'0');
signal TXENA : slbit := '0';
signal TXBUSY : slbit := '0';
signal CLKDIV : slv13 := slv(to_unsigned(c_cdinit,CDWIDTH));
signal CLK_CYCLE : integer := 0;
 
component tbu_rlink_sp1c is -- rlink core+serport combo
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rlink ito time unit clock enable
CE_USEC : in slbit; -- 1 usec clock enable
CE_MSEC : in slbit; -- 1 msec clock enable
RESET : in slbit; -- reset
RXSD : in slbit; -- receive serial data (board view)
TXSD : out slbit; -- transmit serial data (board view)
CTS_N : in slbit; -- clear to send (act.low, board view)
RTS_N : out slbit; -- request to send (act.low, board view)
RB_MREQ_aval : out slbit; -- rbus: request - aval
RB_MREQ_re : out slbit; -- rbus: request - re
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt : out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv16; -- rbus: request - addr
RB_MREQ_din : out slv16; -- rbus: request - din
RB_SRES_ack : in slbit; -- rbus: response - ack
RB_SRES_busy : in slbit; -- rbus: response - busy
RB_SRES_err : in slbit; -- rbus: response - err
RB_SRES_dout : in slv16; -- rbus: response - dout
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4 -- rbus: status flags
);
end component;
 
begin
 
TBU : tbu_rlink_sp1c
port map (
CLK => CLK,
CE_INT => CE_INT,
CE_USEC => CE_USEC,
CE_MSEC => '1',
RESET => RESET,
RXSD => RRI_RXSD,
TXSD => RRI_TXSD,
CTS_N => '0',
RTS_N => RTS_N,
RB_MREQ_aval => RB_MREQ_aval,
RB_MREQ_re => RB_MREQ_re,
RB_MREQ_we => RB_MREQ_we,
RB_MREQ_initt=> RB_MREQ_initt,
RB_MREQ_addr => RB_MREQ_addr,
RB_MREQ_din => RB_MREQ_din,
RB_SRES_ack => RB_SRES_ack,
RB_SRES_busy => RB_SRES_busy,
RB_SRES_err => RB_SRES_err,
RB_SRES_dout => RB_SRES_dout,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT
);
 
UARTRX : serport_uart_rx
generic map (
CDWIDTH => CDWIDTH)
port map (
CLK => CLK,
RESET => RESET,
CLKDIV => CLKDIV,
RXSD => RRI_TXSD,
RXDATA => RXDATA,
RXVAL => RXVAL,
RXERR => open,
RXACT => RXACT
);
 
UARTTX : serport_uart_tx
generic map (
CDWIDTH => CDWIDTH)
port map (
CLK => CLK,
RESET => RESET,
CLKDIV => CLKDIV,
TXSD => RRI_RXSD,
TXDATA => TXDATA,
TXENA => TXENA,
TXBUSY => TXBUSY
);
 
TXRXACT <= RXACT or TXBUSY;
B2CD : byte2cdata -- byte stream -> 9bit comma,data
port map (
CLK => CLK,
RESET => RESET,
DI => RXDATA,
ENA => RXVAL,
ERR => '0',
BUSY => open,
DO => RL_DO,
VAL => RL_VAL,
HOLD => RL_HOLD
);
 
CD2B : cdata2byte -- 9bit comma,data -> byte stream
port map (
CLK => CLK,
RESET => RESET,
ESCXON => '0',
ESCFILL => '0',
DI => RL_DI,
ENA => RL_ENA,
BUSY => RL_BUSY,
DO => TXDATA,
VAL => TXENA,
HOLD => TXBUSY
);
CLKCNT : simclkcnt port map (CLK => CLK, CLK_CYCLE => CLK_CYCLE);
 
proc_moni: process
variable oline : line;
variable rts_last : slbit := '0';
variable ncycle : integer := 0;
begin
loop
wait until rising_edge(CLK); -- check at end of clock cycle
if RTS_N /= rts_last then
writetimestamp(oline, CLK_CYCLE, ": rts ");
write(oline, string'(" RTS_N "));
write(oline, rts_last, right, 1);
write(oline, string'(" -> "));
write(oline, RTS_N, right, 1);
write(oline, string'(" after "));
write(oline, ncycle, right, 5);
write(oline, string'(" cycles"));
writeline(output, oline);
rts_last := RTS_N;
ncycle := 0;
end if;
ncycle := ncycle + 1;
end loop;
end process proc_moni;
 
end syn;
/tb/tbd_rlink_sp1c.vbom
0,0 → 1,17
# libs
../../slvtypes.vhd
../../comlib/comlib.vhd
../../serport/serportlib.vbom
../../rbus/rblib.vhd
../rlinklib.vbom
../../simlib/simlib.vhd
../../simlib/simbus.vhd
# components
${tbu_rlink_sp1c := tbu_rlink_sp1c.vbom}
../../serport/serport_uart_tx.vbom
../../serport/serport_uart_rx.vbom
../../comlib/byte2cdata.vbom
../../comlib/cdata2byte.vbom
../../simlib/simclkcnt.vbom
# design
tbd_rlink_sp1c.vhd
/tb/tbcore_rlink.vbom
0,0 → 1,14
# libs
../../slvtypes.vhd
../../simlib/simlib.vhd
../../simlib/simbus.vhd
../../rbus/rblib.vhd
../rlinklib.vbom
rlinktblib.vhd
rlink_cext_vhpi.vhd
# components
../../simlib/simclkcnt.vbom
# vhpi
rlink_cext.c
# design
tbcore_rlink.vhd
/tb/tbu_rlink_sp1c.vbom
0,0 → 1,8
# libs
../../slvtypes.vhd
../../rbus/rblib.vhd
../rlinklib.vbom
# components
../rlink_sp1c.vbom
# design
tbu_rlink_sp1c.vhd
/tb/tb_rlink_sp1c_ssim.vbom
0,0 → 1,5
# configure tb_rlink with tbd_rlink_sp1c wrapper; _*sim case
tbd_rlink_gen = tbd_rlink_sp1c.vbom
tbu_rlink_sp1c = tbu_rlink_sp1c_ssim.vhd
tb_rlink_sp1c.vbom
@top:tb_rlink_sp1c
/tb/tb_rlink_sp1c.vbom
0,0 → 1,6
# configure tb_rlink with tbd_rlink_sp1c wrapper;
# use vhdl configure file (tb_rlink_sp1c.vhd) to allow
# that all configurations will co-exist in work library
tbd_rlink_gen = tbd_rlink_sp1c.vbom
tb_rlink.vbom
tb_rlink_sp1c.vhd
/tb/tbw.dat
0,0 → 1,10
# $Id: tbw.dat 442 2011-12-23 10:03:28Z mueller $
#
[tb_rlink_direct]
tb_rlink_stim = tb_rlink_stim.dat
[tb_rlink_sp1c]
tb_rlink_stim = tb_rlink_stim.dat
[tb_rlink_tba_ttcombo]
tb_rlink_tba_stim = tb_rlink_tba_ttcombo_stim.dat
[tb_rlink_tba_eyemon]
tb_rlink_tba_stim = tb_rlink_tba_eyemon_stim.dat
/tb/tb_rlink_sp1c.vhd
0,0 → 1,45
-- $Id: tb_rlink_sp1c.vhd 442 2011-12-23 10:03:28Z mueller $
--
-- Copyright 2007-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: tb_rlink_sp1c
-- Description: Configuration for tb_rlink_sp1c for tb_rlink.
--
-- Dependencies: tbd_rlink_gen
--
-- To test: rlink_sp1c
--
-- Target Devices: generic
--
-- Verified (with tb_rlink_stim.dat):
-- Date Rev Code ghdl ise Target Comment
-- 2007-10-12 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok (Test 15 fails)
-- 2007-10-12 88 - 0.26 - - c:ok (Test 15 fails)
--
-- Revision History:
-- Date Rev Version Comment
-- 2011-12-22 442 3.2 renamed and retargeted to tbd_rlink_sp1c
-- 2010-12-05 343 3.0 rri->rlink renames
-- 2007-11-25 98 1.0.1 use entity rather arch name to switch core/serport
-- 2007-07-08 65 1.0 Initial version
------------------------------------------------------------------------------
 
configuration tb_rlink_sp1c of tb_rlink is
 
for sim
for all : tbd_rlink_gen
use entity work.tbd_rlink_sp1c;
end for;
end for;
 
end tb_rlink_sp1c;
/tb/.cvsignore
0,0 → 1,18
tb_rlink_stim
tb_rlink_direct
tb_rlink_direct_[sft]sim
tb_rlink_direct_ISim
tb_rlink_direct_ISim_[sft]sim
tb_rlink_sp1c
tb_rlink_sp1c_[sft]sim
tb_rlink_sp1c_ISim
tb_rlink_sp1c_ISim_[sft]sim
tb_rlink_tba_stim
tb_rlink_tba_ttcombo
tb_rlink_tba_ttcombo_[sft]sim
tb_rlink_tba_ttcombo_ISim
tb_rlink_tba_ttcombo_ISim_[sft]sim
tb_rlink_tba_eyemon
tb_rlink_tba_eyemon_[sft]sim
tb_rlink_tba_eyemon_ISim
tb_rlink_tba_eyemon_ISim_[sft]sim
/tb/tb_rlink_direct_ssim.vbom
0,0 → 1,4
# configure tb_rlink with tbd_rlink_direct wrapper; _*sim case
tbd_rlink_gen = tbd_rlink_direct_ssim.vhd
tb_rlink_direct.vbom
@top : tb_rlink_direct
/tb/tb_rlink_direct.vbom
0,0 → 1,6
# configure tb_rlink with tbd_rlink_direct wrapper
# use vhdl configure file (tb_rlink_direct.vhd) at allow
# that all configurations will co-exist in work library
tbd_rlink_gen = tbd_rlink_direct.vbom
tb_rlink.vbom
tb_rlink_direct.vhd
/tb/tbd_rlink_direct.vbom
0,0 → 1,8
# libs
../../slvtypes.vhd
../../rbus/rblib.vhd
../rlinklib.vbom
# components
../rlink_core.vbom
# design
tbd_rlink_direct.vhd
/tb/tb_rlink_direct.vhd
0,0 → 1,44
-- $Id: tb_rlink_direct.vhd 343 2010-12-05 21:24:38Z mueller $
--
-- Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: tb_rlink_direct
-- Description: Configuration for tb_rlink_direct for tb_rlink.
--
-- Dependencies: tbd_rlink_gen
--
-- To test: rlink_core
--
-- Target Devices: generic
--
-- Verified (with tb_rlink_stim.dat):
-- Date Rev Code ghdl ise Target Comment
-- 2007-11-02 93 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok
-- 2007-10-12 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok
-- 2007-10-12 88 - 0.26 - - c:ok
--
-- Revision History:
-- Date Rev Version Comment
-- 2007-11-25 98 1.0.1 use entity rather arch name to switch core/serport
-- 2007-07-08 65 1.0 Initial version
------------------------------------------------------------------------------
 
configuration tb_rlink_direct of tb_rlink is
 
for sim
for all : tbd_rlink_gen
use entity work.tbd_rlink_direct;
end for;
end for;
 
end tb_rlink_direct;
/tb
tb Property changes : Added: svn:ignore ## -0,0 +1,51 ## +*.dep_ghdl +*.dep_isim +*.dep_xst +work-obj93.cf +*.vcd +*.ghw +*.sav +*.tmp +*.exe +ise +xflow.his +*.ngc +*.ncd +*.pcf +*.bit +*.msk +isim +isim.log +isim.wdb +fuse.log +*_[sft]sim.vhd +*_tsim.sdf +*_xst.log +*_tra.log +*_twr.log +*_map.log +*_par.log +*_tsi.log +*_pad.log +*_bgn.log +*_svn.log +*_sum.log +*_[dsft]sim.log +tb_rlink_stim +tb_rlink_direct +tb_rlink_direct_[sft]sim +tb_rlink_direct_ISim +tb_rlink_direct_ISim_[sft]sim +tb_rlink_sp1c +tb_rlink_sp1c_[sft]sim +tb_rlink_sp1c_ISim +tb_rlink_sp1c_ISim_[sft]sim +tb_rlink_tba_stim +tb_rlink_tba_ttcombo +tb_rlink_tba_ttcombo_[sft]sim +tb_rlink_tba_ttcombo_ISim +tb_rlink_tba_ttcombo_ISim_[sft]sim +tb_rlink_tba_eyemon +tb_rlink_tba_eyemon_[sft]sim +tb_rlink_tba_eyemon_ISim +tb_rlink_tba_eyemon_ISim_[sft]sim Index: rlink_sp1c.vbom =================================================================== --- rlink_sp1c.vbom (nonexistent) +++ rlink_sp1c.vbom (revision 33) @@ -0,0 +1,13 @@ +# libs +../slvtypes.vhd +../rbus/rblib.vhd +../rbus/rbdlib.vhd +rlinklib.vbom +../serport/serportlib.vbom +# components +rlink_core8.vbom +../serport/serport_1clock.vbom +../rbus/rbd_rbmon.vbom +../rbus/rb_sres_or_2.vbom +# design +rlink_sp1c.vhd Index: rlink_core8.vbom =================================================================== --- rlink_core8.vbom (nonexistent) +++ rlink_core8.vbom (revision 33) @@ -0,0 +1,12 @@ +# libs +../slvtypes.vhd +../comlib/comlib.vhd +../rbus/rblib.vhd +rlinklib.vbom +# components +rlink_core.vbom +../comlib/byte2cdata.vbom +../comlib/cdata2byte.vbom +[sim]rlink_mon_sb.vbom +# design +rlink_core8.vhd Index: ioleds_sp1c.vhd =================================================================== --- ioleds_sp1c.vhd (nonexistent) +++ ioleds_sp1c.vhd (revision 33) @@ -0,0 +1,55 @@ +-- $Id: ioleds_sp1c.vhd 649 2015-02-21 21:10:16Z mueller $ +-- +-- Copyright 2015- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ioleds_sp1c - syn +-- Description: io activity leds for rlink+serport_1clk combo +-- +-- Dependencies: - +-- Test bench: - +-- +-- Target Devices: generic +-- Tool versions: xst 17.7; viv 2014.4; ghdl 0.31 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2015-02-21 649 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.slvtypes.all; +use work.rlinklib.all; +use work.serportlib.all; + +entity ioleds_sp1c is -- io activity leds for rlink_sp1c + port ( + SER_MONI : in serport_moni_type; -- ser: monitor port + IOLEDS : out slv4 -- 4 bit IO monitor (e.g. for DSP_DP) + ); +end entity ioleds_sp1c; + + +architecture syn of ioleds_sp1c is + +begin + + -- currently very minimal implementation + IOLEDS(3) <= not SER_MONI.txok; + IOLEDS(2) <= SER_MONI.txact; + IOLEDS(1) <= not SER_MONI.rxok; + IOLEDS(0) <= SER_MONI.rxact; + +end syn; Index: rlink_rlbmux.vhd =================================================================== --- rlink_rlbmux.vhd (nonexistent) +++ rlink_rlbmux.vhd (revision 33) @@ -0,0 +1,92 @@ +-- $Id: rlink_rlbmux.vhd 649 2015-02-21 21:10:16Z mueller $ +-- +-- Copyright 2012- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rlink_rlbmux - syn +-- Description: rlink rlb multiplexer +-- +-- Dependencies: - +-- Test bench: - +-- Tool versions: xst 13.3-14.7; ghdl 0.29-0.31 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2012-12-29 466 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; + +entity rlink_rlbmux is -- rlink rlb multiplexer + port ( + SEL : in slbit; -- port select (0:RLB<->P0; 1:RLB<->P1) + RLB_DI : out slv8; -- rlb: data in + RLB_ENA : out slbit; -- rlb: data enable + RLB_BUSY : in slbit; -- rlb: data busy + RLB_DO : in slv8; -- rlb: data out + RLB_VAL : in slbit; -- rlb: data valid + RLB_HOLD : out slbit; -- rlb: data hold + P0_RXDATA : in slv8; -- p0: rx data + P0_RXVAL : in slbit; -- p0: rx valid + P0_RXHOLD : out slbit; -- p0: rx hold + P0_TXDATA : out slv8; -- p0: tx data + P0_TXENA : out slbit; -- p0: tx enable + P0_TXBUSY : in slbit; -- p0: tx busy + P1_RXDATA : in slv8; -- p1: rx data + P1_RXVAL : in slbit; -- p1: rx valid + P1_RXHOLD : out slbit; -- p1: rx hold + P1_TXDATA : out slv8; -- p1: tx data + P1_TXENA : out slbit; -- p1: tx enable + P1_TXBUSY : in slbit -- p1: tx busy + ); +end rlink_rlbmux; + + +architecture syn of rlink_rlbmux is + +begin + + proc_rlmux : process (SEL, RLB_DO, RLB_VAL, RLB_BUSY, + P0_RXDATA, P0_RXVAL, P0_TXBUSY, + P1_RXDATA, P1_RXVAL, P1_TXBUSY) + begin + + P0_TXDATA <= RLB_DO; + P1_TXDATA <= RLB_DO; + + if SEL = '0' then + RLB_DI <= P0_RXDATA; + RLB_ENA <= P0_RXVAL; + P0_RXHOLD <= RLB_BUSY; + P0_TXENA <= RLB_VAL; + RLB_HOLD <= P0_TXBUSY; + P1_RXHOLD <= '0'; + P1_TXENA <= '0'; + else + RLB_DI <= P1_RXDATA; + RLB_ENA <= P1_RXVAL; + P1_RXHOLD <= RLB_BUSY; + P1_TXENA <= RLB_VAL; + RLB_HOLD <= P1_TXBUSY; + P0_RXHOLD <= '0'; + P0_TXENA <= '0'; + end if; + + end process proc_rlmux; + +end syn; Index: rlink_core.vbom =================================================================== --- rlink_core.vbom (nonexistent) +++ rlink_core.vbom (revision 33) @@ -0,0 +1,17 @@ +# libs +../slvtypes.vhd +../memlib/memlib.vhd +../comlib/comlib.vhd +../rbus/rblib.vhd +rlinklib.vbom +# components +[sim]../memlib/ram_2swsr_rfirst_gen.vbom +[xst,vsyn]../memlib/ram_2swsr_rfirst_gen_unisim.vbom +../memlib/fifo_1c_dram.vbom +../comlib/crc16.vbom +../rbus/rb_sel.vbom +../rbus/rb_sres_or_2.vbom +[sim]rlink_mon_sb.vbom +[sim]../rbus/rb_mon_sb.vbom +# design +rlink_core.vhd Index: rlink_mon_sb.vhd =================================================================== --- rlink_mon_sb.vhd (nonexistent) +++ rlink_mon_sb.vhd (revision 33) @@ -0,0 +1,86 @@ +-- $Id: rlink_mon_sb.vhd 649 2015-02-21 21:10:16Z mueller $ +-- +-- Copyright 2007-2011 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rlink_mon_sb - sim +-- Description: simbus wrapper for rlink monitor +-- +-- Dependencies: simbus +-- simlib/simclkcnt +-- rlink_mon +-- Test bench: - +-- Tool versions: xst 8.2-14.7; ghdl 0.18-0.31 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2011-12-23 444 3.1 use simclkcnt instead of simbus global +-- 2010-12-24 347 3.0.1 rename: CP_*->RL->* +-- 2010-12-22 346 3.0 renamed rritb_cpmon_sb -> rlink_mon_sb +-- 2010-05-02 287 1.0.1 use sbcntl_sbf_cpmon def +-- 2007-08-25 75 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.simbus.all; +use work.rlinklib.all; + +entity rlink_mon_sb is -- simbus wrap for rlink monitor + generic ( + DWIDTH : positive := 9; -- data port width (8 or 9) + ENAPIN : integer := sbcntl_sbf_rlmon); -- SB_CNTL signal to use for enable + port ( + CLK : in slbit; -- clock + RL_DI : in slv(DWIDTH-1 downto 0); -- rlink: data in + RL_ENA : in slbit; -- rlink: data enable + RL_BUSY : in slbit; -- rlink: data busy + RL_DO : in slv(DWIDTH-1 downto 0); -- rlink: data out + RL_VAL : in slbit; -- rlink: data valid + RL_HOLD : in slbit -- rlink: data hold + ); +end rlink_mon_sb; + + +architecture sim of rlink_mon_sb is + + signal ENA : slbit := '0'; + signal CLK_CYCLE : integer := 0; + +begin + + assert ENAPIN>=SB_CNTL'low and ENAPIN<=SB_CNTL'high + report "assert(ENAPIN in SB_CNTL'range)" severity failure; + + CLKCNT : simclkcnt port map (CLK => CLK, CLK_CYCLE => CLK_CYCLE); + + ENA <= to_x01(SB_CNTL(ENAPIN)); + + CPMON : rlink_mon + generic map ( + DWIDTH => DWIDTH) + port map ( + CLK => CLK, + CLK_CYCLE => CLK_CYCLE, + ENA => ENA, + RL_DI => RL_DI, + RL_ENA => RL_ENA, + RL_BUSY => RL_BUSY, + RL_DO => RL_DO, + RL_VAL => RL_VAL, + RL_HOLD => RL_HOLD + ); + +end sim; Index: ioleds_sp1c.vbom =================================================================== --- ioleds_sp1c.vbom (nonexistent) +++ ioleds_sp1c.vbom (revision 33) @@ -0,0 +1,7 @@ +# libs +../slvtypes.vhd +../rlink/rlinklib.vbom +../serport/serportlib.vbom +# components +# design +ioleds_sp1c.vhd Index: rlink_core.vhd =================================================================== --- rlink_core.vhd (nonexistent) +++ rlink_core.vhd (revision 33) @@ -0,0 +1,1660 @@ +-- $Id: rlink_core.vhd 641 2015-02-01 22:12:15Z mueller $ +-- +-- Copyright 2007-2014 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rlink_core - syn +-- Description: rlink core with 9bit interface (with rlmon+rbmon) +-- +-- Dependencies: memlib/ram_2swsr_rfirst_gen +-- memlib/fifo_1c_dram +-- comlib/crc16 +-- rb_sel +-- rb_sres_or_2 +-- rlink_mon_sb [sim only] +-- rbus/rb_mon_sb [sim only] +-- +-- Test bench: tb/tb_rlink_direct +-- tb/tb_rlink_serport +-- tb/tb_rlink_tba_ttcombo +-- +-- Target Devices: generic +-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2014-12-20 614 14.7 131013 xc6slx16-2 310 453 16 146 s 6.8 ver 4.0 +-- 2014-08-13 581 14.7 131013 xc6slx16-2 160 230 0 73 s 6.0 ver 3.0 +-- 2014-08-13 581 14.7 131013 xc3s1000-4 160 358 0 221 s 8.9 ver 3.0 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2014-12-21 617 4.1 use stat(_rbf_rbtout) to signal rbus timeout +-- 2014-12-20 614 4.0 largely rewritten; 2 FSMs; v3 protocol; 4 bit STAT +-- 2014-08-15 583 3.5 rb_mreq addr now 16 bit; add s_rxaddrl state +-- 2011-11-19 427 3.1.3 now numeric_std clean +-- 2010-12-25 348 3.1.2 drop RL_FLUSH support, add RL_MONI for rlink_core; +-- 2010-12-24 347 3.1.1 rename: CP_*->RL->* +-- 2010-12-22 346 3.1 wblk dcrc error: send nak, transit to s_error now; +-- rename stat flags: [cd]crc->[cd]err, ioto->rbnak, +-- ioerr->rberr; '111' cmd now aborts via s_txnak and +-- sets cerr flag; set [cd]err on eop/nak aborts; +-- 2010-12-04 343 3.0 renamed rri_ -> rlink_; rbus V3 interface: use now +-- aval,re,we; add new states: s_rstart, s_wstart +-- 2010-06-20 308 2.6 use rbinit,rbreq,rbwe state flops to drive rb_mreq; +-- now nak on reserved cmd 111; use do_comma_abort(); +-- 2010-06-18 306 2.5.1 rename rbus data fields to _rbf_ +-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining +-- 2010-06-03 299 2.1.2 drop unneeded unsigned casts; change init encoding +-- 2010-05-02 287 2.1.1 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT signal from interfaces +-- 2010-04-03 274 2.1 add CP_FLUSH output +-- 2009-07-12 233 2.0.1 remove snoopers +-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface +-- 2008-03-02 121 1.1.1 comment out snoopers +-- 2007-11-24 98 1.1 new internal init handling (addr=11111111) +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-09-15 82 1.0 Initial version, fully functional +-- 2007-06-17 58 0.5 First preliminary version +------------------------------------------------------------------------------ +-- 7 supported commands: +-- nak aborts to _txnak are indicated as [nak:] +-- commands to rbus engine are indicated as [bcmd:] +-- +-- 000 read reg (rreg): +-- rx: cmd al ah ccrcl ccrch +-- tx: cmd dl dh stat crcl crch +-- seq: _rxcmd _rxaddrl _rxaddrh +-- _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd +-- _rstart[bcmd:rblk] {_txdat}* +-- _txstat _txcrcl[nak:rtovfl] -> _txcrch -> _rxcmd +-- +-- 001 read blk (rblk): +-- rx: cmd al ah cl ch ccrcl ccrch +-- tx: cmd cnt dl dh ... dcl dch stat crcl crch +-- seq: _rxcmd _rxaddrl _rxaddrh _rxcntl _rxcnth +-- _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd +-- _txcntl _txcnth _rstart[bcmd:rblk] {_txdat}* _txdcntl _txdcnth +-- _txstat _txcrcl[nak:rtovfl] -> _txcrch -> _rxcmd +-- +-- 010 write reg (wreg): +-- rx: cmd al ah dl dh ccrcl ccrch +-- tx: cmd stat crcl crch +-- seq: _rxcmd _rxaddrl _rxaddrh _rxdatl _rxdath +-- _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd +-- _txcmd[bcmd:wblk] _wwait0 +-- _txstat _txcrcl[nak:rtovfl] -> _txcrch -> _rxcmd +-- +-- 011 write blk (wblk): +-- rx: cmd al ah cnt ccrcl ccrch dl dh ... dcrcl dcrch +-- tx: cmd dcl dch stat crcl crch +-- seq: _rxcmd _rxaddrl _rxaddrh _rxcntl _rxcnth +-- _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd +-- _wblk {_rxwblk}* _rxdcrc[nak:dcrc,rtwblk] +-- _wblk0 _wblk1 _wblk2[bcmd:wblk] {_wblkl _wblkh}* +-- _wwait0 _wwait1 _txdcntl _txdcnth +-- _txstat _txcrcl[nak:rtovfl] -> _txcrch -> _rxcmd +-- +-- 100 list abort (labo): +-- rx: cmd ccrcl ccrch +-- tx: cmd babo stat crcl crch +-- seq: _rxcmd +-- _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd +-- _txlabo +-- _txstat_txcrcl[nak:rtovfl] -> _txcrch -> [_rxcmd|_rxeop] +-- +-- 101 read attn (attn): +-- rx: cmd ccrcl ccrch +-- tx: cmd dl dh stat crcl crch +-- seq: _rxcmd +-- _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd +-- _attn _txcntl _txcnth +-- _txstat _txcrcl[nak:rtovfl] -> _txcrch -> _rxcmd +-- +-- 110 write init (init): +-- rx: cmd al ah dl dh ccrcl ccrch +-- tx: cmd stat crcl crch +-- seq: _rxcmd _rxaddrl _rxaddrh _rxdatl _rxdath +-- _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd[bcmd:init] +-- _txstat _txcrc[nak:rtovfl] -> _rxcmd +-- +-- 111 is currently not a legal command and causes a nak +-- seq: _txnak +-- +-- The different rbus cycle types are encoded as: +-- +-- init aval re we +-- 0 0 0 0 idle +-- 0 1 1 0 read +-- 0 1 0 1 write +-- 1 0 0 0 init +-- 0 0 1 0 not allowed +-- 0 0 0 1 not allowed +-- 1 0 0 1 not allowed +-- 1 0 1 0 not allowed +-- * * 1 1 not allowed +-- 1 1 * * not allowed +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.slvtypes.all; +use work.memlib.all; +use work.comlib.all; +use work.rblib.all; +use work.rlinklib.all; + +entity rlink_core is -- rlink core with 9bit interface + generic ( + BTOWIDTH : positive := 5; -- rbus timeout counter width + RTAWIDTH : positive := 12; -- retransmit buffer address width + SYSID : slv32 := (others=>'0'); -- rlink system id + ENAPIN_RLMON : integer := -1; -- SB_CNTL for rlmon (-1=none) + ENAPIN_RBMON : integer := -1); -- SB_CNTL for rbmon (-1=none) + port ( + CLK : in slbit; -- clock + CE_INT : in slbit := '0'; -- rri ato time unit clock enable + RESET : in slbit; -- reset + RL_DI : in slv9; -- rlink 9b: data in + RL_ENA : in slbit; -- rlink 9b: data enable + RL_BUSY : out slbit; -- rlink 9b: data busy + RL_DO : out slv9; -- rlink 9b: data out + RL_VAL : out slbit; -- rlink 9b: data valid + RL_HOLD : in slbit; -- rlink 9b: data hold + RL_MONI : out rl_moni_type; -- rlink: monitor port + RB_MREQ : out rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16; -- rbus: look at me + RB_STAT : in slv4 -- rbus: status flags + ); + + attribute fsm_encoding : string; + attribute fsm_encoding of rlink_core : entity is "one-hot"; + +end entity rlink_core; + +architecture syn of rlink_core is + -- core config registers (top 4 in rbus space) + constant rbaddr : slv16 := x"fffc"; -- fffc/4: 1111 1111 1111 11xx + constant rbaddr_cntl : slv2 := "11"; -- cntl address offset + constant rbaddr_stat : slv2 := "10"; -- stat address offset + constant rbaddr_id1 : slv2 := "01"; -- id1 address offset + constant rbaddr_id0 : slv2 := "00"; -- id0 address offset + + constant d_f_cflag : integer := 8; -- d9: comma flag + subtype d_f_ctyp is integer range 2 downto 0; -- d9: comma type + subtype d_f_data is integer range 7 downto 0; -- d9: data field + + subtype f_byte1 is integer range 15 downto 8; + subtype f_byte0 is integer range 7 downto 0; + + constant cntl_rbf_anena : integer := 15; -- anena flag + constant cntl_rbf_atoena : integer := 14; -- atoena flag + subtype cntl_rbf_atoval is integer range 7 downto 0; -- atoval value + subtype stat_rbf_lcmd is integer range 15 downto 8; -- lcmd + constant stat_rbf_babo : integer := 7; -- block abort flag + constant stat_rbf_arpend : integer := 6; -- attn read pend + subtype stat_rbf_rbsize is integer range 2 downto 0; -- rbuf size + + -- following 4 constants can derived from c_rlink_dat_sop,... + -- defined directly here to work around a ghdl bug + constant c_sop : slv3 := "000"; + constant c_eop : slv3 := "001"; + constant c_nak : slv3 := "010"; + constant c_attn : slv3 := "011"; + + constant c_bcmd_stat : slv2 := "00"; + constant c_bcmd_init : slv2 := "01"; + constant c_bcmd_rblk : slv2 := "10"; + constant c_bcmd_wblk : slv2 := "11"; + + constant cntawidth : positive := RTAWIDTH-1; -- cnt is word count + subtype cnt_f_dat is integer range cntawidth-1 downto 0; -- cnt data + + -- link FSM states and state vector ---------------------------------------- + type lstate_type is ( + sl_idle, -- sl_idle: wait for sop + sl_txanot, -- sl_txanot: send attn notify + sl_txsop, -- sl_txsop: send sop + sl_txnak, -- sl_txnak: send nak + sl_txnakcode, -- sl_txnakcode: send nakcode + sl_txrtbuf, -- sl_txrtbuf: send rtbuf + sl_txeop, -- sl_txeop: send eop + sl_rxeop, -- sl_rxeop: wait for eop + sl_rxcmd, -- sl_rxcmd: wait for cmd + sl_rxaddrl, -- sl_rxaddrl: wait for addr low + sl_rxaddrh, -- sl_rxaddrh: wait for addr high + sl_rxdatl, -- sl_rxdatl: wait for data low + sl_rxdath, -- sl_rxdath: wait for data high + sl_rxcntl, -- sl_rxcntl: wait for count low + sl_rxcnth, -- sl_rxcnth: wait for count low + sl_rxccrcl, -- sl_rxccrcl: wait for command crc low + sl_rxccrch, -- sl_rxccrcl: wait for command crc high + sl_txcmd, -- sl_txcmd: send cmd + sl_txcntl, -- sl_txcntl: send cnt lsb + sl_txcnth, -- sl_txcnth: send cnt msb + sl_rstart, -- sl_rstart: start rreg or rblk + sl_txdat, -- sl_txdat: send data + sl_wblk, -- sl_wblk: setup rx wblk data + sl_rxwblk, -- sl_rxwblk: wait for wblk data + sl_rxdcrcl, -- sl_rxdcrcl: wait for data crc low + sl_rxdcrch, -- sl_rxdcrch: wait for data crc high + sl_wblk0, -- sl_wblk0: start wblk pipe + sl_wblk1, -- sl_wblk1: start wblk data lsb + sl_wblk2, -- sl_wblk2: start wblk data msb + sl_wblkl, -- sl_wblkl: wblk data lsb + sl_wblkh, -- sl_wblkh: wblk data msb + sl_wwait0, -- sl_wwait0: wait for wdone + sl_wwait1, -- sl_wwait1: wait for dcnt + sl_txdcntl, -- sl_txdcntl: send dcnt lsb + sl_txdcnth, -- sl_txdcnth: send dcnt lsb + sl_txlabo, -- sl_txlabo: send labo flag + sl_attn, -- sl_attn: handle attention flags + sl_txstat, -- sl_txstat: send status + sl_txcrcl, -- sl_txcrcl: send crc low + sl_txcrch -- sl_txcrch: send crc high + ); + + type lregs_type is record + state : lstate_type; -- state + rcmd : slv8; -- received command + lcmd : slv8; -- last command + addr : slv16; -- rbus register address + din : slv16; -- rbus input data + cnt : slv16; -- block transfer count + bcnt : slv(RTAWIDTH-1 downto 0); -- blk counter (byte and word) + attn : slv16; -- attn mask + anreq : slbit; -- attn notify request + anact : slbit; -- attn notify active + arpend : slbit; -- attn read pending + atocnt : slv8; -- attn timeout counter + babo : slbit; -- last blk aborted + nakdone : slbit; -- nak done + nakcode : slv3; -- nak code + cmdseen : slbit; -- 1st command seen + doretra : slbit; -- do a retransmit + dinl : slv8; -- din lsb for wblk pipeline + rtaddra : slv(RTAWIDTH-1 downto 0); -- rtbuf port a addr (write pointer) + rtaddra_red : slbit; -- rtaddra red (at max) + rtaddra_bad : slbit; -- rtaddra bad (inc beyond max) + rtaddrb : slv(RTAWIDTH-1 downto 0); -- rtbuf port b addr (aux pointer) + rtaddrb_red : slbit; -- rtaddrb red (at max) + rtaddrb_bad : slbit; -- rtaddrb bad (inc beyond max) + moneop : slbit; -- rl_moni: eop send pulse + monattn : slbit; -- rl_moni: attn send pulse + end record lregs_type; + + constant bcnt_zero : slv(RTAWIDTH-1 downto 0) := (others=>'0'); + constant rtaddr_zero : slv(RTAWIDTH-1 downto 0) := (others=>'0'); + constant rtaddr_tred : slv(RTAWIDTH-1 downto 0) := (0=>'0', others=>'1'); + + constant lregs_init : lregs_type := ( + sl_idle, -- state + (others=>'0'), -- rcmd + (others=>'1'), -- lcmd + (others=>'0'), -- addr + (others=>'0'), -- din + (others=>'0'), -- cnt + bcnt_zero, -- bcnt + (others=>'0'), -- attn + '0','0','0', -- anreq,anact,arpend + (others=>'0'), -- atocnt + '0', -- babo + '0', -- nakdone + (others=>'0'), -- nakcode + '0','0', -- cmdseen,doretra + (others=>'0'), -- dinl + rtaddr_zero, -- rtaddra + '0','0', -- rtaddra_red, rtaddra_bad + rtaddr_zero, -- rtaddrb + '0','0', -- rtaddrb_red, rtaddrb_bad + '0','0' -- moneop,monattn + ); + + -- bus FSM states and state vector ----------------------------------------- + type bstate_type is ( + sb_idle, -- sb_idle: wait for cmd + sb_rstart, -- sb_rstart: start rblk + sb_rreg0, -- sb_rreg0: rbus read cycle + sb_rreg1, -- sb_rreg1: send read data + sb_rwait, -- sb_rwait: wait for fifo + sb_rend, -- sb_rend: send last read data + sb_rabo0, -- sb_rabo0: rblk abort, lsb data + sb_rabo1, -- sb_rabo1: rblk abort, msb data + sb_wstart, -- sb_wstart: start wblk + sb_wreg0, -- sb_wreg0: rbus write cycle + sb_wreg1, -- sb_wreg1: wait write data + sb_wabo0, -- sb_wabo0: wblk abort, drop data + sb_wabo1 -- sb_wabo1: wblk abort, wait + ); + + type bregs_type is record + state : bstate_type; -- state + rbinit : slbit; -- rbus init signal + rbaval : slbit; -- rbus aval signal + rbre : slbit; -- rbus re signal + rbwe : slbit; -- rbus we signal + rbdout : slv16; -- rbus dout + rbtout: slbit; -- rbus timeout + rbnak: slbit; -- rbus no ack + rberr : slbit; -- rbus err bit set + blkabo : slbit; -- blk abort + cnt : slv(cntawidth-1 downto 0); -- word count for rblk and wblk + dcnt : slv(cntawidth-1 downto 0); -- done count for rblk and wblk + btocnt : slv(BTOWIDTH-1 downto 0); -- rbus timeout counter + dathpend : slbit; -- dat msb pending + wfifo : slbit; -- wait for fifo + stat : slv4; -- external status flags + end record bregs_type; + + constant btocnt_init : slv(BTOWIDTH-1 downto 0) := (others=>'1'); + constant cnt_zero : slv(cntawidth-1 downto 0) := (others=>'0'); + + constant bregs_init : bregs_type := ( + sb_idle, -- state + '0','0','0','0', -- rbinit,rbaval,rbre,rbwe + (others=>'0'), -- rbdout + '0','0','0', -- rbtout,rbnak,rberr + '0', -- blkabo + cnt_zero, -- cnt + cnt_zero, -- dcnt + btocnt_init, -- btocnt + '0','0', -- dathpend,wfifo + (others=>'0') -- stat + ); + + -- config state regs -------------------------------------------------------- + type cregs_type is record + anena : slbit; -- attn notification enable flag + atoena : slbit; -- attn timeout enable flag + atoval : slv8; -- attn timeout value + end record cregs_type; + + constant cregs_init : cregs_type := ( + '0','0', -- anena,atoena + (others=>'0') -- atoval + ); + + signal R_LREGS : lregs_type := lregs_init; -- state registers link FSM + signal N_LREGS : lregs_type := lregs_init; -- next value state regs link FSM + signal R_BREGS : bregs_type := bregs_init; -- state registers bus FSM + signal N_BREGS : bregs_type := bregs_init; -- next value state regs bus FSM + signal R_CREGS : cregs_type := cregs_init; -- state registers config + signal N_CREGS : cregs_type := cregs_init; -- next value state regs config + + signal RTBUF_ENB : slbit := '0'; + signal RTBUF_WEA : slbit := '0'; + signal RTBUF_WEB : slbit := '0'; + signal RTBUF_DIA : slv8 := (others=>'0'); + signal RTBUF_DIB : slv8 := (others=>'0'); + signal RTBUF_DOB : slv8 := (others=>'0'); + + signal DOFIFO_DI : slv8 := (others=>'0'); + signal DOFIFO_ENA : slbit := '0'; + signal DOFIFO_DO : slv8 := (others=>'0'); + signal DOFIFO_VAL : slbit := '0'; + signal DOFIFO_HOLD : slbit := '0'; + signal DOFIFO_SIZE : slv6 := (others=>'0'); + + signal CRC_RESET : slbit := '0'; + signal ICRC_ENA : slbit := '0'; + signal OCRC_ENA : slbit := '0'; + signal ICRC_OUT : slv16 := (others=>'0'); + signal OCRC_OUT : slv16 := (others=>'0'); + signal OCRC_IN : slv8 := (others=>'0'); + + signal RBSEL : slbit := '0'; + + signal RB_MREQ_L : rb_mreq_type := rb_mreq_init; -- internal mreq + signal RB_SRES_CONF : rb_sres_type := rb_sres_init; -- config sres + signal RB_SRES_TOT : rb_sres_type := rb_sres_init; -- total sres + + signal RL_BUSY_L : slbit := '0'; + signal RL_DO_L : slv9 := (others=>'0'); + signal RL_VAL_L : slbit := '0'; + + signal L2B_GO : slbit := '0'; + signal L2B_CMD : slv2 := (others=>'0'); + signal B2L_WDONE : slbit := '0'; + +begin + + -- allow 11 bit (1 x 18kbit BRAM) to 15 bit (8 x 36 kbit BRAMs) + assert RTAWIDTH>=11 and RTAWIDTH<=14 + report "assert(RTAWIDTH>=11 and RTAWIDTH<=15): unsupported RTAWIDTH" + severity failure; + + RTBUF : ram_2swsr_rfirst_gen + generic map ( + AWIDTH => RTAWIDTH, + DWIDTH => 8) + port map ( + CLKA => CLK, + CLKB => CLK, + ENA => RTBUF_WEA, -- port A write only, thus en=we + ENB => RTBUF_ENB, + WEA => RTBUF_WEA, + WEB => RTBUF_WEB, + ADDRA => R_LREGS.rtaddra, + ADDRB => R_LREGS.rtaddrb, + DIA => RTBUF_DIA, + DIB => RTBUF_DIB, + DOA => open, + DOB => RTBUF_DOB + ); + + DOFIFO : fifo_1c_dram + generic map ( + AWIDTH => 5, + DWIDTH => 8) + port map ( + CLK => CLK, + RESET => RESET, + DI => DOFIFO_DI, + ENA => DOFIFO_ENA, + BUSY => open, + DO => DOFIFO_DO, + VAL => DOFIFO_VAL, + HOLD => DOFIFO_HOLD, + SIZE => DOFIFO_SIZE + ); + + ICRC : crc16 -- crc generator for input data + port map ( + CLK => CLK, + RESET => CRC_RESET, + ENA => ICRC_ENA, + DI => RL_DI(d_f_data), + CRC => ICRC_OUT + ); + + OCRC : crc16 -- crc generator for output data + port map ( + CLK => CLK, + RESET => CRC_RESET, + ENA => OCRC_ENA, + DI => OCRC_IN, + CRC => OCRC_OUT + ); + + SEL : rb_sel -- rbus address select for config regs + generic map ( + RB_ADDR => rbaddr, + SAWIDTH => 2) + port map ( + CLK => CLK, + RB_MREQ => RB_MREQ_L, + SEL => RBSEL + ); + + RB_SRES_OR : rb_sres_or_2 + port map ( + RB_SRES_1 => RB_SRES, + RB_SRES_2 => RB_SRES_CONF, + RB_SRES_OR => RB_SRES_TOT + ); + + proc_regs: process (CLK) + begin + + if rising_edge(CLK) then + if RESET = '1' then + R_LREGS <= lregs_init; + R_BREGS <= bregs_init; + R_CREGS <= cregs_init; + else + R_LREGS <= N_LREGS; + R_BREGS <= N_BREGS; + R_CREGS <= N_CREGS; + end if; + end if; + + end process proc_regs; + + -- link FSM ================================================================ + + proc_lnext: process (R_LREGS, R_CREGS, R_BREGS, + CE_INT, RL_DI, RL_ENA, RL_HOLD, RB_LAM, + ICRC_OUT, OCRC_OUT, RTBUF_DOB, + DOFIFO_DO, DOFIFO_VAL, + B2L_WDONE) + + variable r : lregs_type := lregs_init; + variable n : lregs_type := lregs_init; + + variable ival : slbit := '0'; + variable ibusy : slbit := '0'; + variable ido : slv9 := (others=>'0'); + variable crcreset : slbit := '0'; + variable icrcena : slbit := '0'; + variable ocrcena : slbit := '0'; + variable has_attn : slbit := '0'; + variable idi8 : slv8 := (others=>'0'); + variable is_comma : slbit := '0'; + variable comma_typ : slv3 := "000"; + variable idohold : slbit := '0'; + variable cnt_iszero : slbit := '0'; + variable bcnt_load : slbit := '0'; + variable bcnt_val : slv(RTAWIDTH-1 downto 0) := (others=>'0'); + variable bcnt_dec : slbit := '0'; + variable bcnt_end : slbit := '0'; + variable irtwea : slbit := '0'; + variable irtreb : slbit := '0'; + variable irtweb : slbit := '0'; + variable addra_clear : slbit := '0'; + variable addrb_load : slbit := '0'; + variable addrb_sela : slbit := '0'; + variable ibcmd : slv2 := (others=>'0'); + variable ibgo : slbit := '0'; + + begin + + r := R_LREGS; + n := R_LREGS; + + n.moneop := '0'; -- default '0', only set by states + n.monattn := '0'; -- " + + ival := '0'; + ibusy := '1'; -- default is to hold input + ido := (others=>'0'); + + crcreset := '0'; + icrcena := '0'; + ocrcena := '0'; + + has_attn := '0'; + + is_comma := RL_DI(d_f_cflag); -- get comma marker + comma_typ := RL_DI(d_f_ctyp); -- get comma type + idi8 := RL_DI(d_f_data); -- get data part of RL_DI + + idohold := '1'; -- default is to hold DOFIFO + + cnt_iszero := '0'; + if unsigned(r.cnt(cnt_f_dat)) = 0 then + cnt_iszero := '1'; + end if; + + bcnt_load := '0'; + bcnt_val := r.cnt(cnt_f_dat) & '0'; -- default: 2*cnt (most used) + bcnt_dec := '0'; + bcnt_end := '0'; + if unsigned(r.bcnt) = 1 then + bcnt_end := '1'; + end if; + + irtwea := '0'; + irtreb := '0'; + irtweb := '0'; + addra_clear := '0'; + addrb_load := '0'; + addrb_sela := '1'; -- default: addra (most used) + + ibcmd := (others=>'0'); + ibgo := '0'; + + -- handle attention "LAM's" + n.attn := r.attn or RB_LAM; + + -- detect attn notify requests + if unsigned(r.attn) /= 0 then -- if any of the attn bits set + has_attn := '1'; + if R_CREGS.anena='1' and r.arpend='0' then -- if attn to be send + n.anreq := '1'; -- set notify request flag + end if; + end if; + + -- handle attn read timeouts + -- atocnt is held in reset when no attn read is pending + -- counting down in CE_INT cycles till zero + -- when zero, an attn notify is requested when atoena is set + -- the attn notify flag will reset atocnt to its start value + -- --> when atoena='1' this creates a notify every atoval CE_INT periods + -- --> when atoena='0' atocnt will count to zero and stay there + + if r.arpend = '0' or r.anreq = '1' then -- if no attn read pending + n.atocnt := R_CREGS.atoval; -- keep at start value + else -- otherwise + if CE_INT = '1' then -- if CE_INT + if unsigned(r.atocnt) = 0 then -- alread counted down + n.anreq := R_CREGS.atoena; -- request attn notify if enabled + else -- not yet down + n.atocnt := slv(unsigned(r.atocnt) - 1); -- decrement + end if; + end if; + end if; + + case r.state is + + when sl_idle => -- sl_idle: wait for sop ------------- + bcnt_val := r.rtaddra; -- used for nak handling + addrb_sela := '0'; + n.anact := '0'; + n.doretra := '0'; + crcreset := '1'; -- reset crc generators + if r.anreq = '1' then -- if attn notify requested + n.anreq := '0'; -- acknowledge request + n.arpend := '1'; -- mark attn read pending + n.state := sl_txanot; -- next: send attn notify + else + ibusy := '0'; -- accept input + if RL_ENA = '1' then -- if input + if is_comma = '1' then -- if comma + case comma_typ is + when c_sop => -- if sop + n.cmdseen := '0'; -- clear cmd seen flag + n.state := sl_txsop; -- next: echo it + when c_attn => -- if attn + n.state := sl_txanot; -- next: send attn notify + when c_nak => + addrb_load := '1'; + bcnt_load := '1'; + n.doretra := '1'; + n.state := sl_txsop; -- next: send sop + when others => null; -- other commas: silently ignore + -- especially: eop is ignored + end case; + else -- if normal data + n.state := sl_idle; -- silently dropped + end if; + end if; + end if; + + when sl_txanot => -- sl_txanot: send attn notify ------- + n.cnt := r.attn; -- transfer attn to cnt for transmit + n.anact := '1'; -- signal attn notify active + ido := c_rlink_dat_attn; -- send attn symbol + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + n.monattn := '1'; -- signal on rl_moni + n.state := sl_txcntl; -- next: send cnt lsb + end if; + + when sl_txsop => -- sl_txsop: send sop ---------------- + ido := c_rlink_dat_sop; -- send sop character + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + if r.doretra = '1' then -- if retra request + irtreb := '1'; -- request first byte + n.state := sl_txrtbuf; -- next: send rtbuf + else -- or normal command + n.state := sl_rxcmd; -- next: read first command + end if; + end if; + + when sl_txnak => -- sl_txnak: send nak ---------------- + n.nakdone := '1'; -- set nakdone flag + ido := c_rlink_dat_nak; -- send nak character + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + n.state := sl_txnakcode; -- next: send nakcode + end if; + + when sl_txnakcode => -- sl_txnakcode: send nakcode -------- + ido := '0' & "10" & (not r.nakcode) & r.nakcode; + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + n.state := sl_rxeop; -- next: wait for eop + end if; + + when sl_rxeop => -- sl_rxeop: wait for eop ------------ + ibusy := '0'; -- accept input + if RL_ENA = '1' then + if is_comma = '1' and comma_typ = c_eop then -- if eop seen + n.state := sl_txeop; -- next: echo eop + end if; + end if; + + when sl_txrtbuf => -- sl_txrtbuf: send rtbuf ------------ + ido := '0' & RTBUF_DOB; -- send rtbuf data + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + bcnt_dec := '1'; + if bcnt_end = '0' then -- if not yet done + irtreb := '1'; -- request next byte + else -- all done + if r.nakdone = '0' then -- if no nak active + n.state := sl_txeop; -- next: send eop + else + n.state := sl_txnak; -- next: send nak + end if; + end if; + end if; + + when sl_txeop => -- sl_txeop: send eop ---------------- + ido := c_rlink_dat_eop; -- send eop character + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + n.moneop := '1'; -- signal on rl_moni + n.state := sl_idle; -- next: idle state, wait for sop + end if; + + when sl_rxcmd => -- sl_rxcmd: wait for cmd ------------ + ibusy := '0'; -- accept input + n.cnt := slv(to_unsigned(1,16)); -- preset cnt=1 (used for rreg) + n.rcmd := idi8; -- latch cmd (follow till valid) + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + if comma_typ = c_eop then -- eop seen + n.state := sl_txeop; -- next: echo eop + else -- any other comma seen + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + end if; + else -- if not comma + if r.cmdseen = '0' then -- if first cmd + n.nakdone := '0'; -- clear nakdone flag + addra_clear := '1'; -- clear rtbuf + end if; + n.cmdseen := '1'; -- set cmd seen flag + icrcena := '1'; -- update input crc + case RL_DI(c_rlink_cmd_rbf_code) is + when c_rlink_cmd_rreg | + c_rlink_cmd_rblk | + c_rlink_cmd_wreg | + c_rlink_cmd_wblk | + c_rlink_cmd_init => -- for commands needing addr(data) + n.state := sl_rxaddrl; -- next: read address lsb + when c_rlink_cmd_labo | + c_rlink_cmd_attn => -- labo and attn commands + n.state := sl_rxccrcl; -- next: read command crc low + when others => + n.nakcode := c_rlink_nakcode_cmd; -- signal bad cmd + n.state := sl_txnak; -- next: send nak + end case; + end if; + end if; + + when sl_rxaddrl => -- sl_rxaddrl: wait for addr lsb ----- + ibusy := '0'; -- accept input + n.addr(f_byte0) := idi8; -- latch addr lsb (follow till valid) + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak, + else + icrcena := '1'; -- update input crc + n.state := sl_rxaddrh; -- next: read addr msb + end if; + end if; + + when sl_rxaddrh => -- sl_rxaddrh: wait for addr msb ----- + ibusy := '0'; -- accept input + n.addr(f_byte1) := idi8; -- latch addr msb (follow till valid) + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + else + icrcena := '1'; -- update input crc + case r.rcmd(c_rlink_cmd_rbf_code) is + when c_rlink_cmd_rreg => -- for rreg command + n.state := sl_rxccrcl; -- next: read command crc low + when c_rlink_cmd_wreg | + c_rlink_cmd_init => -- for wreg, init command + n.state := sl_rxdatl; -- next: read data lsb + when others => -- for rblk or wblk + n.state := sl_rxcntl; -- next: read count lsb + end case; + end if; + end if; + + when sl_rxdatl => -- sl_rxdatl: wait for data low ------ + ibusy := '0'; -- accept input + n.din(f_byte0) := idi8; -- latch data lsb (follow till valid) + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + else + icrcena := '1'; -- update input crc + n.state := sl_rxdath; -- next: read data msb + end if; + end if; + + when sl_rxdath => -- sl_rxdath: wait for data high ----- + ibusy := '0'; -- accept input + n.din(f_byte1) := idi8; -- latch data msb (follow till valid) + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + else + icrcena := '1'; -- update input crc + n.state := sl_rxccrcl; -- next: read command crc low + end if; + end if; + + when sl_rxcntl => -- sl_rxcntl: wait for count lsb ----- + ibusy := '0'; -- accept input + n.cnt(f_byte0) := idi8; -- latch count lsb (follow till valid) + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + else + icrcena := '1'; -- update input crc + n.state := sl_rxcnth; -- next: read count msb + end if; + end if; + + when sl_rxcnth => -- sl_rxcnth: wait for count msb ----- + ibusy := '0'; -- accept input + n.cnt(f_byte1) := idi8; -- latch count lsb (follow till valid) + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + else + icrcena := '1'; -- update input crc + if unsigned(idi8(7 downto cntawidth-8)) = 0 then -- if cnt ok + n.state := sl_rxccrcl; -- next: read command crc low + else + n.nakcode := c_rlink_nakcode_cnt; -- signal bad cnt + n.state := sl_txnak; -- next: send nak + end if; + end if; + end if; + + when sl_rxccrcl => -- sl_rxccrcl: wait for command crc low + ibusy := '0'; -- accept input + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + else + if idi8 /= ICRC_OUT(f_byte0) then -- if crc error (lsb) + n.nakcode := c_rlink_nakcode_ccrc; -- signal bad ccrc + n.state := sl_txnak; -- next: send nak + else -- if crc ok + n.state := sl_rxccrch; -- next: wait for command crc high + end if; + end if; + end if; + + when sl_rxccrch => -- sl_rxccrcl: wait for command crc high + ibusy := '0'; -- accept input + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + else + if idi8 /= ICRC_OUT(f_byte1) then -- if crc error (msb) + n.nakcode := c_rlink_nakcode_ccrc; -- signal bad ccrc + n.state := sl_txnak; -- next: send nak + else -- if crc ok + n.state := sl_txcmd; -- next: echo command + end if; + end if; + end if; + + when sl_txcmd => -- sl_txcmd: send cmd ----------------- + ido := '0' & r.rcmd; -- send read command + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + irtwea := '1'; + ocrcena := '1'; -- update output crc + ibcmd := c_bcmd_stat; -- latch external status bits + ibgo := '1'; + + case r.rcmd(c_rlink_cmd_rbf_code) is -- main command dispatcher + when c_rlink_cmd_rreg => -- rreg ---------------- + n.state := sl_rstart; -- next: start rreg + when c_rlink_cmd_rblk => -- rblk ---------------- + n.babo := '0'; -- clear babo flag + n.state := sl_txcntl; + when c_rlink_cmd_wreg => -- wreg ---------------- + ibcmd := c_bcmd_wblk; + ibgo := '1'; + n.state := sl_wwait0; -- next: wait for wdone + when c_rlink_cmd_wblk => -- wblk ---------------- + n.babo := '0'; -- clear babo flag + if cnt_iszero = '0' then -- if cnt /= 0 + n.state := sl_wblk; -- next: read wblk data + else -- otherwise cnt = 0 + n.state := sl_rxdcrcl; -- next: wait for dcrc low + end if; + when c_rlink_cmd_labo => -- labo ---------------- + n.state := sl_txlabo; + when c_rlink_cmd_attn => -- attn ---------------- + n.state := sl_attn; + when c_rlink_cmd_init => -- init ---------------- + ibcmd := c_bcmd_init; + ibgo := '1'; + n.state := sl_txstat; + + when others => -- '111' --------------- + n.nakcode := c_rlink_nakcode_cmd; -- signal bad cmd + n.state := sl_txnak; -- send NAK on reserved command + end case; + end if; + + when sl_txcntl => -- sl_txcntl: send cnt lsb ------------ + ido := '0' & r.cnt(f_byte0); -- send cnt lsb + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + irtwea := not r.anact; -- no rtbuf for attn notify + ocrcena := '1'; -- update output crc + n.state := sl_txcnth; -- next: send cnt msb + end if; + + when sl_txcnth => -- sl_txcnth: send cnt msb ------------ + ido := '0' & r.cnt(f_byte1); -- send cnt msb + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + irtwea := not r.anact; -- no rtbuf for attn notify + ocrcena := '1'; -- update output crc + if r.anact = '1' then -- if in attn notify + n.state := sl_txcrcl; -- next: send crc low + elsif r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_rblk then -- if rblk + if cnt_iszero = '0' then -- if cnt /= 0 + n.state := sl_rstart; -- next: start rblk + else -- otherwise cnt = 0 + n.state := sl_txdcntl; -- next: send dcnt lsb + end if; + else -- otherwise, must be attn + n.state := sl_txstat; -- next: send stat + end if; + end if; + + when sl_rstart => -- sl_rstart: start rreg or rblk ----- + ibcmd := c_bcmd_rblk; + ibgo := '1'; + bcnt_load := '1'; + bcnt_val := r.cnt(cnt_f_dat) & '0'; -- 2*cnt + n.state := sl_txdat; + + when sl_txdat => -- sl_txdat: send data --------------- + ido := '0' & DOFIFO_DO; + if DOFIFO_VAL = '1' then -- wait for input + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + idohold := '0'; + irtwea := '1'; + ocrcena := '1'; -- update output crc + bcnt_dec := '1'; + if bcnt_end = '1' then + if r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_rblk then -- if rblk + n.state := sl_txdcntl; + else + n.state := sl_txstat; + end if; + end if; + end if; + end if; + + when sl_wblk => -- sl_wblk: setup rx wblk data ------- + addrb_load := '1'; -- must be done here because addra + addrb_sela := '1'; -- is incremented in _txcmd + bcnt_load := '1'; + bcnt_val := r.cnt(cnt_f_dat) & '0'; -- 2*cnt + n.state := sl_rxwblk; + + when sl_rxwblk => -- sl_rxwblk: wait for wblk data ----- + ibusy := '0'; -- accept input + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + else + icrcena := '1'; -- update input crc + irtweb := '1'; -- write into rtbuf via b port + bcnt_dec := '1'; + if bcnt_end = '1' then -- if all done + n.state := sl_rxdcrcl; -- next: wait for data crc low + end if; + end if; + end if; + + when sl_rxdcrcl => -- sl_rxdcrcl: wait for data crc low - + ibusy := '0'; -- accept input + bcnt_val := r.cnt(cnt_f_dat) & '0'; -- 2 * cnt + addrb_sela := '1'; + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + else + if idi8 /= ICRC_OUT(f_byte0) then -- if crc error lsb + n.nakcode := c_rlink_nakcode_dcrc; -- signal bad dcrc + n.state := sl_txnak; -- next: send nak + else -- if crc ok + n.state := sl_rxdcrch; -- next: wait for data crc high + end if; + end if; + end if; + + when sl_rxdcrch => -- sl_rxdcrch: wait for data crc high + ibusy := '0'; -- accept input + bcnt_val := r.cnt(cnt_f_dat) & '0'; -- 2 * cnt + addrb_sela := '1'; + if RL_ENA = '1' then + if is_comma = '1' then -- if comma + n.nakcode := c_rlink_nakcode_frame; -- signal framing error + n.state := sl_txnak; -- next: send nak + else + if idi8 /= ICRC_OUT(f_byte1) then -- if crc error msb + n.nakcode := c_rlink_nakcode_dcrc; -- signal bad dcrc + n.state := sl_txnak; -- next: send nak + else -- if crc ok + addrb_load := '1'; + bcnt_load := '1'; + if r.rtaddrb_bad = '0' then -- if rtbuf ok + n.state := sl_wblk0; -- next: start wblk pipe + else -- else rtbuf ovfl + n.nakcode := c_rlink_nakcode_rtwblk; -- signal ovfl in wblk + n.state := sl_txnak; -- next: send nak + end if; + end if; + end if; + end if; + + when sl_wblk0 => -- sl_wblk0: start wblk pipe --------- + if cnt_iszero = '0' then -- if cnt /= 0 + irtreb := '1'; -- request next byte + n.state := sl_wblk1; -- next: start data lsb + else -- otherwise cnt = 0 + n.state := sl_txdcntl; -- next: send dcnt lsb + end if; + + when sl_wblk1 => -- sl_wblk1: start wblk data lsb ----- + n.dinl := RTBUF_DOB; -- latch data lsb + irtreb := '1'; -- request next byte + bcnt_dec := '1'; + n.state := sl_wblk2; -- next: start data msb + + when sl_wblk2 => -- sl_wblk2: start wblk data msb ----- + n.din := RTBUF_DOB & r.dinl; -- setup din + bcnt_dec := '1'; + ibcmd := c_bcmd_wblk; -- start rbus sequencer + ibgo := '1'; + if bcnt_end = '0' then -- if not yet done + irtreb := '1'; -- request next byte + n.state := sl_wblkl; -- next: enter wblk pipe + else -- all done + n.state := sl_wwait0; -- next: wait for wdone + end if; + + when sl_wblkl => -- sl_wblkl: pipe wblk data lsb ------ + n.dinl := RTBUF_DOB; -- latch data lsb + irtreb := '1'; -- request next byte + bcnt_dec := '1'; + n.state := sl_wblkh; -- next: pipe msb + + when sl_wblkh => -- sl_wblkh: pipe wblk data msb ------ + if B2L_WDONE = '1' then -- if last write done + n.din := RTBUF_DOB & r.dinl; -- setup next din + bcnt_dec := '1'; + if bcnt_end = '0' then -- if not yet done + irtreb := '1'; + n.state := sl_wblkl; -- next: pipe lsb + else -- all done + n.state := sl_wwait0; -- next: wait last wdone + end if; + end if; + + when sl_wwait0 => -- sl_wwait0: wait for wdone --------- + if B2L_WDONE = '1' then + if r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_wblk then -- if wblk + n.state := sl_wwait1; -- next: wait for dcnt + else + n.state := sl_txstat; -- next: send stat + end if; + end if; + + when sl_wwait1 => -- sl_wwait1: wait for dcnt ---------- + n.state := sl_txdcntl; -- next: send dcnt lsb + + when sl_txdcntl => -- sl_txdcntl: send dcnt lsb --------- + n.babo := R_BREGS.blkabo; -- remember blk abort + ido := '0' & R_BREGS.dcnt(f_byte0); -- send dcnt lsb + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + irtwea := '1'; + ocrcena := '1'; -- update output crc + n.state := sl_txdcnth; -- next: send dcnt msb + end if; + + when sl_txdcnth => -- sl_txdcnth: send dcnt msb --------- + ido := (others=>'0'); -- send dcnt msb + ido(cntawidth-9 downto 0) := R_BREGS.dcnt(cntawidth-1 downto 8); + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + irtwea := '1'; + ocrcena := '1'; -- update output crc + n.state := sl_txstat; -- next: send stat + end if; + + when sl_txlabo => -- sl_txlabo: send labo flag --------- + ido := '0' & "0000000" & r.babo; -- send babo + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + irtwea := '1'; + ocrcena := '1'; -- update output crc + n.state := sl_txstat; -- next: send stat + end if; + + when sl_attn => -- sl_attn: handle attention flags --- + n.cnt := r.attn; -- use cnt to latch attn status + n.attn := RB_LAM; -- LAM in current cycle send next time + n.arpend := '0'; -- reenable attn nofification + n.anreq := '0'; -- cancel pending notify requests + n.state := sl_txcntl; -- next: send cnt lsb (holding attn) + + when sl_txstat => -- sl_txstat: send status ------------ + ido(c_rlink_stat_rbf_stat) := R_BREGS.stat; + ido(c_rlink_stat_rbf_attn) := has_attn; + ido(c_rlink_stat_rbf_rbtout) := R_BREGS.rbtout; + ido(c_rlink_stat_rbf_rbnak) := R_BREGS.rbnak; + ido(c_rlink_stat_rbf_rberr) := R_BREGS.rberr; + ival := '1'; + if RL_HOLD ='0' then -- wait for accept + irtwea := '1'; + ocrcena := '1'; -- update output crc + n.state := sl_txcrcl; -- next: send crc low + end if; + + when sl_txcrcl => -- sl_txcrcl: send crc low ----------- + ido := "0" & OCRC_OUT(f_byte0); -- send crc code low + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + irtwea := not r.anact; -- no rtbuf for attn notify + n.state := sl_txcrch; -- next: send crc high + end if; + + when sl_txcrch => -- sl_txcrch: send crc high ---------- + ido := "0" & OCRC_OUT(f_byte1); -- send crc code high + -- here check for rtbuf overflow + -- if space for 1 byte complete command and write crc + if r.rtaddra_red = '0' then -- if space for 1 byte + n.lcmd := r.rcmd; -- latch current command in lcmd + ival := '1'; + if RL_HOLD = '0' then -- wait for accept + irtwea := not r.anact; -- no rtbuf for attn notify + -- if this was attn notify, back to idle + if r.anact = '1' then + n.state := sl_txeop; -- next: send eop + -- here handle labo: if labo cmd and babo set, eat rest of list + elsif r.rcmd(c_rlink_cmd_rbf_code)=c_rlink_cmd_labo and + r.babo='1' then + n.state := sl_rxeop; -- next: wait for eop + else + n.state := sl_rxcmd; -- next: read command or eop + end if; + end if; + else + n.nakcode := c_rlink_nakcode_rtovfl; -- signal rtbuf ovfl + n.state := sl_txnak; -- next: send nak + end if; + + when others => null; -- <> -------------------------------- + + end case; + + -- addra logic (write pointer) + if addra_clear = '1' then -- clear + n.rtaddra := (others=>'0'); + n.rtaddra_red := '0'; + n.rtaddra_bad := '0'; + else + if irtwea = '1' then -- inc when write on port a + if r.rtaddra_red = '1' then -- if already red + n. rtaddra_bad := '1'; -- than flag bad + else -- still ok + n.rtaddra := slv(unsigned(r.rtaddra) + 1); -- inc + if r.rtaddra = rtaddr_tred then -- if inc'ed to red + n. rtaddra_red := '1'; -- flag red + end if; + end if; + end if; + end if; + + -- addrb logic (write and read pointer) + if addrb_load = '1' then -- load + if addrb_sela = '1' then + n.rtaddrb := r.rtaddra; + n.rtaddrb_red := r.rtaddra_red; + n.rtaddrb_bad := r.rtaddra_bad; + else + n.rtaddrb := (others=>'0'); + n.rtaddrb_red := '0'; + n.rtaddrb_bad := '0'; + end if; + else + if irtreb = '1' or irtweb = '1' then -- inc when read/write on port b + if r.rtaddrb_red = '1' then -- if already red + n. rtaddrb_bad := '1'; -- than flag bad + else -- still ok + n.rtaddrb := slv(unsigned(r.rtaddrb) + 1); -- inc + if r.rtaddrb = rtaddr_tred then -- if inc'ed to red + n. rtaddrb_red := '1'; -- flag red + end if; + end if; + end if; + end if; + + -- bcnt logic + if bcnt_load = '1' then + n.bcnt := bcnt_val; + else + if bcnt_dec ='1' then + n.bcnt := slv(unsigned(r.bcnt) - 1); + end if; + end if; + + N_LREGS <= n; + + RL_BUSY_L <= ibusy; + RL_DO_L <= ido; + RL_VAL_L <= ival; + + RL_MONI.eop <= r.moneop; + RL_MONI.attn <= r.monattn; + RL_MONI.lamp <= r.arpend; + + DOFIFO_HOLD <= idohold; + + RTBUF_WEA <= irtwea; + RTBUF_DIA <= ido(d_f_data); + RTBUF_ENB <= irtreb or irtweb; + RTBUF_WEB <= irtweb; + RTBUF_DIB <= idi8; + + CRC_RESET <= crcreset; + ICRC_ENA <= icrcena; + OCRC_ENA <= ocrcena; + OCRC_IN <= ido(d_f_data); + + L2B_CMD <= ibcmd; + L2B_GO <= ibgo; + + end process proc_lnext; + + -- bus FSM ================================================================= + + proc_bnext: process (R_BREGS, R_LREGS, + RB_STAT, RB_SRES_TOT, + DOFIFO_SIZE, + L2B_CMD, L2B_GO) + + variable r : bregs_type := bregs_init; + variable n : bregs_type := bregs_init; + + variable bto_go : slbit := '0'; + variable bto_end : slbit := '0'; + variable cnt_load : slbit := '0'; + variable cnt_dec : slbit := '0'; + variable cnt_end : slbit := '0'; + variable dcnt_clear : slbit := '0'; + variable dcnt_inc : slbit := '0'; + variable ival : slbit := '0'; + variable ido : slv8 := (others=>'0'); + variable iwdone : slbit := '0'; + + begin + + r := R_BREGS; + n := R_BREGS; + + bto_go := '0'; -- default: keep rbus timeout in reset + bto_end := '0'; + if unsigned(r.btocnt) = 0 then -- if rbus timeout count at zero + bto_end := '1'; -- signal expiration + end if; + + cnt_load := '0'; + cnt_dec := '0'; + cnt_end := '0'; + if unsigned(r.cnt) = 0 then + cnt_end := '1'; + end if; + + dcnt_clear := '0'; + dcnt_inc := '0'; + + ival := '0'; + ido := (others=>'0'); + + iwdone := '0'; + + -- FIXME: what is proper almost full limit ? + if unsigned(DOFIFO_SIZE) >= 28 then -- almost full + n.wfifo := '1'; + elsif unsigned(DOFIFO_SIZE) <= 2 then -- almost empty + n.wfifo := '0'; + end if; + + n.rbinit := '0'; -- clear rb(init|aval|re|we) by default + n.rbaval := '0'; -- they must always be set by the + n.rbre := '0'; -- 'previous state' + n.rbwe := '0'; -- + + case r.state is + + when sb_idle => -- sb_idle: wait for cmd ------------ + if L2B_GO = '1' then -- if cmd seen + n.stat := RB_STAT; -- always latch external status bits + n.rbtout := '0'; + n.rbnak := '0'; + n.rberr := '0'; + n.blkabo := '0'; + n.dathpend := '0'; + dcnt_clear := '1'; + cnt_load := '1'; + case L2B_CMD is + when c_bcmd_stat => -- stat --------------------- + null; -- nothing else todo + when c_bcmd_init => -- init --------------------- + n.rbinit := '1'; -- send init pulse + when c_bcmd_rblk => -- rblk --------------------- + n.rbaval := '1'; -- start aval chunk + n.state := sb_rstart; -- next: start rblk + when c_bcmd_wblk => -- wblk --------------------- + n.rbaval := '1'; -- start aval chunk + n.state := sb_wstart; -- next: start wblk + when others => null; + end case; + end if; + + when sb_rstart => -- sb_rstart: start rblk ------------- + n.rbaval := '1'; -- extend aval + n.rbre := '1'; -- start read cycle + n.state := sb_rreg0; -- next: do rreg + + when sb_rreg0 => -- sb_rreg0: rbus read cycle --------- + ido := r.rbdout(f_byte1); + n.stat := RB_STAT; -- follow external status bits + if r.dathpend = '1' then -- if pending data msb + ival := '1'; + n.dathpend := '0'; + end if; + n.rbaval := '1'; -- extend aval + bto_go := '1'; -- activate rbus timeout counter + if RB_SRES_TOT.err = '1' then -- latch rbus error flag + n.rberr := '1'; + n.blkabo := '1'; + end if; + n.rbdout := RB_SRES_TOT.dout; -- latch data (follow till valid) + if RB_SRES_TOT.busy='0' or bto_end='1' then -- wait non-busy or timeout + if RB_SRES_TOT.busy='1' and bto_end='1' then -- if timeout and busy + n.rbtout := '1'; -- set rbus timeout flag + n.blkabo := '1'; + elsif RB_SRES_TOT.ack = '0' then -- if non-busy and no ack + n.rbnak := '1'; -- set rbus nak flag + n.blkabo := '1'; + end if; + cnt_dec := '1'; + n.state := sb_rreg1; -- next: send data lsb + else -- otherwise rbus read continues + n.rbre := '1'; -- extend read cycle + end if; + + when sb_rreg1 => -- sb_rreg1: send read data ---------- + ido := r.rbdout(f_byte0); + ival := '1'; -- send lsb + n.dathpend := '1'; -- signal mdb pending + dcnt_inc := not r.blkabo; -- inc dcnt if no error + if cnt_end = '0' then -- if not yet done + if r.blkabo = '0' then -- if no errors + if r.wfifo = '0' then -- if fifo fine + n.rbaval := '1'; -- extend aval + n.rbre := '1'; -- start read cycle + n.state := sb_rreg0; -- next: do rreg + else -- fifo is full + n.state := sb_rwait; -- next: fifo wait + end if; + else -- errors seen, rblk abort + n.state := sb_rabo1; -- next: send rblk abort msb data + end if; + else -- all done + n.state := sb_rend; + end if; + + when sb_rwait => -- sb_rwait: wait for fifo ----------- + if r.wfifo = '0' then -- if fifo fine + n.rbaval := '1'; -- start aval chunk + n.state := sb_rstart; -- restart rblk + end if; + + when sb_rend => -- sb_rend: send last read data ------ + ido := r.rbdout(f_byte1); + ival := '1'; -- send msb + n.dathpend := '0'; + n.state := sb_idle; -- next: idle + + when sb_rabo0 => -- sb_rabo0: rblk abort, lsb data ---- + ido := (others=>'0'); + ival := '1'; + cnt_dec := '1'; + n.state := sb_rabo1; -- next: send rblk abort, msb data + + when sb_rabo1 => -- sb_rabo1: rblk abort, msb data ---- + ido := (others=>'0'); + if r.wfifo = '0' then + n.dathpend := '0'; -- cancel msb pend + ival := '1'; + if cnt_end = '0' then -- if not yet done + n.state := sb_rabo0; -- next: send rblk abort, lsb data + else -- all done + n.state := sb_idle; -- next: idle + end if; + end if; + + when sb_wstart => -- sb_wstart: start wblk + n.rbaval := '1'; -- start aval chunk + n.rbwe := '1'; -- start write cycle + n.state := sb_wreg0; + + when sb_wreg0 => -- sb_wreg0: rbus write cycle + n.stat := RB_STAT; -- follow external status bits + n.rbaval := '1'; -- extend aval + bto_go := '1'; -- activate rbus timeout counter + if RB_SRES_TOT.err = '1' then -- latch rbus error flag + n.rberr := '1'; + n.blkabo := '1'; + end if; + if RB_SRES_TOT.busy='0' or bto_end='1' then -- wait non-busy or timeout + if RB_SRES_TOT.busy='1' and bto_end='1' then -- if timeout and busy + n.rbtout := '1'; -- set rbus timeout flag + n.blkabo := '1'; + elsif RB_SRES_TOT.ack='0' then -- if non-busy and no ack + n.rbnak := '1'; -- set rbus nak flag + n.blkabo := '1'; + end if; + cnt_dec := '1'; + iwdone := '1'; + n.state := sb_wreg1; + else -- otherwise rbus write continues + n.rbwe := '1'; -- extend write cycle + end if; + + when sb_wreg1 => -- sb_wreg1: wait write data + dcnt_inc := not r.blkabo; -- inc dcnt if no error + if cnt_end = '0' then -- if not yet done + if r.blkabo = '0' then -- if no errors + n.rbaval := '1'; -- extend aval + n.rbwe := '1'; -- start write cycle + n.state := sb_wreg0; + else -- errors seen, rblk abort + n.state := sb_wabo0; -- next: drop wblk rest + end if; + else -- all done + n.state := sb_idle; -- next: idle + end if; + + when sb_wabo0 => -- sb_wabo0: wblk abort, drop data -- + iwdone := '1'; -- drop data + cnt_dec := '1'; + n.state := sb_wabo1; -- next: wblk abort, wair + + when sb_wabo1 => -- sb_wabo1: wblk abort, wait -------- + if cnt_end = '0' then -- if not yet done + n.state := sb_wabo0; -- next: wblk abort, drop + else -- all done + n.state := sb_idle; -- next: idle + end if; + + when others => null; -- <> -------------------------------- + + end case; + + if bto_go = '0' then -- handle access timeout counter + n.btocnt := btocnt_init; -- if bto_go=0, keep in reset + else + n.btocnt := slv(unsigned(r.btocnt) - 1);-- otherwise count down + end if; + + if cnt_load = '1' then + n.cnt := R_LREGS.cnt(cnt_f_dat); + else + if cnt_dec ='1' then + n.cnt := slv(unsigned(r.cnt) - 1); + end if; + end if; + + if dcnt_clear = '1' then + n.dcnt := (others=>'0'); + else + if dcnt_inc ='1' then + n.dcnt := slv(unsigned(r.dcnt) + 1); + end if; + end if; + + N_BREGS <= n; + + DOFIFO_DI <= ido; + DOFIFO_ENA <= ival; + + B2L_WDONE <= iwdone; + + end process proc_bnext; + + -- config rbus iface ======================================================= + + proc_cnext: process (R_CREGS, R_LREGS, RBSEL, RB_MREQ_L) + + variable r : cregs_type := cregs_init; + variable n : cregs_type := cregs_init; + variable irb_ack : slbit := '0'; + variable irb_dout : slv16 := (others=>'0'); + + begin + + r := R_CREGS; + n := R_CREGS; + + irb_ack := '0'; + irb_dout := (others=>'0'); + + -- rbus transactions + if RBSEL = '1' then + irb_ack := RB_MREQ_L.re or RB_MREQ_L.we; + + -- config register writes + if RB_MREQ_L.we = '1' then + case RB_MREQ_L.addr(1 downto 0) is + when rbaddr_cntl => + n.anena := RB_MREQ_L.din(cntl_rbf_anena); + n.atoena := RB_MREQ_L.din(cntl_rbf_atoena); + n.atoval := RB_MREQ_L.din(cntl_rbf_atoval); + when others => null; + end case; + end if; + + -- rbus output driver + case RB_MREQ_L.addr(1 downto 0) is + when rbaddr_cntl => + irb_dout(cntl_rbf_anena) := r.anena; + irb_dout(cntl_rbf_atoena) := r.atoena; + irb_dout(cntl_rbf_atoval) := r.atoval; + when rbaddr_stat => + irb_dout(stat_rbf_lcmd) := R_LREGS.lcmd; + irb_dout(stat_rbf_babo) := R_LREGS.babo; + irb_dout(stat_rbf_arpend) := R_LREGS.arpend; + irb_dout(stat_rbf_rbsize) := slv(to_unsigned(RTAWIDTH-10,3)); + when rbaddr_id0 => + irb_dout := SYSID(15 downto 0); + when rbaddr_id1 => + irb_dout := SYSID(31 downto 16); + when others => null; + end case; + + end if; + + N_CREGS <= n; + + RB_SRES_CONF.dout <= irb_dout; + RB_SRES_CONF.ack <= irb_ack; + RB_SRES_CONF.err <= '0'; + RB_SRES_CONF.busy <= '0'; + + end process proc_cnext; + + -- rbus driver ----------------------------------------------------- + + proc_mreq: process (R_LREGS, R_BREGS) + begin + + RB_MREQ_L <= rb_mreq_init; + RB_MREQ_L.aval <= R_BREGS.rbaval; + RB_MREQ_L.re <= R_BREGS.rbre; + RB_MREQ_L.we <= R_BREGS.rbwe; + RB_MREQ_L.init <= R_BREGS.rbinit; + RB_MREQ_L.addr <= R_LREGS.addr; + RB_MREQ_L.din <= R_LREGS.din; + + end process proc_mreq; + + RB_MREQ <= RB_MREQ_L; + + RL_BUSY <= RL_BUSY_L; + RL_DO <= RL_DO_L; + RL_VAL <= RL_VAL_L; + +-- synthesis translate_off + + RLMON: if ENAPIN_RLMON >= 0 generate + MON : rlink_mon_sb + generic map ( + DWIDTH => RL_DI'length, + ENAPIN => ENAPIN_RLMON) + port map ( + CLK => CLK, + RL_DI => RL_DI, + RL_ENA => RL_ENA, + RL_BUSY => RL_BUSY_L, + RL_DO => RL_DO_L, + RL_VAL => RL_VAL_L, + RL_HOLD => RL_HOLD + ); + end generate RLMON; + + RBMON: if ENAPIN_RBMON >= 0 generate + MON : rb_mon_sb + generic map ( + DBASE => 8, + ENAPIN => ENAPIN_RBMON) + port map ( + CLK => CLK, + RB_MREQ => RB_MREQ_L, + RB_SRES => RB_SRES_TOT, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); + end generate RBMON; + +-- synthesis translate_on + +end syn; Index: Makefile =================================================================== --- Makefile (nonexistent) +++ Makefile (revision 33) @@ -0,0 +1,32 @@ +# $Id: Makefile 639 2015-01-30 18:12:19Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2014-07-27 545 1.1.1 make reference board configurable via XTW_BOARD +# 2011-08-13 405 1.1 use includes from rtl/make +# 2007-12-09 100 1.0.1 drop ISE_p definition +# 2007-07-06 64 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +# reference board for test synthesis is Spartan-6 based Nexys3 +ifndef XTW_BOARD + XTW_BOARD=nexys3 +endif +include $(RETROBASE)/rtl/make_ise/xflow_default_$(XTW_BOARD).mk +# +.PHONY : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/make_ise/generic_xflow.mk +# +ifndef DONTINCDEP +include $(VBOM_all:.vbom=.dep_xst) +endif +# Index: rlink_mon.vbom =================================================================== --- rlink_mon.vbom (nonexistent) +++ rlink_mon.vbom (revision 33) @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +../simlib/simlib.vhd +../comlib/comlib.vhd +rlinklib.vbom +# components +# design +rlink_mon.vhd Index: rlink_mon.vhd =================================================================== --- rlink_mon.vhd (nonexistent) +++ rlink_mon.vhd (revision 33) @@ -0,0 +1,194 @@ +-- $Id: rlink_mon.vhd 609 2014-12-07 19:35:25Z mueller $ +-- +-- Copyright 2007-2014 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rlink_mon - sim +-- Description: rlink monitor (for tb's) +-- +-- Dependencies: - +-- Test bench: - +-- Tool versions: xst 8.2-17.7; ghdl 0.18-0.31 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2014-11-08 602 4.0.2 annotate clobber commas +-- 2014-10-25 599 4.0.1 use writeoptint() +-- 2014-10-12 596 4.0 adopt to new escaping, better 8 bit output +-- 2011-12-23 444 3.1 CLK_CYCLE now integer +-- 2011-11-19 427 3.0.2 now numeric_std clean +-- 2010-12-24 347 3.0.1 rename: CP_*->RL->* +-- 2010-12-22 346 3.0 renamed rritb_cpmon -> rlink_mon +-- 2010-06-11 303 2.5.1 fix data9 assignment, always proper width now +-- 2010-06-07 302 2.5 use sop/eop framing instead of soc+chaining +-- 2008-03-24 129 1.0.1 CLK_CYCLE now 31 bits +-- 2007-09-09 81 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.rlinklib.all; +use work.comlib.all; + +entity rlink_mon is -- rlink monitor + generic ( + DWIDTH : positive := 9); -- data port width (8 or 9) + port ( + CLK : in slbit; -- clock + CLK_CYCLE : in integer := 0; -- clock cycle number + ENA : in slbit := '1'; -- enable monitor output + RL_DI : in slv(DWIDTH-1 downto 0); -- rlink: data in + RL_ENA : in slbit; -- rlink: data enable + RL_BUSY : in slbit; -- rlink: data busy + RL_DO : in slv(DWIDTH-1 downto 0); -- rlink: data out + RL_VAL : in slbit; -- rlink: data valid + RL_HOLD : in slbit -- rlink: data hold + ); +end rlink_mon; + + +architecture sim of rlink_mon is + +begin + + assert DWIDTH=8 or DWIDTH=9 + report "assert(DWIDTH=8 or DWIDTH=9)" severity failure; + + proc_moni: process + variable oline : line; + variable nbusy : integer := 0; + variable nhold : integer := 0; + variable edatarx : boolean := false; + variable edatatx : boolean := false; + + procedure write_val(L: inout line; + data: in slv(DWIDTH-1 downto 0); + nwait: in integer; + txt1: in string(1 to 2); + txt2: in string; + edata: in boolean) is + variable data9 : slv9 := (others=>'0'); + variable optxt : string(1 to 8) := ": ??rx "; + begin + + if DWIDTH = 9 then + optxt(3 to 4) := "rl"; + else + optxt(3 to 4) := "r8"; + end if; + optxt(5 to 6) := txt1; + writetimestamp(L, CLK_CYCLE, optxt); + + if DWIDTH = 9 then + write(L, data(data'left), right, 1); + else + write(L, string'(" ")); + end if; + + write(L, data(7 downto 0), right, 9); + writeoptint(L, txt2, nwait); + + if DWIDTH=9 and data(data'left)='1' then + -- a copy to data9 needed to allow following case construct + -- using data directly gives a 'subtype is not locally static' error + data9 := (others=>'0'); + data9(data'range) := data; + write(L, string'(" comma")); + case data9 is + when c_rlink_dat_sop => write(L, string'(" sop")); + when c_rlink_dat_eop => write(L, string'(" eop")); + when c_rlink_dat_nak => write(L, string'(" nak")); + when c_rlink_dat_attn => write(L, string'(" attn")); + when others => write(L, string'(" clobber|oob")); + end case; + end if; + + if DWIDTH = 8 then + + if edata then + write(L, string'(" edata")); + if data(c_cdata_edf_pref) /= c_cdata_ed_pref or + (not data(c_cdata_edf_eci)) /= data(c_cdata_edf_ec) then + write(L, string'(" FAIL: bad format")); + else + write(L, string'(" ec=")); + write(L, data(c_cdata_edf_ec)); + data9 := (others=>'0'); + data9(8) := '1'; + data9(c_cdata_edf_ec) := data(c_cdata_edf_ec); + case data9 is + when c_rlink_dat_sop => write(L, string'(" (sop)")); + when c_rlink_dat_eop => write(L, string'(" (eop)")); + when c_rlink_dat_nak => write(L, string'(" (nak)")); + when c_rlink_dat_attn => write(L, string'(" (attn)")); + when "100000" & c_cdata_ec_xon => write(L, string'(" (xon)")); + when "100000" & c_cdata_ec_xoff => write(L, string'(" (xoff)")); + when "100000" & c_cdata_ec_fill => write(L, string'(" (fill)")); + when "100000" & c_cdata_ec_esc => write(L, string'(" (esc)")); + when others => + write(L, string'(" FAIL: bad ec")); + end case; + end if; + end if; + + if data = c_cdata_escape then + write(L, string'(" escape")); + end if; + end if; + + writeline(output, L); + end procedure write_val; + + begin + + loop + + if ENA='0' then -- if disabled + wait until ENA='1'; -- stall process till enabled + end if; + + wait until rising_edge(CLK); -- check at end of clock cycle + + if RL_ENA = '1' then + if RL_BUSY = '1' then + nbusy := nbusy + 1; + else + write_val(oline, RL_DI, nbusy, "rx", " nbusy=", edatarx); + edatarx := RL_DI=c_cdata_escape; + nbusy := 0; + end if; + else + nbusy := 0; + end if; + + if RL_VAL = '1' then + if RL_HOLD = '1' then + nhold := nhold + 1; + else + write_val(oline, RL_DO, nhold, "tx", " nhold=", edatatx); + edatatx := RL_DO=c_cdata_escape; + nhold := 0; + end if; + else + nhold := 0; + end if; + + end loop; + end process proc_moni; + +end sim; Index: rlinklib.vbom =================================================================== --- rlinklib.vbom (nonexistent) +++ rlinklib.vbom (revision 33) @@ -0,0 +1,5 @@ +# libs +../slvtypes.vhd +../rbus/rblib.vhd +../serport/serportlib.vbom +rlinklib.vhd Index: rlink_rlbmux.vbom =================================================================== --- rlink_rlbmux.vbom (nonexistent) +++ rlink_rlbmux.vbom (revision 33) @@ -0,0 +1,5 @@ +# libs +../slvtypes.vhd +# components +# design +rlink_rlbmux.vhd Index: rlink_mon_sb.vbom =================================================================== --- rlink_mon_sb.vbom (nonexistent) +++ rlink_mon_sb.vbom (revision 33) @@ -0,0 +1,10 @@ +# libs +../slvtypes.vhd +../simlib/simlib.vhd +../simlib/simbus.vhd +rlinklib.vbom +# components +../simlib/simclkcnt.vbom +rlink_mon.vbom +# design +rlink_mon_sb.vhd Index: . =================================================================== --- . (nonexistent) +++ . (revision 33)
. Property changes : Added: svn:ignore ## -0,0 +1,33 ## +*.dep_ghdl +*.dep_isim +*.dep_xst +work-obj93.cf +*.vcd +*.ghw +*.sav +*.tmp +*.exe +ise +xflow.his +*.ngc +*.ncd +*.pcf +*.bit +*.msk +isim +isim.log +isim.wdb +fuse.log +*_[sft]sim.vhd +*_tsim.sdf +*_xst.log +*_tra.log +*_twr.log +*_map.log +*_par.log +*_tsi.log +*_pad.log +*_bgn.log +*_svn.log +*_sum.log +*_[dsft]sim.log

powered by: WebSVN 2.1.0

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