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

Subversion Repositories w11

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /w11/tags/w11a_V0.5/rtl/vlib/rri
    from Rev 4 to Rev 7
    Reverse comparison

Rev 4 → Rev 7

/tb/tb_rri_serport.vhd
0,0 → 1,44
-- $Id: tb_rri_serport.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 2007- 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_rri_serport
-- Description: Configuration for tb_rri_serport for tb_rri.
--
-- Dependencies: tbd_rri_gen
--
-- To test: rri_serport
-- rri_core
--
-- Target Devices: generic
--
-- Verified (with tb_rri_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
-- 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_rri_serport of tb_rri is
 
for sim
for all : tbd_rri_gen
use entity work.tbd_rri_serport;
end for;
end for;
 
end tb_rri_serport;
/tb/rritb_cpmon.vbom
0,0 → 1,7
# libs
../../slvtypes.vhd
../../simlib/simlib.vhd
../rrilib.vhd
# components
# design
rritb_cpmon.vhd
/tb/cext_rriext.c
0,0 → 1,215
/* $Id: cext_rriext.c 314 2010-07-09 17:38:41Z mueller $
*
* Copyright 2007- 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
* 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>
 
#define CPREF 0x80
#define CESC (CPREF|0x0f)
#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;
 
/* returns:
* <0 if error
* >=0 <=0xff normal data
* == 0x100 idle
* 0x1aahhll if side band message seen
*
*/
 
/* returns
0 if EGAIN or
*/
 
static void cext_dotrace(const char *text, int dat)
{
int i;
int mask = 0x80;
printf("cext_rriext-I: %s ", text);
for (i=0; i<8; i++) {
printf("%c", (dat&mask)?'1':'0' );
mask >>= 1;
}
printf("\n");
}
 
static void cext_doread()
{
char buf[1];
ssize_t nbyte;
nbyte = read(fd_rx, buf, 1);
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) 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 */
}
}
}
 
int 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("tb_rriext_fifo_rx", O_RDONLY|O_NONBLOCK);
if (fd_rx <= 0) {
perror("cext_rriext-E: failed to open tb_rriext_fifo_rx");
return -2;
}
printf("cext_rriext-I: connected to tb_rriext_fifo_rx\n");
fd_tx = open("tb_rriext_fifo_tx", O_WRONLY);
if (fd_tx <= 0) {
perror("cext_rriext-E: failed to open tb_rriext_fifo_tx");
return -2;
}
printf("cext_rriext-I: connected to tb_rriext_fifo_tx\n");
nidle = 0;
ncesc = 0;
nside = -1;
 
io_trace = 0;
env_val = getenv("CEXT_RRIEXT_TRACE");
if (env_val && strcmp(env_val, "1") == 0) {
io_trace = 1;
}
}
 
cext_doread();
 
