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
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