if (qr_nb == 0) { /* no character to be processed */
if (qr_eof != 0) { /* EOF seen */
if (ncesc >= 2) { /* two+ CESC seen ? */
printf("cext_rriext-I: seen EOF, wait for reconnect\n");
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("cext_rriext-I: seen EOF, schedule clock stop and exit\n");
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("cext_rriext-W: sched_yield failed");
}
nidle += 1;
return 0x100;
} else { /* must be a read error */
errno = qr_err;
perror("cext_rriext-E: read error on tb_rriext_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;
return tdat;
case 1: /* get ADDR byte */
nside += 1;
odat = 0x1000000 | (tdat<<16);
return 0x100;
case 2: /* get DL byte */
nside += 1;
odat |= tdat;
return 0x100;
case 3: /* get DH byte */
nside = -1;
odat |= tdat<<8;
return odat;
}
}
 
int cext_putbyte(int dat)
{
char buf[1];
ssize_t nbyte;
 
cext_doread();
 
if (io_trace) cext_dotrace("snd8", dat);
 
buf[0] = (unsigned char) dat;
nbyte = write(fd_tx, buf, 1);
 
if (nbyte < 0) {
perror("cext_rriext-E: write error on tb_rriext_fifo_tx");
return -3;
}
 
return 0;
}
/tb/rritb_cpmon_sb.vhd
0,0 → 1,77
-- $Id: rritb_cpmon_sb.vhd 314 2010-07-09 17:38:41Z 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: rritb_cpmon_sb - sim
-- Description: rritb: rri comm port monitor; simbus wrapper
--
-- Dependencies: simbus
-- Test bench: -
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
-- Revision History:
-- Date Rev Version Comment
-- 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.rritblib.all;
 
entity rritb_cpmon_sb is -- simbus wrap rri comm port monitor
generic (
DWIDTH : positive := 9; -- data port width (8 or 9)
ENAPIN : integer := sbcntl_sbf_cpmon); -- SB_CNTL signal to use for enable
port (
CLK : in slbit; -- clock
CP_DI : in slv(DWIDTH-1 downto 0); -- comm port: data in
CP_ENA : in slbit; -- comm port: data enable
CP_BUSY : in slbit; -- comm port: data busy
CP_DO : in slv(DWIDTH-1 downto 0); -- comm port: data out
CP_VAL : in slbit; -- comm port: data valid
CP_HOLD : in slbit -- comm port: data hold
);
end rritb_cpmon_sb;
 
 
architecture sim of rritb_cpmon_sb is
 
signal ENA : slbit := '0';
begin
 
assert ENAPIN>=SB_CNTL'low and ENAPIN<=SB_CNTL'high
report "assert(ENAPIN in SB_CNTL'range)" severity failure;
 
ENA <= to_x01(SB_CNTL(ENAPIN));
CPMON : rritb_cpmon
generic map (
DWIDTH => DWIDTH)
port map (
CLK => CLK,
CLK_CYCLE => SB_CLKCYCLE,
ENA => ENA,
CP_DI => CP_DI,
CP_ENA => CP_ENA,
CP_BUSY => CP_BUSY,
CP_DO => CP_DO,
CP_VAL => CP_VAL,
CP_HOLD => CP_HOLD
);
end sim;
/tb/tb_rri_stim.dat
0,0 → 1,648
# $Id: tb_rri_stim.dat 311 2010-06-30 17:52:37Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2010-06-06 302 2.0 use sop/eop framing instead of soc+chaining
# 2007-11-24 98 1.2 adapt to new internal init handling
# 2007-11-04 95 1.1 add .iowt's in Test 15 to get serport timing right
# 2007-06-17 58 1.0 Initial version
#
.wait 5
C some non frame data first
.tx8 00000000
.wait 5
.tx8 00000001
.wait 5
.tx8 00000010
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 1: wreg
C wreg: tx: sop - cmd(10000,010) addr(0000) dl dh ccrc - eop
C rx: sop - cmd(010) stat crc - eop
#
.rxsop
.rxcs 10000010 00000000
.rxeop
#
.txsop
.txcad 10000010 00000000 0011001111001100
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 2: rreg
C rreg: tx: sop - cmd(10010,000) addr(0000) ccrc - eop
C rx: sop - cmd(000) dl dh stat crc - eop
#
.rxsop
.rxcds 10010000 0011001111001100 00000000
.rxeop
#
.txsop
.txca 10010000 00000000
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 3: chained wreg - wreg - rreg
C wreg: tx: sop - cmd(11001,010) addr(0001) dl dh ccrc
C wreg: tx: - cmd(11011,010) addr(0010) dl dh ccrc
C rreg: tx: - cmd(11100,000) addr(0001) ccrc
C tx: - eop
C rx: sop - cmd(010) stat crc
C rx: - cmd(010) stat crc
C rx: - cmd(000) dl dh stat crc
C rx: - eop
#
.rxsop
.rxcs 11001010 00000000
.rxcs 11001010 00000000
.rxcds 11100000 1111111100000001 00000000
.rxeop
#
.txsop
.txcad 11001010 00000001 1111111100000001
.txcad 11001010 00000010 1111111100000010
.txca 11100000 00000001
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 4: wblk - rblk
C wblk: rx: sop - cmd(10100,011) addr(10000000) cnt(8->111) ccrc dl dh .. dcrc
C rx: - eop
C rx: sop - cmd(011) stat crc
C rx: - eop
#
.rxsop
.rxcs 10100011 00000000
.rxeop
#
.txsop
.txcac 10100011 10000000 00000111
.tx16 0000000001000000
.tx16 0000000001000001
.tx16 0000000001000010
.tx16 0000000001000011
.tx16 0000000001000100
.tx16 0000000001000101
.tx16 0000000001000110
.tx16 0000000001000111
.txcrc
.txeop
#
.iowt 10
C
C now check, that register 16 holds 8, clear it to prepare reread:
C rreg: tx: sop - cmd(10011,000) addr(10000) ccrc
C wreg: tx: - cmd(10000,010) addr(10000) dl dh ccrc
C tx: - eop
C rx: sop - cmd(000) dl dh stat crc
C rx: - cmd(010) stat crc
C rx: - eop
#
.rxsop
.rxcds 10011000 0000000000001000 00000000
.rxcs 10000010 00000000
.rxeop
#
.txsop
.txca 10011000 00010000
.txcad 10000010 00010000 00000000000000000
.txeop
#
.iowt 10
C rblk: rx: sop - cmd(10110,001) addr(10000000) cnt(8->111) ccrc - eop
C rx: sop - cmd(001) cnt dl dh ... stat crc - eop
#
.rxsop
.rx8 10110001
.rx8 00000111
.rx16 0000000001000000
.rx16 0000000001000001
.rx16 0000000001000010
.rx16 0000000001000011
.rx16 0000000001000100
.rx16 0000000001000101
.rx16 0000000001000110
.rx16 0000000001000111
.rx8 00000000
.rxcrc
.rxeop
#
.txsop
.txcac 10110001 10000000 00000111
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 5: stat (in non-error case) re-read last cmd twice, shouldn't change
C wreg: tx: sop - cmd(00001,010) addr(0010) dl dh ccrc
C wreg: tx: - cmd(00011,010) addr(0011) dl dh ccrc
C rreg: tx: - cmd(00101,000) addr(0010) ccrc
C rreg: tx: - cmd(00111,000) addr(0011) ccrc
C stat: tx: - cmd(01001,100) ccrc
C stat: tx: - cmd(01010,100) ccrc
C tx: - eop
C rx: sop - cmd(010) stat crc
C rx: - cmd(010) stat crc
C rx: - cmd(000) dl dh stat crc
C rx: - cmd(000) dl dh stat crc
C rx: - cmd(100) ccmd (000) dl dh stat crc
C rx: - cmd(100) ccmd (000) dl dh stat crc
C rx: - eop
#
.rxsop
.rxcs 00001010 00000000
.rxcs 00011010 00000000
.rxcds 00101000 1000000000000010 00000000
.rxcds 00111000 1000000100000011 00000000
.rxccd 01001100 00111000 1000000100000011 00000000
.rxccd 01010100 00111000 1000000100000011 00000000
.rxeop
#
.txsop
.txcad 00001010 00000010 1000000000000010
.txcad 00011010 00000011 1000000100000011
.txca 00101000 00000010
.txca 00111000 00000011
.txc 01001100
.txc 01010100
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 6: ccrc error abort
C wreg: tx: sop - cmd(01001,010) addr(0010) dl dh ccrc
C wreg: tx: - cmd(01011,010) addr(0011) dl dh ccrc
C rreg: tx: - cmd(01101,000) addr(0010) ccrc
C rreg: tx: - cmd(01110,000) addr(0011) *BAD CRC*
C tx: - eop
C rx: sop - cmd(010) stat crc
C rx: - cmd(010) stat crc
C rx: - cmd(000) dl dh stat crc
C rx: - nak *ABORT*
C rx: - eop
#
.rxsop
.rxcs 01001010 00000000
.rxcs 01011010 00000000
.rxcds 01101000 1000000100001010 00000000
.rxnak
.rxeop
#
.txsop
.txcad 01001010 00000010 1000000100001010
.txcad 01011010 00000011 1000000100001011
.txca 01101000 00000010
.tx8 01110000
.tx8 00000011
.tx8 00000000
.txeop
#
.iowt 10
C
C now check that stat reflects last successfull rreg; re-read ccrc=1 sticks !
C stat: tx: sop - cmd(10001,100) ccrc
C stat: tx: - cmd(10010,100) ccrc
C tx: - eop
C rx: - cmd(100) ccmd (000) dl dh stat crc
C rx: - cmd(100) ccmd (000) dl dh stat crc
C rx: - eop
C stat: stat(000),attn(0),ccrc(1),dcrc(0),ioto(0),ioerr(0) -> 00001000
.rxsop
.rxccd 10001100 01101000 1000000100001010 00001000
.rxccd 10010100 01101000 1000000100001010 00001000
.rxeop
#
.txsop
.txc 10001100
.txc 10010100
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 7: dcrc error condition
C wreg: tx: sop - cmd(00001,010) addr(10000) dl dh ccrc
C wblk: rx: - cmd(00011,011) addr(10000000) cnt(4->011) ccrc dl dh ..
C *BAD CRC*
C rx: - eop
C rx: sop - cmd(010) stat crc
C rx: - cmd(011) stat crc
C rx: - eop
C stat: stat(000),attn(0),ccrc(0),dcrc(1),ioto(0),ioerr(0) -> 00000100
#
.rxsop
.rxcs 00001010 00000000
.rxcs 00010011 00000100
.rxeop
#
.txsop
.txcad 00001010 00010000 00000000000000000
.txcac 00010011 10000000 00000011
.tx16 0001000001000000
.tx16 0001000001000001
.tx16 0001000001000010
.tx16 0001000001000011
.tx8 00000000
.txeop
#
.iowt 10
C
C now check that stat reflects bad dcrc: re-read dcrc=1 sticks !
C stat: tx: sop - cmd(00101,100) ccrc
C stat: tx: - cmd(00110,100) ccrc
C tx: - eop
C rx: - cmd(100) ccmd (000) dl dh stat crc
C rx: - cmd(100) ccmd (000) dl dh stat crc
C rx: - eop
C stat: stat(000),attn(0),ccrc(0),dcrc(1),ioto(0),ioerr(0) -> 00000100
C Note: dl,dh still the last read of Test 6 !!
.rxsop
.rxccd 00101100 00010011 1000000100001010 00000100
.rxccd 00110100 00010011 1000000100001010 00000100
.rxeop
#
.txsop
.txc 00101100
.txc 00110100
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 8: err(bad address) condition; 11000000 is an address returning err=1
C rreg: tx: sop - cmd(00001,000) addr(00010000) ccrc
C rreg: tx: - cmd(00011,000) addr(11000000) ccrc
C wreg: tx: - cmd(00101,010) addr(00010000) dl dh ccrc
C wreg: tx: - cmd(00110,010) addr(11000000) dl dh ccrc
C tx: - eop
C Note: the rreg(10000) will return 4, the prt after the last wblk !
C Note: tb returns 1010101010101010 for access to bad addresses
C stat: stat(000),attn(0),ccrc(0),dcrc(0),ioto(0),ioerr(1) -> 00000001
#
.rxsop
.rxcds 00001000 0000000000000100 00000000
.rxcds 00011000 1010101010101010 00000001
.rxcs 00101010 00000000
.rxcs 00110010 00000001
.rxeop
#
.txsop
.txca 00001000 00010000
.txca 00011000 11000000
.txcad 00101010 00010000 0000000000000000
.txcad 00110010 11000000 1000111110001111
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 9: to(time out) condition; 01bbbbbb addressed take n+1 hold states
C wreg: tx: sop - cmd(00001,010) addr(01000000) dl dh ccrc (nh=1)
C wreg: tx: - cmd(00011,010) addr(01001111) dl dh ccrc (nh=16)
C wreg: tx: - cmd(00101,010) addr(01011101) dl dh ccrc (nh=30)
C wreg: tx: - cmd(00111,010) addr(01011110) dl dh ccrc (nh=31)
C wreg: tx: - cmd(01001,010) addr(01011111) dl dh ccrc (nh=32) TO
C wreg: tx: - cmd(01011,010) addr(01100000) dl dh ccrc (nh=33) TO
C wreg: tx: - cmd(01101,010) addr(01111111) dl dh ccrc (nh=64) TO
C wreg: tx: - cmd(01110,010) addr(01000001) dl dh ccrc (nh=2)
C tx: - eop
C stat: stat(000),attn(0),ccrc(0),dcrc(0),ioto(1),ioerr(0) -> 00000010
#
.rxsop
.rxcs 00001010 00000000
.rxcs 00011010 00000000
.rxcs 00101010 00000000
.rxcs 00111010 00000000
.rxcs 01001010 00000010
.rxcs 01011010 00000010
.rxcs 01101010 00000010
.rxcs 01110010 00000000
.rxeop
#
.txsop
.txcad 00001010 01000000 0000000001000000
.txcad 00011010 01001111 0000000001001111
.txcad 00101010 01011101 0000000001011101
.txcad 00111010 01011110 0000000001011110
.txcad 01001010 01011111 0000000001011111
.txcad 01011010 01100000 0000000001100000
.txcad 01101010 01111110 0000000001111111
.txcad 01110010 01000001 0000000001000001
.txeop
.iowt 10
C
C now same with rreg
C rreg: tx: sop - cmd(00001,000) addr(01000000) ccrc (nh=1)
C rreg: tx: - cmd(00011,000) addr(01001111) ccrc (nh=16)
C rreg: tx: - cmd(00101,000) addr(01011101) ccrc (nh=30)
C rreg: tx: - cmd(00111,000) addr(01011110) ccrc (nh=31)
C rreg: tx: - cmd(01001,000) addr(01011111) ccrc (nh=32) TO
C rreg: tx: - cmd(01011,000) addr(01100000) ccrc (nh=33) TO
C rreg: tx: - cmd(01101,000) addr(01111111) ccrc (nh=64) TO
C rreg: tx: - cmd(01110,000) addr(01000001) ccrc (nh=2)
C tx: - eop
C Note: tb returns 0101010101010101 for timeout
#
.rxsop
.rxcds 00001000 0000000001000000 00000000
.rxcds 00011000 0000000001001111 00000000
.rxcds 00101000 0000000001011101 00000000
.rxcds 00111000 0000000001011110 00000000
.rxcds 01001000 0101010101010101 00000010
.rxcds 01011000 0101010101010101 00000010
.rxcds 01101000 0101010101010101 00000010
.rxcds 01110000 0000000001000001 00000000
.rxeop
#
.txsop
.txca 00001000 01000000
.txca 00011000 01001111
.txca 00101000 01011101
.txca 00111000 01011110
.txca 01001000 01011111
.txca 01011000 01100000
.txca 01101000 01111110
.txca 01110000 01000001
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 10: external init command
C rreg: tx: sop - cmd(00001,000) addr(00010010) ccrc
C init: tx: - cmd(00011,110) addr(10000111) dl dh ccrc
C rreg: tx: - cmd(00100,000) addr(00010010) ccrc
C tx: - eop
C rx: sop - cmd(000) dl dh stat crc
C rx: - cmd(110) stat crc
C rx: - cmd(000) dl dh stat crc
C rx: - eop
#
.rxsop
.rxcds 00001000 0000000000000000 00000000
.rxcs 00011110 00000000
.rxcds 00100000 0000000000000001 00000000
.rxeop
#
.txsop
.txca 00001000 00010010
.txcad 00011110 10000111 0000111000111000
.txca 00100000 00010010
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 11: external status bit (RP_STAT)
C Note: stat bits are not latched for stat command !
C stat <= "001"
C rreg: tx: sop - cmd(00000,000) addr(00010010) ccrc - eop
C rx: sop - cmd(000) dl dh stat crc - eop
#
.rxsop
.rxcds 00000000 0000000000000001 00100000
.rxeop
#
.stat 001
.txsop
.txca 00000000 00010010
.txeop
#
.iowt 10
C stat <= "010"
C stat: tx: sop - cmd(00011,100) ccrc
C rreg: tx: - cmd(00100,000) addr(00010010) ccrc
C tx: - eop
C rx: sop - cmd(100) ccmd (000) dl dh stat crc
C rx: - cmd(000) dl dh stat crc
C rx: - eop
C Note: stat command returns old 001 status
C rreg command returns new 010 status
.rxsop
.rxccd 00011100 00000000 0000000000000001 00100000
.rxcds 00010000 0000000000000001 01000000
.rxeop
#
.stat 010
.txsop
.txc 00011100
.txca 00010000 00010010
.txeop
#
C stat <= "100"
C rreg: tx: sop - cmd(00110,000) addr(00010010) ccrc - eop
C rx: sop - cmd(000) dl dh stat crc - eop
C stat <= '000'
.iowt 10
#
.rxsop
.rxcds 00110000 0000000000000001 10000000
.rxeop
#
.stat 100
.txsop
.txca 00110000 00010010
.txeop
#
.iowt 10
.stat 000
C -----------------------------------------------------------------------------
C Test 12: attention logic
C attn <= "0000000000000100" (async case)
C rreg: tx: sop - cmd(01001,000) addr(00010010) ccrc
C attn: tx: - cmd(01011,101) ccrc
C attn: tx: - cmd(01101,101) ccrc
C rreg: tx: - cmd(01110,000) addr(00010010) ccrc
C tx: - eop
C Note: the rreg command returns attn=1
C the attn has attn=0, because stat is evaluated after read+clear !!
C stat: stat(000),attn(1),ccrc(0),dcrc(0),ioto(0),ioerr(0) -> 00010000
#
.rxsop
.rxcds 01001000 0000000000000001 00010000
.rxcds 01011101 0000000000000100 00000000
.rxcds 01101101 0000000000000000 00000000
.rxcds 01110000 0000000000000001 00000000
.rxeop
#
.wait 5
.attn 00000100
.wait 5
.txsop
.txca 01001000 00010010
.txc 01011101
.txc 01101101
.txca 01110000 00010010
.txeop
#
.iowt 10
C
C now test sync case, the transaction causes the attention
C a write to 10000010 causes AP_LAM(15 downto 8) be pinged with RP_DO data
C wreg: tx: sob - cmd(10001,010) addr(10000010) dl dh ccrc
C rreg: tx: - cmd(10011,000) addr(00010010) ccrc
C attn: tx: - cmd(10101,101) ccrc
C attn: tx: - cmd(10111,101) ccrc
C rreg: tx: - cmd(11000,000) addr(00010010) ccrc
C tx: - eop
.rxsop
.rxcs 10001010 00010000
.rxcds 10011000 0000000000000001 00010000
.rxcds 10101101 0000000100000000 00000000
.rxcds 10111101 0000000000000000 00000000
.rxcds 11000000 0000000000000001 00000000
.rxeop
#
.txsop
.txcad 10001010 10000010 0000000100000000
.txca 10011000 00010010
.txc 10101101
.txc 10111101
.txca 11000000 00010010
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 13: verify that extra 'idle' commas are tolerated
C do wreg+rreg, with "100000000" between bytes
C use as data 1000000 and 10000001 to force escaping here
C wreg: tx: sop - cmd(00001,010) addr(0000) dl dh ccrc
C rreg: tx: sop - cmd(00010,000) addr(0000) ccrc
C tx: - eop
C rx: sop - cmd(010) stat crc
C rx: sop - cmd(000) dl dh stat crc
C rx: - eop
#
.rxsop
.rxcs 00001010 00000000
.rxcds 00010000 1000000010000001 00000000
.rxeop
#
100000000
.txsop
100000000
.tx8 00001010
100000000
.tx8 00000000
100000000
.tx8 10000001
100000000
100000000
.tx8 10000000
100000000
.txcrc
100000000
.tx8 00010000
100000000
100000000
100000000
.tx8 00000000
100000000
.txcrc
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 14: enable and test asynchronous attn notification
C init: tx: sob - cmd(00000,110) addr(00000001) dl dh ccrc - eop
C init: anena(1), itoena(0), ito(0) -> 11111111,1000000000000000
#
.rxsop
.rxcs 00000110 00000000
.rxeop
#
.txsop
.txcad 00000110 11111111 1000000000000000
.txeop
.iowt 10
#
C now ping an attention line, expect oob attn symbol
.wait 50
.rxoob 100000100
.attn 00000001
.iowt 10
C finally read attn flags
C attn: tx: - cmd(00010,101) ccrc - eop
.rxsop
.rxcds 00010101 0000000000000001 00000000
.rxeop
#
.txsop
.txc 00010101
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 15: enable and test idle timeout
C init: tx: sob - cmd(00100,110) addr(00000011) dl dh ccrc - eop
C init: anena(1), itoena(1), ito(9) -> 11111111,1100000000001001
C ito=9 --> divider=10; ce_xsec div is 1:20 --> total every 200 cycles
#
.rxsop
.rxcs 00100110 00000000
.rxeop
.rxoob 100000000
.rxoob 100000000
.rxoob 100000100
.rxoob 100000100
.rxoob 100000100
#
.txsop
.txcad 00100110 11111111 1100000000001001
.txeop
#
.iowt 10
C total ito now 200 cycles; wait 500 cycles, see 2 idle symbols
.wait 500
C ping an attention line, expect oob attn symbol
.attn 00000010
.iowt 10
C wait 500 more cycles, see 2 attn symbols
.wait 500
C finally read attn flags
C attn: tx: - cmd(00110,101) ccrc - eop
.rxsop
.rxcds 00110101 0000000000000010 00000000
.rxeop
#
.txsop
.txc 00110101
.txeop
#
.iowt 10
C wait 500 more cycles, see 2 idle symbols again
.rxoob 100000000
.rxoob 100000000
.wait 500
C finally disable attn notification and idle timeout again
C init: tx: sob - cmd(00000,110) addr(00000000) dl dh ccrc - eop
C init: anena(0), itoena(0), ito(0) -> 11111111,0000000000000000
#
.rxsop
.rxcs 00000110 00000000
.rxeop
#
.txsop
.txcad 00000110 11111111 0000000000000000
.txeop
#
.iowt 10
C -----------------------------------------------------------------------------
C Test 16: attn poll
#
C send 2 attn, expect two idles back
.rxoob 100000000
.rxoob 100000000
100000100
100000100
.iowt 10
#
C ping an attention line
.attn 00000010
#
C send 2 attn, expect two attn back
.rxoob 100000100
.rxoob 100000100
100000100
100000100
.iowt 10
#
/tb/rritblib.vhd
0,0 → 1,152
-- $Id: rritblib.vhd 314 2010-07-09 17:38:41Z 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: rritblib
-- Description: Remote Register Interface test environment components
--
-- Dependencies: -
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.29
-- Revision History:
-- Date Rev Version Comment
-- 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.rrilib.all;
 
package rritblib is
 
-- simbus sb_cntl field usage for rri
constant sbcntl_sbf_cpmon : integer := 15;
constant sbcntl_sbf_rbmon : integer := 14;
 
 
component rritb_cpmon is -- rritb, rri comm port monitor
generic (
DWIDTH : positive := 9); -- data port width (8 or 9)
port (
CLK : in slbit; -- clock
CLK_CYCLE : in slv31 := (others=>'0'); -- clock cycle number
ENA : in slbit := '1'; -- enable monitor output
CP_DI : in slv(DWIDTH-1 downto 0); -- comm port: data in
CP_ENA : in slbit; -- comm port: data enable
CP_BUSY : in slbit; -- comm port: data busy
CP_DO : in slv(DWIDTH-1 downto 0); -- comm port: data out
CP_VAL : in slbit; -- comm port: data valid
CP_HOLD : in slbit -- comm port: data hold
);
end component;
 
component rritb_cpmon_sb is -- simbus wrap for rri comm port monitor
generic (
DWIDTH : positive := 9; -- data port width (8 or 9)
ENAPIN : integer := sbcntl_sbf_cpmon); -- SB_CNTL signal to use for enable
port (
CLK : in slbit; -- clock
CP_DI : in slv(DWIDTH-1 downto 0); -- comm port: data in
CP_ENA : in slbit; -- comm port: data enable
CP_BUSY : in slbit; -- comm port: data busy
CP_DO : in slv(DWIDTH-1 downto 0); -- comm port: data out
CP_VAL : in slbit; -- comm port: data valid
CP_HOLD : in slbit -- comm port: data hold
);
end component;
 
component rritb_rbmon is -- rritb, rri rbus monitor
generic (
DBASE : positive := 2); -- base for writing data values
port (
CLK : in slbit; -- clock
CLK_CYCLE : in slv31 := (others=>'0'); -- clock cycle number
ENA : in slbit := '1'; -- enable monitor output
RB_MREQ : in rb_mreq_type; -- rbus: request
RB_SRES : in rb_sres_type; -- rbus: response
RB_LAM : in slv16 := (others=>'0'); -- rbus: look at me
RB_STAT : in slv3 -- rbus: status flags
);
end component;
 
component rritb_rbmon_sb is -- simbus wrap for rri rbus monitor
generic (
DBASE : positive := 2; -- base for writing data values
ENAPIN : integer := sbcntl_sbf_rbmon); -- SB_CNTL signal to use for enable
port (
CLK : in slbit; -- clock
RB_MREQ : in rb_mreq_type; -- rbus: request
RB_SRES : in rb_sres_type; -- rbus: response
RB_LAM : in slv16 := (others=>'0'); -- rbus: look at me
RB_STAT : in slv3 -- rbus: status flags
);
end component;
 
component rritb_sres_or_mon is -- rribus result or monitor
port (
RB_SRES_1 : in rb_sres_type; -- rb_sres input 1
RB_SRES_2 : in rb_sres_type; -- rb_sres input 2
RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3
RB_SRES_4 : in rb_sres_type := rb_sres_init -- rb_sres input 4
);
end component;
 
component rritb_core is -- core of rri/cext based test bench
generic (
CLK_PERIOD : time := 20 ns; -- clock period
CLK_OFFSET : time := 200 ns; -- clock offset (time to start clock)
SETUP_TIME : time := 5 ns; -- setup time
C2OUT_TIME : time := 10 ns); -- clock to output time
port (
CLK : out slbit; -- main clock
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;
 
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
CP_DI : in slv9; -- comm port: data in
CP_ENA : in slbit; -- comm port: data enable
CP_BUSY : out slbit; -- comm port: data busy
CP_DO : out slv9; -- comm port: data out
CP_VAL : out slbit; -- comm port: data valid
CP_HOLD : in slbit := '0' -- comm port: data hold
);
end component;
 
end rritblib;
/tb/rritb_sres_or_mon.vbom
0,0 → 1,5
# libs
../../slvtypes.vhd
../rrilib.vhd
# design
rritb_sres_or_mon.vhd
/tb/tb_rri_core.vbom
0,0 → 1,6
# configure tb_rri with tbd_rri_core wrapper
# use vhdl configure file (tb_rri_core.vhd) at allow
# that all configurations will co-exist in work library
tbd_rri_gen = tbd_rri_core.vbom
tb_rri.vbom
tb_rri_core.vhd
/tb/rritb_core.vbom
0,0 → 1,12
# libs
../../slvtypes.vhd
../../simlib/simlib.vhd
../../simlib/simbus.vhd
rritblib.vhd
vhpi_rriext.vhd
# components
../../simlib/simclk.vbom
# vhpi
cext_rriext.c
# design
rritb_core.vhd
/tb/rritb_cpmon.vhd
0,0 → 1,144
-- $Id: rritb_cpmon.vhd 314 2010-07-09 17:38:41Z 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: rritb_cpmon - sim
-- Description: rritb: rri comm port monitor
--
-- Dependencies: -
-- Test bench: -
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
-- Revision History:
-- Date Rev Version Comment
-- 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.std_logic_arith.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.simlib.all;
use work.rrilib.all;
 
entity rritb_cpmon is -- rritb, rri comm port monitor
generic (
DWIDTH : positive := 9); -- data port width (8 or 9)
port (
CLK : in slbit; -- clock
CLK_CYCLE : in slv31 := (others=>'0'); -- clock cycle number
ENA : in slbit := '1'; -- enable monitor output
CP_DI : in slv(DWIDTH-1 downto 0); -- comm port: data in
CP_ENA : in slbit; -- comm port: data enable
CP_BUSY : in slbit; -- comm port: data busy
CP_DO : in slv(DWIDTH-1 downto 0); -- comm port: data out
CP_VAL : in slbit; -- comm port: data valid
CP_HOLD : in slbit -- comm port: data hold
);
end rritb_cpmon;
 
 
architecture sim of rritb_cpmon is
 
begin
 
assert DWIDTH=8 or DWIDTH=9
report "assert(DWIDTH=8 or DWIDTH=9)" severity failure;
proc_cpmoni: process
variable oline : line;
variable nbusy : integer := 0;
variable nhold : integer := 0;
 
procedure write_val(L: inout line;
data: in slv(DWIDTH-1 downto 0);
nwait: in integer;
txt1: in string;
txt2: in string) is
variable data9 : slv9 := (others=>'0');
begin
 
writetimestamp(L, CLK_CYCLE, txt1);
 
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);
if nwait > 0 then
write(L, txt2);
write(L, nwait);
end if;
 
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_rri_dat_idle => write(L, string'(" idle"));
when c_rri_dat_sop => write(L, string'(" sop"));
when c_rri_dat_eop => write(L, string'(" eop"));
when c_rri_dat_nak => write(L, string'(" nak"));
when c_rri_dat_attn => write(L, string'(" attn"));
when others => null;
end case;
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 CLK'event and CLK='1'; -- check at end of clock cycle
 
if CP_ENA = '1' then
if CP_BUSY = '1' then
nbusy := nbusy + 1;
else
write_val(oline, CP_DI, nbusy, ": cprx ", " nbusy=");
nbusy := 0;
end if;
else
nbusy := 0;
end if;
if CP_VAL = '1' then
if CP_HOLD = '1' then
nhold := nhold + 1;
else
write_val(oline, CP_DO, nhold, ": cptx ", " nhold=");
nhold := 0;
end if;
else
nhold := 0;
end if;
end loop;
end process proc_cpmoni;
end sim;
/tb/rritb_rbmon.vhd
0,0 → 1,146
-- $Id: rritb_rbmon.vhd 314 2010-07-09 17:38:41Z 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: rritb_rbmon - sim
-- Description: rritb: rri rbus monitor
--
-- Dependencies: -
-- Test bench: -
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
-- Revision History:
-- Date Rev Version Comment
-- 2010-06-05 301 2.1.1 renamed _rpmon -> _rbmon
-- 2010-06-03 299 2.1 new init encoding (WE=0/1 int/ext)
-- 2010-05-02 287 2.0.1 rename RP_STAT->RB_STAT,AP_LAM->RB_LAM
-- drop RP_IINT signal from interfaces
-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface
-- 2008-03-24 129 1.2.1 CLK_CYCLE now 31 bits
-- 2007-12-23 105 1.2 added AP_LAM display
-- 2007-11-24 98 1.1 added RP_IINT support
-- 2007-08-27 76 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.simlib.all;
use work.rrilib.all;
 
entity rritb_rbmon is -- rritb, rri rbus monitor
generic (
DBASE : positive := 2); -- base for writing data values
port (
CLK : in slbit; -- clock
CLK_CYCLE : in slv31 := (others=>'0'); -- clock cycle number
ENA : in slbit := '1'; -- enable monitor output
RB_MREQ : in rb_mreq_type; -- rbus: request
RB_SRES : in rb_sres_type; -- rbus: response
RB_LAM : in slv16 := (others=>'0'); -- rbus: look at me
RB_STAT : in slv3 -- rbus: status flags
);
end rritb_rbmon;
 
 
architecture sim of rritb_rbmon is
begin
 
proc_rbmoni: process
variable oline : line;
variable nhold : integer := 0;
variable data : slv16 := (others=>'0');
variable tag : string(1 to 8) := (others=>' ');
variable err : slbit := '0';
 
procedure write_data(L: inout line;
tag: in string;
data: in slv16;
nhold: in integer := 0;
cond: in boolean := false;
ctxt: in string := " ") is
begin
writetimestamp(L, CLK_CYCLE, tag);
write(L, RB_MREQ.addr, right, 10);
write(L, string'(" "));
writegen(L, data, right, 0, DBASE);
write(L, RB_STAT, right, 4);
if nhold > 0 then
write(L, string'(" nhold="));
write(L, nhold);
end if;
if cond then
write(L, ctxt);
end if;
writeline(output, L);
end procedure write_data;
 
begin
loop
 
if ENA = '0' then -- if disabled
wait until ENA='1'; -- stall process till enabled
end if;
 
wait until CLK'event and CLK='1'; -- check at end of clock cycle
 
if RB_MREQ.req = '1' then
if RB_SRES.err = '1' then
err := '1';
end if;
if RB_SRES.busy = '1' then
nhold := nhold + 1;
else
if RB_MREQ.req = '1' then
if RB_MREQ.we = '0' then
data := RB_SRES.dout;
tag := ": rbre ";
else
data := RB_MREQ.din;
tag := ": rbwe ";
end if;
end if;
 
write_data(oline, tag, data, nhold, err='1', " ERR='1'");
nhold := 0;
end if;
else
if nhold > 0 then
write_data(oline, tag, data, nhold, true, " TIMEOUT");
end if;
nhold := 0;
err := '0';
end if;
 
if RB_MREQ.init = '1' then -- init
if RB_MREQ.we = '1' then
write_data(oline, ": rbini ", RB_MREQ.din); -- external
else
write_data(oline, ": rbint ", RB_MREQ.din); -- internal
end if;
end if;
 
if unsigned(RB_LAM) /= 0 then
write_data(oline, ": rblam ", RB_LAM, 0, true, " RB_LAM active");
end if;
end loop;
end process proc_rbmoni;
end sim;
/tb/tb_rri.vhd
0,0 → 1,720
-- $Id: tb_rri.vhd 314 2010-07-09 17:38:41Z 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_rri - sim
-- Description: Test bench for rri_core
--
-- Dependencies: simlib/simclk
-- genlib/clkdivce
-- tbd_rri_gen [UUT]
--
-- To test: rri_core
-- rri_serport
--
-- Target Devices: generic
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26
-- Revision History:
-- Date Rev Version Comment
-- 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
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.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.rrilib.all;
use work.simlib.all;
 
entity tb_rri is
end tb_rri;
 
architecture sim of tb_rri is
signal CLK : slbit := '0';
signal CE_USEC : slbit := '0';
signal CE_MSEC : slbit := '0';
signal RESET : slbit := '0';
signal CP_DI : slv9 := (others=>'0');
signal CP_ENA : slbit := '0';
signal CP_BUSY : slbit := '0';
signal CP_DO : slv9 := (others=>'0');
signal CP_VAL : slbit := '0';
signal CP_HOLD : slbit := '0';
signal RB_MREQ_req : slbit := '0';
signal RB_MREQ_we : slbit := '0';
signal RB_MREQ_initt: slbit := '0';
signal RB_MREQ_addr : slv8 := (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 : slv16 := (others=>'0');
signal RB_STAT : slv3 := (others=>'0');
signal TXRXACT : slbit := '0';
signal CLK_STOP : slbit := '0';
signal CLK_CYCLE : slv31 := (others=>'0');
 
constant slv9_zero : slv9 := (others=>'0');
constant slv16_zero : slv16 := (others=>'0');
type slv9_array_type is array (0 to 255) of slv9;
type slv16_array_type is array (0 to 255) of slv16;
 
shared variable sv_rxlist : slv9_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_rri_gen is -- rri, generic tb design interface
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rri ito time unit clock enable
CE_USEC : in slbit; -- 1 usec clock enable
RESET : in slbit; -- reset
CP_DI : in slv9; -- comm port: data in
CP_ENA : in slbit; -- comm port: data enable
CP_BUSY : out slbit; -- comm port: data busy
CP_DO : out slv9; -- comm port: data out
CP_VAL : out slbit; -- comm port: data valid
CP_HOLD : in slbit; -- comm port: data hold
RB_MREQ_req : out slbit; -- rbus: request - req
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt: out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv8; -- 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 slv3; -- rbus: status flags
TXRXACT : out slbit -- txrx active flag
);
end component;
 
begin
 
SYSCLK : simclk
generic map (
PERIOD => clock_period,
OFFSET => clock_offset)
port map (
CLK => CLK,
CLK_CYCLE => CLK_CYCLE,
CLK_STOP => CLK_STOP
);
 
CLKDIV : clkdivce
generic map (
CDUWIDTH => 6,
USECDIV => 4,
MSECDIV => 5
)
port map (
CLK => CLK,
CE_USEC => CE_USEC,
CE_MSEC => CE_MSEC
);
 
UUT : tbd_rri_gen
port map (
CLK => CLK,
CE_INT => CE_MSEC,
CE_USEC => CE_USEC,
RESET => RESET,
CP_DI => CP_DI,
CP_ENA => CP_ENA,
CP_BUSY => CP_BUSY,
CP_DO => CP_DO,
CP_VAL => CP_VAL,
CP_HOLD => CP_HOLD,
RB_MREQ_req => RB_MREQ_req,
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_rri_stim";
variable iline : line;
variable oline : line;
variable icmd : slv8 := (others=>'0');
variable iaddr : slv8 := (others=>'0');
variable icnt : slv8 := (others=>'0');
variable istat : slv3 := (others=>'0');
variable iattn : slv8 := (others=>'0');
variable idata : slv16 := (others=>'0');
variable ioob : slv9 := (others=>'0');
variable ok : boolean;
variable dname : string(1 to 6) := (others=>' ');
variable idelta : integer := 0;
variable iowait : integer := 0;
variable txcrc,rxcrc : slv8 := (others=>'0');
variable txlist : slv9_array_type := (others=>slv9_zero);
variable ntxlist : natural := 0;
 
procedure do_tx8 (data : inout slv8) is
begin
txlist(ntxlist) := '0' & data;
ntxlist := ntxlist + 1;
crc8_update_tbl(txcrc, data);
end procedure do_tx8;
procedure do_tx16 (data : inout slv16) is
begin
do_tx8(data( 7 downto 0));
do_tx8(data(15 downto 8));
end procedure do_tx16;
 
procedure do_rx8 (data : inout slv8) is
begin
sv_rxlist(sv_nrxlist) := '0' & data;
sv_nrxlist := sv_nrxlist + 1;
crc8_update_tbl(rxcrc, data);
end procedure do_rx8;
 
procedure do_rx16 (data : inout slv16) is
begin
do_rx8(data( 7 downto 0));
do_rx8(data(15 downto 8));
end procedure do_rx16;
procedure checkmiss_rx is
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)(8));
write(oline, string'(" "));
write(oline, sv_rxlist(i)(7 downto 0));
writeline(output, oline);
end loop;
 
end if;
end procedure checkmiss_rx;
begin
wait for clock_offset - setup_time;
 
file_loop: while not endfile(fstim) loop
 
readline (fstim, iline);
readcomment(iline, ok);
next file_loop when ok;
 
readcommand(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 ".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 ".stat " => -- .stat
read_ea(iline, istat);
RB_STAT <= istat; -- set ext. status lines
wait for clock_period; -- ensure some setling
 
when ".attn " => -- .attn
read_ea(iline, iattn);
RB_LAM(7 downto 0) <= iattn; -- pulse lsb attn lines
wait for clock_period; -- for 1 clock
RB_LAM(7 downto 0) <= (others=>'0');
 
when ".txsop" => -- .txsop send sop
txlist(0) := c_rri_dat_sop;
ntxlist := 1;
txcrc := (others=>'0');
when ".txeop" => -- .txeop send eop
txlist(0) := c_rri_dat_eop;
ntxlist := 1;
txcrc := (others=>'0');
when ".txnak" => -- .txnak send nak
txlist(0) := c_rri_dat_nak;
ntxlist := 1;
txcrc := (others=>'0');
when ".tx8 " => -- .tx8 send 8 bit value
read_ea(iline, iaddr);
ntxlist := 0;
do_tx8(iaddr);
when ".tx16 " => -- .tx16 send 16 bit value
read_ea(iline, idata);
ntxlist := 0;
do_tx16(idata);
when ".txcrc" => -- .txcrc send crc
txlist(0) := '0' & txcrc;
ntxlist := 1;
 
when ".txc " => -- .txc send: cmd crc
read_ea(iline, icmd);
ntxlist := 0;
do_tx8(icmd);
txlist(ntxlist) := '0' & txcrc;
ntxlist := ntxlist + 1;
 
when ".txca " => -- .txc send: cmd addr crc
read_ea(iline, icmd);
read_ea(iline, iaddr);
ntxlist := 0;
do_tx8(icmd);
do_tx8(iaddr);
txlist(ntxlist) := '0' & txcrc;
ntxlist := ntxlist + 1;
 
when ".txcad" => -- .txc send: cmd addr data crc
read_ea(iline, icmd);
read_ea(iline, iaddr);
read_ea(iline, idata);
ntxlist := 0;
do_tx8(icmd);
do_tx8(iaddr);
do_tx16(idata);
txlist(ntxlist) := '0' & txcrc;
ntxlist := ntxlist + 1;
 
when ".txcac" => -- .txc send: cmd addr cnt crc
read_ea(iline, icmd);
read_ea(iline, iaddr);
read_ea(iline, icnt);
ntxlist := 0;
do_tx8(icmd);
do_tx8(iaddr);
do_tx8(icnt);
txlist(ntxlist) := '0' & txcrc;
ntxlist := ntxlist + 1;
 
when ".rxsop" => -- .rxsop expect sop
checkmiss_rx;
sv_rxlist(0) := c_rri_dat_sop;
sv_nrxlist := 1;
sv_rxind := 0;
rxcrc := (others=>'0');
when ".rxeop" => -- .rxeop expect eop
sv_rxlist(sv_nrxlist) := c_rri_dat_eop;
sv_nrxlist := sv_nrxlist + 1;
when ".rxnak" => -- .rxnak expect nak
sv_rxlist(sv_nrxlist) := c_rri_dat_nak;
sv_nrxlist := sv_nrxlist + 1;
when ".rx8 " => -- .rx8 expect 8 bit value
read_ea(iline, iaddr);
do_rx8(iaddr);
when ".rx16 " => -- .rx16 expect 16 bit value
read_ea(iline, idata);
do_rx16(idata);
when ".rxcrc" => -- .rxcrc expect crc
sv_rxlist(sv_nrxlist) := '0' & rxcrc;
sv_nrxlist := sv_nrxlist+1;
 
when ".rxcs " => -- .rxcs expect: cmd stat crc
read_ea(iline, icmd);
read_ea(iline, iaddr);
do_rx8(icmd);
do_rx8(iaddr);
sv_rxlist(sv_nrxlist) := '0' & rxcrc;
sv_nrxlist := sv_nrxlist + 1;
 
when ".rxcds" => -- .rxcsd expect: cmd data stat crc
read_ea(iline, icmd);
read_ea(iline, idata);
read_ea(iline, iaddr);
do_rx8(icmd);
do_rx16(idata);
do_rx8(iaddr);
sv_rxlist(sv_nrxlist) := '0' & rxcrc;
sv_nrxlist := sv_nrxlist + 1;
 
when ".rxccd" => -- .rxccd expect: cmd ccmd dat stat crc
read_ea(iline, icmd);
read_ea(iline, icnt);
read_ea(iline, idata);
read_ea(iline, iaddr);
do_rx8(icmd);
do_rx8(icnt);
do_rx16(idata);
do_rx8(iaddr);
sv_rxlist(sv_nrxlist) := '0' & rxcrc;
sv_nrxlist := sv_nrxlist + 1;
 
when ".rxoob" => -- .rxoob expect: out-of-band symbol
read_ea(iline, ioob);
sv_rxlist(sv_nrxlist) := ioob;
sv_nrxlist := sv_nrxlist + 1;
 
when others => -- bad directive
write(oline, string'("?? unknown directive: "));
write(oline, dname);
writeline(output, oline);
report "aborting" severity failure;
end case;
 
else
read_ea(iline, txlist(0));
ntxlist := 1;
 
end if;
 
next file_loop when ntxlist=0;
for i in 0 to ntxlist-1 loop
CP_DI <= txlist(i);
CP_ENA <= '1';
 
writetimestamp(oline, CLK_CYCLE, ": stim ");
write(oline, txlist(i)(8), right, 3);
write(oline, txlist(i)(7 downto 0), right, 9);
if txlist(i)(8) = '1' then
case txlist(i) is
when c_rri_dat_idle =>
write(oline, string'(" (idle)"));
when c_rri_dat_sop =>
write(oline, string'(" (sop) "));
when c_rri_dat_eop =>
write(oline, string'(" (eop) "));
when c_rri_dat_nak =>
write(oline, string'(" (nak) "));
when c_rri_dat_attn =>
write(oline, string'(" (attn)"));
when others =>
write(oline, string'(" (????)"));
end case;
end if;
writeline(output, oline);
wait for clock_period;
while CP_BUSY = '1' loop
wait for clock_period;
end loop;
CP_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 CLK'event and CLK='1';
wait for c2out_time;
 
if CP_VAL = '1' then
writetimestamp(oline, CLK_CYCLE, ": moni ");
write(oline, CP_DO(8), right, 3);
write(oline, CP_DO(7 downto 0), right, 9);
if CP_DO(8) = '1' then
case CP_DO is
when c_rri_dat_idle =>
write(oline, string'(" (idle)"));
when c_rri_dat_sop =>
write(oline, string'(" (sop) "));
when c_rri_dat_eop =>
write(oline, string'(" (eop) "));
when c_rri_dat_nak =>
write(oline, string'(" (nak) "));
when c_rri_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 CP_DO = sv_rxlist(sv_rxind) then
write(oline, string'(" OK"));
else
write(oline, string'(" FAIL, exp="));
write(oline, sv_rxlist(sv_rxind)(8), right, 2);
write(oline, sv_rxlist(sv_rxind)(7 downto 0), 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;
 
 
-- simulated target:
-- 00000000 ... 00111111: 64 registers, no wait states
-- 00010000 : (16) pointer register for mem 0
-- 00010001 : (17) pointer register for mem 1
-- 00010010 : (18) counter for init's
-- 01000000 ... 01111111: 64 registers, addr(5 downto 0)+1 wait states
-- 10000000 : 256 word memory, addressed by reg(00010000)
-- 10000001 : 256 word memory, addressed by reg(00010001)
-- 10000010 : ping RB_LAM(15 downto 8) on WE access
-- 11000000 : signal err, write noop, read 10101010
-- others : no ack
--
 
proc_targ: process
variable reg0 : slv16_array_type := (others=>slv16_zero);
variable reg1 : slv16_array_type := (others=>slv16_zero);
variable mem0 : slv16_array_type := (others=>slv16_zero);
variable mem1 : slv16_array_type := (others=>slv16_zero);
variable iack : slbit := '0';
variable ierr : slbit := '0';
variable nhold : integer := 0;
variable addr : slv8 := (others=>'0');
variable idout : slv16 := (others=>'0');
variable ind : integer := 0;
variable oline : line;
 
constant c2out_setup : time := clock_period-c2out_time-setup_time;
 
type acc_type is (acc_reg0, acc_reg1, acc_mem0, acc_mem1, acc_lam,
acc_err, acc_bad);
variable acc : acc_type := acc_bad;
 
procedure write_data (pref : in string;
data : in slv16;
iack : in slbit;
ierr : in slbit;
nhold : in integer) is
variable oline : line;
begin
writetimestamp(oline, CLK_CYCLE, pref);
write(oline, RB_MREQ_addr, right, 10);
write(oline, data, right, 18);
if nhold > 0 then
write(oline, string'(" nhold="));
write(oline, nhold, right, 2);
end if;
if iack = '0' then
write(oline, string'(" ACK=0"));
end if;
if ierr = '1' then
write(oline, string'(" ERR=1"));
end if;
writeline(output, oline);
end procedure write_data;
 
begin
 
-- assert c2out_setup>0 report "assert(x>0)" severity FAILURE;
wait until CLK'event and CLK='1';
wait for c2out_time;
 
RB_SRES_ack <= '0';
RB_SRES_busy <= '0';
RB_SRES_err <= '0';
RB_SRES_dout <= (others=>'1');
 
addr := RB_MREQ_addr;
idout := (others=>'0');
nhold := 0;
 
acc := acc_bad;
if unsigned(addr) <= 2#00111111# then
acc := acc_reg0;
elsif unsigned(addr) <= 2#01111111# then
acc := acc_reg1;
nhold := conv_integer(unsigned(addr and "00111111")) + 1;
elsif unsigned(addr) = 2#10000000# then
acc := acc_mem0;
elsif unsigned(addr) = 2#10000001# then
acc := acc_mem1;
elsif unsigned(addr) = 2#10000010# then
acc := acc_lam;
elsif unsigned(addr) = 2#11000000# then
acc := acc_err;
end if;
 
iack := '1';
ierr := '0';
if acc = acc_bad then -- if bad address
iack := '0'; -- don't acknowledge
end if;
 
RB_SRES_ack <= iack;
 
RB_LAM(15 downto 8) <= (others=>'0');
if RB_MREQ_req = '1' then
-- handle WE transactions
if RB_MREQ_we ='1' then
case acc is
when acc_reg0 =>
reg0(conv_integer(unsigned(addr))) := RB_MREQ_din;
when acc_reg1 =>
reg1(conv_integer(unsigned(addr))) := RB_MREQ_din;
when acc_mem0 =>
ind := conv_integer(unsigned(reg0(16) and X"00ff"));
mem0(ind) := RB_MREQ_din;
reg0(16) := unsigned(reg0(16)) + 1;
when acc_mem1 =>
ind := conv_integer(unsigned(reg0(17) and X"00ff"));
mem1(ind) := RB_MREQ_din;
reg0(17) := unsigned(reg0(17)) + 1;
when acc_lam =>
RB_LAM(15 downto 8) <= RB_MREQ_din(15 downto 8);
writetimestamp(oline, CLK_CYCLE,
": targ w ap_lam(15 downto 8) pinged");
writeline(output, oline);
when acc_err =>
ierr := '1';
when others => null;
end case;
write_data(": targ w ", RB_MREQ_din, iack, ierr, nhold);
 
while nhold>0 and RB_MREQ_req='1' loop
RB_SRES_busy <= '1';
wait for clock_period;
nhold := nhold - 1;
end loop;
RB_SRES_ack <= iack;
RB_SRES_err <= ierr;
RB_SRES_busy <= '0';
 
-- handle RE transactions
else
case acc is
when acc_reg0 =>
idout := reg0(conv_integer(unsigned(addr)));
when acc_reg1 =>
idout := reg1(conv_integer(unsigned(addr)));
when acc_mem0 =>
ind := conv_integer(unsigned(reg0(16) and X"00ff"));
idout := mem0(ind);
reg0(16) := unsigned(reg0(16)) + 1;
when acc_mem1 =>
ind := conv_integer(unsigned(reg0(17) and X"00ff"));
idout := mem1(ind);
reg0(17) := unsigned(reg0(17)) + 1;
when acc_err =>
ierr := '1';
idout := "1010101010101010";
when acc_bad =>
idout := "1010101010101010";
when others => null;
end case;
write_data(": targ r ", idout, iack, ierr, nhold);
 
RB_SRES_dout <= "0101010101010101";
wait for c2out_setup;
 
while nhold>0 and RB_MREQ_req='1' loop
RB_SRES_busy <= '1';
wait for clock_period;
nhold := nhold - 1;
end loop;
RB_SRES_ack <= iack;
RB_SRES_err <= ierr;
RB_SRES_busy <= '0';
 
RB_SRES_dout <= idout;
end if;
end if;
 
-- handle INIT transactions (ext and int) (just for monitoring...)
if RB_MREQ_initt = '1' then
if RB_MREQ_we = '1' then -- ext init
write_data(": targ i ", RB_MREQ_din, '1', '0', 0);
reg0(18) := unsigned(reg0(18)) + 1;
else -- int init
write_data(": iint ", RB_MREQ_din, '1', '0', 0);
end if;
end if;
 
end process proc_targ;
 
 
end sim;
/tb/tb_rri_serport.vbom
0,0 → 1,6
# configure tb_rri with tbd_rri_serport wrapper;
# use vhdl configure file (tb_rri_serport.vhd) to allow
# that all configurations will co-exist in work library
tbd_rri_gen = tbd_rri_serport.vbom
tb_rri.vbom
tb_rri_serport.vhd
/tb/tbw.dat
0,0 → 1,12
# $Id: tbw.dat 311 2010-06-30 17:52:37Z mueller $
#
[tb_rri_core]
tb_rri_stim = tb_rri_stim.dat
[tb_rri_serport]
tb_rri_stim = tb_rri_stim.dat
[tb_rritba_ttcombo]
tb_rritba_stim = tb_rritba_ttcombo_stim.dat
[tb_rriext_ttcombo]
tb_rriext_fifo_rx = <fifo>
tb_rriext_fifo_tx = <fifo>
tb_rriext_conf = <null>
/tb/rritb_core.vhd
0,0 → 1,264
-- $Id: rritb_core.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 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: rritb_core - sim
-- Description: Core for a rri and cext based test bench
--
-- Dependencies: simlib/simclk
--
-- To test: generic, any rri/cext based target
--
-- Target Devices: generic
-- Tool versions: xst 11.4; ghdl 0.26
-- Revision History:
-- Date Rev Version Comment
-- 2010-06-05 301 1.1.2 renamed .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.std_logic_arith.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.rritblib.all;
use work.vhpi_rriext.all;
 
entity rritb_core is -- core of rri/cext based test bench
generic (
CLK_PERIOD : time := 20 ns; -- clock period
CLK_OFFSET : time := 200 ns; -- clock offset (time to start clock)
SETUP_TIME : time := 5 ns; -- setup time
C2OUT_TIME : time := 10 ns); -- clock to output time
port (
CLK : out slbit; -- main clock
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 rritb_core;
 
architecture sim of rritb_core is
 
signal CLK_L : slbit := '0';
signal CLK_STOP : slbit := '0';
 
begin
 
SYSCLK : simclk
generic map (
PERIOD => CLK_PERIOD,
OFFSET => CLK_OFFSET)
port map (
CLK => CLK_L,
CLK_CYCLE => SB_CLKCYCLE,
CLK_STOP => CLK_STOP
);
 
CLK <= CLK_L;
proc_conf: process
file fconf : text open read_mode is "tb_rriext_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 ".cpmon" => -- .cpmon
read_ea(iline, ien);
if ien = '1' then
SB_CNTL(sbcntl_sbf_cpmon) <= 'H';
else
SB_CNTL(sbcntl_sbf_cpmon) <= '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 0 ns;
SB_VAL <= 'L';
SB_ADDR <= (others=>'L');
SB_DATA <= (others=>'L');
wait for 0 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:
 
wait; -- halt process here
end process proc_conf;
proc_stim: process
variable icycle : integer := 0;
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
 
wait for CLK_OFFSET;
wait for 10*CLK_PERIOD;
 
stim_loop: loop
wait until CLK_L'event and CLK_L='1';
wait for CLK_PERIOD-SETUP_TIME;
 
SB_ADDR <= (others=>'Z');
SB_DATA <= (others=>'Z');
 
icycle := conv_integer(unsigned(SB_CLKCYCLE));
RX_VAL <= '0';
 
if RX_HOLD = '0' then
irxint := cext_getbyte(icycle);
if irxint >= 0 then
if irxint <= 16#ff# then -- normal data byte
RX_DATA <= conv_std_logic_vector(irxint, 8);
RX_VAL <= '1';
elsif irxint >= 16#1000000# then -- out-of-band message
irxslv := conv_std_logic_vector(irxint, 24);
iaddr := irxslv(23 downto 16);
idata := irxslv(15 downto 0);
writetimestamp(oline, SB_CLKCYCLE, ": 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 := conv_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 "cext_getbyte error: " & integer'image(-irxint)
severity failure;
end if;
end if;
SB_CNTL <= r_sb_cntl;
end loop;
wait for 50*CLK_PERIOD;
CLK_STOP <= '1';
writetimestamp(oline, SB_CLKCYCLE, ": 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 CLK_L'event and CLK_L='1';
wait for C2OUT_TIME;
if TX_ENA = '1' then
itxdata := conv_integer(unsigned(TX_DATA));
itxrc := cext_putbyte(itxdata);
assert itxrc=0
report "cext_putbyte error: " & integer'image(itxrc)
severity failure;
end if;
 
end loop;
end process proc_moni;
 
end sim;
/tb/tbd_rri_core.vhd
0,0 → 1,126
-- $Id: tbd_rri_core.vhd 314 2010-07-09 17:38:41Z 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: tbd_rri_core - syn
-- Description: Wrapper for rri_core to avoid records. It has a port
-- interface which will not be modified by xst synthesis
-- (no records, no generic port).
--
-- Dependencies: rri_core
--
-- To test: rri_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, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26
-- Revision History:
-- Date Rev Version Comment
-- 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.std_logic_arith.all;
 
use work.slvtypes.all;
use work.rrilib.all;
 
entity tbd_rri_core is -- rri_core tb design
-- generic: ATOWIDTH=5; ITOWIDTH=6
-- implements tbd_rri_gen
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rri ito time unit clock enable
CE_USEC : in slbit; -- 1 usec clock enable
RESET : in slbit; -- reset
CP_DI : in slv9; -- comm port: data in
CP_ENA : in slbit; -- comm port: data enable
CP_BUSY : out slbit; -- comm port: data busy
CP_DO : out slv9; -- comm port: data out
CP_VAL : out slbit; -- comm port: data valid
CP_HOLD : in slbit; -- comm port: data hold
RB_MREQ_req : out slbit; -- rbus: request - req
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt : out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv8; -- 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 slv3; -- rbus: status flags
TXRXACT : out slbit -- txrx active flag
);
end entity tbd_rri_core;
 
 
architecture syn of tbd_rri_core is
 
signal CP_FLUSH : slbit := '0';
signal RB_MREQ : rb_mreq_type := rb_mreq_init;
signal RB_SRES : rb_sres_type := rb_sres_init;
 
begin
 
RB_MREQ_req <= RB_MREQ.req;
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 : rri_core
generic map (
ATOWIDTH => 5,
ITOWIDTH => 6)
port map (
CLK => CLK,
CE_INT => CE_INT,
RESET => RESET,
CP_DI => CP_DI,
CP_ENA => CP_ENA,
CP_BUSY => CP_BUSY,
CP_DO => CP_DO,
CP_VAL => CP_VAL,
CP_HOLD => CP_HOLD,
CP_FLUSH => CP_FLUSH,
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT
);
 
TXRXACT <= '0';
end syn;
/tb/.cvsignore
0,0 → 1,19
tb_rri_stim
tb_rri_core
tb_rri_core_[sft]sim
tb_rri_core_ISim
tb_rri_core_ISim_[sft]sim
tb_rri_serport
tb_rri_serport_[sft]sim
tb_rri_serport_ISim
tb_rri_serport_ISim_[sft]sim
tb_rritba_stim
tb_rritba_ttcombo
tb_rritba_ttcombo_[sft]sim
tb_rritba_ttcombo_ISim
tb_rritba_ttcombo_ISim_[sft]sim
tb_rriext_ttcombo
tb_rriext_ttcombo_[sft]sim
tb_rriext_fifo_rx
tb_rriext_fifo_tx
tb_rriext_conf
/tb/Makefile
0,0 → 1,35
# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 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_rri_core tb_rri_serport \
tb_rritba_ttcombo tb_rriext_ttcombo
#
#
.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/vlib/Makefile.ghdl
include $(RETROBASE)/rtl/vlib/Makefile.isim
include $(RETROBASE)/rtl/vlib/Makefile.xflow
#
VBOM_all = $(wildcard *.vbom)
#
include $(VBOM_all:.vbom=.dep_xst)
include $(VBOM_all:.vbom=.dep_ghdl)
include $(VBOM_all:.vbom=.dep_isim)
include $(wildcard *.o.dep_ghdl)
#
/tb/rritb_rbmon.vbom
0,0 → 1,7
# libs
../../slvtypes.vhd
../../simlib/simlib.vhd
../rrilib.vhd
# components
# design
rritb_rbmon.vhd
/tb/rritb_rbmon_sb.vhd
0,0 → 1,80
-- $Id: rritb_rbmon_sb.vhd 314 2010-07-09 17:38:41Z 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: rritb_rbmon_sb - sim
-- Description: rritb: rri reg port monitor; simbus wrapper
--
-- Dependencies: simbus
-- Test bench: -
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
-- Revision History:
-- Date Rev Version Comment
-- 2010-06-05 301 2.0.2 renamed _rpmon -> _rbmon
-- 2010-05-02 287 2.0.1 rename RP_STAT->RB_STAT,AP_LAM->RB_LAM
-- drop RP_IINT signal from interfaces
-- use sbcntl_sbf_cpmon def
-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface
-- 2007-12-23 105 1.2 added AP_LAM display
-- 2007-11-24 98 1.1 added RP_IINT support
-- 2007-08-27 76 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.rrilib.all;
use work.rritblib.all;
 
entity rritb_rbmon_sb is -- simbus wrap for rri rbus monitor
generic (
DBASE : positive := 2; -- base for writing data values
ENAPIN : integer := sbcntl_sbf_rbmon); -- SB_CNTL signal to use for enable
port (
CLK : in slbit; -- clock
RB_MREQ : in rb_mreq_type; -- rbus: request
RB_SRES : in rb_sres_type; -- rbus: response
RB_LAM : in slv16 := (others=>'0'); -- rbus: look at me
RB_STAT : in slv3 -- rbus: status flags
);
end rritb_rbmon_sb;
 
 
architecture sim of rritb_rbmon_sb is
 
signal ENA : slbit := '0';
begin
 
assert ENAPIN>=SB_CNTL'low and ENAPIN<=SB_CNTL'high
report "assert(ENAPIN in SB_CNTL'range)" severity failure;
 
ENA <= to_x01(SB_CNTL(ENAPIN));
RBMON : rritb_rbmon
generic map (
DBASE => DBASE)
port map (
CLK => CLK,
CLK_CYCLE => SB_CLKCYCLE,
ENA => ENA,
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT
);
end sim;
/tb/vhpi_rriext.vhd
0,0 → 1,55
-- $Id: vhpi_rriext.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 2007- 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: vhpi_rriext
-- Description: VHDL procedural interface: VHDL declaration side
--
-- Dependencies: -
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
-- Revision History:
-- Date Rev Version Comment
-- 2007-08-26 76 1.0 Initial version
------------------------------------------------------------------------------
 
package vhpi_rriext is
 
impure function cext_getbyte (
clk : integer) -- clock cycle
return integer;
attribute foreign of cext_getbyte : function is "VHPIDIRECT cext_getbyte";
impure function cext_putbyte (
dat : integer) -- data byte
return integer;
attribute foreign of cext_putbyte : function is "VHPIDIRECT cext_putbyte";
 
end vhpi_rriext;
 
package body vhpi_rriext is
 
impure function cext_getbyte (
clk : integer) -- clock cycle
return integer is
begin
report "cext_getbyte not vhpi'ed" severity failure;
end cext_getbyte;
 
impure function cext_putbyte (
dat : integer) -- data byte
return integer is
begin
report "cext_getbyte not vhpi'ed" severity failure;
end cext_putbyte;
 
end vhpi_rriext;
/tb/tbd_rri_serport.vhd
0,0 → 1,246
-- $Id: tbd_rri_serport.vhd 314 2010-07-09 17:38:41Z 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: tbd_rri_serport - syn
-- Description: Wrapper for rri_core plus rri_serport with an interface
-- compatible to the rri_core only module.
-- NOTE: this implementation is a hack, should be redone
-- using configurations.
--
-- Dependencies: tbu_rri_serport [UUT]
-- serport_uart_tx
-- serport_uart_rx
-- byte2cdata
-- cdata2byte
--
-- To test: rri_serport
--
-- Target Devices: generic
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
-- Revision History:
-- Date Rev Version Comment
-- 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.std_logic_arith.all;
-- synthesis translate_off
use ieee.std_logic_textio.all;
use std.textio.all;
-- synthesis translate_on
 
use work.slvtypes.all;
use work.rrilib.all;
use work.comlib.all;
use work.serport.all;
 
entity tbd_rri_serport is -- rri_core+rri_serport tb design
-- implements tbd_rri_gen
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rri ito time unit clock enable
CE_USEC : in slbit; -- 1 usec clock enable
RESET : in slbit; -- reset
CP_DI : in slv9; -- comm port: data in
CP_ENA : in slbit; -- comm port: data enable
CP_BUSY : out slbit; -- comm port: data busy
CP_DO : out slv9; -- comm port: data out
CP_VAL : out slbit; -- comm port: data valid
CP_HOLD : in slbit; -- comm port: data hold
RB_MREQ_req : out slbit; -- rbus: request - req
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt : out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv8; -- 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 slv3; -- rbus: status flags
TXRXACT : out slbit -- txrx active flag
);
end entity tbd_rri_serport;
 
 
architecture syn of tbd_rri_serport is
 
signal RRI_RXSD : slbit := '0';
signal RRI_TXSD : 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 := conv_std_logic_vector(1,13);
-- NOTE: change also CDINIT in tbu_rri_serport !!
component tbu_rri_serport is -- rri core+serport combo
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rri 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 (uart view)
TXSD : out slbit; -- transmit serial data (uart view)
RB_MREQ_req : out slbit; -- rbus: request - req
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt : out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv8; -- 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 slv3 -- rbus: status flags
);
end component;
 
constant CPREF : slv4 := "1000";
constant NCOMM : positive := 4;
 
begin
 
UUT : tbu_rri_serport
port map (
CLK => CLK,
CE_INT => CE_INT,
CE_USEC => CE_USEC,
CE_MSEC => '1',
RESET => RESET,
RXSD => RRI_RXSD,
TXSD => RRI_TXSD,
RB_MREQ_req => RB_MREQ_req,
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 => 13)
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 => 13)
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
generic map (
CPREF => CPREF,
NCOMM => NCOMM)
port map (
CLK => CLK,
RESET => RESET,
DI => RXDATA,
ENA => RXVAL,
BUSY => open,
DO => CP_DO,
VAL => CP_VAL,
HOLD => CP_HOLD
);
 
CD2B : cdata2byte -- 9bit comma,data -> byte stream
generic map (
CPREF => CPREF,
NCOMM => NCOMM)
port map (
CLK => CLK,
RESET => RESET,
DI => CP_DI,
ENA => CP_ENA,
BUSY => CP_BUSY,
DO => TXDATA,
VAL => TXENA,
HOLD => TXBUSY
);
 
-- synthesis translate_off
proc_moni: process
variable oline : line;
constant c2out_time : time := 10 ns; -- FIXME - this isn't modular !!!
 
begin
 
loop
wait until CLK'event and CLK='1';
wait for c2out_time;
 
if TXENA='1' and TXBUSY='0' then
write(oline, now, right, 12);
write(oline, string'(" "));
write(oline, string'(": tx "));
write(oline, string'(" "));
write(oline, TXDATA, right, 9);
writeline(output, oline);
end if;
if RXVAL = '1' then
write(oline, now, right, 12);
write(oline, string'(" "));
write(oline, string'(": rx "));
write(oline, string'(" "));
write(oline, RXDATA, right, 9);
writeline(output, oline);
end if;
end loop;
 
end process proc_moni;
-- synthesis translate_on
 
end syn;
/tb/tb_rri.vbom
0,0 → 1,17
# Not meant for direct top level usage. Used with
# tb_rri_(core|serport|...)[_ssim].vbom and config
# lines to generate the different cases.
#
# libs
../../slvtypes.vhd
../../genlib/genlib.vhd
../../comlib/comlib.vhd
../rrilib.vhd
../../simlib/simlib.vhd
# components
../../simlib/simclk.vbom
../../genlib/clkdivce.vbom
tbd_rri_gen : tbd_rri_core.vbom
# design
tb_rri.vhd
@top:tb_rri
/tb/tbu_rri_serport.vbom
0,0 → 1,8
# libs
../../slvtypes.vhd
../rrilib.vhd
# components
../rri_core.vbom
../rri_serport.vbom
# design
tbu_rri_serport.vhd
/tb/tbd_rri_core.vbom
0,0 → 1,7
# libs
../../slvtypes.vhd
../rrilib.vhd
# components
../rri_core.vbom
# design
tbd_rri_core.vhd
/tb/rritb_cpmon_sb.vbom
0,0 → 1,9
# libs
../../slvtypes.vhd
../../simlib/simlib.vhd
../../simlib/simbus.vhd
rritblib.vhd
# components
rritb_cpmon.vbom
# design
rritb_cpmon_sb.vhd
/tb/tbu_rri_serport.vhd
0,0 → 1,150
-- $Id: tbu_rri_serport.vhd 314 2010-07-09 17:38:41Z 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: tbu_rri_serport - syn
-- Description: Wrapper for rri_core plus rri_serport to avoid records. It
-- has a port interface which will not be modified by xst
-- synthesis (no records, no generic port).
--
-- Dependencies: rri_core
-- rri_serport
--
-- To test: rri_serport
--
-- Target Devices: generic
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 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.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26
-- Revision History:
-- Date Rev Version Comment
-- 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.std_logic_arith.all;
 
use work.slvtypes.all;
use work.rrilib.all;
 
entity tbu_rri_serport is -- rri core+serport combo
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rri 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)
RB_MREQ_req : out slbit; -- rbus: request - req
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt: out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv8; -- 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 slv3 -- rbus: status flags
);
end entity tbu_rri_serport;
 
 
architecture syn of tbu_rri_serport is
 
signal RB_MREQ : rb_mreq_type := rb_mreq_init;
signal RB_SRES : rb_sres_type := rb_sres_init;
 
signal CTS_N : slbit := '0';
signal RTS_N : slbit := '0';
 
signal CP_DI : slv9 := (others=>'0');
signal CP_ENA : slbit := '0';
signal CP_BUSY : slbit := '0';
signal CP_DO : slv9 := (others=>'0');
signal CP_VAL : slbit := '0';
signal CP_HOLD : slbit := '0';
signal CP_FLUSH : slbit := '0';
begin
 
RB_MREQ_req <= RB_MREQ.req;
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;
CORE : rri_core
port map (
CLK => CLK,
CE_INT => CE_INT,
RESET => RESET,
CP_DI => CP_DI,
CP_ENA => CP_ENA,
CP_BUSY => CP_BUSY,
CP_DO => CP_DO,
CP_VAL => CP_VAL,
CP_HOLD => CP_HOLD,
CP_FLUSH => CP_FLUSH,
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT
);
 
SERPORT : rri_serport
generic map (
CPREF => "1000",
CDWIDTH => 13,
CDINIT => 1) -- NOTE: change also CLKDIV in tbd_rri_serport !!
port map (
CLK => CLK,
CE_USEC => CE_USEC,
CE_MSEC => CE_MSEC,
RESET => RESET,
RXSD => RXSD,
TXSD => TXSD,
CTS_N => CTS_N,
RTS_N => RTS_N,
CP_DI => CP_DI,
CP_ENA => CP_ENA,
CP_BUSY => CP_BUSY,
CP_DO => CP_DO,
CP_VAL => CP_VAL,
CP_HOLD => CP_HOLD,
CP_FLUSH => CP_FLUSH
);
end syn;
/tb/tbd_rri_serport.vbom
0,0 → 1,13
# libs
../../slvtypes.vhd
../../comlib/comlib.vhd
../../serport/serport.vhd
../rrilib.vhd
# components
tbu_rri_serport : tbu_rri_serport.vbom
../../serport/serport_uart_tx.vbom
../../serport/serport_uart_rx.vbom
../../comlib/byte2cdata.vbom
../../comlib/cdata2byte.vbom
# design
tbd_rri_serport.vhd
/tb/rritb_rbmon_sb.vbom
0,0 → 1,10
# libs
../../slvtypes.vhd
../../simlib/simlib.vhd
../../simlib/simbus.vhd
../rrilib.vhd
rritblib.vhd
# components
rritb_rbmon.vbom
# design
rritb_rbmon_sb.vhd
/tb/rritb_sres_or_mon.vhd
0,0 → 1,108
-- $Id: rritb_sres_or_mon.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 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: rritb_sres_or_mon - sim
-- Description: rribus result or monitor
--
-- Dependencies: -
-- Test bench: -
-- Tool versions: ghdl 0.29
-- Revision History:
-- Date Rev Version Comment
-- 2010-06-26 309 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.rrilib.all;
 
-- ----------------------------------------------------------------------------
 
entity rritb_sres_or_mon is -- rribus result or monitor
port (
RB_SRES_1 : in rb_sres_type; -- rb_sres input 1
RB_SRES_2 : in rb_sres_type; -- rb_sres input 2
RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3
RB_SRES_4 : in rb_sres_type := rb_sres_init -- rb_sres input 4
);
end rritb_sres_or_mon;
 
architecture sim of rritb_sres_or_mon is
begin
 
proc_comb : process (RB_SRES_1, RB_SRES_2, RB_SRES_3, RB_SRES_4)
constant dzero : slv16 := (others=>'0');
variable oline : line;
variable nack : integer := 0;
variable nbusy : integer := 0;
variable nerr : integer := 0;
variable ndout : integer := 0;
begin
 
nack := 0;
nbusy := 0;
nerr := 0;
ndout := 0;
if RB_SRES_1.ack /= '0' then nack := nack + 1; end if;
if RB_SRES_2.ack /= '0' then nack := nack + 1; end if;
if RB_SRES_3.ack /= '0' then nack := nack + 1; end if;
if RB_SRES_4.ack /= '0' then nack := nack + 1; end if;
 
if RB_SRES_1.busy /= '0' then nbusy := nbusy + 1; end if;
if RB_SRES_2.busy /= '0' then nbusy := nbusy + 1; end if;
if RB_SRES_3.busy /= '0' then nbusy := nbusy + 1; end if;
if RB_SRES_4.busy /= '0' then nbusy := nbusy + 1; end if;
 
if RB_SRES_1.err /= '0' then nerr := nerr + 1; end if;
if RB_SRES_2.err /= '0' then nerr := nerr + 1; end if;
if RB_SRES_3.err /= '0' then nerr := nerr + 1; end if;
if RB_SRES_4.err /= '0' then nerr := nerr + 1; end if;
 
if RB_SRES_1.dout /= dzero then ndout := ndout + 1; end if;
if RB_SRES_2.dout /= dzero then ndout := ndout + 1; end if;
if RB_SRES_3.dout /= dzero then ndout := ndout + 1; end if;
if RB_SRES_4.dout /= dzero then ndout := ndout + 1; end if;
 
if nack>1 or nbusy>1 or nerr>1 or ndout>1 then
write(oline, now, right, 12);
if nack > 1 then
write(oline, string'(" #ack="));
write(oline, nack);
end if;
if nbusy > 1 then
write(oline, string'(" #busy="));
write(oline, nbusy);
end if;
if nerr > 1 then
write(oline, string'(" #err="));
write(oline, nerr);
end if;
if ndout > 1 then
write(oline, string'(" #dout="));
write(oline, ndout);
end if;
write(oline, string'(" FAIL in "));
write(oline, rritb_sres_or_mon'path_name);
writeline(output, oline);
end if;
end process proc_comb;
end sim;
/tb/tb_rri_core.vhd
0,0 → 1,44
-- $Id: tb_rri_core.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 2007- 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_rri_core
-- Description: Configuration for tb_rri_core for tb_rri.
--
-- Dependencies: tbd_rri_gen
--
-- To test: rri_core
--
-- Target Devices: generic
--
-- Verified (with tb_rri_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_rri_core of tb_rri is
 
for sim
for all : tbd_rri_gen
use entity work.tbd_rri_core;
end for;
end for;
 
end tb_rri_core;
/tb
tb Property changes : Added: svn:ignore ## -0,0 +1,51 ## +*.dep_ghdl +*.dep_isim +*.dep_xst +work-obj93.cf +*.vcd +*.ghw +*.sav +*.tmp +*.exe +ise +xflow.his +*.ngc +*.ncd +*.pcf +*.bit +*.msk +isim +isim.log +isim.wdb +fuse.log +*_[sft]sim.vhd +*_tsim.sdf +*_xst.log +*_tra.log +*_twr.log +*_map.log +*_par.log +*_pad.log +*_bgn.log +*_svn.log +*_sum.log +*_[dsft]sim.log +tb_rri_stim +tb_rri_core +tb_rri_core_[sft]sim +tb_rri_core_ISim +tb_rri_core_ISim_[sft]sim +tb_rri_serport +tb_rri_serport_[sft]sim +tb_rri_serport_ISim +tb_rri_serport_ISim_[sft]sim +tb_rritba_stim +tb_rritba_ttcombo +tb_rritba_ttcombo_[sft]sim +tb_rritba_ttcombo_ISim +tb_rritba_ttcombo_ISim_[sft]sim +tb_rriext_ttcombo +tb_rriext_ttcombo_[sft]sim +tb_rriext_fifo_rx +tb_rriext_fifo_tx +tb_rriext_conf Index: rb_sres_or_2.vhd =================================================================== --- rb_sres_or_2.vhd (nonexistent) +++ rb_sres_or_2.vhd (revision 7) @@ -0,0 +1,76 @@ +-- $Id: rb_sres_or_2.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 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: rb_sres_or_2 - syn +-- Description: rribus result or, 2 input +-- +-- Dependencies: rritb_sres_or_mon [sim only] +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-26 309 1.1 add rritb_sres_or_mon +-- 2008-08-22 161 1.0.1 renamed rri_rbres_ -> rb_sres_ +-- 2008-01-20 113 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.rrilib.all; +-- synthesis translate_off +use work.rritblib.all; +-- synthesis translate_on + +-- ---------------------------------------------------------------------------- + +entity rb_sres_or_2 is -- rribus result or, 2 input + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2 + RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output + ); +end rb_sres_or_2; + +architecture syn of rb_sres_or_2 is + +begin + + proc_comb : process (RB_SRES_1, RB_SRES_2) + begin + + RB_SRES_OR.ack <= RB_SRES_1.ack or + RB_SRES_2.ack; + RB_SRES_OR.busy <= RB_SRES_1.busy or + RB_SRES_2.busy; + RB_SRES_OR.err <= RB_SRES_1.err or + RB_SRES_2.err; + RB_SRES_OR.dout <= RB_SRES_1.dout or + RB_SRES_2.dout; + + end process proc_comb; + +-- synthesis translate_off + ORMON : rritb_sres_or_mon + port map ( + RB_SRES_1 => RB_SRES_1, + RB_SRES_2 => RB_SRES_2, + RB_SRES_3 => rb_sres_init, + RB_SRES_4 => rb_sres_init + ); +-- synthesis translate_on + +end syn; Index: rb_sres_or_3.vhd =================================================================== --- rb_sres_or_3.vhd (nonexistent) +++ rb_sres_or_3.vhd (revision 7) @@ -0,0 +1,81 @@ +-- $Id: rb_sres_or_3.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 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: rb_sres_or_3 - syn +-- Description: rribus result or, 3 input +-- +-- Dependencies: rritb_sres_or_mon [sim only] +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-26 309 1.1 add rritb_sres_or_mon +-- 2008-08-22 161 1.0.1 renamed rri_rbres_ -> rb_sres_ +-- 2008-01-20 113 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.rrilib.all; +-- synthesis translate_off +use work.rritblib.all; +-- synthesis translate_on + +-- ---------------------------------------------------------------------------- + +entity rb_sres_or_3 is -- rribus result or, 3 input + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2 + RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3 + RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output + ); +end rb_sres_or_3; + +architecture syn of rb_sres_or_3 is + +begin + + proc_comb : process (RB_SRES_1, RB_SRES_2, RB_SRES_3) + begin + + RB_SRES_OR.ack <= RB_SRES_1.ack or + RB_SRES_2.ack or + RB_SRES_3.ack; + RB_SRES_OR.busy <= RB_SRES_1.busy or + RB_SRES_2.busy or + RB_SRES_3.busy; + RB_SRES_OR.err <= RB_SRES_1.err or + RB_SRES_2.err or + RB_SRES_3.err; + RB_SRES_OR.dout <= RB_SRES_1.dout or + RB_SRES_2.dout or + RB_SRES_3.dout; + + end process proc_comb; + +-- synthesis translate_off + ORMON : rritb_sres_or_mon + port map ( + RB_SRES_1 => RB_SRES_1, + RB_SRES_2 => RB_SRES_2, + RB_SRES_3 => RB_SRES_3, + RB_SRES_4 => rb_sres_init + ); +-- synthesis translate_on + +end syn; Index: rri_core_serport.vhd =================================================================== --- rri_core_serport.vhd (nonexistent) +++ rri_core_serport.vhd (revision 7) @@ -0,0 +1,170 @@ +-- $Id: rri_core_serport.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- 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: rri_core_serport - syn +-- Description: rri: core + serport combo, with cpmon and rbmon +-- +-- Dependencies: rri_serport +-- rri_core +-- rritb_cpmon_sb [sim only] +-- rritb_rbmon_sb [sim only] +-- +-- Test bench: - +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-04-03 275 11.4 L68 xc3s1000-4 280 600 18 375 s 9.8 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-05 301 1.2.2 renamed _rpmon -> _rbmon +-- 2010-06-03 300 1.2.1 use FAWIDTH=5 +-- 2010-05-02 287 1.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 1.1 drop RTSFBUF generic +-- 2010-04-10 275 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.rrilib.all; +-- synthesis translate_off +use work.rritblib.all; +-- synthesis translate_on + +entity rri_core_serport is -- rri, core+serport with cpmon+rbmon + generic ( + ATOWIDTH : positive := 5; -- access timeout counter width + ITOWIDTH : positive := 6; -- idle timeout counter width + FAWIDTH : positive := 5; -- rx fifo address port width + CDWIDTH : positive := 13; -- clk divider width + CDINIT : natural := 15); -- clk divider initial/reset setting + 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 ito time unit 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 := '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 slv3 -- rbus: status flags + ); +end entity rri_core_serport; + + +architecture syn of rri_core_serport is + + signal CP_DI : slv9 := (others=>'0'); + signal CP_ENA : slbit := '0'; + signal CP_BUSY : slbit := '0'; + signal CP_DO : slv9 := (others=>'0'); + signal CP_VAL : slbit := '0'; + signal CP_HOLD : slbit := '0'; + signal CP_FLUSH : slbit := '0'; + + signal RB_MREQ_L : rb_mreq_type := rb_mreq_init; -- local, readable RB_MREQ + +begin + + SER2RRI : rri_serport + generic map ( + CPREF => "1000", + FAWIDTH => FAWIDTH, + CDWIDTH => CDWIDTH, + CDINIT => CDINIT) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC, + RESET => RESET, + RXSD => RXSD, + TXSD => TXSD, + CTS_N => CTS_N, + RTS_N => RTS_N, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD, + CP_FLUSH => CP_FLUSH + ); + + RRI : rri_core + generic map ( + ATOWIDTH => ATOWIDTH, + ITOWIDTH => ITOWIDTH) + port map ( + CLK => CLK, + CE_INT => CE_INT, + RESET => RESET, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD, + CP_FLUSH => CP_FLUSH, + RB_MREQ => RB_MREQ_L, + RB_SRES => RB_SRES, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); + + -- vhdl'93 unfortunately doesn't allow to read a signal bound to an out port + -- because RB_MREQ is read by the monitors, an extra internal + -- signal must be used. This will not be needed with vhdl'2000 anymore + + RB_MREQ <= RB_MREQ_L; + +-- synthesis translate_off + CPMON : rritb_cpmon_sb + generic map ( + DWIDTH => CP_DI'length, + ENAPIN => 15) + port map ( + CLK => CLK, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD + ); + + RBMON : rritb_rbmon_sb + generic map ( + DBASE => 8, + ENAPIN => 14) + port map ( + CLK => CLK, + RB_MREQ => RB_MREQ_L, + RB_SRES => RB_SRES, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); +-- synthesis translate_on + +end syn; Index: rb_sres_or_2.vbom =================================================================== --- rb_sres_or_2.vbom (nonexistent) +++ rb_sres_or_2.vbom (revision 7) @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +rrilib.vhd +[ghdl,isim]tb/rritblib.vhd +# components +[ghdl,isim]tb/rritb_sres_or_mon.vbom +# design +rb_sres_or_2.vhd Index: rb_sres_or_3.vbom =================================================================== --- rb_sres_or_3.vbom (nonexistent) +++ rb_sres_or_3.vbom (revision 7) @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +rrilib.vhd +[ghdl,isim]tb/rritblib.vhd +# components +[ghdl,isim]tb/rritb_sres_or_mon.vbom +# design +rb_sres_or_3.vhd Index: rrilib.vhd =================================================================== --- rrilib.vhd (nonexistent) +++ rrilib.vhd (revision 7) @@ -0,0 +1,259 @@ +-- $Id: rrilib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 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. +-- +------------------------------------------------------------------------------ +-- Package Name: rrilib +-- Description: Remote Register Interface components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 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 work.slvtypes.all; + +package rrilib is + +constant c_rri_dat_idle : slv9 := "100000000"; +constant c_rri_dat_sop : slv9 := "100000001"; +constant c_rri_dat_eop : slv9 := "100000010"; +constant c_rri_dat_nak : slv9 := "100000011"; +constant c_rri_dat_attn : slv9 := "100000100"; + +constant c_rri_cmd_rreg : slv3 := "000"; +constant c_rri_cmd_rblk : slv3 := "001"; +constant c_rri_cmd_wreg : slv3 := "010"; +constant c_rri_cmd_wblk : slv3 := "011"; +constant c_rri_cmd_stat : slv3 := "100"; +constant c_rri_cmd_attn : slv3 := "101"; +constant c_rri_cmd_init : slv3 := "110"; + +constant c_rri_iint_rbf_anena: integer := 15; -- anena flag +constant c_rri_iint_rbf_itoena: integer := 14; -- itoena flag +subtype c_rri_iint_rbf_itoval is integer range 7 downto 0; -- command code + +subtype c_rri_cmd_rbf_seq is integer range 7 downto 3; -- sequence number +subtype c_rri_cmd_rbf_code is integer range 2 downto 0; -- command code + +subtype c_rri_stat_rbf_stat is integer range 7 downto 5; -- ext status bits +constant c_rri_stat_rbf_attn: integer := 4; -- attention flags set +constant c_rri_stat_rbf_ccrc: integer := 3; -- command crc error +constant c_rri_stat_rbf_dcrc: integer := 2; -- data crc error +constant c_rri_stat_rbf_ioto: integer := 1; -- i/o time out +constant c_rri_stat_rbf_ioerr: integer := 0; -- i/o error + +type rb_mreq_type is record -- rribus - master request + req : slbit; -- request + we : slbit; -- write enable + init : slbit; -- init + addr : slv8; -- address + din : slv16; -- data (input to slave) +end record rb_mreq_type; + +constant rb_mreq_init : rb_mreq_type := + ('0','0','0', -- req, we, init + (others=>'0'), -- addr + (others=>'0')); -- din + +type rb_sres_type is record -- rribus - slave response + ack : slbit; -- acknowledge + busy : slbit; -- busy + err : slbit; -- error + dout : slv16; -- data (output from slave) +end record rb_sres_type; + +constant rb_sres_init : rb_sres_type := + ('0','0','0', -- ack, busy, err + (others=>'0')); -- dout + +component rri_core is -- rri, core interface + generic ( + ATOWIDTH : positive := 5; -- access timeout counter width + ITOWIDTH : positive := 6); -- idle timeout counter width + port ( + CLK : in slbit; -- clock + CE_INT : in slbit := '0'; -- rri ito time unit clock enable + RESET : in slbit; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit; -- comm port: data hold + CP_FLUSH : out slbit; -- comm port: data flush + 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 slv3 -- rbus: status flags + ); +end component; + +component rricp_aif is -- rri comm port, abstract interface + port ( + CLK : in slbit; -- clock + CE_INT : in slbit := '0'; -- rri ito time unit clock enable + RESET : in slbit :='0'; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit := '0' -- comm port: data hold + ); +end component; + +component rrirp_aif is -- rri reg port, abstract interface + port ( + CLK : in slbit; -- clock + RESET : in slbit := '0'; -- reset + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : out rb_sres_type; -- rbus: response + RB_LAM : out slv16; -- rbus: look at me + RB_STAT : out slv3 -- rbus: status flags + ); +end component; + +component rri_serport is -- rri serport adapter + generic ( + CPREF : slv4 := "1000"; -- comma prefix + FAWIDTH : positive := 5; -- rx fifo address port width + CDWIDTH : positive := 13; -- clk divider width + CDINIT : natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + 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 := '0'; -- clear to send (act.low, board view) + RTS_N : out slbit; -- request to send (act.low, board view) + CP_DI : out slv9; -- comm port: data in + CP_ENA : out slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv9; -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : out slbit; -- comm port: data hold + CP_FLUSH : in slbit := '0' -- comm port: data flush + ); +end component; + +component rri_core_serport is -- rri, core+serport with cpmon+rbmon + generic ( + ATOWIDTH : positive := 5; -- access timeout counter width + ITOWIDTH : positive := 6; -- idle timeout counter width + FAWIDTH : positive := 5; -- rx fifo address port width + CDWIDTH : positive := 13; -- clk divider width + CDINIT : natural := 15); -- clk divider initial/reset setting + 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 ito time unit 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 := '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 slv3 -- rbus: status flags + ); +end component; + +component rb_sres_or_2 is -- rribus result or, 2 input + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2 + RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output + ); +end component; +component rb_sres_or_3 is -- rribus result or, 3 input + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2 + RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3 + RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output + ); +end component; +component rb_sres_or_4 is -- rribus result or, 4 input + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2 + RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3 + RB_SRES_4 : in rb_sres_type := rb_sres_init; -- rb_sres input 4 + RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output + ); +end component; + +component rri_wreg_rw_3 is -- rri: wide register r/w 3 bit select + generic ( + DWIDTH : positive := 16); + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + FADDR : slv3; -- field address + SEL : slbit; -- select + DATA : out slv(DWIDTH-1 downto 0); -- data + RB_MREQ : in rb_mreq_type; -- rribus request + RB_SRES : out rb_sres_type -- rribus response + ); +end component; + +component rri_wreg_w_3 is -- rri: wide register w-o 3 bit select + generic ( + DWIDTH : positive := 16); + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + FADDR : slv3; -- field address + SEL : slbit; -- select + DATA : out slv(DWIDTH-1 downto 0); -- data + RB_MREQ : in rb_mreq_type; -- rribus request + RB_SRES : out rb_sres_type -- rribus response + ); +end component; + +component rri_wreg_r_3 is -- rri: wide register r-o 3 bit select + generic ( + DWIDTH : positive := 16); + port ( + FADDR : slv3; -- field address + SEL : slbit; -- select + DATA : in slv(DWIDTH-1 downto 0); -- data + RB_SRES : out rb_sres_type -- rribus response + ); +end component; + +end rrilib; Index: rri_core_serport.vbom =================================================================== --- rri_core_serport.vbom (nonexistent) +++ rri_core_serport.vbom (revision 7) @@ -0,0 +1,11 @@ +# libs +../slvtypes.vhd +rrilib.vhd +[ghdl,isim]tb/rritblib.vhd +# components +rri_serport.vbom +rri_core.vbom +[ghdl,isim]tb/rritb_cpmon_sb.vbom +[ghdl,isim]tb/rritb_rbmon_sb.vbom +# design +rri_core_serport.vhd Index: rri_core.vhd =================================================================== --- rri_core.vhd (nonexistent) +++ rri_core.vhd (revision 7) @@ -0,0 +1,809 @@ +-- $Id: rri_core.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 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: rri_core - syn +-- Description: rri: core interface +-- +-- Dependencies: comlib/crc8 +-- +-- Test bench: tb/tb_rri_core +-- tb/tb_rritba_ttcombo +-- tb/tb_rriext_ttcombo +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-06-06 302 11.4 L68 xc3s1000-4 151 323 0 197 s 8.9 +-- 2010-04-03 274 11.4 L68 xc3s1000-4 148 313 0 190 s 8.0 +-- 2009-07-11 232 10.1.03 K39 xc3s1000-4 147 321 0 197 s 8.3 +-- +-- Revision History: +-- Date Rev Version Comment +-- 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 +------------------------------------------------------------------------------ +-- +-- Overall protocol: +-- _idle : expect +-- sop -> _txsop (echo sop, , to _txsop, _rxcmd) +-- eop -> _txeop (send nak,eop , to _txnak, _txeop, _idle) +-- nak -> _txnak (silently ignore nak) +-- attn -> _txito (send ito , to _idle) +-- data -> _idle (silently ignore data) +-- _error: expect +-- sop -> _txnak (send nak , to _txnak, _error) +-- eop -> _txeop (echo eop , to _txeop, _idle) +-- nak -> _txnak (echo nak , to _txnak, _error) +-- attn -> _txito (silently ignore attn) +-- data -> _idle (silently ignore data) +-- _rxcmd: expect +-- sop -> _txnak (send nak , to _txnak, _error) +-- eop -> _txeop (echo eop , to _txeop, _idle) +-- nak -> _txnak (echo nak , to _txnak, _error) +-- attn -> _txito (silently ignore attn) +-- data -> _idle (decode command) +-- _rx...: expect +-- sop -> _txnak (send nak , to _txnak, _error) +-- eop -> _txnak (send nak,eop , to _txnak, _txeop, _idle) +-- nak -> _txnak (echo nak , to _txnak, _error) +-- attn -> _txito (silently ignore attn) +-- data -> _idle (decode data) +-- +-- 7 supported commands: +-- +-- 000 read reg (rreg): +-- rx: cmd addr ccrc +-- tx: cmd dl dh stat crc +-- seq: _rxcmd _rxaddr _rxccrc (_txcmd|_txnak) +-- _rreg _txdatl _txdath _txstat _txcrc (_rxcmd|_idle) +-- +-- 001 read blk (rblk): +-- rx: cmd addr cnt ccrc +-- tx: cmd cnt dl dh ... stat crc +-- seq: _rxcmd _rxaddr _rxcnt _rxccrc (_txcmd|_txnak) _txcnt +-- {_rreg _txdatl _txdath _blk}* _txstat _txcrc (_rxcmd|_idle) +-- +-- 010 write reg (wreg): +-- rx: cmd addr dl dh ccrc +-- tx: cmd stat crc +-- seq: _rxcmd _rxaddr _rxdatl _rxdath _rxccrc (_txcmd|_txnak) +-- seq: _wreg _txstat _txcrc (_rxcmd|_idle) +-- +-- 011 write blk (wblk): +-- rx: cmd addr cnt ccrc dl dh ... dcrc +-- tx: cmd stat crc +-- seq: _rxcmd _rxaddr _rxcnt _rxccrc (_txcmd|_txnak) +-- {_rxdatl _rxdath _wreg _blk}* _rxdcrc _txstat _txcrc (_rxcmd|_idle) +-- +-- 100 read stat (stat): +-- rx: cmd ccrc +-- tx: cmd ccmd dl dh stat crc +-- seq: _rxcmd _rxccrc (_txcmd|_txnak) +-- _txccmd _txdatl _txdath _txstat _txcrc (_rxcmd|_idle) +-- +-- 101 read attn (attn): +-- rx: cmd ccrc +-- tx: cmd dl dh stat crc +-- seq: _rxcmd _rxccrc (_txcmd|_txnak) +-- _attn _txdatl _txdath _txstat _txcrc (_rxcmd|_idle) +-- +-- 110 write init (init): +-- rx: cmd addr dl dh ccrc +-- tx: cmd stat crc +-- seq: _rxcmd _rxaddr _rxdatl _rxdath _rxccrc (_txcmd|_txnak) +-- seq: _txstat _txcrc (_rxcmd|_idle) +-- like wreg, but no rp_we - rp_hold, just a 1 cycle rp_init pulse +-- +-- 111 is currently not a legal command and causes a nak +-- seq: _txnak +-- +-- The different rbus cycle types are encoded as: +-- +-- init ack we +-- 0 0 0 idle +-- 0 0 1 idle +-- 0 1 0 read +-- 0 1 1 write +-- 1 0 0 internal init +-- 1 0 1 external init +-- 1 1 0 not allowed +-- 1 1 1 not allowed +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.comlib.all; +use work.rrilib.all; + +entity rri_core is -- rri, core interface + generic ( + ATOWIDTH : positive := 5; -- access timeout counter width + ITOWIDTH : positive := 6); -- idle timeout counter width + port ( + CLK : in slbit; -- clock + CE_INT : in slbit := '0'; -- rri ito time unit clock enable + RESET : in slbit; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit; -- comm port: data hold + CP_FLUSH : out slbit; -- comm port: data flush + 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 slv3 -- rbus: status flags + ); +end entity rri_core; + + +architecture syn of rri_core is + + type state_type is ( + s_idle, -- s_idle: wait for sop + s_txito, -- s_txito: send timeout symbol + s_txsop, -- s_txsop: send sop + s_txnak, -- s_txnak: send nak + s_txeop, -- s_txeop: send eop + s_error, -- s_error: wait for eop + s_rxcmd, -- s_rxcmd: wait for cmd + s_rxaddr, -- s_rxaddr: wait for addr + s_rxdatl, -- s_rxdatl: wait for data low + s_rxdath, -- s_rxdath: wait for data high + s_rxcnt, -- s_rxcnt: wait for count + s_rxccrc, -- s_rxccrc: wait for command crc + s_txcmd, -- s_txcmd: send cmd + s_txcnt, -- s_txcnt: send cnt + s_rreg, -- s_rreg: reg or blk read + s_txdatl, -- s_txdatl: send data low + s_txdath, -- s_txdath: send data high + s_wreg, -- s_wreg: reg or blk write + s_blk, -- s_blk: block count handling + s_rxdcrc, -- s_rxdcrc: wait for data crc + s_attn, -- s_attn: handle attention flags + s_txccmd, -- s_txccmd: send last command + s_txstat, -- s_txstat: send status + s_txcrc -- s_txcrc: send crc + ); + + type regs_type is record + state : state_type; -- state + rcmd : slv8; -- received command + ccmd : slv8; -- current command + addr : slv8; -- register address + dil : slv8; -- input data, lsb + dih : slv8; -- input data, msb + dol : slv8; -- output data, lsb + doh : slv8; -- output data, msb + cnt : slv8; -- block transfer count + attn : slv16; -- attn mask + atocnt : slv(ATOWIDTH-1 downto 0); -- access timeout counter + itocnt : slv(ITOWIDTH-1 downto 0); -- idle timeout counter + itoval : slv(ITOWIDTH-1 downto 0); -- idle timeout value + itoena : slbit; -- idle timeout enable flag + anena : slbit; -- attn notification enable flag + andone : slbit; -- attn notification done + ccrc : slbit; -- stat: command crc error + dcrc : slbit; -- stat: data crc error + ioto : slbit; -- stat: i/o time out + ioerr : slbit; -- stat: i/o time error + nakeop : slbit; -- send eop after nak + rbinit : slbit; -- rbus init signal + rbreq : slbit; -- rbus req signal + rbwe : slbit; -- rbus we signal + flush : slbit; -- flush pulse + stat : slv3; -- external status flags + end record regs_type; + + constant atocnt_init : slv(ATOWIDTH-1 downto 0) := (others=>'1'); + constant itocnt_init : slv(ITOWIDTH-1 downto 0) := (others=>'0'); + + constant c_idle : slv4 := "0000"; + constant c_sop : slv4 := "0001"; + constant c_eop : slv4 := "0010"; + constant c_nak : slv4 := "0011"; + constant c_attn : slv4 := "0100"; + + constant regs_init : regs_type := ( + s_idle, -- + (others=>'0'), -- rcmd + (others=>'0'), -- ccmd + (others=>'0'), -- addr + (others=>'0'), -- dil + (others=>'0'), -- dih + (others=>'0'), -- dol + (others=>'0'), -- doh + (others=>'0'), -- cnt + (others=>'0'), -- attn + atocnt_init, -- atocnt + itocnt_init, -- itocnt + itocnt_init, -- itoval + '0', -- itoena + '0','0', -- anena, andone + '0','0','0','0', -- stat flags + '0', -- nakeop + '0','0','0', -- rbinit,rbreq,rbwe + '0', -- flush + (others=>'0') -- stat + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + + signal CRC_RESET : slbit := '0'; + signal ICRC_ENA : slbit := '0'; + signal OCRC_ENA : slbit := '0'; + signal ICRC_OUT : slv8 := (others=>'0'); + signal OCRC_OUT : slv8 := (others=>'0'); + signal OCRC_IN : slv8 := (others=>'0'); + +begin + + assert ITOWIDTH<=8 + report "assert(ITOWIDTH<=8): max byte size ITO counter supported" + severity failure; + + ICRC : crc8 -- crc generator for input data + port map ( + CLK => CLK, + RESET => CRC_RESET, + ENA => ICRC_ENA, + DI => CP_DI(7 downto 0), + CRC => ICRC_OUT + ); + + OCRC : crc8 -- crc generator for output data + port map ( + CLK => CLK, + RESET => CRC_RESET, + ENA => OCRC_ENA, + DI => OCRC_IN, + CRC => OCRC_OUT + ); + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, CE_INT, CP_DI, CP_ENA, CP_HOLD, RB_LAM, + RB_SRES, RB_STAT, ICRC_OUT, OCRC_OUT) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable ival : slbit := '0'; + variable ibusy : slbit := '0'; + variable ido : slv9 := (others=>'0'); + variable ato_go : slbit := '0'; + variable ato_end : slbit := '0'; + variable ito_go : slbit := '0'; + variable ito_end : slbit := '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 : slv4 := "0000"; + + procedure do_comma_abort(nstate : inout state_type; + nnakeop : inout slbit; + comma_typ : in slv4) is + begin + if comma_typ=c_sop or comma_typ=c_eop or comma_typ=c_nak then + if comma_typ = c_eop then + nnakeop := '1'; + end if; + nstate := s_txnak; -- next: send nak + end if; + end procedure do_comma_abort; + + begin + + r := R_REGS; + n := R_REGS; + + idi8 := CP_DI(7 downto 0); -- get data part of CP_DI + is_comma := CP_DI(8); -- get comma marker + comma_typ := CP_DI(3 downto 0); -- get comma type + + n.rbinit := '0'; -- clear rbinit,rbreq,rbwe by default + n.rbreq := '0'; -- they must always be set by the + n.rbwe := '0'; -- 'previous state' + + n.flush := '0'; -- dito for flush + + ibusy := '1'; -- default is to hold input + ival := '0'; + ido := (others=>'0'); + + crcreset := '0'; + icrcena := '0'; + ocrcena := '0'; + + for i in RB_LAM'range loop -- handle attention "LAM's" + if RB_LAM(i) = '1' then -- if LAM bit set + n.attn(i) := '1'; -- set attention bit + end if; + end loop; + + has_attn := '0'; + if unsigned(r.attn) /= 0 then -- is any of the attn bits set ? + has_attn := '1'; + end if; + + ato_go := '0'; -- default: keep access timeout in reset + ato_end := '0'; + if unsigned(r.atocnt) = 0 then -- if access timeout count at zero + ato_end := '1'; -- signal expiration + end if; + + ito_go := '0'; -- default: keep idle timeout in reset + ito_end := '0'; + if unsigned(r.itocnt) = 0 then -- if idle timeout count at zero + ito_end := '1'; -- signal expiration + end if; + + case r.state is + when s_idle => -- s_idle: wait for sop -------------- + ito_go := '1'; -- idle timeout active + if (r.anena='1' and -- if attn notification to send + has_attn='1' and r.andone='0') then + n.state := s_txito; -- next send ito byte + else + ibusy := '0'; -- accept input + if CP_ENA = '1' then -- if input + if is_comma = '1' then -- if comma + case comma_typ is + when c_sop => -- if sop + crcreset := '1'; -- reset crc generators + n.state := s_txsop; -- next: echo it + when c_eop => -- if eop (unexpected) + n.nakeop := '1'; -- send nak,eop + n.state := s_txnak; -- next: send nak + when c_attn => -- if attn + n.state := s_txito; -- next: send ito byte + when others => null; -- other commas: silently ignore + end case; + else -- if normal data + n.state := s_idle; -- silently dropped + end if; + elsif (r.itoena='1' and -- if ito enable, expired and XSEC + ito_end='1' and CE_INT='1') then + n.state := s_txito; -- next: send ito byte + end if; + end if; + + when s_txito => -- s_txito: send timeout symbol ------ + if has_attn = '1' then + ido := c_rri_dat_attn; -- if attn pending: send attn symbol + n.andone := '1'; + else + ido := c_rri_dat_idle; -- otherwise: send idle symbol + end if; + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + n.state := s_idle; -- next: wait for sop + end if; + + when s_txsop => -- s_txsop: send sop ----------------- + ido := c_rri_dat_sop; -- send sop character + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + n.state := s_rxcmd; -- next: read first command + end if; + + when s_txnak => -- s_txnak: send nak ----------------- + ido := c_rri_dat_nak; -- send nak character + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + n.nakeop := '0'; + if r.nakeop = '1' then -- if eop after nak requested + n.state := s_txeop; -- next: send eop + else + n.state := s_error; -- next: error state, wait for eop + end if; + end if; + + when s_txeop => -- s_txeop: send eop ----------------- + ido := c_rri_dat_eop; -- send eop character + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + n.flush := '1'; -- send flush pulse + n.state := s_idle; -- next: idle state, wait for sop + end if; + + when s_error => -- s_error: wait for eop ------------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + case comma_typ is + when c_sop => -- if sop (unexpected) + n.state := s_txnak; -- next: send nak + when c_eop => -- if eop + n.state := s_txeop; -- next: echo eop + when c_nak => -- if nak + n.state := s_txnak; -- next: echo nak + when others => null; -- other commas: silently ignore + end case; + else -- if normal data + n.state := s_error; -- silently dropped + end if; + end if; + + when s_rxcmd => -- s_rxcmd: wait for cmd ------------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + case comma_typ is + when c_sop => -- if sop (unexpected) + n.state := s_txnak; -- next: send nak + when c_eop => -- if eop + n.state := s_txeop; -- next: echo eop + when c_nak => -- if nak + n.state := s_txnak; -- next: echo nak + when others => null; --other commas: silently ignore + end case; + else + icrcena := '1'; -- update input crc + n.rcmd := idi8; -- latch read command code + case CP_DI(c_rri_cmd_rbf_code) is + when c_rri_cmd_rreg | c_rri_cmd_rblk | + c_rri_cmd_wreg | c_rri_cmd_wblk | + c_rri_cmd_init => -- for commands needing addr(data) + n.state := s_rxaddr; -- next: read address + when c_rri_cmd_stat | c_rri_cmd_attn => -- stat and attn commands + n.state := s_rxccrc; -- next: read command crc + when others => + n.state := s_idle; -- if bad command abort here + end case; -- rcmd,ccmd always hold good cmd + end if; + end if; + + when s_rxaddr => -- s_rxaddr: wait for addr ----------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + icrcena := '1'; -- update input crc + n.addr := idi8; -- latch read address + case r.rcmd(c_rri_cmd_rbf_code) is + when c_rri_cmd_rreg => -- for rreg command + n.state := s_rxccrc; -- next: read command crc + when c_rri_cmd_wreg | c_rri_cmd_init => -- for wreg, init command + n.state := s_rxdatl; -- next: read data lsb + when others => -- for rblk or wblk + n.state := s_rxcnt; -- next: read count + end case; + end if; + end if; + + when s_rxdatl => -- s_rxdatl: wait for data low ------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + icrcena := '1'; -- update input crc + n.dil := idi8; -- latch data lsb part + n.state := s_rxdath; -- next: read data msb + end if; + end if; + + when s_rxdath => -- s_rxdath: wait for data high ------ + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + icrcena := '1'; -- update input crc + n.dih := idi8; -- latch data msb part + if r.rcmd(c_rri_cmd_rbf_code) = c_rri_cmd_wblk then -- if wblk + n.rbreq := '1'; + n.rbwe := '1'; + n.state := s_wreg; -- next: write reg + else -- otherwise + n.state := s_rxccrc; -- next: read command crc + end if; + end if; + end if; + + when s_rxcnt => -- s_rxcnt: wait for count ----------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + icrcena := '1'; -- update input crc + n.cnt := idi8; -- latch count + n.state := s_rxccrc; -- next: read command crc + end if; + end if; + + when s_rxccrc => -- s_rxccrc: wait for command crc ---- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + if idi8 /= ICRC_OUT then -- if crc error + n.ccrc := '1'; -- set command crc error flag + n.state := s_txnak; -- next: send nak + else -- if crc ok + n.state := s_txcmd; -- next: echo command + end if; + end if; + end if; + + when s_txcmd => -- s_txcmd: send cmd ----------------- + ido := '0' & r.rcmd; -- send read command + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + ocrcena := '1'; -- update output crc + if r.rcmd(c_rri_cmd_rbf_code) /= c_rri_cmd_stat then -- unless stat + n.ccmd := r.rcmd; -- latch read command in ccmd + n.stat := RB_STAT; -- latch external status bits + n.ccrc := '0'; + n.dcrc := '0'; + n.ioto := '0'; + n.ioerr := '0'; + end if; + case r.rcmd(c_rri_cmd_rbf_code) is -- main command dispatcher + when c_rri_cmd_rreg => -- rreg ---------------- + n.rbreq := '1'; + n.state := s_rreg; + when c_rri_cmd_rblk => -- rblk ---------------- + n.state := s_txcnt; + when c_rri_cmd_wreg => -- wreg ---------------- + n.rbreq := '1'; + n.rbwe := '1'; + n.state := s_wreg; + when c_rri_cmd_wblk => -- wblk ---------------- + n.state := s_rxdatl; + when c_rri_cmd_stat => -- stat ---------------- + n.state := s_txccmd; + when c_rri_cmd_attn => -- attn ---------------- + n.state := s_attn; + + when c_rri_cmd_init => -- init ---------------- + n.rbinit := '1'; -- send init pulse + if r.addr(7 downto 3) = "11111" then -- is internal init + if r.addr(2 downto 0) = "111" then -- is rri init + n.anena := r.dih(c_rri_iint_rbf_anena - 8); + n.itoena := r.dih(c_rri_iint_rbf_itoena - 8); + n.itoval := r.dil(ITOWIDTH-1 downto 0); + -- note: itocnt will load in next + -- cycle because ito_go=0, so no + -- action required here + + end if; + else -- is external init + n.rbwe := '1'; -- send init with we + end if; + n.state := s_txstat; + + when others => -- '111' --------------- + n.state := s_txnak; -- send NAK on reserved command + end case; + end if; + + when s_txcnt => -- s_txcnt: send cnt ----------------- + ido := '0' & r.cnt; -- send cnt + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + ocrcena := '1'; -- update output crc + n.rbreq := '1'; + n.state := s_rreg; -- next: first read reg + end if; + + when s_rreg => -- s_rreg: reg or blk read ----------- + -- this state handles all rbus reads. Expects that previous state + -- sets n.rbreq := '1' to start an rbus read cycle + ato_go := '1'; -- activate timeout counter + if RB_SRES.err = '1' then -- latch error flag + n.ioerr := '1'; + end if; + n.doh := RB_SRES.dout(15 downto 8); -- latch data + n.dol := RB_SRES.dout( 7 downto 0); + n.stat := RB_STAT; -- latch external status bits + if RB_SRES.busy='0' or ato_end='1' then -- wait for non-busy or timeout + if RB_SRES.busy='1' and ato_end='1' then -- if timeout and still busy + n.ioto := '1'; -- set timeout flag + elsif RB_SRES.ack = '0' then -- if non-busy and no ack + n.ioto := '1'; -- set timeout flag + end if; + n.state := s_txdatl; -- next: send data lsb + else -- otherwise rbus read continues + n.rbreq := '1'; -- extend req + end if; + + when s_txdatl => -- s_txdatl: send data low ----------- + ido := '0' & r.dol; -- send data + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + ocrcena := '1'; -- update output crc + n.state := s_txdath; -- next: send data msb + end if; + + when s_txdath => -- s_txdath: send data high + ido := '0' & r.doh; -- send data + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + ocrcena := '1'; -- update output crc + if r.rcmd(c_rri_cmd_rbf_code) = c_rri_cmd_rblk then -- if rblk + n.state := s_blk; -- next: block count handling + else -- otherwise + n.state := s_txstat; -- next: send stat + end if; + end if; + + when s_wreg => -- s_wreg: reg or blk write ---------- + -- this state handles all rbus writes. Expects that previous state + -- sets n.rbreq := '1' and n.rbwe := '1' to start an rbus write cycle + ato_go := '1'; -- activate timeout counter + if RB_SRES.err = '1' then -- latch error flag + n.ioerr := '1'; + end if; + n.stat := RB_STAT; -- latch external status bits + if RB_SRES.busy='0' or ato_end='1' then -- wait for non-busy or timeout + if RB_SRES.busy='1' and ato_end='1' then -- if timeout and still busy + n.ioto := '1'; -- set timeout flag + elsif RB_SRES.ack='0' then -- if non-busy and no ack + n.ioto := '1'; -- set timeout flag + end if; + if r.rcmd(c_rri_cmd_rbf_code) = c_rri_cmd_wblk then -- if wblk + n.state := s_blk; -- next: block count handling + else -- otherwise + n.state := s_txstat; -- next: send stat + end if; + else -- otherwise rbus write continues + n.rbreq := '1'; -- extend req + n.rbwe := '1'; -- extend we + end if; + + when s_blk => -- s_blk: block count handling ------- + n.cnt := unsigned(r.cnt) - 1; -- decrement transfer count + if unsigned(r.cnt) = 0 then -- if last transfer + if r.rcmd(c_rri_cmd_rbf_code) = c_rri_cmd_rblk then -- if rblk + n.state := s_txstat; -- next: send stat + else -- otherwise + n.state := s_rxdcrc; -- next: read data crc + end if; + + else -- otherwise more to transfer + if r.rcmd(c_rri_cmd_rbf_code) = c_rri_cmd_rblk then -- if rblk + n.rbreq := '1'; + n.state := s_rreg; -- next: read blk + else -- otherwise + n.state := s_rxdatl; -- next: read data + end if; + end if; + + when s_rxdcrc => -- s_rxdcrc: wait for data crc ------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + if idi8 /= ICRC_OUT then -- if crc error + n.dcrc := '1'; -- set data crc error flag + end if; + n.state := s_txstat; -- next: echo command + end if; + end if; + + when s_attn => -- s_attn: handle attention flags ---- + n.dol := r.attn(7 downto 0); -- move attention flags to do buffer + n.doh := r.attn(15 downto 8); + n.attn := RB_LAM; -- LAM in current cycle send next time + n.andone := '0'; -- reenable attn nofification + n.state := s_txdatl; -- next: send data lsb + + when s_txccmd => -- s_txccmd: send last command + ido := '0' & r.ccmd; -- send last accepted command + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + ocrcena := '1'; -- update output crc + n.state := s_txdatl; -- next: send last data lsb + end if; + + when s_txstat => -- s_txstat: send status ------------- + ido := (others=>'0'); + ido(c_rri_stat_rbf_stat) := r.stat; + ido(c_rri_stat_rbf_attn) := has_attn; + ido(c_rri_stat_rbf_ccrc) := r.ccrc; + ido(c_rri_stat_rbf_dcrc) := r.dcrc; + ido(c_rri_stat_rbf_ioto) := r.ioto; + ido(c_rri_stat_rbf_ioerr) := r.ioerr; + ival := '1'; + if CP_HOLD ='0' then -- wait for accept + ocrcena := '1'; -- update output crc + n.state := s_txcrc; -- next: send crc + end if; + + when s_txcrc => -- s_txcrc: send crc ----------------- + ido := "0" & OCRC_OUT; -- send crc code + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + n.state := s_rxcmd; -- next: read command or eop + end if; + + when others => null; -- <> -------------------------------- + end case; + + if ato_go = '0' then -- handle access timeout counter + n.atocnt := atocnt_init; -- if ato_go=0, keep in reset + else + n.atocnt := unsigned(r.atocnt) - 1;-- otherwise count down + end if; + + if ito_go = '0' then -- handle idle timeout counter + n.itocnt := r.itoval; -- if ito_go=0, keep at start value + else + if CE_INT = '1' then + n.itocnt := unsigned(r.itocnt) - 1;-- otherwise count down every CE_INT + end if; + end if; + + N_REGS <= n; + + CP_BUSY <= ibusy; + CP_DO <= ido; + CP_VAL <= ival; + CP_FLUSH <= r.flush; + + RB_MREQ <= rb_mreq_init; + RB_MREQ.req <= r.rbreq; + RB_MREQ.we <= r.rbwe; + RB_MREQ.init <= r.rbinit; + RB_MREQ.addr <= r.addr; + RB_MREQ.din <= r.dih & r.dil; + + CRC_RESET <= crcreset; + ICRC_ENA <= icrcena; + OCRC_ENA <= ocrcena; + OCRC_IN <= ido(7 downto 0); + + end process proc_next; + +end syn; Index: rri_core.vbom =================================================================== --- rri_core.vbom (nonexistent) +++ rri_core.vbom (revision 7) @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +../comlib/comlib.vhd +rrilib.vhd +# components +../comlib/crc8.vbom +# design +rri_core.vhd Index: rri_serport.vhd =================================================================== --- rri_serport.vhd (nonexistent) +++ rri_serport.vhd (revision 7) @@ -0,0 +1,201 @@ +-- $Id: rri_serport.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 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: rri_serport - syn +-- Description: rri: serport adapter +-- +-- Dependencies: serport/serport_uart_rxtx_ab +-- comlib/byte2cdata +-- comlib/cdata2byte +-- memlib/fifo_1c_dram +-- +-- Test bench: tb/tb_rri_serport +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-06 301 2.3 use NCOMM=4 (new eop,nak commas) +-- 2010-06-03 300 2.2.1 use FAWIDTH=5 +-- 2010-05-02 287 2.2 drop RTSFLUSH generic +-- 2010-04-18 279 2.1 rewrite flow control, drop RTSFBUF generic +-- 2010-04-03 274 2.0 flow control interfaces: RTSFLUSH, CTS_N, RTS_N +-- 2007-06-24 60 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.genlib.all; +use work.memlib.all; +use work.comlib.all; +use work.serport.all; +use work.rrilib.all; + +entity rri_serport is -- rri serport adapter + generic ( + CPREF : slv4 := "1000"; -- comma prefix + FAWIDTH : positive := 5; -- rx fifo address port width + CDWIDTH : positive := 13; -- clk divider width + CDINIT : natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + 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 := '0'; -- clear to send (act.low, board view) + RTS_N : out slbit; -- request to send (act.low, board view) + CP_DI : out slv9; -- comm port: data in + CP_ENA : out slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv9; -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : out slbit; -- comm port: data hold + CP_FLUSH : in slbit := '0' -- comm port: data flush + ); +end rri_serport; + + +architecture syn of rri_serport is + + signal LRESET : slbit := '0'; + signal RXDATA : slv8 := (others=>'0'); + signal RXVAL : slbit := '0'; + signal TXDATA : slv8 := (others=>'0'); + signal TXENA : slbit := '0'; + signal TXBUSY : slbit := '0'; + signal ABACT : slbit := '0'; + signal FIFO_DI : slv9 := (others=>'0'); + signal FIFO_ENA : slbit := '0'; + signal FIFO_BUSY : slbit := '0'; + signal FIFO_SIZE : slv(FAWIDTH downto 0) := (others=>'0'); + signal CD2B_HOLD : slbit := '0'; + + signal R_FIFOBLOCK : slbit := '0'; -- fifo block flag + signal FLUSH_PULSE : slbit := '0'; -- rri flush as 2-3 usec pulse + + constant NCOMM : positive := 4; + +begin + + UART : serport_uart_rxtx_ab -- uart, rx+tx+autobauder combo + generic map ( + CDWIDTH => CDWIDTH, + CDINIT => CDINIT) + port map ( + CLK => CLK, + CE_MSEC => CE_MSEC, + RESET => RESET, + RXSD => RXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => open, + RXACT => open, + TXSD => TXSD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY, + ABACT => ABACT, + ABDONE => open + ); + + LRESET <= RESET or ABACT; + + B2CD : byte2cdata -- byte stream -> 9bit comma,data + generic map ( + CPREF => CPREF, + NCOMM => NCOMM) + port map ( + CLK => CLK, + RESET => LRESET, + DI => RXDATA, + ENA => RXVAL, + BUSY => open, + DO => FIFO_DI, + VAL => FIFO_ENA, + HOLD => FIFO_BUSY + ); + + CD2B : cdata2byte -- 9bit comma,data -> byte stream + generic map ( + CPREF => CPREF, + NCOMM => NCOMM) + port map ( + CLK => CLK, + RESET => LRESET, + DI => CP_DO, + ENA => CP_VAL, + BUSY => CP_HOLD, + DO => TXDATA, + VAL => TXENA, + HOLD => CD2B_HOLD + ); + + FIFO : fifo_1c_dram -- fifo, 1 clock, dram based + generic map ( + AWIDTH => FAWIDTH, + DWIDTH => 9) + port map ( + CLK => CLK, + RESET => LRESET, + DI => FIFO_DI, + ENA => FIFO_ENA, + BUSY => FIFO_BUSY, + DO => CP_DI, + VAL => CP_ENA, + HOLD => CP_BUSY, + SIZE => FIFO_SIZE + ); + +-- re-write later, use RB_MREQ internal init to set parameters which +-- control the flush logic. +-- +--DOFLUSH: if RTSFLUSH generate +-- +-- PGEN : timer +-- generic map ( +-- TWIDTH => 1, +-- RETRIG => true) +-- port map ( +-- CLK => CLK, +-- CE => CE_USEC, +-- DELAY => "1", +-- START => CP_FLUSH, +-- STOP => RESET, +-- BUSY => FLUSH_PULSE +-- ); +--end generate DOFLUSH; + + proc_fifoblock: process (CLK) + begin + + if CLK'event and CLK='1' then + if unsigned(FIFO_SIZE) >= 3*2**(FAWIDTH-2) then -- more than 3/4 full + R_FIFOBLOCK <= '1'; -- block + elsif unsigned(FIFO_SIZE) < 2**(FAWIDTH-1) then -- less than 1/2 full + R_FIFOBLOCK <= '0'; -- unblock + end if; + end if; + + end process proc_fifoblock; + + RTS_N <= R_FIFOBLOCK or FLUSH_PULSE; + + CD2B_HOLD <= TXBUSY or CTS_N; + +end syn; Index: rri_serport.vbom =================================================================== --- rri_serport.vbom (nonexistent) +++ rri_serport.vbom (revision 7) @@ -0,0 +1,14 @@ +# libs +../slvtypes.vhd +../genlib/genlib.vhd +../memlib/memlib.vhd +../comlib/comlib.vhd +../serport/serport.vhd +rrilib.vhd +# components +../serport/serport_uart_rxtx_ab.vbom +../comlib/byte2cdata.vbom +../comlib/cdata2byte.vbom +../memlib/fifo_1c_dram.vbom +# design +rri_serport.vhd Index: Makefile =================================================================== --- Makefile (nonexistent) +++ Makefile (revision 7) @@ -0,0 +1,22 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 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) +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# Index: . =================================================================== --- . (nonexistent) +++ . (revision 7)
. Property changes : Added: svn:ignore ## -0,0 +1,32 ## +*.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 +*_pad.log +*_bgn.log +*_svn.log +*_sum.log +*_[dsft]sim.log

powered by: WebSVN 2.1.0

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